Skip to content

Commit 4bc04e4

Browse files
committed
test(V2): cover live non-home project mutations
Add live API checks that non-home project update and delete requests are rejected when subscribed non-home project data is available.
1 parent 2b1715e commit 4bc04e4

1 file changed

Lines changed: 82 additions & 6 deletions

File tree

tests/v2/live-api/project-validation.live.spec.js

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,55 @@ import {
1515
makeDeleteRequest,
1616
checkRecordInStaging,
1717
} from './helpers/api-request-helpers.js';
18-
import { addCreatedId, shouldAutoCommit, trackBatchVerification, getFirstRecordIdFromDatabase, getAllRecordIdsFromDatabase } from './helpers/shared-state.js';
18+
import { addCreatedId, shouldAutoCommit, trackBatchVerification } from './helpers/shared-state.js';
1919
import {
2020
generateProject,
2121
generateProjectMinimal,
2222
generateProjectMaximal,
2323
generateProjectLongStrings,
2424
generateProjectForbiddenFields,
25-
getLongString,
2625
getInvalidPicklistValue,
2726
} from './data/test-data-generators.js';
2827

28+
const findNonHomeProject = async (request, homeOrgId) => {
29+
let page = 1;
30+
const limit = 100;
31+
32+
while (page <= 10) {
33+
const response = await request
34+
.get('/v2/project')
35+
.query({ page, limit })
36+
.expect(200);
37+
const data = Array.isArray(response.body) ? response.body : (response.body?.data || []);
38+
const nonHomeProject = data.find(record => record.orgUid && record.orgUid !== homeOrgId);
39+
if (nonHomeProject) return nonHomeProject;
40+
41+
const totalPages = response.body?.pageCount || 1;
42+
if (page >= totalPages || data.length < limit) break;
43+
page++;
44+
}
45+
46+
return null;
47+
};
48+
49+
const buildProjectUpdateData = (record, overrides = {}) => ({
50+
projectRegistryName: record.projectRegistryName,
51+
projectId: record.projectId,
52+
projectName: record.projectName,
53+
projectCreditingProgram: record.projectCreditingProgram ?? null,
54+
projectLink: record.projectLink ?? null,
55+
projectDescription: record.projectDescription ?? null,
56+
projectSector: record.projectSector ?? null,
57+
projectType: record.projectType ?? null,
58+
projectSubtype: record.projectSubtype ?? null,
59+
projectStatus: record.projectStatus ?? null,
60+
projectStatusDate: record.projectStatusDate ?? null,
61+
projectUnitMetric: record.projectUnitMetric ?? null,
62+
cadTrustReferenceProjectId: record.cadTrustReferenceProjectId ?? null,
63+
cadTrustProgramId: record.cadTrustProgramId ?? null,
64+
...overrides,
65+
});
66+
2967
describe('Project Live API Validation Tests', function () {
3068
this.timeout(600000); // 10 minute timeout
3169
let request;
@@ -179,16 +217,37 @@ describe('Project Live API Validation Tests', function () {
179217
});
180218
});
181219
describe('Step 7: PUT Request Tests', function () {
220+
it('should reject updating a project not owned by the home organization', async function () {
221+
const nonHomeProject = await findNonHomeProject(request, homeOrgId);
222+
if (!nonHomeProject) {
223+
this.skip();
224+
}
225+
226+
const updateData = buildProjectUpdateData(nonHomeProject, {
227+
projectName: `Should Not Update ${Date.now()}`,
228+
});
229+
230+
try {
231+
const response = await request
232+
.put(`/v2/project/${nonHomeProject.cadTrustProjectId}`)
233+
.send(updateData);
234+
235+
expect(response.status).to.equal(400);
236+
expect(response.body.success).to.be.false;
237+
expect(response.body.error).to.include('Restricted data');
238+
} finally {
239+
await clearStagingTable(request);
240+
}
241+
});
242+
182243
it('should update a project', async function () {
183244
// Get ID from createdIds (if available) or query for test records we created
184245
let id = createdIds[0];
185246
if (!id) {
186247
// Query for test records by filtering by home org and TEST- prefix
187248
let page = 1;
188249
const limit = 100;
189-
let found = false;
190-
191-
while (!found && page <= 10) { // Limit to 10 pages to avoid infinite loop
250+
while (page <= 10) { // Limit to 10 pages to avoid infinite loop
192251
const response = await request.get(`/v2/project?page=${page}&limit=${limit}&orgUid=${homeOrgId}`).expect(200);
193252
const data = Array.isArray(response.body) ? response.body : (response.body?.data || []);
194253

@@ -199,7 +258,6 @@ describe('Project Live API Validation Tests', function () {
199258

200259
if (testRecord) {
201260
id = testRecord.cadTrustProjectId;
202-
found = true;
203261
break;
204262
}
205263

@@ -306,6 +364,24 @@ describe('Project Live API Validation Tests', function () {
306364
});
307365
});
308366
describe('Step 9: DELETE Request Tests', function () {
367+
it('should reject deleting a project not owned by the home organization', async function () {
368+
const nonHomeProject = await findNonHomeProject(request, homeOrgId);
369+
if (!nonHomeProject) {
370+
this.skip();
371+
}
372+
373+
try {
374+
const response = await request
375+
.delete(`/v2/project/${nonHomeProject.cadTrustProjectId}`);
376+
377+
expect(response.status).to.equal(400);
378+
expect(response.body.success).to.be.false;
379+
expect(response.body.error).to.include('Restricted data');
380+
} finally {
381+
await clearStagingTable(request);
382+
}
383+
});
384+
309385
it('should delete all created projects', async function () {
310386
// Query for test projects by orgUid and TEST- prefix
311387
// This works even when DELETE runs in a separate process

0 commit comments

Comments
 (0)