mirror of
https://gitee.com/pnoker/iot-dc3.git
synced 2026-11-01 02:31:46 +08:00
Apply IDE formatting across all Vue, TypeScript, SCSS and test files. No logic changes — whitespace, quotes and brace style only.
135 lines
4.2 KiB
TypeScript
135 lines
4.2 KiB
TypeScript
/*
|
|
* Copyright 2016-present the IoT DC3 original author or authors.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import {describe, expect, it} from 'vitest';
|
|
|
|
import {isEmail, isNull, isNum, isPhone, isUrl} from '@/utils/validationUtil';
|
|
|
|
describe('validationUtil', () => {
|
|
describe('isUrl', () => {
|
|
it.each([
|
|
['http://example.com', true],
|
|
['https://dc3.example.com/path', true],
|
|
['HTTPS://Example.COM', false], // case-sensitive http(s) prefix
|
|
['ftp://example.com', false],
|
|
['javascript:alert(1)', false],
|
|
['', false],
|
|
['just-text', false],
|
|
[null, false],
|
|
[undefined, false],
|
|
[42, false],
|
|
])('isUrl(%p) → %p', (input, expected) => {
|
|
expect(isUrl(input)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe('isEmail', () => {
|
|
it.each([
|
|
['dc3@example.com', true],
|
|
['user.name+tag@example.co.uk', false], // '+' not allowed by current regex
|
|
['user.name@example.co.uk', true],
|
|
['a@b.cd', true],
|
|
['plain', false],
|
|
['@example.com', false],
|
|
['user@', false],
|
|
['user@example', false],
|
|
// The TLD piece is `([a-zA-Z0-9]{2,4})+$` — the trailing `+` quantifier
|
|
// means a 10-char TLD can still match as 4+4+2. Pin this current
|
|
// behaviour so a future regex tightening shows up in this test.
|
|
['user@example.toolongtld', true],
|
|
['', false],
|
|
[null, false],
|
|
[undefined, false],
|
|
])('isEmail(%p) → %p', (input, expected) => {
|
|
expect(isEmail(input)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe('isPhone', () => {
|
|
it.each([
|
|
['13912345678', true],
|
|
['18512345678', true],
|
|
['14712345678', true],
|
|
['16612345678', true], // 16x prefix (China Unicom IoT)
|
|
['17812345678', true], // 17x prefix (virtual operator)
|
|
['19912345678', true], // 19x prefix (China Telecom)
|
|
['10000000000', false], // invalid prefix (10x)
|
|
['12000000000', false], // invalid prefix (12x)
|
|
['1391234567', false], // too short
|
|
['139123456789', false], // too long
|
|
['abcdefghijk', false],
|
|
['', false],
|
|
[null, false],
|
|
[undefined, false],
|
|
])('isPhone(%p) → %p', (input, expected) => {
|
|
expect(isPhone(input)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe('isNum', () => {
|
|
// type=1: decimal-aware (digits and optional dot)
|
|
// type=2: integer-only (pure digits)
|
|
// default: always true (backward-compatible fallthrough)
|
|
it.each([
|
|
// type=1 (decimal)
|
|
['123', 1, true],
|
|
['1.5', 1, true],
|
|
['.5', 1, true],
|
|
['0', 1, true],
|
|
['abc', 1, false],
|
|
['12a', 1, false],
|
|
// type=2 (integer)
|
|
['5', 2, true],
|
|
['123', 2, true],
|
|
['1.5', 2, false],
|
|
['a5', 2, false],
|
|
// unknown type — fallthrough to true
|
|
['123', 0, true],
|
|
['abc', 99, true],
|
|
])('isNum(%p, %i) → %p', (input, type, expected) => {
|
|
expect(isNum(input, type)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe('isNull', () => {
|
|
it.each([
|
|
[undefined, true],
|
|
[null, true],
|
|
['', true],
|
|
['null', true],
|
|
['undefined', true],
|
|
['ok', false],
|
|
[0, false], // numbers are never null
|
|
[-1, false],
|
|
[Number.NaN, false],
|
|
[false, false], // booleans are never null
|
|
[true, false],
|
|
[[], true],
|
|
[[1], false],
|
|
[{}, true],
|
|
[{a: 1}, false],
|
|
])('isNull(%p) → %p', (input, expected) => {
|
|
expect(isNull(input)).toBe(expected);
|
|
});
|
|
|
|
it('treats nested empty arrays/objects as non-null', () => {
|
|
expect(isNull([[]])).toBe(false);
|
|
expect(isNull({nested: {}})).toBe(false);
|
|
});
|
|
});
|
|
});
|