Add pod list endpoint with pagination, sort...
This commit is contained in:
parent
9fd540562c
commit
8a02bd0433
|
@ -59,7 +59,7 @@ Decentralized video streaming platform using P2P (BitTorrent) directly in the we
|
||||||
Want to see in action?
|
Want to see in action?
|
||||||
|
|
||||||
* [Demo server](http://peertube.cpy.re)
|
* [Demo server](http://peertube.cpy.re)
|
||||||
* [Video](https://vimeo.com/164881662 "Yes Vimeo, please don't judge me") to see how the "decentralization feature" looks like
|
* [Video](https://peertube.cpy.re/videos/watch/f78a97f8-a142-4ce1-a5bd-154bf9386504) to see how the "decentralization feature" looks like
|
||||||
* Experimental demo servers that share videos (they are in the same network): [peertube2](http://peertube2.cpy.re), [peertube3](http://peertube3.cpy.re). Since I do experiments with them, sometimes they might not work correctly.
|
* Experimental demo servers that share videos (they are in the same network): [peertube2](http://peertube2.cpy.re), [peertube3](http://peertube3.cpy.re). Since I do experiments with them, sometimes they might not work correctly.
|
||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
<div class="content-padding">
|
<div class="content-padding">
|
||||||
<h3>Friends list</h3>
|
<h3>Friends list</h3>
|
||||||
|
|
||||||
<p-dataTable [value]="friends">
|
<p-dataTable
|
||||||
<p-column field="id" header="ID"></p-column>
|
[value]="friends" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
|
||||||
<p-column field="host" header="Host"></p-column>
|
sortField="id" (onLazyLoad)="loadLazy($event)"
|
||||||
|
>
|
||||||
|
<p-column field="id" header="ID" [sortable]="true"></p-column>
|
||||||
|
<p-column field="host" header="Host" [sortable]="true"></p-column>
|
||||||
<p-column field="email" header="Email"></p-column>
|
<p-column field="email" header="Email"></p-column>
|
||||||
<p-column field="score" header="Score"></p-column>
|
<p-column field="score" header="Score" [sortable]="true"></p-column>
|
||||||
<p-column field="createdAt" header="Created date"></p-column>
|
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
|
||||||
<p-column header="Delete" styleClass="action-cell">
|
<p-column header="Delete" styleClass="action-cell">
|
||||||
<ng-template pTemplate="body" let-pod="rowData">
|
<ng-template pTemplate="body" let-pod="rowData">
|
||||||
<span (click)="removeFriend(pod)" class="glyphicon glyphicon-remove glyphicon-black" title="Remove this pod"></span>
|
<span (click)="removeFriend(pod)" class="glyphicon glyphicon-remove glyphicon-black" title="Remove this pod"></span>
|
||||||
|
|
|
@ -1,24 +1,32 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
|
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
|
import { SortMeta } from 'primeng/primeng'
|
||||||
|
|
||||||
import { ConfirmService } from '../../../core'
|
import { ConfirmService } from '../../../core'
|
||||||
import { FriendService } from '../shared'
|
import { RestTable, RestPagination } from '../../../shared'
|
||||||
import { Pod } from '../../../../../../shared'
|
import { Pod } from '../../../../../../shared'
|
||||||
|
import { FriendService } from '../shared'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-friend-list',
|
selector: 'my-friend-list',
|
||||||
templateUrl: './friend-list.component.html',
|
templateUrl: './friend-list.component.html',
|
||||||
styleUrls: ['./friend-list.component.scss']
|
styleUrls: ['./friend-list.component.scss']
|
||||||
})
|
})
|
||||||
export class FriendListComponent implements OnInit {
|
export class FriendListComponent extends RestTable implements OnInit {
|
||||||
friends: Pod[] = []
|
friends: Pod[] = []
|
||||||
|
totalRecords = 0
|
||||||
|
rowsPerPage = 10
|
||||||
|
sort: SortMeta = { field: 'id', order: 1 }
|
||||||
|
pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private confirmService: ConfirmService,
|
private confirmService: ConfirmService,
|
||||||
private friendService: FriendService
|
private friendService: FriendService
|
||||||
) {}
|
) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.loadData()
|
this.loadData()
|
||||||
|
@ -65,11 +73,12 @@ export class FriendListComponent implements OnInit {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadData () {
|
protected loadData () {
|
||||||
this.friendService.getFriends()
|
this.friendService.getFriends(this.pagination, this.sort)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
resultList => {
|
resultList => {
|
||||||
this.friends = resultList.data
|
this.friends = resultList.data
|
||||||
|
this.totalRecords = resultList.total
|
||||||
},
|
},
|
||||||
|
|
||||||
err => this.notificationsService.error('Error', err.message)
|
err => this.notificationsService.error('Error', err.message)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { HttpClient } from '@angular/common/http'
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
|
import { Observable } from 'rxjs/Observable'
|
||||||
import 'rxjs/add/operator/catch'
|
import 'rxjs/add/operator/catch'
|
||||||
import 'rxjs/add/operator/map'
|
import 'rxjs/add/operator/map'
|
||||||
|
|
||||||
import { RestExtractor } from '../../../shared'
|
import { SortMeta } from 'primeng/primeng'
|
||||||
|
|
||||||
|
import { RestExtractor, RestPagination, RestService } from '../../../shared'
|
||||||
import { Pod, ResultList } from '../../../../../../shared'
|
import { Pod, ResultList } from '../../../../../../shared'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -12,11 +15,15 @@ export class FriendService {
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private authHttp: HttpClient,
|
private authHttp: HttpClient,
|
||||||
|
private restService: RestService,
|
||||||
private restExtractor: RestExtractor
|
private restExtractor: RestExtractor
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getFriends () {
|
getFriends (pagination: RestPagination, sort: SortMeta): Observable<ResultList<Pod>> {
|
||||||
return this.authHttp.get<ResultList<Pod>>(FriendService.BASE_FRIEND_URL)
|
let params = new HttpParams()
|
||||||
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
|
return this.authHttp.get<ResultList<Pod>>(FriendService.BASE_FRIEND_URL, { params })
|
||||||
.map(res => this.restExtractor.convertResultListDateToHuman(res))
|
.map(res => this.restExtractor.convertResultListDateToHuman(res))
|
||||||
.catch(res => this.restExtractor.handleError(res))
|
.catch(res => this.restExtractor.handleError(res))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,33 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { CONFIG } from '../../initializers'
|
import { logger, getFormattedObjects } from '../../helpers'
|
||||||
import {
|
import {
|
||||||
logger,
|
|
||||||
getMyPublicCert,
|
|
||||||
getFormattedObjects
|
|
||||||
} from '../../helpers'
|
|
||||||
import {
|
|
||||||
sendOwnedVideosToPod,
|
|
||||||
makeFriends,
|
makeFriends,
|
||||||
quitFriends,
|
quitFriends,
|
||||||
removeFriend
|
removeFriend
|
||||||
} from '../../lib'
|
} from '../../lib'
|
||||||
import {
|
import {
|
||||||
podsAddValidator,
|
|
||||||
authenticate,
|
authenticate,
|
||||||
ensureIsAdmin,
|
ensureIsAdmin,
|
||||||
makeFriendsValidator,
|
makeFriendsValidator,
|
||||||
setBodyHostPort,
|
|
||||||
setBodyHostsPort,
|
setBodyHostsPort,
|
||||||
podRemoveValidator
|
podRemoveValidator,
|
||||||
|
paginationValidator,
|
||||||
|
setPagination,
|
||||||
|
setPodsSort,
|
||||||
|
podsSortValidator
|
||||||
} from '../../middlewares'
|
} from '../../middlewares'
|
||||||
import {
|
import { PodInstance } from '../../models'
|
||||||
PodInstance
|
|
||||||
} from '../../models'
|
|
||||||
import { Pod as FormattedPod } from '../../../shared'
|
|
||||||
|
|
||||||
const podsRouter = express.Router()
|
const podsRouter = express.Router()
|
||||||
|
|
||||||
podsRouter.get('/', listPods)
|
podsRouter.get('/',
|
||||||
podsRouter.post('/',
|
paginationValidator,
|
||||||
setBodyHostPort, // We need to modify the host before running the validator!
|
podsSortValidator,
|
||||||
podsAddValidator,
|
setPodsSort,
|
||||||
addPods
|
setPagination,
|
||||||
|
listPods
|
||||||
)
|
)
|
||||||
podsRouter.post('/make-friends',
|
podsRouter.post('/make-friends',
|
||||||
authenticate,
|
authenticate,
|
||||||
|
@ -62,26 +56,9 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const informations = req.body
|
|
||||||
|
|
||||||
const pod = db.Pod.build(informations)
|
|
||||||
pod.save()
|
|
||||||
.then(podCreated => {
|
|
||||||
return sendOwnedVideosToPod(podCreated.id)
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return getMyPublicCert()
|
|
||||||
})
|
|
||||||
.then(cert => {
|
|
||||||
return res.json({ cert: cert, email: CONFIG.ADMIN.EMAIL })
|
|
||||||
})
|
|
||||||
.catch(err => next(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
function listPods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function listPods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
db.Pod.list()
|
db.Pod.listForApi(req.query.start, req.query.count, req.query.sort)
|
||||||
.then(podsList => res.json(getFormattedObjects<FormattedPod, PodInstance>(podsList, podsList.length)))
|
.then(resultList => res.json(getFormattedObjects(resultList.data, resultList.total)))
|
||||||
.catch(err => next(err))
|
.catch(err => next(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,34 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
|
|
||||||
import { database as db } from '../../../initializers/database'
|
import { database as db } from '../../../initializers/database'
|
||||||
import { checkSignature, signatureValidator } from '../../../middlewares'
|
import {
|
||||||
import { PodSignature } from '../../../../shared'
|
checkSignature,
|
||||||
|
signatureValidator,
|
||||||
|
setBodyHostPort,
|
||||||
|
remotePodsAddValidator
|
||||||
|
} from '../../../middlewares'
|
||||||
|
import { sendOwnedVideosToPod } from '../../../lib'
|
||||||
|
import { getMyPublicCert, getFormattedObjects } from '../../../helpers'
|
||||||
|
import { CONFIG } from '../../../initializers'
|
||||||
|
import { PodInstance } from '../../../models'
|
||||||
|
import { PodSignature, Pod as FormattedPod } from '../../../../shared'
|
||||||
|
|
||||||
const remotePodsRouter = express.Router()
|
const remotePodsRouter = express.Router()
|
||||||
|
|
||||||
// Post because this is a secured request
|
|
||||||
remotePodsRouter.post('/remove',
|
remotePodsRouter.post('/remove',
|
||||||
signatureValidator,
|
signatureValidator,
|
||||||
checkSignature,
|
checkSignature,
|
||||||
removePods
|
removePods
|
||||||
)
|
)
|
||||||
|
|
||||||
|
remotePodsRouter.post('/list', remotePodsList)
|
||||||
|
|
||||||
|
remotePodsRouter.post('/add',
|
||||||
|
setBodyHostPort, // We need to modify the host before running the validator!
|
||||||
|
remotePodsAddValidator,
|
||||||
|
addPods
|
||||||
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -21,6 +37,29 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function addPods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
const information = req.body
|
||||||
|
|
||||||
|
const pod = db.Pod.build(information)
|
||||||
|
pod.save()
|
||||||
|
.then(podCreated => {
|
||||||
|
return sendOwnedVideosToPod(podCreated.id)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
return getMyPublicCert()
|
||||||
|
})
|
||||||
|
.then(cert => {
|
||||||
|
return res.json({ cert: cert, email: CONFIG.ADMIN.EMAIL })
|
||||||
|
})
|
||||||
|
.catch(err => next(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
function remotePodsList (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
db.Pod.list()
|
||||||
|
.then(podsList => res.json(getFormattedObjects<FormattedPod, PodInstance>(podsList, podsList.length)))
|
||||||
|
.catch(err => next(err))
|
||||||
|
}
|
||||||
|
|
||||||
function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function removePods (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const signature: PodSignature = req.body.signature
|
const signature: PodSignature = req.body.signature
|
||||||
const host = signature.host
|
const host = signature.host
|
||||||
|
|
|
@ -32,6 +32,7 @@ const SEARCHABLE_COLUMNS = {
|
||||||
|
|
||||||
// Sortable columns per schema
|
// Sortable columns per schema
|
||||||
const SORTABLE_COLUMNS = {
|
const SORTABLE_COLUMNS = {
|
||||||
|
PODS: [ 'id', 'host', 'score', 'createdAt' ],
|
||||||
USERS: [ 'id', 'username', 'createdAt' ],
|
USERS: [ 'id', 'username', 'createdAt' ],
|
||||||
VIDEO_ABUSES: [ 'id', 'createdAt' ],
|
VIDEO_ABUSES: [ 'id', 'createdAt' ],
|
||||||
VIDEOS: [ 'name', 'duration', 'createdAt', 'views', 'likes' ],
|
VIDEOS: [ 'name', 'duration', 'createdAt', 'views', 'likes' ],
|
||||||
|
|
|
@ -334,9 +334,9 @@ function computeWinningPods (hosts: string[], podsScore: { [ host: string ]: num
|
||||||
|
|
||||||
function getForeignPodsList (host: string) {
|
function getForeignPodsList (host: string) {
|
||||||
return new Promise< ResultList<FormattedPod> >((res, rej) => {
|
return new Promise< ResultList<FormattedPod> >((res, rej) => {
|
||||||
const path = '/api/' + API_VERSION + '/pods'
|
const path = '/api/' + API_VERSION + '/remote/pods/list'
|
||||||
|
|
||||||
request.get(REMOTE_SCHEME.HTTP + '://' + host + path, (err, response, body) => {
|
request.post(REMOTE_SCHEME.HTTP + '://' + host + path, (err, response, body) => {
|
||||||
if (err) return rej(err)
|
if (err) return rej(err)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -357,7 +357,7 @@ function makeRequestsToWinningPods (cert: string, podsList: PodInstance[]) {
|
||||||
|
|
||||||
return Promise.map(podsList, pod => {
|
return Promise.map(podsList, pod => {
|
||||||
const params = {
|
const params = {
|
||||||
url: REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + API_VERSION + '/pods/',
|
url: REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + API_VERSION + '/remote/pods/add',
|
||||||
method: 'POST' as 'POST',
|
method: 'POST' as 'POST',
|
||||||
json: {
|
json: {
|
||||||
host: CONFIG.WEBSERVER.HOST,
|
host: CONFIG.WEBSERVER.HOST,
|
||||||
|
|
|
@ -4,6 +4,12 @@ import * as express from 'express'
|
||||||
import { SortType } from '../helpers'
|
import { SortType } from '../helpers'
|
||||||
import { database } from '../initializers'
|
import { database } from '../initializers'
|
||||||
|
|
||||||
|
function setPodsSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||||
|
|
||||||
|
return next()
|
||||||
|
}
|
||||||
|
|
||||||
function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
if (!req.query.sort) req.query.sort = '-createdAt'
|
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||||
|
|
||||||
|
@ -46,6 +52,7 @@ function setBlacklistSort (req: express.Request, res: express.Response, next: ex
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
setPodsSort,
|
||||||
setUsersSort,
|
setUsersSort,
|
||||||
setVideoAbusesSort,
|
setVideoAbusesSort,
|
||||||
setVideosSort,
|
setVideosSort,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as express from 'express'
|
||||||
|
|
||||||
import { database as db } from '../../initializers/database'
|
import { database as db } from '../../initializers/database'
|
||||||
import { checkErrors } from './utils'
|
import { checkErrors } from './utils'
|
||||||
import { logger, isEachUniqueHostValid, isHostValid } from '../../helpers'
|
import { logger, isEachUniqueHostValid } from '../../helpers'
|
||||||
import { CONFIG } from '../../initializers'
|
import { CONFIG } from '../../initializers'
|
||||||
import { hasFriends } from '../../lib'
|
import { hasFriends } from '../../lib'
|
||||||
import { isTestInstance } from '../../helpers'
|
import { isTestInstance } from '../../helpers'
|
||||||
|
@ -41,32 +41,6 @@ const makeFriendsValidator = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const podsAddValidator = [
|
|
||||||
body('host').custom(isHostValid).withMessage('Should have a host'),
|
|
||||||
body('email').isEmail().withMessage('Should have an email'),
|
|
||||||
body('publicKey').not().isEmpty().withMessage('Should have a public key'),
|
|
||||||
|
|
||||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
||||||
logger.debug('Checking podsAdd parameters', { parameters: req.body })
|
|
||||||
|
|
||||||
checkErrors(req, res, () => {
|
|
||||||
db.Pod.loadByHost(req.body.host)
|
|
||||||
.then(pod => {
|
|
||||||
// Pod with this host already exists
|
|
||||||
if (pod) {
|
|
||||||
return res.sendStatus(409)
|
|
||||||
}
|
|
||||||
|
|
||||||
return next()
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
logger.error('Cannot load pod by host.', err)
|
|
||||||
res.sendStatus(500)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const podRemoveValidator = [
|
const podRemoveValidator = [
|
||||||
param('id').isNumeric().not().isEmpty().withMessage('Should have a valid id'),
|
param('id').isNumeric().not().isEmpty().withMessage('Should have a valid id'),
|
||||||
|
|
||||||
|
@ -96,6 +70,5 @@ const podRemoveValidator = [
|
||||||
|
|
||||||
export {
|
export {
|
||||||
makeFriendsValidator,
|
makeFriendsValidator,
|
||||||
podsAddValidator,
|
|
||||||
podRemoveValidator
|
podRemoveValidator
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
export * from './pods'
|
||||||
export * from './signature'
|
export * from './signature'
|
||||||
export * from './videos'
|
export * from './videos'
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { body } from 'express-validator/check'
|
||||||
|
import * as express from 'express'
|
||||||
|
|
||||||
|
import { database as db } from '../../../initializers'
|
||||||
|
import { isHostValid, logger } from '../../../helpers'
|
||||||
|
import { checkErrors } from '../utils'
|
||||||
|
|
||||||
|
const remotePodsAddValidator = [
|
||||||
|
body('host').custom(isHostValid).withMessage('Should have a host'),
|
||||||
|
body('email').isEmail().withMessage('Should have an email'),
|
||||||
|
body('publicKey').not().isEmpty().withMessage('Should have a public key'),
|
||||||
|
|
||||||
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
|
logger.debug('Checking podsAdd parameters', { parameters: req.body })
|
||||||
|
|
||||||
|
checkErrors(req, res, () => {
|
||||||
|
db.Pod.loadByHost(req.body.host)
|
||||||
|
.then(pod => {
|
||||||
|
// Pod with this host already exists
|
||||||
|
if (pod) {
|
||||||
|
return res.sendStatus(409)
|
||||||
|
}
|
||||||
|
|
||||||
|
return next()
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
logger.error('Cannot load pod by host.', err)
|
||||||
|
res.sendStatus(500)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export {
|
||||||
|
remotePodsAddValidator
|
||||||
|
}
|
|
@ -6,11 +6,13 @@ import { logger } from '../../helpers'
|
||||||
import { SORTABLE_COLUMNS } from '../../initializers'
|
import { SORTABLE_COLUMNS } from '../../initializers'
|
||||||
|
|
||||||
// Initialize constants here for better performances
|
// Initialize constants here for better performances
|
||||||
|
const SORTABLE_PODS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.PODS)
|
||||||
const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
|
const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
|
||||||
const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
|
const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
|
||||||
const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
|
const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
|
||||||
const SORTABLE_BLACKLISTS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.BLACKLISTS)
|
const SORTABLE_BLACKLISTS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.BLACKLISTS)
|
||||||
|
|
||||||
|
const podsSortValidator = checkSort(SORTABLE_PODS_COLUMNS)
|
||||||
const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS)
|
const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS)
|
||||||
const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS)
|
const videoAbusesSortValidator = checkSort(SORTABLE_VIDEO_ABUSES_COLUMNS)
|
||||||
const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS)
|
const videosSortValidator = checkSort(SORTABLE_VIDEOS_COLUMNS)
|
||||||
|
@ -19,6 +21,7 @@ const blacklistSortValidator = checkSort(SORTABLE_BLACKLISTS_COLUMNS)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
podsSortValidator,
|
||||||
usersSortValidator,
|
usersSortValidator,
|
||||||
videoAbusesSortValidator,
|
videoAbusesSortValidator,
|
||||||
videosSortValidator,
|
videosSortValidator,
|
||||||
|
|
|
@ -3,12 +3,12 @@ import * as express from 'express'
|
||||||
|
|
||||||
import { logger } from '../../helpers'
|
import { logger } from '../../helpers'
|
||||||
|
|
||||||
function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction, statusCode = 400) {
|
function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const errors = validationResult(req)
|
const errors = validationResult(req)
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() })
|
logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() })
|
||||||
return res.status(statusCode).json({ errors: errors.mapped() })
|
return res.status(400).json({ errors: errors.mapped() })
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -3,6 +3,7 @@ import * as Promise from 'bluebird'
|
||||||
|
|
||||||
// Don't use barrel, import just what we need
|
// Don't use barrel, import just what we need
|
||||||
import { Pod as FormattedPod } from '../../../shared/models/pods/pod.model'
|
import { Pod as FormattedPod } from '../../../shared/models/pods/pod.model'
|
||||||
|
import { ResultList } from '../../../shared/models/result-list.model'
|
||||||
|
|
||||||
export namespace PodMethods {
|
export namespace PodMethods {
|
||||||
export type ToFormattedJSON = (this: PodInstance) => FormattedPod
|
export type ToFormattedJSON = (this: PodInstance) => FormattedPod
|
||||||
|
@ -13,6 +14,8 @@ export namespace PodMethods {
|
||||||
|
|
||||||
export type List = () => Promise<PodInstance[]>
|
export type List = () => Promise<PodInstance[]>
|
||||||
|
|
||||||
|
export type ListForApi = (start: number, count: number, sort: string) => Promise< ResultList<PodInstance> >
|
||||||
|
|
||||||
export type ListAllIds = (transaction: Sequelize.Transaction) => Promise<number[]>
|
export type ListAllIds = (transaction: Sequelize.Transaction) => Promise<number[]>
|
||||||
|
|
||||||
export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string) => Promise<number[]>
|
export type ListRandomPodIdsWithRequest = (limit: number, tableWithPods: string, tableWithPodsJoins: string) => Promise<number[]>
|
||||||
|
@ -32,6 +35,7 @@ export interface PodClass {
|
||||||
countAll: PodMethods.CountAll
|
countAll: PodMethods.CountAll
|
||||||
incrementScores: PodMethods.IncrementScores
|
incrementScores: PodMethods.IncrementScores
|
||||||
list: PodMethods.List
|
list: PodMethods.List
|
||||||
|
listForApi: PodMethods.ListForApi
|
||||||
listAllIds: PodMethods.ListAllIds
|
listAllIds: PodMethods.ListAllIds
|
||||||
listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
||||||
listBadPods: PodMethods.ListBadPods
|
listBadPods: PodMethods.ListBadPods
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as Sequelize from 'sequelize'
|
||||||
import { FRIEND_SCORE, PODS_SCORE } from '../../initializers'
|
import { FRIEND_SCORE, PODS_SCORE } from '../../initializers'
|
||||||
import { logger, isHostValid } from '../../helpers'
|
import { logger, isHostValid } from '../../helpers'
|
||||||
|
|
||||||
import { addMethodsToModel } from '../utils'
|
import { addMethodsToModel, getSort } from '../utils'
|
||||||
import {
|
import {
|
||||||
PodInstance,
|
PodInstance,
|
||||||
PodAttributes,
|
PodAttributes,
|
||||||
|
@ -17,6 +17,7 @@ let toFormattedJSON: PodMethods.ToFormattedJSON
|
||||||
let countAll: PodMethods.CountAll
|
let countAll: PodMethods.CountAll
|
||||||
let incrementScores: PodMethods.IncrementScores
|
let incrementScores: PodMethods.IncrementScores
|
||||||
let list: PodMethods.List
|
let list: PodMethods.List
|
||||||
|
let listForApi: PodMethods.ListForApi
|
||||||
let listAllIds: PodMethods.ListAllIds
|
let listAllIds: PodMethods.ListAllIds
|
||||||
let listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
let listRandomPodIdsWithRequest: PodMethods.ListRandomPodIdsWithRequest
|
||||||
let listBadPods: PodMethods.ListBadPods
|
let listBadPods: PodMethods.ListBadPods
|
||||||
|
@ -78,6 +79,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
|
||||||
countAll,
|
countAll,
|
||||||
incrementScores,
|
incrementScores,
|
||||||
list,
|
list,
|
||||||
|
listForApi,
|
||||||
listAllIds,
|
listAllIds,
|
||||||
listRandomPodIdsWithRequest,
|
listRandomPodIdsWithRequest,
|
||||||
listBadPods,
|
listBadPods,
|
||||||
|
@ -142,6 +144,21 @@ list = function () {
|
||||||
return Pod.findAll()
|
return Pod.findAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listForApi = function (start: number, count: number, sort: string) {
|
||||||
|
const query = {
|
||||||
|
offset: start,
|
||||||
|
limit: count,
|
||||||
|
order: [ getSort(sort) ]
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pod.findAndCountAll(query).then(({ rows, count }) => {
|
||||||
|
return {
|
||||||
|
data: rows,
|
||||||
|
total: count
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
listAllIds = function (transaction: Sequelize.Transaction) {
|
listAllIds = function (transaction: Sequelize.Transaction) {
|
||||||
const query = {
|
const query = {
|
||||||
attributes: [ 'id' ],
|
attributes: [ 'id' ],
|
||||||
|
|
|
@ -15,7 +15,6 @@ import {
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
|
|
||||||
describe('Test pods API validators', function () {
|
describe('Test pods API validators', function () {
|
||||||
const path = '/api/v1/pods/'
|
|
||||||
let server: ServerInfo
|
let server: ServerInfo
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
@ -30,6 +29,7 @@ describe('Test pods API validators', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('When managing friends', function () {
|
describe('When managing friends', function () {
|
||||||
|
const path = '/api/v1/pods/'
|
||||||
let userAccessToken = null
|
let userAccessToken = null
|
||||||
|
|
||||||
before(async function () {
|
before(async function () {
|
||||||
|
@ -110,6 +110,32 @@ describe('Test pods API validators', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('When listing friends', function () {
|
||||||
|
it('Should fail with a bad start pagination', async function () {
|
||||||
|
await request(server.url)
|
||||||
|
.get(path)
|
||||||
|
.query({ start: 'hello' })
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.expect(400)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with a bad count pagination', async function () {
|
||||||
|
await request(server.url)
|
||||||
|
.get(path)
|
||||||
|
.query({ count: 'hello' })
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.expect(400)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should fail with an incorrect sort', async function () {
|
||||||
|
await request(server.url)
|
||||||
|
.get(path)
|
||||||
|
.query({ sort: 'hello' })
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.expect(400)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('When quitting friends', function () {
|
describe('When quitting friends', function () {
|
||||||
it('Should fail with an invalid token', async function () {
|
it('Should fail with an invalid token', async function () {
|
||||||
await request(server.url)
|
await request(server.url)
|
||||||
|
@ -175,7 +201,9 @@ describe('Test pods API validators', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('When adding a pod', function () {
|
describe('When adding a pod from remote', function () {
|
||||||
|
const path = '/api/v1/remote/pods/add'
|
||||||
|
|
||||||
it('Should fail with nothing', async function () {
|
it('Should fail with nothing', async function () {
|
||||||
const fields = {}
|
const fields = {}
|
||||||
await makePostBodyRequest({ url: server.url, path, fields })
|
await makePostBodyRequest({ url: server.url, path, fields })
|
||||||
|
|
|
@ -15,7 +15,8 @@ import {
|
||||||
makeFriends,
|
makeFriends,
|
||||||
getFriendsList,
|
getFriendsList,
|
||||||
dateIsValid,
|
dateIsValid,
|
||||||
quitOneFriend
|
quitOneFriend,
|
||||||
|
getPodsListPaginationAndSort
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
|
|
||||||
describe('Test basic friends', function () {
|
describe('Test basic friends', function () {
|
||||||
|
@ -120,6 +121,22 @@ describe('Test basic friends', function () {
|
||||||
await makeFriends(server.url, server.accessToken, 409)
|
await makeFriends(server.url, server.accessToken, 409)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should list friends correctly', async function () {
|
||||||
|
const start = 1
|
||||||
|
const count = 1
|
||||||
|
const sort = '-host'
|
||||||
|
|
||||||
|
const res = await getPodsListPaginationAndSort(servers[0].url, start, count, sort)
|
||||||
|
expect(res.body.total).to.equal(2)
|
||||||
|
expect(res.body.data).to.have.lengthOf(1)
|
||||||
|
|
||||||
|
const pod = res.body.data[0]
|
||||||
|
expect(pod.host).to.equal('localhost:9002')
|
||||||
|
expect(pod.email).to.equal('admin2@example.com')
|
||||||
|
expect(pod.score).to.equal(20)
|
||||||
|
expect(dateIsValid(pod.createdAt)).to.be.true
|
||||||
|
})
|
||||||
|
|
||||||
it('Should quit friends of pod 2', async function () {
|
it('Should quit friends of pod 2', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,19 @@ function getFriendsList (url: string) {
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPodsListPaginationAndSort (url: string, start: number, count: number, sort: string) {
|
||||||
|
const path = '/api/v1/pods/'
|
||||||
|
|
||||||
|
return request(url)
|
||||||
|
.get(path)
|
||||||
|
.query({ start })
|
||||||
|
.query({ count })
|
||||||
|
.query({ sort })
|
||||||
|
.set('Accept', 'application/json')
|
||||||
|
.expect(200)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
}
|
||||||
|
|
||||||
async function makeFriends (url: string, accessToken: string, expectedStatus = 204) {
|
async function makeFriends (url: string, accessToken: string, expectedStatus = 204) {
|
||||||
// Which pod makes friends with which pod
|
// Which pod makes friends with which pod
|
||||||
const friendsMatrix = {
|
const friendsMatrix = {
|
||||||
|
@ -85,5 +98,6 @@ export {
|
||||||
getFriendsList,
|
getFriendsList,
|
||||||
makeFriends,
|
makeFriends,
|
||||||
quitFriends,
|
quitFriends,
|
||||||
quitOneFriend
|
quitOneFriend,
|
||||||
|
getPodsListPaginationAndSort
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue