streamify-audio 2.3.1 → 2.3.2

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.
@@ -1,219 +0,0 @@
1
- const { describe, it, beforeEach } = require('node:test');
2
- const assert = require('node:assert');
3
-
4
- const youtube = require('../src/providers/youtube');
5
-
6
- describe('YouTube Provider', () => {
7
- const mockConfig = {
8
- ytdlpPath: 'yt-dlp',
9
- ffmpegPath: 'ffmpeg',
10
- cookiesPath: null,
11
- cache: {
12
- searchTTL: 300,
13
- infoTTL: 600
14
- }
15
- };
16
-
17
- describe('search', () => {
18
- it('should return tracks array for valid query', async () => {
19
- const results = await youtube.search('never gonna give you up', 1, mockConfig);
20
-
21
- assert(results.tracks, 'Should have tracks array');
22
- assert(Array.isArray(results.tracks), 'Tracks should be an array');
23
- assert.strictEqual(results.source, 'youtube');
24
- assert(typeof results.searchTime === 'number', 'Should have searchTime');
25
- });
26
-
27
- it('should respect limit parameter', async () => {
28
- const results = await youtube.search('music', 3, mockConfig);
29
-
30
- assert(results.tracks.length <= 3, 'Should not exceed limit');
31
- });
32
-
33
- it('should return track with required fields', async () => {
34
- const results = await youtube.search('test video', 1, mockConfig);
35
-
36
- if (results.tracks.length > 0) {
37
- const track = results.tracks[0];
38
- assert(track.id, 'Track should have id');
39
- assert(track.title, 'Track should have title');
40
- assert(typeof track.duration === 'number', 'Track should have numeric duration');
41
- assert(track.uri, 'Track should have uri');
42
- assert(track.streamUrl, 'Track should have streamUrl');
43
- assert.strictEqual(track.source, 'youtube');
44
- }
45
- });
46
-
47
- it('should handle empty query gracefully', async () => {
48
- await assert.rejects(
49
- () => youtube.search('', 1, mockConfig),
50
- /yt-dlp/
51
- );
52
- });
53
-
54
- it('should handle special characters in query', async () => {
55
- const results = await youtube.search('test & special <chars> "quotes"', 1, mockConfig);
56
- assert(results.tracks, 'Should handle special characters');
57
- });
58
-
59
- it('should handle unicode in query', async () => {
60
- const results = await youtube.search('日本語 テスト', 1, mockConfig);
61
- assert(results.tracks, 'Should handle unicode');
62
- });
63
-
64
- it('should handle very long query', async () => {
65
- const longQuery = 'a'.repeat(200);
66
- const results = await youtube.search(longQuery, 1, mockConfig);
67
- assert(results.tracks, 'Should handle long query');
68
- });
69
-
70
- it('should filter by type when specified', async () => {
71
- const results = await youtube.search('music', 3, mockConfig, { type: 'video' });
72
- assert(results.tracks, 'Should filter by type');
73
- });
74
-
75
- it('should sort by views when specified', async () => {
76
- const results = await youtube.search('music', 3, mockConfig, { sort: 'views' });
77
- assert(results.tracks, 'Should sort by views');
78
- });
79
-
80
- it('should sort by date when specified', async () => {
81
- const results = await youtube.search('music', 3, mockConfig, { sort: 'date' });
82
- assert(results.tracks, 'Should sort by date');
83
- });
84
- });
85
-
86
- describe('getInfo', () => {
87
- it('should return info for valid video ID', async () => {
88
- const info = await youtube.getInfo('dQw4w9WgXcQ', mockConfig);
89
-
90
- assert(info.id, 'Should have id');
91
- assert(info.title, 'Should have title');
92
- assert(typeof info.duration === 'number', 'Should have numeric duration');
93
- assert(info.uri, 'Should have uri');
94
- assert.strictEqual(info.source, 'youtube');
95
- });
96
-
97
- it('should include author/channel info', async () => {
98
- const info = await youtube.getInfo('dQw4w9WgXcQ', mockConfig);
99
- assert(info.author, 'Should have author');
100
- });
101
-
102
- it('should include thumbnail', async () => {
103
- const info = await youtube.getInfo('dQw4w9WgXcQ', mockConfig);
104
- assert(info.thumbnail, 'Should have thumbnail');
105
- });
106
-
107
- it('should throw for invalid video ID', async () => {
108
- await assert.rejects(
109
- () => youtube.getInfo('invalidid123456789', mockConfig),
110
- /yt-dlp/
111
- );
112
- });
113
-
114
- it('should throw for empty video ID', async () => {
115
- await assert.rejects(
116
- () => youtube.getInfo('', mockConfig),
117
- /yt-dlp/
118
- );
119
- });
120
-
121
- it('should detect live streams', async () => {
122
- const info = await youtube.getInfo('dQw4w9WgXcQ', mockConfig);
123
- assert(typeof info.isLive === 'boolean', 'Should have isLive flag');
124
- });
125
-
126
- it('should include streamUrl', async () => {
127
- const info = await youtube.getInfo('dQw4w9WgXcQ', mockConfig);
128
- assert(info.streamUrl.includes('/youtube/stream/'), 'Should have correct streamUrl format');
129
- });
130
- });
131
-
132
- describe('getPlaylist', () => {
133
- it('should return playlist info for valid playlist ID', async () => {
134
- const playlist = await youtube.getPlaylist('PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf', mockConfig);
135
-
136
- assert(playlist.id, 'Should have id');
137
- assert(playlist.tracks, 'Should have tracks');
138
- assert(Array.isArray(playlist.tracks), 'Tracks should be array');
139
- assert.strictEqual(playlist.source, 'youtube');
140
- });
141
-
142
- it('should throw for invalid playlist ID', async () => {
143
- await assert.rejects(
144
- () => youtube.getPlaylist('invalidplaylist', mockConfig),
145
- /yt-dlp/
146
- );
147
- });
148
-
149
- it('should include track details in playlist', async () => {
150
- const playlist = await youtube.getPlaylist('PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf', mockConfig);
151
-
152
- if (playlist.tracks.length > 0) {
153
- const track = playlist.tracks[0];
154
- assert(track.id, 'Track should have id');
155
- assert(track.title, 'Track should have title');
156
- assert(track.streamUrl, 'Track should have streamUrl');
157
- }
158
- });
159
- });
160
-
161
- describe('getRelated', () => {
162
- it('should return related videos', async () => {
163
- const related = await youtube.getRelated('dQw4w9WgXcQ', 5, mockConfig);
164
-
165
- assert(related.tracks, 'Should have tracks');
166
- assert(Array.isArray(related.tracks), 'Tracks should be array');
167
- assert.strictEqual(related.source, 'youtube');
168
- });
169
-
170
- it('should respect limit', async () => {
171
- const related = await youtube.getRelated('dQw4w9WgXcQ', 3, mockConfig);
172
- assert(related.tracks.length <= 3, 'Should not exceed limit');
173
- });
174
-
175
- it('should not include source video in results', async () => {
176
- const sourceId = 'dQw4w9WgXcQ';
177
- const related = await youtube.getRelated(sourceId, 5, mockConfig);
178
-
179
- const hasSourceVideo = related.tracks.some(t => t.id === sourceId);
180
- assert(!hasSourceVideo, 'Should not include source video');
181
- });
182
-
183
- it('should mark tracks as autoplay', async () => {
184
- const related = await youtube.getRelated('dQw4w9WgXcQ', 3, mockConfig);
185
-
186
- if (related.tracks.length > 0) {
187
- assert.strictEqual(related.tracks[0].isAutoplay, true, 'Should be marked as autoplay');
188
- }
189
- });
190
- });
191
-
192
- describe('edge cases', () => {
193
- it('should handle age-restricted content', async () => {
194
- // This test may fail without cookies - that's expected
195
- try {
196
- const info = await youtube.getInfo('6kLq3WMV1nU', mockConfig);
197
- assert(info.id, 'Should get info if cookies available');
198
- } catch (e) {
199
- assert(e.message.includes('yt-dlp'), 'Should fail gracefully without cookies');
200
- }
201
- });
202
-
203
- it('should handle deleted/private videos', async () => {
204
- await assert.rejects(
205
- () => youtube.getInfo('aaaaaaaaaaa', mockConfig),
206
- /yt-dlp/
207
- );
208
- });
209
-
210
- it('should handle region-blocked content gracefully', async () => {
211
- // Most region blocks should produce an error from yt-dlp
212
- try {
213
- await youtube.getInfo('_some_blocked_video_', mockConfig);
214
- } catch (e) {
215
- assert(e.message, 'Should throw with message');
216
- }
217
- });
218
- });
219
- });
@@ -1,26 +0,0 @@
1
- # Netscape HTTP Cookie File
2
- # This file is generated by yt-dlp. Do not edit.
3
-
4
- .youtube.com TRUE / TRUE 1800398983 __Secure-YENID 12.YTE=UfQjguVvlx3WLiJJHSjg4nPS-N-5O3Xj8RZj-wlLmRdjAvaF3TRdMzSmyUmo82Z4P-tggpd89U5d3hMDN886ZuUZUzi5XdEFEmHjL0YrTPBwPhD6pZx5CJ-3bNb3Eb_7eZuq_YlqQb0OX6Hvu2yYtWfWZPq7dZUjnJarOqJB0UaWu4jlsn27LkAmA9ecZK7Tj0NXQsIiDMR_y8pHe-kOfQ9LhLBeMnUWvR7GXsSOo_NqyfHrNnu4W8YnBd45ZUQIhwQ91X7lhuTkbBj3hYNJsWv0G7yda1NfB8j-nh8ZkordnGPIyv5QlCTd745j2DiGeS1GSa2jP2bClx7SoQxTjQ
5
- .youtube.com TRUE / FALSE 0 PREF f6=40000000&tz=UTC&hl=en
6
- .youtube.com TRUE / TRUE 1782082203 NID 527=aqYd85605VNHKMN7IAs-QcA6YfpJm6LGDAjKm929dxg81_ly4EHuc_A0jCgct9sjP-yDkNobeQPSES7fdZYHdzmlnHO_gGQ-oVCIbS3GQvSB89DCDEPB-toK2K62rr6iUVoTg3lcUG5xBhVXwoPPOD6VWWqegOp-IOhJhTb7Ijp_899mbKpj-4Elx8vNwUL0X-lJAe5Th-4Mxv9lDynXDH8axGjFhMHboeuTOHiIXRg10-4BoqyhAGFDhKNohiMwDc66EraGHim03-ZM
7
- .youtube.com TRUE / TRUE 1800826170 __Secure-1PSIDTS sidts-CjUB7I_69MoGgU9hYcmJtLk5dHx1d0LjE7gLaoN86V6V3M8eyIyUH6LOPPFj2llBVQAVsulbqRAA
8
- .youtube.com TRUE / TRUE 1800826170 __Secure-3PSIDTS sidts-CjUB7I_69MoGgU9hYcmJtLk5dHx1d0LjE7gLaoN86V6V3M8eyIyUH6LOPPFj2llBVQAVsulbqRAA
9
- .youtube.com TRUE / FALSE 1803850170 HSID Ab4swI6vjvKUnUkhu
10
- .youtube.com TRUE / TRUE 1803850170 SSID AaxSz8h17yLe-BmmX
11
- .youtube.com TRUE / FALSE 1803850170 APISID pQgk6uQUwAqRtThp/Ape45AAtgBDxnzVco
12
- .youtube.com TRUE / TRUE 1803850170 SAPISID y_RgVkrBXATC2XrL/Avlu8CWS6dwZ7LTEg
13
- .youtube.com TRUE / TRUE 1803850170 __Secure-1PAPISID y_RgVkrBXATC2XrL/Avlu8CWS6dwZ7LTEg
14
- .youtube.com TRUE / TRUE 1803850170 __Secure-3PAPISID y_RgVkrBXATC2XrL/Avlu8CWS6dwZ7LTEg
15
- .youtube.com TRUE / FALSE 1803850170 SID g.a0006AhyolP4RoeyrQXcHsFnRGkuVLVIZ9QQsgpwFaXGd822GTtb98Ev6KQIph7SQPbMD4aekgACgYKAaMSARMSFQHGX2MijLBjWKdOhQm5VmUkh9wlRhoVAUF8yKqE_WWJQO8PgiZpXVV1MiB30076
16
- .youtube.com TRUE / TRUE 1803850170 __Secure-1PSID g.a0006AhyolP4RoeyrQXcHsFnRGkuVLVIZ9QQsgpwFaXGd822GTtb9khH10B1YSjuMht-R8LNjAACgYKAQ8SARMSFQHGX2MiWX5D8_L5MAZK1TLabPQMghoVAUF8yKoFUiQLoi8zHLuskryhcx1P0076
17
- .youtube.com TRUE / TRUE 1803850170 __Secure-3PSID g.a0006AhyolP4RoeyrQXcHsFnRGkuVLVIZ9QQsgpwFaXGd822GTtbc5VtVrqvDy9fWzO4vguctgACgYKAUkSARMSFQHGX2MinKYgh3CtvTW5E5T8SwXiERoVAUF8yKqzIJTS4ajNX5uO8nh3r0j10076
18
- .youtube.com TRUE / TRUE 1803850170 LOGIN_INFO AFmmF2swRQIgH6IrdLYFOhW8xu4opIUHTGxAf33LzI5EXw6pdoqsh_gCIQCxYHQL4VZEyb3nE-rhXM6VU2ua99G4AhzKl4JJlzZBEQ:QUQ3MjNmeFpJOS1rVDgtM2I4cm50Z3M4NUplLTlSbXV4OFl4MTM5eUtHX3FEcVNmT2ltVFlSWmpQdlR2QTVqR29mZlUtTVh4OEhkOGw4Rkd5d2tQZm52NXJmQzdrMFJPVk5uYTFLNFFMZWlGelJhRVk1TkVaMm9Uby0xWlcwR3ozYkwwY2lWT21pV2dpU0lsWW5saFhMektISWxwUkRUcXl3
19
- .youtube.com TRUE / FALSE 1803305829 SIDCC AKEyXzVSEL6KtSGHvInzUQ0BSfXpz5ZrLa-0C-Eai37AQJIjMlJt1w_sEekg2V8xFZDAAGxTWAw
20
- .youtube.com TRUE / TRUE 1803305829 __Secure-1PSIDCC AKEyXzXpSwFxdQf2HR6oN-bhlMdxFzAE_V_Yj8xI1esygZBBs74ztRf0QOQkFC9uwI136LDjIA
21
- .youtube.com TRUE / TRUE 1803305829 __Secure-3PSIDCC AKEyXzUPIscYupkn1WfA8pYnKB611cDvKT0mlN3DFM6aP68r90lpGrwcI3cggeJuvS__Yir28g
22
- .youtube.com TRUE / TRUE 1787290794 __Secure-YNID 16.YT=uhIB3j65_j5F-nN_AIVu93J6J4tqe4fviGdBQuGk0X5EW7VRESfm4qMadhbgM04D7x1YyYRXKI0UIHJjiRMWqsP5PmT_qrHoTUSn4MOLA-FPeX09ELODYdpGvps9F6B3EFC2jC4MXYiWVY6KGZRiEoYBh_KWkh4Suwgn38LgfqN0E4Xv3YAzCB390qeKtLVkaqlQDUIvhnqGBPrObW-DzawPn00gHQph8VM2Zrklq_BzRYVaZHKHs2WkKlHqLljxwOiNXcsLrIkLqGsCgKR_onVOnlWN2gd0zojNv0VyuwYgfB9GBOLzweTnTWBZmp9IPWRA39DH4zMFerdTND-Yfg
23
- .youtube.com TRUE / TRUE 0 YSC -LHUdUOZvC4
24
- .youtube.com TRUE / TRUE 1787321829 VISITOR_INFO1_LIVE AuEVGsoJz2Y
25
- .youtube.com TRUE / TRUE 1787321829 VISITOR_PRIVACY_METADATA CgJVUxIEGgAgVQ%3D%3D
26
- .youtube.com TRUE / TRUE 1787290794 __Secure-ROLLOUT_TOKEN CIbdoKq8kOipXhC__cjij6WSAxiZi8-rseySAw%3D%3D