1
0
Fork 0
mirror of https://github.com/CorentinTh/it-tools.git synced 2025-08-06 14:05:18 +02:00

Updated validation method and related test cases

This commit is contained in:
Bryan Liao 2025-07-14 18:30:31 -07:00
parent 4f4744eddc
commit 4437a4f57b
4 changed files with 59 additions and 25 deletions

View file

@ -17,7 +17,6 @@ test.describe('Tool - Epoch converter', () => {
const localLine = page.locator('text=Local Time:');
await expect(utcLine).toContainText('GMT (UTC): Fri, 20 Jun 2025 20:48:00 GMT');
// await expect(localLine).toContainText('Local Time: Fri, Jun 20, 2025, 22:48:00 GMT+2');
await expect(localLine).toContainText('Local Time:');
await expect(localLine).toContainText('Jun 20, 2025');
await expect(localLine).toContainText('22:48:00');
@ -34,24 +33,24 @@ test.describe('Tool - Epoch converter', () => {
await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click();
await expect(page.getByText('1750420080')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('1750420080')).toBeVisible({ timeout: 5000 });
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
await expect(page.getByText('1750427280')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('1750427280')).toBeVisible({ timeout: 5000 });
});
test('Shows error if year is not 4 digits', async ({ page }) => {
await page.getByPlaceholder('YYYY').fill('99');
await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click();
await expect(page.getByText('Year must be 4 digits')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Year must be 4 digits')).toBeVisible({ timeout: 5000 });
});
test('Shows error if month is invalid', async ({ page }) => {
await page.getByPlaceholder('YYYY').fill('1999');
await page.getByPlaceholder('MM').first().fill('00');
await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click();
await expect(page.getByText('Month must be between 1 and 12')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Month must be between 1 and 12')).toBeVisible({ timeout: 5000 });
});
test('Shows error if day is invalid', async ({ page }) => {
@ -59,7 +58,7 @@ test.describe('Tool - Epoch converter', () => {
await page.getByPlaceholder('MM').first().fill('01');
await page.getByPlaceholder('DD').fill('0');
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
await expect(page.getByText('Day must be between 1 and 31')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Day must be between 1 and 31')).toBeVisible({ timeout: 5000 });
});
test('Shows error if hour is invalid', async ({ page }) => {
@ -68,7 +67,7 @@ test.describe('Tool - Epoch converter', () => {
await page.getByPlaceholder('DD').fill('1');
await page.getByPlaceholder('HH').fill('24');
await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click();
await expect(page.getByText('Hour must be between 0 and 23')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Hour must be between 0 and 23')).toBeVisible({ timeout: 5000 });
});
test('Shows error if minute is invalid', async ({ page }) => {
@ -78,7 +77,7 @@ test.describe('Tool - Epoch converter', () => {
await page.getByPlaceholder('HH').fill('23');
await page.getByPlaceholder('MM').nth(1).fill('60');
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
await expect(page.getByText('Minute must be between 0 and 59')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Minute must be between 0 and 59')).toBeVisible({ timeout: 5000 });
});
test('Shows error if second is invalid', async ({ page }) => {
@ -89,6 +88,45 @@ test.describe('Tool - Epoch converter', () => {
await page.getByPlaceholder('MM').nth(1).fill('59');
await page.getByPlaceholder('SS').fill('99');
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
await expect(page.getByText('Second must be between 0 and 59')).toBeVisible({ timeout: 50000 });
await expect(page.getByText('Second must be between 0 and 59')).toBeVisible({ timeout: 5000 });
});
test('Shows error for invalid combination like February 31', async ({ page }) => {
await page.getByPlaceholder('YYYY').fill('2024');
await page.getByPlaceholder('MM').first().fill('02');
await page.getByPlaceholder('DD').fill('31');
await page.getByPlaceholder('HH').fill('12');
await page.getByPlaceholder('MM').nth(1).fill('00');
await page.getByPlaceholder('SS').fill('00');
await page.getByRole('button', { name: 'Convert to Epoch (Local)' }).click();
await expect(page.getByText('Invalid date string')).toBeVisible({ timeout: 30000 });
});
test('Shows error for invalid date like April 31', async ({ page }) => {
await page.getByPlaceholder('YYYY').fill('2024');
await page.getByPlaceholder('MM').first().fill('04');
await page.getByPlaceholder('DD').fill('31');
await page.getByPlaceholder('HH').fill('12');
await page.getByPlaceholder('MM').nth(1).fill('00');
await page.getByPlaceholder('SS').fill('00');
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
await expect(page.locator('.c-alert--icon')).toBeVisible({ timeout: 60000 });
await expect(page.getByText('Invalid date string')).toBeVisible({ timeout: 60000 });
});
test('Allows valid leap year date: February 29, 2024', async ({ page }) => {
await page.getByPlaceholder('YYYY').fill('2024');
await page.getByPlaceholder('MM').first().fill('02');
await page.getByPlaceholder('DD').fill('29');
await page.getByPlaceholder('HH').fill('12');
await page.getByPlaceholder('MM').nth(1).fill('00');
await page.getByPlaceholder('SS').fill('00');
await page.getByRole('button', { name: 'Convert to Epoch (UTC)' }).click();
// Should not show any error alert
await expect(page.locator('.c-alert')).not.toBeVisible();
});
});

View file

@ -81,23 +81,8 @@ export function dateToEpoch(
if (parseAsUTC && !dateString.endsWith('Z')) {
normalizedDateString = `${dateString}Z`;
}
// eslint-disable-next-line no-console
console.log(`test = ${normalizedDateString}`);
// else {
// // Manually compute local timezone offset and append it
// const tempDate = new Date(`${dateString}`);
// const offsetMinutes = tempDate.getTimezoneOffset();
// const sign = offsetMinutes <= 0 ? '+' : '-';
// const absOffset = Math.abs(offsetMinutes);
// const hours = String(Math.floor(absOffset / 60)).padStart(2, '0');
// const minutes = String(absOffset % 60).padStart(2, '0');
// const offset = `${sign}${hours}:${minutes}`;
// normalizedDateString = `${dateString}${offset}`;
// }
const date = new Date(normalizedDateString);
// eslint-disable-next-line no-console
console.log(date);
if (Number.isNaN(date.getTime())) {
throw new TypeError('Invalid date string');
}

View file

@ -87,6 +87,17 @@ function validateDateParts(parts: DateParts): void {
if (+second < 0 || +second > 59) {
throw new Error('Second must be between 0 and 59');
}
// Cross-check full date validity
const y = +year;
const m = +month - 1;
const d = +day;
const constructed = new Date(y, m, d);
if (constructed.getUTCFullYear() !== y || constructed.getUTCMonth() !== m || constructed.getUTCDate() !== m) {
throw new TypeError('Invalid date string');
}
}
// Clear errors on input
@ -183,7 +194,7 @@ watch(dateParts, () => {
</div>
</div>
<c-alert v-if="dateInputError" type="error" class="mb-4 mt-4">
<c-alert v-if="dateInputError" type="error" class="validateError mb-4 mt-4">
{{ dateInputError }}
</c-alert>
</c-card>