supplejack_client 1.0.1

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +16 -0
  5. data/Guardfile +24 -0
  6. data/LICENSE.txt +674 -0
  7. data/README.md +153 -0
  8. data/Rakefile +9 -0
  9. data/lib/generators/locales/en.yml +11 -0
  10. data/lib/generators/supplejack/install_generator.rb +28 -0
  11. data/lib/generators/templates/README +19 -0
  12. data/lib/generators/templates/supplejack_client.rb +120 -0
  13. data/lib/supplejack/config.rb +116 -0
  14. data/lib/supplejack/controllers/helpers.rb +172 -0
  15. data/lib/supplejack/engine.rb +20 -0
  16. data/lib/supplejack/exceptions.rb +17 -0
  17. data/lib/supplejack/facet.rb +33 -0
  18. data/lib/supplejack/item.rb +94 -0
  19. data/lib/supplejack/item_relation.rb +73 -0
  20. data/lib/supplejack/log_subscriber.rb +58 -0
  21. data/lib/supplejack/paginated_collection.rb +61 -0
  22. data/lib/supplejack/record.rb +147 -0
  23. data/lib/supplejack/request.rb +95 -0
  24. data/lib/supplejack/search.rb +346 -0
  25. data/lib/supplejack/url_formats/item_hash.rb +208 -0
  26. data/lib/supplejack/user.rb +132 -0
  27. data/lib/supplejack/user_set.rb +349 -0
  28. data/lib/supplejack/user_set_relation.rb +143 -0
  29. data/lib/supplejack/util.rb +120 -0
  30. data/lib/supplejack/version.rb +10 -0
  31. data/lib/supplejack_client.rb +29 -0
  32. data/spec/spec_helper.rb +23 -0
  33. data/spec/supplejack/controllers/helpers_spec.rb +277 -0
  34. data/spec/supplejack/facet_spec.rb +44 -0
  35. data/spec/supplejack/item_relation_spec.rb +111 -0
  36. data/spec/supplejack/item_spec.rb +115 -0
  37. data/spec/supplejack/log_subscriber_spec.rb +40 -0
  38. data/spec/supplejack/paginated_collection_spec.rb +43 -0
  39. data/spec/supplejack/record_spec.rb +255 -0
  40. data/spec/supplejack/request_spec.rb +195 -0
  41. data/spec/supplejack/search_spec.rb +727 -0
  42. data/spec/supplejack/url_formats/item_hash_spec.rb +341 -0
  43. data/spec/supplejack/user_set_relation_spec.rb +149 -0
  44. data/spec/supplejack/user_set_spec.rb +465 -0
  45. data/spec/supplejack/user_spec.rb +159 -0
  46. data/supplejack_client.gemspec +30 -0
  47. metadata +159 -0
