aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorWicklow <123956049+wickloww@users.noreply.github.com>2023-03-02 13:50:55 +0000
committerGitHub <noreply@github.com>2023-03-02 14:50:55 +0100
commit692ae8c31caa5a404142c9f46e03fdc8dc5b233f (patch)
tree17d12edb5cfbfeddff2fd6f0d85b11c8954da89e
parentc0a4982ebe27c89f296a0bbd518e938f09d1f054 (diff)
downloadPeerTube-692ae8c31caa5a404142c9f46e03fdc8dc5b233f.tar.gz
PeerTube-692ae8c31caa5a404142c9f46e03fdc8dc5b233f.tar.zst
PeerTube-692ae8c31caa5a404142c9f46e03fdc8dc5b233f.zip
Hotfix/filter subscription videos (#5665)
* Fix filters on subscription videos * Add tests to common video filters * Improve reliability when skipping subscrition path * Better parameters for skipping subscription videos
-rw-r--r--server/tests/api/check-params/videos-common-filters.ts3
-rw-r--r--server/tests/api/users/user-subscriptions.ts37
-rw-r--r--server/tests/api/videos/videos-common-filters.ts63
-rw-r--r--server/tests/feeds/feeds.ts8
-rw-r--r--server/tests/fixtures/peertube-plugin-test/main.js2
-rw-r--r--server/tests/plugins/filter-hooks.ts8
-rw-r--r--shared/server-commands/users/subscriptions-command.ts18
-rw-r--r--shared/server-commands/videos/videos-command.ts14
8 files changed, 94 insertions, 59 deletions
diff --git a/server/tests/api/check-params/videos-common-filters.ts b/server/tests/api/check-params/videos-common-filters.ts
index 95523ce3d..11d9fd95b 100644
--- a/server/tests/api/check-params/videos-common-filters.ts
+++ b/server/tests/api/check-params/videos-common-filters.ts
@@ -42,7 +42,8 @@ describe('Test video filters validators', function () {
42 '/api/v1/video-channels/root_channel/videos', 42 '/api/v1/video-channels/root_channel/videos',
43 '/api/v1/accounts/root/videos', 43 '/api/v1/accounts/root/videos',
44 '/api/v1/videos', 44 '/api/v1/videos',
45 '/api/v1/search/videos' 45 '/api/v1/search/videos',
46 '/api/v1/users/me/subscriptions/videos'
46 ] 47 ]
47 48
48 for (const path of paths) { 49 for (const path of paths) {
diff --git a/server/tests/api/users/user-subscriptions.ts b/server/tests/api/users/user-subscriptions.ts
index b45cfe67e..ad2b82a4a 100644
--- a/server/tests/api/users/user-subscriptions.ts
+++ b/server/tests/api/users/user-subscriptions.ts
@@ -167,14 +167,14 @@ describe('Test users subscriptions', function () {
167 167
168 it('Should list subscription videos', async function () { 168 it('Should list subscription videos', async function () {
169 { 169 {
170 const body = await command.listVideos() 170 const body = await servers[0].videos.listMySubscriptionVideos()
171 expect(body.total).to.equal(0) 171 expect(body.total).to.equal(0)
172 expect(body.data).to.be.an('array') 172 expect(body.data).to.be.an('array')
173 expect(body.data).to.have.lengthOf(0) 173 expect(body.data).to.have.lengthOf(0)
174 } 174 }
175 175
176 { 176 {
177 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 177 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
178 expect(body.total).to.equal(3) 178 expect(body.total).to.equal(3)
179 179
180 const videos = body.data 180 const videos = body.data
@@ -185,6 +185,17 @@ describe('Test users subscriptions', function () {
185 expect(videos[1].name).to.equal('video 2-3') 185 expect(videos[1].name).to.equal('video 2-3')
186 expect(videos[2].name).to.equal('video server 3 added after follow') 186 expect(videos[2].name).to.equal('video server 3 added after follow')
187 } 187 }
188
189 {
190 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, count: 1, start: 1 })
191 expect(body.total).to.equal(3)
192
193 const videos = body.data
194 expect(videos).to.be.an('array')
195 expect(videos).to.have.lengthOf(1)
196
197 expect(videos[0].name).to.equal('video 2-3')
198 }
188 }) 199 })
189 200
190 it('Should upload a video by root on server 1 and see it in the subscription videos', async function () { 201 it('Should upload a video by root on server 1 and see it in the subscription videos', async function () {
@@ -196,14 +207,14 @@ describe('Test users subscriptions', function () {
196 await waitJobs(servers) 207 await waitJobs(servers)
197 208
198 { 209 {
199 const body = await command.listVideos() 210 const body = await servers[0].videos.listMySubscriptionVideos()
200 expect(body.total).to.equal(0) 211 expect(body.total).to.equal(0)
201 expect(body.data).to.be.an('array') 212 expect(body.data).to.be.an('array')
202 expect(body.data).to.have.lengthOf(0) 213 expect(body.data).to.have.lengthOf(0)
203 } 214 }
204 215
205 { 216 {
206 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 217 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
207 expect(body.total).to.equal(4) 218 expect(body.total).to.equal(4)
208 219
209 const videos = body.data 220 const videos = body.data
@@ -264,14 +275,14 @@ describe('Test users subscriptions', function () {
264 275
265 it('Should still list subscription videos', async function () { 276 it('Should still list subscription videos', async function () {
266 { 277 {
267 const body = await command.listVideos() 278 const body = await servers[0].videos.listMySubscriptionVideos()
268 expect(body.total).to.equal(0) 279 expect(body.total).to.equal(0)
269 expect(body.data).to.be.an('array') 280 expect(body.data).to.be.an('array')
270 expect(body.data).to.have.lengthOf(0) 281 expect(body.data).to.have.lengthOf(0)
271 } 282 }
272 283
273 { 284 {
274 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 285 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
275 expect(body.total).to.equal(4) 286 expect(body.total).to.equal(4)
276 287
277 const videos = body.data 288 const videos = body.data
@@ -295,7 +306,7 @@ describe('Test users subscriptions', function () {
295 306
296 await waitJobs(servers) 307 await waitJobs(servers)
297 308
298 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 309 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
299 expect(body.data[2].name).to.equal('video server 3 added after follow updated') 310 expect(body.data[2].name).to.equal('video server 3 added after follow updated')
300 }) 311 })
301 }) 312 })
@@ -311,7 +322,7 @@ describe('Test users subscriptions', function () {
311 }) 322 })
312 323
313 it('Should not display its videos anymore', async function () { 324 it('Should not display its videos anymore', async function () {
314 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 325 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
315 expect(body.total).to.equal(1) 326 expect(body.total).to.equal(1)
316 327
317 const videos = body.data 328 const videos = body.data
@@ -360,7 +371,7 @@ describe('Test users subscriptions', function () {
360 await waitJobs(servers) 371 await waitJobs(servers)
361 372
362 { 373 {
363 const body = await command.listVideos({ token: users[0].accessToken, sort: 'createdAt' }) 374 const body = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken, sort: 'createdAt' })
364 expect(body.total).to.equal(3) 375 expect(body.total).to.equal(3)
365 376
366 const videos = body.data 377 const videos = body.data
@@ -569,13 +580,13 @@ describe('Test users subscriptions', function () {
569 await waitJobs(servers) 580 await waitJobs(servers)
570 581
571 { 582 {
572 const { data } = await command.listVideos({ token: users[0].accessToken }) 583 const { data } = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken })
573 expect(data.find(v => v.name === 'internal')).to.not.exist 584 expect(data.find(v => v.name === 'internal')).to.not.exist
574 } 585 }
575 }) 586 })
576 587
577 it('Should see internal from local user', async function () { 588 it('Should see internal from local user', async function () {
578 const { data } = await servers[2].subscriptions.listVideos({ token: servers[2].accessToken }) 589 const { data } = await servers[2].videos.listMySubscriptionVideos({ token: servers[2].accessToken })
579 expect(data.find(v => v.name === 'internal')).to.exist 590 expect(data.find(v => v.name === 'internal')).to.exist
580 }) 591 })
581 592
@@ -586,12 +597,12 @@ describe('Test users subscriptions', function () {
586 await waitJobs(servers) 597 await waitJobs(servers)
587 598
588 { 599 {
589 const { data } = await command.listVideos({ token: users[0].accessToken }) 600 const { data } = await servers[0].videos.listMySubscriptionVideos({ token: users[0].accessToken })
590 expect(data.find(v => v.name === 'private')).to.not.exist 601 expect(data.find(v => v.name === 'private')).to.not.exist
591 } 602 }
592 603
593 { 604 {
594 const { data } = await servers[2].subscriptions.listVideos({ token: servers[2].accessToken }) 605 const { data } = await servers[2].videos.listMySubscriptionVideos({ token: servers[2].accessToken })
595 expect(data.find(v => v.name === 'private')).to.not.exist 606 expect(data.find(v => v.name === 'private')).to.not.exist
596 } 607 }
597 }) 608 })
diff --git a/server/tests/api/videos/videos-common-filters.ts b/server/tests/api/videos/videos-common-filters.ts
index 160091861..1ab78ac49 100644
--- a/server/tests/api/videos/videos-common-filters.ts
+++ b/server/tests/api/videos/videos-common-filters.ts
@@ -20,6 +20,8 @@ describe('Test videos filter', function () {
20 let paths: string[] 20 let paths: string[]
21 let remotePaths: string[] 21 let remotePaths: string[]
22 22
23 const subscriptionVideosPath = '/api/v1/users/me/subscriptions/videos'
24
23 // --------------------------------------------------------------- 25 // ---------------------------------------------------------------
24 26
25 before(async function () { 27 before(async function () {
@@ -49,6 +51,9 @@ describe('Test videos filter', function () {
49 const attributes = { name: 'private ' + server.serverNumber, privacy: VideoPrivacy.PRIVATE } 51 const attributes = { name: 'private ' + server.serverNumber, privacy: VideoPrivacy.PRIVATE }
50 await server.videos.upload({ attributes }) 52 await server.videos.upload({ attributes })
51 } 53 }
54
55 // Subscribing to itself
56 await server.subscriptions.add({ targetUri: 'root_channel@' + server.host })
52 } 57 }
53 58
54 await doubleFollow(servers[0], servers[1]) 59 await doubleFollow(servers[0], servers[1])
@@ -57,7 +62,8 @@ describe('Test videos filter', function () {
57 `/api/v1/video-channels/root_channel/videos`, 62 `/api/v1/video-channels/root_channel/videos`,
58 `/api/v1/accounts/root/videos`, 63 `/api/v1/accounts/root/videos`,
59 '/api/v1/videos', 64 '/api/v1/videos',
60 '/api/v1/search/videos' 65 '/api/v1/search/videos',
66 subscriptionVideosPath
61 ] 67 ]
62 68
63 remotePaths = [ 69 remotePaths = [
@@ -70,10 +76,20 @@ describe('Test videos filter', function () {
70 76
71 describe('Check deprecated videos filter', function () { 77 describe('Check deprecated videos filter', function () {
72 78
73 async function getVideosNames (server: PeerTubeServer, token: string, filter: string, expectedStatus = HttpStatusCode.OK_200) { 79 async function getVideosNames (options: {
80 server: PeerTubeServer
81 token: string
82 filter: string
83 skipSubscription?: boolean
84 expectedStatus?: HttpStatusCode
85 }) {
86 const { server, token, filter, skipSubscription = false, expectedStatus = HttpStatusCode.OK_200 } = options
87
74 const videosResults: Video[][] = [] 88 const videosResults: Video[][] = []
75 89
76 for (const path of paths) { 90 for (const path of paths) {
91 if (skipSubscription && path === subscriptionVideosPath) continue
92
77 const res = await makeGetRequest({ 93 const res = await makeGetRequest({
78 url: server.url, 94 url: server.url,
79 path, 95 path,
@@ -93,7 +109,7 @@ describe('Test videos filter', function () {
93 109
94 it('Should display local videos', async function () { 110 it('Should display local videos', async function () {
95 for (const server of servers) { 111 for (const server of servers) {
96 const namesResults = await getVideosNames(server, server.accessToken, 'local') 112 const namesResults = await getVideosNames({ server, token: server.accessToken, filter: 'local' })
97 for (const names of namesResults) { 113 for (const names of namesResults) {
98 expect(names).to.have.lengthOf(1) 114 expect(names).to.have.lengthOf(1)
99 expect(names[0]).to.equal('public ' + server.serverNumber) 115 expect(names[0]).to.equal('public ' + server.serverNumber)
@@ -105,7 +121,7 @@ describe('Test videos filter', function () {
105 for (const server of servers) { 121 for (const server of servers) {
106 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) { 122 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
107 123
108 const namesResults = await getVideosNames(server, token, 'all-local') 124 const namesResults = await getVideosNames({ server, token, filter: 'all-local', skipSubscription: true })
109 for (const names of namesResults) { 125 for (const names of namesResults) {
110 expect(names).to.have.lengthOf(3) 126 expect(names).to.have.lengthOf(3)
111 127
@@ -121,7 +137,7 @@ describe('Test videos filter', function () {
121 for (const server of servers) { 137 for (const server of servers) {
122 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) { 138 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
123 139
124 const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames(server, token, 'all') 140 const [ channelVideos, accountVideos, videos, searchVideos ] = await getVideosNames({ server, token, filter: 'all' })
125 expect(channelVideos).to.have.lengthOf(3) 141 expect(channelVideos).to.have.lengthOf(3)
126 expect(accountVideos).to.have.lengthOf(3) 142 expect(accountVideos).to.have.lengthOf(3)
127 143
@@ -162,17 +178,23 @@ describe('Test videos filter', function () {
162 return res.body.data as Video[] 178 return res.body.data as Video[]
163 } 179 }
164 180
165 async function getVideosNames (options: { 181 async function getVideosNames (
166 server: PeerTubeServer 182 options: {
167 isLocal?: boolean 183 server: PeerTubeServer
168 include?: VideoInclude 184 isLocal?: boolean
169 privacyOneOf?: VideoPrivacy[] 185 include?: VideoInclude
170 token?: string 186 privacyOneOf?: VideoPrivacy[]
171 expectedStatus?: HttpStatusCode 187 token?: string
172 }) { 188 expectedStatus?: HttpStatusCode
189 skipSubscription?: boolean
190 }
191 ) {
192 const { skipSubscription = false } = options
173 const videosResults: string[][] = [] 193 const videosResults: string[][] = []
174 194
175 for (const path of paths) { 195 for (const path of paths) {
196 if (skipSubscription && path === subscriptionVideosPath) continue
197
176 const videos = await listVideos({ ...options, path }) 198 const videos = await listVideos({ ...options, path })
177 199
178 videosResults.push(videos.map(v => v.name)) 200 videosResults.push(videos.map(v => v.name))
@@ -196,12 +218,15 @@ describe('Test videos filter', function () {
196 for (const server of servers) { 218 for (const server of servers) {
197 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) { 219 for (const token of [ server.accessToken, server['moderatorAccessToken'] ]) {
198 220
199 const namesResults = await getVideosNames({ 221 const namesResults = await getVideosNames(
200 server, 222 {
201 token, 223 server,
202 isLocal: true, 224 token,
203 privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ] 225 isLocal: true,
204 }) 226 privacyOneOf: [ VideoPrivacy.UNLISTED, VideoPrivacy.PUBLIC, VideoPrivacy.PRIVATE ],
227 skipSubscription: true
228 }
229 )
205 230
206 for (const names of namesResults) { 231 for (const names of namesResults) {
207 expect(names).to.have.lengthOf(3) 232 expect(names).to.have.lengthOf(3)
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 7345f728a..ecd1badc1 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -387,7 +387,7 @@ describe('Test syndication feeds', () => {
387 } 387 }
388 388
389 { 389 {
390 const body = await servers[0].subscriptions.listVideos({ token: feeduserAccessToken }) 390 const body = await servers[0].videos.listMySubscriptionVideos({ token: feeduserAccessToken })
391 expect(body.total).to.equal(0) 391 expect(body.total).to.equal(0)
392 392
393 const query = { accountId: feeduserAccountId, token: feeduserFeedToken } 393 const query = { accountId: feeduserAccountId, token: feeduserFeedToken }
@@ -408,7 +408,7 @@ describe('Test syndication feeds', () => {
408 }) 408 })
409 409
410 it('Should list no videos for a user with videos but no subscriptions', async function () { 410 it('Should list no videos for a user with videos but no subscriptions', async function () {
411 const body = await servers[0].subscriptions.listVideos({ token: userAccessToken }) 411 const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken })
412 expect(body.total).to.equal(0) 412 expect(body.total).to.equal(0)
413 413
414 const query = { accountId: userAccountId, token: userFeedToken } 414 const query = { accountId: userAccountId, token: userFeedToken }
@@ -424,7 +424,7 @@ describe('Test syndication feeds', () => {
424 await waitJobs(servers) 424 await waitJobs(servers)
425 425
426 { 426 {
427 const body = await servers[0].subscriptions.listVideos({ token: userAccessToken }) 427 const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken })
428 expect(body.total).to.equal(1) 428 expect(body.total).to.equal(1)
429 expect(body.data[0].name).to.equal('user video') 429 expect(body.data[0].name).to.equal('user video')
430 430
@@ -442,7 +442,7 @@ describe('Test syndication feeds', () => {
442 await waitJobs(servers) 442 await waitJobs(servers)
443 443
444 { 444 {
445 const body = await servers[0].subscriptions.listVideos({ token: userAccessToken }) 445 const body = await servers[0].videos.listMySubscriptionVideos({ token: userAccessToken })
446 expect(body.total).to.equal(2, 'there should be 2 videos part of the subscription') 446 expect(body.total).to.equal(2, 'there should be 2 videos part of the subscription')
447 447
448 const query = { accountId: userAccountId, token: userFeedToken } 448 const query = { accountId: userAccountId, token: userFeedToken }
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js
index 8b918b634..f01da0226 100644
--- a/server/tests/fixtures/peertube-plugin-test/main.js
+++ b/server/tests/fixtures/peertube-plugin-test/main.js
@@ -91,7 +91,7 @@ async function register ({ registerHook, registerSetting, settingsManager, stora
91 91
92 registerHook({ 92 registerHook({
93 target: 'filter:api.user.me.subscription-videos.list.params', 93 target: 'filter:api.user.me.subscription-videos.list.params',
94 handler: obj => Object.assign({}, obj, { count: 1 }) 94 handler: obj => addToCount(obj)
95 }) 95 })
96 96
97 registerHook({ 97 registerHook({
diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts
index 6bd38cf65..a7e052d06 100644
--- a/server/tests/plugins/filter-hooks.ts
+++ b/server/tests/plugins/filter-hooks.ts
@@ -155,14 +155,14 @@ describe('Test plugin filter hooks', function () {
155 }) 155 })
156 156
157 it('Should run filter:api.user.me.subscription-videos.list.params', async function () { 157 it('Should run filter:api.user.me.subscription-videos.list.params', async function () {
158 const { data } = await servers[0].subscriptions.listVideos() 158 const { data } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 })
159 159
160 // 1 plugin set the count parameter to 1 160 // 1 plugin do +1 to the count parameter
161 expect(data).to.have.lengthOf(1) 161 expect(data).to.have.lengthOf(3)
162 }) 162 })
163 163
164 it('Should run filter:api.user.me.subscription-videos.list.result', async function () { 164 it('Should run filter:api.user.me.subscription-videos.list.result', async function () {
165 const { total } = await servers[0].subscriptions.listVideos() 165 const { total } = await servers[0].videos.listMySubscriptionVideos({ start: 0, count: 2 })
166 166
167 // Plugin do +4 to the total result 167 // Plugin do +4 to the total result
168 expect(total).to.equal(14) 168 expect(total).to.equal(14)
diff --git a/shared/server-commands/users/subscriptions-command.ts b/shared/server-commands/users/subscriptions-command.ts
index edc60e612..b92f037f8 100644
--- a/shared/server-commands/users/subscriptions-command.ts
+++ b/shared/server-commands/users/subscriptions-command.ts
@@ -1,4 +1,4 @@
1import { HttpStatusCode, ResultList, Video, VideoChannel } from '@shared/models' 1import { HttpStatusCode, ResultList, VideoChannel } from '@shared/models'
2import { AbstractCommand, OverrideCommandOptions } from '../shared' 2import { AbstractCommand, OverrideCommandOptions } from '../shared'
3 3
4export class SubscriptionsCommand extends AbstractCommand { 4export class SubscriptionsCommand extends AbstractCommand {
@@ -38,22 +38,6 @@ export class SubscriptionsCommand extends AbstractCommand {
38 }) 38 })
39 } 39 }
40 40
41 listVideos (options: OverrideCommandOptions & {
42 sort?: string // default -createdAt
43 } = {}) {
44 const { sort = '-createdAt' } = options
45 const path = '/api/v1/users/me/subscriptions/videos'
46
47 return this.getRequestBody<ResultList<Video>>({
48 ...options,
49
50 path,
51 query: { sort },
52 implicitToken: true,
53 defaultExpectedStatus: HttpStatusCode.OK_200
54 })
55 }
56
57 get (options: OverrideCommandOptions & { 41 get (options: OverrideCommandOptions & {
58 uri: string 42 uri: string
59 }) { 43 }) {
diff --git a/shared/server-commands/videos/videos-command.ts b/shared/server-commands/videos/videos-command.ts
index 590244484..b5df9c325 100644
--- a/shared/server-commands/videos/videos-command.ts
+++ b/shared/server-commands/videos/videos-command.ts
@@ -210,6 +210,20 @@ export class VideosCommand extends AbstractCommand {
210 }) 210 })
211 } 211 }
212 212
213 listMySubscriptionVideos (options: OverrideCommandOptions & VideosCommonQuery = {}) {
214 const { sort = '-createdAt' } = options
215 const path = '/api/v1/users/me/subscriptions/videos'
216
217 return this.getRequestBody<ResultList<Video>>({
218 ...options,
219
220 path,
221 query: { sort, ...this.buildListQuery(options) },
222 implicitToken: true,
223 defaultExpectedStatus: HttpStatusCode.OK_200
224 })
225 }
226
213 // --------------------------------------------------------------------------- 227 // ---------------------------------------------------------------------------
214 228
215 list (options: OverrideCommandOptions & VideosCommonQuery = {}) { 229 list (options: OverrideCommandOptions & VideosCommonQuery = {}) {