# frozen_string_literal: true
RSpec.describe Blacklight::UrlHelperBehavior do
around { |test| Deprecation.silence(described_class) { test.call } }
let(:blacklight_config) do
Blacklight::Configuration.new.configure do |config|
config.index.title_field = 'title_tsim'
config.index.display_type_field = 'format'
end
end
let(:parameter_class) { ActionController::Parameters }
before do
allow(controller).to receive(:controller_name).and_return('test')
allow(helper).to receive(:search_action_path) do |*args|
search_catalog_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)
allow(helper).to receive_messages(params: parameter_class.new)
end
it "is a polymorphic routing-ready object" do
expect(helper.url_for_document(doc)).to eq doc
end
it "allows 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 "uses 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 }
allow(helper).to receive(:params).and_return(parameter_class.new(controller: 'alternate'))
end
it "supports the :current controller configuration" do
expect(helper.url_for_document(doc)).to eq(controller: 'alternate', action: :show, id: doc)
end
end
it "is 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' } }
before do
# this is bad data but the legacy test exercises search fields, not filters
blacklight_config.configure do |config|
config.search_state_fields << :f
end
end
it "builds 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).not_to match /page=/
expect(tag).not_to match /per_page=/
end
it "builds 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 %r{/bookmarks}
end
context "with a search context" do
it "uses 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 "omits 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).not_to match /per_page=/
end
end
context "without current search context" do
subject { helper.link_back_to_catalog }
before do
controller.request.assign_parameters(Rails.application.routes, 'catalog', 'show', { id: '123' }, '/catalog/123', [:controller, :action, :id])
allow(helper).to receive_messages(current_search_session: nil)
end
it "links to the catalog" do
expect(subject).to eq 'Back to Search'
end
end
context "when an alternate scope is passed in" do
subject(:tag) { helper.link_back_to_catalog(route_set: my_engine) }
let(:my_engine) { double("Engine") }
before do
allow(helper).to receive(:current_search_session).and_return double(query_params: query_params)
end
it "calls url_for on the engine scope" do
expect(my_engine).to receive(:url_for)
.with({ q: "query", f: "facets", controller: "catalog" })
.and_return('link-url')
expect(tag).to match /Back to Search/
expect(tag).to match /link-url/
end
end
end
describe "link_to_previous_document" do
context "when the argument is nil" do
subject { helper.link_to_previous_document(nil) }
it { is_expected.to eq '« Previous' }
end
end
describe "link_to_query" do
it "builds a link tag to catalog using query string (no other params)" do
query = "brilliant"
allow(helper).to receive_messages(params: parameter_class.new)
tag = helper.link_to_query(query)
expect(tag).to match /q=#{query}/
expect(tag).to match %r{>#{query}}
end
it "builds a link tag to catalog using query string and other existing params" do
query = "wonderful"
allow(helper).to receive_messages(params: parameter_class.new(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 "ignores existing :page param" do
query = "yes"
allow(helper).to receive_messages(params: parameter_class.new(page: "2", qt: "author_search"))
tag = helper.link_to_query(query)
expect(tag).to match /qt=author_search/
expect(tag).not_to match /page/
end
it "is html_safe" do
query = "brilliant"
allow(helper).to receive_messages(params: parameter_class.new(page: "2", qt: "author_search"))
tag = helper.link_to_query(query)
expect(tag).to be_html_safe
end
end
describe "start_over_path" do
it 'is the catalog path with the current view type' do
allow(blacklight_config).to receive(:view).and_return(list: nil, abc: nil)
allow(helper).to receive_messages(blacklight_config: blacklight_config)
expect(helper.start_over_path(view: 'abc')).to eq search_catalog_url(view: 'abc')
end
it 'does not include the current view type if it is the default' do
allow(blacklight_config).to receive(:view).and_return(list: nil, asdf: nil)
allow(helper).to receive_messages(blacklight_config: blacklight_config)
expect(helper.start_over_path(view: 'list')).to eq search_catalog_url
end
end
describe "link_to_document" do
let(:title_tsim) { '654321' }
let(:id) { '123456' }
let(:data) { { 'id' => id, 'title_tsim' => [title_tsim] } }
let(:document) { SolrDocument.new(data) }
before do
allow(controller).to receive(:action_name).and_return('index')
allow(helper.main_app).to receive(:track_test_path).and_return('tracking url')
allow(helper.main_app).to receive(:respond_to?).with('track_test_path').and_return(true)
end
it "consists of the document title wrapped in a " do
allow(Deprecation).to receive(:warn)
expect(helper.link_to_document(document, :title_tsim)).to have_selector("a", text: '654321', count: 1)
end
it "accepts and returns a string label" do
expect(helper.link_to_document(document, 'This is the title')).to have_selector("a", text: 'This is the title', count: 1)
end
it "accepts and returns a Proc" do
allow(Deprecation).to receive(:warn)
expect(helper.link_to_document(document, proc { |doc, _opts| doc[:id] + ": " + doc.first(:title_tsim) })).to have_selector("a", text: '123456: 654321', count: 1)
end
context 'when label is missing' do
let(:data) { { 'id' => id } }
it "returns id" do
allow(Deprecation).to receive(:warn)
expect(helper.link_to_document(document, :title_tsim)).to have_selector("a", text: '123456', count: 1)
end
it "is html safe" do
allow(Deprecation).to receive(:warn)
expect(helper.link_to_document(document, :title_tsim)).to be_html_safe
end
it "passes on the title attribute to the link_to_with_data method" do
expect(helper.link_to_document(document, "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
expect(helper.link_to_document(document, "Some crazy long label...")).not_to match(/title=/)
end
context "with an integer id" do
let(:id) { 123_456 }
it "works" do
expect(helper.link_to_document(document)).to have_selector("a")
end
end
end
it "converts the counter parameter into a data- attribute" do
allow(Deprecation).to receive(:warn)
expect(helper.link_to_document(document, :title_tsim, counter: 5)).to include 'data-context-href="tracking url"'
expect(helper.main_app).to have_received(:track_test_path).with(hash_including(id: have_attributes(id: '123456'), counter: 5))
end
it "includes the data- attributes from the options" do
link = helper.link_to_document document, data: { x: 1 }
expect(link).to have_selector '[data-x]'
end
it 'adds a controller-specific tracking attribute' do
expect(helper.main_app).to receive(:track_test_path).and_return('/asdf')
link = helper.link_to_document document, data: { x: 1 }
expect(link).to have_selector '[data-context-href="/asdf"]'
end
end
describe "link_to_previous_search" do
let(:params) { {} }
it "links to the given search parameters" do
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 "#bookmarks_export_url" do
it "is 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
describe "#session_tracking_path" do
let(:document) { SolrDocument.new(id: 1) }
it "determines the correct route for the document class" do
allow(helper.main_app).to receive(:track_test_path).with({ id: have_attributes(id: 1) }).and_return('x')
expect(helper.session_tracking_path(document)).to eq 'x'
end
it "passes through tracking parameters" do
allow(helper.main_app).to receive(:track_test_path).with({ id: have_attributes(id: 1), x: 1 }).and_return('x')
expect(helper.session_tracking_path(document, x: 1)).to eq 'x'
end
it "uses the track_search_session configuration to determine whether to track the search session" do
blacklight_config.track_search_session = false
expect(helper.session_tracking_path(document, x: 1)).to eq nil
end
end
end