From 5b4ea12624e785ebe9a4434b823b8fe0dab9040e Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Mon, 24 Nov 2025 21:12:32 -0500 Subject: [PATCH 01/10] add test to POST officers --- frontend/tests/officers.post.spec.ts | 118 +++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 frontend/tests/officers.post.spec.ts diff --git a/frontend/tests/officers.post.spec.ts b/frontend/tests/officers.post.spec.ts new file mode 100644 index 00000000..3327732a --- /dev/null +++ b/frontend/tests/officers.post.spec.ts @@ -0,0 +1,118 @@ +import { test, expect } from "@playwright/test" + +// This test posts multiple officers to the backend API and verifies they were created. +// It uses Playwright's APIRequestContext via the `request` fixture. The project's +// Playwright config sets `baseURL` to the web container, so we have to specify +// an `apiURL` here instead. + +// Sample officers payload - adjust fields to match backend model expectations. +const sampleOfficers = [ + { + uid: `test-officer-${Date.now()}-1`, + first_name: "TestFirst1", + middle_name: "M", + last_name: "TestLast1", + suffix: "Jr.", + ethnicity: "White", + gender: "Male", + state_ids: [ + { + id_name: "Tax ID Number", + state: "NY", + value: `TAX-${Date.now()}` + } + ] + }, + { + uid: `test-officer-${Date.now()}-2`, + first_name: "TestFirst2", + middle_name: "A", + last_name: "TestLast2", + ethnicity: "Hispanic/Latino", + gender: "Female", + state_ids: [ + { + id_name: "Driver's License", + state: "NY", + value: `DL-${Date.now()}` + } + ] + } +] + +test.describe("Officers API", () => { + test("POST multiple officers and verify they exist", async ({ request }) => { + // Register a temporary user and create a source so the user is promoted + // to CONTRIBUTOR (the backend requires that role to create officers). + const testEmail = `pw-${Date.now()}@example.com` + const testPassword = "TestPass123!" + const apiBase = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:5000/api/v1" + + const regRes = await request.post(`${apiBase}/auth/register`, { + data: { + email: testEmail, + password: testPassword, + firstname: "PW", + lastname: "Test", + phone_number: "000-000-0000" + }, + headers: { "Content-Type": "application/json" } + }) + + if (!regRes.ok()) { + const bad = await regRes.text() + console.error("Register failed:", regRes.status(), bad) + } + expect(regRes.ok()).toBeTruthy() + const regJson = await regRes.json() + const accessToken = regJson?.access_token + expect(accessToken).toBeTruthy() + + // Create a source to promote the user to CONTRIBUTOR + const sourceRes = await request.post(`${apiBase}/sources`, { + data: { + name: `PW Source ${Date.now()}`, + url: "https://example.org", + contact_email: testEmail + }, + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}` + } + }) + + expect(sourceRes.ok()).toBeTruthy() + + // POST each officer individually (API expects single-object create) + const createdUids: string[] = [] + for (const officer of sampleOfficers) { + const postRes = await request.post(`${apiBase}/officers`, { + data: officer, + headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}` } + }) + + if (!postRes.ok()) { + const body = await postRes.text() + console.error("Create officer failed:", postRes.status(), body) + } + expect(postRes.ok()).toBeTruthy() + + const postJson = await postRes.json() + const createdUid = postJson?.uid || postJson?.id || officer.uid + expect(createdUid).toBeTruthy() + createdUids.push(createdUid) + } + + // For each created UID, query the GET endpoint to confirm existence. + for (const uid of createdUids) { + const getRes = await request.get(`${apiBase}/officers/${encodeURIComponent(uid)}`, { + headers: { Authorization: `Bearer ${accessToken}` } + }) + expect(getRes.ok()).toBeTruthy() + const getJson = await getRes.json() + // Basic checks: returned object has matching uid and name + expect(getJson).toBeDefined() + expect(getJson.uid || getJson.id).toBeTruthy() + } + }) +}) From cfb6773fab55ceb81ff1eaa23e7cf1f44fc359e9 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Tue, 25 Nov 2025 22:13:55 -0500 Subject: [PATCH 02/10] fix 5000 by default --- docker-compose.yml | 2 +- frontend/tests/officers.post.spec.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4e99ab84..a9bbadb1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,7 +35,7 @@ services: - /app/node_modules environment: NEXT_PUBLIC_API_MODE: real - NEXT_PUBLIC_API_BASE_URL: http://localhost:${NPDI_API_PORT:-5000}/api/v1 + NEXT_PUBLIC_API_BASE_URL: http://localhost:${NPDI_API_PORT:-5001}/api/v1 ports: - ${NPDI_WEB_PORT:-3000}:${NPDI_WEB_PORT:-3000} api: diff --git a/frontend/tests/officers.post.spec.ts b/frontend/tests/officers.post.spec.ts index 3327732a..60d5b87d 100644 --- a/frontend/tests/officers.post.spec.ts +++ b/frontend/tests/officers.post.spec.ts @@ -46,7 +46,9 @@ test.describe("Officers API", () => { // to CONTRIBUTOR (the backend requires that role to create officers). const testEmail = `pw-${Date.now()}@example.com` const testPassword = "TestPass123!" - const apiBase = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:5000/api/v1" + const apiBase = + process.env.NEXT_PUBLIC_API_BASE_URL ?? + `http://localhost:${process.env.NPDI_API_PORT ?? "5001"}/api/v1` const regRes = await request.post(`${apiBase}/auth/register`, { data: { From aafe504cc7b0ad9f24dbbda1a1f12ec7720234e3 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Tue, 25 Nov 2025 22:21:59 -0500 Subject: [PATCH 03/10] debug docker compose --- .github/workflows/playwright-e2e.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 3bd1808c..36de5fad 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -105,7 +105,8 @@ jobs: working-directory: frontend env: NPDI_WEB_PORT: 3000 - run: npm run test:e2e + NPDI_API_PORT: 5001 + run: docker compose ps && npm run test:e2e - name: Upload test results uses: actions/upload-artifact@v5 From 5a5f12c61f033cdac113f59d0afd07111cca1059 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Tue, 25 Nov 2025 22:28:33 -0500 Subject: [PATCH 04/10] only chromium, look at api logs --- .github/workflows/playwright-e2e.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 36de5fad..502b2667 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -99,14 +99,14 @@ jobs: - name: Install Playwright Browsers working-directory: frontend - run: npx playwright install --with-deps + run: npx playwright install --with-deps chromium - name: Run Playwright tests working-directory: frontend env: NPDI_WEB_PORT: 3000 NPDI_API_PORT: 5001 - run: docker compose ps && npm run test:e2e + run: docker compose ps && docker compose logs api && echo "" && npm run test:e2e - name: Upload test results uses: actions/upload-artifact@v5 From 1575dd4ad15cbfb90fd0e3ed23513c9fad51b41d Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Tue, 25 Nov 2025 22:35:36 -0500 Subject: [PATCH 05/10] set api url env var --- .github/workflows/playwright-e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 502b2667..62faee6f 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -106,6 +106,7 @@ jobs: env: NPDI_WEB_PORT: 3000 NPDI_API_PORT: 5001 + NEXT_PUBLIC_API_BASE_URL: http://0.0.0.0:5001/api/v1 run: docker compose ps && docker compose logs api && echo "" && npm run test:e2e - name: Upload test results From 2a5658c32e419713386f483cbe82c930bae2c524 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Tue, 25 Nov 2025 22:42:07 -0500 Subject: [PATCH 06/10] add GRAPH_NM_URI to dco env in Github --- .github/workflows/playwright-e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 62faee6f..d14166c3 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -26,6 +26,7 @@ jobs: NPDI_API_PORT=5001 GRAPH_PASSWORD=test_password GRAPH_USER=neo4j + GRAPH_NM_URI=bolt://db:7687 FLASK_ENV=development MIXPANEL_TOKEN=notset EOF From 473d40251e64d1744c68fcd5ae720664e29b196c Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Wed, 26 Nov 2025 11:10:43 -0500 Subject: [PATCH 07/10] wrap in quotes, check hosts --- .github/workflows/playwright-e2e.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index d14166c3..ab16099e 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -26,7 +26,7 @@ jobs: NPDI_API_PORT=5001 GRAPH_PASSWORD=test_password GRAPH_USER=neo4j - GRAPH_NM_URI=bolt://db:7687 + GRAPH_NM_URI="bolt://db:7687" FLASK_ENV=development MIXPANEL_TOKEN=notset EOF @@ -39,6 +39,8 @@ jobs: - name: Wait for services to be healthy run: | + docker compose ps + cat /etc/hosts echo "Waiting for services to be ready..." # Wait for Neo4j From 120d758fa973f5637bc2dcac0e485977d5fbd8e1 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Wed, 26 Nov 2025 11:15:08 -0500 Subject: [PATCH 08/10] look at hosts inside --- .github/workflows/playwright-e2e.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index ab16099e..8ef94d8a 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -78,6 +78,10 @@ jobs: echo "All services are ready!" + - name: Wait for services to be healthy + run: | + docker compose exec api cat /etc/hosts + - name: Check service logs if: failure() run: | From a9a5bc60f3472ebb2ab08a88eb59c63c76d41fa8 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Wed, 26 Nov 2025 11:31:17 -0500 Subject: [PATCH 09/10] no double bolt --- .github/workflows/playwright-e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 8ef94d8a..299ce06b 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -26,7 +26,7 @@ jobs: NPDI_API_PORT=5001 GRAPH_PASSWORD=test_password GRAPH_USER=neo4j - GRAPH_NM_URI="bolt://db:7687" + GRAPH_NM_URI="db:7687" FLASK_ENV=development MIXPANEL_TOKEN=notset EOF From 4efe73a052a25f790027c1d4ad7a9e41ac6b62c1 Mon Sep 17 00:00:00 2001 From: Mike Yavorsky Date: Wed, 26 Nov 2025 11:39:46 -0500 Subject: [PATCH 10/10] remove debug --- .github/workflows/playwright-e2e.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/playwright-e2e.yml b/.github/workflows/playwright-e2e.yml index 299ce06b..de0c4044 100644 --- a/.github/workflows/playwright-e2e.yml +++ b/.github/workflows/playwright-e2e.yml @@ -39,8 +39,6 @@ jobs: - name: Wait for services to be healthy run: | - docker compose ps - cat /etc/hosts echo "Waiting for services to be ready..." # Wait for Neo4j @@ -78,10 +76,6 @@ jobs: echo "All services are ready!" - - name: Wait for services to be healthy - run: | - docker compose exec api cat /etc/hosts - - name: Check service logs if: failure() run: | @@ -114,7 +108,7 @@ jobs: NPDI_WEB_PORT: 3000 NPDI_API_PORT: 5001 NEXT_PUBLIC_API_BASE_URL: http://0.0.0.0:5001/api/v1 - run: docker compose ps && docker compose logs api && echo "" && npm run test:e2e + run: npm run test:e2e - name: Upload test results uses: actions/upload-artifact@v5