supplejack_api 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 (291) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +80 -0
  3. data/Rakefile +42 -0
  4. data/app/assets/javascripts/supplejack_api/application.js +26 -0
  5. data/app/assets/stylesheets/supplejack_api/application.css +30 -0
  6. data/app/controllers/supplejack_api/admin/base_controller.rb +24 -0
  7. data/app/controllers/supplejack_api/admin/sessions_controller.rb +25 -0
  8. data/app/controllers/supplejack_api/admin/site_activities_controller.rb +21 -0
  9. data/app/controllers/supplejack_api/admin/users_controller.rb +55 -0
  10. data/app/controllers/supplejack_api/application_controller.rb +70 -0
  11. data/app/controllers/supplejack_api/concepts_controller.rb +52 -0
  12. data/app/controllers/supplejack_api/concerns/ignore_metrics.rb +14 -0
  13. data/app/controllers/supplejack_api/concerns/records_controller_metrics.rb +26 -0
  14. data/app/controllers/supplejack_api/concerns/set_items_controller_metrics.rb +20 -0
  15. data/app/controllers/supplejack_api/concerns/user_sets_controller_metrics.rb +26 -0
  16. data/app/controllers/supplejack_api/harvester/concepts_controller.rb +41 -0
  17. data/app/controllers/supplejack_api/harvester/fragments_controller.rb +30 -0
  18. data/app/controllers/supplejack_api/harvester/records_controller.rb +68 -0
  19. data/app/controllers/supplejack_api/metrics_api_controller.rb +44 -0
  20. data/app/controllers/supplejack_api/partners_controller.rb +39 -0
  21. data/app/controllers/supplejack_api/records_controller.rb +71 -0
  22. data/app/controllers/supplejack_api/schema_controller.rb +19 -0
  23. data/app/controllers/supplejack_api/set_items_controller.rb +38 -0
  24. data/app/controllers/supplejack_api/sources_controller.rb +67 -0
  25. data/app/controllers/supplejack_api/status_controller.rb +67 -0
  26. data/app/controllers/supplejack_api/user_sets_controller.rb +97 -0
  27. data/app/controllers/supplejack_api/users_controller.rb +49 -0
  28. data/app/helpers/supplejack_api/application_helper.rb +39 -0
  29. data/app/helpers/supplejack_api/facets_helper.rb +30 -0
  30. data/app/mailers/supplejack_api/request_limit_mailer.rb +43 -0
  31. data/app/models/supplejack_api/api_concept/concept_fragment.rb +31 -0
  32. data/app/models/supplejack_api/api_record/record_fragment.rb +15 -0
  33. data/app/models/supplejack_api/concept.rb +46 -0
  34. data/app/models/supplejack_api/concept_search.rb +86 -0
  35. data/app/models/supplejack_api/concerns/queryable_by_date.rb +31 -0
  36. data/app/models/supplejack_api/concerns/record.rb +108 -0
  37. data/app/models/supplejack_api/concerns/record_fragmentable.rb +24 -0
  38. data/app/models/supplejack_api/concerns/searchable.rb +430 -0
  39. data/app/models/supplejack_api/concerns/user_set.rb +219 -0
  40. data/app/models/supplejack_api/daily_metrics.rb +20 -0
  41. data/app/models/supplejack_api/faceted_metrics.rb +55 -0
  42. data/app/models/supplejack_api/fragment.rb +82 -0
  43. data/app/models/supplejack_api/interaction_models/record.rb +60 -0
  44. data/app/models/supplejack_api/interaction_models/set.rb +13 -0
  45. data/app/models/supplejack_api/interaction_updaters/all_usage_metric.rb +41 -0
  46. data/app/models/supplejack_api/interaction_updaters/set_metrics.rb +32 -0
  47. data/app/models/supplejack_api/interaction_updaters/usage_metrics.rb +73 -0
  48. data/app/models/supplejack_api/partner.rb +24 -0
  49. data/app/models/supplejack_api/preview_record.rb +30 -0
  50. data/app/models/supplejack_api/record.rb +18 -0
  51. data/app/models/supplejack_api/record_search.rb +12 -0
  52. data/app/models/supplejack_api/schema_definition.rb +147 -0
  53. data/app/models/supplejack_api/search.rb +14 -0
  54. data/app/models/supplejack_api/set_item.rb +57 -0
  55. data/app/models/supplejack_api/site_activity.rb +59 -0
  56. data/app/models/supplejack_api/source.rb +28 -0
  57. data/app/models/supplejack_api/source_activity.rb +36 -0
  58. data/app/models/supplejack_api/source_authority.rb +42 -0
  59. data/app/models/supplejack_api/supplejack_schema.rb +37 -0
  60. data/app/models/supplejack_api/support/concept/searchable.rb +79 -0
  61. data/app/models/supplejack_api/support/concept/storable.rb +59 -0
  62. data/app/models/supplejack_api/support/fragment_helpers.rb +96 -0
  63. data/app/models/supplejack_api/support/harvestable.rb +105 -0
  64. data/app/models/supplejack_api/support/searchable.rb +115 -0
  65. data/app/models/supplejack_api/support/status_logger.rb +23 -0
  66. data/app/models/supplejack_api/support/storable.rb +49 -0
  67. data/app/models/supplejack_api/support/validation_logger.rb +23 -0
  68. data/app/models/supplejack_api/usage_metrics.rb +25 -0
  69. data/app/models/supplejack_api/user.rb +211 -0
  70. data/app/models/supplejack_api/user_activity.rb +65 -0
  71. data/app/models/supplejack_api/user_set.rb +17 -0
  72. data/app/serializers/supplejack_api/application_serializer.rb +12 -0
  73. data/app/serializers/supplejack_api/concept_record_serializer.rb +23 -0
  74. data/app/serializers/supplejack_api/concept_search_serializer.rb +12 -0
  75. data/app/serializers/supplejack_api/concept_serializer.rb +100 -0
  76. data/app/serializers/supplejack_api/concerns/record_serializable.rb +119 -0
  77. data/app/serializers/supplejack_api/concerns/search_serializable.rb +24 -0
  78. data/app/serializers/supplejack_api/record_search_serializer.rb +64 -0
  79. data/app/serializers/supplejack_api/record_serializer.rb +13 -0
  80. data/app/serializers/supplejack_api/search_serializer.rb +13 -0
  81. data/app/serializers/supplejack_api/source_authority_serializer.rb +23 -0
  82. data/app/serializers/supplejack_api/user_serializer.rb +13 -0
  83. data/app/serializers/supplejack_api/user_set_record_serializer.rb +14 -0
  84. data/app/serializers/supplejack_api/user_set_serializer.rb +77 -0
  85. data/app/services/metrics_api/v3/api.rb +30 -0
  86. data/app/services/metrics_api/v3/endpoints/facets.rb +23 -0
  87. data/app/services/metrics_api/v3/endpoints/global.rb +26 -0
  88. data/app/services/metrics_api/v3/endpoints/helpers.rb +14 -0
  89. data/app/services/metrics_api/v3/endpoints/root.rb +97 -0
  90. data/app/services/metrics_api/v3/presenters/daily_metric.rb +23 -0
  91. data/app/services/metrics_api/v3/presenters/extended_metadata.rb +41 -0
  92. data/app/services/metrics_api/v3/presenters/record.rb +26 -0
  93. data/app/services/metrics_api/v3/presenters/view.rb +28 -0
  94. data/app/views/layouts/supplejack_api/_head.html.erb +17 -0
  95. data/app/views/layouts/supplejack_api/_top_nav.html.erb +33 -0
  96. data/app/views/layouts/supplejack_api/application.html.erb +33 -0
  97. data/app/views/supplejack_api/admin/sessions/new.html.erb +25 -0
  98. data/app/views/supplejack_api/admin/shared/_links.erb +34 -0
  99. data/app/views/supplejack_api/admin/site_activities/index.csv.erb +22 -0
  100. data/app/views/supplejack_api/admin/site_activities/index.html.erb +54 -0
  101. data/app/views/supplejack_api/admin/users/edit.html.erb +16 -0
  102. data/app/views/supplejack_api/admin/users/index.csv.erb +22 -0
  103. data/app/views/supplejack_api/admin/users/index.html.erb +57 -0
  104. data/app/views/supplejack_api/admin/users/show.html.erb +33 -0
  105. data/app/views/supplejack_api/request_limit_mailer/at100percent.text.erb +13 -0
  106. data/app/views/supplejack_api/request_limit_mailer/at100percent_admin.text.erb +1 -0
  107. data/app/views/supplejack_api/request_limit_mailer/at90percent.text.erb +13 -0
  108. data/app/views/supplejack_api/request_limit_mailer/at90percent_admin.text.erb +1 -0
  109. data/app/workers/supplejack_api/daily_metrics_worker.rb +112 -0
  110. data/app/workers/supplejack_api/interaction_metrics_worker.rb +45 -0
  111. data/config/cucumber.yml +16 -0
  112. data/config/initializers/force_eagerload.rb +11 -0
  113. data/config/initializers/interaction_updaters.rb +7 -0
  114. data/config/routes.rb +81 -0
  115. data/db/binding_records.development.json +7 -0
  116. data/db/binding_records.staging.json +7 -0
  117. data/db/concepts.json +33 -0
  118. data/db/concepts_data.json +569745 -0
  119. data/db/source_authorities.json +119 -0
  120. data/lib/generators/supplejack_api/install_generator.rb +124 -0
  121. data/lib/mongoid/paperclip.rb +53 -0
  122. data/lib/mongoid/string.rb +20 -0
  123. data/lib/sunspot/mongoid.rb +51 -0
  124. data/lib/sunspot/resque_session_proxy.rb +72 -0
  125. data/lib/sunspot/sunspot_spellcheck.rb +98 -0
  126. data/lib/supplejack_api.rb +13 -0
  127. data/lib/supplejack_api/admin/sortable.rb +40 -0
  128. data/lib/supplejack_api/engine.rb +46 -0
  129. data/lib/supplejack_api/harvester_constraint.rb +28 -0
  130. data/lib/supplejack_api/stylesheets.rb +36 -0
  131. data/lib/supplejack_api/utils.rb +75 -0
  132. data/lib/supplejack_api/version.rb +11 -0
  133. data/lib/tasks/resque.rake +22 -0
  134. data/lib/url_validator.rb +38 -0
  135. data/spec/controllers/supplejack_api/admin/base_controller_spec.rb +55 -0
  136. data/spec/controllers/supplejack_api/admin/site_activities_controller_spec.rb +43 -0
  137. data/spec/controllers/supplejack_api/admin/users_controller_spec.rb +79 -0
  138. data/spec/controllers/supplejack_api/application_controller_spec.rb +133 -0
  139. data/spec/controllers/supplejack_api/concepts_controller_spec.rb +83 -0
  140. data/spec/controllers/supplejack_api/concerns/records_controller_metrics_spec.rb +60 -0
  141. data/spec/controllers/supplejack_api/harvester/concepts_controller_spec.rb +57 -0
  142. data/spec/controllers/supplejack_api/harvester/records_controller_spec.rb +138 -0
  143. data/spec/controllers/supplejack_api/metrics_api_controller_spec.rb +71 -0
  144. data/spec/controllers/supplejack_api/partners_controller_spec.rb +77 -0
  145. data/spec/controllers/supplejack_api/records_controller_spec.rb +143 -0
  146. data/spec/controllers/supplejack_api/set_items_controller_spec.rb +78 -0
  147. data/spec/controllers/supplejack_api/sources_controller_spec.rb +161 -0
  148. data/spec/controllers/supplejack_api/status_controller_spec.rb +120 -0
  149. data/spec/controllers/supplejack_api/user_sets_controller_spec.rb +233 -0
  150. data/spec/controllers/supplejack_api/users_controller_spec.rb +61 -0
  151. data/spec/dummy/README.rdoc +268 -0
  152. data/spec/dummy/Rakefile +7 -0
  153. data/spec/dummy/app/assets/javascripts/application.js +23 -0
  154. data/spec/dummy/app/assets/stylesheets/application.css +22 -0
  155. data/spec/dummy/app/controllers/application_controller.rb +10 -0
  156. data/spec/dummy/app/helpers/application_helper.rb +9 -0
  157. data/spec/dummy/app/supplejack_api/concept_schema.rb +83 -0
  158. data/spec/dummy/app/supplejack_api/record_schema.rb +64 -0
  159. data/spec/dummy/app/supplejack_api/record_schema.txt +66 -0
  160. data/spec/dummy/app/views/layouts/application.html.erb +23 -0
  161. data/spec/dummy/app/workers/supplejack_api/clear_index_buffer.rb +32 -0
  162. data/spec/dummy/app/workers/supplejack_api/flush_old_records_worker.rb +17 -0
  163. data/spec/dummy/app/workers/supplejack_api/index_buffer.rb +49 -0
  164. data/spec/dummy/app/workers/supplejack_api/index_source_worker.rb +39 -0
  165. data/spec/dummy/app/workers/supplejack_api/index_worker.rb +82 -0
  166. data/spec/dummy/app/workers/supplejack_api/store_user_activity_worker.rb +24 -0
  167. data/spec/dummy/config.ru +11 -0
  168. data/spec/dummy/config/application.rb +76 -0
  169. data/spec/dummy/config/application.yml +31 -0
  170. data/spec/dummy/config/application.yml.example +36 -0
  171. data/spec/dummy/config/boot.rb +17 -0
  172. data/spec/dummy/config/environment.rb +12 -0
  173. data/spec/dummy/config/environments/development.rb +42 -0
  174. data/spec/dummy/config/environments/production.rb +76 -0
  175. data/spec/dummy/config/environments/test.rb +46 -0
  176. data/spec/dummy/config/initializers/backtrace_silencers.rb +14 -0
  177. data/spec/dummy/config/initializers/devise.rb +214 -0
  178. data/spec/dummy/config/initializers/inflections.rb +22 -0
  179. data/spec/dummy/config/initializers/kaminari_config.rb +17 -0
  180. data/spec/dummy/config/initializers/mime_types.rb +12 -0
  181. data/spec/dummy/config/initializers/mongoid.rb +9 -0
  182. data/spec/dummy/config/initializers/quiet_logger.rb +23 -0
  183. data/spec/dummy/config/initializers/resque.rb +18 -0
  184. data/spec/dummy/config/initializers/secret_token.rb +14 -0
  185. data/spec/dummy/config/initializers/session_store.rb +15 -0
  186. data/spec/dummy/config/initializers/simple_form.rb +149 -0
  187. data/spec/dummy/config/initializers/simple_form_foundation.rb +33 -0
  188. data/spec/dummy/config/initializers/state_machine.rb +8 -0
  189. data/spec/dummy/config/initializers/sunspot.rb +32 -0
  190. data/spec/dummy/config/initializers/wrap_parameters.rb +17 -0
  191. data/spec/dummy/config/locales/devise.en.yml +63 -0
  192. data/spec/dummy/config/locales/en.yml +66 -0
  193. data/spec/dummy/config/locales/simple_form.en.yml +33 -0
  194. data/spec/dummy/config/mongoid.travis.yml +34 -0
  195. data/spec/dummy/config/mongoid.yml +36 -0
  196. data/spec/dummy/config/resque-pool.yml +18 -0
  197. data/spec/dummy/config/resque_schedule.yml +12 -0
  198. data/spec/dummy/config/routes.rb +11 -0
  199. data/spec/dummy/config/secrets.yml +8 -0
  200. data/spec/dummy/config/sunspot.yml +38 -0
  201. data/spec/dummy/db/concepts.json +37 -0
  202. data/spec/dummy/db/source_authorities.json +116 -0
  203. data/spec/dummy/public/404.html +35 -0
  204. data/spec/dummy/public/422.html +35 -0
  205. data/spec/dummy/public/500.html +34 -0
  206. data/spec/dummy/public/favicon.ico +8 -0
  207. data/spec/dummy/script/rails +6 -0
  208. data/spec/dummy/solr/collection1/conf/elevate.xml +36 -0
  209. data/spec/dummy/solr/collection1/conf/mapping-FoldToASCII.txt +3813 -0
  210. data/spec/dummy/solr/collection1/conf/schema.xml +292 -0
  211. data/spec/dummy/solr/collection1/conf/solrconfig.xml +1780 -0
  212. data/spec/dummy/solr/collection1/conf/spellings.txt +2 -0
  213. data/spec/dummy/solr/collection1/conf/stopwords.txt +58 -0
  214. data/spec/dummy/solr/collection1/conf/synonyms.txt +31 -0
  215. data/spec/factories/concepts.rb +16 -0
  216. data/spec/factories/daily_metrics.rb +10 -0
  217. data/spec/factories/faceted_metrics.rb +25 -0
  218. data/spec/factories/fragment.rb +14 -0
  219. data/spec/factories/partners.rb +14 -0
  220. data/spec/factories/record_interaction.rb +17 -0
  221. data/spec/factories/records.rb +47 -0
  222. data/spec/factories/set_interaction.rb +15 -0
  223. data/spec/factories/source_authorities.rb +19 -0
  224. data/spec/factories/sources.rb +16 -0
  225. data/spec/factories/usage_metrics.rb +20 -0
  226. data/spec/factories/user_activities.rb +14 -0
  227. data/spec/factories/user_sets.rb +27 -0
  228. data/spec/factories/users.rb +23 -0
  229. data/spec/helpers/application_helper_spec.rb +35 -0
  230. data/spec/models/concept_spec.rb +163 -0
  231. data/spec/models/fragment_spec.rb +15 -0
  232. data/spec/models/site_activity_spec.rb +103 -0
  233. data/spec/models/source_activity_spec.rb +56 -0
  234. data/spec/models/source_authority_spec.rb +42 -0
  235. data/spec/models/supplejack_api/api_concept/concept_fragment_spec.rb +189 -0
  236. data/spec/models/supplejack_api/api_record/record_fragment_spec.rb +189 -0
  237. data/spec/models/supplejack_api/concept_spec.rb +0 -0
  238. data/spec/models/supplejack_api/interaction_updaters/all_usage_metric_spec.rb +41 -0
  239. data/spec/models/supplejack_api/interaction_updaters/set_metrics_spec.rb +32 -0
  240. data/spec/models/supplejack_api/interaction_updaters/usage_metrics_spec.rb +44 -0
  241. data/spec/models/supplejack_api/partner_spec.rb +20 -0
  242. data/spec/models/supplejack_api/record_search_spec.rb +429 -0
  243. data/spec/models/supplejack_api/record_spec.rb +280 -0
  244. data/spec/models/supplejack_api/schema_definition_spec.rb +272 -0
  245. data/spec/models/supplejack_api/search_spec.rb +243 -0
  246. data/spec/models/supplejack_api/set_item_spec.rb +123 -0
  247. data/spec/models/supplejack_api/source_spec.rb +22 -0
  248. data/spec/models/supplejack_api/support/fragment_helpers_spec.rb +216 -0
  249. data/spec/models/supplejack_api/support/harvestable_spec.rb +177 -0
  250. data/spec/models/supplejack_api/support/searchable_spec.rb +85 -0
  251. data/spec/models/supplejack_api/support/storable_spec.rb +18 -0
  252. data/spec/models/supplejack_api/user_activity_spec.rb +88 -0
  253. data/spec/models/supplejack_api/user_set_spec.rb +559 -0
  254. data/spec/models/supplejack_api/user_spec.rb +348 -0
  255. data/spec/routing/concepts_routing_spec.rb +22 -0
  256. data/spec/routing/harvester_constraint_spec.rb +66 -0
  257. data/spec/routing/harvester_routing_spec.rb +51 -0
  258. data/spec/routing/partner_routing_spec.rb +34 -0
  259. data/spec/routing/records_routing_spec.rb +26 -0
  260. data/spec/routing/sets_routing_spec.rb +44 -0
  261. data/spec/routing/source_routing_spec.rb +38 -0
  262. data/spec/routing/users_routing_spec.rb +18 -0
  263. data/spec/serializers/concept_record_serializer_spec.rb +30 -0
  264. data/spec/serializers/supplejack_api/application_serializer_spec.rb +14 -0
  265. data/spec/serializers/supplejack_api/concept_search_serializer_spec.rb +34 -0
  266. data/spec/serializers/supplejack_api/concept_serializer_spec.rb +92 -0
  267. data/spec/serializers/supplejack_api/record_search_serializer_spec.rb +34 -0
  268. data/spec/serializers/supplejack_api/record_serializer_spec.rb +271 -0
  269. data/spec/serializers/supplejack_api/search_serializer_spec.rb +90 -0
  270. data/spec/serializers/supplejack_api/user_serializer_spec.rb +22 -0
  271. data/spec/serializers/supplejack_api/user_set_serializer_spec.rb +96 -0
  272. data/spec/services/metrics_api/v3/api_spec.rb +23 -0
  273. data/spec/services/metrics_api/v3/endpoints/facets_spec.rb +25 -0
  274. data/spec/services/metrics_api/v3/endpoints/global_spec.rb +22 -0
  275. data/spec/services/metrics_api/v3/endpoints/root_spec.rb +49 -0
  276. data/spec/services/metrics_api/v3/presenters/extended_metadata_spec.rb +49 -0
  277. data/spec/spec_helper.rb +70 -0
  278. data/spec/support/api/schemas/metrics/daily_metrics_metadata.json +24 -0
  279. data/spec/support/api/schemas/metrics/extended_metrics.json +26 -0
  280. data/spec/support/api/schemas/metrics/extended_response.json +6 -0
  281. data/spec/support/api/schemas/metrics/facets_response.json +6 -0
  282. data/spec/support/api/schemas/metrics/record_metadata.json +33 -0
  283. data/spec/support/api/schemas/metrics/top_level_response.json +6 -0
  284. data/spec/support/api/schemas/metrics/view_metadata.json +33 -0
  285. data/spec/support/api_schema_matcher.rb +14 -0
  286. data/spec/support/devise.rb +10 -0
  287. data/spec/workers/supplejack_api/daily_metrics_worker_spec.rb +140 -0
  288. data/spec/workers/supplejack_api/flush_old_records_worker_spec.rb +20 -0
  289. data/spec/workers/supplejack_api/index_worker_spec.rb +52 -0
  290. data/spec/workers/supplejack_api/source_index_worker_spec.rb +61 -0
  291. metadata +1231 -0
