Skip to content

test(frontend): render the project list item's permission and description rules - #7415

Merged
aglinxinyuan merged 3 commits into
apache:mainfrom
aglinxinyuan:test-project-list-item-template
Aug 8, 2026
Merged

test(frontend): render the project list item's permission and description rules#7415
aglinxinyuan merged 3 commits into
apache:mainfrom
aglinxinyuan:test-project-list-item-template

Conversation

@aglinxinyuan

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

UserProjectListItemComponent decides in its template what a viewer may touch, and none of it was rendered — the existing specs call the save and colour methods directly.

Adds 8 tests. The one that matters most is the editable gating: a project the viewer only holds READ on must not be offered the rename, add-description, share or delete controls, and that decision lives entirely in two *ngIf="editable" guards plus one on the action list.

Also covered: the name/edit-input swap, the description starting collapsed and expanding on request, the trim() guard that stops a whitespace-only description rendering an empty expander, the character counter, the save icon appearing only once the text actually differs, and the creation-date format.

Verified by mutation, all reverted (template diff empty):

Mutation Result
show the rename button to a read-only viewer red
show the share/delete actions to a read-only viewer red
invert the name / edit-input branch red
drop the collapse guard red
drop the whitespace trim() guard red
always show the save icon red
count characters against the max instead of the text red
change the creation-date format red

Two things worth recording:

  • MarkdownModule.forRoot() joins the TestBed. An expanded description renders a <markdown> element, and no existing test reached that path, so MarkdownService had never been needed.
  • descriptionCollapsed defaults to true. My first version of the collapse test asserted the opposite and failed, which also revealed that the whitespace test would have passed vacuously — collapsed hides the block regardless. It now expands first, so the trim() guard is the only thing left doing the work.

No production file is touched.

Any related issues, documentation, discussions?

Closes #7412

How was this PR tested?

npx ng test --watch=false --include="**/user-project-list-item.component.spec.ts"
 Test Files  1 passed (1)
      Tests  18 passed (18)

8 new on top of the existing 10. yarn format:ci passes.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

…tion rules

The list item decides in its template what a viewer may touch and how much of a
description to show, and none of it was rendered: the existing specs call the
save and colour methods directly.

Adds 8 tests. The one that matters most is the editable gating — a project the
viewer only has READ on must not be shown the rename, description, share or
delete controls, and that decision lives entirely in two *ngIf="editable"
guards.

Also covers the name/edit-input swap, the description starting collapsed and
expanding on request, the trim() guard that keeps a whitespace-only description
from rendering an empty expander, the character counter, the save icon
appearing only once the text actually changed, and the creation-date format.

MarkdownModule.forRoot() joins the TestBed: an expanded description renders a
<markdown> element, which no existing test reached.

No production file is touched.
Copilot AI lite review requested due to automatic review settings August 8, 2026 02:06
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @mengw15
    You can notify them by mentioning @mengw15 in a comment.

@github-actions github-actions Bot added the frontend Changes related to the frontend GUI label Aug 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens frontend unit coverage for UserProjectListItemComponent by adding rendered-template tests that verify permission-gated controls (editable) and description rendering/editing behavior that previously wasn’t exercised by the spec suite.

Changes:

  • Adds a new “rendered item” test suite that asserts UI gating for read-only vs write-access viewers (icons/actions visibility).
  • Adds tests for description collapse/expand behavior, whitespace-only description suppression, character counting, and save-icon visibility.
  • Updates the TestBed setup to include MarkdownModule.forRoot() so expanded descriptions rendering <markdown> can be tested.
Suppressed comments (2)

frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts:258

  • This test only asserts the rename control and the existence of the actions container; it doesn’t verify the add/edit-description control (or that share/delete actions actually render). Adding a couple of targeted assertions will better pin the editable gating behavior described in the PR.
    it("offers the editing controls to a viewer with write access", () => {
      const el = render({}, true);

      expect(el.querySelector(".edit-name-icon")).not.toBeNull();
      expect(el.querySelector("ul[nz-list-item-actions]")).not.toBeNull();

frontend/src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts:300

  • The character-count test verifies the initial count but doesn’t assert that the counter updates as the user types. Simulating an input change here would prevent regressions where the count becomes disconnected from the textarea’s current value.
      const count = hostFixture.nativeElement.querySelector(".character-count")!;
      expect(count.textContent?.trim()).toBe(`3/${component.MAX_PROJECT_DESCRIPTION_CHAR_COUNT}`);
    });

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov-commenter

codecov-commenter commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.98%. Comparing base (1362167) to head (75e7140).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7415      +/-   ##
============================================
+ Coverage     84.70%   84.98%   +0.28%     
  Complexity     4150     4150              
============================================
  Files          1169     1169              
  Lines         46740    46740              
  Branches       5202     5202              
