From 209507a4eaf0c8b77de805e08dc5a9cb5aa165c0 Mon Sep 17 00:00:00 2001 From: surfingbytes Date: Wed, 25 Mar 2026 09:39:50 +0000 Subject: [PATCH] Check if project exists, added tests --- .../composables/useRedirectToLastVisited.ts | 3 +- frontend/src/router/index.ts | 10 +- .../e2e/misc/default-landing-page.spec.ts | 98 +++++++++++++++++++ 3 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 frontend/tests/e2e/misc/default-landing-page.spec.ts diff --git a/frontend/src/composables/useRedirectToLastVisited.ts b/frontend/src/composables/useRedirectToLastVisited.ts index 799488a40..ad6b7dc4c 100644 --- a/frontend/src/composables/useRedirectToLastVisited.ts +++ b/frontend/src/composables/useRedirectToLastVisited.ts @@ -1,6 +1,7 @@ import {useRouter} from 'vue-router' import {getLastVisited, clearLastVisited, getLastVisitedPage} from '@/helpers/saveLastVisited' import {useAuthStore} from '@/stores/auth' +import {useProjectStore} from '@/stores/projects' import {DEFAULT_PAGE} from '@/constants/defaultPage' export function useRedirectToLastVisited() { @@ -30,7 +31,7 @@ export function useRedirectToLastVisited() { return {name: 'tasks.range'} case DEFAULT_PAGE.DEFAULT_PROJECT: { const projectId = authStore.settings?.defaultProjectId - if (projectId) { + if (projectId && useProjectStore().projects[projectId]) { return {name: 'project.index', params: {projectId}} } return {name: 'home'} diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 7eaf0971d..6e43b8b28 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -10,6 +10,7 @@ import {AUTH_ROUTE_NAMES} from '@/constants/authRouteNames' import {DEFAULT_PAGE} from '@/constants/defaultPage' import {useAuthStore} from '@/stores/auth' +import {useProjectStore} from '@/stores/projects' import Login from '@/views/user/Login.vue' import Register from '@/views/user/Register.vue' @@ -43,7 +44,7 @@ const router = createRouter({ path: '/', name: 'home', component: () => import('@/views/Home.vue'), - beforeEnter(_to, from) { + async beforeEnter(_to, from) { if (from.name !== undefined) { return } @@ -63,7 +64,12 @@ const router = createRouter({ case DEFAULT_PAGE.DEFAULT_PROJECT: { const projectId = authStore.settings?.defaultProjectId if (projectId) { - return {name: 'project.index', params: {projectId}} + try { + await useProjectStore().loadProject(projectId) + return {name: 'project.index', params: {projectId}} + } catch { + break + } } break } diff --git a/frontend/tests/e2e/misc/default-landing-page.spec.ts b/frontend/tests/e2e/misc/default-landing-page.spec.ts new file mode 100644 index 000000000..395e9a138 --- /dev/null +++ b/frontend/tests/e2e/misc/default-landing-page.spec.ts @@ -0,0 +1,98 @@ +import {test, expect} from '../../support/fixtures' +import {ProjectFactory} from '../../factories/project' +import {UserFactory} from '../../factories/user' +import {TaskFactory} from '../../factories/task' +import {login} from '../../support/authenticateUser' +import {updateUserSettings} from '../../support/updateUserSettings' +import {createDefaultViews} from '../project/prepareProjects' + +test.describe('Default Landing Page', () => { + test('shows overview page with default settings when no last visited page exists', async ({authenticatedPage: page}) => { + await page.goto('/') + await page.waitForLoadState('networkidle') + await expect(page).toHaveURL('/') + await expect(page.locator('.home.app-content')).toBeVisible() + }) + + test('redirects to upcoming when set as default page', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({defaultPage: 'upcoming'}), + }))[0] + await ProjectFactory.create(1, {owner_id: user.id}) + await login(page, apiContext, user) + + await page.goto('/') + await page.waitForURL('**/tasks/range**') + }) + + test('redirects to default project when set as default page', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({defaultPage: 'defaultProject'}), + }))[0] + const project = (await ProjectFactory.create(1, {owner_id: user.id}))[0] + await createDefaultViews(project.id) + + const {token} = await login(page, apiContext, user) + + await updateUserSettings(apiContext, token, { + default_project_id: project.id, + overdue_tasks_reminders_time: '9:00', + }) + + await page.goto('/') + await page.waitForURL(`**/projects/${project.id}/**`) + }) + + test('falls back to overview when default project does not exist', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({defaultPage: 'defaultProject'}), + }))[0] + await ProjectFactory.create(1, {owner_id: user.id}) + + const {token} = await login(page, apiContext, user) + + await updateUserSettings(apiContext, token, { + default_project_id: 999999, + overdue_tasks_reminders_time: '9:00', + }) + + await page.goto('/') + await page.waitForLoadState('networkidle') + await expect(page).toHaveURL('/') + }) + + test('redirects to last visited page when set as default page', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({defaultPage: 'lastVisited'}), + }))[0] + const project = (await ProjectFactory.create(1, {owner_id: user.id}))[0] + const views = await createDefaultViews(project.id) + await TaskFactory.create(1, {project_id: project.id}) + + await login(page, apiContext, user) + + await page.goto(`/projects/${project.id}/${views[0].id}`) + await page.waitForLoadState('networkidle') + + await page.goto('/') + await page.waitForURL(`**/projects/${project.id}/${views[0].id}`) + }) + + test('does not redirect on in-app navigation to home', async ({page, apiContext}) => { + const user = (await UserFactory.create(1, { + frontend_settings: JSON.stringify({defaultPage: 'upcoming'}), + }))[0] + const project = (await ProjectFactory.create(1, {owner_id: user.id}))[0] + await createDefaultViews(project.id) + await TaskFactory.create(1, {project_id: project.id}) + + await login(page, apiContext, user) + + await page.goto(`/projects/${project.id}/1`) + await page.waitForLoadState('networkidle') + + await page.locator('.logo-link').click() + await page.waitForLoadState('networkidle') + await expect(page).toHaveURL('/') + }) +})