bento_search 1.7.0.beta.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ <% # An initially hidden div with loading msg/spinner that will be shown
2
+ # by js on ajax load
3
+ %>
4
+
5
+ <noscript>
6
+ <%= I18n.t("bento_search.ajax_noscript") %>
7
+ </noscript>
8
+
9
+ <%=
10
+ content_tag(:div,
11
+ :class => "bento_search_ajax_loading",
12
+ :style => "display:none") do
13
+ image_tag("bento_search/large_loader.gif",
14
+ :alt => I18n.translate("bento_search.ajax_loading")
15
+ )
16
+ end
17
+ %>
@@ -1,6 +1,6 @@
1
- <%= link_to(link.label, link.url,
2
- :rel => link.rel,
1
+ <%= link_to(link.label, link.url,
2
+ :rel => link.rel,
3
3
  :class => (link.style_classes + ["bento_search_link", "btn", "btn-mini", "btn-default", "btn-sm"]),
4
- :target => link.target
4
+ :target => local_assigns[:target] || link.target
5
5
  ) %>
6
6
 
@@ -47,6 +47,18 @@ module BentoSearch
47
47
  # Avoid deprecation warnings in ruby 2.3.0
48
48
  RubyTimeoutClass = (defined?(Timeout::Error) ? Timeout::Error : TimeoutError)
49
49
 
50
+ @@defaults = Confstruct::Configuration.new(
51
+ error_partial: 'bento_search/search_error',
52
+ item_partial: 'bento_search/std_item',
53
+ no_results_partial: 'bento_search/no_results',
54
+ ajax_loading_partial: 'bento_search/ajax_loading'
55
+ )
56
+ def self.set_defaults(hash)
57
+ @@defaults.merge!(hash)
58
+ end
59
+ def self.defaults
60
+ @@defaults
61
+ end
50
62
  end
51
63
 
52
64
 
@@ -1,5 +1,7 @@
1
1
  module BentoSearch
2
2
  class Engine < ::Rails::Engine
3
3
  #isolate_namespace BentoSearch
4
+
5
+ config.assets.precompile += %w( bento_search/large_loader.gif )
4
6
  end
5
7
  end
@@ -1,3 +1,3 @@
1
1
  module BentoSearch
2
- VERSION = "1.7.0.beta.1"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -2,12 +2,14 @@ require 'test_helper'
2
2
 
3
3
  class EdsEngineTest < ActiveSupport::TestCase
4
4
  extend TestWithCassette
5
-
5
+
6
6
  @@user_id = (ENV['EDS_USER_ID'] || 'DUMMY_USER_ID')
7
7
  @@password = (ENV['EDS_PASSWORD'] || 'DUMMY_PWD')
8
- @@profile = (ENV['EDS_PROFILE'] || 'edsapi')
9
-
10
-
8
+ @@profile = (ENV['EDS_PROFILE'] || 'wsapi')
9
+ # something where the first hit will be from catalog for the profile above
10
+ @@catalog_result_query = (ENV['EDS_CATALOG_RESULT_QUERY'] || 'New York exposed the gilded age police scandal that launched the progressive era Daniel Czitrom')
11
+ @@catalog_ebook_result_query = (ENV['EDS_CATALOG_EBOOK_RESULT_QUERY'] || 'Stakeholder forum on federal wetlands mitigation environmental law institute')
12
+ @@catalog_custom_result_query = (ENV['EDS_CATALOG_CUSTOM_RESULT_QUERY'] || 'Drafting New York Civil-Litigation Documents Part XXIV Summary-Judgment Motions Continued')
11
13
  VCR.configure do |c|
12
14
  c.filter_sensitive_data("DUMMY_USER_ID", :eds) { @@user_id }
13
15
  c.filter_sensitive_data("DUMMY_PWD", :eds) { @@password }
@@ -16,140 +18,170 @@ class EdsEngineTest < ActiveSupport::TestCase
16
18
  def setup
17
19
  # Class-level remembered auth token messes up our VCR-recording,
18
20
  # since one test will try to use an auth token fetched by a different
19
- # test. For testing, blank out the cache before each test.
21
+ # test. For testing, blank out the cache before each test.
20
22
  BentoSearch::EdsEngine.remembered_auth = nil
21
23
 
22
24
  @config = {:user_id => @@user_id, :password => @@password, :profile => @@profile, :auth => true}
23
25
  @engine = BentoSearch::EdsEngine.new(@config)
24
26
  end
25
-
27
+
26
28
  test "construct simple search, with comma escaping" do
27
29
  url = @engine.construct_search_url(:query => "foo, bar,baz")
28
-
30
+
29
31
  query_params = CGI.parse( URI.parse(url).query )
30
32
 
31
33
  assert_equal ["all"], query_params["searchmode"]
32
-
34
+
33
35
  assert_equal ["detailed"], query_params["view"]
34
-
35
- assert_equal ["AND,foo bar baz"], query_params["query"]
36
+
37
+ assert_equal ["AND,foo bar baz"], query_params["query"]
36
38
  end
37
-
39
+
38
40
  test "only_source_types config" do
39
41
  engine = BentoSearch::EdsEngine.new( @config.merge(:only_source_types => [
40
42
  "Academic Journals", "Magazines"
41
43
  ]))
42
-
44
+
43
45
  url = engine.construct_search_url(:query => "cancer", :per_page => 10)
44
-
46
+
45
47
  query_params = CGI.parse( URI.parse(url).query )
46
-
48
+
47
49
  # should be
48
50
  # facetfilter=1,SourceType:Academic Journals,SourceType:Magazines
49
51
  # but with value query encoded
50
-
52
+
51
53
  assert_equal 1, query_params["facetfilter"].length
52
-
54
+
53
55
  facetfilter = query_params["facetfilter"].first
54
-
56
+
55
57
  parts = facetfilter.split(",")
56
-
58
+
57
59
  assert_equal 3, parts.length
58
-
60
+
59
61
  assert_equal "1", parts.first
60
-
62
+
61
63
  assert_includes parts, "SourceType:Academic Journals"
62
- assert_includes parts, "SourceType:Magazines"
64
+ assert_includes parts, "SourceType:Magazines"
63
65
  end
64
-
66
+
65
67
  def test_has_http_timeout_set
66
68
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.receive_timeout
67
69
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.send_timeout
68
70
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.connect_timeout
69
- end
71
+ end
72
+
70
73
 
71
-
72
74
  test_with_cassette("get_auth_token failure", :eds) do
73
75
  engine = BentoSearch::EdsEngine.new(:user_id => "bad", :password => "bad", :profile => "bad")
74
76
  exception = assert_raise(BentoSearch::EdsEngine::EdsCommException) do
75
77
  token = engine.get_auth_token
76
- end
77
-
78
+ end
79
+
78
80
  assert_present exception.http_status
79
- assert_present exception.http_body
81
+ assert_present exception.http_body
80
82
  end
81
-
83
+
82
84
  test_with_cassette("get_auth_token", :eds) do
83
85
  token = @engine.get_auth_token
84
-
86
+
85
87
  assert_present token
86
88
  end
87
-
89
+
88
90
  # No idea why VCR is having buggy problems with record and playback of this request
89
- # We'll emcompass it in the get_with_auth test
91
+ # We'll emcompass it in the get_with_auth test
90
92
  #
91
- #test_with_cassette("with_session", :eds, :match_requests_on => [:method, :uri, :headers, :body]) do
93
+ #test_with_cassette("with_session", :eds, :match_requests_on => [:method, :uri, :headers, :body]) do
92
94
  # @engine.with_session do |session_token|
93
95
  # assert_present session_token
94
- # end
96
+ # end
95
97
  #end
96
-
98
+
97
99
  test_with_cassette("get_with_auth", :eds) do
98
100
  @engine.with_session do |session_token|
99
101
  assert_present session_token
100
-
102
+
101
103
  # Coudln't get 'info' request to work even as a test, let's
102
- # try a simple search.
104
+ # try a simple search.
103
105
  url = "#{@engine.configuration.base_url}info"
104
106
  response = @engine.get_with_auth(url, session_token)
105
-
107
+
106
108
  assert_present response
107
109
  assert_kind_of Nokogiri::XML::Document, response
108
-
109
- assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
110
- end
110
+
111
+ assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
112
+ end
111
113
  end
112
-
114
+
113
115
  test_with_cassette("get_with_auth recovers from bad auth", :eds) do
114
116
  @engine.with_session do |session_token|
115
117
  BentoSearch::EdsEngine.remembered_auth = "BAD"
116
-
118
+
117
119
  url = "#{@engine.configuration.base_url}info"
118
120
  response = @engine.get_with_auth(url, session_token)
119
-
121
+
120
122
  assert_present response
121
123
  assert_kind_of Nokogiri::XML::Document, response
122
-
123
- assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
124
- end
125
-
124
+
125
+ assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
126
+ end
127
+
126
128
  BentoSearch::EdsEngine.remembered_auth = nil
127
129
  end
128
-
130
+
129
131
  test_with_cassette("basic search smoke test", :eds) do
130
- results = @engine.search("cancer")
131
-
132
+ results = @engine.search("cancer")
133
+
132
134
  assert_present results
133
-
135
+
134
136
  assert_present results.total_items
135
-
137
+
136
138
  first = results.first
137
139
 
138
140
  assert_present first.title
139
141
  assert first.title.html_safe? # yeah, for now we use EDS html
140
-
142
+
141
143
  assert_present first.abstract
142
144
  assert_present first.abstract.html_safe?
143
-
144
- assert_present first.custom_data["citation_blob"]
145
-
145
+
146
+ assert_present first.custom_data["citation_blob"]
147
+
148
+ assert_present first.source_title
149
+ assert_present first.issn
150
+ assert_present first.volume
151
+ assert_present first.issue
152
+ assert_present first.year
153
+ assert_present first.publication_date
154
+ assert_present first.start_page
155
+ assert_present first.end_page
156
+
157
+ assert_present first.doi
158
+
146
159
  assert_present first.format_str
147
-
160
+
148
161
  assert_present first.unique_id
149
162
  # EDS id is db name, colon, accession number
150
163
  assert_match /.+\:.+/, first.unique_id
151
164
  end
152
-
153
-
165
+
166
+ test_with_cassette("catalog query", :eds) do
167
+ results = @engine.search(@@catalog_result_query)
168
+
169
+ cat_result = results.first
170
+
171
+ assert_present cat_result.custom_data[:holdings]
172
+ assert cat_result.custom_data[:holdings].all? { |h| h.location.present? && h.call_number.present? }
173
+ end
174
+
175
+ test_with_cassette("catalog ebook query", :eds) do
176
+ result = @engine.search(@@catalog_ebook_result_query).first
177
+
178
+ assert_present result.other_links
179
+ end
180
+
181
+ test_with_cassette("FullText CustomLink", :eds) do
182
+ result = @engine.search(@@catalog_custom_result_query).first
183
+ assert_present result
184
+ assert result.other_links.any? { |r| r.label.present? && r.label != "Link" && r.url.present? && URI::regexp =~ r.url && r.rel == "alternate"}
185
+ end
154
186
  end
155
187
 
@@ -288,5 +288,16 @@ class ParseSearchArgumentsTest < ActiveSupport::TestCase
288
288
  assert_equal "I am a horrible engine", results.error[:exception].message, "results.error has right exception"
289
289
  end
290
290
 
291
+ def test_cover_consistency_api
292
+ d = Dummy.new()
293
+ assert_nil d.engine_id
294
+ assert_equal({}, d.display_configuration)
295
+
296
+ d = Dummy.new(id: 'test', for_display: { testkey: 'test' })
297
+ assert_equal 'test', d.engine_id
298
+ assert_equal({ testkey: 'test' }, d.display_configuration)
299
+
300
+ end
301
+
291
302
  end
292
303
 
@@ -132,6 +132,7 @@ class SearchEngineTest < ActiveSupport::TestCase
132
132
 
133
133
  assert results.failed?, "marked failed"
134
134
  assert_present results.error
135
+ assert_present results.error[:exception]
135
136
  assert_equal "raises", results.engine_id
136
137
  assert_present results.search_args
137
138
  assert_equal "foo", results.search_args[:query]
@@ -139,6 +140,17 @@ class SearchEngineTest < ActiveSupport::TestCase
139
140
  assert_equal( {:foo => "foo"}, results.display_configuration )
140
141
  end
141
142
 
143
+ test "can set auto rescued exceptions on instance" do
144
+ engine = MockEngine.new(:id => "raises", :raise_exception_class => "StandardError", :for_display => {:foo => "foo"})
145
+ engine.auto_rescued_exceptions = [StandardError]
146
+
147
+ results = engine.search("foo", :per_page => 20)
148
+
149
+ assert results.failed?, "marked failed"
150
+ assert_present results.error
151
+ assert_present results.error[:exception]
152
+ end
153
+
142
154
 
143
155
  test "has empty :for_display config" do
144
156
  engine = MockEngine.new
@@ -0,0 +1,75 @@
1
+ require 'test_helper'
2
+
3
+ # Doesn't really test the concurrency, but basic smoke test with fake
4
+ # searchers.
5
+ class ConcurrentSearcherTest < ActiveSupport::TestCase
6
+ setup do
7
+ BentoSearch.register_engine("one") do |conf|
8
+ conf.engine = "MockEngine"
9
+ end
10
+ BentoSearch.register_engine("two") do |conf|
11
+ conf.engine = "MockEngine"
12
+ end
13
+ BentoSearch.register_engine("three") do |conf|
14
+ conf.engine = "MockEngine"
15
+ end
16
+
17
+ BentoSearch.register_engine("raiser") do |conf|
18
+ conf.engine = "MockEngine"
19
+ conf.raise_exception_class = "StandardError"
20
+ end
21
+ end
22
+
23
+ teardown do
24
+ BentoSearch.reset_engine_registrations!
25
+ end
26
+
27
+
28
+ def test_concurrent_search
29
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :two, :three)
30
+ returnval = searcher.search("cancer")
31
+
32
+ assert_same searcher, returnval
33
+
34
+ results = searcher.results
35
+
36
+ assert_kind_of Hash, results
37
+ assert_equal ["one", "two", "three"].sort, results.keys.sort
38
+
39
+ ["one", "two", "three"].each do |key|
40
+ assert_kind_of BentoSearch::Results, results[key]
41
+ end
42
+
43
+ # call results again, we get the exact same hash back.
44
+ new_results = searcher.results
45
+ assert_kind_of Hash, new_results
46
+ assert( results.equal? new_results )
47
+ end
48
+
49
+ def test_results_before_search
50
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :two, :three)
51
+
52
+ assert_raises(ArgumentError) do
53
+ results = searcher.results
54
+ end
55
+ end
56
+
57
+
58
+ def test_concurrent_search_uncaught_exception
59
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :raiser, :two)
60
+ results = searcher.search("cancer").results
61
+
62
+ [:one, :two].each do |success_engine_id|
63
+ assert( results[success_engine_id.to_s].kind_of?(BentoSearch::Results) )
64
+ assert( !results[success_engine_id.to_s].failed? )
65
+ end
66
+
67
+
68
+ error_results = results["raiser"]
69
+
70
+ assert( error_results.kind_of?(BentoSearch::Results) )
71
+ assert( error_results.failed? )
72
+ assert( error_results.error[:exception].present? )
73
+ assert( error_results.engine_id == "raiser" )
74
+ end
75
+ end
@@ -21,29 +21,26 @@ class MultiSearcherTest < ActiveSupport::TestCase
21
21
 
