itube-specs 0.0.710 → 0.0.712
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/converters/convert-date-to-timestamp.test.ts +38 -0
- package/runtime/utils/converters/convert-snake-keys-to-camel.test.ts +29 -0
- package/runtime/utils/converters/convert-string.test.ts +78 -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/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/package.json
CHANGED
|
@@ -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
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertSnakeKeysToCamel } from './convert-snake-keys-to-camel';
|
|
3
|
+
|
|
4
|
+
describe('convertSnakeKeysToCamel', () => {
|
|
5
|
+
it('простой объект', () => {
|
|
6
|
+
expect(convertSnakeKeysToCamel({ user_name: 'John', is_active: true }))
|
|
7
|
+
.toEqual({ userName: 'John', isActive: true });
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('вложенный объект', () => {
|
|
11
|
+
expect(convertSnakeKeysToCamel({ user_info: { first_name: 'John' } }))
|
|
12
|
+
.toEqual({ userInfo: { firstName: 'John' } });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('массив объектов', () => {
|
|
16
|
+
expect(convertSnakeKeysToCamel([{ video_id: 1 }, { video_id: 2 }]))
|
|
17
|
+
.toEqual([{ videoId: 1 }, { videoId: 2 }]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('примитив возвращается как есть', () => {
|
|
21
|
+
expect(convertSnakeKeysToCamel('hello')).toBe('hello');
|
|
22
|
+
expect(convertSnakeKeysToCamel(42)).toBe(42);
|
|
23
|
+
expect(convertSnakeKeysToCamel(null)).toBe(null);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('ключ без подчёркиваний', () => {
|
|
27
|
+
expect(convertSnakeKeysToCamel({ name: 'John' })).toEqual({ name: 'John' });
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertString } from './convert-string';
|
|
3
|
+
|
|
4
|
+
const s = convertString();
|
|
5
|
+
|
|
6
|
+
describe('convertString', () => {
|
|
7
|
+
describe('toSlug', () => {
|
|
8
|
+
it('пробелы → дефисы', () => {
|
|
9
|
+
expect(s.toSlug('Big Tits')).toBe('big-tits');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('дефисы → подчёркивания', () => {
|
|
13
|
+
expect(s.toSlug('A-B')).toBe('a_b');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('подчёркивания → тильда', () => {
|
|
17
|
+
expect(s.toSlug('a_b')).toBe('a~b');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('fromSlug', () => {
|
|
22
|
+
it('дефисы → пробелы', () => {
|
|
23
|
+
expect(s.fromSlug('big-tits')).toBe('big tits');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('подчёркивания → дефисы', () => {
|
|
27
|
+
expect(s.fromSlug('a_b')).toBe('a-b');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('тильда → подчёркивание', () => {
|
|
31
|
+
expect(s.fromSlug('a~b')).toBe('a_b');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('toSnakeCase', () => {
|
|
36
|
+
it('camelCase', () => {
|
|
37
|
+
expect(s.toSnakeCase('bigTits')).toBe('big_tits');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('пробелы', () => {
|
|
41
|
+
expect(s.toSnakeCase('big tits')).toBe('big_tits');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('дефисы', () => {
|
|
45
|
+
expect(s.toSnakeCase('big-tits')).toBe('big_tits');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('toKebabCase', () => {
|
|
50
|
+
it('camelCase', () => {
|
|
51
|
+
expect(s.toKebabCase('bigTits')).toBe('big-tits');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('подчёркивания', () => {
|
|
55
|
+
expect(s.toKebabCase('big_tits')).toBe('big-tits');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('пробелы', () => {
|
|
59
|
+
expect(s.toKebabCase('big tits')).toBe('big-tits');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('toCapitalize', () => {
|
|
64
|
+
it('одно слово', () => {
|
|
65
|
+
expect(s.toCapitalize('teen')).toBe('Teen');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('несколько слов', () => {
|
|
69
|
+
expect(s.toCapitalize('big tits')).toBe('Big Tits');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('roundtrip', () => {
|
|
74
|
+
it('toSlug → fromSlug', () => {
|
|
75
|
+
expect(s.fromSlug(s.toSlug('Big Tits'))).toBe('big tits');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { groupObjectsByFirstLetter } from './group-objects-by-first-letter';
|
|
3
|
+
|
|
4
|
+
describe('groupObjectsByFirstLetter', () => {
|
|
5
|
+
const items = [
|
|
6
|
+
{ name: 'Alice' },
|
|
7
|
+
{ name: 'Anna' },
|
|
8
|
+
{ name: 'Bob' },
|
|
9
|
+
{ name: '123test' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
it('группирует по первой букве', () => {
|
|
13
|
+
const result = groupObjectsByFirstLetter(items, 'name');
|
|
14
|
+
expect(result['A']).toHaveLength(2);
|
|
15
|
+
expect(result['B']).toHaveLength(1);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('цифры попадают в POST', () => {
|
|
19
|
+
const result = groupObjectsByFirstLetter(items, 'name');
|
|
20
|
+
expect(result['POST']).toHaveLength(1);
|
|
21
|
+
expect(result['POST'][0]).toEqual({ name: '123test' });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('кастомный nonLetterKey', () => {
|
|
25
|
+
const result = groupObjectsByFirstLetter(items, 'name', 'OTHER');
|
|
26
|
+
expect(result['OTHER']).toHaveLength(1);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('пустой массив', () => {
|
|
30
|
+
const result = groupObjectsByFirstLetter([], 'name');
|
|
31
|
+
expect(result).toEqual({});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { formatDate } from './format-date';
|
|
3
|
+
|
|
4
|
+
describe('formatDate', () => {
|
|
5
|
+
it('обычная дата', () => {
|
|
6
|
+
// 2025-01-15 00:00:00 UTC
|
|
7
|
+
expect(formatDate(1736899200)).toBe('15.01.2025');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('начало эпохи', () => {
|
|
11
|
+
expect(formatDate(0)).toBe('01.01.1970');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('с padding нулей', () => {
|
|
15
|
+
// 2024-03-05 UTC
|
|
16
|
+
expect(formatDate(1709596800)).toBe('05.03.2024');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { formatNumber } from './format-number';
|
|
3
|
+
|
|
4
|
+
describe('formatNumber', () => {
|
|
5
|
+
it('тысячи', () => {
|
|
6
|
+
expect(formatNumber(10400)).toBe('10.4K');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('миллионы', () => {
|
|
10
|
+
expect(formatNumber(1500000)).toBe('1.5M');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('маленькое число без сокращения', () => {
|
|
14
|
+
expect(formatNumber(999)).toBe('999');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('ноль', () => {
|
|
18
|
+
expect(formatNumber(0)).toBe('0');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('ровно тысяча', () => {
|
|
22
|
+
expect(formatNumber(1000)).toBe('1K');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { formatTime } from './format-time';
|
|
3
|
+
|
|
4
|
+
describe('formatTime', () => {
|
|
5
|
+
it('только секунды', () => {
|
|
6
|
+
expect(formatTime(5)).toBe('00:05');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('минуты и секунды', () => {
|
|
10
|
+
expect(formatTime(65)).toBe('01:05');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('часы, минуты, секунды', () => {
|
|
14
|
+
expect(formatTime(3661)).toBe('01:01:01');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('ноль', () => {
|
|
18
|
+
expect(formatTime(0)).toBe('00:00');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('ровно час', () => {
|
|
22
|
+
expect(formatTime(3600)).toBe('01:00:00');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getDuration } from './get-duration';
|
|
3
|
+
|
|
4
|
+
describe('getDuration', () => {
|
|
5
|
+
it('только секунды', () => {
|
|
6
|
+
expect(getDuration(45)).toBe('00:45');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('минуты и секунды', () => {
|
|
10
|
+
expect(getDuration(125)).toBe('02:05');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('с часами', () => {
|
|
14
|
+
expect(getDuration(3661)).toBe('01:01:01');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('ноль', () => {
|
|
18
|
+
expect(getDuration(0)).toBe('00:00');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('ровно час', () => {
|
|
22
|
+
expect(getDuration(3600)).toBe('01:00:00');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getMonth } from './get-month';
|
|
3
|
+
|
|
4
|
+
const t = (key: string) => key;
|
|
5
|
+
|
|
6
|
+
describe('getMonth', () => {
|
|
7
|
+
it('январь = 0', () => {
|
|
8
|
+
expect(getMonth(t, 0)).toBe('january');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('декабрь = 11', () => {
|
|
12
|
+
expect(getMonth(t, 11)).toBe('december');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('июнь = 5', () => {
|
|
16
|
+
expect(getMonth(t, 5)).toBe('june');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('undefined → декабрь (дефолт)', () => {
|
|
20
|
+
expect(getMonth(t)).toBe('december');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('отрицательное число → декабрь', () => {
|
|
24
|
+
expect(getMonth(t, -1)).toBe('december');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('число >= 12 → декабрь', () => {
|
|
28
|
+
expect(getMonth(t, 12)).toBe('december');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { normalizeUrl } from './normalize-url';
|
|
3
|
+
|
|
4
|
+
describe('normalizeUrl', () => {
|
|
5
|
+
it('удаляет page=1', () => {
|
|
6
|
+
const result = normalizeUrl({ path: '/videos', query: { page: '1' } });
|
|
7
|
+
expect(result.query.page).toBeUndefined();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('сохраняет page=2', () => {
|
|
11
|
+
const result = normalizeUrl({ path: '/videos', query: { page: '2' } });
|
|
12
|
+
expect(result.query.page).toBe('2');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('удаляет sort=trending', () => {
|
|
16
|
+
const result = normalizeUrl({ path: '/videos', query: { sort: 'trending' } });
|
|
17
|
+
expect(result.query.sort).toBeUndefined();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('сохраняет sort=popular', () => {
|
|
21
|
+
const result = normalizeUrl({ path: '/videos', query: { sort: 'popular' } });
|
|
22
|
+
expect(result.query.sort).toBe('popular');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('удаляет пустые значения', () => {
|
|
26
|
+
const result = normalizeUrl({ path: '/', query: { a: '', b: null as any, c: 'ok' } });
|
|
27
|
+
expect(result.query).toEqual({ c: 'ok' });
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('lowercase путь', () => {
|
|
31
|
+
const result = normalizeUrl({ path: '/Videos/BIG', query: {} });
|
|
32
|
+
expect(result.path).toBe('/videos/big');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('lowercase query', () => {
|
|
36
|
+
const result = normalizeUrl({ path: '/', query: { Sort: 'Popular' } });
|
|
37
|
+
expect(result.query).toEqual({ sort: 'popular' });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('%20 и пробелы → дефисы', () => {
|
|
41
|
+
const result = normalizeUrl({ path: '/big%20tits videos', query: {} });
|
|
42
|
+
expect(result.path).toBe('/big-tits-videos');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('убирает двойные дефисы', () => {
|
|
46
|
+
const result = normalizeUrl({ path: '/big--tits', query: {} });
|
|
47
|
+
expect(result.path).toBe('/big-tits');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('убирает trailing slash', () => {
|
|
51
|
+
const result = normalizeUrl({ path: '/videos/', query: {} });
|
|
52
|
+
expect(result.path).toBe('/videos');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('не убирает /', () => {
|
|
56
|
+
const result = normalizeUrl({ path: '/', query: {} });
|
|
57
|
+
expect(result.path).toBe('/');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseApiError } from './parse-api-error';
|
|
3
|
+
|
|
4
|
+
describe('parseApiError', () => {
|
|
5
|
+
it('error.message', () => {
|
|
6
|
+
expect(parseApiError({ message: 'Not found' })).toBe('Not found');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('response._data как объект', () => {
|
|
10
|
+
const error = { response: { _data: { error: 'Bad request' } } };
|
|
11
|
+
expect(parseApiError(error)).toBe('Bad request');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('response._data как JSON строка', () => {
|
|
15
|
+
const error = { response: { _data: '{"error":"Forbidden"}' } };
|
|
16
|
+
expect(parseApiError(error)).toBe('Forbidden');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('вложенный data.error', () => {
|
|
20
|
+
const error = { response: { _data: { data: { error: 'Validation failed' } } } };
|
|
21
|
+
expect(parseApiError(error)).toBe('Validation failed');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('массив ошибок — первый элемент', () => {
|
|
25
|
+
const error = { response: { _data: { error: ['Field required', 'Too short'] } } };
|
|
26
|
+
expect(parseApiError(error)).toBe('Field required');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('fallback при null', () => {
|
|
30
|
+
expect(parseApiError(null)).toBe('Unknown error occurred.');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('fallback при пустом объекте', () => {
|
|
34
|
+
expect(parseApiError({})).toBe('Unknown error occurred.');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { validateEmail } from './validate-email';
|
|
3
|
+
|
|
4
|
+
describe('validateEmail', () => {
|
|
5
|
+
it('валидный email', () => {
|
|
6
|
+
expect(validateEmail('user@example.com')).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('с точкой в имени', () => {
|
|
10
|
+
expect(validateEmail('first.last@example.com')).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('с поддоменом', () => {
|
|
14
|
+
expect(validateEmail('user@mail.example.com')).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('без @', () => {
|
|
18
|
+
expect(validateEmail('userexample.com')).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('без домена', () => {
|
|
22
|
+
expect(validateEmail('user@')).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('пустая строка', () => {
|
|
26
|
+
expect(validateEmail('')).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('пробелы', () => {
|
|
30
|
+
expect(validateEmail('user @example.com')).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { validatePassword } from './validate-password';
|
|
3
|
+
|
|
4
|
+
describe('validatePassword', () => {
|
|
5
|
+
it('длина > 4 — валиден', () => {
|
|
6
|
+
expect(validatePassword('12345')).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('длина 4 — невалиден', () => {
|
|
10
|
+
expect(validatePassword('1234')).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('длина 1 — невалиден', () => {
|
|
14
|
+
expect(validatePassword('a')).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('длинный пароль', () => {
|
|
18
|
+
expect(validatePassword('super_secure_password_123')).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { validatePhone } from './validate-phone';
|
|
3
|
+
|
|
4
|
+
describe('validatePhone', () => {
|
|
5
|
+
it('международный формат', () => {
|
|
6
|
+
expect(validatePhone('+79001234567')).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('с дефисами', () => {
|
|
10
|
+
expect(validatePhone('8-900-123-45-67')).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('с пробелами', () => {
|
|
14
|
+
expect(validatePhone('+7 900 123 4567')).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('со скобками', () => {
|
|
18
|
+
expect(validatePhone('+7(900)1234567')).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('слишком короткий', () => {
|
|
22
|
+
expect(validatePhone('12345')).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('пустая строка', () => {
|
|
26
|
+
expect(validatePhone('')).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('буквы', () => {
|
|
30
|
+
expect(validatePhone('phone123')).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { validateUsername } from './validate-username';
|
|
3
|
+
|
|
4
|
+
describe('validateUsername', () => {
|
|
5
|
+
it('латиница', () => {
|
|
6
|
+
expect(validateUsername('john')).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('с цифрами', () => {
|
|
10
|
+
expect(validateUsername('user123')).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('с подчёркиванием и дефисом', () => {
|
|
14
|
+
expect(validateUsername('my_user-name')).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('1 символ — невалиден', () => {
|
|
18
|
+
expect(validateUsername('a')).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('21 символ — невалиден', () => {
|
|
22
|
+
expect(validateUsername('a'.repeat(21))).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('20 символов — валиден', () => {
|
|
26
|
+
expect(validateUsername('a'.repeat(20))).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('пустая строка', () => {
|
|
30
|
+
expect(validateUsername('')).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('спецсимволы', () => {
|
|
34
|
+
expect(validateUsername('user@name')).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|