You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #784 (writeLock endpoints in waltham-data-science/ndi-cloud-node, PR #106).
The PR adds unit tests in api/src/tests/ that cover the service / middleware / controller in isolation (mocked Mongoose), but there are no end-to-end tests against a deployed API for the new endpoints. We have e2e coverage for the older Dataset / Document endpoints in api/e2eScripts/, so the gap is specifically the new write-lock surface.
Scope
Add e2e scripts under api/e2eScripts/datasets/ (or a new api/e2eScripts/datasets/write-lock/ folder) in the same style as the existing scripts. The tests should run against a deployed dev environment and exercise the real HTTP API, not the in-process service.
Endpoints to cover
GET /v1/datasets/:datasetId/write-lock
POST /v1/datasets/:datasetId/write-lock
PATCH /v1/datasets/:datasetId/write-lock
DELETE /v1/datasets/:datasetId/write-lock
Plus the Document write paths under lock:
POST /v1/datasets/:datasetId/documents
POST /v1/datasets/:datasetId/documents/:documentId
POST /v1/datasets/:datasetId/documents/bulk-delete
POST /v1/datasets/:datasetId/documents/bulk-upload
Test cases (golden-path + edge)
Lifecycle
GET on a fresh dataset returns { writeLock: { state: 'idle' } }.
POST with { reason: 'e2e-test' } returns 200 with state: 'held', heldBy, heldUntil, reason.
GET after acquire returns the held lock.
PATCH extends heldUntil (compare timestamps).
DELETE releases the lock; subsequent GET shows state: 'idle'.
Idempotency / conflict
6. POST twice by the same user → both 200 (idempotent re-acquire).
7. User A acquires; user B POSTs → 409 with current holder details (heldBy, reason).
8. User A acquires; user B DELETEs → 403.
9. User A acquires; user B PATCHes → 403.
Write-path enforcement
10. User A acquires the lock; user B POSTs a document → 423 with { heldBy, heldUntil, reason }.
11. User A acquires; user B POSTs to documents/:id (update), DELETEs a document, POSTs bulk-delete, POSTs bulk-upload → all 423.
12. While held, user B GETs documents → still 200 (reads must not be blocked).
13. While held, user A (the holder) writes a document → 200 (holder bypass).
Expiry
14. Acquire with ttlSeconds: 30 (the service minimum), wait > 30s, then user B POSTs a document → 200 (lazy expiry clears the lock). GET write-lock after the next write call should show state: 'idle'.
Admin force-release
15. User A acquires the lock; admin user DELETEs the lock → 204. Subsequent GET shows state: 'idle'.
16. Admin force-releasing an already-idle lock → 204.
Auth
17. Unauthenticated POST / PATCH / DELETE → 401 or 403 (whatever the auth middleware returns; document it).
Out of scope
The client-side ndi.migrate.cloud consumer (separate issue, NDI-matlab Dayone #10).
Load / concurrency stress tests; one acquire-attempt-from-each-of-two-users is enough for v1.
Dependencies
PR waltham-data-science/ndi-cloud-node#106 must be merged and deployed to dev before these tests can run green.
Follow-up to #784 (writeLock endpoints in
waltham-data-science/ndi-cloud-node, PR #106).The PR adds unit tests in
api/src/tests/that cover the service / middleware / controller in isolation (mocked Mongoose), but there are no end-to-end tests against a deployed API for the new endpoints. We have e2e coverage for the older Dataset / Document endpoints inapi/e2eScripts/, so the gap is specifically the new write-lock surface.Scope
Add e2e scripts under
api/e2eScripts/datasets/(or a newapi/e2eScripts/datasets/write-lock/folder) in the same style as the existing scripts. The tests should run against a deployed dev environment and exercise the real HTTP API, not the in-process service.Endpoints to cover
GET /v1/datasets/:datasetId/write-lockPOST /v1/datasets/:datasetId/write-lockPATCH /v1/datasets/:datasetId/write-lockDELETE /v1/datasets/:datasetId/write-lockPlus the Document write paths under lock:
POST /v1/datasets/:datasetId/documentsPOST /v1/datasets/:datasetId/documents/:documentIdDELETE /v1/datasets/:datasetId/documents/:documentIdPOST /v1/datasets/:datasetId/documents/bulk-deletePOST /v1/datasets/:datasetId/documents/bulk-uploadTest cases (golden-path + edge)
Lifecycle
GETon a fresh dataset returns{ writeLock: { state: 'idle' } }.POSTwith{ reason: 'e2e-test' }returns 200 withstate: 'held',heldBy,heldUntil,reason.GETafter acquire returns the held lock.PATCHextendsheldUntil(compare timestamps).DELETEreleases the lock; subsequentGETshowsstate: 'idle'.Idempotency / conflict
6.
POSTtwice by the same user → both 200 (idempotent re-acquire).7. User A acquires; user B
POSTs → 409 with current holder details (heldBy,reason).8. User A acquires; user B
DELETEs → 403.9. User A acquires; user B
PATCHes → 403.Write-path enforcement
10. User A acquires the lock; user B
POSTs a document → 423 with{ heldBy, heldUntil, reason }.11. User A acquires; user B
POSTs todocuments/:id(update),DELETEs a document,POSTsbulk-delete,POSTsbulk-upload→ all 423.12. While held, user B
GETs documents → still 200 (reads must not be blocked).13. While held, user A (the holder) writes a document → 200 (holder bypass).
Expiry
14. Acquire with
ttlSeconds: 30(the service minimum), wait > 30s, then user BPOSTs a document → 200 (lazy expiry clears the lock).GET write-lockafter the next write call should showstate: 'idle'.Admin force-release
15. User A acquires the lock; admin user
DELETEs the lock → 204. SubsequentGETshowsstate: 'idle'.16. Admin force-releasing an already-idle lock → 204.
Auth
17. Unauthenticated
POST/PATCH/DELETE→ 401 or 403 (whatever the auth middleware returns; document it).Out of scope
ndi.migrate.cloudconsumer (separate issue, NDI-matlab Dayone #10).Dependencies
PR
waltham-data-science/ndi-cloud-node#106must be merged and deployed to dev before these tests can run green.Suggested file layout
…or one consolidated script if that matches the existing style better.