Return 404 when session is not found and add test coverage for GET session route

This commit is contained in:
Mike Cao committed 2026-07-20 17:15:52 -07:00
1 parent 9bf95ef112
commit eb9a77ea64
2 files changed
+77 -29

No files matched your search

@@ -0,0 +1,53 @@
import { beforeEach, expect, test, vi } from 'vitest';
import { parseRequest } from '@/lib/request';
import { canViewWebsiteSection } from '@/permissions';
import { getLinkedDistinctIds, getLinkedSessionIds, getWebsiteSession } from '@/queries/sql';
import { GET } from './route';
vi.mock('@/lib/request', () => ({
parseRequest: vi.fn(),
}));
vi.mock('@/permissions', () => ({
canViewWebsiteSection: vi.fn(),
}));
vi.mock('@/queries/sql', () => ({
getLinkedDistinctIds: vi.fn(),
getLinkedSessionIds: vi.fn(),
getWebsiteSession: vi.fn(),
}));
const parseRequestMock = vi.mocked(parseRequest);
const canViewWebsiteSectionMock = vi.mocked(canViewWebsiteSection);
const getLinkedDistinctIdsMock = vi.mocked(getLinkedDistinctIds);
const getLinkedSessionIdsMock = vi.mocked(getLinkedSessionIds);
const getWebsiteSessionMock = vi.mocked(getWebsiteSession);
beforeEach(() => {
parseRequestMock.mockReset();
canViewWebsiteSectionMock.mockReset();
getLinkedDistinctIdsMock.mockReset();
getLinkedSessionIdsMock.mockReset();
getWebsiteSessionMock.mockReset();
});
test('GET returns not found when the session does not exist', async () => {
parseRequestMock.mockResolvedValue({ auth: {}, error: undefined });
canViewWebsiteSectionMock.mockResolvedValue(true);
getWebsiteSessionMock.mockResolvedValue(undefined);
const response = await GET(
new Request('http://localhost/api/websites/website-1/sessions/missing-session'),
{
params: Promise.resolve({ websiteId: 'website-1', sessionId: 'missing-session' }),
},
);
expect(response.status).toBe(404);
await expect(response.json()).resolves.toMatchObject({
error: { code: 'not-found', status: 404 },
});
expect(getLinkedDistinctIdsMock).not.toHaveBeenCalled();
expect(getLinkedSessionIdsMock).not.toHaveBeenCalled();
});
@@ -1,5 +1,5 @@
import { parseRequest } from '@/lib/request';
import { json, unauthorized } from '@/lib/response';
import { json, notFound, unauthorized } from '@/lib/response';
import { canViewWebsiteSection } from '@/permissions';
import { getLinkedDistinctIds, getLinkedSessionIds, getWebsiteSession } from '@/queries/sql';
@@ -16,42 +16,37 @@ export async function GET(
const { websiteId, sessionId } = await params;
if (
!(await canViewWebsiteSection(auth, websiteId, [
'sessions',
'events',
'realtime',
'revenue',
]))
!(await canViewWebsiteSection(auth, websiteId, ['sessions', 'events', 'realtime', 'revenue']))
) {
return unauthorized();
}
const data = await getWebsiteSession(websiteId, sessionId);
let stitchedSessionCount = 0;
if (data) {
let sessionIds = [sessionId];
const distinctIds = data.distinctId
? [data.distinctId]
: await getLinkedDistinctIds(websiteId, sessionId);
if (!data.distinctId && distinctIds.length === 1) {
data.distinctId = distinctIds[0];
}
if (distinctIds.length) {
const links = await Promise.all(
distinctIds.map(distinctId => getLinkedSessionIds(websiteId, distinctId)),
);
const linkedIds = links.flatMap(group => group.map(link => link.sessionId));
sessionIds = Array.from(new Set([sessionId, ...linkedIds]));
}
stitchedSessionCount = sessionIds.length;
if (!data) {
return notFound();
}
let sessionIds = [sessionId];
const distinctIds = data.distinctId
? [data.distinctId]
: await getLinkedDistinctIds(websiteId, sessionId);
if (!data.distinctId && distinctIds.length === 1) {
data.distinctId = distinctIds[0];
}
if (distinctIds.length) {
const links = await Promise.all(
distinctIds.map(distinctId => getLinkedSessionIds(websiteId, distinctId)),
);
const linkedIds = links.flatMap(group => group.map(link => link.sessionId));
sessionIds = Array.from(new Set([sessionId, ...linkedIds]));
}
const stitchedSessionCount = sessionIds.length;
return json({
...data,
stitchedSessionCount,