@pixwel/pixwel-sdk 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.babelrc +3 -0
  2. package/.editorconfig +36 -0
  3. package/.vs/slnx.sqlite +0 -0
  4. package/.vscode/launch.json +0 -0
  5. package/coverage/clover.xml +7 -0
  6. package/coverage/coverage-final.json +1 -0
  7. package/coverage/lcov-report/Ass.js.html +651 -0
  8. package/coverage/lcov-report/Asset.js.html +129 -0
  9. package/coverage/lcov-report/Filename.js.html +849 -0
  10. package/coverage/lcov-report/Ingest.js.html +591 -0
  11. package/coverage/lcov-report/IngestFile.js.html +87 -0
  12. package/coverage/lcov-report/IngestFileDrop.js.html +540 -0
  13. package/coverage/lcov-report/Order.js.html +162 -0
  14. package/coverage/lcov-report/Srt.js.html +333 -0
  15. package/coverage/lcov-report/Sub.js.html +177 -0
  16. package/coverage/lcov-report/TimeFormat.js.html +210 -0
  17. package/coverage/lcov-report/base.css +223 -0
  18. package/coverage/lcov-report/block-navigation.js +63 -0
  19. package/coverage/lcov-report/index.html +84 -0
  20. package/coverage/lcov-report/lib/Filename.js.html +720 -0
  21. package/coverage/lcov-report/lib/index.html +97 -0
  22. package/coverage/lcov-report/prettify.css +1 -0
  23. package/coverage/lcov-report/prettify.js +1 -0
  24. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  25. package/coverage/lcov-report/sorter.js +158 -0
  26. package/coverage/lcov-report/test/index.html +97 -0
  27. package/coverage/lcov-report/test/mocks.js.html +423 -0
  28. package/coverage/lcov.info +0 -0
  29. package/dist/index.js +61 -0
  30. package/dist/src/Ass.js +200 -0
  31. package/dist/src/Asset.js +41 -0
  32. package/dist/src/Filename.js +252 -0
  33. package/dist/src/Ingest.js +200 -0
  34. package/dist/src/IngestFile.js +17 -0
  35. package/dist/src/IngestFileDrop.js +178 -0
  36. package/dist/src/Order.js +58 -0
  37. package/dist/src/Srt.js +102 -0
  38. package/dist/src/Sub.js +42 -0
  39. package/dist/src/TimeFormat.js +48 -0
  40. package/index.js +6 -0
  41. package/package.json +26 -0
  42. package/src/Ass.js +195 -0
  43. package/src/Asset.js +20 -0
  44. package/src/Filename.js +260 -0
  45. package/src/Ingest.js +175 -0
  46. package/src/IngestFile.js +6 -0
  47. package/src/IngestFileDrop.js +157 -0
  48. package/src/Order.js +31 -0
  49. package/src/Srt.js +89 -0
  50. package/src/Sub.js +37 -0
  51. package/src/TimeFormat.js +48 -0
  52. package/src/docs.json +1 -0
  53. package/test/Ass.spec.js +150 -0
  54. package/test/Asset.spec.js +24 -0
  55. package/test/Filename.spec.js +728 -0
  56. package/test/Ingest.spec.js +95 -0
  57. package/test/Srt.spec.js +111 -0
  58. package/test/Sub.spec.js +75 -0
  59. package/test/TimeFormat.spec.js +84 -0
  60. package/test/mocks/mediainfo.mock.js +67 -0
  61. package/test/mocks/mediainfo.png.mock.js +22 -0
  62. package/test/mocks/mocks.js +118 -0
  63. package/test/mocks/prores.mock.js +71 -0
  64. package/test/parse.spec.ts +927 -0
  65. package/tsconfig.json +11 -0
