supplejack_client 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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