Skip to content

test(db): expand /api/db/permissions coverage + document accepted mode formats#47

Open
joewiz wants to merge 2 commits into
eXist-db:developfrom
joewiz:test/db-permissions-coverage
Open

test(db): expand /api/db/permissions coverage + document accepted mode formats#47
joewiz wants to merge 2 commits into
eXist-db:developfrom
joewiz:test/db-permissions-coverage

Conversation

@joewiz

@joewiz joewiz commented Jun 6, 2026

Copy link
Copy Markdown
Member

[This PR was co-authored with Claude Code. -Joe]

POST /api/db/permissions accepts owner / group / mode (all optional), but the existing test exercised only one path: mode change on a resource, single rwxrwxrwx-style value. Coverage was shallow. Filling in the gaps so we have real confidence in the endpoint before eXide's DB Manager round-trips against it.

New tests (7)

Case What it verifies
owner change on a resource admin → guest, verify via /properties, restore to admin
group change on a resource dba → guest, verify, restore
{owner, group, mode} combined in one request all three fields applied in a single call
mode change on a collection (not just a resource) sm:chmod treats collections the same way, but the eXide UI surfaces this separately, so worth pinning
Octal mode '0644' → rejected Documenting the contract: sm:chmod only accepts the symbolic rwxrwxrwx form (and relative u+x / g-w / …), NOT octal strings. Clients that want to send a numeric mode must convert it first.
Missing path → HTTP 400 Declared in the spec but previously untested
Nonexistent path → HTTP 5xx with a sensible error description

Each round-trip test verifies via GET /api/db/properties that the requested field changed, then restores the original value so later tests in the suite aren't affected.

Setup creates a dedicated permResource and permSubCollection inside the existing testCollection so these tests don't perturb (or get perturbed by) the earlier /test.xml mode-change test; cleanup is handled by the existing testCollection teardown.

Result

All 50 db.cy.js tests pass — up from 43. No production-code change in this PR; this is pure test infill against existing endpoint behavior, surfacing the contract for clients to rely on.

Discovery worth flagging: octal mode strings are silently rejected

While building the tests I found that POST /api/db/permissions with "mode": "0644" (or "644") fails with Unrecognised mode syntax. Tracked it to AbstractUnixStylePermission.setMode(String) in eXist core, which accepts exactly three symbolic formats — simple rwxr-xr-x, Unix relative u+x,g-w, eXist verbose user=+read,… — and not octal strings. eXist does support octal via the integer overload of sm:chmod, but existdb-openapi's handler passes $body?mode (a JSON string) to the string overload, which doesn't try parsing as octal.

Checked the impact on real clients:

  • eXide builds modes from its DB Manager checkbox grid as Unix symbolic strings (directory.js:298-313 — e.g. "u+r,u-w,u+x,g+r,…"). Already works.
  • existdb-oxygen-plugin — UI not yet inspected, but a similar checkbox grid would naturally build symbolic too.

Octal-as-string only burdens callers who think in chmod 644 terms (scripts, CLI tools, docs ported from Unix tutorials). No current first-party client hits it.

What this PR does about it: pin the current behaviour as a test, document the three accepted formats and the octal omission in api.json so the contract is on the spec page. If a client comes back wanting octal, the implementation is small — detect ^0?[0-7]{3,4}$ in the handler, convert to xs:integer, dispatch to the integer overload of sm:chmod — and the test flips from "rejected" to "coerced and applied". Open an issue at that point.

Why now

Per the eXide-side conversation: before adding round-trip permission-change tests to eXide's DB Manager cypress suite, the underlying existdb-openapi endpoint should have proper coverage. With this PR, the eXide tests can confidently treat the endpoint as a stable contract.

joewiz added 2 commits June 5, 2026 23:32
The endpoint accepts owner/group/mode (all optional), but the existing
test only exercised mode-on-a-resource with one rwxrwxrwx-style value.
Real coverage was shallow. Adding the cases that actually matter for
clients (eXide DB Manager, Oxygen plugin) before they round-trip
against the endpoint:

- owner change on a resource (admin → guest → admin)
- group change on a resource (dba → guest → dba)
- combined {owner, group, mode} in a single request — verify all three
  applied
- mode change on a collection (sm:chmod handles collections same as
  resources, but worth pinning since the eXide UI surfaces this)
- octal mode '0644' → rejected. Documenting the contract:
  sm:chmod only accepts the symbolic rwxrwxrwx form (and relative
  u+x/g-w/...), not octal strings. Clients that want to send a numeric
  mode must convert it first.
- missing 'path' → HTTP 400 (declared in spec but previously untested)
- nonexistent path → HTTP 5xx with a sensible error description

Each round-trip-style test now verifies via GET /api/db/properties
that the requested field actually changed, then restores the original
value so later tests in the same suite aren't affected.

Setup creates a dedicated permResource + permSubCollection in the
test collection so these tests don't perturb the earlier /test.xml
mode-change test (and vice versa); cleanup is handled by the existing
testCollection teardown.

All 50 db.cy.js tests pass (up from 43).
…ccepts

Spell out in the OpenAPI spec which mode-string formats sm:chmod's
string overload accepts, and call out that octal strings (0644 / 644)
are NOT accepted — this is the same contract the new octal-rejection
test pins. Clients now have the formats documented up front instead
of having to file an issue when a typed numeric mode fails.

If a client comes back asking for octal support, the test flips to
assert success and the handler gains a small parse-and-coerce step.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant