1#!/usr/bin/python 2 3import re 4import unittest 5 6import napi.fs 7import napi.sandbox 8import napi.subtitles 9import napi.testcase 10 11class LegacyApiModeTest(napi.testcase.NapiTestCase): 12 13 def test_ifFailsCorrectlyIfSubsUnavailable(self): 14 """ 15 Brief: 16 Verify if handles subs acquisition failure without any errors 17 18 Procedure: 19 1. Prepare media file 20 2. Program napi mock to respond with no data and 404 HTTP Status 21 3. Call napi.sh in legacy mode with id = pynapi 22 23 Expected Results: 24 No processing errors should be detected. Normal error response handling 25 should be done. No files should be produced afterwards. 26 27 """ 28 media = None 29 with napi.sandbox.Sandbox() as sandbox: 30 # generate a media file 31 media = self.videoAssets.prepareRandomMedia(sandbox) 32 33 # program napiprojekt mock 34 self.napiMock.programPlainRequest() 35 36 # call napi 37 self.isStderrExpected = True 38 self.napiScan('-i', 'pynapi', media['path']) 39 fs = napi.fs.Filesystem(media) 40 41 # check assertions 42 req = self.napiMock.getRequest() 43 self.assertEquals(req.method, "GET") 44 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 45 46 self.assertTrue(self.output.hasErrors()) 47 self.assertTrue(self.output.stderrContains( 48 re.compile(r'nie udalo sie pobrac napisow'))) 49 self.assertFalse(fs.subtitlesExists()) 50 51 52 def test_ifFailsCorrectlyIfResponseIsTooShort(self): 53 """ 54 Brief: Verify if napi fails responses which are awkwardly short. 55 Procedure: 56 1. Prepare a media file 57 2. Program napi mock to respond with: 58 4 59 NPc0 60 0 61 62 This response most of the time indicates lack of requested subtitles. 63 64 Expected Results: 65 No processing errors should be detected. Normal error response handling 66 should be done. No files should be produced afterwards. 67 """ 68 media = None 69 with napi.sandbox.Sandbox() as sandbox: 70 # generate a media file 71 media = self.videoAssets.prepareRandomMedia(sandbox) 72 73 # program napiprojekt mock 74 self.napiMock.programPlainRequest( 75 napi.subtitles.Subtitles.fromString( 76 media['asset'], '4\nNPc0\n0')) 77 78 # call napi 79 self.isStderrExpected = True 80 self.napiScan('-i', 'pynapi', media['path']) 81 fs = napi.fs.Filesystem(media) 82 83 # check assertions 84 req = self.napiMock.getRequest() 85 self.assertEquals(req.method, "GET") 86 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 87 88 self.assertTrue(self.output.hasErrors()) 89 self.assertTrue(self.output.stdoutContains( 90 re.compile(r'plik uszkodzony. niepoprawna ilosc linii'))) 91 self.assertFalse(fs.subtitlesExists()) 92 93 94 def test_ifFetchesSingleCompressedFile(self): 95 """ 96 Brief: 97 Verify if napi works for single media files in legacy mode (other) 98 99 Procedure: 100 1. Prepare subtitles media 101 2. Prepare video media 102 3. Program napi mock to respond with plain compressed subs HTTP 103 response for GET request 104 4. Call napi.sh in legacy mode with id = other 105 106 Expected Results: 107 napi.sh should perform a GET request to napi.sh using legacy API. 108 Subtitles file should exist afterwards. 109 """ 110 media = None 111 subsMedia = None 112 with napi.sandbox.Sandbox() as sandbox: 113 # generate a media file 114 media = self.videoAssets.prepareRandomMedia(sandbox) 115 subsMedia = self.subtitlesAssets.prepareRandomMedia(sandbox) 116 117 # program napiprojekt mock 118 self.napiMock.programPlainRequest( 119 napi.subtitles.CompressedSubtitles.fromFile( 120 media['asset'], subsMedia['path'])) 121 122 # call napi 123 self.napiScan('-i', 'other', media['path']) 124 fs = napi.fs.Filesystem(media) 125 126 # check assertions 127 req = self.napiMock.getRequest() 128 self.assertEquals(req.method, "GET") 129 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 130 131 self.assertTrue(self.output.stdoutContains( 132 re.compile(r'napisy pobrano pomyslnie'))) 133 134 self.assertTrue(fs.subtitlesExists()) 135 136 def test_ifFetchesSingleMediaFile(self): 137 """ 138 Brief: 139 Verify if napi works for single media files in legacy mode (pynapi) 140 141 Procedure: 142 1. Prepare subtitles media 143 2. Prepare video media 144 3. Program napi mock to respond with plain subs HTTP response for GET 145 request 146 4. Call napi.sh in legacy mode with id = pynapi 147 148 Expected Results: 149 napi.sh should perform a GET request to napi.sh using legacy API. 150 Subtitles file should exist afterwards. 151 """ 152 media = None 153 subsMedia = None 154 with napi.sandbox.Sandbox() as sandbox: 155 # generate a media file 156 media = self.videoAssets.prepareRandomMedia(sandbox) 157 subsMedia = self.subtitlesAssets.prepareRandomMedia(sandbox) 158 159 # program napiprojekt mock 160 self.napiMock.programPlainRequest( 161 napi.subtitles.Subtitles.fromFile( 162 media['asset'], subsMedia['path'])) 163 164 # call napi 165 self.napiScan('-i', 'pynapi', media['path']) 166 fs = napi.fs.Filesystem(media) 167 168 # check assertions 169 req = self.napiMock.getRequest() 170 self.assertEquals(req.method, "GET") 171 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 172 173 self.assertTrue(self.output.stdoutContains( 174 re.compile(r'napisy pobrano pomyslnie'))) 175 176 self.assertTrue(fs.subtitlesExists()) 177 178 def test_ifScanWorksForDirectory(self): 179 """ 180 Brief: Verify if napi works for specified media directory 181 Procedure: 182 1. Prepare sandbox and media files with random names 183 2. Program napiprojekt mock to reply with success for some of the media 184 files and failure for the others. 185 3. Call napi with the path to the sandbox 186 187 Expected Results: 188 Napi should successfully download subtitles for media files for which 189 napiprojekt mock has been programmed to return a successful result. 190 """ 191 mediasAvailable = [] 192 mediasUnavailable = [] 193 with napi.sandbox.Sandbox() as sandbox: 194 195 nAvailable = 3 196 nUnavailable = 3 197 nTotal = nAvailable + nUnavailable 198 199 # prepare responses for available subs 200 for _ in xrange(nAvailable): 201 media = self.videoAssets.prepareRandomMedia(sandbox) 202 subsMedia = self.subtitlesAssets.prepareRandomMedia(sandbox) 203 mediasAvailable.append(media) 204 205 # program http mock 206 self.napiMock.programPlainRequest( 207 napi.subtitles.Subtitles.fromFile( 208 media['asset'], subsMedia['path'])) 209 210 # prepare responses for unavailable subs 211 for _ in xrange(nUnavailable): 212 media = self.videoAssets.prepareRandomMedia(sandbox) 213 mediasUnavailable.append(media) 214 self.napiMock.programPlainRequest() 215 216 # call napi 217 self.isStderrExpected = True 218 self.napiScan('--stats', '-i', 'pynapi', sandbox.path) 219 220 # check assertions 221 for n in xrange(nTotal): 222 req = self.napiMock.getRequest(n) 223 self.assertEquals(req.method, "GET") 224 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 225 226 # check statistics 227 stats = self.output.parseNapiStats() 228 self.assertEquals(nAvailable, stats['ok']) 229 self.assertEquals(nUnavailable, stats['unav']) 230 self.assertEquals(nTotal, stats['total']) 231 232 allMedia = mediasAvailable + mediasUnavailable 233 self.assertEqual(nAvailable, sum([ 1 for m in allMedia 234 if napi.fs.Filesystem(m).subtitlesExists()])) 235 236 def test_ifSkippingWorks(self): 237 """ 238 Brief: 239 This test verifies if napi is skipping the subtitles download for media 240 files for which the subtitles file seems to already exist in the 241 filesystem. 242 243 Procedure: 244 1. Prepare a set of media files. 245 2. Program napiprojekt.pl mock to respond with success response. 246 3. Call napi -s. 247 4. Call napi -s again. 248 249 Expected Results: 250 Check if it skipped the download for media files for which subtitles 251 have been already obtained. 252 253 """ 254 medias = [] 255 with napi.sandbox.Sandbox() as sandbox: 256 257 nTotal = 4 258 nAttempts = 3 259 260 # prepare responses for available subs 261 for _ in xrange(nTotal): 262 media = self.videoAssets.prepareRandomMedia(sandbox) 263 subsMedia = self.subtitlesAssets.prepareRandomMedia(sandbox) 264 medias.append(media) 265 266 # program http mock 267 self.napiMock.programPlainRequest( 268 napi.subtitles.CompressedSubtitles.fromFile( 269 media['asset'], subsMedia['path']), 270 200, 271 nAttempts) 272 273 for attempt in xrange(nAttempts): 274 # call napi 275 self.napiScan('--stats', '-s', '-i', 'pynapi', sandbox.path) 276 277 stats = self.output.parseNapiStats() 278 if attempt == 0: 279 for n in xrange(nTotal): 280 req = self.napiMock.getRequest(n + nTotal*attempt) 281 self.assertTrue(req) 282 self.assertEquals(req.method, "GET") 283 self.assertTrue(re.match(r'/unit_napisy/dl\.php\?', req.url)) 284 285 # check statistics 286 self.assertEquals(nTotal, stats['ok']) 287 self.assertEquals(0, stats['skip']) 288 self.assertEquals(0, stats['unav']) 289 self.assertEquals(nTotal, stats['total']) 290 else: 291 for n in xrange(nTotal): 292 req = self.napiMock.getRequest(n + nTotal*attempt) 293 self.assertFalse(req) 294 295 # check statistics 296 self.assertEquals(0, stats['ok']) 297 self.assertEquals(nTotal, stats['skip']) 298 self.assertEquals(0, stats['unav']) 299 self.assertEquals(nTotal, stats['total']) 300 301 self.assertEqual(nTotal, sum([ 1 for m in medias 302 if napi.fs.Filesystem(m).subtitlesExists()])) 303 304# # Brief: 305# # 306# # Verify if napi works for specified media directory and skips downloading if the subtitles file already exist 307# # 308# # Preconditions: 309# # - prepare a set of test files and a test directory structure 310# # - the subtitles files should exist as well 311# # 312# # Procedure: 313# # - Call napi with the path to the pre-prepared media directory 314# # 315# # Expected results: 316# # - napi shouldn't download the subtitles for the media files (for which they are available) if it detects that the 317# # subtitles file already exist 318# # 319# $output = NapiTest::qx_napi($shell, " --id pynapi --stats -s " . $NapiTest::testspace); 320# %output = NapiTest::parse_summary($output); 321# is ($output{skip}, $total_available, "Total number of skipped"); 322# is ($output{skip} + $output{unav}, $output{total}, "Total processed (with skipping)"); 323# is ($output{total}, $total_available + $total_unavailable, "Total processed (with skipping) 2"); 324 325if __name__ == '__main__': 326 napi.testcase.runTests() 327