Skip to content

TUL/fix: default filter operator to 'equals' for operator-less search URLs (#781) - #1368

Open
milanmajchrak wants to merge 2 commits into
customer/TULfrom
fix/tul-default-filter-operator-781
Open

TUL/fix: default filter operator to 'equals' for operator-less search URLs (#781)#1368
milanmajchrak wants to merge 2 commits into
customer/TULfrom
fix/tul-default-filter-operator-781

Conversation

@milanmajchrak

Copy link
Copy Markdown
Collaborator

Problem

A search URL whose filter carries no operator — e.g. a legacy or crawled /search?f.subject=radiodiagnostika instead of f.subject=radiodiagnostika,equals — is forwarded to the backend verbatim. The backend correctly rejects the operator-less filter with HTTP 422 per the DSpace REST Contract, and because one search page fans out into ~6 discover sub-requests (search/objects + each facet), each affected render produces a burst of 422s (dataquest-dev/dspace-customers#781).

Today's UI always emits ,equals on facet links, so these operator-less URLs are legacy/bookmarked/crawled links from before the operator format.

Fix

In SearchConfigurationService.getCurrentFilters(), when building SearchFilters from the URL, default the operator to 'equals' — mirroring the existing range-filter (.min/.max) branch right above, which already passes 'equals'.

-  filters.push(new SearchFilter(key, filterParams[key]));
+  filters.push(new SearchFilter(key, filterParams[key], 'equals'));

This is safe because SearchOptions.toRestUrl only appends the operator when the value does not already contain a comma:

const filterValue = value.includes(',') ? `${value}` : value + (filter.operator ? ',' + filter.operator : '');

So values that already embed an operator (radiodiagnostika,equals, foo,notequals, id,authority, …) are left untouched; only truly operator-less values gain ,equals. Operator-less legacy URLs now resolve to <value>,equals and return results instead of 422.

Tests

Updated the getCurrentFilters expectations in search-configuration.service.spec.ts and my-dspace-configuration.service.spec.ts (the plain, non-range filter now carries operator: 'equals').

Companion

A backend PR (dataquest-dev/DSpace customer/TUL) downgrades any remaining discover 422 from ERROR to WARN so monitoring is not tripped even if an operator-less request slips through another path.

…781)

A search URL whose filter carries no operator (e.g. a legacy or crawled
"/search?f.subject=foo" instead of "f.subject=foo,equals") was forwarded to the
backend verbatim. The backend correctly rejects the operator-less filter with
HTTP 422 per the DSpace REST Contract, producing an error on every affected
search render (dataquest-dev/dspace-customers#781).

When reading active filters from the URL in SearchConfigurationService.
getCurrentFilters, default the operator to 'equals' (mirroring the existing
range-filter branch). Values that already embed an operator - i.e. contain a
comma - are left untouched by SearchOptions.toRestUrl, so explicit operators
(equals/notequals/contains/authority/...) are preserved. Operator-less legacy
URLs now resolve to "<value>,equals" and return results instead of 422.

Updated the getCurrentFilters expectations in the SearchConfigurationService
and MyDSpaceConfigurationService specs accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 59c1cd40-663b-4b9d-8377-8d820e2ba2b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

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.

Pull request overview

This PR aims to prevent legacy/crawled search URLs with operator-less filters (e.g. f.subject=foo) from being forwarded to the REST backend without an operator, which currently triggers HTTP 422 responses and cascades into multiple failing discover requests per page render.

Changes:

  • Default non-range URL-derived SearchFilter operators to 'equals' in SearchConfigurationService.getCurrentFilters().
  • Update unit test expectations so non-range filters created from URL params include operator: 'equals'.
  • Keep range filter handling (.min/.max) unchanged (already uses 'equals').

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/app/core/shared/search/search-configuration.service.ts Defaults operator to 'equals' when converting URL filter params to SearchFilters.
src/app/core/shared/search/search-configuration.service.spec.ts Adjusts getCurrentFilters expectations for the default operator behavior.
src/app/my-dspace-page/my-dspace-configuration.service.spec.ts Updates MyDSpace filter expectations to include the default operator.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/core/shared/search/search-configuration.service.ts Outdated
Comment thread src/app/core/shared/search/search-configuration.service.spec.ts
Previously getCurrentFilters set operator='equals' on every non-range filter,
even when the URL value already embedded an operator (e.g. "foo,contains"),
which could confuse consumers reading filter.operator directly (e.g. CSV export).
Now default to 'equals' only when no value carries an operator suffix (contains a
comma), matching SearchOptions.toRestUrl. Added a spec fixture for an
operator-embedded value asserting the operator stays unset. Per Copilot review on #1368.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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