Conversation
|
Warning Review limit reached
Next review available in: 25 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (55)
📝 WalkthroughWalkthroughThis PR adds a new Analytics page: a Symfony Estimated code review effort: 3 (Moderate) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant AnalyticsView
participant statisticsClient
participant AnalyticsController
participant Session
User->>AnalyticsController: GET /analytics/
AnalyticsController->>Session: read auth_token
AnalyticsController-->>User: render SPA shell (page, api_token, api_base_url)
User->>AnalyticsView: mount (onMounted)
AnalyticsView->>statisticsClient: fetch campaign statistics, view opens, top domains, domain confirmation, top local parts (Promise.all)
statisticsClient-->>AnalyticsView: dataset responses
AnalyticsView->>AnalyticsView: populate refs, compute metrics/chart data
AnalyticsView-->>User: render metrics, charts, tables
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@assets/vue/views/AnalyticsView.vue`:
- Around line 71-125: The empty-state sections in AnalyticsView.vue are
rendering before loadAnalytics() finishes, which causes a misleading “no data”
flash on first paint. Update the loading logic in AnalyticsView and the affected
empty-state blocks to stay hidden until the initial fetch completes, either by
introducing a hasLoaded flag or by guarding all “No ... found” branches with
!isLoading. Make sure the fix is applied consistently across the
domainConfirmation view and the other matching empty states so the template only
shows “no data” after the data request has actually finished.
- Around line 306-320: The formatDate helper in AnalyticsView.vue currently
passes date-only strings straight into new Date, which can shift the displayed
day in some time zones. Update formatDate to detect YYYY-MM-DD inputs and
normalize them before formatting, while keeping the existing Unknown date
fallback and Intl.DateTimeFormat output.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 137c0e28-face-46b0-ab9a-c3fa52df4efc
📒 Files selected for processing (6)
assets/router/index.jsassets/vue/api.jsassets/vue/views/AnalyticsView.spec.jsassets/vue/views/AnalyticsView.vuesrc/Controller/AnalyticsController.phptests/Integration/Controller/AnalyticsControllerTest.php
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/Unit/assets/vue/views/AnalyticsView.spec.js (1)
19-21: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winMock the same
apimodule the component imports. Intests/Unit/assets/vue/views/AnalyticsView.spec.js:19,vi.mock('../api', ...)resolves totests/Unit/assets/vue/api, whileassets/vue/views/AnalyticsView.vueimports../apifrom the source tree. Point the mock at the component’s resolved path so the test doesn’t fall through to the real client.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Unit/assets/vue/views/AnalyticsView.spec.js` around lines 19 - 21, The mock in AnalyticsView.spec.js is targeting the wrong module path, so AnalyticsView.vue still resolves its own ../api import to the real client. Update the vi.mock call to match the component’s actual resolved api module path used by AnalyticsView.vue, and keep the statisticsClient stub there so the test intercepts the same import the component loads.
♻️ Duplicate comments (2)
tests/Unit/assets/vue/components/settings/SettingsConfigs.spec.js (1)
12-18: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winSame
vi.mockrelative-path mismatch as in the other settings modal/panel specs.
'../../api'resolves relative to this spec's own directory, landing ontests/Unit/assets/vue/apiinstead of the realassets/vue/api.jsimported bySettingsConfigs.vue, soconfigClientcalls likely bypass the mock.🔧 Proposed fix
-vi.mock('../../api', () => ({ +vi.mock('../../../../../../assets/vue/api', () => ({ default: {}, configClient: { getConfigs: getConfigsMock, update: updateMock, }, }))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Unit/assets/vue/components/settings/SettingsConfigs.spec.js` around lines 12 - 18, The SettingsConfigs spec is mocking the wrong relative module path, so the `configClient` mock may not intercept the import used by `SettingsConfigs.vue`. Update the `vi.mock` call in `SettingsConfigs.spec.js` to target the same resolved `assets/vue/api` module path that the component imports, matching the pattern used in the other settings modal/panel specs, so `getConfigs` and `update` are properly mocked.tests/Unit/assets/vue/components/settings/SettingsSubscriberAttributes.spec.js (1)
13-42: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winSame
vi.mockrelative-path mismatch, affecting all 4 mocks in this file.All of
'../../api'(Line 13),'../base/BaseIcon.vue'(Line 20),'./CreateSubscriberAttributeModal.vue'(Line 26), and'./EditSubscriberAttributeModal.vue'(Line 35) are resolved relative to this spec file's directory, not relative toSettingsSubscriberAttributes.vue's actual location — so none of them likely intercept the real imports the component makes.🔧 Proposed fix
-vi.mock('../../api', () => ({ +vi.mock('../../../../../../assets/vue/api', () => ({ subscriberAttributesClient: { getAttributeDefinitions: getAttributeDefinitionsMock, deleteAttributeDefinition: deleteAttributeDefinitionMock, }, })) -vi.mock('../base/BaseIcon.vue', () => ({ +vi.mock('../../../../../../assets/vue/components/base/BaseIcon.vue', () => ({ default: { template: '<span />', }, })) -vi.mock('./CreateSubscriberAttributeModal.vue', () => ({ +vi.mock('../../../../../../assets/vue/components/settings/CreateSubscriberAttributeModal.vue', () => ({ default: defineComponent({ name: 'CreateSubscriberAttributeModal', props: ['isOpen'], emits: ['close', 'created'], template: '<div />', }), })) -vi.mock('./EditSubscriberAttributeModal.vue', () => ({ +vi.mock('../../../../../../assets/vue/components/settings/EditSubscriberAttributeModal.vue', () => ({ default: defineComponent({ name: 'EditSubscriberAttributeModal', props: ['isOpen', 'attribute'], emits: ['close', 'updated'], template: '<div />', }), }))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Unit/assets/vue/components/settings/SettingsSubscriberAttributes.spec.js` around lines 13 - 42, The four vi.mock calls in SettingsSubscriberAttributes.spec.js are using paths relative to the spec file instead of matching the imports used by SettingsSubscriberAttributes.vue, so they won’t stub the real dependencies. Update the mocked module specifiers for subscriberAttributesClient, BaseIcon, CreateSubscriberAttributeModal, and EditSubscriberAttributeModal to the exact paths that SettingsSubscriberAttributes.vue imports, using the existing mock names to locate each entry.
🧹 Nitpick comments (3)
vitest.config.mjs (1)
9-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDrop the stale
assets/vue/**/*.spec.jsglob. It matches nothing now, sotests/Unit/assets/vue/**/*.spec.jsis enough.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@vitest.config.mjs` at line 9, The Vitest include list still contains the stale assets/vue/**/*.spec.js glob, which no longer matches any files. Update the include configuration in vitest.config.mjs to keep only the valid tests/Unit/assets/vue/**/*.spec.js pattern so the test discovery remains accurate.tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js (1)
126-136: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winTest asserts nothing.
reloads attributes after createonly emits'created'and never assertsgetAttributeDefinitionsMockwas called again — it will pass regardless of whether the reload actually happens, defeating the purpose of the test.🔧 Suggested fix
it('reloads attributes after create', async () => { const wrapper = mountComponent() await flushPromises() getAttributeDefinitionsMock.mockClear() const createModal = wrapper.findComponent(CreateStub) expect(createModal.exists()).toBe(true) await createModal.vm.$emit('created') + await flushPromises() + + expect(getAttributeDefinitionsMock).toHaveBeenCalled() })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js` around lines 126 - 136, The reload-after-create test is not verifying any behavior because it only emits created and never checks that the refresh happens. Update the SettingsAdminAttributes.spec.js test around reloads attributes after create to assert the expected reload behavior by checking getAttributeDefinitionsMock is called again after the CreateStub emits created, so the test fails if the refresh does not occur.tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js (1)
96-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFragile selector for the "remove" button.
find(button => !button.text().trim())picks the first button with empty text, which is brittle if markup adds an icon-only close button elsewhere in the modal. Low priority given "Chill" review mode, but worth adata-testiddown the line.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js` around lines 96 - 116, The remove-button lookup in CreateSubscriberAttributeModal.spec.js is brittle because it uses an empty-text button search that can accidentally match other icon-only buttons. Update the test around mountComponent and the “adds and removes options” case to target a stable identifier instead, such as a data-testid or a dedicated selector on the remove control, and use that for removeButton so the assertion only clicks the intended button.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/Unit/assets/vue/components/bounces/BouncePer.spec.js`:
- Around line 3-4: The vi.mock path in BouncePer.spec.js is targeting the wrong
module, so it does not intercept the api import used by BouncePer.vue. Update
the mock to match the component’s actual relative import for bouncesClient from
assets/vue/api, and keep the test import of BouncePer aligned so the mocked
module is the one exercised by the component under test.
In `@tests/Unit/assets/vue/components/settings/CreateAdminAttributeModal.spec.js`:
- Around line 10-14: The vi.mock target in CreateAdminAttributeModal.spec.js is
pointing at the wrong api module, so the component’s imported
adminAttributeClient is never replaced. Update the mock path to match the same
assets/vue/api module that CreateAdminAttributeModal.vue imports, and keep the
createAttributeDefinition stub wired through adminAttributeClient so the spec
uses the mocked client.
In `@tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js`:
- Around line 24-34: The mocks in CreateAdminModal.spec.js are targeting paths
that resolve relative to the test file instead of the modules imported by
CreateAdminModal.vue, so they never intercept the real dependencies. Update the
vi.mock calls to use the same module IDs that CreateAdminModal.vue imports for
the API client and BaseIcon component, and verify the mock names still match the
references used in the test setup.
In
`@tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js`:
- Around line 10-20: Fix the Vitest mocks in
CreateSubscriberAttributeModal.spec.js so they intercept the same import paths
used by the component. Update the vi.mock calls for the API module and
BaseIcon.vue to match the component’s assets/vue/api.js and
assets/vue/components/base/BaseIcon.vue imports, ensuring
subscriberAttributesClient.createAttributeDefinition is actually mocked when the
modal tests run.
In `@tests/Unit/assets/vue/components/settings/EditAdminModal.spec.js`:
- Around line 24-34: The test mocks in EditAdminModal.spec.js are using module
ids that do not match the imports in EditAdminModal.vue, so the real adminClient
and BaseIcon dependencies are still being loaded. Update the vi.mock targets to
match the exact import paths used by EditAdminModal (for adminClient) and the
BaseIcon component so the update tests fully stub those dependencies.
In
`@tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js`:
- Around line 10-20: The mocks in EditSubscriberAttributeModal.spec.js are
targeting the wrong module ids, so they do not intercept the imports used by
EditSubscriberAttributeModal.vue. Update the vi.mock calls for the api client
and BaseIcon.vue to point at the same source module paths that the component
imports, using the existing identifiers subscriberAttributesClient and
updateAttributeDefinitionMock so the component receives the intended stubs.
In `@tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js`:
- Around line 13-24: The mocks in SettingsAdminAttributes.spec.js are resolving
from the test file location instead of the component’s import paths, so they do
not intercept the imports used by SettingsAdminAttributes.vue. Update the
vi.mock targets for the api client and BaseIcon.vue to match the component’s
actual relative imports (or switch both to a shared alias) so
adminAttributeClient and BaseIcon are properly mocked during the component test.
In `@tests/Unit/assets/vue/components/settings/SettingsAdmins.spec.js`:
- Around line 13-42: Update the mocks in SettingsAdmins.spec.js so they match
the import paths used by SettingsAdmins.vue rather than resolving from the spec
file; adjust the vi.mock targets for ../../api, ../base/BaseIcon.vue,
CreateAdminModal.vue, and EditAdminModal.vue to the component-relative asset
paths so the component under test actually receives the mocked modules.
In `@tests/Unit/assets/vue/components/subscribers/SubscriberModal.spec.js`:
- Around line 5-6: The test mock for subscribersClient is targeting a different
resolved module than the one SubscriberModal actually imports, so it will not
intercept the real dependency. Update the vi.mock setup in
SubscriberModal.spec.js to mock the same assets/vue/api module path used by
SubscriberModal, and keep the subscribersClient import aligned with that same
module resolution so the component under test receives the mocked client.
---
Outside diff comments:
In `@tests/Unit/assets/vue/views/AnalyticsView.spec.js`:
- Around line 19-21: The mock in AnalyticsView.spec.js is targeting the wrong
module path, so AnalyticsView.vue still resolves its own ../api import to the
real client. Update the vi.mock call to match the component’s actual resolved
api module path used by AnalyticsView.vue, and keep the statisticsClient stub
there so the test intercepts the same import the component loads.
---
Duplicate comments:
In `@tests/Unit/assets/vue/components/settings/SettingsConfigs.spec.js`:
- Around line 12-18: The SettingsConfigs spec is mocking the wrong relative
module path, so the `configClient` mock may not intercept the import used by
`SettingsConfigs.vue`. Update the `vi.mock` call in `SettingsConfigs.spec.js` to
target the same resolved `assets/vue/api` module path that the component
imports, matching the pattern used in the other settings modal/panel specs, so
`getConfigs` and `update` are properly mocked.
In
`@tests/Unit/assets/vue/components/settings/SettingsSubscriberAttributes.spec.js`:
- Around line 13-42: The four vi.mock calls in
SettingsSubscriberAttributes.spec.js are using paths relative to the spec file
instead of matching the imports used by SettingsSubscriberAttributes.vue, so
they won’t stub the real dependencies. Update the mocked module specifiers for
subscriberAttributesClient, BaseIcon, CreateSubscriberAttributeModal, and
EditSubscriberAttributeModal to the exact paths that
SettingsSubscriberAttributes.vue imports, using the existing mock names to
locate each entry.
---
Nitpick comments:
In
`@tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js`:
- Around line 96-116: The remove-button lookup in
CreateSubscriberAttributeModal.spec.js is brittle because it uses an empty-text
button search that can accidentally match other icon-only buttons. Update the
test around mountComponent and the “adds and removes options” case to target a
stable identifier instead, such as a data-testid or a dedicated selector on the
remove control, and use that for removeButton so the assertion only clicks the
intended button.
In `@tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js`:
- Around line 126-136: The reload-after-create test is not verifying any
behavior because it only emits created and never checks that the refresh
happens. Update the SettingsAdminAttributes.spec.js test around reloads
attributes after create to assert the expected reload behavior by checking
getAttributeDefinitionsMock is called again after the CreateStub emits created,
so the test fails if the refresh does not occur.
In `@vitest.config.mjs`:
- Line 9: The Vitest include list still contains the stale
assets/vue/**/*.spec.js glob, which no longer matches any files. Update the
include configuration in vitest.config.mjs to keep only the valid
tests/Unit/assets/vue/**/*.spec.js pattern so the test discovery remains
accurate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 01cd48f1-4350-4439-a850-7a50220d3540
📒 Files selected for processing (54)
.github/workflows/ci.yml.husky/pre-commitassets/vue/components/settings/EditAdminModal.vuetests/Unit/assets/vue/components/base/BaseBadge.spec.jstests/Unit/assets/vue/components/base/BaseButton.spec.jstests/Unit/assets/vue/components/base/BaseCard.spec.jstests/Unit/assets/vue/components/base/BaseIcon.spec.jstests/Unit/assets/vue/components/base/BaseProgressBar.spec.jstests/Unit/assets/vue/components/base/CkEditorField.spec.jstests/Unit/assets/vue/components/bounces/BounceOverview.spec.jstests/Unit/assets/vue/components/bounces/BouncePer.spec.jstests/Unit/assets/vue/components/bounces/BounceRules.spec.jstests/Unit/assets/vue/components/bounces/BouncesActionsPanel.spec.jstests/Unit/assets/vue/components/campaigns/CampaignDirectory.spec.jstests/Unit/assets/vue/components/campaigns/ViewCampaignModal.spec.jstests/Unit/assets/vue/components/dashboard/CampaignsTable.spec.jstests/Unit/assets/vue/components/dashboard/KpiCard.spec.jstests/Unit/assets/vue/components/dashboard/KpiGrid.spec.jstests/Unit/assets/vue/components/dashboard/PerformanceChartCard.spec.jstests/Unit/assets/vue/components/dashboard/QuickActionsCard.spec.jstests/Unit/assets/vue/components/dashboard/RecentCampaignsCard.spec.jstests/Unit/assets/vue/components/lists/AddSubscribersModal.spec.jstests/Unit/assets/vue/components/lists/CreateListModal.spec.jstests/Unit/assets/vue/components/lists/EditListModal.spec.jstests/Unit/assets/vue/components/lists/ListDirectory.spec.jstests/Unit/assets/vue/components/lists/ListSubscribersExportPanel.spec.jstests/Unit/assets/vue/components/public-pages/PublicPageEditor.spec.jstests/Unit/assets/vue/components/public-pages/PublicPagesDirectory.spec.jstests/Unit/assets/vue/components/settings/CreateAdminAttributeModal.spec.jstests/Unit/assets/vue/components/settings/CreateAdminModal.spec.jstests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.jstests/Unit/assets/vue/components/settings/EditAdminAttributeModal.spec.jstests/Unit/assets/vue/components/settings/EditAdminModal.spec.jstests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.jstests/Unit/assets/vue/components/settings/SettingsActionsPanel.spec.jstests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.jstests/Unit/assets/vue/components/settings/SettingsAdmins.spec.jstests/Unit/assets/vue/components/settings/SettingsConfigs.spec.jstests/Unit/assets/vue/components/settings/SettingsSubscriberAttributes.spec.jstests/Unit/assets/vue/components/sidebar/AppSidebar.spec.jstests/Unit/assets/vue/components/sidebar/SidebarLogo.spec.jstests/Unit/assets/vue/components/sidebar/SidebarNavItem.spec.jstests/Unit/assets/vue/components/sidebar/SidebarNavSection.spec.jstests/Unit/assets/vue/components/subscribers/ImportResult.spec.jstests/Unit/assets/vue/components/subscribers/SubscriberDirectory.spec.jstests/Unit/assets/vue/components/subscribers/SubscriberFilters.spec.jstests/Unit/assets/vue/components/subscribers/SubscriberModal.spec.jstests/Unit/assets/vue/components/subscribers/SubscriberTable.spec.jstests/Unit/assets/vue/components/templates/TemplateLibrary.spec.jstests/Unit/assets/vue/layouts/AdminLayout.spec.jstests/Unit/assets/vue/views/AnalyticsView.spec.jstests/Unit/assets/vue/views/BouncesView.spec.jstests/Unit/assets/vue/views/DashboardView.spec.jsvitest.config.mjs
✅ Files skipped from review due to trivial changes (21)
- tests/Unit/assets/vue/components/base/BaseButton.spec.js
- tests/Unit/assets/vue/components/base/BaseCard.spec.js
- .husky/pre-commit
- tests/Unit/assets/vue/views/BouncesView.spec.js
- tests/Unit/assets/vue/components/public-pages/PublicPagesDirectory.spec.js
- tests/Unit/assets/vue/components/base/BaseProgressBar.spec.js
- tests/Unit/assets/vue/components/lists/EditListModal.spec.js
- tests/Unit/assets/vue/components/campaigns/ViewCampaignModal.spec.js
- tests/Unit/assets/vue/layouts/AdminLayout.spec.js
- tests/Unit/assets/vue/components/subscribers/ImportResult.spec.js
- tests/Unit/assets/vue/components/public-pages/PublicPageEditor.spec.js
- tests/Unit/assets/vue/components/subscribers/SubscriberTable.spec.js
- tests/Unit/assets/vue/components/base/BaseIcon.spec.js
- tests/Unit/assets/vue/components/sidebar/AppSidebar.spec.js
- tests/Unit/assets/vue/components/templates/TemplateLibrary.spec.js
- tests/Unit/assets/vue/components/lists/ListDirectory.spec.js
- tests/Unit/assets/vue/components/subscribers/SubscriberFilters.spec.js
- tests/Unit/assets/vue/components/base/BaseBadge.spec.js
- tests/Unit/assets/vue/components/settings/EditAdminAttributeModal.spec.js
- tests/Unit/assets/vue/components/sidebar/SidebarNavItem.spec.js
- tests/Unit/assets/vue/components/settings/SettingsActionsPanel.spec.js
| vi.mock('../../api', () => ({ | ||
| adminClient: { | ||
| createAdministrator: createAdministratorMock, | ||
| }, | ||
| })) | ||
|
|
||
| vi.mock('../base/BaseIcon.vue', () => ({ | ||
| default: { | ||
| template: '<span />', | ||
| }, | ||
| })) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Files ==\n'
git ls-files 'tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js' \
'assets/vue/components/settings/CreateAdminModal.vue' \
'assets/vue/api.*' \
'assets/vue/components/base/BaseIcon.vue'
printf '\n== Outline spec ==\n'
ast-grep outline tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js --view expanded || true
printf '\n== Outline component ==\n'
ast-grep outline assets/vue/components/settings/CreateAdminModal.vue --view expanded || true
printf '\n== Spec lines ==\n'
cat -n tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js | sed -n '1,120p'
printf '\n== Component lines ==\n'
cat -n assets/vue/components/settings/CreateAdminModal.vue | sed -n '1,120p'Repository: phpList/web-frontend
Length of output: 11090
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Search for vi.mock usage near these paths ==\n'
rg -n --hidden --glob '!node_modules' "vi\.mock\((['\"])\.\./.*BaseIcon|vi\.mock\((['\"])\.\./.*api|CreateAdminModal" tests/Unit assets/vue | sed -n '1,200p'
printf '\n== Search for explicit absolute mock patterns in nearby tests ==\n'
rg -n --hidden --glob '!node_modules' "vi\.mock\(.*assets/vue" tests/Unit | sed -n '1,200p'
printf '\n== Search for import in component ==\n'
rg -n --hidden --glob '!node_modules' "from ['\"].*api|from ['\"].*BaseIcon" assets/vue/components/settings/CreateAdminModal.vue assets/vue/components/base/BaseIcon.vue assets/vue/api.* | sed -n '1,200p'Repository: phpList/web-frontend
Length of output: 4745
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== CreateAdminModal component imports ==\n'
rg -n --context 3 "from ['\"].*api|from ['\"].*BaseIcon|<script|defineProps|import " assets/vue/components/settings/CreateAdminModal.vue | sed -n '1,120p'
printf '\n== Similar settings tests/component imports ==\n'
for f in \
tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js \
assets/vue/components/settings/CreateSubscriberAttributeModal.vue \
tests/Unit/assets/vue/components/settings/EditAdminModal.spec.js \
assets/vue/components/settings/EditAdminModal.vue \
tests/Unit/assets/vue/components/settings/SettingsAdmins.spec.js \
assets/vue/components/settings/SettingsAdmins.vue
do
printf '\n--- %s ---\n' "$f"
if [ -f "$f" ]; then
rg -n --context 2 "from ['\"].*api|from ['\"].*BaseIcon|from ['\"].*CreateAdminModal|<script|import " "$f" | sed -n '1,160p'
fi
doneRepository: phpList/web-frontend
Length of output: 2423
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,80p' assets/vue/components/settings/CreateAdminModal.vueRepository: phpList/web-frontend
Length of output: 3573
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
test = Path('tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js').read_text()
comp = Path('assets/vue/components/settings/CreateAdminModal.vue').read_text()
print('test mocks:')
for line in test.splitlines():
if 'vi.mock(' in line:
print(line)
print('\ncomponent imports:')
for line in comp.splitlines():
if 'from ' in line or '<script' in line or 'import ' in line:
print(line)
PYRepository: phpList/web-frontend
Length of output: 505
🌐 Web query:
Vitest vi.mock relative path resolved relative to test file module path docs
💡 Result:
In Vitest, when you provide a relative path to vi.mock(), it is resolved relative to the test file where the vi.mock() call is located [1][2]. This behavior aligns with standard relative path resolution in modules, where paths are interpreted relative to the file containing the code [3][1]. Vitest treats the path provided to vi.mock() as a reference to the specific file you intend to mock, rather than a path relative to the project root or the current working directory [1]. Key points regarding vi.mock() path resolution: 1. Consistency: The path in vi.mock() should match the file path of the module you want to mock, resolved from the location of your test file [1]. 2. Hoisting: vi.mock() calls are hoisted to the top of the file [4][5]. Even though they are moved during transformation, the resolution of the relative path remains anchored to the original location of the test file [1]. 3. Aliases: You can also use configured Vite aliases within the vi.mock() path [5][6]. If you encounter resolution issues with aliases, it is often recommended to use explicit relative paths (e.g., ./path/to/module) or ensure aliases are correctly defined in your Vitest/Vite configuration [3][5][7]. 4. Best Practices: If your project structure is complex, ensure that the path provided to vi.mock() accurately points to the target module file relative to your test [1]. If you find vi.mock() is not working as expected, verify the path by checking how you would import the module in that same test file; the vi.mock() path should correspond to the same target [1].
Citations:
- 1: Help with mocking a local import vitest-dev/vitest#3197
- 2: When running using 'vitest workspace' the imported module path needs relative to root vitest-dev/vitest#3242
- 3: mocking a module with relative path alias is not working vitest-dev/vitest#3081
- 4: https://vitest.dev/guide/mocking/modules
- 5: https://vitest.dev/api/vi
- 6: https://github.com/vitest-dev/vitest/blob/v4.1.9/docs/api/vi.md
- 7: https://stackoverflow.com/questions/75741665/vitest-module-mock-with-alias-paths
🌐 Web query:
site:vitest.dev vi.mock relative path test file resolved module path
💡 Result:
In Vitest, when you use a relative path in vi.mock(path, factory), the path is resolved relative to the file where the vi.mock call is located [1][2]. Vitest performs static analysis on your files to identify and hoist vi.mock calls to the top of the file, ensuring they execute before any imports [3][4]. Key aspects of path resolution and behavior include: 1. Path Aliases: You can use configured Vite aliases (e.g., '@/') within the path string [3][5]. If you are using TypeScript with paths aliases in tsconfig.json, ensure you have configured a tool like vite-tsconfig-paths or defined the equivalent aliases in your Vitest configuration, as Vite does not automatically respect tsconfig.json paths [1][2]. 2. Relative Path Gotchas: Be careful with relative aliases or paths that depend on the project root. Vite treats relative paths (e.g., './module') as relative to the file being imported, while aliases are resolved according to your Vite configuration [1][2]. If you encounter a "Cannot find module" error, verify the path spelling and ensure it correctly references the file relative to the test file's location [1][2]. 3. Hoisting: Because vi.mock is hoisted, its placement in your code does not affect resolution; it will always execute before your imports [3][5]. However, vi.mock must be imported directly from 'vitest' to be correctly detected by Vitest's static analyzer [5]. 4. Module Resolution: If you do not provide a factory function, Vitest looks for a corresponding file in a mocks folder relative to the mocked module [3][5]. If you are mocking a dependency in node_modules, it looks for a mocks folder in the project root by default [3][5]. You can customize where Vitest looks for these via the deps.moduleDirectories configuration option [6][7]. If you need more precise control or are having trouble with resolution, you can pass a dynamic import like vi.mock(import('./path/to/module.js'), factory) to provide better IDE support and explicit module reference [3].
Citations:
- 1: https://vitest.dev/guide/common-errors
- 2: https://v3.vitest.dev/guide/common-errors
- 3: https://vitest.dev/api/vi
- 4: https://vitest.dev/guide/mocking/modules
- 5: https://v0.vitest.dev/api/vi
- 6: https://v3.vitest.dev/config/
- 7: https://vitest.dev/config/deps
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '120,220p' assets/vue/components/settings/CreateAdminModal.vueRepository: phpList/web-frontend
Length of output: 3047
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n --hidden --glob '!node_modules' "adminClient\.createAdministrator|createAdministrator\(" assets/vue tests/Unit | sed -n '1,200p'Repository: phpList/web-frontend
Length of output: 286
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n --hidden --glob '!node_modules' "resolve:|alias:|tests/Unit/assets/vue|assets/vue/api" vitest.config.* vite.config.* package.json tests src . | sed -n '1,240p'Repository: phpList/web-frontend
Length of output: 4000
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
test_file = Path('tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js')
component_file = Path('assets/vue/components/settings/CreateAdminModal.vue')
test_mock_api = (test_file.parent / '../../api').resolve(strict=False)
test_mock_icon = (test_file.parent / '../base/BaseIcon.vue').resolve(strict=False)
component_api = (component_file.parent / '../../api').resolve(strict=False)
component_icon = (component_file.parent / '../base/BaseIcon.vue').resolve(strict=False)
print('test mock api =', test_mock_api)
print('component api =', component_api)
print('same api? =', test_mock_api == component_api)
print('test mock icon =', test_mock_icon)
print('component icon =', component_icon)
print('same icon? =', test_mock_icon == component_icon)
PYRepository: phpList/web-frontend
Length of output: 498
Point the mocks at the modules CreateAdminModal.vue imports
vi.mock('../../api') and vi.mock('../base/BaseIcon.vue') resolve under tests/Unit/assets/vue/components/settings/, so they miss assets/vue/api.js and assets/vue/components/base/BaseIcon.vue. Use the same module IDs as the component import so the mocks actually apply.
Suggested fix
-vi.mock('../../api', () => ({
+vi.mock('../../../../../../assets/vue/api', () => ({
adminClient: {
createAdministrator: createAdministratorMock,
},
}))
-vi.mock('../base/BaseIcon.vue', () => ({
+vi.mock('../../../../../../assets/vue/components/base/BaseIcon.vue', () => ({
default: {
template: '<span />',
},
}))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| vi.mock('../../api', () => ({ | |
| adminClient: { | |
| createAdministrator: createAdministratorMock, | |
| }, | |
| })) | |
| vi.mock('../base/BaseIcon.vue', () => ({ | |
| default: { | |
| template: '<span />', | |
| }, | |
| })) | |
| vi.mock('../../../../../../assets/vue/api', () => ({ | |
| adminClient: { | |
| createAdministrator: createAdministratorMock, | |
| }, | |
| })) | |
| vi.mock('../../../../../../assets/vue/components/base/BaseIcon.vue', () => ({ | |
| default: { | |
| template: '<span />', | |
| }, | |
| })) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/Unit/assets/vue/components/settings/CreateAdminModal.spec.js` around
lines 24 - 34, The mocks in CreateAdminModal.spec.js are targeting paths that
resolve relative to the test file instead of the modules imported by
CreateAdminModal.vue, so they never intercept the real dependencies. Update the
vi.mock calls to use the same module IDs that CreateAdminModal.vue imports for
the API client and BaseIcon component, and verify the mock names still match the
references used in the test setup.
| vi.mock('../../api', () => ({ | ||
| subscriberAttributesClient: { | ||
| createAttributeDefinition: createAttributeDefinitionMock, | ||
| }, | ||
| })) | ||
|
|
||
| vi.mock('../base/BaseIcon.vue', () => ({ | ||
| default: { | ||
| template: '<span />', | ||
| }, | ||
| })) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n[File list]\n'
git ls-files 'tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js' \
'assets/vue/components/settings/CreateSubscriberAttributeModal.vue' \
'assets/vue/components/base/BaseIcon.vue' \
'assets/vue/api*' \
'tests/Unit/assets/vue/api*' \
'tests/Unit/assets/vue/components/base/BaseIcon.vue' || true
printf '\n[Spec file excerpt]\n'
sed -n '1,120p' tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js
printf '\n[Component file excerpt]\n'
sed -n '1,120p' assets/vue/components/settings/CreateSubscriberAttributeModal.vue
printf '\n[Directory paths]\n'
python3 - <<'PY'
from pathlib import Path
spec = Path('tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js').resolve().parts
comp = Path('assets/vue/components/settings/CreateSubscriberAttributeModal.vue').resolve().parts
print('spec depth:', len(spec), spec)
print('comp depth:', len(comp), comp)
PYRepository: phpList/web-frontend
Length of output: 7459
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "vi\.mock\(['\"](\.\./|\.\./\.\./)|vi\.mock\(['\"].*api|BaseIcon" tests/Unit/assets/vue/components/settings assets/vue/components/settings -g '*.spec.js' -g '*.spec.ts' -g '*.test.js' -g '*.test.ts'Repository: phpList/web-frontend
Length of output: 2373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "[Spec]"
sed -n '1,40p' tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js
echo
echo "[Component]"
sed -n '1,80p' assets/vue/components/settings/CreateSubscriberAttributeModal.vueRepository: phpList/web-frontend
Length of output: 3311
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n[Component script]\n'
sed -n '120,260p' assets/vue/components/settings/CreateSubscriberAttributeModal.vue
printf '\n[API module]\n'
sed -n '1,220p' assets/vue/api.jsRepository: phpList/web-frontend
Length of output: 7547
Fix the mock paths in this spec.
vi.mock('../../api') and vi.mock('../base/BaseIcon.vue') resolve under tests/Unit/assets/vue/components/settings/, so they don’t match the component’s assets/vue/api.js and assets/vue/components/base/BaseIcon.vue imports. That leaves subscriberAttributesClient.createAttributeDefinition unmocked.
🔧 Suggested fix
-vi.mock('../../api', () => ({
+vi.mock('../../../../../../assets/vue/api', () => ({
subscriberAttributesClient: {
createAttributeDefinition: createAttributeDefinitionMock,
},
}))
-vi.mock('../base/BaseIcon.vue', () => ({
+vi.mock('../../../../../../assets/vue/components/base/BaseIcon.vue', () => ({
default: {
template: '<span />',
},
}))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| vi.mock('../../api', () => ({ | |
| subscriberAttributesClient: { | |
| createAttributeDefinition: createAttributeDefinitionMock, | |
| }, | |
| })) | |
| vi.mock('../base/BaseIcon.vue', () => ({ | |
| default: { | |
| template: '<span />', | |
| }, | |
| })) | |
| vi.mock('../../../../../../assets/vue/api', () => ({ | |
| subscriberAttributesClient: { | |
| createAttributeDefinition: createAttributeDefinitionMock, | |
| }, | |
| })) | |
| vi.mock('../../../../../../assets/vue/components/base/BaseIcon.vue', () => ({ | |
| default: { | |
| template: '<span />', | |
| }, | |
| })) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@tests/Unit/assets/vue/components/settings/CreateSubscriberAttributeModal.spec.js`
around lines 10 - 20, Fix the Vitest mocks in
CreateSubscriberAttributeModal.spec.js so they intercept the same import paths
used by the component. Update the vi.mock calls for the API module and
BaseIcon.vue to match the component’s assets/vue/api.js and
assets/vue/components/base/BaseIcon.vue imports, ensuring
subscriberAttributesClient.createAttributeDefinition is actually mocked when the
modal tests run.
| vi.mock('../../api', () => ({ | ||
| subscriberAttributesClient: { | ||
| updateAttributeDefinition: updateAttributeDefinitionMock, | ||
| }, | ||
| })) | ||
|
|
||
| vi.mock('../base/BaseIcon.vue', () => ({ | ||
| default: { | ||
| template: '<span />', | ||
| }, | ||
| })) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== files ==\n'
git ls-files 'tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js' \
'assets/vue/components/settings/EditSubscriberAttributeModal.vue' \
'tests/Unit/assets/vue/components/settings/*.spec.js' \
'assets/vue/components/base/BaseIcon.vue' \
'assets/vue/api.*' \
'assets/vue/api/index.*' \
'tests/Unit/assets/vue/api.*' \
'tests/Unit/assets/vue/api/index.*'
printf '\n== spec outline ==\n'
ast-grep outline tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js --view expanded || true
printf '\n== component outline ==\n'
ast-grep outline assets/vue/components/settings/EditSubscriberAttributeModal.vue --view expanded || true
printf '\n== spec excerpt ==\n'
sed -n '1,120p' tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js
printf '\n== component excerpt ==\n'
sed -n '1,140p' assets/vue/components/settings/EditSubscriberAttributeModal.vueRepository: phpList/web-frontend
Length of output: 8476
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== sibling specs using mocks ==\n'
rg -n "vi\.mock\\(" tests/Unit/assets/vue/components/settings -g '*.spec.js'
printf '\n== search component imports ==\n'
rg -n "from ['\"].*api|from ['\"].*BaseIcon|import .*api|import .*BaseIcon" assets/vue/components/settings/EditSubscriberAttributeModal.vue tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.jsRepository: phpList/web-frontend
Length of output: 3651
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '== read spec =='
sed -n '1,80p' tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js
echo '== read component =='
sed -n '1,120p' assets/vue/components/settings/EditSubscriberAttributeModal.vue
echo '== nearby sibling spec mocks =='
for f in tests/Unit/assets/vue/components/settings/*.spec.js; do
echo "--- $f"
rg -n "vi\.mock\(" "$f" || true
doneRepository: phpList/web-frontend
Length of output: 7851
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== api file ==\n'
sed -n '1,220p' assets/vue/api.js
printf '\n== edit subscriber spec full around update test ==\n'
sed -n '80,220p' tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.jsRepository: phpList/web-frontend
Length of output: 8084
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== api symbols ==\n'
rg -n "subscriberAttributesClient|updateAttributeDefinition" assets/vue/api.js assets/vue -g '*.js' -g '*.ts'Repository: phpList/web-frontend
Length of output: 625
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,240p' assets/vue/api.jsRepository: phpList/web-frontend
Length of output: 4992
Mock the same module ids the component imports.
vi.mock('../../api') and vi.mock('../base/BaseIcon.vue') resolve to tests/Unit/assets/vue/api and tests/Unit/assets/vue/components/base/BaseIcon.vue from this spec, so they won’t intercept EditSubscriberAttributeModal.vue’s assets/vue/api and assets/vue/components/base/BaseIcon.vue imports. Point both mocks at the source modules.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@tests/Unit/assets/vue/components/settings/EditSubscriberAttributeModal.spec.js`
around lines 10 - 20, The mocks in EditSubscriberAttributeModal.spec.js are
targeting the wrong module ids, so they do not intercept the imports used by
EditSubscriberAttributeModal.vue. Update the vi.mock calls for the api client
and BaseIcon.vue to point at the same source module paths that the component
imports, using the existing identifiers subscriberAttributesClient and
updateAttributeDefinitionMock so the component receives the intended stubs.
| vi.mock('../../api', () => ({ | ||
| adminAttributeClient: { | ||
| getAttributeDefinitions: getAttributeDefinitionsMock, | ||
| deleteAttributeDefinition: deleteAttributeDefinitionMock, | ||
| }, | ||
| })) | ||
|
|
||
| vi.mock('../base/BaseIcon.vue', () => ({ | ||
| default: { | ||
| template: '<span />', | ||
| }, | ||
| })) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git ls-files 'tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js' 'assets/vue/components/settings/SettingsAdminAttributes.vue' 'tests/Unit/assets/vue/components/settings/*spec.js' | sed 's#^`#-` #'
printf '\n--- SPEC ---\n'
cat -n tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js | sed -n '1,220p'
printf '\n--- COMPONENT ---\n'
cat -n assets/vue/components/settings/SettingsAdminAttributes.vue | sed -n '1,260p'
printf '\n--- SIBLING SPECS (mock usage) ---\n'
rg -n "vi\.mock\(" tests/Unit/assets/vue/components/settings/*spec.jsRepository: phpList/web-frontend
Length of output: 21197
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- VITE / VITEST CONFIG ---'
git ls-files | rg '(^|/)(vite|vitest|vite\.config|vitest\.config)\.(js|ts|mjs|cjs|mts|cts)$|(^|/)package\.json$|(^|/)tsconfig.*\.json$' || true
printf '\n--- SEARCH FOR vi.mock PATTERN WITH RELATIVE IMPORTS ---\n'
rg -n "vi\.mock\('(\.\./|\./|\.{2}/)" tests/Unit assets/vue -g '*spec.js' -g '*spec.ts'
printf '\n--- SETTINGS COMPONENT IMPORTS ---\n'
rg -n "from '../base/BaseIcon.vue'|from '../../api'" assets/vue/components/settings/SettingsAdminAttributes.vue assets/vue/components/settings/*.vue
printf '\n--- VITEST DOC HINTS IN REPO ---\n'
rg -n "vi\.mock|mock path|relative to" README.md docs tests/Unit package.json vite.config.* vitest.config.* 2>/dev/null || trueRepository: phpList/web-frontend
Length of output: 15761
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- vitest.config.mjs ---'
cat -n vitest.config.mjs | sed -n '1,220p'
printf '\n--- package.json (relevant bits) ---\n'
cat -n package.json | sed -n '1,220p'Repository: phpList/web-frontend
Length of output: 1923
🏁 Script executed:
#!/bin/bash
set -euo pipefail
node - <<'JS'
const path = require('path');
const testDir = path.posix.dirname('tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js');
const apiFromTest = path.posix.normalize(path.posix.join(testDir, '../../api'));
const iconFromTest = path.posix.normalize(path.posix.join(testDir, '../base/BaseIcon.vue'));
const apiFromComponent = path.posix.normalize(path.posix.join('assets/vue/components/settings', '../../api'));
const iconFromComponent = path.posix.normalize(path.posix.join('assets/vue/components/settings', '../base/BaseIcon.vue'));
console.log({ apiFromTest, iconFromTest, apiFromComponent, iconFromComponent });
console.log({
apiRelative: path.posix.relative(testDir, 'assets/vue/api'),
iconRelative: path.posix.relative(testDir, 'assets/vue/components/base/BaseIcon.vue'),
});
JSRepository: phpList/web-frontend
Length of output: 508
Point the mocks at the component imports. vi.mock('../../api') and vi.mock('../base/BaseIcon.vue') resolve from tests/Unit/assets/vue/components/settings/, so they miss the ../../api and ../base/BaseIcon.vue imports inside SettingsAdminAttributes.vue. Use the longer relative paths (or a shared alias) so the component’s client and icon are actually mocked.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/Unit/assets/vue/components/settings/SettingsAdminAttributes.spec.js`
around lines 13 - 24, The mocks in SettingsAdminAttributes.spec.js are resolving
from the test file location instead of the component’s import paths, so they do
not intercept the imports used by SettingsAdminAttributes.vue. Update the
vi.mock targets for the api client and BaseIcon.vue to match the component’s
actual relative imports (or switch both to a shared alias) so
adminAttributeClient and BaseIcon are properly mocked during the component test.
Summary by CodeRabbit
New Features
Bug Fixes
Summary
Provide a general description of the code changes in your pull request …
were there any bugs you had fixed? If so, mention them. If these bugs have open
GitHub issues, be sure to tag them here as well, to keep the conversation
linked together.
Unit test
Are your changes covered with unit tests, and do they not break anything?
You can run the existing unit tests using this command:
Code style
Have you checked that you code is well-documented and follows the PSR-2 coding
style?
You can check for this using this command:
Other Information
If there's anything else that's important and relevant to your pull
request, mention that information here. This could include benchmarks,
or other information.
If you are updating any of the CHANGELOG files or are asked to update the
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
Thanks for contributing to phpList!