@@ -0,0 +1,280 @@
1
+ # The majority of the Supplejack API code is Crown copyright (C) 2014, New Zealand Government,
2
+ # and is licensed under the GNU General Public License, version 3.
3
+ # One component is a third party component. See https://github.com/DigitalNZ/supplejack_api for details.
4
+ #
5
+ # Supplejack was created by DigitalNZ at the National Library of NZ and
6
+ # the Department of Internal Affairs. http://digitalnz.org/supplejack
7
+
8
+ require 'spec_helper'
9
+
10
+ module SupplejackApi
11
+ describe Record do
12
+ let(:record) { FactoryGirl.build(:record, record_id: 1234) }
13
+
14
+ subject { record }
15
+
16
+ it { should have_and_belong_to_many(:concepts) }
17
+
18
+ describe '#custom_find' do
19
+ before(:each) do
20
+ @record = FactoryGirl.create(:record, record_id: 54321)
21
+ allow(@record).to receive(:find_next_and_previous_records).and_return(nil)
22
+ end
23
+
24
+ it 'should search for a record via its record_id' do
25
+ expect(Record.custom_find(54321)).to eq(@record)
26
+ end
27
+
28
+ it 'should search for a record via its ObjectId (MongoDB autoassigned id)' do
29
+ expect(Record.custom_find(@record.id)).to eq(@record)
30
+ end
31
+
32
+ it 'should raise a error when a record is not found' do
33
+ expect { Record.custom_find(111) }.to raise_error(Mongoid::Errors::DocumentNotFound)
34
+ end
35
+
36
+ it "shouldn't call find when the mongo id is invalid" do
37
+ expect(Record).to_not receive(:find)
38
+ expect { Record.custom_find('1234567abc') }.to raise_error(Mongoid::Errors::DocumentNotFound)
39
+ end
40
+
41
+ it 'should find next and previous records' do
42
+ @user = double(:user)
43
+ allow(Record).to receive_message_chain(:unscoped, :active, :where, :first).and_return(@record)
44
+ expect(@record).to receive(:find_next_and_previous_records).with(@user, {text: 'dogs'})
45
+ Record.custom_find(54321, @user, {text: 'dogs'})
46
+ end
47
+
48
+ [Sunspot::UnrecognizedFieldError, Timeout::Error, Errno::ECONNREFUSED, Errno::ECONNRESET].each do |error_klass|
49
+ it 'should rescue from a #{error_klass}' do
50
+ allow(Record).to receive_message_chain(:unscoped, :active, :where, :first).and_return(@record)
51
+ allow(@record).to receive(:find_next_and_previous_records).and_raise(error_klass)
52
+ Record.custom_find(54321, nil, {text: 'dogs'})
53
+ end
54
+ end
55
+
56
+ it 'should rescue from a RSolr::Error::Http' do
57
+ allow(Record).to receive_message_chain(:unscoped, :active, :where, :first).and_return(@record)
58
+ allow(@record).to receive(:find_next_and_previous_records).and_raise(RSolr::Error::Http.new({}, {}))
59
+ Record.custom_find(54321, nil, {text: 'dogs'})
60
+ end
61
+
62
+ context 'restricting inactive records' do
63
+ it 'finds only active records' do
64
+ @record.update_attribute(:status, 'deleted')
65
+ @record.reload
66
+ expect { Record.custom_find(54321) }.to raise_error(Mongoid::Errors::DocumentNotFound)
67
+ end
68
+
69
+ it 'finds also inactive records when :status => :all' do
70
+ @record.update_attribute(:status, 'deleted')
71
+ @record.reload
72
+ expect(Record.custom_find(54321, nil, {status: :all})).to eq @record
73
+ end
74
+
75
+ it "doesn't find next and previous record without any search options" do
76
+ allow(Record).to receive_message_chain(:unscoped, :where, :first) { @record }
77
+ expect(@record).to_not receive(:find_next_and_previous_records)
78
+ Record.custom_find(54321, nil, {status: :all})
79
+ end
80
+
81
+ it "doesn't break with nil options" do
82
+ expect(Record.custom_find(54321, nil, nil)).to eq @record
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#find_multiple' do
88
+ before(:each) do
89
+ @record = FactoryGirl.create(:record, record_id: 54321)
90
+ end
91
+
92
+ it 'should find multiple records by numeric id' do
93
+ r1 = FactoryGirl.create(:record, record_id: 999)
94
+ r2 = FactoryGirl.create(:record, record_id: 998)
95
+ expect(Record.find_multiple([999, 998])).to include(r1, r2)
96
+ expect(Record.find_multiple([999, 998]).length).to eq(2)
97
+ end
98
+
99
+ it 'should find multiple records by ObjectId' do
100
+ r1 = FactoryGirl.create(:record)
101
+ r2 = FactoryGirl.create(:record)
102
+ expect(Record.find_multiple([r1.id, r2.id])).to include(r1, r2)
103
+ expect(Record.find_multiple([r1.id, r2.id]).length).to eq(2)
104
+ end
105
+
106
+ it "should find multiple records with ObjectId's and numeric id's" do
107
+ r1 = FactoryGirl.create(:record, record_id: 997)
108
+ r2 = FactoryGirl.create(:record)
109
+ expect(Record.find_multiple([997, r2.id])).to include(r1, r2)
110
+ expect(Record.find_multiple([997, r2.id]).length).to eq(2)
111
+ end
112
+
113
+ it 'returns an empty array when ids is nil' do
114
+ expect(Record.find_multiple(nil)).to eq []
115
+ end
116
+
117
+ it 'should not return inactive records' do
118
+ r1 = FactoryGirl.create(:record, record_id: 997, status: 'deleted')
119
+ r2 = FactoryGirl.create(:record, record_id: 667, status: 'active')
120
+ records = Record.find_multiple([997, 667]).to_a
121
+ expect(records).to_not include(r1)
122
+ expect(records).to include(r2)
123
+ end
124
+
125
+ it 'returns the records in the same order as requested' do
126
+ r1 = FactoryGirl.create(:record, record_id: 1, created_at: Time.now-10.days)
127
+ r2 = FactoryGirl.create(:record, record_id: 2, created_at: Time.now)
128
+ records = Record.find_multiple([2,1]).to_a
129
+ expect(records.first).to eq r2
130
+ end
131
+ end
132
+
133
+ describe '#find_next_and_previous_records' do
134
+ pending 'Implement record search'
135
+ # before(:each) do
136
+ # @record = FactoryGirl.create(:record, :record_id => 123)
137
+ # @search = Search.new
138
+ # @search.stub(:total).and_return(3)
139
+ # Search.stub(:new).and_return(@search)
140
+ # @user = FactoryGirl.build(:user)
141
+ # end
142
+
143
+ # it 'should not do anything when options are empty' do
144
+ # Search.should_not_receive(:new)
145
+ # record.find_next_and_previous_records(@user, {})
146
+ # end
147
+
148
+ # it 'should not do anything when options is null' do
149
+ # Search.should_not_receive(:new)
150
+ # record.find_next_and_previous_records(@user, nil)
151
+ # end
152
+
153
+ # it 'should not do anything when the solr request fails' do
154
+ # @search.stub(:valid?) { false }
155
+ # @search.should_not_receive(:hits)
156
+ # record.find_next_and_previous_records(@user, {text: 'dogs'})
157
+ # end
158
+
159
+ # it 'should set the scope in the search' do
160
+ # Search.stub(:new) { @search }
161
+ # @search.should_receive('scope=').with(@user)
162
+ # record.find_next_and_previous_records(@user, {text: 'dogs'})
163
+ # end
164
+
165
+ # context 'records within the current page' do
166
+ # before do
167
+ # Record.stub(:find).with('12345') {mock_model(Record, :record_id => 654)}
168
+ # Record.stub(:find).with('98765') {mock_model(Record, :record_id => 987)}
169
+ # end
170
+
171
+ # it 'should set the previous record' do
172
+ # @search.stub(:hits) { mock_hits(['12345', @record.id, '98765']) }
173
+ # Record.should_receive(:find).with('12345').and_return(mock_model(Record, :record_id => 654))
174
+ # @record.find_next_and_previous_records(@user, text: 'dogs')
175
+ # @record.previous_record).to eq(654)
176
+ # end
177
+
178
+ # it 'should set the next record' do
179
+ # @search.stub(:hits).and_return(mock_hits([nil, @record.id, '98765']))
180
+ # Record.should_receive(:find).with('98765').and_return(mock_model(Record, :record_id => 987))
181
+ # @record.find_next_and_previous_records(@user, {text: 'dogs'})
182
+ # @record.next_record).to eq(987)
183
+ # end
184
+ # end
185
+
186
+ # context 'first record in the results' do
187
+ # before(:each) do
188
+ # @search.stub(:hits).and_return(mock_hits([@record.id, '12345', '98765']))
189
+ # end
190
+
191
+ # it 'should perform a new search for the previous page' do
192
+ # @search.stub(:page).and_return(2)
193
+ # Search.should_receive(:new).with(anything)
194
+ # Search.should_receive(:new).with(hash_including(page: 1))
195
+ # @record.find_next_and_previous_records(@user, {text: 'dogs'})
196
+ # @record.previous_page).to eq(1)
197
+ # end
198
+
199
+ # it 'should not perform a new search when in the first page' do
200
+ # @search.stub(:hits).and_return(mock_hits([@record.id, '12345', '98765']))
201
+ # Search.should_receive(:new).once
202
+ # @record.find_next_and_previous_records(@user, {text: 'dogs'})
203
+ # @record.previous_record).to be_nil
204
+ # end
205
+ # end
206
+
207
+ # context 'last record in the results' do
208
+ # before(:each) do
209
+ # @search.stub(:hits).and_return(mock_hits(['12345', '98765', @record.id]))
210
+ # @search.stub(:per_page).and_return(3)
211
+ # end
212
+
213
+ # it 'should perform a new search for the next page' do
214
+ # @search.stub(:total).and_return(6)
215
+ # Search.should_receive(:new).with(anything)
216
+ # Search.should_receive(:new).with(hash_including(page: 2))
217
+ # @record.find_next_and_previous_records(@user, {text: 'dogs'})
218
+ # @record.next_page).to eq(2)
219
+ # end
220
+
221
+ # it 'should not perform a new search when in the last page' do
222
+ # @search.stub(:total).and_return(3)
223
+ # Search.should_receive(:new).once
224
+ # @record.find_next_and_previous_records(@user, {text: 'dogs'})
225
+ # @record.next_record).to be_nil
226
+ # end
227
+ # end
228
+ end
229
+
230
+ def mock_hits(primary_keys=[])
231
+ primary_keys.map {|pk| double(:hit, primary_key: pk.to_s )}
232
+ end
233
+
234
+ # describe 'harvest_job_id=()' do
235
+ # it 'finds a harvest job and assigns it to harvest_job' do
236
+ # harvest_job = FactoryGirl.create(:harvest_job, harvest_job_id: 13)
237
+ # record = Record.new(harvest_job_id: 13)
238
+ # record.harvest_job).to eq(harvest_job)
239
+ # end
240
+
241
+ # it 'returns nil for a non existent harvest job' do
242
+ # record = Record.new(harvest_job_id: 13)
243
+ # record.harvest_job).to be_nil
244
+ # end
245
+ # end
246
+
247
+ describe '#active?' do
248
+ before(:each) do
249
+ @record = FactoryGirl.build(:record)
250
+ end
251
+
252
+ it 'returns true when state is active' do
253
+ @record.status = 'active'
254
+ expect(@record.active?).to be_truthy
255
+ end
256
+
257
+ it 'returns false when state is deleted' do
258
+ @record.status = 'deleted'
259
+ expect(@record.active?).to be_falsey
260
+ end
261
+ end
262
+
263
+ describe '#should_index?' do
264
+ before(:each) do
265
+ @record = FactoryGirl.build(:record)
266
+ end
267
+
268
+ it 'returns false when active? is false' do
269
+ allow(@record).to receive(:active?) { false }
270
+ expect(@record.should_index?).to be_falsey
271
+ end
272
+
273
+ it 'returns true when active? is true' do
274
+ allow(@record).to receive(:active?) { true }
275
+ expect(@record.should_index?).to be_truthy
276
+ end
277
+ end
278
+
279
+ end
280
+ end
@@ -0,0 +1,272 @@
1
+ # The majority of the Supplejack API code is Crown copyright (C) 2014, New Zealand Government,
2
+ # and is licensed under the GNU General Public License, version 3.
3
+ # One component is a third party component. See https://github.com/DigitalNZ/supplejack_api for details.
4
+ #
5
+ # Supplejack was created by DigitalNZ at the National Library of NZ and
6
+ # the Department of Internal Affairs. http://digitalnz.org/supplejack
7
+
8
+ require 'spec_helper'
9
+
10
+ module SupplejackApi
11
+ describe SchemaDefinition do
12
+
13
+ class ExampleSchema
14
+ include SchemaDefinition
15
+
16
+ namespace :dc, url: 'http://purl.org/dc/elements/1.1/'
17
+
18
+ string :title, search_boost: 10, search_as: [:fulltext], namespace: :dc, namespace_field: :creator
19
+ string :display_collection
20
+ string :primary_collection, multi_value: true, search_as: [:filter]
21
+ boolean :is_natlib_record, search_as: [:filter]
22
+ integer :year do
23
+ multi_value true
24
+ store false
25
+ search_as [:filter]
26
+ search_value do |record|
27
+ record.date.map { |date| Date.parse(date).year rescue nil}.compact if record.date
28
+ end
29
+ end
30
+ datetime :syndication_date, search_as: [:filter]
31
+ string :text, solr_name: :text
32
+ string :display_date, date_format: '%y/%d/%m'
33
+ string :dnz_type, default_value: 'Unknown'
34
+
35
+ latlon(:lat_lng) do
36
+ search_as [:filter]
37
+ multi_value true
38
+ search_value do |record|
39
+ record.locations.keep_if do |l|
40
+ (l.lat.present? and l.lng.present?) ? Sunspot::Util::Coordinates.new(l.lat, l.lng) : Sunspot::Util::Coordinates.new(0, 0)
41
+ end
42
+ end
43
+ end
44
+
45
+ mongo_index :year, fields: [{year: 1}], index_options: [{background:true}]
46
+ mongo_index :title_is_natlib_record, fields: [{title: 1, is_natlib_record: 1}]
47
+
48
+ group :default do
49
+ fields [
50
+ :title,
51
+ :year
52
+ ]
53
+ end
54
+
55
+ group :verbose do
56
+ includes [:default]
57
+ fields [
58
+ :locations
59
+ ]
60
+ end
61
+
62
+ group :everything do
63
+ includes [:default, :verbose]
64
+ fields [
65
+ :id
66
+ ]
67
+ end
68
+
69
+ role :admin
70
+ role :user
71
+
72
+ role :developer do
73
+ default true
74
+ field_restrictions (
75
+ {
76
+ creator: { 'John Smith' => ['attachments', 'location'] },
77
+ thumbnail_url: { /^http:\/\/secret/ => ['thumbnail_url'] }
78
+ }
79
+ )
80
+ record_restrictions (
81
+ {
82
+ is_catalog_record: true
83
+ }
84
+ )
85
+ end
86
+
87
+ model_field :name, field_options: { type: String }, validation: { presence: true }, index_fields: { name: 1, address: 1 }, index_options: { background: true }, store: false
88
+ end
89
+
90
+
91
+ describe '#fields' do
92
+
93
+ it 'describes title' do
94
+ expect(ExampleSchema.fields[:title].name).to eq :title
95
+ expect(ExampleSchema.fields[:title].type).to eq :string
96
+ expect(ExampleSchema.fields[:title].search_boost).to eq 10
97
+ expect(ExampleSchema.fields[:title].search_as).to eq [:fulltext]
98
+ expect(ExampleSchema.fields[:title].namespace).to eq :dc
99
+ expect(ExampleSchema.fields[:title].namespace_field).to eq :creator
100
+ end
101
+
102
+ it 'deiscribe dnz_type' do
103
+ expect(ExampleSchema.fields[:dnz_type].name).to eq :dnz_type
104
+ expect(ExampleSchema.fields[:dnz_type].default_value).to eq 'Unknown'
105
+ end
106
+
107
+ it 'deiscribe display_date' do
108
+ expect(ExampleSchema.fields[:display_date].name).to eq :display_date
109
+ expect(ExampleSchema.fields[:display_date].date_format).to eq '%y/%d/%m'
110
+ end
111
+
112
+ it 'describes display_collection' do
113
+ expect(ExampleSchema.fields[:display_collection].name).to eq :display_collection
114
+ expect(ExampleSchema.fields[:display_collection].type).to eq :string
115
+ end
116
+
117
+ it 'describes primary_collection' do
118
+ expect(ExampleSchema.fields[:primary_collection].name).to eq :primary_collection
119
+ expect(ExampleSchema.fields[:primary_collection].type).to eq :string
120
+ expect(ExampleSchema.fields[:primary_collection].multi_value).to be_truthy
121
+ expect(ExampleSchema.fields[:primary_collection].search_as).to eq [:filter]
122
+ end
123
+
124
+ it 'describes is_natlib_record' do
125
+ expect(ExampleSchema.fields[:is_natlib_record].name).to eq :is_natlib_record
126
+ expect(ExampleSchema.fields[:is_natlib_record].type).to eq :boolean
127
+ end
128
+
129
+ it 'describes year' do
130
+ expect(ExampleSchema.fields[:year].name).to eq :year
131
+ expect(ExampleSchema.fields[:year].type).to eq :integer
132
+ expect(ExampleSchema.fields[:year].multi_value).to be_truthy
133
+ expect(ExampleSchema.fields[:year].store).to be_falsey
134
+ expect(ExampleSchema.fields[:year].search_as).to eq [:filter]
135
+ expect(ExampleSchema.fields[:year].search_value).to be_a Proc
136
+ end
137
+
138
+ it 'describes syndication_date' do
139
+ expect(ExampleSchema.fields[:syndication_date].name).to eq :syndication_date
140
+ expect(ExampleSchema.fields[:syndication_date].type).to eq :datetime
141
+ expect(ExampleSchema.fields[:syndication_date].search_as).to eq [:filter]
142
+ end
143
+
144
+ it 'describes text' do
145
+ expect(ExampleSchema.fields[:text].name).to eq :text
146
+ expect(ExampleSchema.fields[:text].type).to eq :string
147
+ expect(ExampleSchema.fields[:text].solr_name).to eq :text
148
+ end
149
+
150
+ it 'describes lat_lng' do
151
+ expect(ExampleSchema.fields[:lat_lng].name).to eq :lat_lng
152
+ expect(ExampleSchema.fields[:lat_lng].type).to eq :latlon
153
+ expect(ExampleSchema.fields[:lat_lng].search_as).to eq [:filter]
154
+ expect(ExampleSchema.fields[:lat_lng].multi_value).to be_truthy
155
+ end
156
+
157
+ context 'namespace field' do
158
+ it 'returns the namespace field' do
159
+ expect(ExampleSchema.fields[:title].namespace_field).to eq :creator
160
+ end
161
+
162
+ it 'returns the field name if a namespace_field is not defined' do
163
+ expect(ExampleSchema.fields[:display_collection].namespace_field).to eq :display_collection
164
+ end
165
+ end
166
+ end
167
+
168
+ describe '#groups' do
169
+ it 'returns all the groups defined' do
170
+ expect(ExampleSchema.groups.keys).to eq([:default, :verbose, :everything])
171
+ end
172
+
173
+ describe '#fields' do
174
+ it 'returns a list of fields in a group' do
175
+ expect(ExampleSchema.groups[:default].fields).to eq([:title, :year])
176
+ end
177
+ end
178
+
179
+ context 'includes groups' do
180
+ it 'includes another group of fields' do
181
+ expect(ExampleSchema.groups[:verbose].fields).to eq([:title, :year, :locations])
182
+ end
183
+
184
+ it 'includes multiple groups of fields' do
185
+ expect(ExampleSchema.groups[:everything].fields).to eq([:title, :year, :locations, :id])
186
+ end
187
+ end
188
+ end
189
+
190
+ describe '#roles' do
191
+ it 'should all the roles defined' do
192
+ expect(ExampleSchema.roles.keys).to eq([:admin, :user, :developer])
193
+ end
194
+
195
+ context 'field_restrictions' do
196
+ let(:restrictions) { ExampleSchema.roles[:developer].field_restrictions }
197
+
198
+ it 'should create a restriction on the attachments and location fields if the creator is John Smith' do
199
+ expect(restrictions[:creator]).to eq( {'John Smith' => ['attachments', 'location']} )
200
+ end
201
+
202
+ it 'should create a restriction on the thumbnail_url field if contains a value (matches regex)' do
203
+ expect(restrictions[:thumbnail_url]).to eq( {/^http:\/\/secret/ => ['thumbnail_url']} )
204
+ end
205
+ end
206
+
207
+ context 'record_restrictions' do
208
+ let(:restrictions) { ExampleSchema.roles[:developer].record_restrictions }
209
+
210
+ it 'should create a restriction on records where is_catalog_record is true' do
211
+ expect(restrictions[:is_catalog_record]).to be_truthy
212
+ end
213
+
214
+ it 'should not create a restriction if none are set' do
215
+ expect(ExampleSchema.roles[:admin].record_restrictions).to be_nil
216
+ end
217
+ end
218
+
219
+ context 'default' do
220
+ it 'should set the developer role as default' do
221
+ expect(ExampleSchema.default_role.name).to eq :developer
222
+ end
223
+
224
+ it 'should not set the admin role as default' do
225
+ expect(ExampleSchema.default_role.name).to_not eq :admin
226
+ end
227
+ end
228
+ end
229
+
230
+ describe '#namespaces' do
231
+ it 'should return all the defined namespaces' do
232
+ expect(ExampleSchema.namespaces.keys).to eq([:dc])
233
+ end
234
+ end
235
+
236
+ describe '#mongo_indexes' do
237
+ it 'returns all the mongo indexes that are defined' do
238
+ expect(ExampleSchema.mongo_indexes.keys).to eq [:year, :title_is_natlib_record]
239
+ end
240
+
241
+ it 'returns the fields for a given index' do
242
+ expect(ExampleSchema.mongo_indexes[:year].fields).to eq [{year: 1}]
243
+ end
244
+
245
+ it 'returns the index_options for an index' do
246
+ expect(ExampleSchema.mongo_indexes[:year].index_options).to eq [{background:true}]
247
+ end
248
+ end
249
+
250
+ describe '#model_field' do
251
+ it 'returns all the model fields that are defined' do
252
+ expect(ExampleSchema.model_fields.keys).to eq [:name]
253
+ end
254
+
255
+ it 'returns the field_options for a model' do
256
+ expect(ExampleSchema.model_fields[:name].field_options).to include({ type: String })
257
+ end
258
+
259
+ it 'returns the validation for a model' do
260
+ expect(ExampleSchema.model_fields[:name].validation).to include({ presence: true })
261
+ end
262
+
263
+ it 'returns the index_fields for a model' do
264
+ expect(ExampleSchema.model_fields[:name].index_fields).to include({ name: 1 })
265
+ end
266
+
267
+ it 'returns the index_options for a model' do
268
+ expect(ExampleSchema.model_fields[:name].index_options).to include({ background: true })
269
+ end
270
+ end
271
+ end
272
+ end