Skip to content

TEST-001: Add unit test coverage for parseSearchQuery + keywords field - #438

Merged
motirebuma merged 2 commits into
QuoteVote:mainfrom
Sakshamk17:test-001-parse-search-query-unit-tests
Jul 26, 2026
Merged

TEST-001: Add unit test coverage for parseSearchQuery + keywords field#438
motirebuma merged 2 commits into
QuoteVote:mainfrom
Sakshamk17:test-001-parse-search-query-unit-tests

Conversation

@Sakshamk17

Copy link
Copy Markdown
Contributor

Closes #388

Summary

Adds comprehensive unit test coverage for parseSearchQuery on both the
frontend and backend, and extends the parsing utility to return the
{ keywords, usernames, hashtags } shape requested in the issue.

Background / design decision

A parseSearchQuery utility already existed in both packages
(quotevote-frontend/src/utils/parseSearchQuery.ts and
quotevote-backend/app/data/utils/parseSearchQuery.ts), returning
{ usernames, hashtags, textQuery, tokens }. textQuery and tokens are
already consumed elsewhere:

  • SearchContainer.tsx (frontend) builds its "matching "..."" label from
    textQuery
  • postsResolver.ts (backend) uses textQuery for the Mongo $text search
    filter, and tokens for username/hashtag filter construction

Rather than replace that shape and risk a breaking refactor, this PR
extends it with a keywords: string[] field (the existing textQuery
split on whitespace), so the issue's required shape is satisfied as a
strict superset. textQuery and tokens are unchanged and kept for
backwards compatibility — no consumer needed to change.

Changes

  • quotevote-frontend/src/types/search.ts — added keywords: readonly string[] to ParsedSearchQuery
  • quotevote-frontend/src/utils/parseSearchQuery.ts — compute and return keywords
  • quotevote-frontend/src/__tests__/utils/parseSearchQuery.test.ts — expanded from 3 → 26 tests
  • quotevote-backend/app/types/search.ts — added keywords: readonly string[] to ParsedSearchQuery
  • quotevote-backend/app/data/utils/parseSearchQuery.ts — compute and return keywords
  • quotevote-backend/__tests__/unit/parseSearchQuery.test.ts — expanded from ~20 → 28 tests

