@ekipnico/video-fetch 1.0.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.
- package/out/DownloadProvider.d.ts +22 -0
- package/out/DownloadProvider.js +7 -0
- package/out/DownloadProvider.js.map +1 -0
- package/out/VideoDownloadModule.d.ts +27 -0
- package/out/VideoDownloadModule.js +39 -0
- package/out/VideoDownloadModule.js.map +1 -0
- package/out/VideoDownloader.d.ts +22 -0
- package/out/VideoDownloader.js +42 -0
- package/out/VideoDownloader.js.map +1 -0
- package/out/index.d.ts +5 -0
- package/out/index.js +6 -0
- package/out/index.js.map +1 -0
- package/out/providers/YtDlpProvider.d.ts +36 -0
- package/out/providers/YtDlpProvider.js +215 -0
- package/out/providers/YtDlpProvider.js.map +1 -0
- package/out/schema/DownloadConfig.d.ts +24 -0
- package/out/schema/DownloadConfig.js +8 -0
- package/out/schema/DownloadConfig.js.map +1 -0
- package/out/schema/DownloadResult.d.ts +26 -0
- package/out/schema/DownloadResult.js +2 -0
- package/out/schema/DownloadResult.js.map +1 -0
- package/out/schema/VideoMetadata.d.ts +46 -0
- package/out/schema/VideoMetadata.js +35 -0
- package/out/schema/VideoMetadata.js.map +1 -0
- package/out/schema/index.d.ts +3 -0
- package/out/schema/index.js +4 -0
- package/out/schema/index.js.map +1 -0
- package/out/test/VideoDownloadModule.test.d.ts +1 -0
- package/out/test/VideoDownloadModule.test.js +61 -0
- package/out/test/VideoDownloadModule.test.js.map +1 -0
- package/out/test/VideoDownloader.test.d.ts +1 -0
- package/out/test/VideoDownloader.test.js +132 -0
- package/out/test/VideoDownloader.test.js.map +1 -0
- package/out/test/YtDlpProvider.test.d.ts +1 -0
- package/out/test/YtDlpProvider.test.js +215 -0
- package/out/test/YtDlpProvider.test.js.map +1 -0
- package/out/test/channel-download.test.d.ts +1 -0
- package/out/test/channel-download.test.js +269 -0
- package/out/test/channel-download.test.js.map +1 -0
- package/out/test/integration.test.d.ts +1 -0
- package/out/test/integration.test.js +120 -0
- package/out/test/integration.test.js.map +1 -0
- package/out/test/schema.test.d.ts +1 -0
- package/out/test/schema.test.js +62 -0
- package/out/test/schema.test.js.map +1 -0
- package/out/test/setup.test.d.ts +5 -0
- package/out/test/setup.test.js +7 -0
- package/out/test/setup.test.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { Mesh } from 'mesh-ioc';
|
|
3
|
+
import { createVideoDownloadMesh, registerVideoDownloadServices } from '../VideoDownloadModule.js';
|
|
4
|
+
import { VideoDownloader } from '../VideoDownloader.js';
|
|
5
|
+
import { DownloadProvider } from '../DownloadProvider.js';
|
|
6
|
+
import { YtDlpProvider } from '../providers/YtDlpProvider.js';
|
|
7
|
+
describe('VideoDownloadModule', () => {
|
|
8
|
+
describe('createVideoDownloadMesh', () => {
|
|
9
|
+
it('creates a mesh with VideoDownloader', () => {
|
|
10
|
+
const mesh = createVideoDownloadMesh();
|
|
11
|
+
const downloader = mesh.resolve(VideoDownloader);
|
|
12
|
+
assert.ok(downloader instanceof VideoDownloader);
|
|
13
|
+
});
|
|
14
|
+
it('creates a mesh with DownloadProvider as YtDlpProvider', () => {
|
|
15
|
+
const mesh = createVideoDownloadMesh();
|
|
16
|
+
const provider = mesh.resolve(DownloadProvider);
|
|
17
|
+
assert.ok(provider instanceof YtDlpProvider);
|
|
18
|
+
assert.strictEqual(provider.name, 'yt-dlp');
|
|
19
|
+
});
|
|
20
|
+
it('creates new instances for each call', () => {
|
|
21
|
+
const mesh1 = createVideoDownloadMesh();
|
|
22
|
+
const mesh2 = createVideoDownloadMesh();
|
|
23
|
+
assert.notStrictEqual(mesh1, mesh2);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('registerVideoDownloadServices', () => {
|
|
27
|
+
it('registers VideoDownloader into existing mesh', () => {
|
|
28
|
+
const mesh = new Mesh('TestMesh');
|
|
29
|
+
registerVideoDownloadServices(mesh);
|
|
30
|
+
const downloader = mesh.resolve(VideoDownloader);
|
|
31
|
+
assert.ok(downloader instanceof VideoDownloader);
|
|
32
|
+
});
|
|
33
|
+
it('registers DownloadProvider as YtDlpProvider', () => {
|
|
34
|
+
const mesh = new Mesh('TestMesh');
|
|
35
|
+
registerVideoDownloadServices(mesh);
|
|
36
|
+
const provider = mesh.resolve(DownloadProvider);
|
|
37
|
+
assert.ok(provider instanceof YtDlpProvider);
|
|
38
|
+
});
|
|
39
|
+
it('allows resolving services multiple times', () => {
|
|
40
|
+
const mesh = new Mesh('TestMesh');
|
|
41
|
+
registerVideoDownloadServices(mesh);
|
|
42
|
+
const downloader1 = mesh.resolve(VideoDownloader);
|
|
43
|
+
const downloader2 = mesh.resolve(VideoDownloader);
|
|
44
|
+
// mesh-ioc typically returns the same instance
|
|
45
|
+
assert.strictEqual(downloader1, downloader2);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('DI wiring', () => {
|
|
49
|
+
it('VideoDownloader has provider injected', async () => {
|
|
50
|
+
const mesh = createVideoDownloadMesh();
|
|
51
|
+
const downloader = mesh.resolve(VideoDownloader);
|
|
52
|
+
// Test that provider is accessible through the downloader
|
|
53
|
+
// by calling a method that delegates to provider
|
|
54
|
+
// This would throw if provider wasn't injected
|
|
55
|
+
const isSupported = await downloader.isSupported('invalid-url');
|
|
56
|
+
// yt-dlp returns false for invalid URLs
|
|
57
|
+
assert.strictEqual(typeof isSupported, 'boolean');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=VideoDownloadModule.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoDownloadModule.test.js","sourceRoot":"","sources":["../../src/test/VideoDownloadModule.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { Mesh } from 'mesh-ioc';
|
|
3
|
+
import { DownloadProvider } from '../DownloadProvider.js';
|
|
4
|
+
import { VideoDownloader } from '../VideoDownloader.js';
|
|
5
|
+
/**
|
|
6
|
+
* Mock provider for testing VideoDownloader without yt-dlp.
|
|
7
|
+
*/
|
|
8
|
+
class MockDownloadProvider extends DownloadProvider {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.name = 'mock';
|
|
12
|
+
this.mockDownloadResult = {
|
|
13
|
+
success: true,
|
|
14
|
+
videoDir: '/mock/mock123',
|
|
15
|
+
filePath: '/mock/mock123/video.mp4',
|
|
16
|
+
metadataPath: '/mock/mock123/meta.json',
|
|
17
|
+
format: 'mp4',
|
|
18
|
+
sizeBytes: 1000000,
|
|
19
|
+
duration: 120,
|
|
20
|
+
metadata: {
|
|
21
|
+
id: 'mock123',
|
|
22
|
+
platform: 'mock',
|
|
23
|
+
url: 'https://mock.com/video',
|
|
24
|
+
title: 'Mock Video',
|
|
25
|
+
description: 'A mock video',
|
|
26
|
+
uploader: 'Mock User',
|
|
27
|
+
duration: 120,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
this.mockMetadata = {
|
|
31
|
+
id: 'mock123',
|
|
32
|
+
platform: 'mock',
|
|
33
|
+
url: 'https://mock.com/video',
|
|
34
|
+
title: 'Mock Video',
|
|
35
|
+
description: 'A mock video',
|
|
36
|
+
uploader: 'Mock User',
|
|
37
|
+
duration: 120,
|
|
38
|
+
};
|
|
39
|
+
this.mockIsSupported = true;
|
|
40
|
+
}
|
|
41
|
+
async download(url, config) {
|
|
42
|
+
this.lastDownloadUrl = url;
|
|
43
|
+
this.lastDownloadConfig = config;
|
|
44
|
+
return this.mockDownloadResult;
|
|
45
|
+
}
|
|
46
|
+
async extractMetadata(url) {
|
|
47
|
+
this.lastMetadataUrl = url;
|
|
48
|
+
return this.mockMetadata;
|
|
49
|
+
}
|
|
50
|
+
async isSupported(url) {
|
|
51
|
+
this.lastIsSupportedUrl = url;
|
|
52
|
+
return this.mockIsSupported;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
describe('VideoDownloader', () => {
|
|
56
|
+
let downloader;
|
|
57
|
+
let mockProvider;
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
mockProvider = new MockDownloadProvider();
|
|
60
|
+
// Use mesh-ioc to properly inject the mock provider
|
|
61
|
+
const mesh = new Mesh('TestMesh');
|
|
62
|
+
mesh.constant(DownloadProvider, mockProvider);
|
|
63
|
+
mesh.service(VideoDownloader);
|
|
64
|
+
downloader = mesh.resolve(VideoDownloader);
|
|
65
|
+
});
|
|
66
|
+
describe('download', () => {
|
|
67
|
+
it('delegates to provider with merged config', async () => {
|
|
68
|
+
const result = await downloader.download('https://example.com/video');
|
|
69
|
+
assert.strictEqual(mockProvider.lastDownloadUrl, 'https://example.com/video');
|
|
70
|
+
assert.ok(mockProvider.lastDownloadConfig);
|
|
71
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.format, 'best');
|
|
72
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.quality, 'best');
|
|
73
|
+
});
|
|
74
|
+
it('merges partial config with defaults', async () => {
|
|
75
|
+
await downloader.download('https://example.com/video', {
|
|
76
|
+
quality: 720,
|
|
77
|
+
audioOnly: true,
|
|
78
|
+
});
|
|
79
|
+
assert.ok(mockProvider.lastDownloadConfig);
|
|
80
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.quality, 720);
|
|
81
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.audioOnly, true);
|
|
82
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.format, 'best'); // default
|
|
83
|
+
assert.strictEqual(mockProvider.lastDownloadConfig.timeout, 600); // default
|
|
84
|
+
});
|
|
85
|
+
it('returns provider result', async () => {
|
|
86
|
+
const result = await downloader.download('https://example.com/video');
|
|
87
|
+
assert.strictEqual(result.success, true);
|
|
88
|
+
assert.strictEqual(result.videoDir, '/mock/mock123');
|
|
89
|
+
assert.strictEqual(result.filePath, '/mock/mock123/video.mp4');
|
|
90
|
+
assert.strictEqual(result.metadataPath, '/mock/mock123/meta.json');
|
|
91
|
+
assert.strictEqual(result.metadata.id, 'mock123');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
describe('extractMetadata', () => {
|
|
95
|
+
it('delegates to provider', async () => {
|
|
96
|
+
const metadata = await downloader.extractMetadata('https://example.com/video');
|
|
97
|
+
assert.strictEqual(mockProvider.lastMetadataUrl, 'https://example.com/video');
|
|
98
|
+
assert.strictEqual(metadata.id, 'mock123');
|
|
99
|
+
assert.strictEqual(metadata.title, 'Mock Video');
|
|
100
|
+
});
|
|
101
|
+
it('returns provider metadata', async () => {
|
|
102
|
+
mockProvider.mockMetadata = {
|
|
103
|
+
id: 'custom123',
|
|
104
|
+
platform: 'youtube',
|
|
105
|
+
url: 'https://youtube.com/watch?v=custom123',
|
|
106
|
+
title: 'Custom Title',
|
|
107
|
+
description: 'Custom description',
|
|
108
|
+
uploader: 'Custom Channel',
|
|
109
|
+
duration: 300,
|
|
110
|
+
viewCount: 1000000,
|
|
111
|
+
};
|
|
112
|
+
const metadata = await downloader.extractMetadata('https://youtube.com/watch?v=custom123');
|
|
113
|
+
assert.strictEqual(metadata.id, 'custom123');
|
|
114
|
+
assert.strictEqual(metadata.platform, 'youtube');
|
|
115
|
+
assert.strictEqual(metadata.title, 'Custom Title');
|
|
116
|
+
assert.strictEqual(metadata.viewCount, 1000000);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('isSupported', () => {
|
|
120
|
+
it('delegates to provider', async () => {
|
|
121
|
+
const result = await downloader.isSupported('https://example.com/video');
|
|
122
|
+
assert.strictEqual(mockProvider.lastIsSupportedUrl, 'https://example.com/video');
|
|
123
|
+
assert.strictEqual(result, true);
|
|
124
|
+
});
|
|
125
|
+
it('returns provider result when not supported', async () => {
|
|
126
|
+
mockProvider.mockIsSupported = false;
|
|
127
|
+
const result = await downloader.isSupported('https://unsupported.com/video');
|
|
128
|
+
assert.strictEqual(result, false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=VideoDownloader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoDownloader.test.js","sourceRoot":"","sources":["../../src/test/VideoDownloader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { YtDlpProvider } from '../providers/YtDlpProvider.js';
|
|
3
|
+
import { DEFAULT_DOWNLOAD_CONFIG } from '../schema/DownloadConfig.js';
|
|
4
|
+
describe('YtDlpProvider', () => {
|
|
5
|
+
describe('constructor', () => {
|
|
6
|
+
it('creates provider with default options', () => {
|
|
7
|
+
const provider = new YtDlpProvider();
|
|
8
|
+
assert.strictEqual(provider.name, 'yt-dlp');
|
|
9
|
+
});
|
|
10
|
+
it('accepts custom outputDir', () => {
|
|
11
|
+
const provider = new YtDlpProvider({
|
|
12
|
+
outputDir: '/custom/output',
|
|
13
|
+
});
|
|
14
|
+
assert.strictEqual(provider.name, 'yt-dlp');
|
|
15
|
+
});
|
|
16
|
+
it('accepts custom cookiesPath', () => {
|
|
17
|
+
const provider = new YtDlpProvider({
|
|
18
|
+
cookiesPath: '/path/to/cookies.txt',
|
|
19
|
+
});
|
|
20
|
+
assert.strictEqual(provider.name, 'yt-dlp');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('name property', () => {
|
|
24
|
+
it('returns yt-dlp', () => {
|
|
25
|
+
const provider = new YtDlpProvider();
|
|
26
|
+
assert.strictEqual(provider.name, 'yt-dlp');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Test subclass to expose private methods for testing.
|
|
32
|
+
*/
|
|
33
|
+
class TestableYtDlpProvider extends YtDlpProvider {
|
|
34
|
+
testBuildDownloadArgs(url, outputPath, config) {
|
|
35
|
+
// @ts-expect-error - accessing private method for testing
|
|
36
|
+
return this.buildDownloadArgs(url, outputPath, config);
|
|
37
|
+
}
|
|
38
|
+
testMapMetadata(data, url) {
|
|
39
|
+
// @ts-expect-error - accessing private method for testing
|
|
40
|
+
return this.mapMetadata(data, url);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
describe('YtDlpProvider (internal methods)', () => {
|
|
44
|
+
let provider;
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
provider = new TestableYtDlpProvider();
|
|
47
|
+
});
|
|
48
|
+
describe('buildDownloadArgs', () => {
|
|
49
|
+
it('builds basic args with default config', () => {
|
|
50
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', DEFAULT_DOWNLOAD_CONFIG);
|
|
51
|
+
assert.ok(args.includes('-f'));
|
|
52
|
+
assert.ok(args.includes('"bestvideo+bestaudio/best"'));
|
|
53
|
+
assert.ok(args.includes('--merge-output-format'));
|
|
54
|
+
assert.ok(args.includes('mp4'));
|
|
55
|
+
assert.ok(args.includes('-o'));
|
|
56
|
+
assert.ok(args.includes('"/output/test.%(ext)s"'));
|
|
57
|
+
assert.ok(args.includes('"https://youtube.com/watch?v=test"'));
|
|
58
|
+
});
|
|
59
|
+
it('adds audio-only flags when audioOnly is true', () => {
|
|
60
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, audioOnly: true };
|
|
61
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
62
|
+
assert.ok(args.includes('-f'));
|
|
63
|
+
assert.ok(args.includes('"bestaudio[ext=m4a]/bestaudio"'));
|
|
64
|
+
assert.ok(args.includes('-x'));
|
|
65
|
+
});
|
|
66
|
+
it('adds quality filter when quality is specified', () => {
|
|
67
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, quality: 720 };
|
|
68
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
69
|
+
assert.ok(args.some(arg => arg.includes('height<=720')));
|
|
70
|
+
});
|
|
71
|
+
it('adds subtitle flags when includeSubtitles is true', () => {
|
|
72
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, includeSubtitles: true };
|
|
73
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
74
|
+
assert.ok(args.includes('--write-subs'));
|
|
75
|
+
});
|
|
76
|
+
it('adds subtitle language when specified', () => {
|
|
77
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, includeSubtitles: true, subtitleLang: 'en' };
|
|
78
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
79
|
+
assert.ok(args.includes('--write-subs'));
|
|
80
|
+
assert.ok(args.includes('--sub-lang'));
|
|
81
|
+
assert.ok(args.includes('en'));
|
|
82
|
+
});
|
|
83
|
+
it('adds rate limit when specified', () => {
|
|
84
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, rateLimit: 1000000 };
|
|
85
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
86
|
+
assert.ok(args.includes('-r'));
|
|
87
|
+
assert.ok(args.includes('1000000'));
|
|
88
|
+
});
|
|
89
|
+
it('adds extra args when specified', () => {
|
|
90
|
+
const config = { ...DEFAULT_DOWNLOAD_CONFIG, extraArgs: ['--verbose', '--no-playlist'] };
|
|
91
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
|
|
92
|
+
assert.ok(args.includes('--verbose'));
|
|
93
|
+
assert.ok(args.includes('--no-playlist'));
|
|
94
|
+
});
|
|
95
|
+
it('URL is always last argument', () => {
|
|
96
|
+
const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', DEFAULT_DOWNLOAD_CONFIG);
|
|
97
|
+
const lastArg = args[args.length - 1];
|
|
98
|
+
assert.strictEqual(lastArg, '"https://youtube.com/watch?v=test"');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('mapMetadata', () => {
|
|
102
|
+
it('maps basic yt-dlp JSON output', () => {
|
|
103
|
+
const ytDlpData = {
|
|
104
|
+
id: 'test123',
|
|
105
|
+
extractor_key: 'Youtube',
|
|
106
|
+
webpage_url: 'https://youtube.com/watch?v=test123',
|
|
107
|
+
title: 'Test Video',
|
|
108
|
+
description: 'A test video description',
|
|
109
|
+
uploader: 'Test Channel',
|
|
110
|
+
duration: 120,
|
|
111
|
+
};
|
|
112
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://youtube.com/watch?v=test123');
|
|
113
|
+
assert.strictEqual(metadata.id, 'test123');
|
|
114
|
+
assert.strictEqual(metadata.platform, 'youtube');
|
|
115
|
+
assert.strictEqual(metadata.url, 'https://youtube.com/watch?v=test123');
|
|
116
|
+
assert.strictEqual(metadata.title, 'Test Video');
|
|
117
|
+
assert.strictEqual(metadata.description, 'A test video description');
|
|
118
|
+
assert.strictEqual(metadata.uploader, 'Test Channel');
|
|
119
|
+
assert.strictEqual(metadata.duration, 120);
|
|
120
|
+
});
|
|
121
|
+
it('handles missing optional fields', () => {
|
|
122
|
+
const ytDlpData = {
|
|
123
|
+
id: 'test123',
|
|
124
|
+
title: 'Test Video',
|
|
125
|
+
duration: 60,
|
|
126
|
+
};
|
|
127
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com/video');
|
|
128
|
+
assert.strictEqual(metadata.id, 'test123');
|
|
129
|
+
assert.strictEqual(metadata.platform, 'unknown');
|
|
130
|
+
assert.strictEqual(metadata.url, 'https://example.com/video');
|
|
131
|
+
assert.strictEqual(metadata.title, 'Test Video');
|
|
132
|
+
assert.strictEqual(metadata.description, '');
|
|
133
|
+
assert.strictEqual(metadata.uploader, 'Unknown');
|
|
134
|
+
assert.strictEqual(metadata.duration, 60);
|
|
135
|
+
assert.strictEqual(metadata.viewCount, undefined);
|
|
136
|
+
assert.strictEqual(metadata.chapters, undefined);
|
|
137
|
+
});
|
|
138
|
+
it('maps engagement metrics', () => {
|
|
139
|
+
const ytDlpData = {
|
|
140
|
+
id: 'test123',
|
|
141
|
+
title: 'Test',
|
|
142
|
+
duration: 60,
|
|
143
|
+
view_count: 1000000,
|
|
144
|
+
like_count: 50000,
|
|
145
|
+
comment_count: 1500,
|
|
146
|
+
};
|
|
147
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
|
|
148
|
+
assert.strictEqual(metadata.viewCount, 1000000);
|
|
149
|
+
assert.strictEqual(metadata.likeCount, 50000);
|
|
150
|
+
assert.strictEqual(metadata.commentCount, 1500);
|
|
151
|
+
});
|
|
152
|
+
it('maps technical metadata', () => {
|
|
153
|
+
const ytDlpData = {
|
|
154
|
+
id: 'test123',
|
|
155
|
+
title: 'Test',
|
|
156
|
+
duration: 60,
|
|
157
|
+
width: 1920,
|
|
158
|
+
height: 1080,
|
|
159
|
+
fps: 30,
|
|
160
|
+
vcodec: 'vp9',
|
|
161
|
+
acodec: 'opus',
|
|
162
|
+
filesize: 50000000,
|
|
163
|
+
};
|
|
164
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
|
|
165
|
+
assert.strictEqual(metadata.width, 1920);
|
|
166
|
+
assert.strictEqual(metadata.height, 1080);
|
|
167
|
+
assert.strictEqual(metadata.fps, 30);
|
|
168
|
+
assert.strictEqual(metadata.vcodec, 'vp9');
|
|
169
|
+
assert.strictEqual(metadata.acodec, 'opus');
|
|
170
|
+
assert.strictEqual(metadata.filesize, 50000000);
|
|
171
|
+
});
|
|
172
|
+
it('maps chapters when present', () => {
|
|
173
|
+
const ytDlpData = {
|
|
174
|
+
id: 'test123',
|
|
175
|
+
title: 'Test',
|
|
176
|
+
duration: 600,
|
|
177
|
+
chapters: [
|
|
178
|
+
{ title: 'Intro', start_time: 0, end_time: 60 },
|
|
179
|
+
{ title: 'Main Content', start_time: 60, end_time: 500 },
|
|
180
|
+
{ title: 'Outro', start_time: 500, end_time: 600 },
|
|
181
|
+
],
|
|
182
|
+
};
|
|
183
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
|
|
184
|
+
assert.ok(metadata.chapters);
|
|
185
|
+
assert.strictEqual(metadata.chapters.length, 3);
|
|
186
|
+
assert.strictEqual(metadata.chapters[0].title, 'Intro');
|
|
187
|
+
assert.strictEqual(metadata.chapters[0].startTime, 0);
|
|
188
|
+
assert.strictEqual(metadata.chapters[0].endTime, 60);
|
|
189
|
+
assert.strictEqual(metadata.chapters[1].title, 'Main Content');
|
|
190
|
+
assert.strictEqual(metadata.chapters[2].title, 'Outro');
|
|
191
|
+
});
|
|
192
|
+
it('uses channel as uploader fallback', () => {
|
|
193
|
+
const ytDlpData = {
|
|
194
|
+
id: 'test123',
|
|
195
|
+
title: 'Test',
|
|
196
|
+
duration: 60,
|
|
197
|
+
channel: 'Channel Name',
|
|
198
|
+
};
|
|
199
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
|
|
200
|
+
assert.strictEqual(metadata.uploader, 'Channel Name');
|
|
201
|
+
assert.strictEqual(metadata.channel, 'Channel Name');
|
|
202
|
+
});
|
|
203
|
+
it('uses filesize_approx when filesize is not available', () => {
|
|
204
|
+
const ytDlpData = {
|
|
205
|
+
id: 'test123',
|
|
206
|
+
title: 'Test',
|
|
207
|
+
duration: 60,
|
|
208
|
+
filesize_approx: 25000000,
|
|
209
|
+
};
|
|
210
|
+
const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
|
|
211
|
+
assert.strictEqual(metadata.filesize, 25000000);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=YtDlpProvider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YtDlpProvider.test.js","sourceRoot":"","sources":["../../src/test/YtDlpProvider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'dotenv/config';
|