Conversation
Coverage Report for CI Build 26300577853Coverage decreased (-0.05%) to 98.322%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
❌ 8 blocking issues (10 total)
|
There was a problem hiding this comment.
Pull request overview
Adds a controller-layer implementation for a “natural language search” opt-in/out preference using a cookie, wiring it to the existing UI toggle and conditionally showing an alert when NLS isn’t applicable to the active tab.
Changes:
- Add
/natural_language_search_optinendpoint to set/clear the opt-in cookie and redirect back. - Apply the cookie in
SearchController#resultsto defaultqueryMode=hybridand expose view flags for toggle state + warning display. - Add a Stimulus controller to toggle the preference from the UI and introduce a dedicated integration test file for the behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/controllers/natural_language_search_optin_test.rb | Adds integration tests covering cookie setting, redirects, toggle UI state, and warning display. |
| config/routes.rb | Adds route for the opt-in toggle endpoint. |
| app/views/search/results.html.erb | Renders the NLS alert only when @show_nls_warning is true. |
| app/views/search/_form.html.erb | Makes the toggle reflect opt-in state and wires click behavior to a Stimulus controller. |
| app/javascript/controllers/natural_language_search_toggle_controller.js | Implements client-side toggle behavior by hitting the opt-in endpoint and returning to the current page. |
| app/controllers/static_controller.rb | Adds natural_language_search_optin action to set/delete cookie and redirect. |
| app/controllers/search_controller.rb | Applies cookie-driven default query mode and sets view vars for toggle state + warning logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| safe_return_to = nil | ||
| end | ||
| end | ||
| redirect_to(safe_return_to || root_path) |
| safe_return_to = nil | ||
| end | ||
| end | ||
| redirect_to(safe_return_to || root_path) |
There was a problem hiding this comment.
Found 5 issues:
1. Function with high complexity (count = 9): natural_language_search_optin [qlty:function-complexity]
2. Assignment Branch Condition size for natural_language_search_optin is too high. [<7, 21, 10> 24.29/17] [rubocop:Metrics/AbcSize]
3. Cyclomatic complexity for natural_language_search_optin is too high. [10/7] [rubocop:Metrics/CyclomaticComplexity]
4. Method has too many lines. [19/10] [rubocop:Metrics/MethodLength]
5. Perceived complexity for natural_language_search_optin is too high. [11/8] [rubocop:Metrics/PerceivedComplexity]
Why these changes are being introduced: We want users to be able to decide whether to use hybrid (termed 'natural language search' in the public UI) or lexical search. USE-577 implemented the frontend work on this feature; this ticket implements the controller layer. Relevant ticket(s): - [USE-576](https://mitlibraries.atlassian.net/browse/USE-576) - [USE-577](https://mitlibraries.atlassian.net/browse/USE-577) How this addresses that need: This adds natural language search opt-in cookie, which is toggled via a stimulus controller. When the cookie is set, hybrid search is the default query mode. When it is not set, the query mode falls back to lexical search (or other default mode specified by env). This behavior can be overridden by supplying a `queryMode` param manually. For example, if a user has the NLS cookie set but adds `queryMode=semantic` to their query string, the search will execute in semantic mode, not hybrid. If NLS is not available for a given tab, a message displays to notify the user of the limitation. Side effects of this change: Tests for this feature are stored in a separate file. This is different from how we usually do things, but there are so many conditions to test that I did not want to pollute the search controller test file further.
JPrevost
left a comment
There was a problem hiding this comment.
The only required change is around a line accidentally reintroduced during a rebase.
The other comments are things you can tweak or not based on how they land with you.
Solid feature, I'm excited for others to get to try this soon!
| # inject session preference for boolean type if it is present | ||
| params[:booleanType] = cookies[:boolean_type] || 'AND' | ||
|
|
||
| # inject queryMode from cookie if not provided in URL params |
There was a problem hiding this comment.
Minor nit: this comment feels slightly misleading. We aren't injecting the queryMode from the cookie, we are injecting hybrid if the cookie evaluates to true but no url parameter is passed. It's minor difference but it made me have to read this several times to convince myself what it was doing was how I was interpreting it lol
| end | ||
|
|
||
| # show_nls_warning? determines if the user should see a warning that results are not using natural language search. | ||
| # Shows when: user is opted-in AND viewing a Primo-only tab (which only supports keyword search). |
There was a problem hiding this comment.
Not asking for a change now as I'm pretty sure this is what was asked for, but I'm curious if we should have a partial warning on the all tab like "Some results are not using natural language search" with a link to why. Let's leave this as-is for now though and we can bring this up to the project team.
| class ApplicationController < ActionController::Base | ||
| helper Mitlibraries::Theme::Engine.helpers | ||
|
|
||
| before_action :set_natural_language_search_optin |
There was a problem hiding this comment.
There really a few aspects of this that I think are fine but we definitely need to confirm are innocuous in geo mode.
There was a problem hiding this comment.
I think GeoData is largely unaffected. It will set the cookie, but since GeoData doesn't use queryMode, it won't actually change the behavior. I also confirmed that nothing changes in the UI.
|
|
||
| <h2 class="results-context" data-matomo-seen="Search, Results Found, Tab: {{getActiveTabName}}"><%= results_summary(@pagination[:hits]) %></h2> | ||
| <%= render partial: 'search/nls_alert' %> | ||
| <p class="results-context-description"><%= tab_description %></p> |
There was a problem hiding this comment.
Change requested:
I think this line got accidentally rebased into place and can be removed. It moved in a commit that just landed earlier today. This branch now shows the tab description twice, once in the new location near the tab as well as in this old location closer to the results.
There was a problem hiding this comment.
Oops, good catch! Yes, that rebase was done hastily before review tagging.
| assert_redirected_to '/results?q=test' | ||
| end | ||
|
|
||
| test 'route redirects to root when no referer or return_to' do |
There was a problem hiding this comment.
Maybe a test for and illegal redirect to an external link goes to root?
| assert_select 'aside.nls-alert', count: 0 | ||
| end | ||
|
|
||
| test 'warning does not show on articles tab with no opt-in cookie' do |
There was a problem hiding this comment.
Minor: these tests sometimes mention an articles tab and sometimes cdi. Consistency might make this easier to follow. I'd go with cdi if you do adjust as that should remain stable even if our labels change
| # Shows when: user is opted-in AND viewing a Primo-only tab (which only supports keyword search). | ||
| def show_nls_warning? | ||
| @natural_language_search_optin && primo_tabs.include?(@active_tab) | ||
| end |
| assert_redirected_to root_path | ||
| end | ||
|
|
||
| test 'external URLs redirect to route' do |
There was a problem hiding this comment.
Typo: I think you meant root here. Feel free to fixup without a re-review :)
Why these changes are being introduced:
We want users to be able to decide whether to use
hybrid (termed 'natural language search' in the
public UI) or lexical search. USE-577 implemented
the frontend work on this feature; this ticket
implements the controller layer.
Relevant ticket(s):
How this addresses that need:
This adds natural language search opt-in cookie,
which is toggled via a stimulus controller. When
the cookie is set, hybrid search is the default
query mode. When it is not set, the query mode
falls back to lexical search (or other default
mode specified by env).
This behavior can be overridden by supplying a
queryModeparam manually. For example, if a user has the NLS cookie set but addsqueryMode=semanticto their query string, the search will executein semantic mode, not hybrid.
If NLS is not available for a given tab, a
message displays to notify the user of the
limitation.
Side effects of this change:
Tests for this feature are stored in a separate
file. This is different from how we usually do
things, but there are so many conditions to test
that I did not want to pollute the search
controller test file further.
Developer
Accessibility
New ENV
Approval beyond code review
Additional context needed to review
E.g., if the PR includes updated dependencies and/or data
migration, or how to confirm the feature is working.
Code Reviewer
Code
added technical debt.
Documentation
(not just this pull request message).
Testing