Skip to content

fix(web): await automatic license key installation - #2055

Draft
Ajit-Mehrotra wants to merge 1 commit into
mainfrom
codex/fix-install-key-response
Draft

fix(web): await automatic license key installation#2055
Ajit-Mehrotra wants to merge 1 commit into
mainfrom
codex/fix-install-key-response

Conversation

@Ajit-Mehrotra

@Ajit-Mehrotra Ajit-Mehrotra commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Automatic license-key installation could report success before WebGUI answered; this waits for and validates the response so HTTP and network failures reach the existing manual-install recovery flow.

Why This Exists

Wretch 2.11.0 starts the request when .get() is called but returns a non-thenable response-chain. Awaiting that chain without consuming it completed immediately, allowing the store to set keyInstallStatus to success while the HTTP request was still pending.

A later WebGUI 406 response, including download failures, or a fetch rejection then became an unhandled background rejection. The callback stayed successful and users did not see the existing Copy Key URL and Tools > Registration recovery instructions.

Resolution

Consume the Wretch response with .json(), locally rethrow shared request errors into the install store catch path, and accept success only when the response matches { status: "success", message: string }.

This keeps the existing trial action and key URL intact. The change does not retry or reissue a license; it makes the existing fallback reliable.

Reviewer Considerations

  • Review the per-call Error and TypeError rethrow handlers closely. The shared request resolver records those errors and otherwise returns undefined, so this install call overrides them to preserve the original HTTP or fetch failure for its own state transition.
  • Confirm the success contract matches InstallKey.php. Malformed 200 responses now fail closed instead of being treated as successful installs.
  • The related unused WebguiNotify helper has the same unconsumed response-chain pattern but is intentionally outside this PR because no repository callers were found.
  • This does not add download retries or change trial issuance. It only fixes response handling and the existing manual fallback.

Behavior Changes

  • A delayed successful install remains installing until WebGUI responds, then becomes success.
  • HTTP 406 and network failures become failed, resolve callback status to error, and preserve a useful safe error message where available.
  • Failed installs show the existing Copy Key URL action and Tools > Registration instructions.
  • Request failures no longer create unhandled promise rejections.

Implementation Summary

  • Consume and validate the InstallKey.php JSON response before marking installation successful.
  • Preserve safe WebGUI JSON errors such as download failures in the errors store.
  • Add regression tests using the real Wretch response-chain with controlled delayed responses.
  • Extend store and component coverage for invalid success responses, callback failure resolution, retained key URLs, and manual-install UI.

Verification

  • pnpm test __test__/store/installKey.test.ts __test__/store/installKey.wretch.test.ts __test__/store/callbackActions.helpers.test.ts __test__/components/CallbackFeedback.test.ts — 4 files, 50 tests passed.
  • pnpm test — 68 files passed, 660 tests passed, 6 skipped.
  • pnpm codegen — passed.
  • pnpm type-check — passed.
  • pnpm lint — passed.
  • git diff --check — passed.

Risk

Low. The change is isolated to client-side install response handling and tests. It does not change the request URL, key URL, server endpoint, trial issuance, or installation retry behavior. Validation used the installed Wretch version with controlled HTTP responses; a live WebGUI install was not reissued.

Summary by CodeRabbit

  • Bug Fixes

    • Improved key-installation response handling and validation.
    • Installation failures now display clearer, more reliable error messages across invalid responses, server errors, and network failures.
    • Prevented installation requests from leaving the interface in an inconsistent or unresolved state.
    • Added manual recovery guidance for failed trial-key installations, including a Copy Key URL action and a link to Tools > Registration.
  • Tests

    • Expanded coverage for successful, failed, delayed, and network-error installation scenarios.

Purpose:
- Prevent automatic license-key installation from reporting success before WebGUI confirms the result.

Previous behavior:
- Awaiting Wretch .get() returned its response-chain immediately without consuming the HTTP response.

Why this was a problem:
- Delayed HTTP 406 and network failures bypassed the store catch path, produced background rejections, and hid manual-install recovery UI.

New behavior:
- Keep installation pending until a valid success response arrives, and mark HTTP, network, or malformed responses as failed.

How it works:
- Consume the response with .json(), validate the InstallKey.php success contract, preserve safe WebGUI errors, and add real-Wretch plus UI regression coverage.

Verification:
- Pass focused and full web tests, codegen, typecheck, lint, and git diff checks.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The install-key store now validates JSON response shapes, extracts errors consistently, and handles request failures. Tests cover mocked and delayed Wretch responses, invalid payloads, network errors, and manual-install recovery UI guidance.

Changes

Install key handling

Layer / File(s) Summary
Response validation and error handling
web/src/store/installKey.ts
The install action validates unknown responses, rethrows request errors, and derives error messages from supported response and error shapes.
Response contract test coverage
web/__test__/store/installKey.test.ts
Tests now model chained JSON responses, verify installation state and key-type derivation, preserve error cases, and reject invalid response shapes.
Async failure and manual recovery coverage
web/__test__/store/installKey.wretch.test.ts, web/__test__/components/CallbackFeedback.test.ts
Controlled fetch tests cover delayed success, HTTP failures, network rejection, and unhandled-rejection behavior; callback tests verify manual recovery guidance.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant useInstallKeyStore
  participant Wretch
  participant useErrorsStore
  User->>useInstallKeyStore: start key installation
  useInstallKeyStore->>Wretch: request InstallKey.php
  Wretch-->>useInstallKeyStore: JSON response or error
  useInstallKeyStore->>useErrorsStore: store derived error message
  useInstallKeyStore-->>User: success or failed status
