itube-specs 0.0.710 → 0.0.713
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/package.json +1 -1
- package/runtime/utils/cleaners/clean-category-card.test.ts +45 -0
- package/runtime/utils/cleaners/clean-category-info.test.ts +42 -0
- package/runtime/utils/cleaners/clean-channel-card.test.ts +44 -0
- package/runtime/utils/cleaners/clean-channel-info.test.ts +41 -0
- package/runtime/utils/cleaners/clean-mini-category-card.test.ts +31 -0
- package/runtime/utils/cleaners/clean-model-card.test.ts +57 -0
- package/runtime/utils/cleaners/clean-playlist-card.test.ts +45 -0
- package/runtime/utils/cleaners/clean-playlist-data.test.ts +42 -0
- package/runtime/utils/cleaners/clean-playlist-video.test.ts +39 -0
- package/runtime/utils/cleaners/clean-profile-data.test.ts +30 -0
- package/runtime/utils/cleaners/clean-user-playlists-card.test.ts +40 -0
- package/runtime/utils/cleaners/clean-video-card.test.ts +57 -0
- package/runtime/utils/cleaners/clean-video-data.test.ts +57 -0
- package/runtime/utils/converters/convert-categories-to-chips.test.ts +26 -0
- package/runtime/utils/converters/convert-categories-to-footer.test.ts +20 -0
- package/runtime/utils/converters/convert-date-to-timestamp.test.ts +38 -0
- package/runtime/utils/converters/convert-model-card-to-chips.test.ts +20 -0
- package/runtime/utils/converters/convert-query-categories.test.ts +22 -0
- package/runtime/utils/converters/convert-snake-keys-to-camel.test.ts +29 -0
- package/runtime/utils/converters/convert-string-array-to-chips.test.ts +21 -0
- package/runtime/utils/converters/convert-string.test.ts +78 -0
- package/runtime/utils/converters/group-categories-by-first-letter.test.ts +46 -0
- package/runtime/utils/converters/group-objects-by-first-letter.test.ts +33 -0
- package/runtime/utils/format-date.test.ts +18 -0
- package/runtime/utils/format-number.test.ts +24 -0
- package/runtime/utils/format-time.test.ts +24 -0
- package/runtime/utils/get-duration.test.ts +24 -0
- package/runtime/utils/get-month.test.ts +30 -0
- package/runtime/utils/get-multiple-query.test.ts +32 -0
- package/runtime/utils/get-selected-query.test.ts +24 -0
- package/runtime/utils/is-mobile-device.test.ts +24 -0
- package/runtime/utils/normalize-url.test.ts +59 -0
- package/runtime/utils/server/parse-api-error.test.ts +36 -0
- package/runtime/utils/validate-email.test.ts +32 -0
- package/runtime/utils/validate-password.test.ts +20 -0
- package/runtime/utils/validate-phone.test.ts +32 -0
- package/runtime/utils/validate-username.test.ts +36 -0
- package/runtime/utils/video-data-add-model-icon.test.ts +32 -0
package/package.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanCategoryCard } from './clean-category-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanCategoryCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
name: 'teen',
|
|
8
|
+
title: 'Teen',
|
|
9
|
+
videosCount: 100,
|
|
10
|
+
video_thumb_urls: {
|
|
11
|
+
webp: { '320x180': 'https://img.com/small.webp' },
|
|
12
|
+
},
|
|
13
|
+
guid: 'abc-123',
|
|
14
|
+
description: 'Test desc',
|
|
15
|
+
icon: 'icon.svg',
|
|
16
|
+
};
|
|
17
|
+
const result = cleanCategoryCard(raw as any);
|
|
18
|
+
expect(result).toEqual({
|
|
19
|
+
name: 'teen',
|
|
20
|
+
title: 'Teen',
|
|
21
|
+
videosCount: 100,
|
|
22
|
+
thumbUrls: { webp: { '320x180': 'https://img.com/small.webp' } },
|
|
23
|
+
guid: 'abc-123',
|
|
24
|
+
description: 'Test desc',
|
|
25
|
+
icon: 'icon.svg',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('пустые данные → дефолты', () => {
|
|
30
|
+
const result = cleanCategoryCard({} as any);
|
|
31
|
+
expect(result.name).toBe('');
|
|
32
|
+
expect(result.title).toBe('');
|
|
33
|
+
expect(result.videosCount).toBe(0);
|
|
34
|
+
expect(result.thumbUrls).toBeUndefined();
|
|
35
|
+
expect(result.guid).toBe('');
|
|
36
|
+
expect(result.description).toBe('');
|
|
37
|
+
expect(result.icon).toBe('');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('thumbUrls без нужного размера', () => {
|
|
41
|
+
const raw = { video_thumb_urls: { webp: {} } };
|
|
42
|
+
const result = cleanCategoryCard(raw as any);
|
|
43
|
+
expect(result.thumbUrls).toEqual({ webp: { '320x180': '' } });
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanCategoryInfo } from './clean-category-info';
|
|
3
|
+
|
|
4
|
+
describe('cleanCategoryInfo', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'abc',
|
|
8
|
+
title: 'Teen',
|
|
9
|
+
videosCount: 50,
|
|
10
|
+
description: 'desc',
|
|
11
|
+
fullDescription: 'full desc',
|
|
12
|
+
related: [{ title: 'MILF', name: 'milf' }],
|
|
13
|
+
meta_description: 'meta desc',
|
|
14
|
+
meta_title: 'meta title',
|
|
15
|
+
header: 'h1 header',
|
|
16
|
+
};
|
|
17
|
+
const result = cleanCategoryInfo(raw as any);
|
|
18
|
+
expect(result.guid).toBe('abc');
|
|
19
|
+
expect(result.title).toBe('Teen');
|
|
20
|
+
expect(result.videosCount).toBe(50);
|
|
21
|
+
expect(result.fullDescription).toBe('full desc');
|
|
22
|
+
expect(result.metaDescription).toBe('meta desc');
|
|
23
|
+
expect(result.metaTitle).toBe('meta title');
|
|
24
|
+
expect(result.header).toBe('h1 header');
|
|
25
|
+
expect(result.related).toEqual([
|
|
26
|
+
{ title: 'MILF', value: 'milf', prefix: 'categories' },
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('пустые данные → дефолты', () => {
|
|
31
|
+
const result = cleanCategoryInfo({} as any);
|
|
32
|
+
expect(result.guid).toBe('');
|
|
33
|
+
expect(result.title).toBe('');
|
|
34
|
+
expect(result.videosCount).toBe(0);
|
|
35
|
+
expect(result.description).toBe('');
|
|
36
|
+
expect(result.fullDescription).toBe('');
|
|
37
|
+
expect(result.related).toEqual([]);
|
|
38
|
+
expect(result.metaDescription).toBe('');
|
|
39
|
+
expect(result.metaTitle).toBe('');
|
|
40
|
+
expect(result.header).toBe('');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanChannelCard } from './clean-channel-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanChannelCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'ch-1',
|
|
8
|
+
name: 'Channel',
|
|
9
|
+
url: '/channel/1',
|
|
10
|
+
videos_count: 200,
|
|
11
|
+
is_network: true,
|
|
12
|
+
updated: 1700000000,
|
|
13
|
+
avatar_url: 'https://img.com/avatar.jpg',
|
|
14
|
+
video_thumb_urls: {
|
|
15
|
+
webp: {
|
|
16
|
+
'320x180': 'https://img.com/s.webp',
|
|
17
|
+
'480x270': 'https://img.com/m.webp',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
description: 'Channel desc',
|
|
21
|
+
};
|
|
22
|
+
const result = cleanChannelCard(raw as any);
|
|
23
|
+
expect(result.guid).toBe('ch-1');
|
|
24
|
+
expect(result.name).toBe('Channel');
|
|
25
|
+
expect(result.videosCount).toBe(200);
|
|
26
|
+
expect(result.isNetwork).toBe(true);
|
|
27
|
+
expect(result.avatarUrl).toBe('https://img.com/avatar.jpg');
|
|
28
|
+
expect(result.thumbUrls).toEqual({
|
|
29
|
+
webp: {
|
|
30
|
+
'320x180': 'https://img.com/s.webp',
|
|
31
|
+
'480x270': 'https://img.com/m.webp',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('пустые данные → дефолты', () => {
|
|
37
|
+
const result = cleanChannelCard({} as any);
|
|
38
|
+
expect(result.guid).toBe('');
|
|
39
|
+
expect(result.name).toBe('');
|
|
40
|
+
expect(result.videosCount).toBe(0);
|
|
41
|
+
expect(result.isNetwork).toBe(false);
|
|
42
|
+
expect(result.thumbUrls).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanChannelInfo } from './clean-channel-info';
|
|
3
|
+
|
|
4
|
+
describe('cleanChannelInfo', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'ch-1',
|
|
8
|
+
name: 'Channel Name',
|
|
9
|
+
url: '/channel/1',
|
|
10
|
+
description: 'desc',
|
|
11
|
+
videos_count: 100,
|
|
12
|
+
is_network: false,
|
|
13
|
+
updated: 1700000000,
|
|
14
|
+
avatar_url: 'https://img.com/avatar.jpg',
|
|
15
|
+
video_thumb_urls: { webp: { '320x180': 'https://img.com/s.webp' } },
|
|
16
|
+
tags: ['tag1', 'tag2'],
|
|
17
|
+
};
|
|
18
|
+
const result = cleanChannelInfo(raw as any);
|
|
19
|
+
expect(result.title).toBe('Channel Name');
|
|
20
|
+
expect(result.img).toBe('https://img.com/avatar.jpg');
|
|
21
|
+
expect(result.tags).toEqual(['tag1', 'tag2']);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('без avatar_url → берёт thumb', () => {
|
|
25
|
+
const raw = {
|
|
26
|
+
avatar_url: '',
|
|
27
|
+
video_thumb_urls: { webp: { '320x180': 'https://img.com/thumb.webp' } },
|
|
28
|
+
};
|
|
29
|
+
const result = cleanChannelInfo(raw as any);
|
|
30
|
+
expect(result.img).toBe('https://img.com/thumb.webp');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('пустые данные с пустым webp → дефолты', () => {
|
|
34
|
+
const raw = { video_thumb_urls: { webp: {} } };
|
|
35
|
+
const result = cleanChannelInfo(raw as any);
|
|
36
|
+
expect(result.guid).toBe('');
|
|
37
|
+
expect(result.title).toBe('');
|
|
38
|
+
expect(result.videosCount).toBe(0);
|
|
39
|
+
expect(result.tags).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanMiniCategoryCard } from './clean-mini-category-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanMiniCategoryCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
name: 'teen',
|
|
8
|
+
title: 'Teen',
|
|
9
|
+
is_top: true,
|
|
10
|
+
videosCount: 50,
|
|
11
|
+
icon: 'icon.svg',
|
|
12
|
+
};
|
|
13
|
+
const result = cleanMiniCategoryCard(raw as any);
|
|
14
|
+
expect(result).toEqual({
|
|
15
|
+
name: 'teen',
|
|
16
|
+
title: 'Teen',
|
|
17
|
+
isTop: true,
|
|
18
|
+
videosCount: 50,
|
|
19
|
+
icon: 'icon.svg',
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('пустые данные → дефолты', () => {
|
|
24
|
+
const result = cleanMiniCategoryCard({} as any);
|
|
25
|
+
expect(result.name).toBe('');
|
|
26
|
+
expect(result.title).toBe('');
|
|
27
|
+
expect(result.isTop).toBe(false);
|
|
28
|
+
expect(result.videosCount).toBe(0);
|
|
29
|
+
expect(result.icon).toBeUndefined();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanModelCard } from './clean-model-card';
|
|
3
|
+
|
|
4
|
+
const makeRaw = (overrides = {}) => ({
|
|
5
|
+
title: 'Model Name',
|
|
6
|
+
videos_count: 10,
|
|
7
|
+
video_thumb_urls: { webp: { '320x180': 'https://img.com/s.webp' } },
|
|
8
|
+
primary_image_url: 'https://img.com/primary.jpg',
|
|
9
|
+
guid: 'model-1',
|
|
10
|
+
parameters: [
|
|
11
|
+
{ name: 'birthplace_country', values: [{ title: 'USA', name: 'usa' }] },
|
|
12
|
+
{ name: 'age', values: [{ title: '25' }] },
|
|
13
|
+
{ name: 'height_cm', values: [{ title: '170' }] },
|
|
14
|
+
{ name: 'weight_kg', values: [{ title: '55' }] },
|
|
15
|
+
],
|
|
16
|
+
...overrides,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('cleanModelCard', () => {
|
|
20
|
+
it('полные данные', () => {
|
|
21
|
+
const result = cleanModelCard(makeRaw() as any);
|
|
22
|
+
expect(result.title).toBe('Model Name');
|
|
23
|
+
expect(result.videosCount).toBe(10);
|
|
24
|
+
expect(result.thumbUrl).toBe('https://img.com/s.webp');
|
|
25
|
+
expect(result.guid).toBe('model-1');
|
|
26
|
+
expect(result.country).toEqual({ title: 'USA', name: 'usa' });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('параметры: age, height, weight', () => {
|
|
30
|
+
const result = cleanModelCard(makeRaw() as any);
|
|
31
|
+
expect(result.parameters).toEqual([
|
|
32
|
+
{ title: 'age', value: '25' },
|
|
33
|
+
{ title: 'height_cm', value: '170' },
|
|
34
|
+
{ title: 'weight_kg', value: '55' },
|
|
35
|
+
]);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('без age → параметры без age', () => {
|
|
39
|
+
const raw = makeRaw({
|
|
40
|
+
parameters: [
|
|
41
|
+
{ name: 'birthplace_country', values: [{ title: 'USA', name: 'usa' }] },
|
|
42
|
+
{ name: 'height_cm', values: [{ title: '170' }] },
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
const result = cleanModelCard(raw as any);
|
|
46
|
+
expect(result.parameters).toEqual([
|
|
47
|
+
{ title: 'height_cm', value: '170' },
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('пустые параметры', () => {
|
|
52
|
+
const raw = makeRaw({ parameters: [] });
|
|
53
|
+
const result = cleanModelCard(raw as any);
|
|
54
|
+
expect(result.country).toEqual({ title: '', name: '' });
|
|
55
|
+
expect(result.parameters).toEqual([]);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanPlaylistCard } from './clean-playlist-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanPlaylistCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
created: 1700000000,
|
|
8
|
+
id: 'pl-1',
|
|
9
|
+
name: 'My Playlist',
|
|
10
|
+
username: 'user1',
|
|
11
|
+
playlist_type: 'public',
|
|
12
|
+
thumbs: [
|
|
13
|
+
{ urls: { webp: { '320x180': 'https://img.com/s1.webp', '480x270': 'https://img.com/m1.webp' } } },
|
|
14
|
+
],
|
|
15
|
+
videos_count: 5,
|
|
16
|
+
first_video_id: 'v-1',
|
|
17
|
+
search_tags: 'tag1,tag2',
|
|
18
|
+
views: 100,
|
|
19
|
+
likes: 10,
|
|
20
|
+
dislikes: 2,
|
|
21
|
+
};
|
|
22
|
+
const result = cleanPlaylistCard(raw as any);
|
|
23
|
+
expect(result.id).toBe('pl-1');
|
|
24
|
+
expect(result.name).toBe('My Playlist');
|
|
25
|
+
expect(result.playlistType).toBe('public');
|
|
26
|
+
expect(result.videosCount).toBe(5);
|
|
27
|
+
expect(result.thumbUrls).toHaveLength(1);
|
|
28
|
+
expect(result.thumbUrls![0]).toEqual({
|
|
29
|
+
webp: {
|
|
30
|
+
'320x180': 'https://img.com/s1.webp',
|
|
31
|
+
'480x270': 'https://img.com/m1.webp',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('пустые данные → дефолты', () => {
|
|
37
|
+
const result = cleanPlaylistCard({} as any);
|
|
38
|
+
expect(result.id).toBe('');
|
|
39
|
+
expect(result.name).toBe('');
|
|
40
|
+
expect(result.videosCount).toBe(0);
|
|
41
|
+
expect(result.views).toBe(0);
|
|
42
|
+
expect(result.likes).toBe(0);
|
|
43
|
+
expect(result.dislikes).toBe(0);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanPlaylistData } from './clean-playlist-data';
|
|
3
|
+
|
|
4
|
+
describe('cleanPlaylistData', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
updated: 1700000000,
|
|
8
|
+
id: 'pl-1',
|
|
9
|
+
name: 'Playlist',
|
|
10
|
+
username: 'user1',
|
|
11
|
+
playlist_type: 'private',
|
|
12
|
+
videos_count: 10,
|
|
13
|
+
first_video_id: 'v-1',
|
|
14
|
+
search_tags: 'tags',
|
|
15
|
+
views: 200,
|
|
16
|
+
likes: 20,
|
|
17
|
+
dislikes: 3,
|
|
18
|
+
};
|
|
19
|
+
const result = cleanPlaylistData(raw as any);
|
|
20
|
+
expect(result).toEqual({
|
|
21
|
+
updated: 1700000000,
|
|
22
|
+
id: 'pl-1',
|
|
23
|
+
name: 'Playlist',
|
|
24
|
+
username: 'user1',
|
|
25
|
+
playlistType: 'private',
|
|
26
|
+
videosCount: 10,
|
|
27
|
+
firstVideoId: 'v-1',
|
|
28
|
+
searchTags: 'tags',
|
|
29
|
+
views: 200,
|
|
30
|
+
likes: 20,
|
|
31
|
+
dislikes: 3,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('пустые данные → дефолты', () => {
|
|
36
|
+
const result = cleanPlaylistData({} as any);
|
|
37
|
+
expect(result.updated).toBe(0);
|
|
38
|
+
expect(result.id).toBe('');
|
|
39
|
+
expect(result.videosCount).toBe(0);
|
|
40
|
+
expect(result.views).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanPlaylistVideo } from './clean-playlist-video';
|
|
3
|
+
|
|
4
|
+
describe('cleanPlaylistVideo', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'v-1',
|
|
8
|
+
duration: 300,
|
|
9
|
+
title: 'Video Title',
|
|
10
|
+
id: 'id-1',
|
|
11
|
+
thumb_urls: {
|
|
12
|
+
webp: {
|
|
13
|
+
'320x180': 'https://img.com/s.webp',
|
|
14
|
+
'480x270': 'https://img.com/m.webp',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
md5: 'abc123',
|
|
18
|
+
};
|
|
19
|
+
const result = cleanPlaylistVideo(raw as any);
|
|
20
|
+
expect(result.guid).toBe('v-1');
|
|
21
|
+
expect(result.duration).toBe(300);
|
|
22
|
+
expect(result.title).toBe('Video Title');
|
|
23
|
+
expect(result.thumbUrls).toEqual({
|
|
24
|
+
webp: {
|
|
25
|
+
'320x180': 'https://img.com/s.webp',
|
|
26
|
+
'480x270': 'https://img.com/m.webp',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('пустые данные → дефолты', () => {
|
|
32
|
+
const result = cleanPlaylistVideo({} as any);
|
|
33
|
+
expect(result.guid).toBe('');
|
|
34
|
+
expect(result.duration).toBe(0);
|
|
35
|
+
expect(result.title).toBe('');
|
|
36
|
+
expect(result.thumbUrls).toBeUndefined();
|
|
37
|
+
expect(result.md5).toBe('');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanProfileData } from './clean-profile-data';
|
|
3
|
+
|
|
4
|
+
describe('cleanProfileData', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
username: 'john',
|
|
8
|
+
email: 'john@test.com',
|
|
9
|
+
avatar: 'https://img.com/avatar.jpg',
|
|
10
|
+
country: 'US',
|
|
11
|
+
city: 'NYC',
|
|
12
|
+
birthday: 946684800,
|
|
13
|
+
gender: 'male',
|
|
14
|
+
created: 1700000000,
|
|
15
|
+
};
|
|
16
|
+
const result = cleanProfileData(raw as any);
|
|
17
|
+
expect(result).toEqual(raw);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('пустые данные → дефолты', () => {
|
|
21
|
+
const result = cleanProfileData({} as any);
|
|
22
|
+
expect(result.username).toBe('');
|
|
23
|
+
expect(result.email).toBe('');
|
|
24
|
+
expect(result.avatar).toBe('');
|
|
25
|
+
expect(result.country).toBe('');
|
|
26
|
+
expect(result.birthday).toBe(0);
|
|
27
|
+
expect(result.gender).toBe('');
|
|
28
|
+
expect(result.created).toBe(0);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanUserPlaylistCard } from './clean-user-playlists-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanUserPlaylistCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
created: 1700000000,
|
|
8
|
+
id: 'pl-1',
|
|
9
|
+
name: 'My Playlist',
|
|
10
|
+
username: 'user1',
|
|
11
|
+
playlistType: 'public',
|
|
12
|
+
thumbs: [
|
|
13
|
+
'https://img.com/1.webp',
|
|
14
|
+
'https://img.com/2.webp',
|
|
15
|
+
'https://img.com/3.webp',
|
|
16
|
+
'https://img.com/4.webp',
|
|
17
|
+
'https://img.com/5.webp',
|
|
18
|
+
],
|
|
19
|
+
videoCount: 10,
|
|
20
|
+
firstVideoID: 'v-1',
|
|
21
|
+
};
|
|
22
|
+
const result = cleanUserPlaylistCard(raw as any);
|
|
23
|
+
expect(result.id).toBe('pl-1');
|
|
24
|
+
expect(result.playlistType).toBe('public');
|
|
25
|
+
expect(result.videosCount).toBe(10);
|
|
26
|
+
expect(result.firstVideoId).toBe('v-1');
|
|
27
|
+
expect(result.thumbUrls).toHaveLength(4); // slice(0, 4)
|
|
28
|
+
expect(result.thumbUrls![0]).toEqual({
|
|
29
|
+
webp: { '320x180': 'https://img.com/1.webp' },
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('пустые данные → дефолты', () => {
|
|
34
|
+
const result = cleanUserPlaylistCard({} as any);
|
|
35
|
+
expect(result.id).toBe('');
|
|
36
|
+
expect(result.name).toBe('');
|
|
37
|
+
expect(result.videosCount).toBe(0);
|
|
38
|
+
expect(result.thumbUrls).toEqual([]);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanVideoCard } from './clean-video-card';
|
|
3
|
+
|
|
4
|
+
describe('cleanVideoCard', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'v-1',
|
|
8
|
+
quality: '1080p',
|
|
9
|
+
duration: 600,
|
|
10
|
+
title: 'Video Title',
|
|
11
|
+
views: 1000,
|
|
12
|
+
id: 'id-1',
|
|
13
|
+
tags: 'tag1,tag2',
|
|
14
|
+
is_new: true,
|
|
15
|
+
channel: { avatar_url: 'https://img.com/ch.jpg', name: 'Channel' },
|
|
16
|
+
url: '/video/1',
|
|
17
|
+
preview_url: 'https://img.com/preview.mp4',
|
|
18
|
+
thumb_urls: {
|
|
19
|
+
webp: {
|
|
20
|
+
'320x180': 'https://img.com/s.webp',
|
|
21
|
+
'480x270': 'https://img.com/m.webp',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
md5: 'abc',
|
|
25
|
+
thumb_number: 3,
|
|
26
|
+
models: [{ title: 'Model A' }, { title: 'Model B' }],
|
|
27
|
+
};
|
|
28
|
+
const result = cleanVideoCard(raw as any);
|
|
29
|
+
expect(result.guid).toBe('v-1');
|
|
30
|
+
expect(result.quality).toBe('1080p');
|
|
31
|
+
expect(result.isNew).toBe(true);
|
|
32
|
+
expect(result.channelName).toBe('Channel');
|
|
33
|
+
expect(result.channelAvatar).toBe('https://img.com/ch.jpg');
|
|
34
|
+
expect(result.models).toEqual(['Model A', 'Model B']);
|
|
35
|
+
expect(result.thumbNum).toBe(3);
|
|
36
|
+
expect(result.thumbUrls).toEqual({
|
|
37
|
+
webp: {
|
|
38
|
+
'320x180': 'https://img.com/s.webp',
|
|
39
|
+
'480x270': 'https://img.com/m.webp',
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('пустые данные → дефолты', () => {
|
|
45
|
+
const result = cleanVideoCard({} as any);
|
|
46
|
+
expect(result.guid).toBe('');
|
|
47
|
+
expect(result.quality).toBe('');
|
|
48
|
+
expect(result.duration).toBe(0);
|
|
49
|
+
expect(result.views).toBe(0);
|
|
50
|
+
expect(result.isNew).toBe(false);
|
|
51
|
+
expect(result.channelAvatar).toBe('');
|
|
52
|
+
expect(result.channelName).toBe('');
|
|
53
|
+
expect(result.thumbUrls).toBeUndefined();
|
|
54
|
+
expect(result.models).toEqual([]);
|
|
55
|
+
expect(result.thumbNum).toBe(0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { cleanVideoData } from './clean-video-data';
|
|
3
|
+
|
|
4
|
+
describe('cleanVideoData', () => {
|
|
5
|
+
it('полные данные', () => {
|
|
6
|
+
const raw = {
|
|
7
|
+
guid: 'v-1',
|
|
8
|
+
md5: 'abc',
|
|
9
|
+
quality: '1080p',
|
|
10
|
+
duration: 600,
|
|
11
|
+
title: 'Title',
|
|
12
|
+
header: 'Header',
|
|
13
|
+
views: 1000,
|
|
14
|
+
likes: 100,
|
|
15
|
+
id: 'id-1',
|
|
16
|
+
tags: 'tag1',
|
|
17
|
+
models: 'model1',
|
|
18
|
+
categories: 'cat1',
|
|
19
|
+
actions: { liked: true },
|
|
20
|
+
channel: { name: 'Channel', avatar_url: 'https://img.com/ch.jpg' },
|
|
21
|
+
url: '/video/1',
|
|
22
|
+
preview_url: 'https://img.com/preview.mp4',
|
|
23
|
+
thumb_urls: { webp: { '320x180': 'small' } },
|
|
24
|
+
vtt_url: '/vtt',
|
|
25
|
+
vtt_sprite_url: '/sprite',
|
|
26
|
+
created: 1700000000,
|
|
27
|
+
video_url: '/stream',
|
|
28
|
+
is_deleted: false,
|
|
29
|
+
thumb_number: 5,
|
|
30
|
+
description: 'desc',
|
|
31
|
+
dislikes: 3,
|
|
32
|
+
};
|
|
33
|
+
const result = cleanVideoData(raw as any);
|
|
34
|
+
expect(result.guid).toBe('v-1');
|
|
35
|
+
expect(result.channelName).toBe('Channel');
|
|
36
|
+
expect(result.thumbUrls).toEqual({ webp: { '320x180': 'small' } });
|
|
37
|
+
expect(result.vttUrl).toBe('/vtt');
|
|
38
|
+
expect(result.videoUrl).toBe('/stream');
|
|
39
|
+
expect(result.isDeleted).toBe(false);
|
|
40
|
+
expect(result.thumbNum).toBe(5);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('пустые данные → дефолты', () => {
|
|
44
|
+
const result = cleanVideoData({} as any);
|
|
45
|
+
expect(result.guid).toBe('');
|
|
46
|
+
expect(result.duration).toBe(0);
|
|
47
|
+
expect(result.views).toBe(0);
|
|
48
|
+
expect(result.likes).toBe(0);
|
|
49
|
+
expect(result.channelName).toBe('');
|
|
50
|
+
expect(result.channelAvatar).toBe('');
|
|
51
|
+
expect(result.thumbUrls).toBeUndefined();
|
|
52
|
+
expect(result.isDeleted).toBe(false);
|
|
53
|
+
expect(result.created).toBe(0);
|
|
54
|
+
expect(result.actions).toBe(null);
|
|
55
|
+
expect(result.dislikes).toBe(0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertCategoriesToChips } from './convert-categories-to-chips';
|
|
3
|
+
|
|
4
|
+
describe('convertCategoriesToChips', () => {
|
|
5
|
+
it('конвертирует массив категорий в чипсы', () => {
|
|
6
|
+
const items = [
|
|
7
|
+
{ title: 'Teen', name: 'teen' },
|
|
8
|
+
{ title: 'MILF', name: 'milf' },
|
|
9
|
+
];
|
|
10
|
+
const result = convertCategoriesToChips(items as any, 'categories');
|
|
11
|
+
expect(result).toEqual([
|
|
12
|
+
{ title: 'Teen', value: 'teen', prefix: 'categories' },
|
|
13
|
+
{ title: 'MILF', value: 'milf', prefix: 'categories' },
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('пустой массив', () => {
|
|
18
|
+
expect(convertCategoriesToChips([], 'categories')).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('использует переданный prefix', () => {
|
|
22
|
+
const items = [{ title: 'A', name: 'a' }];
|
|
23
|
+
const result = convertCategoriesToChips(items as any, 'models');
|
|
24
|
+
expect(result[0].prefix).toBe('models');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertCategoriesToFooter } from './convert-categories-to-footer';
|
|
3
|
+
|
|
4
|
+
describe('convertCategoriesToFooter', () => {
|
|
5
|
+
it('конвертирует категории в футер', () => {
|
|
6
|
+
const items = [
|
|
7
|
+
{ title: 'Teen', name: 'teen' },
|
|
8
|
+
{ title: 'MILF', name: 'milf' },
|
|
9
|
+
];
|
|
10
|
+
const result = convertCategoriesToFooter(items as any);
|
|
11
|
+
expect(result).toEqual([
|
|
12
|
+
{ title: 'Teen', name: 'teen' },
|
|
13
|
+
{ title: 'MILF', name: 'milf' },
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('пустой массив', () => {
|
|
18
|
+
expect(convertCategoriesToFooter([])).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertDateToTimestamp } from './convert-date-to-timestamp';
|
|
3
|
+
|
|
4
|
+
const c = convertDateToTimestamp();
|
|
5
|
+
|
|
6
|
+
describe('convertDateToTimestamp', () => {
|
|
7
|
+
describe('toUnix', () => {
|
|
8
|
+
it('валидная дата', () => {
|
|
9
|
+
expect(c.toUnix('2025-01-01')).toBe(Date.UTC(2025, 0, 1) / 1000);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('начало эпохи', () => {
|
|
13
|
+
expect(c.toUnix('1970-01-01')).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('невалидная дата → null', () => {
|
|
17
|
+
expect(c.toUnix('invalid')).toBe(null);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('fromUnix', () => {
|
|
22
|
+
it('timestamp → дата', () => {
|
|
23
|
+
expect(c.fromUnix(0)).toBe('1970-01-01');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('конкретная дата', () => {
|
|
27
|
+
const ts = Date.UTC(2024, 2, 5) / 1000;
|
|
28
|
+
expect(c.fromUnix(ts)).toBe('2024-03-05');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('roundtrip', () => {
|
|
33
|
+
it('toUnix → fromUnix', () => {
|
|
34
|
+
const date = '2024-03-05';
|
|
35
|
+
expect(c.fromUnix(c.toUnix(date)!)).toBe(date);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|