Context-items UI: project + story panels + picker#116
Merged
Conversation
Three Volt-style single-file pages under `resources/views/pages/context-items/`: - `project-assets-panel` — list/create/edit/delete project-scoped ContextItems. Supports text, link, and file types. File uploads go through `AssetUploader` (first `WithFileUploads` usage in the repo). Edits route through `ContextItemWriter` so file metadata stays immutable. - `story-assets-panel` — same shape but story-scoped, with a reopen-approval banner. Mutations bump the Story revision via `StoryRevisionLifecycle::recordContentArtifactChanged`. - `story-context-picker` — checkbox list over `Story::availableContextItems()`. Story-scoped items render pre-checked and disabled. Save calls `ContextItemSelector::bulkSet()` once for a single approval-reopen per save. Tampered-in story-scoped IDs are silently filtered before reaching the selector. Permissions are inline: every mount and mutation gates on `in_array($projectId, $user->accessibleProjectIds(), true)`, matching the `pages/projects/⚡show.blade.php` pattern. Embedded the project panel into the project show page (Assets section) and the picker + story panel into the story show page (AI Context section, above the plan area). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests don't run `npm run build`, so `public/build/manifest.json` doesn't exist. Any view that pulls in `partials/head.blade.php` (every authenticated page, every auth screen) was 500ing with `ViteManifestNotFoundException`. That masked 16 pre-existing test failures unrelated to functionality. Call `withoutVite()` in the base TestCase setUp — Laravel's built-in helper swaps the container binding for a stub that returns empty asset markup. The whole suite is now green (568 tests, 0 failures). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the test harness and adds new Livewire feature tests for the Context Items UI (project assets panel, story assets panel, and story context picker), aiming to make view-based tests independent from a built Vite frontend and to validate core user flows/permissions.
Changes:
- Added a global
withoutVite()call intests/TestCase.phpto preventViteManifestNotFoundExceptionduring view rendering in tests. - Added Livewire tests for story context picker behavior (listing/prefill/save/no-op/tamper filtering/403 for non-members).
- Added Livewire tests for project and story assets panels (scoping, CRUD basics, upload happy path for project panel, and 403 for non-members).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/TestCase.php | Disables Vite in test setup so view assertions don’t depend on a built manifest. |
| tests/Feature/ContextItem/Livewire/StoryContextPickerTest.php | Adds coverage for picker list/prefill/save behaviors and authorization. |
| tests/Feature/ContextItem/Livewire/StoryAssetsPanelTest.php | Adds coverage for story-owned asset panel scoping + text create/edit/delete effects. |
| tests/Feature/ContextItem/Livewire/ProjectAssetsPanelTest.php | Adds coverage for project asset panel scoping, CRUD, and file upload happy path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Rename misleading `$story` (it was a Feature) to `$feature` in the panel rendering test. - Replace the "non-member cannot mutate" test that only asserted mount status with one that walks every mutation entry point and pins that the row stays untouched. The mount gate is what fires; the test now documents and verifies that. - Story panel: add link create + file upload coverage. The file test also pins current behaviour — `AssetUploader` does not call the approval-reopen helper or attach to the pivot for story-scoped file uploads, so neither the revision nor the selection moves. Future work to align this with text/link create paths now has a failing test to flip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AssetUploader: story-scoped file uploads now reopen story approval and auto-attach to the context_item_story pivot, matching the text/link path (StoryRevisionLifecycle + DB::transaction added) - Project + story panels: catch InvalidArgumentException from AssetUploader and ContextItemWriter; surface as a validation error instead of 500ing - Panels: show URL for link items and original_name for file items in the item list (previously only showed bare title) - StoryAssetsPanelTest: flip file upload test from pinning the old broken behaviour to asserting the correct contract Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slice 8 of the project/story context-asset stack — the user-facing surface for assets that the prior slices wired up under the hood.
Three Volt-style single-file Livewire pages under
resources/views/pages/context-items/:project-assets-panel— list, create (text/link/file), edit, delete project-scoped ContextItems. File uploads go throughAssetUploader(firstWithFileUploadsusage in the repo).story-assets-panel— same shape, story-scoped, with a reopen-approval banner. Mutations bump the Story revision viaStoryRevisionLifecycle::recordContentArtifactChanged.story-context-picker— checkbox list overStory::availableContextItems(). Story-scoped items render pre-checked and disabled. Save callsContextItemSelector::bulkSet()once per save (single approval-reopen). Tampered-in story-scoped IDs are silently filtered before reaching the selector.Permissions are inline on every mount and mutation:
in_array($projectId, $user->accessibleProjectIds(), true)— anyone in the project's team can manage assets, matching the read-access bar.Embedded:
pages/projects/⚡show.blade.php— new "Assets" section after featurespages/stories/⚡show.blade.php— new "AI Context" section (picker + story panel) above the plan areaTest plan
🤖 Generated with Claude Code