Loading

Poem

A rabbit checks the key’s reply,
And catches errors hopping by.
JSON paths are neat and clear,
Recovery links now persevere.
Copy, register—done with cheer!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main behavior change: waiting for automatic license key installation confirmation before success.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-install-key-response

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.

❤️ Share

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

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 53.10%. Comparing base (12c23d8) to head (9c13eb4).

Files with missing lines Patch % Lines
web/src/store/installKey.ts 98.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2055      +/-   ##
==========================================
+ Coverage   53.07%   53.10%   +0.02%     
==========================================
  Files        1041     1041              
  Lines       72425    72467      +42     
  Branches     8354     8371      +17     
==========================================
+ Hits        38440    38480      +40     
- Misses      33858    33860       +2     
  Partials      127      127              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/__test__/store/installKey.wretch.test.ts (1)

54-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clear all mocks between tests.

The cleanup only clears unhandledRejection directly. Add vi.clearAllMocks() so every mock is reset between cases.

Proposed fix
 afterEach(() => {
   process.off('unhandledRejection', unhandledRejection);
+  vi.clearAllMocks();
   vi.unstubAllGlobals();
   vi.restoreAllMocks();
-  unhandledRejection.mockClear();
 });

As per coding guidelines, reset mocks between tests with vi.clearAllMocks().

#!/bin/bash
sed -n '43,62p' web/__test__/store/installKey.wretch.test.ts
rg -n 'vi\.(clearAllMocks|restoreAllMocks|unstubAllGlobals)' web/__test__/store/installKey.wretch.test.ts
🤖 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 `@web/__test__/store/installKey.wretch.test.ts` around lines 54 - 59, Update
the afterEach cleanup hook to call vi.clearAllMocks() so all mocks are reset
between tests, while preserving the existing unhandledRejection cleanup, global
unstubbing, and mock restoration.
web/__test__/components/CallbackFeedback.test.ts (1)

309-309: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Query the copy control semantically.

.brand-button couples this behavior test to a styling class. Prefer the native button selector, or findComponent(BrandButton) if it does not render a button.

As per coding guidelines, use semantic queries such as find('button') and verify element existence in Vue component tests.

#!/bin/bash
fd -HI -t f '^BrandButton\.vue$' web -x sh -c 'echo "--- $1"; rg -n -C2 "<button|<a|brand-button" "$1"' sh {}
sed -n '297,313p' web/__test__/components/CallbackFeedback.test.ts
🤖 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 `@web/__test__/components/CallbackFeedback.test.ts` at line 309, Update the
test around the callback copy control to query it semantically with
find('button') or findComponent(BrandButton) instead of the styling-dependent
'.brand-button' selector, and assert that the queried control exists before
verifying its 'Copy Key URL' text.
🤖 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 `@web/__test__/store/installKey.wretch.test.ts`:
- Around line 7-9: Update the local imports in the installKey test to use `.js`
extensions, including the imports for resolveCallbackStatus, useErrorsStore, and
useInstallKeyStore, while leaving package imports unchanged.

---

Nitpick comments:
In `@web/__test__/components/CallbackFeedback.test.ts`:
- Line 309: Update the test around the callback copy control to query it
semantically with find('button') or findComponent(BrandButton) instead of the
styling-dependent '.brand-button' selector, and assert that the queried control
exists before verifying its 'Copy Key URL' text.

In `@web/__test__/store/installKey.wretch.test.ts`:
- Around line 54-59: Update the afterEach cleanup hook to call
vi.clearAllMocks() so all mocks are reset between tests, while preserving the
existing unhandledRejection cleanup, global unstubbing, and mock restoration.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bd576f5-2dbe-472d-a79e-ce32c373a5a6

📥 Commits

Reviewing files that changed from the base of the PR and between 12c23d8 and 9c13eb4.

📒 Files selected for processing (4)
  • web/__test__/components/CallbackFeedback.test.ts
  • web/__test__/store/installKey.test.ts
  • web/__test__/store/installKey.wretch.test.ts
  • web/src/store/installKey.ts

Comment on lines +7 to +9
import { resolveCallbackStatus } from '~/store/callbackActions.helpers';
import { useErrorsStore } from '~/store/errors';
import { useInstallKeyStore } from '~/store/installKey';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use .js extensions for local ESM imports.

These local TypeScript imports violate the repository ESM import convention.

Proposed fix
-import { resolveCallbackStatus } from '~/store/callbackActions.helpers';
-import { useErrorsStore } from '~/store/errors';
-import { useInstallKeyStore } from '~/store/installKey';
+import { resolveCallbackStatus } from '~/store/callbackActions.helpers.js';
+import { useErrorsStore } from '~/store/errors.js';
+import { useInstallKeyStore } from '~/store/installKey.js';

As per coding guidelines, use .js extensions in TypeScript imports for ESM compatibility.

#!/bin/bash
sed -n '1,15p' web/__test__/store/installKey.wretch.test.ts
fd -HI -t f '^(tsconfig.*\.json|package\.json)$' . -x sh -c 'echo "--- $1"; sed -n "1,180p" "$1"' sh {}
🤖 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 `@web/__test__/store/installKey.wretch.test.ts` around lines 7 - 9, Update the
local imports in the installKey test to use `.js` extensions, including the
imports for resolveCallbackStatus, useErrorsStore, and useInstallKeyStore, while
leaving package imports unchanged.

@github-actions

Copy link
Copy Markdown
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR2055/dynamix.unraid.net.plg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant