- 
                Notifications
    You must be signed in to change notification settings 
- Fork 20
Show other results from GOV.UK in a scoped search #784
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
`count` should be a string not an integer, though there should only ever be 1 result when searching by link anyway. Add a trailing comma for cleaner diffs(tm).
Given this is only being used for 3 things and I just spent quite a while getting lost in the meta-programming while debugging something, I've unpacked this to non-metaprogrammed methods to save the next person who comes to this some time.
We're about to do a lot of fiddling around with results, to keep the code nice and clean, extract `result` to a single template.
| This PR is too advanced for me to review but 👍 on the detailed commit messages! | 
73f3d42    to
    0db47e9      
    Compare
  
    | I have had a quick look and this looks great to me. Thanks for taking the time to make the commits really easy to follow. | 
| I'm very excited to see this, it looks shiny. ✨. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this bit of the test is quite involved. I wonder whether it'd be more obvious if you checked the actual (hard-coded) values instead of variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hard-coded values are more like:
<[{:attributes=>[],
    :debug_score=>1,
    :description=>nil,
    :display_link=>nil,
    :es_score=>nil,
    :examples=>nil,
    :examples_present?=>false,
    :external=>false,
    :format=>nil,
    :formatted_section_name=>nil,
    :formatted_subsection_name=>nil,
    :formatted_subsubsection_name=>nil,
    :link=>nil,
    :section=>nil,
    :suggested_filter_link=>nil,
    :suggested_filter_present?=>false,
    :suggested_filter_title=>nil,
    :title=>"scoped_result_1"},
   {:attributes=>[],
    :debug_score=>1,
    :description=>nil,
    :display_link=>nil,
    :es_score=>nil,
    :examples=>nil,
    :examples_present?=>false,
    :external=>false,
    :format=>nil,
    :formatted_section_name=>nil,
    :formatted_subsection_name=>nil,
    :formatted_subsubsection_name=>nil,
    :link=>nil,
    :section=>nil,
    :suggested_filter_link=>nil,
    :suggested_filter_present?=>false,
    :suggested_filter_title=>nil,
    :title=>"scoped_result_2"},
   {:attributes=>[],
    :debug_score=>1,
    :description=>nil,
    :display_link=>nil,
    :es_score=>nil,
    :examples=>nil,
    :examples_present?=>false,
    :external=>false,
    :format=>nil,
    :formatted_section_name=>nil,
    :formatted_subsection_name=>nil,
    :formatted_subsubsection_name=>nil,
    :link=>nil,
    :section=>nil,
    :suggested_filter_link=>nil,
    :suggested_filter_present?=>false,
    :suggested_filter_title=>nil,
    :title=>"scoped_result_3"},
   {:is_multiple_results=>true,
    :results=>
     [{:attributes=>[],
       :debug_score=>1,
       :description=>nil,
       :display_link=>nil,
       :es_score=>nil,
       :examples=>nil,
       :examples_present?=>false,
       :external=>false,
       :format=>nil,
       :formatted_section_name=>nil,
       :formatted_subsection_name=>nil,
       :formatted_subsubsection_name=>nil,
       :link=>nil,
       :section=>nil,
       :suggested_filter_link=>nil,
       :suggested_filter_present?=>false,
       :suggested_filter_title=>nil,
       :title=>"unscoped_result_1"},
      {:attributes=>[],
       :debug_score=>1,
       :description=>nil,
       :display_link=>nil,
       :es_score=>nil,
       :examples=>nil,
       :examples_present?=>false,
       :external=>false,
       :format=>nil,
       :formatted_section_name=>nil,
       :formatted_subsection_name=>nil,
       :formatted_subsubsection_name=>nil,
       :link=>nil,
       :section=>nil,
       :suggested_filter_link=>nil,
       :suggested_filter_present?=>false,
       :suggested_filter_title=>nil,
       :title=>"unscoped_result_2"},
      {:attributes=>[],
       :debug_score=>1,
       :description=>nil,
       :display_link=>nil,
       :es_score=>nil,
       :examples=>nil,
       :examples_present?=>false,
       :external=>false,
       :format=>nil,
       :formatted_section_name=>nil,
       :formatted_subsection_name=>nil,
       :formatted_subsubsection_name=>nil,
       :link=>nil,
       :section=>nil,
       :suggested_filter_link=>nil,
       :suggested_filter_present?=>false,
       :suggested_filter_title=>nil,
       :title=>"unscoped_result_3"}]},
   {:attributes=>[],
    :debug_score=>1,
    :description=>nil,
    :display_link=>nil,
    :es_score=>nil,
    :examples=>nil,
    :examples_present?=>false,
    :external=>false,
    :format=>nil,
    :formatted_section_name=>nil,
    :formatted_subsection_name=>nil,
    :formatted_subsubsection_name=>nil,
    :link=>nil,
    :section=>nil,
    :suggested_filter_link=>nil,
    :suggested_filter_present?=>false,
    :suggested_filter_title=>nil,
    :title=>"scoped_result_4"}]>.
