Skip to content

test: simplify test file mocking patterns#8320

Merged
DrJKL merged 9 commits intomainfrom
drjkl/mock-yeah-ing-yeah
Jan 28, 2026
Merged

test: simplify test file mocking patterns#8320
DrJKL merged 9 commits intomainfrom
drjkl/mock-yeah-ing-yeah

Conversation

@DrJKL
Copy link
Contributor

@DrJKL DrJKL commented Jan 26, 2026

Simplifies test mocking patterns across multiple test files.

  • Removes redundant vi.hoisted() calls
  • Cleans up mock implementations
  • Removes unused imports and variables

┆Issue is synchronized with this Notion page by Unito

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 26, 2026

📝 Walkthrough

Walkthrough

Replaces the legacy src/services/newUserService.ts with a composable useNewUserService, updates callers (e.g., GraphCanvas.vue) to call useNewUserService().initializeIfNewUser() (no args), converts many tests from dynamic import() to static imports, and adds new public functions to jobOutputCache.

Changes

Cohort / File(s) Summary
New User Service Migration
src/components/graph/GraphCanvas.vue, src/services/newUserService.ts, src/services/useNewUserService.ts, src/services/useNewUserService.test.ts
Deleted legacy newUserService; added useNewUserService (shared composable) exposing registerInitCallback, initializeIfNewUser() (no args), isNewUser, reset. Call sites updated to useNewUserService().initializeIfNewUser(). Review init/callback lifecycle and tests for new API usage.
Test Import Refactoring - Dynamic → Static
src/components/graph/SelectionToolbox.test.ts, src/components/graph/selectionToolbox/ExecuteButton.test.ts, src/composables/useTemplateFiltering.test.ts, src/lib/litegraph/src/LGraph.test.ts, src/lib/litegraph/src/litegraph.test.ts, src/platform/assets/composables/useMediaAssetActions.test.ts, src/platform/surveys/useFeatureUsageTracker.test.ts, src/renderer/core/thumbnail/useWorkflowThumbnail.test.ts, src/renderer/extensions/minimap/composables/useMinimap.test.ts, src/renderer/extensions/minimap/composables/useMinimapRenderer.test.ts, src/renderer/extensions/minimap/composables/useMinimapViewport.test.ts, src/renderer/extensions/vueNodes/widgets/composables/useRemoteWidget.test.ts, src/stores/subgraphNavigationStore.test.ts
Replaced runtime import() calls with static top-level imports; converted async setups to synchronous; updated spies/mocks to target statically imported symbols. Pay attention to mock reset behavior and test isolation changes.
Module API / Job Output Cache
src/services/jobOutputCache.test.ts, src/services/jobOutputCache.ts
jobOutputCache now exposes findActiveIndex, getOutputsForTask, getJobDetail, getJobWorkflow. Tests updated to mock api.getJobDetail and exercise these public functions. Review cache semantics and API surface additions.
Telemetry & Topup API Adjustments in Tests
src/platform/telemetry/topupTracker.test.ts, src/platform/telemetry/useTelemetry.test.ts
Tests switched from module namespace imports to direct named function imports (e.g., startTopupTracking, checkForCompletedTopup, clearTopupTracking) and direct useTelemetry() import. Check exported names and test expectations align with new imports.
Testing Infrastructure & Mocks
src/platform/updates/common/releaseStore.test.ts, src/platform/updates/common/versionCompatibilityStore.test.ts, src/workbench/extensions/manager/components/manager/packCard/PackCard.test.ts
Introduced composable-style mocks, replaced vi.resetModules() with vi.clearAllMocks() where appropriate, added createTestingPinia and shared storageMap in PackCard tests. Review mock factories and shared state handling.
Various Test Simplifications
src/lib/litegraph/..., src/renderer/extensions/minimap/..., src/platform/..., src/renderer/core/thumbnail/... (see above)
Multiple tests simplified from dynamic import patterns to direct imports and synchronous assertions; behavior unchanged but async boilerplate removed. Verify mock scoping and timing utilities (fake timers) where used.
Docs
docs/testing/unit-testing.md
Added "Mocking Composables with Reactive State" guidance with patterns and anti-patterns for mocking composables in tests.

Sequence Diagram(s)

sequenceDiagram
  participant GraphCanvas
  participant useNewUserService
  participant SettingStore
  participant LocalStorage

  GraphCanvas->>useNewUserService: useNewUserService().initializeIfNewUser()
  useNewUserService->>SettingStore: read settings (e.g., tutorial/workflow flags)
  useNewUserService->>LocalStorage: check workflow/install indicators
  alt determined as new user
    useNewUserService->>LocalStorage: set Comfy.InstalledVersion
    useNewUserService->>useNewUserService: execute pending callbacks (try/catch)
  else not new user
    useNewUserService->>useNewUserService: clear pending callbacks
  end
  useNewUserService-->>GraphCanvas: initialization complete
Loading

Possibly related PRs

Suggested reviewers

  • shinshin86
  • KarryCharon
  • Myestery
  • jtydhr88
  • simula-r
✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 26, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/28/2026, 07:40:15 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 26, 2026

🎭 Playwright Tests: ✅ Passed

Results: 507 passed, 0 failed, 0 flaky, 8 skipped (Total: 515)

