Skip to content

chore: add unit tests for utils#183

Merged
MatteoGabriele merged 7 commits into
MatteoGabriele:mainfrom
graphieros:chore-unit-tests
Jun 19, 2026
Merged

chore: add unit tests for utils#183
MatteoGabriele merged 7 commits into
MatteoGabriele:mainfrom
graphieros:chore-unit-tests

Conversation

@graphieros

@graphieros graphieros commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

This adds unit tests for utils (#166)

Adding tests revealed a few small bugs for the server/utils/format-username util:

  • runtime could crash if the username contains a '%' symbol
  • empty space was only removed for all spaces

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes

    • Username normalization is more robust against malformed URL-encoded input and now consistently removes all spaces.
  • Improvements

    • Health stats utility now has an explicit return type for clearer expectations.
    • Chart day-key helper is now publicly available for reuse.
  • Tests

    • Added/expanded unit test coverage for username formatting, color utilities, chart analytics helpers, health statistics, progression calculations, plus new ecosystem health item mocks.

@netlify

netlify Bot commented Jun 16, 2026

Copy link
Copy Markdown

Deploy Preview for agentscan ready!

Name Link
🔨 Latest commit 8478104
🔍 Latest deploy log https://app.netlify.com/projects/agentscan/deploys/6a356a97b4fae3000849794f
😎 Deploy Preview https://deploy-preview-183--agentscan.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 89cd882e-9c69-4c78-a204-5a2c08bb5257

📥 Commits

Reviewing files that changed from the base of the PR and between ceca381 and 8478104.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • server/utils/format-username.ts
  • test/unit/mocks/ecosystemHealthItems.ts
  • test/unit/server/utils/format-username.test.ts
  • test/unit/shared/utils/charts.test.ts
  • test/unit/shared/utils/count-classification-by-date.test.ts
  • test/unit/shared/utils/health-stats.test.ts
✅ Files skipped from review due to trivial changes (1)
  • test/unit/mocks/ecosystemHealthItems.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • test/unit/shared/utils/count-classification-by-date.test.ts
  • test/unit/server/utils/format-username.test.ts
  • test/unit/shared/utils/health-stats.test.ts
  • test/unit/shared/utils/charts.test.ts

📝 Walkthrough

Walkthrough

Three production utility files receive small targeted fixes: formatUsername now strips all spaces globally, getDayKey is exported from charts.ts, and getHealthStats gains an explicit TypeScript return type. A shared mock fixture (MOCK_ECOSYSTEM_HEALTH_ITEMS) is introduced, and Vitest unit test suites are added for format-username, color, chart, health-stats, calc-linear-progression, and count-classification-by-date utilities.

Changes

Utility Fixes, Exports, and Unit Test Additions

Layer / File(s) Summary
Production utility fixes and export changes
server/utils/format-username.ts, shared/utils/charts.ts, shared/utils/health-stats.ts
formatUsername replaces all spaces globally (was first-only) and guards decodeURIComponent in a try-catch; getDayKey gains the export modifier; getHealthStats adds an explicit Record<IdentityClassification, { count: number; percentage: string }> | null return type.
Shared mock data
test/unit/mocks/ecosystemHealthItems.ts
Adds MOCK_ECOSYSTEM_HEALTH_ITEMS (hardcoded ecosystem health records) and EXPECTED_NB_UNIQUE_REPOS (set size of distinct repo_name values) used across multiple test suites.
formatUsername unit tests
test/unit/server/utils/format-username.test.ts
New suite covering empty input, lowercasing, leading/trailing whitespace trimming, global space removal, malformed URL encoding, and URL-decoding including Unicode sequences.
Color utility unit tests
test/unit/app/utils/colors.test.ts
New test file for clamp, hexToRgb (with/without #, error cases), rgbToHex, interpolate, and interpolateHexColors at 0.5 ratio.
Shared utils unit tests
test/unit/shared/utils/calc-linear-progression.test.ts, test/unit/shared/utils/count-classification-by-date.test.ts, test/unit/shared/utils/health-stats.test.ts, test/unit/shared/utils/charts.test.ts
New suites for calcLinearProgression (edge cases, slopes, undefined-as-zero), countClassificationByDate (ISO timestamp keys, classification shape), formatTrend/getHealthStats (percentage strings, classified output), and all chart helpers (getCompleteDayRange, getDayKey, convertToHorizontalBarDataset, getClosedPrPercentageByRepo, getUniqueDatesFromSource, getClosedPrPercentageEvolutionByRepo, getClosedPrPercentageEvolutionTotal, getClosedPrPercentageTotal).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

  • MatteoGabriele/agentscan#177: Touches shared/utils/health-stats.ts with changes to getHealthStats's typing and return contract, directly related to the explicit return type added in this PR.

Suggested reviewers

  • MatteoGabriele

Poem

🐇 Hop hop, spaces flee,
A global replace sets the username free!
getDayKey now exported, bright and clear,
Return types explicit — no guessing here.
Tests blooming like clover across the land,
This bunny approves with a tiny paw's hand! 🌿

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'chore: add unit tests for utils' is vague and generic, using the non-descriptive term 'utils' without specifying which utilities are being tested or clarifying the scope of the changes. Consider revising the title to be more specific, such as 'chore: add unit tests for format-username and chart utilities' or 'chore: add comprehensive unit tests for shared and server utilities' to better convey the changeset scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Organic activity

No automation signals detected in the analyzed events.

View full analysis →

This is an automated analysis by AgentScan

@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

🤖 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 `@server/utils/format-username.ts`:
- Line 2: The decodeURIComponent call in the return statement lacks error
handling and will crash when processing malformed URI input with invalid
percent-encoding sequences. Wrap the decodeURIComponent call in a try-catch
block to safely handle URIError exceptions, and provide a fallback that uses the
original username parameter when decoding fails, ensuring the function returns a
valid formatted username string even with invalid input.

In `@test/unit/server/utils/format-username.test.ts`:
- Around line 4-36: Add a new test case to the formatUsername test suite that
verifies the function handles malformed URL-encoded input without throwing an
error. Include a test case like "handles malformed percent-encoding" that calls
formatUsername with invalid percent-encoding (such as a string with incomplete
or invalid percent sequences) and asserts that it does not throw an exception,
ensuring the utility is resilient to malformed user input.

In `@test/unit/shared/utils/charts.test.ts`:
- Around line 58-67: The current test validation using arrayContaining with
mapped matchers does not reliably validate every element in the result array.
Replace this approach by using forEach to iterate through each element in the
result array and explicitly validate that each element contains the required
properties (name as String and value as Number). This ensures all elements meet
the validation criteria rather than just checking for the presence of matching
elements.

In `@test/unit/shared/utils/count-classification-by-date.test.ts`:
- Around line 15-30: The forEach callback iterates over Object.values(result)
but ignores the iterated value and creates unused expect.objectContaining
matchers that are never evaluated. Fix this by accepting the iterated value as a
parameter in the forEach callback and passing it to an expect assertion. Call
expect() on the iterated value and chain it with toMatchObject() or toEqual(),
using the objectContaining structure to validate that each result value matches
the expected schema with organic, mixed, and automation properties each
containing count and trend number fields.

In `@test/unit/shared/utils/health-stats.test.ts`:
- Around line 29-34: The forEach loop in the test is not asserting anything
against each item - the loop parameter is unused and expect.objectContaining is
called without being part of an expect assertion. Update the forEach loop to
capture each item as a parameter, then use that parameter to assert the item's
shape by calling expect on it with .toEqual(expect.objectContaining({...})) to
properly enforce the contract that each value contains count as a Number and
percentage as a String.
🪄 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

Run ID: 13e5cebf-bcad-4366-a575-3ce86186a814

📥 Commits

Reviewing files that changed from the base of the PR and between 7c22b65 and ceca381.

📒 Files selected for processing (10)
  • server/utils/format-username.ts
  • shared/utils/charts.ts
  • shared/utils/health-stats.ts
  • test/unit/app/utils/colors.test.ts
  • test/unit/mocks/ecosystemHealthItems.ts
  • test/unit/server/utils/format-username.test.ts
  • test/unit/shared/utils/calc-linear-progression.test.ts
  • test/unit/shared/utils/charts.test.ts
  • test/unit/shared/utils/count-classification-by-date.test.ts
  • test/unit/shared/utils/health-stats.test.ts

Comment thread server/utils/format-username.ts Outdated
Comment thread test/unit/server/utils/format-username.test.ts
Comment thread test/unit/shared/utils/charts.test.ts Outdated
Comment thread test/unit/shared/utils/count-classification-by-date.test.ts Outdated
Comment thread test/unit/shared/utils/health-stats.test.ts Outdated

@MatteoGabriele MatteoGabriele left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

❤️

@MatteoGabriele MatteoGabriele merged commit 70c9106 into MatteoGabriele:main Jun 19, 2026
5 checks passed
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.

2 participants