require 'spec_helper'
describe BlacklightUrlHelper do
let(:blacklight_config) do
Blacklight::Configuration.new.configure do |config|
config.index.title_field = 'title_display'
config.index.display_type_field = 'format'
end
end
before do
allow(helper).to receive(:search_action_path) do |*args|
catalog_index_url *args
end
allow(helper).to receive_messages(blacklight_config: blacklight_config)
allow(helper).to receive_messages(current_search_session: nil)
allow(helper).to receive(:search_session).and_return({})
end
describe "url_for_document" do
let(:controller_class) { ::CatalogController.new }
let(:doc) { SolrDocument.new }
before do
allow(helper).to receive_messages(controller: controller_class)
allow(helper).to receive_messages(controller_name: controller_class.controller_name)
end
it "should be a polymorphic routing-ready object" do
expect(helper.url_for_document(doc)).to eq doc
end
it "should allow for custom show routes" do
helper.blacklight_config.show.route = { controller: 'catalog' }
expect(helper.url_for_document(doc)).to eq({controller: 'catalog', action: :show, id: doc})
end
context "within bookmarks" do
let(:controller_class) { ::BookmarksController.new }
it "should use polymorphic routing" do
expect(helper.url_for_document(doc)).to eq doc
end
end
context "within an alternative catalog controller" do
let(:controller_class) { ::AlternateController.new }
before do
helper.blacklight_config.show.route = { controller: :current }
end
it "should support the :current controller configuration" do
expect(helper.url_for_document(doc)).to eq({controller: 'alternate', action: :show, id: doc})
end
end
it "should be a polymorphic route if the solr document responds to #to_model with a non-SolrDocument" do
some_model = double
doc = SolrDocument.new
allow(doc).to receive_messages(to_model: some_model)
expect(helper.url_for_document(doc)).to eq doc
end
end
describe "link_back_to_catalog" do
let(:query_params) {{:q => "query", :f => "facets", :controller=>'catalog'}}
let(:bookmarks_query_params) {{ :controller=>'bookmarks'}}
it "should build a link tag to catalog using session[:search] for query params" do
allow(helper).to receive(:current_search_session).and_return double(:query_params => query_params)
tag = helper.link_back_to_catalog
expect(tag).to match /q=query/
expect(tag).to match /f=facets/
expect(tag).to_not match /page=/
expect(tag).to_not match /per_page=/
end
it "should build a link tag to bookmarks using session[:search] for query params" do
allow(helper).to receive(:current_search_session).and_return double(:query_params => bookmarks_query_params)
tag = helper.link_back_to_catalog
expect(tag).to match /Back to Bookmarks/
expect(tag).to match /\/bookmarks/
end
context "with a search context" do
it "should use the current search session counter and per page information to construct the appropriate pagination context" do
allow(helper).to receive_messages(current_search_session: double(query_params: query_params))
allow(helper).to receive_messages(search_session: { 'per_page' => 15, 'counter' => 31 })
tag = helper.link_back_to_catalog
expect(tag).to match /page=3/
expect(tag).to match /per_page=15/
end
it "should omit per_page if the value is the same as the default" do
allow(helper).to receive_messages(current_search_session: double(query_params: query_params))
allow(helper).to receive_messages(search_session: { 'per_page' => 10, 'counter' => 31 })
tag = helper.link_back_to_catalog
expect(tag).to match /page=4/
expect(tag).to_not match /per_page=/
end
end
context "without current search context" do
before do
controller.request.assign_parameters(Rails.application.routes, 'catalog', 'show', id: '123')
allow(helper).to receive_messages(current_search_session: nil)
end
subject { helper.link_back_to_catalog }
it "should link to the catalog" do
expect(subject).to eq 'Back to Search'
end
end
context "when an alternate scope is passed in" do
let(:my_engine) { double("Engine") }
it "should call url_for on the engine scope" do
allow(helper).to receive(:current_search_session).and_return double(:query_params => query_params)
expect(my_engine).to receive(:url_for).and_return(url_for(query_params))
tag = helper.link_back_to_catalog(route_set: my_engine)
expect(tag).to match /Back to Search/
expect(tag).to match /q=query/
expect(tag).to match /f=facets/
end
end
end
describe "link_to_query" do
it "should build a link tag to catalog using query string (no other params)" do
query = "brilliant"
allow(helper).to receive_messages(params: {})
tag = helper.link_to_query(query)
expect(tag).to match /q=#{query}/
expect(tag).to match />#{query}<\/a>/
end
it "should build a link tag to catalog using query string and other existing params" do
query = "wonderful"
allow(helper).to receive_messages(params: {:qt => "title_search", :per_page => "50"})
tag = helper.link_to_query(query)
expect(tag).to match /qt=title_search/
expect(tag).to match /per_page=50/
end
it "should ignore existing :page param" do
query = "yes"
allow(helper).to receive_messages(params: {:page => "2", :qt => "author_search"})
tag = helper.link_to_query(query)
expect(tag).to match /qt=author_search/
expect(tag).to_not match /page/
end
it "should be html_safe" do
query = "brilliant"
allow(helper).to receive_messages(params: {:page => "2", :qt => "author_search"})
tag = helper.link_to_query(query)
expect(tag).to be_html_safe
end
end
describe "sanitize_search_params" do
it "should strip nil values" do
result = helper.sanitize_search_params(:a => nil, :b => 1)
expect(result).to_not have_key(:a)
expect(result[:b]).to eq 1
end
it "should remove blacklisted keys" do
result = helper.sanitize_search_params(:action => true, :controller => true, :id => true, :commit => true, :utf8 => true)
expect(result).to be_empty
end
end
describe "params_for_search" do
before do
allow(helper).to receive_messages(params: { 'default' => 'params'})
end
it "should default to using the controller's params" do
result = helper.params_for_search
expect(result).to eq({ 'default' => 'params' })
expect(params.object_id).to_not eq result.object_id
end
it "should let you pass in params to merge into the controller's params" do
source_params = { :q => 'query'}
result = helper.params_for_search( source_params )
expect(result).to include(:q => 'query', 'default' => 'params')
end
it "should not return blacklisted elements" do
source_params = { :action => 'action', :controller => 'controller', :id => "id", :commit => 'commit'}
result = helper.params_for_search(source_params)
expect(result.keys).to_not include(:action, :controller, :commit, :id)
end
it "should adjust the current page if the per_page changes" do
source_params = { :per_page => 20, :page => 5}
result = helper.params_for_search(source_params, :per_page => 100)
expect(result[:page]).to eq 1
end
it "should not adjust the current page if the per_page is the same as it always was" do
source_params = { :per_page => 20, :page => 5}
result = helper.params_for_search(source_params, :per_page => 20)
expect(result[:page]).to eq 5
end
it "should adjust the current page if the sort changes" do
source_params = { :sort => 'field_a', :page => 5}
result = helper.params_for_search(source_params, :sort => 'field_b')
expect(result[:page]).to eq 1
end
it "should not adjust the current page if the sort is the same as it always was" do
source_params = { :sort => 'field_a', :page => 5}
result = helper.params_for_search(source_params, :sort => 'field_a')
expect(result[:page]).to eq 5
end
describe "params_for_search with a block" do
it "should evalute the block and allow it to add or remove keys" do
result = helper.params_for_search({:a => 1, :b => 2}, :c => 3) do |params|
params.except! :a, :b
params[:d] = 'd'
end
expect(result.keys).to_not include(:a, :b)
expect(result[:c]).to eq 3
expect(result[:d]).to eq 'd'
end
end
end
describe "start_over_path" do
it 'should be the catalog path with the current view type' do
allow(blacklight_config).to receive(:view) { { list: nil, abc: nil} }
allow(helper).to receive_messages(:blacklight_config => blacklight_config)
expect(helper.start_over_path(:view => 'abc')).to eq catalog_index_url(:view => 'abc')
end
it 'should not include the current view type if it is the default' do
allow(blacklight_config).to receive(:view) { { list: nil, asdf: nil} }
allow(helper).to receive_messages(:blacklight_config => blacklight_config)
expect(helper.start_over_path(:view => 'list')).to eq catalog_index_url
end
end
describe "link_to_document" do
it "should consist of the document title wrapped in a " do
data = {'id'=>'123456','title_display'=>['654321'] }
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => :title_display })).to have_selector("a", :text => '654321', :count => 1)
end
it "should accept and return a string label" do
data = {'id'=>'123456','title_display'=>['654321'] }
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => "title_display" })).to have_selector("a", :text => 'title_display', :count => 1)
end
it "should accept and return a Proc" do
data = {'id'=>'123456','title_display'=>['654321'] }
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => Proc.new { |doc, opts| doc.get(:id) + ": " + doc.get(:title_display) } })).to have_selector("a", :text => '123456: 654321', :count => 1)
end
it "should return id when label is missing" do
data = {'id'=>'123456'}
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => :title_display })).to have_selector("a", :text => '123456', :count => 1)
end
it "should be html safe" do
data = {'id'=>'123456'}
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => :title_display })).to be_html_safe
end
it "should convert the counter parameter into a data- attribute" do
data = {'id'=>'123456','title_display'=>['654321']}
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document, { :label => :title_display, :counter => 5 })).to match /\/catalog\/123456\/track\?counter=5/
end
it "should merge the data- attributes from the options with the counter params" do
data = {'id'=>'123456','title_display'=>['654321']}
@document = SolrDocument.new(data)
link = helper.link_to_document @document, { data: { x: 1 } }
expect(link).to have_selector '[data-x]'
expect(link).to have_selector '[data-context-href]'
end
it "passes on the title attribute to the link_to_with_data method" do
@document = SolrDocument.new('id'=>'123456')
expect(helper.link_to_document(@document,:label=>"Some crazy long label...",:title=>"Some crazy longer label")).to match(/title=\"Some crazy longer label\"/)
end
it "doesn't add an erroneous title attribute if one isn't provided" do
@document = SolrDocument.new('id'=>'123456')
expect(helper.link_to_document(@document,:label=>"Some crazy long label...")).to_not match(/title=/)
end
it "should work with integer ids" do
data = {'id'=> 123456 }
@document = SolrDocument.new(data)
expect(helper.link_to_document(@document)).to have_selector("a")
end
end
describe "link_to_previous_search" do
it "should link to the given search parameters" do
params = {}
allow(helper).to receive(:render_search_to_s).with(params).and_return "link text"
expect(helper.link_to_previous_search({})).to eq helper.link_to("link text", helper.search_action_path)
end
end
describe "add_facet_params" do
before do
@params_no_existing_facet = {:q => "query", :search_field => "search_field", :per_page => "50"}
@params_existing_facets = {:q => "query", :search_field => "search_field", :per_page => "50", :f => {"facet_field_1" => ["value1"], "facet_field_2" => ["value2", "value2a"]}}
end
it "should add facet value for no pre-existing facets" do
allow(helper).to receive(:params).and_return(@params_no_existing_facet)
result_params = helper.add_facet_params("facet_field", "facet_value")
expect(result_params[:f]).to be_a_kind_of(Hash)
expect(result_params[:f]["facet_field"]).to be_a_kind_of(Array)
expect(result_params[:f]["facet_field"]).to eq ["facet_value"]
end
it "should add a facet param to existing facet constraints" do
allow(helper).to receive(:params).and_return(@params_existing_facets)
result_params = helper.add_facet_params("facet_field_2", "new_facet_value")
expect(result_params[:f]).to be_a_kind_of(Hash)
@params_existing_facets[:f].each_pair do |facet_field, value_list|
expect(result_params[:f][facet_field]).to be_a_kind_of(Array)
if facet_field == 'facet_field_2'
expect(result_params[:f][facet_field]).to eq (@params_existing_facets[:f][facet_field] | ["new_facet_value"])
else
expect(result_params[:f][facet_field]).to eq @params_existing_facets[:f][facet_field]
end
end
end
it "should leave non-facet params alone" do
[@params_existing_facets, @params_no_existing_facet].each do |params|
allow(helper).to receive(:params).and_return(params)
result_params = helper.add_facet_params("facet_field_2", "new_facet_value")
params.each_pair do |key, value|
next if key == :f
expect(result_params[key]).to eq params[key]
end
end
end
it "should replace facets for facets configured as single" do
allow(helper).to receive(:facet_configuration_for_field).with('single_value_facet_field').and_return(double(:single => true))
params = { :f => { 'single_value_facet_field' => 'other_value'}}
allow(helper).to receive(:params).and_return params
result_params = helper.add_facet_params('single_value_facet_field', 'my_value')
expect(result_params[:f]['single_value_facet_field']).to have(1).item
expect(result_params[:f]['single_value_facet_field'].first).to eq 'my_value'
end
it "should accept a FacetItem instead of a plain facet value" do
result_params = helper.add_facet_params('facet_field_1', double(:value => 123))
expect(result_params[:f]['facet_field_1']).to include(123)
end
it "should defer to the field set on a FacetItem" do
result_params = helper.add_facet_params('facet_field_1', double(:field => 'facet_field_2', :value => 123))
expect(result_params[:f]['facet_field_1']).to be_blank
expect(result_params[:f]['facet_field_2']).to include(123)
end
it "should add any extra fq parameters from the FacetItem" do
result_params = helper.add_facet_params('facet_field_1', double(:value => 123, :fq => {'facet_field_2' => 'abc'}))
expect(result_params[:f]['facet_field_1']).to include(123)
expect(result_params[:f]['facet_field_2']).to include('abc')
end
end
describe "add_facet_params_and_redirect" do
before do
catalog_facet_params = {:q => "query",
:search_field => "search_field",
:per_page => "50",
:page => "5",
:f => {"facet_field_1" => ["value1"], "facet_field_2" => ["value2", "value2a"]},
Blacklight::Solr::FacetPaginator.request_keys[:page] => "100",
Blacklight::Solr::FacetPaginator.request_keys[:sort] => "index",
:id => 'facet_field_name'
}
allow(helper).to receive(:params).and_return(catalog_facet_params)
end
it "should not include request parameters used by the facet paginator" do
params = helper.add_facet_params_and_redirect("facet_field_2", "facet_value")
bad_keys = Blacklight::Solr::FacetPaginator.request_keys.values + [:id]
bad_keys.each do |paginator_key|
expect(params.keys).to_not include(paginator_key)
end
end
it 'should remove :page request key' do
params = helper.add_facet_params_and_redirect("facet_field_2", "facet_value")
expect(params.keys).to_not include(:page)
end
it "should otherwise do the same thing as add_facet_params" do
added_facet_params = helper.add_facet_params("facet_field_2", "facet_value")
added_facet_params_from_facet_action = helper.add_facet_params_and_redirect("facet_field_2", "facet_value")
expect(added_facet_params_from_facet_action).to eq added_facet_params.except(Blacklight::Solr::FacetPaginator.request_keys[:page], Blacklight::Solr::FacetPaginator.request_keys[:sort])
end
end
describe "#bookmarks_export_url" do
it "should be the bookmark url with an encrypted user token" do
allow(helper).to receive_messages(encrypt_user_id: 'xyz', current_or_guest_user: double(id: 123))
url = helper.bookmarks_export_url(:html)
expect(url).to eq helper.bookmarks_url(format: :html, encrypted_user_id: 'xyz')
end
end
end