diff --git a/apps/app/src/app/login/page.tsx b/apps/app/src/app/login/page.tsx index 975af2f8a..2149dee5b 100644 --- a/apps/app/src/app/login/page.tsx +++ b/apps/app/src/app/login/page.tsx @@ -2,32 +2,42 @@ import { isSafeRedirectPath } from '@op/common/client'; import { useAuthUser } from '@op/hooks'; -import { redirect, useSearchParams } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { useEffect } from 'react'; import { LoginPanel } from '@/components/LoginPanel'; -const LoginPageWithLayout = () => { - return ; -}; - const LoginPage = () => { const user = useAuthUser(); + const router = useRouter(); const searchParams = useSearchParams(); const redirectParam = searchParams.get('redirect'); + useEffect(() => { + if (!user || user.isFetching || user.isPending) { + return; + } + + if (user.isFetchedAfterMount && !user.data?.user) { + return; + } + + if (isSafeRedirectPath(redirectParam)) { + router.replace(redirectParam); + } else { + router.replace('/'); + } + }, [user, redirectParam, router]); + if (!user || user.isFetching || user.isPending) { return null; } if (user.isFetchedAfterMount && !user.isFetching && !user.data?.user) { - return ; - } - - if (isSafeRedirectPath(redirectParam)) { - redirect(redirectParam); + return ; } - redirect('/'); + return null; }; export default LoginPage; diff --git a/services/api/src/routers/decision/instances/getCategories.test.ts b/services/api/src/routers/decision/instances/getCategories.test.ts index 0de1c8c35..ea50a2fdb 100644 --- a/services/api/src/routers/decision/instances/getCategories.test.ts +++ b/services/api/src/routers/decision/instances/getCategories.test.ts @@ -6,7 +6,7 @@ import { taxonomyTerms, } from '@op/db/schema'; import { randomUUID } from 'node:crypto'; -import { describe, expect, it } from 'vitest'; +import { afterAll, describe, expect, it } from 'vitest'; import { appRouter } from '../..'; import { TestDecisionsDataManager } from '../../../test/helpers/TestDecisionsDataManager'; @@ -42,11 +42,9 @@ async function seedProposalTaxonomy( .returning({ id: taxonomies.id }); let resolvedTaxonomyId: string; - let ownsTheTaxonomy = false; if (inserted) { resolvedTaxonomyId = inserted.id; - ownsTheTaxonomy = true; } else { // Another test created it — look up the existing one const [existing] = await db @@ -82,10 +80,6 @@ async function seedProposalTaxonomy( ), ); } - // Only delete taxonomy if this test created it - if (ownsTheTaxonomy) { - await db.delete(taxonomies).where(eq(taxonomies.id, resolvedTaxonomyId)); - } }); return { taxonomyId: resolvedTaxonomyId, termRecords }; @@ -278,6 +272,10 @@ describe.concurrent('getCategories permissions', () => { }); describe.concurrent('getCategories category matching', () => { + afterAll(async () => { + await db.delete(taxonomies).where(eq(taxonomies.name, 'proposal')); + }); + it('should return matched categories when config.categories and taxonomy terms exist', async ({ task, onTestFinished,