Move to eslint
[oweals/peertube.git] / server / tests / api / videos / video-captions.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import * as chai from 'chai'
4 import 'mocha'
5 import {
6   checkVideoFilesWereRemoved,
7   cleanupTests,
8   doubleFollow,
9   flushAndRunMultipleServers,
10   removeVideo,
11   uploadVideo,
12   wait
13 } from '../../../../shared/extra-utils'
14 import { ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index'
15 import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
16 import {
17   createVideoCaption,
18   deleteVideoCaption,
19   listVideoCaptions,
20   testCaptionFile
21 } from '../../../../shared/extra-utils/videos/video-captions'
22 import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
23
24 const expect = chai.expect
25
26 describe('Test video captions', function () {
27   let servers: ServerInfo[]
28   let videoUUID: string
29
30   before(async function () {
31     this.timeout(30000)
32
33     servers = await flushAndRunMultipleServers(2)
34
35     await setAccessTokensToServers(servers)
36     await doubleFollow(servers[0], servers[1])
37
38     await waitJobs(servers)
39
40     const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'my video name' })
41     videoUUID = res.body.video.uuid
42
43     await waitJobs(servers)
44   })
45
46   it('Should list the captions and return an empty list', async function () {
47     for (const server of servers) {
48       const res = await listVideoCaptions(server.url, videoUUID)
49       expect(res.body.total).to.equal(0)
50       expect(res.body.data).to.have.lengthOf(0)
51     }
52   })
53
54   it('Should create two new captions', async function () {
55     this.timeout(30000)
56
57     await createVideoCaption({
58       url: servers[0].url,
59       accessToken: servers[0].accessToken,
60       language: 'ar',
61       videoId: videoUUID,
62       fixture: 'subtitle-good1.vtt'
63     })
64
65     await createVideoCaption({
66       url: servers[0].url,
67       accessToken: servers[0].accessToken,
68       language: 'zh',
69       videoId: videoUUID,
70       fixture: 'subtitle-good2.vtt',
71       mimeType: 'application/octet-stream'
72     })
73
74     await waitJobs(servers)
75   })
76
77   it('Should list these uploaded captions', async function () {
78     for (const server of servers) {
79       const res = await listVideoCaptions(server.url, videoUUID)
80       expect(res.body.total).to.equal(2)
81       expect(res.body.data).to.have.lengthOf(2)
82
83       const caption1: VideoCaption = res.body.data[0]
84       expect(caption1.language.id).to.equal('ar')
85       expect(caption1.language.label).to.equal('Arabic')
86       expect(caption1.captionPath).to.equal('/static/video-captions/' + videoUUID + '-ar.vtt')
87       await testCaptionFile(server.url, caption1.captionPath, 'Subtitle good 1.')
88
89       const caption2: VideoCaption = res.body.data[1]
90       expect(caption2.language.id).to.equal('zh')
91       expect(caption2.language.label).to.equal('Chinese')
92       expect(caption2.captionPath).to.equal('/static/video-captions/' + videoUUID + '-zh.vtt')
93       await testCaptionFile(server.url, caption2.captionPath, 'Subtitle good 2.')
94     }
95   })
96
97   it('Should replace an existing caption', async function () {
98     this.timeout(30000)
99
100     await createVideoCaption({
101       url: servers[0].url,
102       accessToken: servers[0].accessToken,
103       language: 'ar',
104       videoId: videoUUID,
105       fixture: 'subtitle-good2.vtt'
106     })
107
108     await waitJobs(servers)
109   })
110
111   it('Should have this caption updated', async function () {
112     for (const server of servers) {
113       const res = await listVideoCaptions(server.url, videoUUID)
114       expect(res.body.total).to.equal(2)
115       expect(res.body.data).to.have.lengthOf(2)
116
117       const caption1: VideoCaption = res.body.data[0]
118       expect(caption1.language.id).to.equal('ar')
119       expect(caption1.language.label).to.equal('Arabic')
120       expect(caption1.captionPath).to.equal('/static/video-captions/' + videoUUID + '-ar.vtt')
121       await testCaptionFile(server.url, caption1.captionPath, 'Subtitle good 2.')
122     }
123   })
124
125   it('Should replace an existing caption with a srt file and convert it', async function () {
126     this.timeout(30000)
127
128     await createVideoCaption({
129       url: servers[0].url,
130       accessToken: servers[0].accessToken,
131       language: 'ar',
132       videoId: videoUUID,
133       fixture: 'subtitle-good.srt'
134     })
135
136     await waitJobs(servers)
137
138     // Cache invalidation
139     await wait(3000)
140   })
141
142   it('Should have this caption updated and converted', async function () {
143     for (const server of servers) {
144       const res = await listVideoCaptions(server.url, videoUUID)
145       expect(res.body.total).to.equal(2)
146       expect(res.body.data).to.have.lengthOf(2)
147
148       const caption1: VideoCaption = res.body.data[0]
149       expect(caption1.language.id).to.equal('ar')
150       expect(caption1.language.label).to.equal('Arabic')
151       expect(caption1.captionPath).to.equal('/static/video-captions/' + videoUUID + '-ar.vtt')
152
153       const expected = 'WEBVTT FILE\r\n' +
154         '\r\n' +
155         '1\r\n' +
156         '00:00:01.600 --> 00:00:04.200\r\n' +
157         'English (US)\r\n' +
158         '\r\n' +
159         '2\r\n' +
160         '00:00:05.900 --> 00:00:07.999\r\n' +
161         'This is a subtitle in American English\r\n' +
162         '\r\n' +
163         '3\r\n' +
164         '00:00:10.000 --> 00:00:14.000\r\n' +
165         'Adding subtitles is very easy to do\r\n'
166       await testCaptionFile(server.url, caption1.captionPath, expected)
167     }
168   })
169
170   it('Should remove one caption', async function () {
171     this.timeout(30000)
172
173     await deleteVideoCaption(servers[0].url, servers[0].accessToken, videoUUID, 'ar')
174
175     await waitJobs(servers)
176   })
177
178   it('Should only list the caption that was not deleted', async function () {
179     for (const server of servers) {
180       const res = await listVideoCaptions(server.url, videoUUID)
181       expect(res.body.total).to.equal(1)
182       expect(res.body.data).to.have.lengthOf(1)
183
184       const caption: VideoCaption = res.body.data[0]
185
186       expect(caption.language.id).to.equal('zh')
187       expect(caption.language.label).to.equal('Chinese')
188       expect(caption.captionPath).to.equal('/static/video-captions/' + videoUUID + '-zh.vtt')
189       await testCaptionFile(server.url, caption.captionPath, 'Subtitle good 2.')
190     }
191   })
192
193   it('Should remove the video, and thus all video captions', async function () {
194     await removeVideo(servers[0].url, servers[0].accessToken, videoUUID)
195
196     await checkVideoFilesWereRemoved(videoUUID, 1)
197   })
198
199   after(async function () {
200     await cleanupTests(servers)
201   })
202 })