Skip to content

fix: preserve Google Workspace domain in alias suggestions - #87

Merged
hoangsvit merged 19 commits into
devfrom
fix/preserve-workspace-alias-domain
Jul 29, 2026
Merged

fix: preserve Google Workspace domain in alias suggestions#87
hoangsvit merged 19 commits into
devfrom
fix/preserve-workspace-alias-domain

Conversation

@hoangsvit

@hoangsvit hoangsvit commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • preserve the selected account domain when generating website-specific aliases;
  • remove the hard-coded @gmail.com suffix from inline helper suggestions;
  • ignore stale website mappings that belong to another account or domain;
  • isolate inline recent history and favorites by the active account, including legacy global-storage fallback data;
  • validate the active email before generating aliases;
  • add browser-storage integration and malformed-data regression tests.

Bug

The inline helper displayed the selected Google Workspace account correctly, but generated suggestions and legacy history could still use Gmail addresses.

Before:

user@company.com
→ user+webike@gmail.com

After:

user@company.com
→ user+webike@company.com

Behavior

  • Website suggestions retain the selected account domain.
  • Previous website aliases are shown only when they belong to the active account.
  • Recent aliases and favorites from legacy storage are filtered before rendering.
  • Malformed emails such as user@localhost or user @gmail.com produce no suggestions.
  • Storage read failures continue to propagate to the existing inline popup error/retry state.

Testing

  • GitHub Actions workflow validation
  • TypeScript compile
  • Unit and browser-storage integration tests
  • Production extension build
  • Production manifest-scope verification
  • Website build
  • CodeRabbit
  • Qodo findings addressed

Notes

This PR targets dev. It does not change package versions, release workflows, tags, or dependencies.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds account-aware inline history loading, integrates it into the content script, and strengthens website alias ownership and suggestion generation for validated Workspace accounts.

Changes

Account-aware alias behavior

Layer / File(s) Summary
Inline history service and coverage
src/services/inlineHistoryService.ts, tests/services/inlineHistoryService.test.ts
Adds typed history loading that normalizes, filters, sorts, and prioritizes account-scoped storage, with tests for isolation and legacy fallback behavior.
History tab service integration
entrypoints/content/index.ts
Routes History-tab loading through loadInlineAccountHistory while preserving existing rendering and error handling.
Website alias validation and suggestions
src/services/websiteAliasService.ts, tests/services/websiteAliasService.test.ts
Rejects cross-account stored aliases, validates base emails, and generates suggestions using the selected account domain through generateAlias.

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

Sequence Diagram(s)

sequenceDiagram
  participant HistoryTab
  participant loadInlineAccountHistory
  participant browser.storage.local
  HistoryTab->>loadInlineAccountHistory: load active account history
  loadInlineAccountHistory->>browser.storage.local: read scoped and legacy values
  browser.storage.local-->>loadInlineAccountHistory: stored history and favorites
  loadInlineAccountHistory-->>HistoryTab: return filtered history and favorites
Loading

Possibly related PRs

Suggested reviewers: eplus-bot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: preserving the Workspace domain in generated alias suggestions.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/preserve-workspace-alias-domain

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

@eplus-bot

Copy link
Copy Markdown
Contributor

Thank you for creating this pull request and helping make the project better.

We will review / merge it when we are online.

@eplus-bot eplus-bot added needs-review Pull request is ready for maintainer review app Application or extension source code tests Test coverage or test tooling changes labels Jul 29, 2026
@eplus-bot
eplus-bot self-requested a review July 29, 2026 03:48

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30420555375

@eplus-bot

eplus-bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

CI passed

Approved by @eplus-bot after all pull request checks passed.

Approval refresh: #8
CI updated: 2026-07-29T04:18:15Z
CI attempt: #1
Approval workflow: #425.1

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30421865510

@qodo-code-review

qodo-code-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

PR Summary by Qodo

Preserve Workspace domains and isolate inline alias history

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Preserve active Workspace domains when generating website-specific aliases.
• Reject malformed emails and prevent aliases from leaking across accounts.
• Isolate and validate inline history with legacy-storage compatibility.
Diagram

