Add get subscription endpoint

pull/974/head
Chocobozzz 2018-08-21 10:34:18 +02:00
parent 8a19bee1a1
commit 99492dbc0d
7 changed files with 137 additions and 34 deletions

View File

@ -12,7 +12,7 @@ import {
setDefaultPagination,
setDefaultSort,
userSubscriptionAddValidator,
userSubscriptionRemoveValidator,
userSubscriptionGetValidator,
usersUpdateMeValidator,
usersVideoRatingValidator
} from '../../../middlewares'
@ -97,6 +97,17 @@ meRouter.post('/me/avatar/pick',
// ##### Subscriptions part #####
meRouter.get('/me/subscriptions/videos',
authenticate,
authenticate,
paginationValidator,
videosSortValidator,
setDefaultSort,
setDefaultPagination,
commonVideosFiltersValidator,
asyncMiddleware(getUserSubscriptionVideos)
)
meRouter.get('/me/subscriptions',
authenticate,
paginationValidator,
@ -112,21 +123,16 @@ meRouter.post('/me/subscriptions',
asyncMiddleware(addUserSubscription)
)
meRouter.delete('/me/subscriptions/:uri',
meRouter.get('/me/subscriptions/:uri',
authenticate,
userSubscriptionRemoveValidator,
asyncMiddleware(deleteUserSubscription)
userSubscriptionGetValidator,
getUserSubscription
)
meRouter.get('/me/subscriptions/videos',
meRouter.delete('/me/subscriptions/:uri',
authenticate,
authenticate,
paginationValidator,
videosSortValidator,
setDefaultSort,
setDefaultPagination,
commonVideosFiltersValidator,
asyncMiddleware(getUserSubscriptionVideos)
userSubscriptionGetValidator,
asyncMiddleware(deleteUserSubscription)
)
// ---------------------------------------------------------------------------
@ -153,6 +159,12 @@ async function addUserSubscription (req: express.Request, res: express.Response)
return res.status(204).end()
}
function getUserSubscription (req: express.Request, res: express.Response) {
const subscription: ActorFollowModel = res.locals.subscription
return res.json(subscription.ActorFollowing.VideoChannel.toFormattedJSON())
}
async function deleteUserSubscription (req: express.Request, res: express.Response) {
const subscription: ActorFollowModel = res.locals.subscription

View File

@ -20,11 +20,11 @@ const userSubscriptionAddValidator = [
}
]
const userSubscriptionRemoveValidator = [
const userSubscriptionGetValidator = [
param('uri').custom(isValidActorHandle).withMessage('Should have a valid URI to unfollow'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking unfollow parameters', { parameters: req.params })
logger.debug('Checking userSubscriptionGetValidator parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return
@ -34,7 +34,7 @@ const userSubscriptionRemoveValidator = [
const user: UserModel = res.locals.oauth.token.User
const subscription = await ActorFollowModel.loadByActorAndTargetNameAndHost(user.Account.Actor.id, name, host)
if (!subscription) {
if (!subscription || !subscription.ActorFollowing.VideoChannel) {
return res
.status(404)
.json({
@ -52,7 +52,7 @@ const userSubscriptionRemoveValidator = [
export {
userSubscriptionAddValidator,
userSubscriptionRemoveValidator
userSubscriptionGetValidator
}
// ---------------------------------------------------------------------------

View File

@ -137,7 +137,7 @@ const videosGetValidator = [
// Video private or blacklisted
if (video.privacy === VideoPrivacy.PRIVATE || video.VideoBlacklist) {
authenticate(req, res, () => {
return authenticate(req, res, () => {
const user: UserModel = res.locals.oauth.token.User
// Only the owner or a user that have blacklist rights can see the video

View File

@ -28,6 +28,7 @@ import { ServerModel } from '../server/server'
import { getSort } from '../utils'
import { ActorModel } from './actor'
import { VideoChannelModel } from '../video/video-channel'
import { IIncludeOptions } from '../../../node_modules/sequelize-typescript/lib/interfaces/IIncludeOptions'
@Table({
tableName: 'actorFollow',
@ -166,28 +167,30 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
}
static loadByActorAndTargetNameAndHost (actorId: number, targetName: string, targetHost: string, t?: Sequelize.Transaction) {
const actorFollowingPartInclude = {
const actorFollowingPartInclude: IIncludeOptions = {
model: ActorModel,
required: true,
as: 'ActorFollowing',
where: {
preferredUsername: targetName
}
},
include: [
{
model: VideoChannelModel,
required: false
}
]
}
if (targetHost === null) {
actorFollowingPartInclude.where['serverId'] = null
} else {
Object.assign(actorFollowingPartInclude, {
include: [
{
model: ServerModel,
required: true,
where: {
host: targetHost
}
}
]
actorFollowingPartInclude.include.push({
model: ServerModel,
required: true,
where: {
host: targetHost
}
})
}

View File

@ -61,7 +61,7 @@ describe('Test user subscriptions API validators', function () {
})
})
it('Should success with the correct parameters', async function () {
it('Should succeed with the correct parameters', async function () {
await makeGetRequest({
url: server.url,
path,
@ -94,7 +94,7 @@ describe('Test user subscriptions API validators', function () {
})
})
it('Should success with the correct parameters', async function () {
it('Should succeed with the correct parameters', async function () {
await makeGetRequest({
url: server.url,
path,
@ -140,7 +140,7 @@ describe('Test user subscriptions API validators', function () {
})
})
it('Should success with the correct parameters', async function () {
it('Should succeed with the correct parameters', async function () {
await makePostBodyRequest({
url: server.url,
path,
@ -151,6 +151,57 @@ describe('Test user subscriptions API validators', function () {
})
})
describe('When getting a subscription', function () {
it('Should fail with a non authenticated user', async function () {
await makeGetRequest({
url: server.url,
path: path + '/user1_channel@localhost:9001',
statusCodeExpected: 401
})
})
it('Should fail with bad URIs', async function () {
await makeGetRequest({
url: server.url,
path: path + '/root',
token: server.accessToken,
statusCodeExpected: 400
})
await makeGetRequest({
url: server.url,
path: path + '/root@',
token: server.accessToken,
statusCodeExpected: 400
})
await makeGetRequest({
url: server.url,
path: path + '/root@hello@',
token: server.accessToken,
statusCodeExpected: 400
})
})
it('Should fail with an unknown subscription', async function () {
await makeGetRequest({
url: server.url,
path: path + '/root1@localhost:9001',
token: server.accessToken,
statusCodeExpected: 404
})
})
it('Should succeed with the correct parameters', async function () {
await makeGetRequest({
url: server.url,
path: path + '/user1_channel@localhost:9001',
token: server.accessToken,
statusCodeExpected: 200
})
})
})
describe('When removing a subscription', function () {
it('Should fail with a non authenticated user', async function () {
await makeDeleteRequest({
@ -192,7 +243,7 @@ describe('Test user subscriptions API validators', function () {
})
})
it('Should success with the correct parameters', async function () {
it('Should succeed with the correct parameters', async function () {
await makeDeleteRequest({
url: server.url,
path: path + '/user1_channel@localhost:9001',

View File

@ -11,7 +11,8 @@ import {
addUserSubscription,
listUserSubscriptions,
listUserSubscriptionVideos,
removeUserSubscription
removeUserSubscription,
getUserSubscription
} from '../../utils/users/user-subscriptions'
const expect = chai.expect
@ -101,6 +102,30 @@ describe('Test users subscriptions', function () {
}
})
it('Should get subscription', async function () {
{
const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'user3_channel@localhost:9003')
const videoChannel: VideoChannel = res.body
expect(videoChannel.name).to.equal('user3_channel')
expect(videoChannel.host).to.equal('localhost:9003')
expect(videoChannel.displayName).to.equal('Main user3 channel')
expect(videoChannel.followingCount).to.equal(0)
expect(videoChannel.followersCount).to.equal(1)
}
{
const res = await getUserSubscription(servers[ 0 ].url, users[ 0 ].accessToken, 'root_channel@localhost:9001')
const videoChannel: VideoChannel = res.body
expect(videoChannel.name).to.equal('root_channel')
expect(videoChannel.host).to.equal('localhost:9001')
expect(videoChannel.displayName).to.equal('Main root channel')
expect(videoChannel.followingCount).to.equal(0)
expect(videoChannel.followersCount).to.equal(1)
}
})
it('Should list subscription videos', async function () {
{
const res = await listUserSubscriptionVideos(servers[0].url, servers[0].accessToken)

View File

@ -36,6 +36,17 @@ function listUserSubscriptionVideos (url: string, token: string, sort = '-create
})
}
function getUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 200) {
const path = '/api/v1/users/me/subscriptions/' + uri
return makeGetRequest({
url,
path,
token,
statusCodeExpected
})
}
function removeUserSubscription (url: string, token: string, uri: string, statusCodeExpected = 204) {
const path = '/api/v1/users/me/subscriptions/' + uri
@ -52,6 +63,7 @@ function removeUserSubscription (url: string, token: string, uri: string, status
export {
addUserSubscription,
listUserSubscriptions,
getUserSubscription,
listUserSubscriptionVideos,
removeUserSubscription
}