Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .Jules/vantage.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
## 2026-05-20 - Hardening Telemetry Verification and Refining Stream Types | **Learning:** Index-based assertions in telemetry tests are brittle; using `.find()` ensures robust verification. Standardizing on `String(error)` across all API catch blocks prevents context loss during failure events. | **Action:** Refactored `chat-api.test.ts` and `github-releases.test.ts` to use search-based spy assertions, and added explicit return types to `chat-stream.ts` to resolve Astro compiler hints.

## 2026-05-24 - Comprehensive Unit Testing for Visitor Changelog Formatting | **Learning:** Single-pass Edge transformations require dedicated unit tests covering edge cases like empty inputs, internal agent filtering, and fallback formatting to prevent silent regressions in SSR release streams. | **Action:** Added `src/utils/visitor-changelog.test.ts` to test `toVisitorChangelogTitle`, `stripChangelogChrome`, `toVisitorReleaseBody`, and `toVisitorRelease`.

## 2026-09-13 - Hardening Chat Explore Card Question Matching & Expanding Edge-Case Tests | **Learning:** Helper functions operating on user inputs in Cloudflare Workers edge runtimes must explicitly guard against non-string arguments to prevent unexpected runtime errors. | **Action:** Added runtime type check in `exploreCardForQuestion` in `src/utils/chat-explore.ts` and added unit test cases covering non-string, empty whitespace, and uppercase inputs in `src/utils/chat-explore.test.ts`.
15 changes: 15 additions & 0 deletions src/utils/chat-explore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ describe('exploreCardForQuestion', () => {
);
});

it('handles edge cases gracefully such as non-string values or empty whitespace', () => {
// @ts-expect-error testing runtime guard against non-string input
expect(exploreCardForQuestion(null)).toBeNull();
// @ts-expect-error testing runtime guard against non-string input
expect(exploreCardForQuestion(undefined)).toBeNull();
expect(exploreCardForQuestion('')).toBeNull();
expect(exploreCardForQuestion(' ')).toBeNull();
});

it('handles uppercase and mixed-case queries', () => {
expect(exploreCardForQuestion('TELL ME ABOUT YOUR WORK')).toEqual(EXPLORE_CARDS.work);
expect(exploreCardForQuestion('DESIGN SYSTEM')).toEqual(EXPLORE_CARDS.designSystem);
expect(exploreCardForQuestion('LINKEDIN')).toEqual(LINKEDIN_CONFIRM);
});

it('keeps action cards on published routes and LinkedIn confirm on the hire path', () => {
expect(EXPLORE_CARDS.designSystem.href).toBe('/work/ifs-design-system/');
expect(EXPLORE_CARDS.designSystem.actionLabel).toBe('View the case');
Expand Down
1 change: 1 addition & 0 deletions src/utils/chat-explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const EXPLORE_CARDS = {
} as const satisfies Record<string, ExploreCard>;

export function exploreCardForQuestion(lastUserMessage: string): ExploreCard | null {
if (typeof lastUserMessage !== 'string') return null;
const question = lastUserMessage.trim().toLowerCase();
if (!question) return null;

Expand Down
Loading