graph TD
  C["Inline Popup"] --> W["Alias Service"] --> U["Account Utilities"]
  C --> H["History Service"] --> U
  W --> S[("Browser Storage")]
  H --> S
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Migrate legacy storage eagerly
  • ➕ Removes legacy fallback logic after migration
  • ➕ Keeps runtime reads limited to account-scoped keys
  • ➖ Legacy global entries may not have unambiguous account ownership
  • ➖ Adds migration state, failure handling, and rollback complexity
2. Relocate account utilities into src
  • ➕ Removes service dependencies on the popup entrypoint
  • ➕ Creates a cleaner shared domain layer for extension components
  • ➖ Broadens this targeted bug fix into a cross-cutting refactor
  • ➖ Requires updating and retesting additional import sites

Recommendation: Keep the PR's runtime filtering and scoped-key precedence for this fix because it safely preserves compatible legacy data while preventing cross-account leakage. Consider relocating shared account utilities from the popup entrypoint into src in a follow-up architectural cleanup.

Files changed (5) +400 / -66

Bug fix (2) +129 / -19
inlineHistoryService.tsAdd account-isolated inline history loading +104/-0

Add account-isolated inline history loading

• Introduces a service that prefers account-scoped storage while retaining legacy-key fallback. It validates stored values, normalizes favorite formats, filters aliases by active account, and sorts history newest-first.

src/services/inlineHistoryService.ts

websiteAliasService.tsPreserve active domains and reject foreign website aliases +25/-19

Preserve active domains and reject foreign website aliases

• Uses shared email validation and alias generation so suggestions retain the selected account domain and malformed addresses return no results. Previously stored website aliases are returned only when they belong to the active account.

src/services/websiteAliasService.ts

Refactor (1) +4 / -34
index.tsDelegate inline history loading to the account-aware service +4/-34

Delegate inline history loading to the account-aware service

• Replaces embedded browser-storage parsing with loadInlineAccountHistory for the popup's active email. The content entrypoint now consumes normalized, account-isolated history and favorites.

entrypoints/content/index.ts

Tests (2) +267 / -13
inlineHistoryService.test.tsCover Workspace history isolation and malformed storage +183/-0

Cover Workspace history isolation and malformed storage

• Adds tests for scoped and legacy storage, cross-account filtering, scoped-key precedence, sorting, mixed favorite formats, and malformed values.

tests/services/inlineHistoryService.test.ts

websiteAliasService.test.tsAdd Workspace domain and account-isolation regressions +84/-13

Add Workspace domain and account-isolation regressions

• Adds coverage for preserving Workspace domains, rejecting malformed base emails, and ignoring stale aliases owned by another account. The popup utility mock now retains real alias helpers and overrides only storage-key generation.

tests/services/websiteAliasService.test.ts

@qodo-code-review

qodo-code-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. createPopupUtilsMock return type omitted ✓ Resolved 📘 Rule violation ⚙ Maintainability ⭐ New JS-D1001; JS-0356; JS-0437
Description
The new createPopupUtilsMock function relies on an inferred return type, which triggers the
checklist’s JS-D1001 explicit-return-type requirement. This prevents the change from satisfying the
required DeepSource checks.
Code

tests/services/websiteAliasService.test.ts[58]