============================================
+ Hits          39589    39723     +134     
+ Misses         5433     5302     -131     
+ Partials       1718     1715       -3     
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø) Carriedforward from e44b491
agent-service 85.50% <ø> (ø) Carriedforward from e44b491
amber 80.85% <ø> (ø) Carriedforward from e44b491
computing-unit-managing-service 50.72% <ø> (ø) Carriedforward from e44b491
config-service 65.97% <ø> (ø) Carriedforward from e44b491
file-service 69.05% <ø> (ø) Carriedforward from e44b491
frontend 87.10% <ø> (+0.65%) ⬆️
notebook-migration-service 78.89% <ø> (ø) Carriedforward from e44b491
pyamber 97.55% <ø> (ø) Carriedforward from e44b491
workflow-compiling-service 26.31% <ø> (ø) Carriedforward from e44b491

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mengw15 mengw15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

…ter checks

The creation-date assertion looked for the 1970-01-01 substring, which neither
pinned the yyyy-MM-dd HH:mm format nor held up outside the runner's timezone; it
now matches the rendered line as a shape.

The editable case asserted only the rename control, so it now also covers the
add-description control and counts the two action buttons.

The character counter was checked once at its initial value; it now types into
the textarea and confirms the count follows the box rather than the saved
description.
@aglinxinyuan

Copy link
Copy Markdown
Contributor Author

Both suppressed comments were worth acting on — fixed in e44b491.

The editable gating. The read-only case did already assert the add-description control, but the positive case asserted only the rename control and the existence of the actions container, so it would not have noticed either action disappearing. It now checks the add-description control too and counts the two action buttons. Verified: hiding the add-description button, and dropping one action, each now fail — neither did before.

One implementation note in case it saves someone time: nz-list-item-action renders as an <li>, so counting nz-list-item-action elements finds zero. The assertion counts the buttons inside ul[nz-list-item-actions].

The character counter. Right — it only saw the initial value, so a counter wired to entry.description.length instead of descriptionBox.value.length would have passed. The test now types into the textarea and asserts the count follows the box; that mutation is red as of this commit.

The regex introduced in e44b491 fixed the format and timezone concerns but
matched only the shape, so the assertion would have stayed green if the template
rendered a different timestamp entirely.

Formats the expected string with the same pipe and format literal instead, which
pins the value too and still holds in any timezone. Rendering a different
timestamp now fails; it did not before.
@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Aug 8, 2026
Merged via the queue into apache:main with commit 97dac3c Aug 8, 2026
22 checks passed
@aglinxinyuan
aglinxinyuan deleted the test-project-list-item-template branch August 8, 2026 07:40
renovate-bot pushed a commit to renovate-bot/apache-_-texera that referenced this pull request Aug 8, 2026
…apache#7418)

### What changes were proposed in this PR?

Rebased onto `main` after apache#7415 landed on the same file, and reduced to
what that
PR left uncovered. apache#7415 pins what each template branch *looks like* by
putting the
component into the state directly; this PR pins the wiring that produces
those
states, so a control losing its handler fails here. Together they take
`user-project-list-item.component.html` to 100% (110/110 statements, no
uncovered
branches — it was 77/110 after apache#7415).

8 new tests:

- **colour panel** — the `[(colorPicker)]` / `(colorPickerSelect)`
outputs, and the
`cpExtraTemplate` menu, whose markup exists only while the picker is
open: its
Save action, and its Delete action in both states (disabled while the
project has
no colour, enabled and wired once one is set). None of this was
previously
  rendered — it is the bulk of the gap apache#7410 describes.
- **name** — the edit button opens the input, `keyup.enter` saves,
`focusout` closes.
- **description** — the expand/collapse controls, the edit button,
`focusout`
  saving, and the suffix save icon closing the editor.
- **actions** — the share button and the delete popconfirm's
`nzOnConfirm`.
- three class-level gaps: the `entry` getter's guard, `ngOnInit`
adopting a stored
colour, and `updateProjectColor` skipping the service when the colour is
  unchanged (class 63/67 -> 66/67).

This block queries with `By.css` + `triggerEventHandler` rather than
`querySelector`: `nzOnConfirm`, `keyup.enter` and `colorPickerSelect`
are directive
outputs, not DOM events, so a native dispatch cannot reach them. apache#7415's
`MarkdownModule.forRoot()` is kept as-is. No production code was
changed.

Tests that apache#7415 already covers (the creation date, the `editable`
gating, the
read-only delete branch) were dropped from this PR rather than
duplicated.

One statement stays uncovered: the `if (!this.entry) throw` guard inside
`saveProjectName`'s subscribe. The `entry` getter already throws when no
entry was
provided, so that branch cannot be reached — it is dead code rather than
a coverage
gap, and removing it felt out of scope for a test-only PR.

### Any related issues, documentation, discussions?

Closes apache#7410. Builds on apache#7415 (apache#7412), which covers the same template
from the
rendering side.

### How was this PR tested?

`ng test --watch=false --include
src/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts`
— 28 passed (20 existing + 8 new), run 3x for determinism. Coverage
(`--coverage`)
confirms `user-project-list-item.component.html` at 110/110 statements
with no
uncovered branches, and the class at 66/67. The failure path was
verified by
breaking an assertion (red, non-zero exit); eslint and prettier are
clean.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 4.8 [1M context])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend Changes related to the frontend GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Render the project list item's permission and description rules

4 participants