Test coverage added (per issue's matrix)

  • Plain keyword search (single word, multiple words)
  • @username search (single, multiple, dedup, case normalization, hyphen/underscore rules, lone @, @ + trailing text)
  • #hashtag search (single, multiple, dedup, case normalization, hyphen/underscore rules, lone #, # + trailing text)
  • Mixed: keyword + username, keyword + hashtag, username + hashtag, keyword + username + hashtag
  • Token-order independence
  • Empty string / whitespace-only string
  • Leading/trailing whitespace, repeated internal whitespace
  • Email-address false-positive check (user@example.com should not be parsed as a username)

Test plan

# Frontend
cd quotevote-frontend
pnpm test          # 158 suites, 1891 passed, 4 skipped

# Backend
cd quotevote-backend
pnpm test          # 95 suites, 791 passed, 100% coverage on parseSearchQuery.ts

# Type safety
npx tsc --noEmit    # clean on both packages

All existing tests pass with no regressions, including
SearchContainer.test.tsx, NewSearchContainer.test.tsx, and
postsResolver.test.ts — confirming the keywords addition doesn't
disturb existing textQuery/tokens consumers.

Acceptance criteria checklist

  • Search query parsing has unit test coverage
  • Tests cover keywords, usernames, hashtags, mixed queries, and edge cases
  • Parsing behavior is deterministic and documented through test cases
  • Empty, whitespace-only, and incomplete-token inputs are handled safely
  • Tests pass locally
  • Existing search behavior is not broken
  • No unrelated search UI changes are included
  • No Playwright/browser tests added (pure Jest unit tests only, per Tech Notes)

Note for reviewer

keywords preserves the original casing of the input text (only
usernames/hashtags are lowercased) — e.g. parseSearchQuery('Hello World')
returns keywords: ['Hello', 'World'], matching the existing textQuery
behavior. Flagging this in case keyword-level case normalization is also
expected — happy to add .toLowerCase() to the keywords array if so.

Extends ParsedSearchQuery on both frontend and backend with a
keywords: string[] field (derived from the existing textQuery),
satisfying TEST-001's required { keywords, usernames, hashtags }
shape without breaking existing consumers (SearchContainer,
postsResolver) that still rely on textQuery/tokens.

Also expands unit test coverage for parseSearchQuery per the issue's
full matrix: plain keywords, @username, #hashtag, all mixed
combinations, empty/whitespace input, case normalization, repeated
whitespace, lone @/#, hyphen/underscore handling, multiple
usernames/hashtags, and order-independence.

Frontend: 3 -> 26 tests
Backend: ~20 -> 28 tests, 100% coverage on parseSearchQuery.ts maintained
Copilot AI review requested due to automatic review settings July 25, 2026 12:21
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

@Sakshamk17 is attempting to deploy a commit to the Louis Girifalco's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copy link
Copy Markdown
Contributor

@Sakshamk17 thank you for adding focused coverage around parseSearchQuery. The implementation is mergeable and CI has passed. Before final review, could you update the PR description to describe this as Jest unit coverage rather than Playwright coverage and confirm that the test suite preserves the existing textQuery and tokens behavior while adding keywords?

@motirebuma could you provide the technical review once that clarification is recorded, with particular attention to backward compatibility for existing search consumers? The Vercel authorization warning appears separate from the unit-test result, so it may be documented rather than treated as evidence that the test suite failed.

@motirebuma motirebuma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hi @Sakshamk17 - PR is good, the keywords field is a welcomed addition, and the test expansion is thorough.

What's good

  1. keywords field - splitting the text query on spaces is simple and correct, guarding against empty string is also a good idea to avoid [''], and it's applied symmetrically on both sides. The ParsedSearchQuery type is correctly updated in both the backend (quotevote-backend/app/types/search.ts) and the frontend (quotevote-frontend/src/types/search.ts).

  2. Backend test expansion - all existing tests assert the keywords field, and more importantly, there are additional tests for single word queries, mixed queries (school safety @marta #education), token ordering, isolated @ and #, and collapsed whitespace. Everything seems well-covered.

  3. Frontend test expansion - going from 4 tests to something comprehensive is great to see, and they're well-organized with describes for each category (plain keywords, @, #, mixed, whitespace). There are tests for case folding, deduplication, hyphen truncation, underscores, and isolated symbols. Everything seems well-covered.

  4. Nothing changed where nothing was supposed to change - keywords are a new addition, and the existing usernames, hashtags, textQuery, and tokens are all untouched.

Items to address

  1. Newline at the end of file is missing - quotevote-backend/__tests__/unit/parseSearchQuery.test.ts and quotevote-frontend/src/__tests__/utils/parseSearchQuery.test.ts both have the last line end with }); without a newline after. It's a minor style issue but most linters and git_configs will warn about it - just add an extra newline at the end of the file.

  2. The keywords field may contain punctuation from the query - if the input was @ hello, keywords would be ['@', 'hello'], same with # hello['#', 'hello']. It's a minor issue really - those are valid entries if you consider @ and # to be standalone tokens, but it's worth noting that the field may contain such punctuation. Unless, of course, you actually parse @ and # out into their own fields, but I don't think you do - you probably just full-text search over keywords, which is fine.

Thank you @Sakshamk17

@flyblackbox @Sakshamk17

- keywords no longer includes tokens made up entirely of punctuation
  (e.g. a lone '@' or '#'); textQuery is unaffected and still retains
  them verbatim for backwards compatibility
- words containing punctuation (e.g. user@example.com) are unaffected
- addresses review feedback from @flyblackbox on QuoteVote#388
@Sakshamk17

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review!

Fixed the trailing newlines on both test files.
Good catch — filtered punctuation-only tokens (e.g. a lone @ or #) out of keywords (using /\w/.test(word)), while textQuery still retains them verbatim for backwards compatibility. Words that merely contain punctuation, like user@example.com, are unaffected. Added a dedicated punctuation-only tokens test group in both suites to lock this in, plus updated the existing lone-@/# tests accordingly.

Pushed as a follow-up commit — all tests green .

@motirebuma
motirebuma self-requested a review July 26, 2026 21:34

@motirebuma motirebuma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hey @Sakshamk17 - good job with the follow-up. The punctuation filtering is handled correctly now.

Previously raised issues

Punctuation in keywords - RESOLVED. The keywords array is now correctly filtered using .filter((word) => /\w/.test(word)) to remove punctuation-only tokens like standalone @ and #. Updated tests, including a new section titled "punctuation-only tokens" that checks for single @, single #, punctuation-only words, email addresses, and punctuation mixed with letters. Added JSDoc to the type description. Great job.

What's good (as mentioned in the previous review)

  • The keywords field is simple, correct, and consistently used on both sides

  • Good test coverage for both FE and BE, with tests nicely organized into describes

  • Purely additive - existing usernames, hashtags, textQuery, and tokens are untouched

CI is all green.

Thanks!

@flyblackbox @Sakshamk17

@motirebuma
motirebuma merged commit 400c2de into QuoteVote:main Jul 26, 2026
3 of 4 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.

5.1.1 TEST-001 Jest unit coverage for parseSearchQuery

4 participants