@@ -0,0 +1,927 @@
1
+ import * as parse from '../lib/parse';
2
+ // import * as api from '../common/api';
3
+
4
+ import {
5
+ merge,
6
+ filter,
7
+ whereEq
8
+ } from 'ramda';
9
+
10
+ import {
11
+ each,
12
+ resolve
13
+ } from 'bluebird';
14
+
15
+ describe('parse', () => {
16
+ const input = (data: Object) => merge({
17
+ api: mockApi,
18
+ parts: [],
19
+ tags: [],
20
+ types: [],
21
+ territories: []
22
+ }, data) as parse.Input;
23
+
24
+ var mockApi: any;
25
+
26
+ beforeEach(() => {
27
+ mockApi = jasmine.createSpyObj('api', ['read', 'update']);
28
+ spyOn(api, 'create').and.returnValue(mockApi);
29
+ });
30
+
31
+ describe('.project()', () => {
32
+ var parts = [
33
+ 'PROJECT-A',
34
+ 'ASSET-ONE'
35
+ ];
36
+
37
+ it('matches a Project by `filePrefix` and removes first part', done => {
38
+ mockApi.read.and.callFake(() => resolve([{
39
+ _id: 'projectA',
40
+ filePrefix: 'PROJECT-A'
41
+ }]));
42
+
43
+ parse.project(input({parts}))
44
+ .then(result => {
45
+ expect(mockApi.read).toHaveBeenCalledWith('projects', {
46
+ filePrefix: 'PROJECT-A'
47
+ });
48
+
49
+ expect(result.project).toEqual({_id: 'projectA'});
50
+ expect(result.parts).toEqual(['ASSET-ONE']);
51
+ })
52
+ .finally(done);
53
+ });
54
+ });
55
+
56
+ describe('.type()', () => {
57
+ var types = [{
58
+ name: 'greetings'
59
+ }, {
60
+ name: 'dubbing-refs',
61
+ file: 'DUB-REF'
62
+ }];
63
+
64
+ it('matches a Type by `name`', () => {
65
+ var parts = [
66
+ 'GREETINGS',
67
+ 'TEST-GREETING'
68
+ ];
69
+
70
+ var result = parse.type(input({parts, types}))
71
+ expect(result.asset).toEqual({type: 'greetings'});
72
+ expect(result.parts).toEqual(['TEST-GREETING']);
73
+ });
74
+
75
+ it('matches a Type by `file`', () => {
76
+ var parts = [
77
+ 'DUB-REF',
78
+ 'TEST-DUBBING-REFERENCE'
79
+ ];
80
+
81
+ var result = parse.type(input({parts, types}))
82
+ expect(result.asset).toEqual({type: 'dubbing-refs'});
83
+ expect(result.parts).toEqual(['TEST-DUBBING-REFERENCE']);
84
+ });
85
+ });
86
+
87
+ describe('.trailer()', () => {
88
+ it('does nothing if next filename part is `TR`', () => {
89
+ expect(parse.trailer(input({parts: ['TR']}))).toBeUndefined();
90
+ });
91
+
92
+ it('does nothing when next filename part does not match convention', () => {
93
+ expect(parse.trailer(input({parts: ['FOO']}))).toBeUndefined();
94
+ });
95
+
96
+ it('handles domestic, international and generic trailer types', () => {
97
+ var tests = [{
98
+ part: 'DTR-A',
99
+ name: 'Domestic Trailer A',
100
+ slug: 'domestic-trailer-a',
101
+ type: 'trailer.us'
102
+ }, {
103
+ part: 'DTR-A-CRE-TEST-ONE',
104
+ name: 'Domestic Trailer A - Test One',
105
+ slug: 'domestic-trailer-a-test-one',
106
+ type: 'trailer.us.cre'
107
+ }, {
108
+ part: 'ITR-1',
109
+ name: `Int'l Trailer 1`,
110
+ slug: 'int-l-trailer-1',
111
+ type: 'trailer.intl'
112
+ }, {
113
+ part: 'ITR-1-CRE-TEST-TWO',
114
+ name: `Int'l Trailer 1 - Test Two`,
115
+ slug: 'int-l-trailer-1-test-two',
116
+ type: 'trailer.intl.cre'
117
+ }, {
118
+ part: 'TR-TEST',
119
+ name: 'Test Trailer',
120
+ slug: 'test-trailer',
121
+ type: 'trailer'
122
+ }, {
123
+ part: 'TR-TEST-CRE-GENERIC-TEST-THREE',
124
+ name: 'Test Trailer - Generic Test Three',
125
+ slug: 'test-trailer-generic-test-three',
126
+ type: 'trailer.cre'
127
+ }];
128
+
129
+ tests.forEach(test => {
130
+ var parts = [test.part, 'TAG-TWO'];
131
+ var result = parse.trailer(input({parts}));
132
+
133
+ expect(result.parts).toEqual(['TAG-TWO']);
134
+ expect(result.asset.name).toEqual(test.name);
135
+ expect(result.asset.slug).toEqual(test.slug);
136
+ expect(result.asset.type).toEqual(test.type);
137
+ });
138
+ });
139
+ });
140
+
141
+ describe('.nonTrailer()', () => {
142
+ it('does nothing for `trailer` asset types', () => {
143
+ var types = ['trailer', 'trailer.intl', 'trailer.us'];
144
+
145
+ types.forEach(type => {
146
+ var result = parse.nonTrailer(input({asset: {type}}));
147
+ expect(result).toBeUndefined();
148
+ });
149
+ });
150
+
151
+ it('extracts asset name and slug', () => {
152
+ var parts = [
153
+ 'HELLO-WORLD',
154
+ 'PREVIEW'
155
+ ];
156
+
157
+ var asset = {};
158
+
159
+ var result = parse.nonTrailer(input({parts, asset}));
160
+ expect(result.parts).toEqual(['PREVIEW']);
161
+ expect(result.asset).toEqual({
162
+ name: 'Hello World',
163
+ slug: 'hello-world'
164
+ });
165
+ });
166
+
167
+ it('it normalizes `intl` to `int\'l`', () => {
168
+ var parts = [
169
+ 'HELLO-WORLD-INTL',
170
+ 'PREVIEW'
171
+ ];
172
+
173
+ var asset = {};
174
+
175
+ var result = parse.nonTrailer(input({parts, asset}));
176
+ expect(result.asset).toEqual({
177
+ name: `Hello World Int'l`,
178
+ slug: 'hello-world-int-l'
179
+ });
180
+ });
181
+
182
+ it('normalizes a domestic Asset Type to International', () => {
183
+ var parts = [
184
+ 'HELLO-WORLD-INTL',
185
+ 'PREVIEW'
186
+ ];
187
+
188
+ var asset = {
189
+ type: 'tv-spot.us'
190
+ };
191
+
192
+ var result = parse.nonTrailer(input({parts, asset}));
193
+ expect(result.asset).toEqual({
194
+ name: `Hello World Int'l`,
195
+ slug: 'hello-world-int-l',
196
+ type: 'tv-spot.intl'
197
+ });
198
+ });
199
+
200
+ it('extracts length from Asset Name', () => {
201
+ var parts = [
202
+ 'HELLO-WORLD-30',
203
+ 'PREVIEW'
204
+ ];
205
+
206
+ var asset = {
207
+ type: 'tv-spot.us'
208
+ };
209
+
210
+ var result = parse.nonTrailer(input({parts, asset}));
211
+ expect(result.asset).toEqual({
212
+ name: `Hello World 30`,
213
+ slug: 'hello-world-30',
214
+ type: 'tv-spot.us',
215
+ length: 30
216
+ });
217
+ });
218
+ });
219
+
220
+ describe('.locale()', () => {
221
+ var territories = [{
222
+ languages: [{code: 'ENG'}],
223
+ countries: [{code: 'AU'}]
224
+ }, {
225
+ languages: [{code: 'PFR'}],
226
+ countries: [{code: 'FR'}]
227
+ }, {
228
+ languages: [{code: 'BPO'}],
229
+ countries: [{code: 'BR'}]
230
+ }, {
231
+ languages: [{code: 'LIT'}],
232
+ countries: [{code: 'LT'}]
233
+ }, {
234
+ languages: [{code: 'ENG'}],
235
+ countries: [{code: 'US'}]
236
+ }];
237
+
238
+ it('does nothing if part does not match', () => {
239
+ var tests = [
240
+ ['TEST'],
241
+ ['SOME-OTHER-TAG', 'ANOTHER'],
242
+ ['ENG-TEST'],
243
+ ['GB']
244
+ ];
245
+
246
+ tests.forEach(parts => {
247
+ var result = parse.locale(input({parts, territories}));
248
+ expect(result).toBeUndefined();
249
+ });
250
+ });
251
+
252
+ it('determines country and `*.intl` type for dual-language codes', () => {
253
+ var tests = [{
254
+ parts: ['ARA-PFR'],
255
+ language: 'ARA-PFR',
256
+ country: 'LB'
257
+ }, {
258
+ parts: ['PFR-ARA'],
259
+ language: 'ARA-PFR',
260
+ country: 'LB'
261
+ }];
262
+
263
+ tests.forEach(test => {
264
+ var result = parse.locale(input({
265
+ parts: test.parts,
266
+ asset: {
267
+ type: 'tv-spot.us'
268
+ }
269
+ }));
270
+
271
+ expect(result.file.country).toEqual(test.country);
272
+ expect(result.file.language).toEqual(test.language);
273
+ expect(result.asset.type).toEqual('tv-spot.intl');
274
+ });
275
+ });
276
+
277
+ it('corrects `BZP` to `BPO` and `LTH` to `LIT`', () => {
278
+ var tests = [{
279
+ parts: ['BZP'],
280
+ language: 'BPO'
281
+ }, {
282
+ parts: ['LTH'],
283
+ language: 'LIT'
284
+ }];
285
+
286
+ tests.forEach(test => {
287
+ var result = parse.locale(input({
288
+ territories,
289
+ asset: {},
290
+ parts: test.parts
291
+ }));
292
+
293
+ expect(result.file.language).toEqual(test.language);
294
+ });
295
+ });
296
+
297
+ it('sets `SUB` and `DUB` tags', () => {
298
+ var tests = [{
299
+ parts: ['PFR-DUB'],
300
+ language: 'PFR',
301
+ tags: ['dub']
302
+ }, {
303
+ parts: ['ENG-SUB'],
304
+ language: 'ENG',
305
+ tags: ['sub']
306
+ }];
307
+
308
+ tests.forEach(test => {
309
+ var result = parse.locale(input({
310
+ territories,
311
+ asset: {},
312
+ parts: test.parts
313
+ }));
314
+
315
+ expect(result.file.language).toEqual(test.language);
316
+ expect(result.file.tags).toEqual(test.tags);
317
+ });
318
+ });
319
+
320
+ it('ignores languages which do not exist in `territories`', () => {
321
+ expect(parse.locale(input({territories, parts: ['FOO']}))).toBeUndefined();
322
+ });
323
+
324
+ it('defaults country to `WW` if country does not exist', () => {
325
+ var tests = [{
326
+ parts: ['ENG-AU'],
327
+ language: 'ENG',
328
+ country: 'AU'
329
+ }, {
330
+ parts: ['PFR'],
331
+ language: 'PFR',
332
+ country: 'WW'
333
+ }, {
334
+ parts: ['PFR-FR'],
335
+ language: 'PFR',
336
+ country: 'FR'
337
+ }, {
338
+ parts: ['ENG'],
339
+ language: 'ENG',
340
+ country: 'WW'
341
+ }, {
342
+ parts: ['ENG-FOO'],
343
+ language: 'ENG',
344
+ country: 'WW'
345
+ }];
346
+
347
+ tests.forEach(test => {
348
+ var result = parse.locale(input({
349
+ territories,
350
+ asset: {},
351
+ parts: test.parts
352
+ }));
353
+
354
+ expect(result.file.language).toEqual(test.language);
355
+ expect(result.file.country).toEqual(test.country);
356
+ });
357
+ });
358
+
359
+ it('normalizes a domestic asset type to `*.intl` if country is not `US`', () => {
360
+ var asset = {
361
+ type: 'tv-spot.us'
362
+ };
363
+
364
+ var tests = [{
365
+ parts: ['ENG-US'],
366
+ type: 'tv-spot.us'
367
+ }, {
368
+ parts: ['ENG'],
369
+ type: 'tv-spot.intl'
370
+ }, {
371
+ parts: ['PFR'],
372
+ type: 'tv-spot.intl'
373
+ }];
374
+
375
+ tests.forEach(test => {
376
+ var result = parse.locale(input({
377
+ territories,
378
+ asset,
379
+ parts: test.parts
380
+ }));
381
+
382
+ expect(result.asset.type).toBe(test.type);
383
+ });
384
+ });
385
+ });
386
+
387
+ describe('.tags()', () => {
388
+ var tags = [{
389
+ name: 'mp3',
390
+ extension: 'MP3'
391
+ }, {
392
+ name: 'prores',
393
+ aliases: ['ProRes']
394
+ }, {
395
+ name: 'hd'
396
+ }, {
397
+ name: 'txtl',
398
+ aliases: ['TXTL', 'txtl1']
399
+ }, {
400
+ name: '480p',
401
+ set: ['h264', '848x480', 'online']
402
+ }];
403
+
404
+ it('uses file extension to append initial tags', () => {
405
+ var tests = [{
406
+ ext: 'mp3',
407
+ prev: [],
408
+ tags: ['mp3']
409
+ }, {
410
+ ext: 'mp3',
411
+ prev: ['dub'],
412
+ tags: ['dub', 'mp3']
413
+ }, {
414
+ ext: 'mp4',
415
+ prev: [],
416
+ tags: []
417
+ }, {
418
+ ext: 'mp4',
419
+ prev: ['sub'],
420
+ tags: ['sub']
421
+ }];
422
+
423
+ tests.forEach((test, index) => {
424
+ var result = parse.tags(input({
425
+ tags,
426
+ parts: [],
427
+ asset: {},
428
+ file: {
429
+ tags: test.prev,
430
+ ext: test.ext
431
+ }
432
+ }));
433
+
434
+ expect(result.file.tags).toEqual(test.tags);
435
+ });
436
+ });
437
+
438
+ it('appends `broadcast` tag to Radio Spots', () => {
439
+ var types = ['radio-spot.us', 'radio-spot.intl'];
440
+
441
+ types.forEach(type => {
442
+ var result = parse.tags(input({
443
+ tags,
444
+ parts: [],
445
+ asset: {type},
446
+ file: {
447
+ ext: 'mp3'
448
+ }
449
+ }));
450
+
451
+ expect(result.file.tags).toEqual(['mp3', 'broadcast']);
452
+ });
453
+
454
+ var result = parse.tags(input({
455
+ tags,
456
+ parts: [],
457
+ asset: 'radio-spot.us',
458
+ file: {
459
+ tags: ['broadcast'],
460
+ ext: 'mp3'
461
+ }
462
+ }));
463
+
464
+ expect(result.file.tags).toEqual(['broadcast', 'mp3']);
465
+ });
466
+
467
+ it('uses remaining unique file parts that exist as tags', () => {
468
+ var parts = [
469
+ 'PRORES',
470
+ 'PRORES',
471
+ 'FOO',
472
+ 'HD',
473
+ 'TXTL',
474
+ 'TXTL1'
475
+ ];
476
+
477
+ var result = parse.tags(input({
478
+ tags,
479
+ parts,
480
+ asset: {},
481
+ file: {
482
+ ext: 'mov'
483
+ }
484
+ }));
485
+
486
+ expect(result.parts).toEqual(['FOO']);
487
+ expect(result.file.tags).toEqual(['prores', 'hd', 'txtl']);
488
+ });
489
+
490
+ it('expands a single tag to a set', () => {
491
+ var result = parse.tags(input({
492
+ tags,
493
+ parts: ['FOO', 'prores', '480p'],
494
+ asset: {},
495
+ file: {
496
+ ext: 'mov'
497
+ }
498
+ }));
499
+
500
+ expect(result.parts).toEqual(['FOO']);
501
+ expect(result.file.tags).toEqual(['prores', 'h264', '848x480', 'online']);
502
+ });
503
+ });
504
+
505
+ describe('.defaultTextTag()', () => {
506
+ var tags = [{
507
+ name: 'txtd',
508
+ type: 'Text'
509
+ }, {
510
+ name: 'txtl',
511
+ type: 'Text'
512
+ }, {
513
+ name: 'flattened',
514
+ type: 'Text'
515
+ }, {
516
+ name: 'layered',
517
+ type: 'Text'
518
+ }];
519
+
520
+ var types = [{
521
+ name: 'tv-spot.intl',
522
+ category: 'av'
523
+ }, {
524
+ name: 'magazines',
525
+ category: 'print'
526
+ }];
527
+
528
+ it('does nothing if no text tags are defined', () => {
529
+ var result = parse.defaultTextTag(input({
530
+ types,
531
+ tags: [],
532
+ asset: {},
533
+ file: {}
534
+ }));
535
+
536
+ expect(result).toBeUndefined();
537
+ });
538
+
539
+ it('does nothing if text tags are already present', () => {
540
+ var tests = [{
541
+ tags: ['foo', 'txtd']
542
+ }, {
543
+ tags: ['foo', 'flattened']
544
+ }];
545
+
546
+ tests.forEach(test => {
547
+ var result = parse.defaultTextTag(input({
548
+ tags,
549
+ types,
550
+ file: {
551
+ tags: test.tags
552
+ }
553
+ }));
554
+
555
+ expect(result).toBeUndefined();
556
+ });
557
+ });
558
+
559
+ it('appends the default text tag based on asset type', () => {
560
+ var tests = [{
561
+ type: 'tv-spot.intl',
562
+ prev: ['foo'],
563
+ tags: ['foo', 'txtd']
564
+ }, {
565
+ type: 'magazines',
566
+ prev: ['foo'],
567
+ tags: ['foo', 'flattened']
568
+ }];
569
+
570
+ tests.forEach(test => {
571
+ var result = parse.defaultTextTag(input({
572
+ tags,
573
+ types,
574
+ asset: {
575
+ type: test.type
576
+ },
577
+ file: {
578
+ tags: test.prev
579
+ }
580
+ }));
581
+
582
+ expect(result.file.tags).toEqual(test.tags);
583
+ });
584
+ });
585
+ });
586
+
587
+ describe('.runningTime()', () => {
588
+ it('does nothing if a matching tag is not found', () => {
589
+ var result = parse.runningTime(input({
590
+ parts: ['FOO', 'BAR']
591
+ }));
592
+
593
+ expect(result).toBeUndefined();
594
+ });
595
+
596
+ it('extracts running time', () => {
597
+ var tests = [{
598
+ prev: ['FOO', '30', 'BAR'],
599
+ parts: ['FOO', 'BAR'],
600
+ length: 30
601
+ }, {
602
+ prev: ['FOO', '1hr', 'BAR'],
603
+ parts: ['FOO', 'BAR'],
604
+ length: 3600
605
+ }, {
606
+ prev: ['FOO', '1hr30min', 'BAR'],
607
+ parts: ['FOO', 'BAR'],
608
+ length: 5400
609
+ }, {
610
+ prev: ['FOO', '1hr30min12sec', 'BAR'],
611
+ parts: ['FOO', 'BAR'],
612
+ length: 5412
613
+ }];
614
+
615
+ tests.forEach(test => {
616
+ var result = parse.runningTime(input({
617
+ parts: test.prev
618
+ }));
619
+
620
+ expect(result.asset.length).toEqual(test.length);
621
+ expect(result.parts).toEqual(test.parts);
622
+ });
623
+ });
624
+ });
625
+
626
+ describe('.version()', () => {
627
+ it('does nothing when last part is not `PREVIEW` or `OFFLINE`', () => {
628
+ var result = parse.version(input({
629
+ parts: ['FOO', 'BAR']
630
+ }));
631
+
632
+ expect(result).toEqual({
633
+ parts: ['FOO', 'BAR']
634
+ });
635
+ });
636
+
637
+ it('does nothing if tag is just `REV`', () => {
638
+ var result = parse.version(input({
639
+ parts: ['FOO', 'REV', 'BAR', 'PREVIEW']
640
+ }));
641
+
642
+ expect(result).toEqual({
643
+ parts: ['FOO', 'REV', 'BAR', 'PREVIEW']
644
+ });
645
+ });
646
+
647
+ it('formats version label accordingly', () => {
648
+ var result = parse.version(input({
649
+ parts: ['FOO', 'REV-NEW-VERSION', 'BAR', 'PREVIEW']
650
+ }));
651
+
652
+ expect(result.preview).toBe(true);
653
+ expect(result.version).toBe('New Version');
654
+ });
655
+ });
656
+
657
+ describe('.mediaType()', () => {
658
+ it('does nothing for an unrecognized extension', () => {
659
+ var result = parse.mediaType(input({
660
+ file: {
661
+ ext: 'foo'
662
+ }
663
+ }));
664
+
665
+ expect(result).toBeUndefined();
666
+ });
667
+
668
+ it('determines media type by file extension', () => {
669
+ var tests = [{
670
+ ext: 'txt',
671
+ type: 'document'
672
+ }, {
673
+ ext: 'mov',
674
+ type: 'video'
675
+ }, {
676
+ ext: 'jpg',
677
+ type: 'image'
678
+ }];
679
+
680
+ tests.forEach(test => {
681
+ var result = parse.mediaType(input({
682
+ file: {
683
+ ext: test.ext
684
+ }
685
+ }));
686
+
687
+ expect(result).toEqual({
688
+ asset: {
689
+ mediaType: test.type
690
+ }
691
+ });
692
+ });
693
+ });
694
+ });
695
+
696
+ describe('.asset()', () => {
697
+ it('does nothing if project ID could not be determined previously', () => {
698
+ parse.asset(input({
699
+ project: {
700
+ _id: undefined
701
+ },
702
+ asset: {
703
+ slug: 'test-asset-slug'
704
+ }
705
+ }));
706
+
707
+ expect(mockApi.read).not.toHaveBeenCalled();
708
+ });
709
+
710
+ it('attempts to matches by project and slug', done => {
711
+ mockApi.read.and.callFake(() => resolve([{
712
+ _id: 'test-asset-id',
713
+ slug: 'test-asset-slug'
714
+ }]));
715
+
716
+ parse
717
+ .asset(input({
718
+ project: {
719
+ _id: 'test-project-id'
720
+ },
721
+ asset: {
722
+ slug: 'test-asset-slug'
723
+ }
724
+ }))
725
+ .then(result => {
726
+ expect(mockApi.read).toHaveBeenCalledWith('assets', {
727
+ project: 'test-project-id',
728
+ slug: 'test-asset-slug'
729
+ });
730
+
731
+ expect(result).toEqual({
732
+ asset: {
733
+ _id: 'test-asset-id'
734
+ }
735
+ });
736
+ })
737
+ .finally(done);
738
+ });
739
+ });
740
+
741
+ describe('.default()', () => {
742
+ var input = {
743
+ ingest: 'test-ingest',
744
+ source: 'http: //test.com/path/to/test_FILE.mov',
745
+ token: 'test-token',
746
+ apiRoot: 'http://test.com/api',
747
+ skipScratchPreview: false
748
+ };
749
+
750
+ var mocks = {
751
+ tags: 'mockTags',
752
+ assettypes: 'mockAssetTypes',
753
+ territories: 'mockTerritories'
754
+ };
755
+
756
+ beforeEach(() => {
757
+ for (let parser in parse) {
758
+ if (parser === 'default') {
759
+ continue;
760
+ }
761
+ spyOn(<any> parse, parser);
762
+ }
763
+
764
+ mockApi.read.and.callFake((path: string) => resolve(mocks[path]));
765
+ });
766
+
767
+ it('configures API according to job parameters', done => {
768
+ parse.default(input)
769
+ .then(() => {
770
+ expect(api.create).toHaveBeenCalledWith('http://test.com/api', 'test-token');
771
+ })
772
+ .finally(done);
773
+ });
774
+
775
+ it('calls each parser with API instance and initial data', done => {
776
+ parse.default(input)
777
+ .then(() => {
778
+ for (let parser in parse) {
779
+ if (parser === 'default') {
780
+ continue;
781
+ }
782
+
783
+ expect(parse[parser]).toHaveBeenCalledWith({
784
+ territories: mocks.territories,
785
+ api: mockApi,
786
+ tags: mocks.tags,
787
+ types: mocks.assettypes,
788
+ parts: ['test', 'FILE'],
789
+ file: {
790
+ ext: 'mov'
791
+ }
792
+ });
793
+ }
794
+ })
795
+ .finally(done);
796
+ });
797
+
798
+ it('merges the result of parser into the data that is given to the next', done => {
799
+ (parse.type as jasmine.Spy).and.returnValue({
800
+ asset: {
801
+ type: 'trailer.intl'
802
+ }
803
+ });
804
+
805
+ (parse.runningTime as jasmine.Spy).and.returnValue({
806
+ asset: {
807
+ length: 30
808
+ }
809
+ });
810
+
811
+ parse.default(input)
812
+ .then(() => {
813
+ expect(parse.trailer).toHaveBeenCalledWith({
814
+ territories: mocks.territories,
815
+ api: mockApi,
816
+ tags: mocks.tags,
817
+ types: mocks.assettypes,
818
+ parts: ['test', 'FILE'],
819
+ file: {
820
+ ext: 'mov'
821
+ },
822
+ asset: {
823
+ type: 'trailer.intl'
824
+ }
825
+ });
826
+
827
+ expect(parse.version).toHaveBeenCalledWith({
828
+ territories: mocks.territories,
829
+ api: mockApi,
830
+ tags: mocks.tags,
831
+ types: mocks.assettypes,
832
+ parts: ['test', 'FILE'],
833
+ asset: {
834
+ type: 'trailer.intl',
835
+ length: 30
836
+ },
837
+ file: {
838
+ ext: 'mov'
839
+ }
840
+ });
841
+ })
842
+ .finally(done);
843
+ });
844
+
845
+ it('returns the merged result of all parsers with initial data omitted', done => {
846
+ (parse.project as jasmine.Spy).and.returnValue({
847
+ project: {
848
+ _id: 'test-project'
849
+ }
850
+ });
851
+
852
+ (parse.type as jasmine.Spy).and.returnValue({
853
+ asset: {
854
+ type: 'trailer.intl'
855
+ }
856
+ });
857
+
858
+ (parse.runningTime as jasmine.Spy).and.returnValue({
859
+ asset: {
860
+ length: 30
861
+ }
862
+ });
863
+
864
+ parse.default(input)
865
+ .then((result: any) => {
866
+ expect(result).toEqual({
867
+ project: {
868
+ _id: 'test-project'
869
+ },
870
+ asset: {
871
+ type: 'trailer.intl',
872
+ length: 30
873
+ },
874
+ file: {
875
+ ext: 'mov'
876
+ }
877
+ });
878
+ })
879
+ .finally(done);
880
+ });
881
+
882
+ it('updates the ingest document with filename metadata', done => {
883
+ parse.default(input)
884
+ .then(() => {
885
+ expect(mockApi.update).toHaveBeenCalledWith('ingests/test-ingest', {
886
+ filename: {
887
+ file: {
888
+ ext: 'mov'
889
+ }
890
+ }
891
+ });
892
+ })
893
+ .finally(done);
894
+ });
895
+ });
896
+
897
+ describe('integration tests', () => {
898
+ var suite = require('./parse.integration');
899
+
900
+ beforeEach(() => {
901
+ mockApi.read.and.callFake((path: string, params?: Object) => {
902
+ var data = suite.mocks[path];
903
+ var response = params ? filter(whereEq(params), data) : data;
904
+
905
+ return resolve(response);
906
+ });
907
+ });
908
+
909
+ suite.tests.forEach((test: any) => {
910
+ it(`parses '${test.filename}'`, done => {
911
+ var input = {
912
+ ingest: 'test-ingest',
913
+ source: `http: //test.com/path/to/${test.filename}`,
914
+ token: 'test-token',
915
+ apiRoot: 'http://test.com/api',
916
+ skipScratchPreview: false
917
+ };
918
+
919
+ parse.default(input)
920
+ .then((result: any) => {
921
+ expect(result).toEqual(test.result);
922
+ })
923
+ .finally(done);
924
+ });
925
+ });
926
+ });
927
+ });