diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e41e66bc01d..73a2d77efffe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3290,6 +3290,10 @@ importers: react: specifier: 18.3.1 version: 18.3.1 + devDependencies: + kea-test-utils: + specifier: 'catalog:' + version: 0.2.4(kea@4.0.0-pre.6(patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5)(react@18.3.1)) products/links: dependencies: diff --git a/products/legal_documents/frontend/scenes/legalDocumentsLogic.test.ts b/products/legal_documents/frontend/scenes/legalDocumentsLogic.test.ts new file mode 100644 index 000000000000..6a56b86997f5 --- /dev/null +++ b/products/legal_documents/frontend/scenes/legalDocumentsLogic.test.ts @@ -0,0 +1,34 @@ +import { expectLogic } from 'kea-test-utils' + +import { initKeaTests } from '~/test/init' + +import { AppContext } from '../../../../frontend/src/types' +import * as api from '../generated/api' +import { legalDocumentsLogic } from './legalDocumentsLogic' + +jest.mock('../generated/api', () => ({ + legalDocumentsList: jest.fn().mockResolvedValue({ results: [] }), +})) + +describe('legalDocumentsLogic', () => { + let logic: ReturnType + + afterEach(() => { + logic?.unmount() + }) + + it('does not call the API with the "@current" sentinel while the organization is still loading', async () => { + // No organization in context yet, and organizationLogic won't resolve it + // synchronously — currentOrganizationId falls back to '@current' during + // this window, which the backend 404s on. + window.POSTHOG_APP_CONTEXT = { current_user: null } as unknown as AppContext + initKeaTests(false) + logic = legalDocumentsLogic() + logic.mount() + + await expectLogic(logic).toDispatchActions(['loadLegalDocumentsSuccess']) + + expect(api.legalDocumentsList).not.toHaveBeenCalled() + expect(logic.values.legalDocuments).toEqual([]) + }) +}) diff --git a/products/legal_documents/frontend/scenes/legalDocumentsLogic.ts b/products/legal_documents/frontend/scenes/legalDocumentsLogic.ts index 2cb3528a71dc..1cfafa2e8a2b 100644 --- a/products/legal_documents/frontend/scenes/legalDocumentsLogic.ts +++ b/products/legal_documents/frontend/scenes/legalDocumentsLogic.ts @@ -215,17 +215,22 @@ export const legalDocumentsLogic = kea([ [] as LegalDocument[], { loadLegalDocuments: async () => { - if (!values.currentOrganizationId) { + if (!values.currentOrganization?.id) { + // Organization hasn't loaded yet — currentOrganizationId would + // fall back to the '@current' sentinel, which the backend can't + // resolve. No-op until the real organization is available. return [] } - if (values.isAdminOrOwner === false && values.currentOrganization) { + if (values.isAdminOrOwner === false) { return [] } try { const response = await api.legalDocumentsList(values.currentOrganizationId) return (response.results ?? []) as LegalDocument[] } catch (error) { - if (error instanceof ApiError && error.status === 403) { + // 403 (non-admin) and 404 (organization not resolvable, e.g. a + // stale/transient race) both degrade to an empty list. + if (error instanceof ApiError && (error.status === 403 || error.status === 404)) { return [] } throw error @@ -287,7 +292,7 @@ export const legalDocumentsLogic = kea([ actions.setLegalDocumentValue('dpa_mode', dpaMode) }, deleteLegalDocument: async ({ id, documentType }) => { - if (!values.currentOrganizationId) { + if (!values.currentOrganization?.id) { return } actions.setDeletingId(id) diff --git a/products/legal_documents/package.json b/products/legal_documents/package.json index ba786583c1a8..7c960c506f37 100644 --- a/products/legal_documents/package.json +++ b/products/legal_documents/package.json @@ -10,6 +10,9 @@ "kea-loaders": "catalog:", "kea-router": "catalog:" }, + "devDependencies": { + "kea-test-utils": "catalog:" + }, "peerDependencies": { "@posthog/icons": "catalog:", "@posthog/lemon-ui": "*",