which is why I've written it this way, though I understand your point. Do you think this is clearer:
     expected_results_list = [{ "title"=> "scoped_result_1" },
                               { "title"=> "scoped_result_2" },
                               { "title"=> "scoped_result_3" },
                               { "is_multiple_results" => true,
                                 "results" => [{ "title"=> "unscoped_result_1" },
                                               { "title"=> "unscoped_result_2" },
                                               { "title"=> "unscoped_result_3" },
                                              ]
                                },
                                { "title"=> "scoped_result_4" },
                              ]
      results.
      # Scoped results
     expected_results_list[0..2].each_with_index do | result, i |
        assert_equal result["title"], results[:results][i][:title]
      end
      # Check un-scoped sub-list has flag
      assert_equal true, results[:results][3][:is_multiple_results]
      # iterate unscoped sublist of results
      expected_results_list[3]["results"].each_with_index do | result, i |
        assert_equal result["title"], results[:results][3][:results][i][:title]
      end
      # iterate remaining results
      expected_results_list[3..-1].each_with_index do | result, i |
        assert_equal result["title"], results[:results][i+4][:title]
      end
    end
| Design looks good to me and the copy is correct! | 
9fe22cf    to
    4c2d431      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this would be better as an override of the results method?
def results
  presentable_result_list = super # possibly a better local var name than this, but I'm currently unable to brain
  if unscoped_results.any?
    insertion_point = [results.count, 3].min
    unscoped_results_sublist = { results: unscoped_results, is_multiple_results: true }
     presentable_result_list.insert(insertion_point, unscoped_results_sublist)
  end
  presentable_result_list
endThen you wouldn't need to change results in to_hash above, and intent is clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaaaactually, I'm already overwriting results in this class to only dish out ScopedResults which I don't want the super to have to know about, so this won't work. There's probably still a clearer way though, want to come pair on it when you're free?
| Pedantic style comments, but otherwise seems to do the trick 👍 | 
When users search within a manual (this is doing a "scoped" search) we want to show them some results from the rest of GOV.UK (ie some "un-scoped" results) so that they are aware that here are other results available that might be useful. This commit adds a third rummager request for scoped searches which returns three un-scoped results. This request is built by removing the scoping `filer_manual[]=this/manual` and adding an extra parameter `reject_manual[]=this/manual` which tells rummager we don't want any results that occur in this manual.
Since out code for scoped searches is getting a bit more involved with the inclusion of un-scoped results, let's extract this functionality to a new presenter `scoped_search_results_presenter`. This commit just extracts the existing functionality into a new presenter, no new features are added.
4c2d431    to
    3c05577      
    Compare
  
    This commit:
  - adds methods to `scoped_search_results_presenter` to show unscoped
results from rummager in the view.
  - Amends `search_results_presenter` to put the `.to_hash` call inside the
  `.map` on the result builder. So now whenever `results` is called the
  returned array is read to be sent to the view. This is because we call
  `results` from `scoped_search_results_presenter` now too.
  - Adds a template for unscoped results
  - adds tests for `scoped_search_results_presenter`
`presentable_result_list` is the starting point for the biggest change
here. I'm not sure the implementation choices here are very obvious so
I'll explain them.
The design (results with an embedded list of other results) is difficult
to represent semantically in HTML. Ideally the extra results would be in
an `<aside>` tag outside of the result list, but the design has them
interrupting the list so that sighted users will notice them.
A compromise that I'm happy with is to have them nested in the list of
results like so:
```
<li>result 1</li>
<li>result 2</li>
<li>result 3</li>
<li>More results from GOV.UK
  <ol>
    <li>..</li>
    <li>..</li>
    <li>..</li>
  </ol>
</li>
<li>result 4</li>
etc
```
Given this markup, and the constraint of using a logic-less templating
language (mustache) the best way I could thing to achieve this HTML
was to pass mustache an object that contains this structure. The
responsibility for mashing up the scoped results and unscoped results
falls to `presentable_result_list`.
This software pattern is a bit uncomfortable because it pushes the
design of the interface ("the unscoped results should be nested") onto
the presenter, though it should be the view's responsibility. However
it is the only way I can think to write it.
    3c05577    to
    a933fc9      
    Compare
  
    | OK I think I've responded to all the comments now, thanks everyone! | 
| Looks good to me 👍 | 
| 👍 | 
Show other results from GOV.UK in a scoped search
Pivotal: https://www.pivotaltracker.com/story/show/
What
This PR exposes the top three search results from the whole of GOV.UK in a search that has been scoped to a single document.
Before:

After:

Summary of commits:
search_api.rbto add an the additional call to rummager for three GOV.UK wide search results. Tests for this request are also included in this commit.ScopedSearchResultsPresenterand adds tests for this new presenter.search_api.rbin 5b7049b, and formats them properly and displays them in the view.How to review this PR
I've done quite a lot of hindsight based refactoring so each commit should make sense in isolation. Review however you prefer.
Who should review this PR