+async function createPopupUtilsMock(importOriginal: ImportOriginal) {
Evidence
Compliance rule 1 requires zero DeepSource issues, including JS-D1001. The newly declared async
function at line 58 has no explicit return type, unlike the other new function declarations.

Rule JS-D1001; JS-0356; JS-0437: Pass DeepSource Checks and Document Every Function and Component
tests/services/websiteAliasService.test.ts[57-67]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`createPopupUtilsMock` lacks an explicit return type and therefore violates the JS-D1001 DeepSource requirement.

## Issue Context
The function asynchronously returns the popup utilities module with `getAccountStorageKey` overridden. Declare a compatible `Promise` return type without changing the mock behavior.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[58-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. History parser edges untested ✓ Resolved 📘 Rule violation ☼ Reliability ⭐ New
Description
The new service explicitly handles malformed and non-array storage values, but its tests only
register valid array-based, account-filtering, and precedence scenarios. Missing malformed-shape
tests leave relevant parser edge and boundary behavior unverified.
Code

tests/services/inlineHistoryService.test.ts[R117-128]

+  it(
+    "filters account-scoped history and favorites by active Workspace account",
+    assertScopedWorkspaceHistoryIsIsolated,
+  );
+  it(
+    "filters legacy history and favorites by active Workspace account",
+    assertLegacyWorkspaceHistoryIsIsolated,
+  );
+  it(
+    "prefers account-scoped storage over legacy global storage",
+    assertScopedStorageTakesPrecedence,
+  );
Evidence
Compliance rule 4 requires changed service behavior to cover applicable errors, edge cases, and
boundaries. The service contains explicit branches for non-array storage values and malformed
history/favorite entries, while the three registered tests do not exercise those malformed parser
inputs.

CLAUDE.md: Provide Organized Tests for New and Changed Behavior
src/services/inlineHistoryService.ts[20-68]
tests/services/inlineHistoryService.test.ts[117-128]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The inline history service tests omit malformed storage shapes handled by the new parsing functions.

## Issue Context
Add organized cases for non-array history and favorites, malformed history objects such as missing or nonnumeric timestamps, and malformed favorite objects or empty strings. Continue using the existing mocked `browser.storage.local` fixture and reset state through `beforeEach`.

## Fix Focus Areas
- tests/services/inlineHistoryService.test.ts[33-131]
- src/services/inlineHistoryService.ts[20-68]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. History filtering lacks interaction tests 📘 Rule violation ☼ Reliability
Description
The popup now filters browser-stored history by active account, but no interaction test exercises
this loadHistory() path or verifies its rendered result. Utility-only coverage does not verify the
browser storage and component integration required by the checklist.
Code

entrypoints/content/index.ts[R737-740]

+      currentHistory = filterAliasesForAccount(
+        validHistory,
+        data.activeEmail,
+      )
Evidence
PR Compliance ID 4 requires interaction coverage for changed component logic and mocked browser
integrations. Lines 737-740 introduce account filtering inside the browser-backed popup history
flow, while the test suite contains no test invoking loadHistory() or its rendered history
behavior.

CLAUDE.md: Provide Organized Tests for New and Changed Behavior
entrypoints/content/index.ts[721-740]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new account-scoped history filtering in the content popup lacks an interaction test covering storage retrieval and rendering.

## Issue Context
PR Compliance ID 4 requires changed component behavior and browser API integrations to be tested with appropriately mocked external dependencies. Add a test that supplies mixed-account history through mocked `browser.storage.local`, opens or refreshes the History view, and verifies only aliases belonging to `data.activeEmail` are rendered.

## Fix Focus Areas
- entrypoints/content/index.ts[737-740]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (6)
4. Stale-alias test callback undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new stale-alias test's asynchronous arrow callback has no one-line JSDoc purpose description.
This violates the documentation requirement for every arrow function.
Code

tests/services/websiteAliasService.test.ts[156]

+    it("ignores a stale website alias owned by another account", async () => {
Evidence
PR Compliance ID 1 requires all arrow functions to have a one-line JSDoc description, but the added
it() callback is undocumented.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
tests/services/websiteAliasService.test.ts[156-168]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The asynchronous callback introduced for the stale website-alias test lacks required JSDoc documentation.

## Issue Context
PR Compliance ID 1 applies the one-line JSDoc requirement to every arrow function, including test callbacks.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[156-156]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. History filter callback undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new history.filter() arrow function has no one-line JSDoc purpose description. This violates
the explicit documentation requirement for every arrow function.
Code

entrypoints/content/index.ts[R734-736]

+      const validHistory = history.filter(
+        (item) => item && typeof item.email === "string",
+      );
Evidence
PR Compliance ID 1 requires every arrow function to have a one-line JSDoc purpose description, while
the newly added history.filter() callback is undocumented.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
entrypoints/content/index.ts[734-736]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new inline history-filtering arrow function lacks the JSDoc required for every arrow function.

## Issue Context
PR Compliance ID 1 requires every arrow function to have at least a one-line JSDoc purpose description. Refactor the callback into a documented function if inline JSDoc would reduce readability.

## Fix Focus Areas
- entrypoints/content/index.ts[734-736]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Favorite callbacks undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new map() and filter() callbacks used to normalize favorite entries have no one-line JSDoc
purpose descriptions. These callbacks violate the documentation requirement for every arrow
function.
Code

entrypoints/content/index.ts[R748-752]

+            .map((favorite) => ({
+              email:
+                typeof favorite === "string" ? favorite : favorite.email || "",
+            }))
+            .filter((favorite) => Boolean(favorite.email))
Evidence
PR Compliance ID 1 explicitly requires every arrow function to be documented; the added favorite
map() and filter() callbacks have no JSDoc.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
entrypoints/content/index.ts[748-752]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly added favorite normalization and validation arrow functions lack required JSDoc purpose descriptions.

## Issue Context
PR Compliance ID 1 requires documentation for every arrow function. Add suitable JSDoc or replace the inline callbacks with documented named functions.

## Fix Focus Areas
- entrypoints/content/index.ts[748-752]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Workspace test arrows lack JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The added Workspace-domain test callback and its forEach callback lack purpose-describing JSDoc
comments. Both newly introduced arrow functions violate the documentation requirement.
Code

tests/services/websiteAliasService.test.ts[R276-287]

+    it("preserves the selected Google Workspace domain", async () => {
+      const workspaceEmail = "nguyen.minh.hoang@rivercrane.vn";
      const suggestions = await generateSuggestionsForWebsite(
-        "user@example.com",
+        workspaceEmail,
        "https://github.com",
      );

-      // Suggestions always use @gmail.com, not the original email domain
-      suggestions.forEach((s) => expect(s).toMatch(/@gmail\.com$/));
+      expect(suggestions).toContain(
+        "nguyen.minh.hoang+github@rivercrane.vn",
+      );
+      suggestions.forEach((suggestion) =>
+        expect(suggestion).toMatch(/@rivercrane\.vn$/),
Evidence
PR Compliance ID 1 requires JSDoc for every arrow function. The asynchronous callback at line 276
and the forEach callback at line 286 are both newly added and undocumented.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[276-287]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Workspace-domain regression test introduces undocumented arrow functions for the test body and domain assertion callback.

## Issue Context
PR Compliance ID 1 requires purpose-describing JSDoc for all arrow functions, including test and collection callbacks.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[276-287]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Malformed-email test lacks JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The newly added asynchronous callback for the malformed-email test has no purpose-describing JSDoc
comment. This introduces an undocumented arrow function.
Code

tests/services/websiteAliasService.test.ts[193]

+    it("returns empty array for malformed base email", async () => {
Evidence
PR Compliance ID 1 requires every arrow function to have purpose-describing JSDoc. Line 193 adds an
undocumented asynchronous test callback.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[193-193]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The malformed-base-email test introduces an asynchronous arrow callback without the required JSDoc comment.

## Issue Context
PR Compliance ID 1 applies to every arrow function, including callbacks passed to `it()`.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[193-193]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. vi.mock arrows lack JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The added asynchronous mock factory and getAccountStorageKey arrow function have no
purpose-describing JSDoc comments. Both violate the requirement to document every arrow function.
Code

tests/services/websiteAliasService.test.ts[R51-59]

+vi.mock("../../entrypoints/popup/utils", async (importOriginal) => {
+  const original = await importOriginal<
+    typeof import("../../entrypoints/popup/utils")
+  >();
+
+  return {
+    ...original,
+    getAccountStorageKey: (email: string, suffix: string) => `${email}:${suffix}`,
+  };
Evidence
PR Compliance ID 1 requires JSDoc for every arrow function. The added mock factory at line 51 and
nested arrow function at line 58 are undocumented.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[51-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly added mock factory and mocked `getAccountStorageKey` arrow function lack required purpose-describing JSDoc comments.

## Issue Context
PR Compliance ID 1 requires every arrow function, including test and mock callbacks, to have at least a one-line JSDoc comment.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[51-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

10. Malformed emails still accepted ✓ Resolved 🐞 Bug ≡ Correctness
Description
generateSuggestionsForWebsite treats a successful generateAlias call as email validation, but
that helper accepts malformed values such as user@localhost and user @gmail.com. These values
produce invalid inline suggestions instead of the required empty array.
Code

src/services/websiteAliasService.ts[80]

+  if (!normalized || !generateAlias(baseEmail, normalized)) return [];
Evidence
The shared alias helper only splits on @ and checks that both pieces are non-empty, while the
repository's validator rejects whitespace and domains without a dot. The content entrypoint directly
exposes this service's results as inline suggestions, and the added regression test only covers a
value with no @, leaving malformed-but-structurally-splittable inputs accepted.

entrypoints/popup/utils.ts[57-65]
entrypoints/popup/utils.ts[176-205]
entrypoints/content/index.ts[162-175]
tests/services/websiteAliasService.test.ts[193-199]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`generateSuggestionsForWebsite` uses `generateAlias` as a malformed-email guard, although that helper only verifies that the input has one `@` and non-empty components. Validate the base email using the repository's full email-validation rules before constructing suggestions.

Add regression coverage for malformed values that still contain `@`, such as `user@localhost` and `user @gmail.com`, and verify they return no suggestions.

## Issue Context
Keep using `generateAlias` to construct aliases and preserve the selected account domain; only replace or strengthen the initial validity check.

## Fix Focus Areas
- src/services/websiteAliasService.ts[79-87]
- entrypoints/popup/utils.ts[176-205]
- tests/services/websiteAliasService.test.ts[184-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Previous review results

Review updated until commit 7c71b38

Results up to commit 596ee9f ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. Workspace test arrows lack JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The added Workspace-domain test callback and its forEach callback lack purpose-describing JSDoc
comments. Both newly introduced arrow functions violate the documentation requirement.
Code

tests/services/websiteAliasService.test.ts[R276-287]

+    it("preserves the selected Google Workspace domain", async () => {
+      const workspaceEmail = "nguyen.minh.hoang@rivercrane.vn";
      const suggestions = await generateSuggestionsForWebsite(
-        "user@example.com",
+        workspaceEmail,
        "https://github.com",
      );

-      // Suggestions always use @gmail.com, not the original email domain
-      suggestions.forEach((s) => expect(s).toMatch(/@gmail\.com$/));
+      expect(suggestions).toContain(
+        "nguyen.minh.hoang+github@rivercrane.vn",
+      );
+      suggestions.forEach((suggestion) =>
+        expect(suggestion).toMatch(/@rivercrane\.vn$/),
Evidence
PR Compliance ID 1 requires JSDoc for every arrow function. The asynchronous callback at line 276
and the forEach callback at line 286 are both newly added and undocumented.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[276-287]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Workspace-domain regression test introduces undocumented arrow functions for the test body and domain assertion callback.

## Issue Context
PR Compliance ID 1 requires purpose-describing JSDoc for all arrow functions, including test and collection callbacks.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[276-287]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. vi.mock arrows lack JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The added asynchronous mock factory and getAccountStorageKey arrow function have no
purpose-describing JSDoc comments. Both violate the requirement to document every arrow function.
Code

tests/services/websiteAliasService.test.ts[R51-59]

+vi.mock("../../entrypoints/popup/utils", async (importOriginal) => {
+  const original = await importOriginal<
+    typeof import("../../entrypoints/popup/utils")
+  >();
+
+  return {
+    ...original,
+    getAccountStorageKey: (email: string, suffix: string) => `${email}:${suffix}`,
+  };
Evidence
PR Compliance ID 1 requires JSDoc for every arrow function. The added mock factory at line 51 and
nested arrow function at line 58 are undocumented.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[51-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly added mock factory and mocked `getAccountStorageKey` arrow function lack required purpose-describing JSDoc comments.

## Issue Context
PR Compliance ID 1 requires every arrow function, including test and mock callbacks, to have at least a one-line JSDoc comment.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[51-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Malformed-email test lacks JSDoc ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001
Description
The newly added asynchronous callback for the malformed-email test has no purpose-describing JSDoc
comment. This introduces an undocumented arrow function.
Code

tests/services/websiteAliasService.test.ts[193]

+    it("returns empty array for malformed base email", async () => {
Evidence
PR Compliance ID 1 requires every arrow function to have purpose-describing JSDoc. Line 193 adds an
undocumented asynchronous test callback.

Rule JS-D1001: Document All Functions, Arrow Functions, and Exported Components with JSDoc
tests/services/websiteAliasService.test.ts[193-193]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The malformed-base-email test introduces an asynchronous arrow callback without the required JSDoc comment.

## Issue Context
PR Compliance ID 1 applies to every arrow function, including callbacks passed to `it()`.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[193-193]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended
4. Malformed emails still accepted ✓ Resolved 🐞 Bug ≡ Correctness
Description
generateSuggestionsForWebsite treats a successful generateAlias call as email validation, but
that helper accepts malformed values such as user@localhost and user @gmail.com. These values
produce invalid inline suggestions instead of the required empty array.
Code

src/services/websiteAliasService.ts[80]

+  if (!normalized || !generateAlias(baseEmail, normalized)) return [];
Evidence
The shared alias helper only splits on @ and checks that both pieces are non-empty, while the
repository's validator rejects whitespace and domains without a dot. The content entrypoint directly
exposes this service's results as inline suggestions, and the added regression test only covers a
value with no @, leaving malformed-but-structurally-splittable inputs accepted.

entrypoints/popup/utils.ts[57-65]
entrypoints/popup/utils.ts[176-205]
entrypoints/content/index.ts[162-175]
tests/services/websiteAliasService.test.ts[193-199]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`generateSuggestionsForWebsite` uses `generateAlias` as a malformed-email guard, although that helper only verifies that the input has one `@` and non-empty components. Validate the base email using the repository's full email-validation rules before constructing suggestions.

Add regression coverage for malformed values that still contain `@`, such as `user@localhost` and `user @gmail.com`, and verify they return no suggestions.

## Issue Context
Keep using `generateAlias` to construct aliases and preserve the selected account domain; only replace or strengthen the initial validity check.

## Fix Focus Areas
- src/services/websiteAliasService.ts[79-87]
- entrypoints/popup/utils.ts[176-205]
- tests/services/websiteAliasService.test.ts[184-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 4c13406 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. Stale-alias test callback undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new stale-alias test's asynchronous arrow callback has no one-line JSDoc purpose description.
This violates the documentation requirement for every arrow function.
Code

tests/services/websiteAliasService.test.ts[156]

+    it("ignores a stale website alias owned by another account", async () => {
Evidence
PR Compliance ID 1 requires all arrow functions to have a one-line JSDoc description, but the added
it() callback is undocumented.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
tests/services/websiteAliasService.test.ts[156-168]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The asynchronous callback introduced for the stale website-alias test lacks required JSDoc documentation.

## Issue Context
PR Compliance ID 1 applies the one-line JSDoc requirement to every arrow function, including test callbacks.

## Fix Focus Areas
- tests/services/websiteAliasService.test.ts[156-156]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. History filter callback undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new history.filter() arrow function has no one-line JSDoc purpose description. This violates
the explicit documentation requirement for every arrow function.
Code

entrypoints/content/index.ts[R734-736]

+      const validHistory = history.filter(
+        (item) => item && typeof item.email === "string",
+      );
Evidence
PR Compliance ID 1 requires every arrow function to have a one-line JSDoc purpose description, while
the newly added history.filter() callback is undocumented.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
entrypoints/content/index.ts[734-736]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new inline history-filtering arrow function lacks the JSDoc required for every arrow function.

## Issue Context
PR Compliance ID 1 requires every arrow function to have at least a one-line JSDoc purpose description. Refactor the callback into a documented function if inline JSDoc would reduce readability.

## Fix Focus Areas
- entrypoints/content/index.ts[734-736]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Favorite callbacks undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability JS-D1001, JS-0356, JS-0437
Description
The new map() and filter() callbacks used to normalize favorite entries have no one-line JSDoc
purpose descriptions. These callbacks violate the documentation requirement for every arrow
function.
Code

entrypoints/content/index.ts[R748-752]

+            .map((favorite) => ({
+              email:
+                typeof favorite === "string" ? favorite : favorite.email || "",
+            }))
+            .filter((favorite) => Boolean(favorite.email))
Evidence
PR Compliance ID 1 explicitly requires every arrow function to be documented; the added favorite
map() and filter() callbacks have no JSDoc.

Rule JS-D1001, JS-0356, JS-0437: Pass All DeepSource Code Quality Checks
entrypoints/content/index.ts[748-752]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly added favorite normalization and validation arrow functions lack required JSDoc purpose descriptions.

## Issue Context
PR Compliance ID 1 requires documentation for every arrow function. Add suitable JSDoc or replace the inline callbacks with documented named functions.

## Fix Focus Areas
- entrypoints/content/index.ts[748-752]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. History filtering lacks interaction tests 📘 Rule violation ☼ Reliability
Description
The popup now filters browser-stored history by active account, but no interaction test exercises
this loadHistory() path or verifies its rendered result. Utility-only coverage does not verify the
browser storage and component integration required by the checklist.
Code

entrypoints/content/index.ts[R737-740]

+      currentHistory = filterAliasesForAccount(
+        validHistory,
+        data.activeEmail,
+      )
Evidence
PR Compliance ID 4 requires interaction coverage for changed component logic and mocked browser
integrations. Lines 737-740 introduce account filtering inside the browser-backed popup history
flow, while the test suite contains no test invoking loadHistory() or its rendered history
behavior.

CLAUDE.md: Provide Organized Tests for New and Changed Behavior
entrypoints/content/index.ts[721-740]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new account-scoped history filtering in the content popup lacks an interaction test covering storage retrieval and rendering.

## Issue Context
PR Compliance ID 4 requires changed component behavior and browser API integrations to be tested with appropriately mocked external dependencies. Add a test that supplies mixed-account history through mocked `browser.storage.local`, opens or refreshes the History view, and verifies only aliases belonging to `data.activeEmail` are rendered.

## Fix Focus Areas
- entrypoints/content/index.ts[737-740]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread tests/services/websiteAliasService.test.ts Outdated
Comment thread tests/services/websiteAliasService.test.ts Outdated
Comment thread tests/services/websiteAliasService.test.ts Outdated
Comment thread src/services/websiteAliasService.ts Outdated
@eplus-bot
eplus-bot self-requested a review July 29, 2026 03:51

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30420694028

@eplus-bot
eplus-bot self-requested a review July 29, 2026 03:53
@eplus-bot eplus-bot added the build-ci Build, CI, release, or project configuration label Jul 29, 2026
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30420959771

@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30421479147

Comment thread tests/services/websiteAliasService.test.ts Outdated
Comment thread tests/services/inlineHistoryService.test.ts
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 301e063

@hoangsvit

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@eplus-bot
eplus-bot self-requested a review July 29, 2026 04:12
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026

@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

🤖 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/services/inlineHistoryService.test.ts`:
- Around line 114-131: Add a test within defineInlineHistoryServiceTests that
mocks browser.storage.local.get to reject and asserts loadInlineAccountHistory()
propagates the rejection. Preserve resetMockStorage cleanup and the existing
successful-read coverage.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d394005b-09bc-400b-99a6-c72f74c1d794

📥 Commits

Reviewing files that changed from the base of the PR and between 65282dc and 301e063.

📒 Files selected for processing (5)
  • entrypoints/content/index.ts
  • src/services/inlineHistoryService.ts
  • src/services/websiteAliasService.ts
  • tests/services/inlineHistoryService.test.ts
  • tests/services/websiteAliasService.test.ts

Comment thread tests/services/inlineHistoryService.test.ts
@hoangsvit hoangsvit closed this Jul 29, 2026
@hoangsvit hoangsvit reopened this Jul 29, 2026

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30421753283

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit b70a116

@eplus-bot
eplus-bot self-requested a review July 29, 2026 04:17

@eplus-bot eplus-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.

Approved by @eplus-bot after all pull request checks passed.

CI run: https://github.com/ePlus-DEV/gmail-alias-toolkit/actions/runs/30421865510

@hoangsvit
hoangsvit merged commit 63c969f into dev Jul 29, 2026
5 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for helping make Gmail Alias Toolkit better!

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

Labels

app Application or extension source code build-ci Build, CI, release, or project configuration needs-review Pull request is ready for maintainer review tests Test coverage or test tooling changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants