Skip to content

feat(api): client-side request guards matching server validation - #79

Merged
ngjunsiang merged 1 commit into
bugfix/submissions-unsubmitfrom
feat/request-guards
Oct 4, 2026
Merged

ngjunsiang merged 1 commit into
bugfix/submissions-unsubmitfrom
feat/request-guards

Conversation

@nycomp

@nycomp nycomp commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Stack (merge in order): #78 -> #79 -> #80 -> #81 -> #82 -> #85
This is 2 of 6. Base is the branch of the PR below; each PR's diff shows only its own commit, and GitHub retargets it to main when the one below merges. Branches rebuilt on current main (9563443) — content unchanged from the original commits.
As always per SOP: after each merge, verify the issue auto-closed and close it manually if not.

Summary

Client-side validation for the three payloads the campus weekly server always rejects (discovered in the PR #70 sweep), so consumers get immediate client errors instead of surprise 4xx responses:

  1. Circles — Circle.update() now has an explicit signature: name is required (server 422s on a circle PATCH without it), description optional and unchanged when omitted. Also exposes members.set(member_id, access_value), the PATCH /circles/<id>/members/ upsert route the server provides (add/remove were the only members operations until now).
  2. Assignments — Assignment.update() raises ValueError("At least one field must be provided for update") on an empty body, mirroring Submissions.update()'s contract (server: "Empty request body" 400).
  3. Timetable — Timetables.new() raises ValueError unless data contains lessongroups, with a rename hint when lesson_groups is present (mirroring the server's 400 suggestion).

All guards are client-side; no server changes.

Tests

tests/unit/test_request_guards.py — 9 tests pinning each guard (including that no request is sent when a guard fires) and the members PATCH upsert path. Full suite: 155 passed.

Fixes #75

- Circles.Circle.update(): explicit signature with required name
  (server 422s without it); description optional/unchanged
- Circles members.set(): expose the PATCH /members/ upsert route
- Assignments.Assignment.update(): ValueError on empty body
  (server rejects "Empty request body")
- Timetables.new(): ValueError unless data carries the lessongroups
  key, with a rename hint when lesson_groups is present

Fixes #75
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.

feat(api): client-side request guards matching server validation (circles name, assignments non-empty, timetable lessongroups)

2 participants