@@ -0,0 +1,341 @@
1
+ # The Supplejack Client code is Crown copyright (C) 2014, New Zealand Government,
2
+ # and is licensed under the GNU General Public License, version 3.
3
+ # See https://github.com/DigitalNZ/supplejack_client for details.
4
+ #
5
+ # Supplejack was created by DigitalNZ at the National Library of NZ
6
+ # and the Department of Internal Affairs. http://digitalnz.org/supplejack
7
+
8
+ require 'spec_helper'
9
+
10
+ def item_hash(params={}, search=nil)
11
+ Supplejack::UrlFormats::ItemHash.new(params, search)
12
+ end
13
+
14
+ module Supplejack
15
+ module UrlFormats
16
+ describe ItemHash do
17
+
18
+ describe '#to_api_hash' do
19
+ it 'doesn\'t return blank text' do
20
+ item_hash({:text => '' }).to_api_hash.should_not have_key(:text)
21
+ end
22
+
23
+ it 'returns the text in the params' do
24
+ item_hash({:text => 'dog'}).to_api_hash.should include(:text => 'dog')
25
+ end
26
+
27
+ it 'returns the geo_bbox in the params' do
28
+ item_hash({:geo_bbox => '1,2,3,4'}).to_api_hash.should include(:geo_bbox => '1,2,3,4')
29
+ end
30
+
31
+ it 'type casts the record_type' do
32
+ item_hash({:record_type => '1'}).to_api_hash.should include(:record_type => 1)
33
+ end
34
+
35
+ it 'returns by default page 1' do
36
+ item_hash.to_api_hash.should include(:page => 1)
37
+ end
38
+
39
+ it 'returns the page parameter' do
40
+ item_hash({:page => '3'}).to_api_hash.should include(:page => 3)
41
+ end
42
+
43
+ it 'returns the per_page set in the initializer' do
44
+ Supplejack.stub(:per_page) { 15 }
45
+ item_hash.to_api_hash.should include(:per_page => 15)
46
+ end
47
+
48
+ it 'returns the per_page in the parameters' do
49
+ item_hash({:per_page => '22'}).to_api_hash.should include(:per_page => 22)
50
+ end
51
+
52
+ it 'returns the and_filters in the :and key' do
53
+ item_hash({:i => {:description => 'Weird one'}}).to_api_hash.should include(:and => {:description => 'Weird one'})
54
+ end
55
+
56
+ it 'returns the without_filters in the :without key' do
57
+ item_hash({:i => {'-description' => 'Weird one'}}).to_api_hash.should include(:without => {:description => 'Weird one'})
58
+ end
59
+
60
+ it 'returns the facets' do
61
+ item_hash({:facets => 'description,creator'}).to_api_hash.should include(:facets => 'description,creator')
62
+ end
63
+
64
+ it 'returns the facets per page' do
65
+ item_hash({:facets_per_page => '12'}).to_api_hash.should include(:facets_per_page => 12)
66
+ end
67
+
68
+ it 'returns the sort and direction' do
69
+ item_hash({:sort => 'title', :direction => 'desc'}).to_api_hash.should include(:sort => 'title', :direction => 'desc')
70
+ end
71
+
72
+ it 'doesn\'t return either sort nor direction when sort not present' do
73
+ item_hash({:direction => 'desc'}).to_api_hash.should_not include(:direction => 'desc')
74
+ end
75
+
76
+ it 'returns default direction "asc"' do
77
+ item_hash({:sort => 'title'}).to_api_hash.should include(:direction => 'asc')
78
+ end
79
+
80
+ it 'returns the default set of fields from config' do
81
+ Supplejack.stub(:fields) { [:default,:atl] }
82
+ item_hash.to_api_hash.should include(:fields => 'default,atl')
83
+ end
84
+
85
+ it 'overrides the fields from the parameters' do
86
+ item_hash({:fields => 'verbose,authorities'}).to_api_hash.should include(:fields => 'verbose,authorities')
87
+ end
88
+
89
+ it 'doesn\'t break when nil options hash' do
90
+ item_hash(nil).to_api_hash.should be_a Hash
91
+ end
92
+
93
+ it 'sends the solr_query option to the api' do
94
+ item_hash({:solr_query => 'dc_type:Images'}).to_api_hash.should include(:solr_query => 'dc_type:Images')
95
+ end
96
+
97
+ it 'shouldn\'t send the solr_query if empty' do
98
+ item_hash({:solr_query => ''}).to_api_hash.should_not have_key(:solr_query)
99
+ end
100
+
101
+ # it 'adds query_fields to the hash if present' do
102
+ # convert(@search, {:i => {:creator_text => 'john'}}).should include(:query_fields => [:creator])
103
+ # end
104
+ #
105
+ # it 'doesn't add empty query fields' do
106
+ # convert(@search, {:i => {:display_collection => 'nzlnz'}}).should_not have_key(:query_fields)
107
+ # end
108
+ end
109
+
110
+ describe '#and_filters' do
111
+ it 'returns every filter' do
112
+ item_hash({:i => {'sample_filter' => 'Groups'}}).and_filters.should eq({:sample_filter => 'Groups'})
113
+ end
114
+
115
+ it 'returns every filter' do
116
+ item_hash({:i => {'sample_filter' => 'Groups', '-content_partner' => 'nlnz'}}).and_filters.should eq({:sample_filter => 'Groups'})
117
+ end
118
+
119
+ it 'removes any _text filters' do
120
+ item_hash({:i => {'filter_with_text' => 'dog'}}).and_filters.should eq({})
121
+ end
122
+
123
+ it 'returns only item filters if filter_type is :items' do
124
+ item_hash({:i => {'subject' => 'dog'}, :h => {'heading_type' => 'record_type'}, :record_type => 1}).and_filters(:items).should eq({:subject => 'dog'})
125
+ end
126
+
127
+ it 'returns only headings filters if filter_type is :headings' do
128
+ item_hash({:i => {'subject' => 'dog'}, :h => {'heading_type' => 'record_type'}, :record_type => 0}).and_filters(:headings).should eq({:heading_type => 'record_type'})
129
+ end
130
+
131
+ it 'memoizes :i and :h filters seperatly' do
132
+ hash = item_hash({:i => {'subject' => 'dog'}, :h => {'heading_type' => 'record_type'}})
133
+ hash.and_filters(:items).should eq({:subject => 'dog'})
134
+ hash.and_filters(:headings).should eq({:heading_type => 'record_type'})
135
+ end
136
+ end
137
+
138
+ describe '#is_text_field?' do
139
+ it 'returns true when the passed field is text' do
140
+ item_hash.is_text_field?('title_text').should be_true
141
+ end
142
+
143
+ it 'returns false when the passed field is not text' do
144
+ item_hash.is_text_field?('title_authority').should be_false
145
+ end
146
+
147
+ it 'returns false when the passed field is nil' do
148
+ item_hash.is_text_field?(nil).should be_false
149
+ end
150
+ end
151
+
152
+ describe '#without_filters' do
153
+ it 'returns only negative filters' do
154
+ item_hash({:i => {'-negative_category' => 'Groups', 'positive_category' => 'nlnz'}}).without_filters.should eq({:negative_category => 'Groups'})
155
+ end
156
+
157
+ it 'returns only item filters if filter_type is :items' do
158
+ item_hash({:i => {'-subject' => 'dog'}, :h => {'-heading_type' => 'record_type'}, :record_type => 1}).without_filters(:items).should eq({:subject => 'dog'})
159
+ end
160
+
161
+ it 'returns only headings filters if filter_type is :headings' do
162
+ item_hash({:i => {'-subject' => 'dog'}, :h => {'-heading_type' => 'record_type'}, :record_type => 0}).without_filters(:headings).should eq({:heading_type => 'record_type'})
163
+ end
164
+
165
+ it 'memoizes :i and :h filters seperatly' do
166
+ hash = item_hash({:i => {'-subject' => 'dog'}, :h => {'-heading_type' => 'record_type'}})
167
+ hash.without_filters(:items).should eq({:subject => 'dog'})
168
+ hash.without_filters(:headings).should eq({:heading_type => 'record_type'})
169
+ end
170
+
171
+ end
172
+
173
+ describe '#text' do
174
+ it 'returns the text if present' do
175
+ item_hash.text('dog').should eq 'dog'
176
+ end
177
+
178
+ it 'returns nil when text is not present' do
179
+ item_hash().text('').should be_nil
180
+ end
181
+
182
+ it 'extracts the text from name_text' do
183
+ item_hash({:i => {:name_text => 'john'}}).text.should eq 'john'
184
+ end
185
+ end
186
+
187
+ describe '#query_fields' do
188
+ it 'returns all fields that end with _text' do
189
+ item_hash(:i => {:name_text => 'john', :location_text => 'New Zealand'}).query_fields.should include(:name, :location)
190
+ end
191
+
192
+ it 'returns nil when no filters match _text' do
193
+ item_hash(:i => {:sample_collection => 'nlnz'}).query_fields.should be_nil
194
+ end
195
+
196
+ it 'returns only _text filters' do
197
+ item_hash(:i => {:name_text => 'john', :sample_collection => 'nlnz'}).query_fields.should eq [:name]
198
+ end
199
+ end
200
+
201
+ describe '#filters' do
202
+ context 'default records' do
203
+ it 'returns the hash within the :i key and symbolizes them' do
204
+ item_hash({:i => {'location' => 'NZ'}}).filters.should eq({:location => 'NZ'})
205
+ end
206
+
207
+ it 'merges in the locked filters' do
208
+ result = {:location => 'NZ', :category => 'Images'}
209
+ item_hash({:i => {'location' => 'NZ'}, :il => {'category' => 'Images'}}).filters.should eq(result)
210
+ end
211
+
212
+ it 'returns :h filters with record_type parameter' do
213
+ item_hash({:i => {'location' => 'NZ'}, :h => {:dc_type => 'Names'}}).filters(:headings).should eq({:dc_type => 'Names'})
214
+ end
215
+
216
+ it 'memoizes the :i and :h filters separately' do
217
+ @hash = item_hash({:i => {'location' => 'NZ'}, :h => {:dc_type => 'Names'}})
218
+ @hash.filters.should eq({:location => 'NZ'})
219
+ @hash.filters(:headings).should eq({:dc_type => 'Names'})
220
+ end
221
+
222
+ it 'handles a string in the :i hash' do
223
+ item_hash({:i => ''}).filters.should be_empty
224
+ end
225
+
226
+ it 'handles a string in the :il hash' do
227
+ item_hash({:il => ''}).filters.should be_empty
228
+ end
229
+ end
230
+
231
+ context 'headings tab' do
232
+ it 'returns the hash within the :h key' do
233
+ item_hash({:h => {'heading_type' => 'Name'}, :record_type => '1'}).filters.should eq({:heading_type => 'Name'})
234
+ end
235
+
236
+ it 'merges in the locked filters' do
237
+ result = {:heading_type => 'Name', :year => '1900'}
238
+ item_hash({:h => {'heading_type' => 'Name'}, :hl => {'year' => '1900'}, :record_type => '1'}).filters.should eq(result)
239
+ end
240
+ end
241
+ end
242
+
243
+ describe '#filter_symbol' do
244
+ context 'when filter_type is nil' do
245
+ it 'returns "i" when record_type is 0' do
246
+ item_hash(:record_type => 0).filter_symbol.should eq 'i'
247
+ end
248
+
249
+ it 'returns "h" when record_type is 1' do
250
+ item_hash(:record_type => 1).filter_symbol.should eq 'h'
251
+ end
252
+ end
253
+
254
+ context 'filter_type is provided' do
255
+ it 'returns "i" when filter_type is :items' do
256
+ item_hash(:record_type => 1).filter_symbol(:items).should eq 'i'
257
+ end
258
+
259
+ it 'returns "h" when filter_type is :headings' do
260
+ item_hash(:record_type => 0).filter_symbol(:headings).should eq 'h'
261
+ end
262
+ end
263
+ end
264
+
265
+ describe '#filters_of_type' do
266
+ it 'returns item unlocked filters' do
267
+ item_hash({:i => {:category => 'Images'}}).filters_of_type(:i).should eq({:category => 'Images'})
268
+ end
269
+ end
270
+
271
+ describe '#options' do
272
+ before(:each) do
273
+ @search = Supplejack::Search.new
274
+ end
275
+
276
+ it 'returns a hash with the search parameters' do
277
+ params = {:i => {:name => 'John'}, :il => {:type => 'Person'}, :h => {:heading_type => 'Name'}, :hl => {:year => '1900'}}
278
+ item_hash(params, @search).options.should eq params
279
+ end
280
+
281
+ it 'doesnt return any empty values' do
282
+ item_hash({:i => {:name => '', :type => nil, :location => 'Wellington'}}, @search).options.should eq(:i => {:location => 'Wellington'})
283
+ end
284
+
285
+ it 'returns a empty hash when filters are empty' do
286
+ item_hash({:i => {:name => '', :type => nil}}, @search).options.should eq({})
287
+ end
288
+
289
+ it 'doesn\'t return page parameter when page 1' do
290
+ item_hash({:page => 1}, @search).options.should eq({})
291
+ end
292
+
293
+ it 'doesn\'t return page parameter is empty' do
294
+ item_hash({}, @search).options.should eq({})
295
+ end
296
+
297
+ it 'removes the filters in the :except parameter' do
298
+ item_hash({:i => {:name => 'John'}, :il => {:type => 'Person'}}, @search).options(:except => [:name]).should eq(:il => {:type => 'Person'})
299
+ end
300
+
301
+ it 'includes the record_type when is 1' do
302
+ search = Supplejack::Search.new(:record_type => 1)
303
+ item_hash({:record_type => 1}, search).options.should include(:record_type => 1)
304
+ end
305
+
306
+ it 'excludes the page parameter' do
307
+ search = Supplejack::Search.new(:page => 3)
308
+ item_hash({}, search).options(:except => [:page]).should_not include(:page => 3)
309
+ end
310
+
311
+ it 'adds multiple values to the same facet' do
312
+ search = Supplejack::Search.new(:i => {:name => 'John'})
313
+ item_hash({:i => {:name => 'John'}}, search).options(:plus => {:i => {:name => 'James'}})[:i].should include(:name => ['John', 'James'])
314
+ end
315
+
316
+ it 'only removes one value from the same facet' do
317
+ search = Supplejack::Search.new(:i => {:name => ['John', 'James']})
318
+ item_hash({:i => {:name => ['John', 'James']}}, search).options(:except => [{:name => 'James'}])[:i].should include(:name => 'John')
319
+ end
320
+
321
+ it 'only removes one value from the same facet' do
322
+ search = Supplejack::Search.new(:i => {:name => ['John', 'James', 'Jake']})
323
+ item_hash({:i => {:name => ['John', 'James', 'Jake']}}, search).options(:except => [{:name => 'James'}])[:i].should include(:name => ['John', 'Jake'])
324
+ end
325
+
326
+ it 'removes the whole facet if there is no remaining values' do
327
+ params = {:i => {:name => ['John', 'James'], :type => 'Person'}}
328
+ search = Supplejack::Search.new(params)
329
+ item_hash(params, search).options(:except => [{:name => ['James', 'John']}])[:i].should_not have_key(:name)
330
+ end
331
+
332
+ context 'in the items tab' do
333
+ it 'merges filters in the :plus parameter to the unlocked hash' do
334
+ item_hash({}, @search).options(:plus => {:i => {'type' => 'Something'}})[:i].should include(:type => 'Something')
335
+ end
336
+ end
337
+ end
338
+
339
+ end
340
+ end
341
+ end
@@ -0,0 +1,149 @@
1
+ # The Supplejack Client code is Crown copyright (C) 2014, New Zealand Government,
2
+ # and is licensed under the GNU General Public License, version 3.
3
+ # See https://github.com/DigitalNZ/supplejack_client for details.
4
+ #
5
+ # Supplejack was created by DigitalNZ at the National Library of NZ
6
+ # and the Department of Internal Affairs. http://digitalnz.org/supplejack
7
+
8
+ require 'spec_helper'
9
+
10
+ module Supplejack
11
+ describe UserSetRelation do
12
+ let(:user) { Supplejack::User.new({authentication_token: '123abc'}) }
13
+ let(:relation) { Supplejack::UserSetRelation.new(user) }
14
+
15
+ before :each do
16
+ relation.stub(:get) { {'sets' => [{'id' => '1', 'name' => 'dogs', 'count' => 1, 'priority' => 2}, {'id' => '2', 'name' => 'Favourites', 'count' => 1, 'priority' => 1}]} }
17
+ end
18
+
19
+ describe '#initialize' do
20
+ it 'initializes with a UserSet object' do
21
+ @user = user
22
+ Supplejack::UserSetRelation.new(@user).user.should eq @user
23
+ end
24
+ end
25
+
26
+ describe '#fetch_sets' do
27
+ it 'fetches the user sets with the App api_key' do
28
+ relation.should_receive(:get).with('/users/123abc/sets', {})
29
+ relation.fetch_sets
30
+ end
31
+
32
+ it 'returns a array of UserSet objects' do
33
+ relation.fetch_sets.should be_a Array
34
+ relation.fetch_sets.each do |set|
35
+ set.should be_a Supplejack::UserSet
36
+ end
37
+ end
38
+
39
+ it 'should order the user sets by priority' do
40
+ relation.fetch_sets.first.name.should eq 'Favourites'
41
+ relation.fetch_sets.last.name.should eq 'dogs'
42
+ end
43
+ end
44
+
45
+ describe 'sets_response' do
46
+ context 'caching disabled' do
47
+ before :each do
48
+ Supplejack.stub(:enable_caching) { false }
49
+ end
50
+
51
+ it 'fetches the user sets with the App api_key' do
52
+ relation.should_receive(:get).with('/users/123abc/sets', {})
53
+ relation.sets_response
54
+ end
55
+
56
+ context 'user with use_own_api_key set to true' do
57
+ it 'fetches the user sets with it\'s own API Key' do
58
+ user.stub(:use_own_api_key?) { true }
59
+ relation.should_receive(:get).with('/sets', {api_key: '123abc'})
60
+ relation.sets_response
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#sets' do
67
+ it 'memoizes the sets array' do
68
+ relation.should_receive(:fetch_sets).once { [] }
69
+ relation.sets
70
+ relation.sets
71
+ end
72
+ end
73
+
74
+ describe '#find' do
75
+ it 'finds a user and sets the correct api_key' do
76
+ Supplejack::UserSet.should_receive(:find).with('555', '123abc')
77
+ relation.find('555')
78
+ end
79
+ end
80
+
81
+ describe '#build' do
82
+ it 'initializes a new UserSet with the user\'s api_key' do
83
+ user_set = relation.build
84
+ user_set.should be_a UserSet
85
+ user_set.api_key.should eq '123abc'
86
+ end
87
+
88
+ it 'initializes the UserSet with the provided attributes' do
89
+ user_set = relation.build({name: 'Dogs', description: 'Hi'})
90
+ user_set.name.should eq 'Dogs'
91
+ user_set.description.should eq 'Hi'
92
+ end
93
+ end
94
+
95
+ describe '#create' do
96
+ it 'initializes the UserSet and saves it' do
97
+ user_set = relation.build({name: 'Dogs'})
98
+ relation.should_receive(:build).with(name: 'Dogs') { user_set }
99
+ user_set.should_receive(:save) { true }
100
+ relation.create({name: 'Dogs'}).should be_a Supplejack::UserSet
101
+ end
102
+ end
103
+
104
+ describe '#order' do
105
+ before :each do
106
+ relation.stub(:get) { {'sets' => [{'name' => 'dogs', 'priority' => 2, 'count' => 3}, { 'name' => 'zavourites', 'priority' => 1, 'count' => 2},{ 'name' => 'Favourites', 'priority' => 2, 'count' => 1}]} }
107
+ end
108
+ it 'orders the sets based on the name' do
109
+ relation.order(:name)[0].name.should eq 'zavourites'
110
+ relation.order(:name)[1].name.should eq 'dogs'
111
+ relation.order(:name)[2].name.should eq 'Favourites'
112
+ end
113
+ it 'orders the sets based on the count' do
114
+ relation.order(:count)[0].name.should eq 'zavourites'
115
+ relation.order(:count)[1].name.should eq 'Favourites'
116
+ relation.order(:count)[2].name.should eq 'dogs'
117
+ end
118
+
119
+ it 'orders the sets based on the updated_at ignoring the priority' do
120
+ relation.stub(:get) { {'sets' => [{'name' => '1', 'updated_at' => Time.now.to_s, 'priority' => 2}, {'name' => '3', 'updated_at' => (Time.now-4.hours).to_s, 'priority' => 1},{'name' => '2', 'updated_at' => (Time.now-1.hours).to_s, 'priority' => 2}]} }
121
+ relation.order(:updated_at)[0].name.should eq '1'
122
+ relation.order(:updated_at)[1].name.should eq '2'
123
+ relation.order(:updated_at)[2].name.should eq '3'
124
+ end
125
+ end
126
+
127
+ describe '#all' do
128
+ it 'returns the actual array with the sets' do
129
+ relation.all.should be_a Array
130
+ end
131
+ end
132
+
133
+ context 'user sets array behaviour' do
134
+ it 'executes array methods on the @sets array' do
135
+ sets = relation.stub(:sets) { [] }
136
+ relation.size.should eq 0
137
+ end
138
+
139
+ it 'should be able to iterate through the user sets relation' do
140
+ relation.stub(:sets) { [Supplejack::UserSet.new] }
141
+ relation.each do |set|
142
+ set.should be_a Supplejack::UserSet
143
+ end
144
+ relation.size.should eq 1
145
+ end
146
+ end
147
+
148
+ end
149
+ end