Skip to content

test: improve coverage for services, utils, and components (issue #69) - #80

Merged
CodeWithMa merged 8 commits into
CodeWithMa:devfrom
CodeWithMaBot:improve-test-coverage-69
Aug 4, 2026
Merged

test: improve coverage for services, utils, and components (issue #69)#80
CodeWithMa merged 8 commits into
CodeWithMa:devfrom
CodeWithMaBot:improve-test-coverage-69

Conversation

@CodeWithMaBot

@CodeWithMaBot CodeWithMaBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

fixes #69

Summary by CodeRabbit

  • Tests
    • Added comprehensive automated coverage for season management, settings, group operations, data import/export, watch list functionality, form utilities, and round-robin processing to improve reliability and stability.
    • Expanded validation for edge cases, error handling, data persistence, ordering, history preservation, and import/export workflows.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

@CodeWithMaBot is attempting to deploy a commit to the Ma's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This change expands tests for Angular components, IndexedDB-backed services, import/export workflows, watch-list state, and form utilities. Tests cover normal behavior, validation, error handling, persistence, and computed state.

Changes

Coverage Test Expansion

Layer / File(s) Summary
Component behavior tests
src/app/components/season-editor/season-editor.component.spec.ts, src/app/components/settings/settings.component.spec.ts
Tests cover season editing, settings import/export workflows, error handling, and mock cleanup.
Group service storage tests
src/app/services/group.service.spec.ts
Tests cover fake IndexedDB setup, group ordering, creation, updates, deletion reassignment, reordering, lookup, and fixture construction.
Import and export workflow tests
src/app/services/import-export.service.spec.ts
Tests cover JSON import, downloads, recovery backups, DOM operations, and error propagation.
Watch-list state tests
src/app/services/watch-list.service.spec.ts, src/app/services/round-robin.service.spec.ts
Tests cover item lifecycle operations, watch-status transitions, history lookup, computed signals, and shared schema-version fixtures.
Form utility validation tests
src/app/utils/form.utils.spec.ts
Tests cover positive-number parsing, optional values, and date-string validation.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR improves coverage for most named targets but does not add tests for list.service.ts and its core listing and pagination logic. Add focused tests for list.service.ts, including core listing and pagination logic, or update the linked issue scope.
Out of Scope Changes check ⚠️ Warning The watch-list and round-robin test changes are not identified in issue #69, which names different coverage targets. Remove unrelated watch-list and round-robin changes, or document them with linked issue requirements.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the added coverage for services, utilities, and components.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
src/app/services/import-export.service.spec.ts (1)

35-46: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert the serialized Blob payload in both download tests.

The tests verify filenames and DOM calls, but they can pass when downloadJson serializes the wrong object. Inspect the Blob passed to createObjectURL, then assert its JSON content. Also assert that exportData calls storageService.getData.

  • src/app/services/import-export.service.spec.ts#L35-L46: assert storageService.getData was called and validate the exported Blob content.
  • src/app/services/import-export.service.spec.ts#L62-L71: retain createObjectURL from mockDownload() and validate the recovery-backup Blob content.
🤖 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 `@src/app/services/import-export.service.spec.ts` around lines 35 - 46, The
export tests in src/app/services/import-export.service.spec.ts at lines 35-46
(anchor) and 62-71 (sibling) verify DOM interactions and filenames but do not
validate the actual Blob content passed to createObjectURL. At the anchor site,
add an assertion that storageService.getData was called, then extract the Blob
argument from the createObjectURL call and assert that its JSON content matches
the expected export structure (the data returned by storageService.getData). At
the sibling site, retain the createObjectURL reference from mockDownload() and
similarly validate the Blob content to ensure the recovery-backup is serialized
correctly. This prevents the tests from passing when downloadJson serializes the
wrong object.
🤖 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 `@src/app/components/season-editor/season-editor.component.spec.ts`:
- Around line 44-55: Update the “handles non-contiguous season numbers” test
fixture to include seasons 1 and 3, then add one season and assert the new
season number is 4, ensuring the test distinguishes maximum-plus-one behavior
from length-plus-one behavior.

In `@src/app/components/settings/settings.component.spec.ts`:
- Around line 223-234: Both test cases are testing clearing/cleanup operations
but start with already-cleared state, so they pass without proving the cleanup
path executed. At
src/app/components/settings/settings.component.spec.ts#L223-L234 (anchor),
initialize target.value to a non-empty string before calling onFileSelected with
the empty-value cancellation target, then assert that the component clears it to
an empty string. At
src/app/components/settings/settings.component.spec.ts#L274-L283 (sibling), seed
the recoveryBackups signal with a valid backup entry and ensure
getRecoveryBackups() runs to populate it, then verify that the failure path
clears the signal instead of testing the already-empty state.

In `@src/app/services/group.service.spec.ts`:
- Around line 84-102: The deleteGroup test should verify that unrelated groups
and their items are preserved. Extend the test data with a second non-target
group, assign untouched to that group, and assert after
service.deleteGroup('films') that the second group still exists and
untouched.groupId remains its original group ID, while retaining the existing
assertions for the deleted group and moved items.

In `@src/app/services/watch-list.service.spec.ts`:
- Around line 75-81: Update the missing status-transition tests in
src/app/services/watch-list.service.spec.ts lines 237-243 to use a non-empty
fixture and assert storageService.getData() remains unchanged after all three
calls. The existing deleteItem missing-item test at
src/app/services/watch-list.service.spec.ts lines 75-81 already performs the
required unchanged-state assertion and needs no direct change.

In `@src/app/utils/form.utils.spec.ts`:
- Around line 19-23: Rename the affected test descriptions around
toPositiveNumber from “positive integers” to “positive numbers” so they
accurately reflect that decimal values such as 3.5 are accepted.

---

Nitpick comments:
In `@src/app/services/import-export.service.spec.ts`:
- Around line 35-46: The export tests in
src/app/services/import-export.service.spec.ts at lines 35-46 (anchor) and 62-71
(sibling) verify DOM interactions and filenames but do not validate the actual
Blob content passed to createObjectURL. At the anchor site, add an assertion
that storageService.getData was called, then extract the Blob argument from the
createObjectURL call and assert that its JSON content matches the expected
export structure (the data returned by storageService.getData). At the sibling
site, retain the createObjectURL reference from mockDownload() and similarly
validate the Blob content to ensure the recovery-backup is serialized correctly.
This prevents the tests from passing when downloadJson serializes the wrong
object.
🪄 Autofix

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: 91947da7-61c8-4a2e-9e01-047afaa9c6c5

📥 Commits

Reviewing files that changed from the base of the PR and between f8d1455 and 949103d.

📒 Files selected for processing (6)
  • src/app/components/season-editor/season-editor.component.spec.ts
  • src/app/components/settings/settings.component.spec.ts
  • src/app/services/group.service.spec.ts
  • src/app/services/import-export.service.spec.ts
  • src/app/services/watch-list.service.spec.ts
  • src/app/utils/form.utils.spec.ts

Comment thread src/app/components/season-editor/season-editor.component.spec.ts
Comment thread src/app/components/settings/settings.component.spec.ts
Comment thread src/app/services/group.service.spec.ts
Comment thread src/app/services/watch-list.service.spec.ts Outdated
Comment thread src/app/utils/form.utils.spec.ts Outdated
- Fix non-contiguous season test to use truly non-contiguous data (1, 3)
- Verify unrelated groups preserved in deleteGroup test
- Add existing item and assertion in status-transition no-op test
- Initialize target.value with non-empty string in import cancellation test
- Rename 'positive integers' to 'positive numbers' in form utils tests
- Assert Blob content in import-export download tests
- watch-list.service.spec.ts: schemaVersion 3 -> CURRENT_SCHEMA_VERSION
- group.service.spec.ts: schemaVersion 4 -> CURRENT_SCHEMA_VERSION
- round-robin.service.spec.ts: schemaVersion 4 -> CURRENT_SCHEMA_VERSION

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
src/app/components/settings/settings.component.spec.ts (1)

274-285: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Seed the recovery-backup signal before testing failure cleanup.

The test still asserts an empty signal after getRecoveryBackups() fails, but it does not prove that stale backups were cleared. Seed a valid backup before the failure, then assert that the signal becomes empty. The new errorMessage() assertion checks a separate behavior.

🤖 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 `@src/app/components/settings/settings.component.spec.ts` around lines 274 -
285, To prove that stale backups are cleared when loading fails, first seed the
recoveryBackups signal with valid backup data before creating the fixture and
triggering the getRecoveryBackups failure. After the fixture is created and
stable, assert that recoveryBackups() becomes empty, demonstrating the clearing
behavior. Keep the existing errorMessage() assertion unchanged to verify that
separate concern.
🧹 Nitpick comments (2)
src/app/services/import-export.service.spec.ts (2)

80-80: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Use CURRENT_SCHEMA_VERSION for the recovery fixture.

Line 80 hardcodes schemaVersion: 1. If the schema changes, this test still passes because ImportExportService.exportRecoveryBackup only serializes the value returned by StorageService. Use CURRENT_SCHEMA_VERSION, or define this as an explicit legacy-backup fixture.

Suggested fix
-      const backupData = { schemaVersion: 1, data: 'test' };
+      const backupData = { schemaVersion: CURRENT_SCHEMA_VERSION, data: 'test' };
🤖 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 `@src/app/services/import-export.service.spec.ts` at line 80, Replace the
hardcoded schemaVersion value of 1 in the backupData fixture with the
CURRENT_SCHEMA_VERSION constant. This ensures that the test fixture remains
synchronized with the actual schema version used in the
ImportExportService.exportRecoveryBackup flow, so the test will properly fail if
the schema version changes in the codebase.

15-25: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Restore the Blob.prototype.text override after the suite.

When the fallback branch runs, it assigns a method to a global prototype. vi.restoreAllMocks() does not undo this assignment. Later tests can observe the test-only FileReader implementation. Save the original value and restore it, or delete the added property, in afterAll.

Suggested cleanup
+let originalBlobText: Blob['text'] | undefined;
+
 beforeAll(() => {
+  originalBlobText = Blob.prototype.text;
   if (!Blob.prototype.text) {
     Blob.prototype.text = function () {
       return new Promise<string>((resolve) => {
@@
   });
 });
+
+afterAll(() => {
+  if (originalBlobText) {
+    Blob.prototype.text = originalBlobText;
+  } else {
+    Reflect.deleteProperty(Blob.prototype, 'text');
+  }
+});
🤖 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 `@src/app/services/import-export.service.spec.ts` around lines 15 - 25, The
beforeAll hook modifies the global Blob.prototype.text without cleanup, causing
test pollution for subsequent suites. In the beforeAll hook, save the original
value of Blob.prototype.text before the conditional assignment, then add an
afterAll hook that restores the saved original value or deletes the property if
it did not exist before the suite began.
🤖 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.

Outside diff comments:
In `@src/app/components/settings/settings.component.spec.ts`:
- Around line 274-285: To prove that stale backups are cleared when loading
fails, first seed the recoveryBackups signal with valid backup data before
creating the fixture and triggering the getRecoveryBackups failure. After the
fixture is created and stable, assert that recoveryBackups() becomes empty,
demonstrating the clearing behavior. Keep the existing errorMessage() assertion
unchanged to verify that separate concern.

---

Nitpick comments:
In `@src/app/services/import-export.service.spec.ts`:
- Line 80: Replace the hardcoded schemaVersion value of 1 in the backupData
fixture with the CURRENT_SCHEMA_VERSION constant. This ensures that the test
fixture remains synchronized with the actual schema version used in the
ImportExportService.exportRecoveryBackup flow, so the test will properly fail if
the schema version changes in the codebase.
- Around line 15-25: The beforeAll hook modifies the global Blob.prototype.text
without cleanup, causing test pollution for subsequent suites. In the beforeAll
hook, save the original value of Blob.prototype.text before the conditional
assignment, then add an afterAll hook that restores the saved original value or
deletes the property if it did not exist before the suite began.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f21f021-735a-49fe-a0ab-7939b314f9bb

📥 Commits

Reviewing files that changed from the base of the PR and between 949103d and 69b8405.

📒 Files selected for processing (7)
  • src/app/components/season-editor/season-editor.component.spec.ts
  • src/app/components/settings/settings.component.spec.ts
  • src/app/services/group.service.spec.ts
  • src/app/services/import-export.service.spec.ts
  • src/app/services/round-robin.service.spec.ts
  • src/app/services/watch-list.service.spec.ts
  • src/app/utils/form.utils.spec.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/app/utils/form.utils.spec.ts
  • src/app/services/group.service.spec.ts
  • src/app/services/watch-list.service.spec.ts
  • src/app/components/season-editor/season-editor.component.spec.ts

- Seed explicit groups in createGroup ordering test to match test name
- Replace global Blob.prototype.text polyfill with local readBlobText helper
- Assert saveData not called in no-op tests instead of comparing snapshots
@CodeWithMa
CodeWithMa merged commit 164c9a3 into CodeWithMa:dev Aug 4, 2026
4 of 5 checks passed
@CodeWithMaBot
CodeWithMaBot deleted the improve-test-coverage-69 branch August 16, 2026 08:55
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.

Improve test coverage

2 participants