Fix TopNav prisma error

This commit is contained in:
Francis Cao committed 2026-08-06 09:20:27 -07:00
1 parent 8d6943bf51
commit 92fd4b71c3
3 files changed
+91 -4

No files matched your search

+74
View File
@@ -0,0 +1,74 @@
import { beforeEach, expect, test, vi } from 'vitest';
import { render, screen } from '@/test/render';
import { TopNav } from './TopNav';
const mockPush = vi.fn();
const mockRenderUrl = vi.fn((path: string) => path);
const mockUseNavigation = vi.fn();
vi.mock('@/components/hooks', () => ({
useNavigation: () => mockUseNavigation(),
}));
vi.mock('@/components/input/TeamsButton', () => ({
TeamsButton: () => <div>TeamsButton</div>,
}));
vi.mock('@/components/input/WebsiteSelect', () => ({
WebsiteSelect: ({ onChange }: { onChange: (value: string | number | null) => void }) => (
<>
<button type="button" onClick={() => onChange(null)}>
clear website
</button>
<button type="button" onClick={() => onChange('website-2')}>
select website
</button>
</>
),
}));
vi.mock('@/components/input/LinkSelect', () => ({
LinkSelect: () => null,
}));
vi.mock('@/components/input/PixelSelect', () => ({
PixelSelect: () => null,
}));
vi.mock('@/components/input/BoardSelect', () => ({
BoardSelect: () => null,
}));
beforeEach(() => {
mockPush.mockReset();
mockRenderUrl.mockClear();
mockUseNavigation.mockReturnValue({
websiteId: 'website-1',
linkId: undefined,
pixelId: undefined,
boardId: undefined,
teamId: undefined,
router: {
push: mockPush,
},
renderUrl: mockRenderUrl,
});
});
test('does not navigate when the website select emits null', async () => {
const { user } = render(<TopNav />);
await user.click(screen.getByRole('button', { name: 'clear website' }));
expect(mockRenderUrl).not.toHaveBeenCalled();
expect(mockPush).not.toHaveBeenCalled();
});
test('navigates when the website select emits a website id', async () => {
const { user } = render(<TopNav />);
await user.click(screen.getByRole('button', { name: 'select website' }));
expect(mockRenderUrl).toHaveBeenCalledWith('/websites/website-2', false);
expect(mockPush).toHaveBeenCalledWith('/websites/website-2');
});
+12 -4
View File
@@ -11,20 +11,28 @@ import { WebsiteSelect } from '@/components/input/WebsiteSelect';
export function TopNav() {
const { websiteId, linkId, pixelId, boardId, teamId, router, renderUrl } = useNavigation();
const navigateToEntity = (basePath: string, value: string | number | null) => {
if (value === null || value === undefined || value === '') {
return;
}
router.push(renderUrl(`${basePath}/${value}`, false));
};
const handleWebsiteChange = (value: string | number | null) => {
router.push(renderUrl(`/websites/${value}`, false));
navigateToEntity('/websites', value);
};
const handleLinkChange = (value: string | number | null) => {
router.push(renderUrl(`/links/${value}`, false));
navigateToEntity('/links', value);
};
const handlePixelChange = (value: string | number | null) => {
router.push(renderUrl(`/pixels/${value}`, false));
navigateToEntity('/pixels', value);
};
const handleBoardChange = (value: string | number | null) => {
router.push(renderUrl(`/boards/${value}`, false));
navigateToEntity('/boards', value);
};
return (
+5
View File
@@ -4,6 +4,7 @@ import prisma from '@/lib/prisma';
import redis from '@/lib/redis';
import { sanitizeSortFilters } from '@/lib/sort';
import type { QueryFilters } from '@/lib/types';
import { z } from 'zod';
const WEBSITE_SORT_FIELDS = ['name', 'domain', 'createdAt'] as const;
@@ -12,6 +13,10 @@ export async function findWebsite(criteria: Prisma.WebsiteFindUniqueArgs) {
}
export async function getWebsite(websiteId: string) {
if (!z.uuid().safeParse(websiteId).success) {
return null;
}
const website = await findWebsite({
where: {
id: websiteId,