mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-10-16 01:33:18 +01:00
replace TimezoneModalMismatch unit test with e2e test
This commit is contained in:
89
e2e/timezone-mismatch.spec.ts
Normal file
89
e2e/timezone-mismatch.spec.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { test, expect } from '../playwright/fixtures';
|
||||||
|
import { PLAYWRIGHT_BASE_URL } from '../playwright/config';
|
||||||
|
import type { Page, TestContext } from '../playwright/fixtures';
|
||||||
|
import { getCurrentUserViaApi, updateUserProfileViaApi } from './utils/api';
|
||||||
|
|
||||||
|
const BROWSER_TIMEZONE = 'Europe/Vienna';
|
||||||
|
const MISMATCHED_TIMEZONE = 'America/New_York';
|
||||||
|
|
||||||
|
test.use({ timezoneId: BROWSER_TIMEZONE });
|
||||||
|
|
||||||
|
function mismatchModal(page: Page) {
|
||||||
|
return page.getByRole('dialog').filter({ hasText: 'Timezone mismatch detected' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openPageWithTimezoneMismatch(page: Page, ctx: TestContext) {
|
||||||
|
await updateUserProfileViaApi(ctx, { timezone: MISMATCHED_TIMEZONE });
|
||||||
|
await page.goto(PLAYWRIGHT_BASE_URL + '/dashboard');
|
||||||
|
await expect(mismatchModal(page)).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
test('timezone mismatch modal saves the device timezone through the users API', async ({
|
||||||
|
page,
|
||||||
|
ctx,
|
||||||
|
}) => {
|
||||||
|
await openPageWithTimezoneMismatch(page, ctx);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForResponse(
|
||||||
|
(response) =>
|
||||||
|
response.url().includes('/api/v1/users/') &&
|
||||||
|
response.request().method() === 'PUT' &&
|
||||||
|
response.status() === 200
|
||||||
|
),
|
||||||
|
mismatchModal(page).getByRole('button', { name: 'Update timezone' }).click(),
|
||||||
|
]);
|
||||||
|
await expect(mismatchModal(page)).toBeHidden();
|
||||||
|
|
||||||
|
const user = await getCurrentUserViaApi(ctx);
|
||||||
|
expect(user.timezone).toBe(BROWSER_TIMEZONE);
|
||||||
|
|
||||||
|
// After the automatic reload the timezones match again, so the modal stays gone.
|
||||||
|
await page.waitForLoadState('load');
|
||||||
|
await page.goto(PLAYWRIGHT_BASE_URL + '/dashboard');
|
||||||
|
await expect(mismatchModal(page)).toBeHidden();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('timezone mismatch modal does not open for a different timezone with the same time', async ({
|
||||||
|
page,
|
||||||
|
ctx,
|
||||||
|
}) => {
|
||||||
|
// Berlin and Vienna share the same offset and DST rules, so the times match.
|
||||||
|
await updateUserProfileViaApi(ctx, { timezone: 'Europe/Berlin' });
|
||||||
|
await page.goto(PLAYWRIGHT_BASE_URL + '/dashboard');
|
||||||
|
|
||||||
|
// Wait until the dashboard is rendered so the modal had its chance to mount.
|
||||||
|
await expect(page.getByTestId('dashboard_view')).toBeVisible();
|
||||||
|
await expect(mismatchModal(page)).toBeHidden();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('timezone mismatch modal stays open when the update fails', async ({ page, ctx }) => {
|
||||||
|
await openPageWithTimezoneMismatch(page, ctx);
|
||||||
|
|
||||||
|
await page.route('**/api/v1/users/*', (route) => {
|
||||||
|
if (route.request().method() === 'PUT') {
|
||||||
|
return route.fulfill({
|
||||||
|
status: 500,
|
||||||
|
contentType: 'application/json',
|
||||||
|
body: JSON.stringify({ message: 'Server error' }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return route.fallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForResponse(
|
||||||
|
(response) =>
|
||||||
|
response.url().includes('/api/v1/users/') &&
|
||||||
|
response.request().method() === 'PUT' &&
|
||||||
|
response.status() === 500
|
||||||
|
),
|
||||||
|
mismatchModal(page).getByRole('button', { name: 'Update timezone' }).click(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await expect(mismatchModal(page)).toBeVisible();
|
||||||
|
await expect(page.getByText('Failed to update profile')).toBeVisible();
|
||||||
|
|
||||||
|
const user = await getCurrentUserViaApi(ctx);
|
||||||
|
expect(user.timezone).toBe(MISMATCHED_TIMEZONE);
|
||||||
|
});
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
import { flushPromises, shallowMount } from '@vue/test-utils';
|
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
||||||
import { createPinia } from 'pinia';
|
|
||||||
import { VueQueryPlugin } from '@tanstack/vue-query';
|
|
||||||
import UserTimezoneMismatchModal from './UserTimezoneMismatchModal.vue';
|
|
||||||
import TimezoneMismatchModal from '@/packages/ui/src/TimezoneMismatchModal.vue';
|
|
||||||
import { api } from '@/packages/api/src';
|
|
||||||
|
|
||||||
vi.mock('@/packages/api/src', async (importOriginal) => ({
|
|
||||||
...(await importOriginal<typeof import('@/packages/api/src')>()),
|
|
||||||
api: {
|
|
||||||
updateUser: vi.fn(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('@inertiajs/vue3', async (importOriginal) => ({
|
|
||||||
...(await importOriginal<typeof import('@inertiajs/vue3')>()),
|
|
||||||
usePage: () => ({
|
|
||||||
props: {
|
|
||||||
auth: {
|
|
||||||
user: { id: 'user-1' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
function mountModal() {
|
|
||||||
return shallowMount(UserTimezoneMismatchModal, {
|
|
||||||
props: { show: true },
|
|
||||||
global: {
|
|
||||||
plugins: [createPinia(), VueQueryPlugin],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('UserTimezoneMismatchModal', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
vi.mocked(api.updateUser).mockReset();
|
|
||||||
Object.defineProperty(window.location, 'reload', {
|
|
||||||
configurable: true,
|
|
||||||
value: vi.fn(),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('saves the new timezone through the users API', async () => {
|
|
||||||
vi.mocked(api.updateUser).mockResolvedValue({
|
|
||||||
data: { id: 'user-1', timezone: 'Australia/Sydney' },
|
|
||||||
} as never);
|
|
||||||
|
|
||||||
const wrapper = mountModal();
|
|
||||||
wrapper.findComponent(TimezoneMismatchModal).vm.$emit('update', 'Australia/Sydney');
|
|
||||||
await flushPromises();
|
|
||||||
|
|
||||||
expect(api.updateUser).toHaveBeenCalledWith(
|
|
||||||
{ timezone: 'Australia/Sydney' },
|
|
||||||
{ params: { user: 'user-1' } }
|
|
||||||
);
|
|
||||||
expect(wrapper.findComponent(TimezoneMismatchModal).props('show')).toBe(false);
|
|
||||||
expect(window.location.reload).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('leaves the modal open when the update fails', async () => {
|
|
||||||
vi.mocked(api.updateUser).mockRejectedValue(new Error('nope'));
|
|
||||||
|
|
||||||
const wrapper = mountModal();
|
|
||||||
wrapper.findComponent(TimezoneMismatchModal).vm.$emit('update', 'Australia/Sydney');
|
|
||||||
await flushPromises();
|
|
||||||
|
|
||||||
expect(wrapper.findComponent(TimezoneMismatchModal).props('show')).toBe(true);
|
|
||||||
expect(window.location.reload).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user