Skip to content

635 — should apply highest-priority dimension when matching billable rate

Description

End-to-end check that the priority order genuinely drives which billable rate is applied when creating a time record. Six rates are created — one per dimension (Task, Label, Project, Client, Team, User) — each with a distinct value. The Task / Project / Client rates carry their parent dimensions to mirror the UI's auto-fill (Task → Project → Client; Project → Client). The same fully-populated time record is then matched against the backend's matchingBillableRate query under three different priorities to prove that reordering the priority changes which rate is picked.

Preconditions

  • Signed-in tenant owner with a fresh organization.
  • Priority is at the server default.
  • The Finance Settings → Hourly rates page is open.

Steps

  1. Seed entities via API: a client, a project (in the seeded client), a task (in the seeded project, assignee = owner), a team (owner added as a member), and a label. Expected: all entities are created and return non-null payloads.
  2. Create six billable rates with distinct values (e.g. 1001…1006): Task (carries client+project+task), Project (carries client+project), Client (client only), Label (tag only), Team (team only), User (user only). Expected: all six createBillableRate mutations return non-null billableRate.id.
  3. Build a TimeRecordInput that references the owner, client, project, task, and label, and query matchingBillableRate. Expected: the matched rate equals the Task value (default priority puts Task first).
  4. Open the Change priority dialog and drag User to the top. Click Save. Expected: "Updated" snackbar appears; dialog closes.
  5. Re-query matchingBillableRate with the same input. Expected: the matched rate equals the User value.
  6. Set priority to put Tags first via the updateBillableRatePriority mutation. Re-query matchingBillableRate. Expected: the matched rate equals the Label value. (Note: a CLIENT-first reorder doesn't work as a counter-test here — the TASK rate is seeded with its parent client/project to mirror the UI's auto-fill behaviour, so under CLIENT-first the TASK rate still ties at priority 0 and wins by specificity. The Label rate is the only top-priority candidate that isn't also reachable via the TASK rate's scope.)
  • Spec: playwright/tests/integration/hourlyRate.spec.ts
  • GraphQL: matchingBillableRate, billableRatePriority, updateBillableRatePriority, createBillableRate, createTimeRecord