📊 Browser Reports
  • chromium: View Report (✅ 495 / ❌ 0 / ⚠️ 0 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@github-actions
Copy link

github-actions bot commented Jan 26, 2026

Bundle Size Report

Summary

  • Raw size: 22.1 MB baseline 22.1 MB — 🔴 +112 B
  • Gzip: 4.59 MB baseline 4.59 MB — 🔴 +36 B
  • Brotli: 3.41 MB baseline 3.41 MB — 🟢 -50 B
  • Bundles: 173 current • 173 baseline • 81 added / 81 removed

Category Glance
Graph Workspace 🔴 +317 B (960 kB) · Other 🟢 -198 B (7.05 MB) · Panels & Settings 🟢 -8 B (471 kB) · Data & Services 🔴 +1 B (2.7 MB) · Vendor & Third-Party ⚪ 0 B (10.7 MB) · Views & Navigation ⚪ 0 B (80.7 kB) · + 5 more

Per-category breakdown
App Entry Points — 25.9 kB (baseline 25.9 kB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BJO6Mu6M.js (removed) 25.9 kB 🟢 -25.9 kB 🟢 -7.48 kB 🟢 -6.59 kB
assets/index-BynoGGdq.js (new) 25.9 kB 🔴 +25.9 kB 🔴 +7.48 kB 🔴 +6.58 kB

Status: 1 added / 1 removed

Graph Workspace — 960 kB (baseline 960 kB) • 🔴 +317 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-aIiusPzs.js (new) 960 kB 🔴 +960 kB 🔴 +194 kB 🔴 +147 kB
assets/GraphView-CPBcPnSR.js (removed) 960 kB 🟢 -960 kB 🟢 -194 kB 🟢 -147 kB

Status: 1 added / 1 removed

Views & Navigation — 80.7 kB (baseline 80.7 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-BAoICnZB.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +3.6 kB 🔴 +3.05 kB
assets/CloudSurveyView-CWDj-WrE.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -3.6 kB 🟢 -3.05 kB
assets/CloudLoginView-BHdJrrmI.js (new) 11.8 kB 🔴 +11.8 kB 🔴 +3.09 kB 🔴 +2.72 kB
assets/CloudLoginView-BxwzFDzO.js (removed) 11.8 kB 🟢 -11.8 kB 🟢 -3.09 kB 🟢 -2.72 kB
assets/UserCheckView-BM_Bq7Ab.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.45 kB 🔴 +2.13 kB
assets/UserCheckView-BPTrcfB4.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.44 kB 🟢 -2.12 kB
assets/CloudLayoutView-DKcRswM4.js (removed) 8.54 kB 🟢 -8.54 kB 🟢 -2.24 kB 🟢 -1.95 kB
assets/CloudLayoutView-DO3kesTp.js (new) 8.54 kB 🔴 +8.54 kB 🔴 +2.24 kB 🔴 +1.95 kB
assets/CloudSignupView-4T9hkpSw.js (removed) 8.18 kB 🟢 -8.18 kB 🟢 -2.33 kB 🟢 -2.02 kB
assets/CloudSignupView-DmzV0O9y.js (new) 8.18 kB 🔴 +8.18 kB 🔴 +2.33 kB 🔴 +2.02 kB
assets/CloudForgotPasswordView-BqyWR5yV.js (removed) 6.26 kB 🟢 -6.26 kB 🟢 -1.93 kB 🟢 -1.69 kB
assets/CloudForgotPasswordView-CV-qh0UG.js (new) 6.26 kB 🔴 +6.26 kB 🔴 +1.93 kB 🔴 +1.69 kB
assets/UserSelectView-B77FaBTs.js (removed) 5.28 kB 🟢 -5.28 kB 🟢 -1.76 kB 🟢 -1.57 kB
assets/UserSelectView-D6BlyZDS.js (new) 5.28 kB 🔴 +5.28 kB 🔴 +1.76 kB 🔴 +1.57 kB
assets/CloudSubscriptionRedirectView-2VSvIg6l.js (removed) 5.27 kB 🟢 -5.27 kB 🟢 -1.73 kB 🟢 -1.54 kB
assets/CloudSubscriptionRedirectView-LizReqQE.js (new) 5.27 kB 🔴 +5.27 kB 🔴 +1.73 kB 🔴 +1.54 kB
assets/CloudAuthTimeoutView-BIrLdlda.js (new) 5.24 kB 🔴 +5.24 kB 🔴 +1.7 kB 🔴 +1.48 kB
assets/CloudAuthTimeoutView-BtwugSCE.js (removed) 5.24 kB 🟢 -5.24 kB 🟢 -1.71 kB 🟢 -1.48 kB
assets/CloudSorryContactSupportView-n5f-fGMz.js 1.97 kB 1.97 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-V93lMUpe.js 500 B 500 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 9 added / 9 removed

Panels & Settings — 471 kB (baseline 471 kB) • 🟢 -8 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WorkspacePanel-ChxwVWsZ.js (removed) 29.8 kB 🟢 -29.8 kB 🟢 -5.89 kB 🟢 -5.14 kB
assets/WorkspacePanel-CqLDVUBB.js (new) 29.8 kB 🔴 +29.8 kB 🔴 +5.89 kB 🔴 +5.14 kB
assets/LegacyCreditsPanel-BK9kFQT_.js (new) 23.8 kB 🔴 +23.8 kB 🔴 +5.95 kB 🔴 +5.22 kB
assets/LegacyCreditsPanel-CUIPkFtt.js (removed) 23.8 kB 🟢 -23.8 kB 🟢 -5.95 kB 🟢 -5.23 kB
assets/SubscriptionPanel-C0UFDZv3.js (new) 21 kB 🔴 +21 kB 🔴 +5.05 kB 🔴 +4.44 kB
assets/SubscriptionPanel-l8maW0Gs.js (removed) 21 kB 🟢 -21 kB 🟢 -5.05 kB 🟢 -4.46 kB
assets/KeybindingPanel-B-tcmjU_.js (removed) 14.2 kB 🟢 -14.2 kB 🟢 -3.74 kB 🟢 -3.31 kB
assets/KeybindingPanel-DdxCgf2p.js (new) 14.2 kB 🔴 +14.2 kB 🔴 +3.74 kB 🔴 +3.31 kB
assets/AboutPanel-B3du2C0K.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.68 kB 🟢 -2.43 kB
assets/AboutPanel-Dlf9gYSV.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.68 kB 🔴 +2.43 kB
assets/ExtensionPanel-CMcOwalt.js (removed) 10.2 kB 🟢 -10.2 kB 🟢 -2.71 kB 🟢 -2.4 kB
assets/ExtensionPanel-CyClheDN.js (new) 10.2 kB 🔴 +10.2 kB 🔴 +2.71 kB 🔴 +2.4 kB
assets/ServerConfigPanel-D5ywNUCD.js (new) 7.23 kB 🔴 +7.23 kB 🔴 +2.17 kB 🔴 +1.94 kB
assets/ServerConfigPanel-DRyBi-zQ.js (removed) 7.23 kB 🟢 -7.23 kB 🟢 -2.17 kB 🟢 -1.94 kB
assets/UserPanel-CdA-NNKB.js (new) 6.58 kB 🔴 +6.58 kB 🔴 +1.91 kB 🔴 +1.68 kB
assets/UserPanel-D73dVw9h.js (removed) 6.58 kB 🟢 -6.58 kB 🟢 -1.91 kB 🟢 -1.67 kB
assets/refreshRemoteConfig-Dhl89R6S.js (new) 1.31 kB 🔴 +1.31 kB 🔴 +573 B 🔴 +500 B
assets/refreshRemoteConfig-DQFgZ0IS.js (removed) 1.31 kB 🟢 -1.31 kB 🟢 -574 B 🟢 -499 B
assets/config-DETlADga.js (removed) 1.16 kB 🟢 -1.16 kB 🟢 -610 B 🟢 -536 B
assets/config-sf4FMtMp.js (new) 1.15 kB 🔴 +1.15 kB 🔴 +604 B 🔴 +534 B
assets/cloudRemoteConfig-Cr5E1lSv.js (removed) 1.08 kB 🟢 -1.08 kB 🟢 -498 B 🟢 -433 B
assets/cloudRemoteConfig-D3F8Yitc.js (new) 1.08 kB 🔴 +1.08 kB 🔴 +497 B 🔴 +432 B
assets/refreshRemoteConfig-CMbj6r2i.js (removed) 169 B 🟢 -169 B 🟢 -108 B 🟢 -106 B
assets/refreshRemoteConfig-CQXxknda.js (new) 169 B 🔴 +169 B 🔴 +108 B 🔴 +105 B
assets/remoteConfig-B0mlVvm7.js 788 B 788 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-2UNjEj6k.js 32.9 kB 32.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-B2OMGvh7.js 31.2 kB 31.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BcujOfpn.js 29.6 kB 29.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BI09_t23.js 29.4 kB 29.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BKamuseh.js 25.8 kB 25.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BlTun9tZ.js 26.4 kB 26.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CZ62uO3e.js 30.2 kB 30.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DaK-NByz.js 35.2 kB 35.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DaS3cSXp.js 39.4 kB 39.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DWbMuaAa.js 32 kB 32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-S7pA60Hj.js 30.4 kB 30.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 12 added / 12 removed

User & Accounts — 3.94 kB (baseline 3.94 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-2Nlb1oEZ.js (new) 3.54 kB 🔴 +3.54 kB 🔴 +1.24 kB 🔴 +1.05 kB
assets/auth-C-u1b-o4.js (removed) 3.54 kB 🟢 -3.54 kB 🟢 -1.24 kB 🟢 -1.05 kB
assets/firebaseAuthStore-CBOhTAQb.js (new) 217 B 🔴 +217 B 🔴 +136 B 🔴 +136 B
assets/firebaseAuthStore-Ddf27ak8.js (removed) 217 B 🟢 -217 B 🟢 -136 B 🟢 -118 B
assets/auth-CMgeu4PX.js (removed) 178 B 🟢 -178 B 🟢 -141 B 🟢 -128 B
assets/auth-Dax0YNGJ.js (new) 178 B 🔴 +178 B 🔴 +142 B 🔴 +130 B

Status: 3 added / 3 removed

Editors & Dialogs — 2.89 kB (baseline 2.89 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-DbbUvMas.js (new) 2.71 kB 🔴 +2.71 kB 🔴 +1.29 kB 🔴 +1.13 kB
assets/useSubscriptionDialog-DG3_Noiq.js (removed) 2.71 kB 🟢 -2.71 kB 🟢 -1.29 kB 🟢 -1.15 kB
assets/useSubscriptionDialog-T86ahmHU.js (new) 179 B 🔴 +179 B 🔴 +110 B 🔴 +97 B
assets/useSubscriptionDialog-xS6mhi4F.js (removed) 179 B 🟢 -179 B 🟢 -110 B 🟢 -96 B

Status: 2 added / 2 removed

UI Components — 33.7 kB (baseline 33.7 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-DE-oj_mH.js (removed) 9.52 kB 🟢 -9.52 kB 🟢 -2.68 kB 🟢 -2.41 kB
assets/ComfyQueueButton-DoQOZUu0.js (new) 9.52 kB 🔴 +9.52 kB 🔴 +2.69 kB 🔴 +2.41 kB
assets/SubscribeButton-C_UyDV9l.js (removed) 4.63 kB 🟢 -4.63 kB 🟢 -1.57 kB 🟢 -1.39 kB
assets/SubscribeButton-WqQ8VkKR.js (new) 4.63 kB 🔴 +4.63 kB 🔴 +1.57 kB 🔴 +1.39 kB
assets/cloudFeedbackTopbarButton-D4_NFoCf.js (removed) 1.24 kB 🟢 -1.24 kB 🟢 -675 B 🟢 -574 B
assets/cloudFeedbackTopbarButton-DyKtQNER.js (new) 1.24 kB 🔴 +1.24 kB 🔴 +674 B 🔴 +573 B
assets/ComfyQueueButton-Dme2holj.js (new) 181 B 🔴 +181 B 🔴 +118 B 🔴 +120 B
assets/ComfyQueueButton-XktXTV-j.js (removed) 181 B 🟢 -181 B 🟢 -118 B 🟢 -118 B
assets/Button-DNv6_y7F.js 3.82 kB 3.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-sJFM8Oh-.js 1.85 kB 1.85 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-qACg_vGT.js 8.36 kB 8.36 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-D80lITos.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-DlN5KSpc.js 2.41 kB 2.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 4 added / 4 removed

Data & Services — 2.7 MB (baseline 2.7 MB) • 🔴 +1 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-2oWWNTnH.js (removed) 2 MB 🟢 -2 MB 🟢 -423 kB 🟢 -323 kB
assets/dialogService-Y-pr4Cfk.js (new) 2 MB 🔴 +2 MB 🔴 +423 kB 🔴 +323 kB
assets/api-xUk7NpMW.js (new) 672 kB 🔴 +672 kB 🔴 +148 kB 🔴 +118 kB
assets/api-Br0qGC84.js (removed) 672 kB 🟢 -672 kB 🟢 -148 kB 🟢 -118 kB
assets/releaseStore-Ckxv8NPR.js (new) 8.91 kB 🔴 +8.91 kB 🔴 +2.4 kB 🔴 +2.12 kB
assets/releaseStore-DgMntUAi.js (removed) 8.91 kB 🟢 -8.91 kB 🟢 -2.4 kB 🟢 -2.12 kB
assets/keybindingService-B8MSsZ0Y.js (removed) 6.78 kB 🟢 -6.78 kB 🟢 -1.74 kB 🟢 -1.51 kB
assets/keybindingService-BtGzc2rW.js (new) 6.78 kB 🔴 +6.78 kB 🔴 +1.74 kB 🔴 +1.51 kB
assets/bootstrapStore-BikXtNlO.js (removed) 2.69 kB 🟢 -2.69 kB 🟢 -1.03 kB 🟢 -955 B
assets/bootstrapStore-gwRW43nD.js (new) 2.69 kB 🔴 +2.69 kB 🔴 +1.03 kB 🔴 +964 B
assets/userStore-DGfOHufp.js (removed) 2.16 kB 🟢 -2.16 kB 🟢 -810 B 🟢 -723 B
assets/userStore-OhcJ4BKx.js (new) 2.16 kB 🔴 +2.16 kB 🔴 +812 B 🔴 +725 B
assets/audioService-BOfK9N4L.js (new) 2.03 kB 🔴 +2.03 kB 🔴 +932 B 🔴 +809 B
assets/audioService-T_jrnhMQ.js (removed) 2.03 kB 🟢 -2.03 kB 🟢 -930 B 🟢 -814 B
assets/releaseStore-DqRAcHQE.js (new) 140 B 🔴 +140 B 🔴 +106 B 🔴 +106 B
assets/releaseStore-uXdwuHk3.js (removed) 140 B 🟢 -140 B 🟢 -106 B 🟢 -116 B
assets/serverConfigStore-DOoqLe5c.js 2.64 kB 2.64 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 removed

Utilities & Hooks — 25.3 kB (baseline 25.3 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useErrorHandling-BQwtBAir.js (new) 5.21 kB 🔴 +5.21 kB 🔴 +1.53 kB 🔴 +1.34 kB
assets/useErrorHandling-DVnPstR9.js (removed) 5.21 kB 🟢 -5.21 kB 🟢 -1.53 kB 🟢 -1.34 kB
assets/useWorkspaceUI-BcZa_ND-.js (new) 3.42 kB 🔴 +3.42 kB 🔴 +976 B 🔴 +836 B
assets/useWorkspaceUI-CNegFxEP.js (removed) 3.42 kB 🟢 -3.42 kB 🟢 -976 B 🟢 -846 B
assets/useSubscriptionActions-BWjUGMhb.js (new) 2.22 kB 🔴 +2.22 kB 🔴 +870 B 🔴 +762 B
assets/useSubscriptionActions-Dwh4401C.js (removed) 2.22 kB 🟢 -2.22 kB 🟢 -872 B 🟢 -762 B
assets/subscriptionCheckoutUtil-BvDYFECa.js (new) 2.03 kB 🔴 +2.03 kB 🔴 +873 B 🔴 +772 B
assets/subscriptionCheckoutUtil-D3R3uti7.js (removed) 2.03 kB 🟢 -2.03 kB 🟢 -873 B 🟢 -770 B
assets/useSubscriptionCredits-inhFrC_U.js (removed) 1.39 kB 🟢 -1.39 kB 🟢 -597 B 🟢 -529 B
assets/useSubscriptionCredits-J8RXoD2I.js (new) 1.39 kB 🔴 +1.39 kB 🔴 +598 B 🔴 +529 B
assets/audioUtils-CzF_lFAV.js (removed) 970 B 🟢 -970 B 🟢 -548 B 🟢 -486 B
assets/audioUtils-DtVUlZCe.js (new) 970 B 🔴 +970 B 🔴 +547 B 🔴 +484 B
assets/useCurrentUser-BDUsCAu4.js (removed) 145 B 🟢 -145 B 🟢 -114 B 🟢 -110 B
assets/useCurrentUser-ip3lo6x2.js (new) 145 B 🔴 +145 B 🔴 +114 B 🔴 +103 B
assets/_plugin-vue_export-helper-DuK_Fly3.js 467 B 467 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-GMAsfHxw.js 7.2 kB 7.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-ivqHoiOs.js 1.78 kB 1.78 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/tailwindUtil-CJjrIEVR.js 488 B 488 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 7 added / 7 removed

Vendor & Third-Party — 10.7 MB (baseline 10.7 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DHGfk3hn.js 408 kB 408 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-jpGqhHNG.js 4.1 MB 4.1 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-4Jj8eU28.js 3.04 MB 3.04 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-CEgfUa-v.js 256 kB 256 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-CERwhPwK.js 1.83 MB 1.83 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-BxrEVL6s.js 650 kB 650 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-Dwii0E-t.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-IX6P8SWv.js 398 kB 398 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.05 MB (baseline 7.05 MB) • 🟢 -198 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-CWxj7Ota.js (removed) 180 kB 🟢 -180 kB 🟢 -43.3 kB 🟢 -36.2 kB
assets/core-gv69fGKI.js (new) 180 kB 🔴 +180 kB 🔴 +43.3 kB 🔴 +36.2 kB
assets/WidgetSelect-Og4I7AuG.js (new) 51 kB 🔴 +51 kB 🔴 +11.2 kB 🔴 +9.81 kB
assets/WidgetSelect-wRR4Yot1.js (removed) 51 kB 🟢 -51 kB 🟢 -11.2 kB 🟢 -9.81 kB
assets/Load3DControls-CvjdDN2x.js (removed) 35.9 kB 🟢 -35.9 kB 🟢 -5.87 kB 🟢 -5.08 kB
assets/Load3DControls-DzP1SIO-.js (new) 35.9 kB 🔴 +35.9 kB 🔴 +5.87 kB 🔴 +5.07 kB
assets/SubscriptionRequiredDialogContent-BThpKDhl.js (new) 28.7 kB 🔴 +28.7 kB 🔴 +6.79 kB 🔴 +5.92 kB
assets/SubscriptionRequiredDialogContent-C8zJymkA.js (removed) 28.7 kB 🟢 -28.7 kB 🟢 -6.79 kB 🟢 -5.92 kB
assets/CurrentUserPopoverWorkspace-CxSfWGxD.js (new) 22.2 kB 🔴 +22.2 kB 🔴 +5 kB 🔴 +4.42 kB
assets/CurrentUserPopoverWorkspace-DGI-lvay.js (removed) 22.2 kB 🟢 -22.2 kB 🟢 -4.99 kB 🟢 -4.42 kB
assets/Load3D-CZGSUcOu.js (removed) 19.2 kB 🟢 -19.2 kB 🟢 -4.37 kB 🟢 -3.84 kB
assets/Load3D-DTIFC4te.js (new) 19.2 kB 🔴 +19.2 kB 🔴 +4.37 kB 🔴 +3.85 kB
assets/WidgetRecordAudio-4fTGxlno.js (removed) 18.3 kB 🟢 -18.3 kB 🟢 -4.97 kB 🟢 -4.43 kB
assets/WidgetRecordAudio-Bts9GfaE.js (new) 18.3 kB 🔴 +18.3 kB 🔴 +4.97 kB 🔴 +4.44 kB
assets/WidgetInputNumber-De4E41TL.js (new) 18.3 kB 🔴 +18.3 kB 🔴 +4.51 kB 🔴 +4.02 kB
assets/WidgetInputNumber-PWYJtmkM.js (removed) 18.3 kB 🟢 -18.3 kB 🟢 -4.51 kB 🟢 -4.02 kB
assets/SubscriptionPanelContentWorkspace-BMycZi-l.js (new) 18.2 kB 🔴 +18.2 kB 🔴 +4.47 kB 🔴 +3.9 kB
assets/SubscriptionPanelContentWorkspace-Cqf08bD2.js (removed) 18.2 kB 🟢 -18.2 kB 🟢 -4.47 kB 🟢 -3.9 kB
assets/WidgetImageCrop-D_u2yCsC.js (new) 17.1 kB 🔴 +17.1 kB 🔴 +4.14 kB 🔴 +3.63 kB
assets/WidgetImageCrop-qWDBA8Xd.js (removed) 17.1 kB 🟢 -17.1 kB 🟢 -4.14 kB 🟢 -3.62 kB
assets/PanelTemplate-CbRWWYXR.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -5.46 kB 🟢 -4.8 kB
assets/PanelTemplate-CfdLJLX1.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +5.46 kB 🔴 +4.8 kB
assets/AudioPreviewPlayer-CrTvIBTI.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.98 kB 🟢 -2.65 kB
assets/AudioPreviewPlayer-D_trgHx7.js (new) 10.8 kB 🔴 +10.8 kB 🔴 +2.97 kB 🔴 +2.65 kB
assets/InviteMemberDialogContent-D_pi3loR.js (removed) 8.36 kB 🟢 -8.36 kB 🟢 -2.5 kB 🟢 -2.17 kB
assets/InviteMemberDialogContent-DcXps7MH.js (new) 8.36 kB 🔴 +8.36 kB 🔴 +2.51 kB 🔴 +2.16 kB
assets/WidgetWithControl-T0GRXy9I.js (removed) 8.07 kB 🟢 -8.07 kB 🟢 -2.68 kB 🟢 -2.42 kB
assets/WidgetWithControl-TEs_6m90.js (new) 8.07 kB 🔴 +8.07 kB 🔴 +2.68 kB 🔴 +2.41 kB
assets/CreateWorkspaceDialogContent-Ck13tfeT.js (removed) 5.93 kB 🟢 -5.93 kB 🟢 -1.93 kB 🟢 -1.68 kB
assets/CreateWorkspaceDialogContent-D2O2eYx_.js (new) 5.93 kB 🔴 +5.93 kB 🔴 +1.93 kB 🔴 +1.68 kB
assets/EditWorkspaceDialogContent-BSemG5OH.js (removed) 5.7 kB 🟢 -5.7 kB 🟢 -1.88 kB 🟢 -1.64 kB
assets/EditWorkspaceDialogContent-DfadLC15.js (new) 5.7 kB 🔴 +5.7 kB 🔴 +1.88 kB 🔴 +1.64 kB
assets/ValueControlPopover-CaYZGMOI.js (removed) 5.17 kB 🟢 -5.17 kB 🟢 -1.69 kB 🟢 -1.5 kB
assets/ValueControlPopover-DszBAMBI.js (new) 5.17 kB 🔴 +5.17 kB 🔴 +1.69 kB 🔴 +1.5 kB
assets/DeleteWorkspaceDialogContent-D8bp9SRh.js (removed) 4.59 kB 🟢 -4.59 kB 🟢 -1.56 kB 🟢 -1.35 kB
assets/DeleteWorkspaceDialogContent-DKn8LkOR.js (new) 4.59 kB 🔴 +4.59 kB 🔴 +1.56 kB 🔴 +1.35 kB
assets/LeaveWorkspaceDialogContent-Cbsiux73.js (new) 4.41 kB 🔴 +4.41 kB 🔴 +1.5 kB 🔴 +1.3 kB
assets/LeaveWorkspaceDialogContent-Cd8ATIr4.js (removed) 4.41 kB 🟢 -4.41 kB 🟢 -1.5 kB 🟢 -1.31 kB
assets/RemoveMemberDialogContent-BZmEVC5S.js (removed) 4.38 kB 🟢 -4.38 kB 🟢 -1.46 kB 🟢 -1.27 kB
assets/RemoveMemberDialogContent-DJ9SjO2h.js (new) 4.38 kB 🔴 +4.38 kB 🔴 +1.45 kB 🔴 +1.27 kB
assets/RevokeInviteDialogContent-6HgL145L.js (removed) 4.29 kB 🟢 -4.29 kB 🟢 -1.47 kB 🟢 -1.29 kB
assets/RevokeInviteDialogContent-B3xKUT1G.js (new) 4.29 kB 🔴 +4.29 kB 🔴 +1.47 kB 🔴 +1.29 kB
assets/GlobalToast-BRlQinhi.js (removed) 3.05 kB 🟢 -3.05 kB 🟢 -1.1 kB 🟢 -937 B
assets/GlobalToast-kGuisoDT.js (new) 3.05 kB 🔴 +3.05 kB 🔴 +1.1 kB 🔴 +935 B
assets/SubscribeToRun-Br6IDKrW.js (removed) 2.96 kB 🟢 -2.96 kB 🟢 -1.16 kB 🟢 -1.01 kB
assets/SubscribeToRun-z2vMxsWp.js (new) 2.96 kB 🔴 +2.96 kB 🔴 +1.15 kB 🔴 +1.01 kB
assets/cloudSessionCookie-CjkBuJ5u.js (new) 2.94 kB 🔴 +2.94 kB 🔴 +929 B 🔴 +802 B
assets/cloudSessionCookie-ypMTi88P.js (removed) 2.94 kB 🟢 -2.94 kB 🟢 -929 B 🟢 -802 B
assets/BaseViewTemplate-BLw3nFc_.js (removed) 2.42 kB 🟢 -2.42 kB 🟢 -1.04 kB 🟢 -936 B
assets/BaseViewTemplate-C6n6NMIy.js (new) 2.42 kB 🔴 +2.42 kB 🔴 +1.04 kB 🔴 +944 B
assets/CloudRunButtonWrapper-BZwI3reI.js (new) 1.79 kB 🔴 +1.79 kB 🔴 +644 B 🔴 +605 B
assets/CloudRunButtonWrapper-EDygqMUk.js (removed) 1.79 kB 🟢 -1.79 kB 🟢 -643 B 🟢 -561 B
assets/cloudBadges-CF9ldRYF.js (new) 1.08 kB 🔴 +1.08 kB 🔴 +535 B 🔴 +476 B
assets/cloudBadges-DEheDFsd.js (removed) 1.08 kB 🟢 -1.08 kB 🟢 -536 B 🟢 -476 B
assets/graphHasMissingNodes-BIsFLKH5.js (new) 1.06 kB 🔴 +1.06 kB 🔴 +463 B 🔴 +420 B
assets/graphHasMissingNodes-CzLX6Mmh.js (removed) 1.06 kB 🟢 -1.06 kB 🟢 -463 B 🟢 -420 B
assets/cloudSubscription-B39qSbfj.js (removed) 976 B 🟢 -976 B 🟢 -464 B 🟢 -397 B
assets/cloudSubscription-B8F4S5yi.js (new) 976 B 🔴 +976 B 🔴 +463 B 🔴 +397 B
assets/nightlyBadges-Dp3-pJbC.js (new) 595 B 🔴 +595 B 🔴 +354 B 🔴 +308 B
assets/nightlyBadges-HoEgDhAD.js (removed) 595 B 🟢 -595 B 🟢 -355 B 🟢 -309 B
assets/SubscriptionPanelContentWorkspace-Cd_86m-z.js (new) 266 B 🔴 +266 B 🔴 +136 B 🔴 +124 B
assets/SubscriptionPanelContentWorkspace-eVI9p_gu.js (removed) 266 B 🟢 -266 B 🟢 -136 B 🟢 -117 B
assets/WidgetInputNumber-BkEZrF9m.js (new) 186 B 🔴 +186 B 🔴 +119 B 🔴 +113 B
assets/WidgetInputNumber-H7XRwMNT.js (removed) 186 B 🟢 -186 B 🟢 -119 B 🟢 -118 B
assets/WidgetLegacy-CpQx7_Y0.js (new) 164 B 🔴 +164 B 🔴 +125 B 🔴 +110 B
assets/WidgetLegacy-Dl-RN1q7.js (removed) 164 B 🟢 -164 B 🟢 -125 B 🟢 -108 B
assets/Load3D-CiwsAokE.js (new) 131 B 🔴 +131 B 🔴 +107 B 🔴 +115 B
assets/Load3D-DyNmDkMF.js (removed) 131 B 🟢 -131 B 🟢 -107 B 🟢 -109 B
assets/auto-DWs2ctGL.js 1.73 kB 1.73 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BEw5ErI4.js 18.5 kB 18.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BGeHkplA.js 17.9 kB 17.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV0l36Iz.js 17.2 kB 17.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C_Y3D6Cn.js 17.8 kB 17.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C6piRza5.js 19.3 kB 19.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Cf8Zq1td.js 18.8 kB 18.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CiziP3Xs.js 18 kB 18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-D1595tOr.js 19.3 kB 19.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DXauvccL.js 20.6 kB 20.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-P5QCEfZc.js 18 kB 18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-WbYP_D61.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-C2wkDFMb.js 188 B 188 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-yEs1bv5v.js 496 kB 496 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage-DHwPdKGO.js 14.1 kB 14.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-12Ugs8uH.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-bK51E1AF.js 133 kB 133 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BpNRRXRJ.js 151 kB 151 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-c-Kg1DWL.js 126 kB 126 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C16qe5Pa.js 144 kB 144 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C2P63O3F.js 126 kB 126 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C5b27iBR.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CcswxyNG.js 173 kB 173 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-D6eu0Wen.js 128 kB 128 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DbxHumst.js 130 kB 130 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DKTrxQrQ.js 155 kB 155 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-DUmUhXD6.js 2.38 kB 2.38 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-CD66_Mw_.js 2 kB 2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-Bqe7yvm_.js 2.34 kB 2.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-De3MzVmp.js 2.82 kB 2.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/mixpanel.module-CC2-PIpB.js 143 B 143 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B0UaQKt6.js 363 kB 363 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B68z80AD.js 413 kB 413 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bg1UEeRw.js 448 kB 448 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CicFSATk.js 339 kB 339 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CinCueZ7.js 373 kB 373 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DgzjkU5p.js 366 kB 366 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DKHHBXVW.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dn1Haq99.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DxR-7ogK.js 383 kB 383 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-qCfy7PeV.js 412 kB 412 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-xDY-sSQw.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-CmezY7As.js 838 B 838 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-cVp-94Rc.js 1.96 kB 1.96 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-BckXXL4E.js 4.21 kB 4.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-BJiJuR5i.js 518 B 518 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-CUtab2CB.js 4.71 kB 4.71 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-D79nBMxa.js 186 B 186 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-CiXfBVBH.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-BxNqMlFv.js 3.71 kB 3.71 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-DDD96zwa.js 4.57 kB 4.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-A6pZMGtc.js 3.79 kB 3.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-DSMUKRnt.js 2.58 kB 2.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-MDImyvc3.js 2.7 kB 2.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-C95PPn5g.js 3.22 kB 3.22 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-ERx8czR8.js 1.31 kB 1.31 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-CV3BoahN.js 3.87 kB 3.87 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-ZdaYkxkD.js 3.26 kB 3.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-KPj-zM0O.js 573 B 573 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 34 added / 34 removed

@DrJKL DrJKL force-pushed the drjkl/mock-yeah-ing-yeah branch from a0cf3b6 to 0eb4a23 Compare January 27, 2026 00:51
@DrJKL DrJKL marked this pull request as ready for review January 27, 2026 00:52
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jan 27, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/platform/updates/common/versionCompatibilityStore.test.ts (1)

1-55: Replace any-typed mock stores with explicit types.

any obscures the mock store API surface. Please type the mocks with the real store signatures and use Partial<...> as ... for incomplete mock shapes.

♻️ Suggested typing for mocks
-  let mockSystemStatsStore: any
-  let mockSettingStore: any
+  let mockSystemStatsStore: ReturnType<typeof useSystemStatsStore>
+  let mockSettingStore: ReturnType<typeof useSettingStore>
@@
-    mockSystemStatsStore = {
+    mockSystemStatsStore = {
       systemStats: null,
       isInitialized: false,
       refetchSystemStats: vi.fn()
-    }
+    } as Partial<ReturnType<typeof useSystemStatsStore>> as ReturnType<
+      typeof useSystemStatsStore
+    >
@@
-    mockSettingStore = {
+    mockSettingStore = {
       get: vi.fn(() => false) // Default to warnings enabled
-    }
+    } as Partial<ReturnType<typeof useSettingStore>> as ReturnType<
+      typeof useSettingStore
+    >
src/platform/updates/common/releaseStore.test.ts (1)

1-83: Type the mocked stores/services instead of any.

Please align the mocks with the real store/service signatures and use Partial<...> as ... for partial mock shapes.

♻️ Suggested typing for mocks
-  let mockReleaseService: any
-  let mockSettingStore: any
-  let mockSystemStatsStore: any
+  let mockReleaseService: ReturnType<typeof useReleaseService>
+  let mockSettingStore: ReturnType<typeof useSettingStore>
+  let mockSystemStatsStore: ReturnType<typeof useSystemStatsStore>
@@
-    mockReleaseService = {
+    mockReleaseService = {
       getReleases: vi.fn(),
       isLoading: { value: false },
       error: { value: null }
-    }
+    } as Partial<ReturnType<typeof useReleaseService>> as ReturnType<
+      typeof useReleaseService
+    >
@@
-    mockSettingStore = {
+    mockSettingStore = {
       get: vi.fn(),
       set: vi.fn()
-    }
+    } as Partial<ReturnType<typeof useSettingStore>> as ReturnType<
+      typeof useSettingStore
+    >
@@
-    mockSystemStatsStore = {
+    mockSystemStatsStore = {
       systemStats: {
         system: {
           comfyui_version: '1.0.0'
         }
       },
       isInitialized: true,
       refetchSystemStats: vi.fn(),
       getFormFactor: vi.fn(() => 'git-windows')
-    }
+    } as Partial<ReturnType<typeof useSystemStatsStore>> as ReturnType<
+      typeof useSystemStatsStore
+    >
🤖 Fix all issues with AI agents
In `@src/lib/litegraph/src/LGraph.test.ts`:
- Around line 49-52: The test asserting equality between LiteGraph.LGraph and
LGraph ("expect(LiteGraph.LGraph).toBe(LGraph)") is duplicated elsewhere; remove
one of the duplicates to avoid redundancy—specifically delete the test named "is
exactly the same type" that contains the assertion, or alternatively remove the
identical assertion from the "Legacy LGraph Compatibility Layer" block (the test
named "is correctly assigned to LiteGraph"), ensuring only a single test remains
verifying LiteGraph.LGraph === LGraph.

In `@src/renderer/extensions/minimap/composables/useMinimap.test.ts`:
- Around line 156-157: The new static imports for useMinimap and api are
triggering import-x/no-unresolved due to the '@' alias; either update the ESLint
import resolver config used for tests to recognize '@' (ensure test eslint
config extends resolver settings or add "import/resolver" mapping) or change the
two imports in useMinimap.test.ts to relative paths that point to the same
modules (replace "@/renderer/extensions/minimap/composables/useMinimap" and
"@/scripts/api" with their relative filesystem equivalents) so CI lint passes;
locate the import lines referencing useMinimap and api and apply one of these
fixes.

In `@src/renderer/extensions/minimap/composables/useMinimapViewport.test.ts`:
- Around line 6-10: The test import of calculateMinimapScale,
calculateNodeBounds, and enforceMinimumBounds from
'@/renderer/core/spatial/boundsCalculator' is triggering import-x/no-unresolved;
update the import in useMinimapViewport.test.ts to use the project's relative
path to the module (e.g., navigate up from the test file into
renderer/core/spatial/boundsCalculator) OR update the test ESLint/TS resolver
config so the '@' alias is recognized in tests; modify the import statement
referencing those three functions accordingly so CI no longer flags the
unresolved alias.

In `@src/services/jobOutputCache.test.ts`:
- Around line 260-264: The test uses an unsafe cast
mockResolvedValue(mockWorkflow as any) for extractWorkflow; replace the any with
a properly typed mock that matches extractWorkflow's return type (e.g., derive
the type via ReturnType<typeof extractWorkflow> or import the extractWorkflow
return/interface) and update mockWorkflow to conform to that type so
vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow) is fully typed; keep
api.getJobDetail mocking unchanged.

In `@src/services/useNewUserService.test.ts`:
- Around line 29-30: The test currently silences TypeScript with
//@ts-expect-error for global.__COMFYUI_FRONTEND_VERSION__; either add a brief
inline comment explaining why the expect-error is necessary for this test global
(e.g., "define test-only global used by ComfyUI snapshots") or, preferably, add
a test type declaration (e.g., declare const __COMFYUI_FRONTEND_VERSION__:
string) in a test globals file so the symbol is properly typed; update
useNewUserService.test.ts to remove the expect-error or reference the new test
globals declaration accordingly.

In
`@src/workbench/extensions/manager/components/manager/packCard/PackCard.test.ts`:
- Around line 50-60: The test's vi.mock for '@vueuse/core' returns raw values
from the mocked useStorage, but VueUse's useStorage returns a Ref/RemovableRef,
so update the useStorage mock in PackCard.test.ts to return a ref-like object
(e.g., an object with a .value property holding the stored value, and persist
updates back into storageMap when .value changes) so components reading `.value`
behave correctly; locate the mocked useStorage inside the vi.mock block and
replace its return with a ref-compatible shape (or use Vue's ref() to wrap the
default value) and ensure createSharedComposable and whenever mocks remain
unchanged.

Comment on lines +156 to +204
import { useMinimap } from '@/renderer/extensions/minimap/composables/useMinimap'
import { api } from '@/scripts/api'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix lint-breaking unresolved alias on new static imports.

import-x/no-unresolved now fires on these static imports, which can fail CI. Either update the ESLint resolver to honor the @ alias for test files or switch to relative imports as a local fix.

✅ Example fallback using relative imports
-import { useMinimap } from '@/renderer/extensions/minimap/composables/useMinimap'
-import { api } from '@/scripts/api'
+import { useMinimap } from './useMinimap'
+import { api } from '../../../../scripts/api'
📝 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.

Suggested change
import { useMinimap } from '@/renderer/extensions/minimap/composables/useMinimap'
import { api } from '@/scripts/api'
import { useMinimap } from './useMinimap'
import { api } from '../../../../scripts/api'
🧰 Tools
🪛 ESLint

[error] 156-156: Unable to resolve path to module '@/renderer/extensions/minimap/composables/useMinimap'.

(import-x/no-unresolved)


[error] 157-157: Unable to resolve path to module '@/scripts/api'.

(import-x/no-unresolved)

🤖 Prompt for AI Agents
In `@src/renderer/extensions/minimap/composables/useMinimap.test.ts` around lines
156 - 157, The new static imports for useMinimap and api are triggering
import-x/no-unresolved due to the '@' alias; either update the ESLint import
resolver config used for tests to recognize '@' (ensure test eslint config
extends resolver settings or add "import/resolver" mapping) or change the two
imports in useMinimap.test.ts to relative paths that point to the same modules
(replace "@/renderer/extensions/minimap/composables/useMinimap" and
"@/scripts/api" with their relative filesystem equivalents) so CI lint passes;
locate the import lines referencing useMinimap and api and apply one of these
fixes.

Comment on lines +6 to +11
import {
calculateMinimapScale,
calculateNodeBounds,
enforceMinimumBounds
} from '@/renderer/core/spatial/boundsCalculator'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Resolve ESLint alias failure for boundsCalculator import.

The new static import is flagged by import-x/no-unresolved. Either ensure the ESLint resolver uses the TS path alias for @ in tests, or use a relative path to unblock CI.

✅ Example fallback using a relative import
-import {
-  calculateMinimapScale,
-  calculateNodeBounds,
-  enforceMinimumBounds
-} from '@/renderer/core/spatial/boundsCalculator'
+import {
+  calculateMinimapScale,
+  calculateNodeBounds,
+  enforceMinimumBounds
+} from '../../../core/spatial/boundsCalculator'
📝 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.

Suggested change
import {
calculateMinimapScale,
calculateNodeBounds,
enforceMinimumBounds
} from '@/renderer/core/spatial/boundsCalculator'
import {
calculateMinimapScale,
calculateNodeBounds,
enforceMinimumBounds
} from '../../../core/spatial/boundsCalculator'
🧰 Tools
🪛 ESLint

[error] 10-10: Unable to resolve path to module '@/renderer/core/spatial/boundsCalculator'.

(import-x/no-unresolved)

🤖 Prompt for AI Agents
In `@src/renderer/extensions/minimap/composables/useMinimapViewport.test.ts`
around lines 6 - 10, The test import of calculateMinimapScale,
calculateNodeBounds, and enforceMinimumBounds from
'@/renderer/core/spatial/boundsCalculator' is triggering import-x/no-unresolved;
update the import in useMinimapViewport.test.ts to use the project's relative
path to the module (e.g., navigate up from the test file into
renderer/core/spatial/boundsCalculator) OR update the test ESLint/TS resolver
config so the '@' alias is recognized in tests; modify the import statement
referencing those three functions accordingly so CI no longer flags the
unresolved alias.

Comment on lines 260 to 264
const mockWorkflow = { version: 1 }

vi.mocked(fetchJobDetail).mockResolvedValue(mockDetail)
vi.mocked(api.getJobDetail).mockResolvedValue(mockDetail)
vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow as any)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Avoid as any in the workflow mock.

mockResolvedValue(mockWorkflow as any) violates the test typing rule and can hide mismatches. Use a concrete type derived from extractWorkflow instead.

🔧 Suggested fix
-      const mockWorkflow = { version: 1 }
+      type Workflow = NonNullable<Awaited<ReturnType<typeof extractWorkflow>>>
+      const mockWorkflow: Workflow = { version: 1 }
       vi.mocked(api.getJobDetail).mockResolvedValue(mockDetail)
-      vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow as any)
+      vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow)

As per coding guidelines, avoid any in test files.

📝 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.

Suggested change
const mockWorkflow = { version: 1 }
vi.mocked(fetchJobDetail).mockResolvedValue(mockDetail)
vi.mocked(api.getJobDetail).mockResolvedValue(mockDetail)
vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow as any)
type Workflow = NonNullable<Awaited<ReturnType<typeof extractWorkflow>>>
const mockWorkflow: Workflow = { version: 1 }
vi.mocked(api.getJobDetail).mockResolvedValue(mockDetail)
vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow)
🤖 Prompt for AI Agents
In `@src/services/jobOutputCache.test.ts` around lines 260 - 264, The test uses an
unsafe cast mockResolvedValue(mockWorkflow as any) for extractWorkflow; replace
the any with a properly typed mock that matches extractWorkflow's return type
(e.g., derive the type via ReturnType<typeof extractWorkflow> or import the
extractWorkflow return/interface) and update mockWorkflow to conform to that
type so vi.mocked(extractWorkflow).mockResolvedValue(mockWorkflow) is fully
typed; keep api.getJobDetail mocking unchanged.

Comment on lines 29 to 30
//@ts-expect-error Define global for the test
global.__COMFYUI_FRONTEND_VERSION__ = '1.24.0'
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider documenting the @ts-expect-error usage.

Per coding guidelines, @ts-expect-error should be avoided and the underlying type issue fixed. However, for global test definitions like __COMFYUI_FRONTEND_VERSION__, this may be necessary. Consider adding a brief comment explaining why this is required or declaring the global in a test types file.

💡 Optional: Add type declaration for test globals

You could add a test globals declaration file (e.g., tests/globals.d.ts):

declare const __COMFYUI_FRONTEND_VERSION__: string

Or add a more descriptive comment:

-//@ts-expect-error Define global for the test
+// `@ts-expect-error` - Required: __COMFYUI_FRONTEND_VERSION__ is a compile-time constant injected by Vite
 global.__COMFYUI_FRONTEND_VERSION__ = '1.24.0'
🤖 Prompt for AI Agents
In `@src/services/useNewUserService.test.ts` around lines 29 - 30, The test
currently silences TypeScript with //@ts-expect-error for
global.__COMFYUI_FRONTEND_VERSION__; either add a brief inline comment
explaining why the expect-error is necessary for this test global (e.g., "define
test-only global used by ComfyUI snapshots") or, preferably, add a test type
declaration (e.g., declare const __COMFYUI_FRONTEND_VERSION__: string) in a test
globals file so the symbol is properly typed; update useNewUserService.test.ts
to remove the expect-error or reference the new test globals declaration
accordingly.

Comment on lines +50 to +59
vi.mock('@vueuse/core', () => ({
whenever: vi.fn(),
useStorage: vi.fn((key: string, defaultValue: unknown) => {
if (!storageMap.has(key)) storageMap.set(key, defaultValue)
return storageMap.get(key)
}),
createSharedComposable: vi.fn((fn) => {
let cached: ReturnType<typeof fn>
return (...args: Parameters<typeof fn>) => (cached ??= fn(...args))
})
}))
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

useStorage mock should return a ref to match VueUse's actual API.

VueUse's useStorage returns a RemovableRef<T> (extending Ref), but this mock returns the raw value. If the component (or a future change) accesses .value, the mock will behave incorrectly.

♻️ Suggested fix to match VueUse API
+import { ref } from 'vue'
+
 vi.mock('@vueuse/core', () => ({
   whenever: vi.fn(),
   useStorage: vi.fn((key: string, defaultValue: unknown) => {
     if (!storageMap.has(key)) storageMap.set(key, defaultValue)
-    return storageMap.get(key)
+    return ref(storageMap.get(key))
   }),
   createSharedComposable: vi.fn((fn) => {
     let cached: ReturnType<typeof fn>
     return (...args: Parameters<typeof fn>) => (cached ??= fn(...args))
   })
 }))
📝 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.

Suggested change
vi.mock('@vueuse/core', () => ({
whenever: vi.fn(),
useStorage: vi.fn((key: string, defaultValue: unknown) => {
if (!storageMap.has(key)) storageMap.set(key, defaultValue)
return storageMap.get(key)
}),
createSharedComposable: vi.fn((fn) => {
let cached: ReturnType<typeof fn>
return (...args: Parameters<typeof fn>) => (cached ??= fn(...args))
})
}))
import { ref } from 'vue'
vi.mock('@vueuse/core', () => ({
whenever: vi.fn(),
useStorage: vi.fn((key: string, defaultValue: unknown) => {
if (!storageMap.has(key)) storageMap.set(key, defaultValue)
return ref(storageMap.get(key))
}),
createSharedComposable: vi.fn((fn) => {
let cached: ReturnType<typeof fn>
return (...args: Parameters<typeof fn>) => (cached ??= fn(...args))
})
}))
🤖 Prompt for AI Agents
In
`@src/workbench/extensions/manager/components/manager/packCard/PackCard.test.ts`
around lines 50 - 60, The test's vi.mock for '@vueuse/core' returns raw values
from the mocked useStorage, but VueUse's useStorage returns a Ref/RemovableRef,
so update the useStorage mock in PackCard.test.ts to return a ref-like object
(e.g., an object with a .value property holding the stored value, and persist
updates back into storageMap when .value changes) so components reading `.value`
behave correctly; locate the mocked useStorage inside the vi.mock block and
replace its return with a ref-compatible shape (or use Vue's ref() to wrap the
default value) and ensure createSharedComposable and whenever mocks remain
unchanged.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/platform/updates/common/releaseStore.test.ts (1)

4-91: Fix TS type mismatches in mocked stores (CI is failing due to type incompatibility).

The partial mocks being assigned to vi.mocked(...).mockReturnValue(...) don't match the full store types. mockSettingStore omits properties like settingValues, settingsById, isReady, load, addSetting, exists, getDefaultValue, and isLoading/error. mockSystemStatsStore is missing isLoading and error. Cast these partial mocks explicitly using as Partial<StoreType> as StoreType to satisfy the type system while acknowledging the incomplete implementation.

🐛 Proposed fix
 import type { Mock } from 'vitest'
 import { beforeEach, describe, expect, it, vi } from 'vitest'
+import type { Ref } from 'vue'
 import { ref } from 'vue'

@@
-  let mockReleaseService: {
-    getReleases: Mock
-    isLoading: ReturnType<typeof ref<boolean>>
-    error: ReturnType<typeof ref<string | null>>
-  }
-  let mockSettingStore: { get: Mock; set: Mock }
-  let mockSystemStatsStore: {
-    systemStats: {
-      system: {
-        comfyui_version: string
-        argv?: string[]
-        [key: string]: unknown
-      }
-      devices?: unknown[]
-    } | null
-    isInitialized: boolean
-    refetchSystemStats: Mock
-    getFormFactor: Mock
-  }
+  type ReleaseService = ReturnType<typeof useReleaseService>
+  type SettingStore = ReturnType<typeof useSettingStore>
+  type SystemStatsStore = ReturnType<typeof useSystemStatsStore>
+
+  let mockReleaseService: ReleaseService
+  let mockSettingStore: SettingStore
+  let mockSystemStatsStore: SystemStatsStore
@@
-    mockReleaseService = {
-      getReleases: vi.fn(),
-      isLoading: ref(false),
-      error: ref(null)
-    }
+    mockReleaseService = {
+      getReleases: vi.fn<ReleaseService['getReleases']>(),
+      isLoading: ref(false) as Ref<boolean>,
+      error: ref<string | null>(null)
+    }

-    mockSettingStore = {
-      get: vi.fn(),
-      set: vi.fn()
-    }
+    mockSettingStore = {
+      get: vi.fn(),
+      set: vi.fn()
+    } as Partial<SettingStore> as SettingStore

-    mockSystemStatsStore = {
+    mockSystemStatsStore = {
       systemStats: {
         system: {
           comfyui_version: '1.0.0'
         }
       },
       isInitialized: true,
       refetchSystemStats: vi.fn(),
       getFormFactor: vi.fn(() => 'git-windows')
-    }
+    } as Partial<SystemStatsStore> as SystemStatsStore
🤖 Fix all issues with AI agents
In
`@src/workbench/extensions/manager/components/manager/packCard/PackCard.test.ts`:
- Around line 3-4: Tests import unused symbols Card and setActivePinia; remove
these unused imports from the PackCard.test.ts file to satisfy static analysis.
Locate the import statements that reference Card and setActivePinia and delete
those identifiers (or the entire import line if it only contains unused symbols)
so there are no unused imports remaining.

DrJKL and others added 5 commits January 27, 2026 23:02
- releaseStore.test.ts: remove 5 dynamic imports, sync beforeEach

- useMinimap.test.ts: static imports for useMinimap and api

- jobOutputCache.test.ts: static imports, uniqueId() for cache isolation

Amp-Thread-ID: https://ampcode.com/threads/T-019bfbc0-fe5e-75d3-b4fb-b7427ef0dada
Co-authored-by: Amp <amp@ampcode.com>
Replace await import() with static imports for mocked modules where module isolation is not required. This simplifies test code and improves readability.

Amp-Thread-ID: https://ampcode.com/threads/T-019bfbe0-e248-7002-9a0a-e36b42bdfbc1
Co-authored-by: Amp <amp@ampcode.com>
- Use createSharedComposable from VueUse for singleton pattern
- Move module-scoped state into reactive refs
- Encapsulate reset() method within the composable
- Update GraphCanvas.vue to use new composable

Amp-Thread-ID: https://ampcode.com/threads/T-019bfc08-b23e-72ed-8d69-fb04e42b4d14
Co-authored-by: Amp <amp@ampcode.com>
Refactor test files to use cleaner mocking approaches:
- Remove redundant vi.hoisted() calls where not needed
- Simplify mock implementations
- Clean up unused imports and variables

Amp-Thread-ID: https://ampcode.com/threads/T-019bfc31-6862-7278-96c3-a17e0b2cb350
Co-authored-by: Amp <amp@ampcode.com>
@DrJKL DrJKL force-pushed the drjkl/mock-yeah-ing-yeah branch from 0eb4a23 to 6cf7e17 Compare January 28, 2026 19:06
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jan 28, 2026
@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Oxfmt formatting

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/components/graph/selectionToolbox/ExecuteButton.test.ts (1)

75-81: vi.clearAllMocks() clears the mock configuration set above it.

Calling vi.clearAllMocks() after mockReturnValue() will reset the mock, causing useSelectionState to return undefined instead of the configured value with mockSelectedNodes. Move vi.clearAllMocks() to the beginning of beforeEach.

🐛 Proposed fix
   beforeEach(() => {
+    vi.clearAllMocks()
+
     // Set up Pinia with testing utilities
     setActivePinia(
       createTestingPinia({
         createSpy: vi.fn
       })
     )

     // Reset mocks
     const partialCanvas: Partial<LGraphCanvas> = {
       setDirty: vi.fn()
     }
     mockCanvas = partialCanvas as Partial<LGraphCanvas> as LGraphCanvas

     mockSelectedNodes = []

     // Get store instances and mock methods
     const canvasStore = useCanvasStore()
     const commandStore = useCommandStore()

     vi.spyOn(canvasStore, 'getCanvas').mockReturnValue(mockCanvas)
     vi.spyOn(commandStore, 'execute').mockResolvedValue()

     // Update the useSelectionState mock
     vi.mocked(useSelectionState).mockReturnValue({
       selectedNodes: {
         value: mockSelectedNodes
       }
     } as ReturnType<typeof useSelectionState>)
-
-    vi.clearAllMocks()
   })
src/workbench/extensions/manager/components/manager/packCard/PackCard.test.ts (2)

133-158: Avoid testing CSS utility classes; test behavior instead.

Tests asserting on .ring-3 and .rounded-lg classes are dependent on implementation details rather than behavior. If the styling implementation changes (e.g., different Tailwind classes or CSS approach), these tests will break even though the visual behavior is unchanged.

Consider testing the user-visible outcome or accessible properties instead:

♻️ Suggested approach
     it('should apply selected ring when isSelected is true', () => {
       const wrapper = createWrapper({
         nodePack: mockNodePack,
         isSelected: true
       })
 
-      expect(wrapper.find('.ring-3').exists()).toBe(true)
+      // Test via aria attribute, data attribute, or computed style if visual distinction is important
+      expect(wrapper.classes()).toContain('ring-3') // If class check is necessary, use classes() on the root
     })
 
-    it('should not apply selected ring when isSelected is false', () => {
-      const wrapper = createWrapper({
-        nodePack: mockNodePack,
-        isSelected: false
-      })
-
-      expect(wrapper.find('.ring-3').exists()).toBe(false)
-    })
+    // Consider removing the negative test - testing absence of a style is low value
   })
 
   describe('component behavior', () => {
     it('should render without errors', () => {
       const wrapper = createWrapper({ nodePack: mockNodePack })
 
       expect(wrapper.exists()).toBe(true)
-      expect(wrapper.find('.rounded-lg').exists()).toBe(true)
     })
   })