22
22
 
23
23
  def test_multisearch
24
- searcher = BentoSearch::MultiSearcher.new(:one, :two, :three)
25
- start_returnval = searcher.start("cancer")
24
+ ActiveSupport::Deprecation.silence do
25
+ searcher = BentoSearch::MultiSearcher.new(:one, :two, :three)
26
+ start_returnval = searcher.start("cancer")
26
27
 
27
- assert_same searcher, start_returnval
28
+ assert_same searcher, start_returnval
28
29
 
29
- results = searcher.results
30
+ results = searcher.results
30
31
 
31
- assert_kind_of Hash, results
32
- assert_equal ["one", "two", "three"].sort, results.keys.sort
32
+ assert_kind_of Hash, results
33
+ assert_equal ["one", "two", "three"].sort, results.keys.sort
33
34
 
34
- ["one", "two", "three"].each do |key|
35
- assert_kind_of BentoSearch::Results, results[key]
36
- end
37
-
38
- # call results again, we get an empty hash, can only call
39
- # results once per start.
40
- new_results = searcher.results
41
- assert_kind_of Hash, new_results
42
- assert_empty new_results
35
+ ["one", "two", "three"].each do |key|
36
+ assert_kind_of BentoSearch::Results, results[key]
37
+ end
43
38
 
39
+ # call results again, we get an empty hash, can only call
40
+ # results once per start.
41
+ new_results = searcher.results
42
+ assert_kind_of Hash, new_results
43
+ assert_empty new_results
44
+ end
44
45
  end
45
-
46
-
47
-
48
-
49
46
  end