aglinxinyuan opened a new pull request, #7825:
URL: https://github.com/apache/texera/pull/7825

   ### What changes were proposed in this PR?
   
   Six sortable columns in the admin user table rendered backwards relative to 
the caret they lit. `sortByName`, `sortByEmail`, `sortByAffiliation`, 
`sortByJoiningReason`, `sortByComment` and `sortByRole` all compared with 
reversed operands.
   
   ng-zorro uses an `NzTableSortFn`'s result **as-is** for `ascend` and negates 
it for `descend` (`ng-zorro-antd-table.mjs:822`). Every one of these six 
headers declares `nzSortDirections="['ascend','descend']"` — no `null` member — 
so the first click is always `ascend`, and reversed operands render Z→A under a 
lit up-caret.
   
   All six were verified individually against their own `<th>` before being 
touched; none was already correct and none started at `descend`:
   
   | Comparator | `<th>` `nzSortDirections` |
   |---|---|
   | `sortByName` | line 46, `['ascend','descend']` |
   | `sortByEmail` | line 60, `['ascend','descend']` |
   | `sortByAffiliation` | line 74, `['ascend','descend']` |
   | `sortByJoiningReason` | line 79, `['ascend','descend']` |
   | `sortByComment` | line 84, `['ascend','descend']` |
   | `sortByRole` | line 99 (`nzSortFn` at 105), `['ascend','descend']` |
   
   Same defect and same signature as `sortBySize` in #7806. Two corroborations 
inside this file: the tie-breaker in all six is the contract-correct ascending 
`a.uid - b.uid`, and `sortByAccountCreation` already uses ascending form under 
an identical header.
   
   ### The existing spec was cementing the defect
   
   Its "column sort comparators" block asserted the reversed behaviour directly 
— e.g. `sortByName(Alice, Bob) > 0`. Those six assertions are corrected here, 
which is why they appear in the failing-before set below rather than being 
untouched.
   
   ### Failing before, passing after
   
   | | production reverted | with fix |
   |---|---|---|
   | `admin-user.component.spec.ts` | **12 failed, 42 passed** | **54 passed** |
   
   12 is exactly 6 comparators × 2 tests each. The rendered-header failures 
show the #7806 signature — the caret assertions *passed* and only the order 
failed, e.g. `sorts User Role A-to-Z…` → `expected [3, 2, 1, 4] to deeply equal 
[4, 1, 2, 3]`.
   
   ### Test design, which matters more here than the fix
   
   The fix is six operand swaps; the risk is a test that cannot tell a correct 
comparator from one inverted the other way. Two layers, both covering all six 
fields individually:
   
   1. Corrected per-comparator unit assertions (direction only; the existing 
null-value uid-tiebreak assertions are unaffected and kept).
   2. A new `describe("sorted columns (rendered header)")`, table-driven over 
`ASCENDING_BY_COLUMN` and generating one `it()` per column so each gets a fresh 
fixture — these headers have no `null` state, so a shared fixture would leave 
earlier columns sorted as secondary keys. Each case clicks the **real rendered 
`<th>`**, waits a macrotask (nz-table republishes its sort operators on 
`delay(0)`, so a bare `detectChanges()` reads the previous ordering), and pins 
the uid order **and** which caret carries `.active`, in both directions.
   
   The four fixture rows carry a distinct value in every sorted field, so no 
comparator reaches its uid tiebreak and any row exchange is visible. The six 
per-field orders were chosen so all twelve sequences (6 ascending + 6 
descending) are distinct across the table and none equals the supplied order — 
no column's expectation can be satisfied by another column's sort, or by the 
table not sorting at all.
   
   Two mutation checks confirm both halves are load-bearing:
   
   - Re-inverting **only** `sortByAffiliation`: `2 failed | 52 passed` — 
precisely its unit test and its rendered test. So no test passes while five of 
six are still broken.
   - Keeping it inverted but flipping its header to `['descend','ascend']` — 
the tempting wrong "fix" that yields the right order with the wrong caret — 
still fails, on `expected false to be true` from the caret assertion.
   
   ### One adjacent case deliberately left alone
   
   `sortByID` (line 247) is `b.uid - a.uid` under an `['ascend','descend']` 
header, so it has the same signature. Unlike the string columns, "highest uid 
first" is plausibly a deliberate newest-accounts-first default, so it wants a 
product decision rather than a mechanical flip.
   
   ### Verification
   
   - `admin-user.component.spec.ts` **54/54**; sibling 
`user-quota.component.spec.ts` 25/25, unaffected.
   - No other file in `frontend/src` references these comparators 
(`user-project.component.ts`'s `sortByNameAsc`/`Desc` are explicit-direction 
buttons, not `NzTableSortFn`).
   - `yarn format:ci` exits 0; no `junit.xml` left behind.
   
   ### Any related issues, documentation, discussions?
   
   Closes #7824
   
   ### How was this PR tested?
   
   ```
   npx ng test --watch=false --include="**/admin-user.component.spec.ts"
   ```
   
   ```
    Test Files  1 passed (1)
         Tests  54 passed (54)
   ```
   
   ### Was this PR authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 5)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to