As per coding guidelines: "Do not write tests dependent on non-behavioral features like utility classes or styles."


161-178: Consider consolidating redundant tests.

The tests for should display package name, should display package description, and should display author name (lines 162-178) duplicate assertions already made in should render package card with basic information (lines 118-125).

♻️ Suggested consolidation
   describe('package information display', () => {
-    it('should display package name', () => {
-      const wrapper = createWrapper({ nodePack: mockNodePack })
-
-      expect(wrapper.text()).toContain('Test Package')
-    })
-
-    it('should display package description', () => {
-      const wrapper = createWrapper({ nodePack: mockNodePack })
-
-      expect(wrapper.text()).toContain('Test package description')
-    })
-
-    it('should display author name', () => {
-      const wrapper = createWrapper({ nodePack: mockNodePack })
-
-      expect(wrapper.text()).toContain('Test Author')
-    })
-
     it('should handle missing description', () => {
       // ... keep edge case tests
     })

As per coding guidelines: "Do not write redundant tests; be parsimonious in testing."

src/lib/litegraph/src/litegraph.test.ts (1)

11-36: Avoid direct LGraph import; keep barrel-only.

The direct import from @/lib/litegraph/src/LGraph bypasses the barrel export policy and risks circular dependencies. Drop the direct import and its assertion.

♻️ Proposed change
-import { LGraph as DirectLGraph } from '@/lib/litegraph/src/LGraph'
-
 describe('Import order dependency', () => {
   test('Imports reference the same types', ({ expect }) => {
-    // Both imports should reference the same LGraph class
-    expect(LiteGraph.LGraph).toBe(DirectLGraph)
     expect(LiteGraph.LGraph).toBe(LGraph)
   })
 })

Based on learnings: Always import from the barrel export for subgraph code to avoid circular dependencies (import from '@/lib/litegraph/src/litegraph' instead of individual modules like '@/lib/litegraph/src/LGraph').

🤖 Fix all issues with AI agents
In `@docs/testing/unit-testing.md`:
- Around line 317-330: The markdown contains a stray empty fenced code block
that triggers MD040; remove the empty triple-backtick block or give it a
language tag and ensure the intended snippet (the
vi.mocked(useMyComposable).mockReturnValue({ isLoading: ref(false) }) line) is
inside a properly delimited fenced block (e.g., ```typescript) instead of
leaving an empty block; update the section around the examples referencing
mockService, useMyComposable, vi.mocked and beforeEach so there are no
standalone empty triple-backtick fences.

In `@src/platform/updates/common/releaseStore.test.ts`:
- Around line 373-385: The test "should fetch normally when argv is undefined"
(using useReleaseStore, useReleaseService, useSystemStatsStore and mutating
systemStats.system.argv) is flagged as a smell because it violates TypeScript
types; either remove the test if you rely on static types to guarantee argv
presence or convert it into an explicit runtime-safety test: keep it but rename
to indicate it intentionally breaks types (e.g., "handles missing argv at
runtime"), add a comment explaining why we bypass types, and wrap the argv
deletion and expectations in a clearly scoped block so future readers know this
is a deliberate runtime-only guard; update test name and comment or delete the
test accordingly.

In `@src/services/jobOutputCache.test.ts`:
- Around line 17-20: The mock object in the vi.mock call includes an unused
fetchJobDetail mock which should be removed to avoid confusion; update the mock
to only export extractWorkflow (remove the fetchJobDetail property from the
mocked object in jobOutputCache.test.ts) and ensure any imports or references to
fetchJobDetail are removed or updated so the tests only rely on extractWorkflow.

Comment on lines +317 to +330
```typescript
// ❌ Don't configure mock return values in beforeEach with shared variable
let mockService: { doSomething: Mock }
beforeEach(() => {
mockService = { doSomething: vi.fn() }
vi.mocked(useMyComposable).mockReturnValue(mockService)
})

// ❌ Don't auto-mock then override — reactive refs won't work correctly
vi.mock('@/path/to/composable')
vi.mocked(useMyComposable).mockReturnValue({ isLoading: ref(false) })
```

```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the stray fenced block or add a language tag (MD040).
An empty fenced block without a language spec trips markdownlint.

🧹 Proposed fix
-vi.mocked(useMyComposable).mockReturnValue({ isLoading: ref(false) })
-```
-
-```
+vi.mocked(useMyComposable).mockReturnValue({ isLoading: ref(false) })
+```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

330-330: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@docs/testing/unit-testing.md` around lines 317 - 330, The markdown contains a
stray empty fenced code block that triggers MD040; remove the empty
triple-backtick block or give it a language tag and ensure the intended snippet
(the vi.mocked(useMyComposable).mockReturnValue({ isLoading: ref(false) }) line)
is inside a properly delimited fenced block (e.g., ```typescript) instead of
leaving an empty block; update the section around the examples referencing
mockService, useMyComposable, vi.mocked and beforeEach so there are no
standalone empty triple-backtick fences.

Comment on lines 373 to 385
it('should fetch normally when argv is undefined', async () => {
mockSystemStatsStore.systemStats!.system.argv = undefined
mockReleaseService.getReleases.mockResolvedValue([mockRelease])
const store = useReleaseStore()
const releaseService = useReleaseService()
const systemStatsStore = useSystemStatsStore()
// TODO: Consider deleting this test since the types have to be violated for it to be relevant
delete (systemStatsStore.systemStats!.system as { argv?: string[] }).argv
vi.mocked(releaseService.getReleases).mockResolvedValue([mockRelease])

await store.initialize()

expect(mockReleaseService.getReleases).toHaveBeenCalled()
expect(releaseService.getReleases).toHaveBeenCalled()
expect(store.releases).toEqual([mockRelease])
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

The TODO comment appropriately flags a potential test smell.

The comment at line 377 correctly identifies that this test requires violating TypeScript types to be relevant. Consider whether this edge case is worth testing given the type system should prevent argv from being undefined. The test provides runtime safety validation but may be redundant if types are enforced throughout.

🤖 Prompt for AI Agents
In `@src/platform/updates/common/releaseStore.test.ts` around lines 373 - 385, The
test "should fetch normally when argv is undefined" (using useReleaseStore,
useReleaseService, useSystemStatsStore and mutating systemStats.system.argv) is
flagged as a smell because it violates TypeScript types; either remove the test
if you rely on static types to guarantee argv presence or convert it into an
explicit runtime-safety test: keep it but rename to indicate it intentionally
breaks types (e.g., "handles missing argv at runtime"), add a comment explaining
why we bypass types, and wrap the argv deletion and expectations in a clearly
scoped block so future readers know this is a deliberate runtime-only guard;
update test name and comment or delete the test accordingly.

Comment on lines 17 to 20
vi.mock('@/platform/remote/comfyui/jobs/fetchJobs', () => ({
fetchJobDetail: vi.fn(),
extractWorkflow: vi.fn()
}))
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove unused fetchJobDetail mock.

The fetchJobDetail mock is defined but never used in these tests—only extractWorkflow is imported and tested. Keeping unused mocks adds confusion about what the tests actually depend on.

♻️ Suggested fix
 vi.mock('@/platform/remote/comfyui/jobs/fetchJobs', () => ({
-  fetchJobDetail: vi.fn(),
   extractWorkflow: vi.fn()
 }))
📝 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.

Suggested change
vi.mock('@/platform/remote/comfyui/jobs/fetchJobs', () => ({
fetchJobDetail: vi.fn(),
extractWorkflow: vi.fn()
}))
vi.mock('@/platform/remote/comfyui/jobs/fetchJobs', () => ({
extractWorkflow: vi.fn()
}))
🤖 Prompt for AI Agents
In `@src/services/jobOutputCache.test.ts` around lines 17 - 20, The mock object in
the vi.mock call includes an unused fetchJobDetail mock which should be removed
to avoid confusion; update the mock to only export extractWorkflow (remove the
fetchJobDetail property from the mocked object in jobOutputCache.test.ts) and
ensure any imports or references to fetchJobDetail are removed or updated so the
tests only rely on extractWorkflow.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/platform/updates/common/releaseStore.test.ts`:
- Around line 28-39: The mock creates shared mutable refs (isLoading, error)
that persist between tests; update the mock for useReleaseService to return
fresh refs per test or expose a reset helper on the mock (e.g.,
mockReleaseService.reset) that reinitializes isLoading and error, and call that
reset in beforeEach; specifically change the vi.mock for
'@/platform/updates/common/releaseService' so useReleaseService returns new ref
instances each invocation (or provide a reset function alongside
getReleases/isLoading/error) and invoke that reset in the test suite setup to
mirror the mockSystemStatsState.reset pattern.

Comment on lines +28 to +39
vi.mock('@/platform/updates/common/releaseService', () => {
const getReleases = vi.fn()
const isLoading = ref(false)
const error = ref<string | null>(null)
return {
useReleaseService: () => ({
getReleases,
isLoading,
error
})
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Mutable ref state is not reset between tests.

The isLoading and error refs are created once and shared across all tests. Unlike mock functions, Vue refs are not reset by vi.resetAllMocks(). When a test sets releaseService.error.value = 'API Error' (line 390), this value persists into subsequent tests.

Consider adding a reset mechanism similar to mockSystemStatsState.reset():

♻️ Proposed fix
 vi.mock('@/platform/updates/common/releaseService', () => {
   const getReleases = vi.fn()
   const isLoading = ref(false)
   const error = ref<string | null>(null)
+  const reset = () => {
+    isLoading.value = false
+    error.value = null
+  }
   return {
     useReleaseService: () => ({
       getReleases,
       isLoading,
       error
-    })
+    }),
+    __resetReleaseServiceMock: reset
   }
 })

Then in beforeEach:

+import { __resetReleaseServiceMock } from '@/platform/updates/common/releaseService'
+
 beforeEach(() => {
   setActivePinia(createTestingPinia({ stubActions: false }))
   vi.resetAllMocks()
   mockSystemStatsState.reset()
+  __resetReleaseServiceMock()
 })

Based on learnings: "Leverage Vitest utilities for mocking where possible and keep module mocks contained without global mutable state".

🤖 Prompt for AI Agents
In `@src/platform/updates/common/releaseStore.test.ts` around lines 28 - 39, The
mock creates shared mutable refs (isLoading, error) that persist between tests;
update the mock for useReleaseService to return fresh refs per test or expose a
reset helper on the mock (e.g., mockReleaseService.reset) that reinitializes
isLoading and error, and call that reset in beforeEach; specifically change the
vi.mock for '@/platform/updates/common/releaseService' so useReleaseService
returns new ref instances each invocation (or provide a reset function alongside
getReleases/isLoading/error) and invoke that reset in the test suite setup to
mirror the mockSystemStatsState.reset pattern.

@DrJKL DrJKL merged commit e44b411 into main Jan 28, 2026
27 checks passed
@DrJKL DrJKL deleted the drjkl/mock-yeah-ing-yeah branch January 28, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants