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,177 @@
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
+ module Support
12
+ describe Harvestable do
13
+ let(:record) { FactoryGirl.build(:record) }
14
+
15
+ describe '#create_or_update_fragment' do
16
+ before { record.save }
17
+
18
+ context 'existing fragment' do
19
+ before do
20
+ @fragment = record.fragments.create(source_id: 'nz_census', name: 'John Smith', age: 50)
21
+ record.create_or_update_fragment({'source_id' => 'nz_census', 'age' => 100})
22
+ end
23
+
24
+ it 'updates the fragment attributes' do
25
+ expect(@fragment.age).to eq 100
26
+ end
27
+
28
+ it 'nilifies the fields not updated in the fragment' do
29
+ expect(@fragment.name).to be_nil
30
+ end
31
+ end
32
+
33
+ context 'new fragment' do
34
+ it 'creates a new fragment' do
35
+ record.create_or_update_fragment({'source_id' => 'nz_census', 'name' => 'John Smith', 'priority' => [1]})
36
+ fragment = record.find_fragment('nz_census')
37
+ expect(fragment).to_not be_nil
38
+ expect(fragment.name).to eq 'John Smith'
39
+ expect(fragment.priority).to eq 1
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#set_status' do
45
+ before {
46
+ record.fragments.build(source_id: 'nz_census', name: 'John Smith')
47
+ }
48
+
49
+ it 'sets the status to active if nil is passed' do
50
+ record.set_status(nil)
51
+ expect(record.status).to eq 'active'
52
+ end
53
+
54
+ it 'sets the status to active if an empty array is passed' do
55
+ record.set_status([])
56
+ expect(record.status).to eq 'active'
57
+ end
58
+
59
+ it 'sets the status to partial if one required fragment does not exists' do
60
+ record.set_status(['nz_census', 'thumbnails'])
61
+ expect(record.status).to eq 'partial'
62
+ end
63
+
64
+ it 'sets the status to active if all required fragments exist' do
65
+ record.fragments.build(source_id: 'thumbnails', name: 'John Smith')
66
+ record.set_status(['nz_census', 'thumbnails'])
67
+ expect(record.status).to eq 'active'
68
+ end
69
+ end
70
+
71
+ describe '#clear_attributes' do
72
+ let(:record) { FactoryGirl.create(:record, internal_identifier: "1234") }
73
+
74
+ it 'doesn\'t clear the _id attribute' do
75
+ record.clear_attributes
76
+ expect(record._id).to_not be_nil
77
+ end
78
+
79
+ end
80
+
81
+ describe '#unset_null_fields' do
82
+ it 'unsets null fields Mongo' do
83
+ record = FactoryGirl.create(:record, name: 'John Smith')
84
+ record.update_attributes(name: nil)
85
+ record.unset_null_fields
86
+ raw_record = record.reload.raw_attributes
87
+ expect(raw_record).to_not have_key('name')
88
+ end
89
+
90
+ it 'should unset null fields inside fragments' do
91
+ record = FactoryGirl.build(:record_with_fragment, record_id: 1234)
92
+ record.primary_fragment.update_attributes(address: nil)
93
+ record.unset_null_fields
94
+ raw_record = record.reload.raw_attributes
95
+ expect(raw_record['fragments'][0]).to_not have_key('address')
96
+ end
97
+
98
+ it 'should handle null fragments' do
99
+ record = FactoryGirl.create(:record_with_fragment, record_id: 1234)
100
+ allow(record).to receive(:raw_attributes) { {'fragments' => [nil]} }
101
+ expect { record.unset_null_fields }.to_not raise_exception
102
+ end
103
+
104
+ it 'should handle false fields inside fragments' do
105
+ record = FactoryGirl.create(:record_with_fragment, record_id: 1234)
106
+ record.primary_fragment.update_attributes(nz_citizen: false)
107
+ record.unset_null_fields
108
+ raw_record = record.reload.raw_attributes
109
+ expect(raw_record['fragments'][0]).to have_key('nz_citizen')
110
+ end
111
+
112
+ it 'doesn\'t unset any field with values' do
113
+ record = FactoryGirl.create(:record_with_fragment, record_id: 1234)
114
+ record.unset_null_fields
115
+ raw_record = record.reload.raw_attributes
116
+ expect(raw_record).to include({'record_id' => 1234})
117
+ expect(raw_record['fragments'][0]).to include({'address' => 'Wellington'})
118
+ end
119
+
120
+ it 'should not trigger a db query if there is nothing to unset' do
121
+ record = FactoryGirl.create(:record)
122
+ expect(record.collection).to_not receive(:find)
123
+ record.unset_null_fields
124
+ end
125
+
126
+ it 'should handle new records' do
127
+ records = Record.new
128
+ record.unset_null_fields
129
+ end
130
+ end
131
+
132
+ describe '.find_or_initialize_by_identifier' do
133
+ it 'finds from the internal_identifier param' do
134
+ expect(Record).to receive(:find_or_initialize_by).with(internal_identifier: '1234')
135
+ Record.find_or_initialize_by_identifier({internal_identifier: '1234'})
136
+ end
137
+
138
+ it 'handles an array of identifiers' do
139
+ expect(Record).to receive(:find_or_initialize_by).with(internal_identifier: '1234')
140
+ Record.find_or_initialize_by_identifier({internal_identifier: ['1234']})
141
+ end
142
+ end
143
+
144
+ describe '.flush_old_records' do
145
+ before do
146
+ @record1 = FactoryGirl.create(:record_with_fragment)
147
+ @record1.primary_fragment.job_id = '123'
148
+ @record1.save
149
+
150
+ @record2 = FactoryGirl.create(:record_with_fragment)
151
+ @record2.primary_fragment.job_id = 'abc'
152
+ @record2.save
153
+ end
154
+
155
+ it 'sets status deleted on records with the source_id, but without the given job_id' do
156
+ Record.flush_old_records @record1.primary_fragment.source_id, '123'
157
+
158
+ expect(@record1.reload.status).to eq 'active'
159
+ expect(@record2.reload.status).to eq 'deleted'
160
+ end
161
+
162
+ it 'only deletes record that don\'t have the job_id in any fragment' do
163
+ @record1.fragments.create(priority: -4, job_id: 'abc', source_id: 'a-fragment')
164
+ Record.flush_old_records @record1.primary_fragment.source_id, '123'
165
+
166
+ expect(@record1.reload.status).to eq 'active'
167
+ expect(@record2.reload.status).to eq 'deleted'
168
+ end
169
+
170
+ it 'indexs deleted records' do
171
+ expect(Sunspot).to receive(:remove)
172
+ Record.flush_old_records @record1.primary_fragment.source_id, '123'
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,85 @@
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
+ module Support
12
+ describe Searchable do
13
+ let(:record) { FactoryGirl.create(:record, record_id: 1234) }
14
+ let(:fragment) { record.fragments.create({nz_citizen: false }) }
15
+
16
+ before do
17
+ allow(RecordSchema).to receive(:fields) do
18
+ {
19
+ name: double(:field, name: :name, type: :string, search_as: [:filter]).as_null_object,
20
+ age: double(:field, name: :age, type: :integer, search_as: [:filter]).as_null_object,
21
+ birth_date: double(:field, name: :birth_date, type: :datetime, search_as: [:filter]).as_null_object,
22
+ nz_citizen: double(:field, name: :nz_citizen, type: :boolean, search_as: [:filter]).as_null_object,
23
+ email: double(:field, name: :email, type: :string, multi_value: true, search_as: [:filter]).as_null_object,
24
+ address: double(:field, name: :address, type: :string, search_as: [:filter], solr_name: :new_address).as_null_object,
25
+ occupation: double(:field, name: :occupation, type: :string, search_as: [:fulltext]).as_null_object,
26
+ birth_place: double(:field, name: :birth_place, type: :string, search_as: [:fulltext], search_boost: 10).as_null_object,
27
+ short_description: double(:field, name: :short_description, multi_value: true, type: :string, search_as: [:fulltext, :filter], search_boost: 2).as_null_object
28
+ }
29
+ end
30
+ end
31
+
32
+ describe 'build_sunspot_schema' do
33
+ let(:builder) { double(:search_builder).as_null_object }
34
+ let(:search_value) { double(:proc) }
35
+
36
+ after do
37
+ Record.build_sunspot_schema(builder)
38
+ end
39
+
40
+ it 'defines a single value string field' do
41
+ expect(builder).to receive(:string).with(:name, {})
42
+ end
43
+
44
+ it 'defines a single value integer field' do
45
+ expect(builder).to receive(:integer).with(:age, {})
46
+ end
47
+
48
+ it 'defines a single value time field' do
49
+ expect(builder).to receive(:time).with(:birth_date, {})
50
+ end
51
+
52
+ it 'defines a single value boolean field' do
53
+ expect(builder).to receive(:boolean).with(:nz_citizen, {})
54
+ end
55
+
56
+ it 'defines a multivalue field' do
57
+ expect(builder).to receive(:string).with(:email, {multiple: true})
58
+ end
59
+
60
+ it 'defines a field with a different name' do
61
+ expect(builder).to receive(:string).with(:address, {as: :new_address})
62
+ end
63
+
64
+ it 'defines a full text field' do
65
+ expect(builder).to receive(:text).with(:occupation, {})
66
+ end
67
+
68
+ it 'defines a full text field with boost' do
69
+ expect(builder).to receive(:text).with(:birth_place, {boost: 10})
70
+ end
71
+
72
+ it 'defines a field with fulltext and filter, and lots of options' do
73
+ expect(builder).to receive(:text).with(:short_description, {boost: 2})
74
+ expect(builder).to receive(:string).with(:short_description, {multiple: true})
75
+ end
76
+ end
77
+
78
+ describe 'valid_facets' do
79
+ it 'returns all fields with search_as filter' do
80
+ expect(Record.valid_facets).to eq [:name, :age, :birth_date, :nz_citizen, :email, :address, :short_description]
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,18 @@
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
+ module Support
12
+ describe Storable do
13
+ let(:record) { FactoryGirl.create(:record, record_id: 1234, internal_identifier: "nlnz:1234") }
14
+ let(:source) { record.sources.create }
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,88 @@
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 UserActivity do
12
+ let(:activity) { SupplejackApi::UserActivity.new }
13
+
14
+ describe '#calculate_total_for' do
15
+ it 'generates the total for the grouped activities' do
16
+ activity.user_sets = {create: 1, update: 2, destroy: 3, index: 4, show: 5}
17
+ activity.calculate_total_for(:user_sets)
18
+ expect(activity.user_sets['total']).to eq 15
19
+ end
20
+
21
+ it 'handles activities with null values' do
22
+ activity.search = {records: nil, custom_search: 3}
23
+ activity.calculate_total_for(:search)
24
+ expect(activity.search['total']).to eq 3
25
+ end
26
+
27
+ it 'handles where the whole hash is nil' do
28
+ activity.search = nil
29
+ activity.calculate_total_for(:search)
30
+ expect(activity.search['total']).to eq 0
31
+ end
32
+ end
33
+
34
+ describe '#calculate_total' do
35
+ it 'calculates the overall total' do
36
+ activity.user_sets = {'total' => 1}
37
+ activity.search = {'total' => 2}
38
+ activity.records = {'total' => 3}
39
+ activity.custom_searches = {'total' => 5}
40
+ activity.calculate_total
41
+ expect(activity.total).to eq 11
42
+ end
43
+
44
+ it 'handles nil fields' do
45
+ activity.user_sets = nil
46
+ activity.calculate_total
47
+ expect(activity.total).to eq 0
48
+ end
49
+ end
50
+
51
+ describe '#build_from_user' do
52
+ let(:activity) { {'user_sets' => {'total' => 1},
53
+ 'search' => {'custom_search' => 2},
54
+ 'records' => {'show' => 1, 'multiple' => 2},
55
+ 'custom_searches' => {'index' => 1, 'show' => 2}
56
+ } }
57
+
58
+ it 'buils a user_activity with user_sets stats' do
59
+ user_activity = SupplejackApi::UserActivity.build_from_user(activity)
60
+ expect(user_activity.user_sets).to eq({'total' => 1})
61
+ end
62
+
63
+ it 'buils a user_activity with search stats' do
64
+ user_activity = SupplejackApi::UserActivity.build_from_user(activity)
65
+ expect(user_activity.search).to eq({'custom_search' => 2, 'total' => 2})
66
+ end
67
+
68
+ it 'buils a user_activity with records stats' do
69
+ user_activity = SupplejackApi::UserActivity.build_from_user(activity)
70
+ expect(user_activity.records).to eq({'show' => 1, 'multiple' => 2, 'total' => 3})
71
+ end
72
+
73
+ it 'buils a user_activity with custom_searches stats' do
74
+ user_activity = SupplejackApi::UserActivity.build_from_user(activity)
75
+ expect(user_activity.custom_searches).to eq({'index' => 1, 'show' => 2, 'total' => 3})
76
+ end
77
+
78
+ it 'calculates the total of requests' do
79
+ user_activity = SupplejackApi::UserActivity.build_from_user(activity)
80
+ expect(user_activity.total).to eq 9
81
+ end
82
+
83
+ it 'returns nil when there is no activity for a group' do
84
+ expect(SupplejackApi::UserActivity.build_from_user(nil).records).to be_nil
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,559 @@
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 UserSet do
12
+
13
+ let(:user_set) { FactoryGirl.build(:user_set)}
14
+
15
+ before(:each) do
16
+ allow(user_set).to receive(:update_record)
17
+ allow(user_set).to receive(:reindex_items)
18
+ end
19
+
20
+ context "validations" do
21
+ it "is not valid without a name" do
22
+ user_set.name = nil
23
+ expect(user_set).to_not be_valid
24
+ end
25
+
26
+ ["public", "hidden", "private"].each do |privacy|
27
+ it "is valid with a #{privacy} privacy" do
28
+ user_set.privacy = privacy
29
+ expect(user_set).to be_valid
30
+ end
31
+ end
32
+
33
+ it "is not valid with another privacy setting" do
34
+ user_set.privacy = "admin"
35
+ expect(user_set).to_not be_valid
36
+ end
37
+ end
38
+
39
+ context "callbacks" do
40
+ it "sets the privacy to public if not set" do
41
+ user_set.privacy = ""
42
+ user_set.save
43
+ user_set.reload
44
+ expect(user_set.privacy).to eq "public"
45
+ end
46
+
47
+ describe "set_default_privacy" do
48
+ it "should not override the privacy if set" do
49
+ user_set.privacy = "private"
50
+ user_set.set_default_privacy
51
+ expect(user_set.privacy).to eq "private"
52
+ end
53
+ end
54
+
55
+ describe "#strip_html_tags" do
56
+ it "removes html tags from the name" do
57
+ user_set.name = "Dogs and <b>Cats</b>"
58
+ user_set.strip_html_tags
59
+ expect(user_set.name).to eq "Dogs and Cats"
60
+ end
61
+
62
+ it "removes html tags from the description" do
63
+ user_set.description = "Dogs and <b>Cats</b>"
64
+ user_set.strip_html_tags
65
+ expect(user_set.description).to eq "Dogs and Cats"
66
+ end
67
+
68
+ it "removes html tags from the tags" do
69
+ user_set.tags = ["Dogs", "<b>Cats</b>"]
70
+ user_set.strip_html_tags
71
+ expect(user_set.tags).to eq ["Dogs", "Cats"]
72
+ end
73
+ end
74
+
75
+ it "calls update_record before saving" do
76
+ expect(user_set).to receive(:update_record)
77
+ user_set.save
78
+ end
79
+
80
+ it "should mark the associated record for deletion before deleting the set" do
81
+ expect(user_set).to receive(:delete_record)
82
+ user_set.destroy
83
+ end
84
+
85
+ it "calls reindex_items after save" do
86
+ expect(user_set).to receive(:reindex_items)
87
+ user_set.save
88
+ end
89
+ end
90
+
91
+ describe ".find_by_record_id" do
92
+ it "returns a set_item by it's record_id" do
93
+ set_item = user_set.set_items.build(record_id: 12)
94
+ user_set.save
95
+ expect(user_set.set_items.find_by_record_id(12)).to eq set_item
96
+ end
97
+ end
98
+
99
+ describe "relationships" do
100
+ it "should have a single record" do
101
+ user_set.record = SupplejackApi::Record.new
102
+ expect(user_set.record).to_not be_nil
103
+ end
104
+ end
105
+
106
+ describe ".find_by_record_id" do
107
+ it "returns a set_item by it's record_id" do
108
+ set_item = user_set.set_items.build(record_id: 12)
109
+ user_set.save
110
+ expect(user_set.set_items.find_by_record_id(12)).to eq set_item
111
+ end
112
+ end
113
+
114
+ describe "#name" do
115
+ let(:user_set) { FactoryGirl.build(:user_set, user_id: User.new.id, url: "1234abc")}
116
+
117
+ it "titlizes the name" do
118
+ user_set.name = "set name"
119
+ expect(user_set.name).to eq "Set name"
120
+ end
121
+
122
+ it "only force capitalizes the first letter" do
123
+ user_set.name = "YMCA"
124
+ expect(user_set.name).to eq "YMCA"
125
+ end
126
+ end
127
+
128
+ describe "#custom_find" do
129
+ before(:each) do
130
+ @user_set = FactoryGirl.build(:user_set, user_id: User.new.id, url: "1234abc")
131
+ allow(@user_set).to receive(:update_record)
132
+ @user_set.save
133
+ end
134
+
135
+ it "finds a user set by its default Mongo ID" do
136
+ expect(UserSet.custom_find(@user_set.id.to_s)).to eq @user_set
137
+ end
138
+
139
+ it "returns nil when it doesn't find the user by Mongo ID" do
140
+ expect(UserSet.custom_find("111122223333444455556666")).to be_nil
141
+ end
142
+
143
+ it "finds a user set by it's url" do
144
+ expect(UserSet.custom_find("1234abc")).to eq @user_set
145
+ end
146
+
147
+ it "returns nil when id is nil" do
148
+ expect(UserSet.custom_find(nil)).to be_nil
149
+ end
150
+
151
+ it "returns nil when it doesn't find the user set" do
152
+ expect(UserSet.custom_find("12345678")).to be_nil
153
+ end
154
+ end
155
+
156
+ describe "#public_sets" do
157
+ before :each do
158
+ @set1 = FactoryGirl.create(:user_set, privacy: "public")
159
+ @set2 = FactoryGirl.create(:user_set, privacy: "hidden")
160
+ end
161
+
162
+ it "returns all public sets" do
163
+ expect(UserSet.public_sets).to eq([@set1])
164
+ end
165
+
166
+ it "ignores favourites" do
167
+ @set3 = FactoryGirl.create(:user_set, privacy: "public", name: "Favourites")
168
+ expect(UserSet.public_sets.to_a).to_not include(@set3)
169
+ end
170
+
171
+ it "paginates the sets" do
172
+ expect(UserSet.public_sets(page: 2).to_a).to be_empty
173
+ end
174
+
175
+ it "handles an empty page parameter" do
176
+ proxy = double(:proxy).as_null_object
177
+ allow(UserSet).to receive(:where) { proxy }
178
+ expect(proxy).to receive(:page).with(1)
179
+ UserSet.public_sets(page: "")
180
+ end
181
+
182
+ it "sorts the sets by last modified date" do
183
+ proxy = double(:proxy).as_null_object
184
+ allow(UserSet).to receive(:where) { proxy }
185
+ allow(proxy).to receive_message_chain(:desc, :page)
186
+ expect(proxy).to receive(:desc).with(:created_at)
187
+ UserSet.public_sets
188
+ end
189
+ end
190
+
191
+ describe "#featured_sets" do
192
+ before :each do
193
+ @record = FactoryGirl.create(:record, status: "active", record_id: 1234)
194
+ @set1 = FactoryGirl.create(:user_set, privacy: "public", featured: true, featured_at: Time.now - 4.hours)
195
+ @set1.set_items.create(record_id: 1234)
196
+ @set2 = FactoryGirl.create(:user_set, privacy: "hidden", featured: true)
197
+ @set2.set_items.create(record_id: 1234)
198
+ @set3 = FactoryGirl.create(:user_set, privacy: "public", featured: false)
199
+ @set3.set_items.create(record_id: 1234)
200
+ end
201
+
202
+ it "returns public sets" do
203
+ expect(UserSet.featured_sets.to_a).to eq [@set1]
204
+ end
205
+
206
+ it "orders the sets based on when they were added" do
207
+ @set4 = FactoryGirl.create(:user_set, privacy: "public", featured: true, featured_at: Time.now)
208
+ @set4.set_items.create(record_id: 1234)
209
+ expect(UserSet.featured_sets.first).to eq @set4
210
+ end
211
+
212
+ it "doesn't return sets without active records" do
213
+ @set4 = FactoryGirl.create(:user_set, privacy: "public", featured: true, name: "No records")
214
+ expect(UserSet.featured_sets).to_not include(@set4)
215
+ end
216
+ end
217
+
218
+ describe "#update_attributes_and_embedded" do
219
+ before {
220
+ developer = double(:developer)
221
+ admin = double(:admin, admin: true, role: 'admin')
222
+ allow(RecordSchema).to receive(:roles) { { admin: admin, developer: developer } }
223
+ }
224
+
225
+ it "updates the set attributes" do
226
+ user_set.update_attributes_and_embedded(name: "New dog", description: "New dog", privacy: "hidden")
227
+ user_set.reload
228
+ expect(user_set.name).to eq "New dog"
229
+ expect(user_set.description).to eq "New dog"
230
+ expect(user_set.privacy).to eq "hidden"
231
+ end
232
+
233
+ it "updates the embedded set items" do
234
+ user_set.update_attributes_and_embedded(records: [{"record_id" => "13", "position" => "2"}])
235
+ user_set.reload
236
+ expect(user_set.set_items.size).to eq 1
237
+ expect(user_set.set_items.first.record_id).to eq 13
238
+ expect(user_set.set_items.first.position).to eq 2
239
+ end
240
+
241
+ it "ignores invalid attributes" do
242
+ user_set.update_attributes_and_embedded(something: "Bad attribute")
243
+ user_set.reload
244
+ expect(user_set[:something]).to be_nil
245
+ end
246
+
247
+ it "ignores invalid set items but still saves the set" do
248
+ user_set.update_attributes_and_embedded(records: [{"record_id" => "13", "position" => "1"}, {"position" => "2"}])
249
+ user_set.reload
250
+ expect(user_set.set_items.size).to eq 1
251
+ expect(user_set.set_items.first.record_id).to eq 13
252
+ expect(user_set.set_items.first.position).to eq 1
253
+ end
254
+
255
+ it "ignores set_items when the format is incorrect" do
256
+ user_set.update_attributes_and_embedded(records: {"record_id" => "13", "position" => "1"})
257
+ user_set.reload
258
+ expect(user_set.set_items.size).to eq 0
259
+ end
260
+
261
+ it "regular users should not be able to change the :featured attribute" do
262
+ regular_user = FactoryGirl.create(:user, role: "developer")
263
+ user_set = FactoryGirl.create(:user_set, user_id: regular_user.id, featured: false)
264
+ user_set.update_attributes_and_embedded({featured: true}, regular_user)
265
+ user_set.reload
266
+ expect(user_set.featured).to be_falsey
267
+ end
268
+
269
+ it "should allow admins to change the :featured attribute" do
270
+ admin_user = FactoryGirl.create(:user, role: "admin")
271
+ user_set = FactoryGirl.create(:user_set, user_id: admin_user.id)
272
+ user_set.update_attributes_and_embedded({featured: true}, admin_user)
273
+ user_set.reload
274
+ expect(user_set.featured).to be_truthy
275
+ end
276
+
277
+ it "should update the featured_at when the featured attribute is updated" do
278
+ admin_user = FactoryGirl.create(:user, role: "admin")
279
+ user_set = FactoryGirl.create(:user_set, user_id: admin_user.id)
280
+ Timecop.freeze(Time.now) do
281
+ user_set.update_attributes_and_embedded({featured: true}, admin_user)
282
+ user_set.reload
283
+ expect(user_set.featured_at.to_i).to eq Time.now.to_i
284
+ end
285
+ end
286
+
287
+ it "should not update the featured_at if the featured hasn't changed" do
288
+ admin_user = FactoryGirl.create(:user, role: "admin")
289
+ time = Time.now-1.day
290
+ user_set = FactoryGirl.create(:user_set, user_id: admin_user.id, featured: true, featured_at: time)
291
+ Timecop.freeze(Time.now) do
292
+ user_set.update_attributes_and_embedded({featured: true}, admin_user)
293
+ user_set.reload
294
+ expect(user_set.featured_at.to_i).to eq time.to_i
295
+ end
296
+ end
297
+
298
+ it "removes the set from the featured" do
299
+ admin_user = FactoryGirl.create(:user, role: "admin")
300
+ time = Time.now-1.day
301
+ user_set = FactoryGirl.create(:user_set, user_id: admin_user.id, featured: true, featured_at: time)
302
+ user_set.update_attributes_and_embedded({featured: false}, admin_user)
303
+ user_set.reload
304
+ expect(user_set.featured).to be_falsey
305
+ end
306
+
307
+ it "initializes the set_items through the user_set" do
308
+ item = user_set.set_items.build(record_id: 13)
309
+ expect(user_set.set_items).to receive(:find_or_initialize_by).with({record_id: "13"}) { item }
310
+ user_set.update_attributes_and_embedded(records: [{"record_id" => "13", "position" => nil}])
311
+ end
312
+
313
+ it "can replace the set items" do
314
+ user_set.save
315
+ user_set.set_items.create(record_id: 13)
316
+ user_set.update_attributes_and_embedded(records: [{"record_id" => "13", "position" => nil}])
317
+ user_set.reload
318
+ expect(user_set.set_items.size).to eq 1
319
+ expect(user_set.set_items.first.record_id).to eq 13
320
+ end
321
+
322
+ it "should not replace the set items if :records is nil" do
323
+ user_set.save
324
+ user_set.set_items.create(record_id: 13)
325
+ user_set.update_attributes_and_embedded(records: nil)
326
+ user_set.reload
327
+ expect(user_set.set_items.count).to eq 1
328
+ end
329
+
330
+ it "raises a error when then records array format is not correct" do
331
+ expect { user_set.update_attributes_and_embedded(records: [1,2]) }.to raise_error(UserSet::WrongRecordsFormat)
332
+ end
333
+ end
334
+
335
+ describe "#calculate_count" do
336
+ it "returns 2 when there are 2 active set items" do
337
+ allow(user_set).to receive(:records){[double(:record), double(:record)]}
338
+ user_set.calculate_count
339
+ expect(user_set.count).to eq(2)
340
+ end
341
+ end
342
+
343
+ describe "record_status" do
344
+ it "should return 'active' for public and approved sets" do
345
+ user_set.privacy = "public"
346
+ user_set.approved = true
347
+
348
+ expect(user_set.record_status).to eq "active"
349
+ end
350
+
351
+ it "should return 'suppressed' for non-public or non-approved sets" do
352
+ user_set.privacy = "protected"
353
+ user_set.approved = false
354
+
355
+ expect(user_set.record_status).to eq "suppressed"
356
+ end
357
+ end
358
+
359
+ describe "update record" do
360
+ before(:each) do
361
+ allow(user_set).to receive(:update_record).and_call_original
362
+ allow(SupplejackApi::Record).to receive(:custom_find) { double(:record).as_null_object }
363
+ end
364
+
365
+ context "user set attributes" do
366
+ before(:each) do
367
+ allow(user_set).to receive(:set_items) { [double(:set_item).as_null_object] }
368
+ end
369
+
370
+ it "should create a new record if not linked" do
371
+ expect(SupplejackApi::Record).to receive(:new) { mock_model(SupplejackApi::Record).as_null_object }
372
+ user_set.update_record
373
+ end
374
+
375
+ it "should not create a new record if already linked" do
376
+ allow(user_set).to receive(:record) { double(:record).as_null_object }
377
+ expect(SupplejackApi::Record).to_not receive(:new)
378
+ user_set.update_record
379
+ end
380
+
381
+ context "record status" do
382
+ it "should default the status to supressed" do
383
+ user_set.privacy = "private"
384
+
385
+ user_set.update_record
386
+ expect(user_set.record.status).to eq "suppressed"
387
+ end
388
+
389
+ it "should set the status to active if set is public and is approved" do
390
+ user_set.privacy = "public"
391
+ user_set.approved = true
392
+
393
+ user_set.update_record
394
+ expect(user_set.record.status).to eq "active"
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ describe "delete_record" do
401
+ before(:each) do
402
+ @record = FactoryGirl.build(:record)
403
+ allow(user_set).to receive(:record) { @record }
404
+ end
405
+
406
+ it "should set record status to deleted" do
407
+ user_set.delete_record
408
+ expect(user_set.record.status).to eq "deleted"
409
+ end
410
+
411
+ it "should save the record" do
412
+ expect(@record).to receive(:save!)
413
+ user_set.delete_record
414
+ end
415
+ end
416
+
417
+ describe "#record_ids" do
418
+ it "returns an array of record ids for the set" do
419
+ user_set.set_items.build(record_id:100, position:0)
420
+ user_set.set_items.build(record_id:101, position:1)
421
+ user_set.save
422
+ expect(user_set.record_ids).to include(100,101)
423
+ end
424
+
425
+ it "returns an empty array when set items is nil" do
426
+ user_set.set_items = nil
427
+ expect(user_set.record_ids).to be_empty
428
+ end
429
+
430
+ it "returns the record_id's in the correct order" do
431
+ user_set.set_items.build(record_id:100, position:1)
432
+ user_set.set_items.build(record_id:101, position:0)
433
+ user_set.save
434
+ expect(user_set.record_ids).to eq([101,100])
435
+ end
436
+ end
437
+
438
+ describe "#records" do
439
+ before :each do
440
+ allow(user_set).to receive(:record_ids){[100,101]}
441
+ end
442
+
443
+ it "should get the active record objects included in the set" do
444
+ @record1 = FactoryGirl.create(:record, record_id:100, status: "active")
445
+ @record2 = FactoryGirl.create(:record, record_id:101, status: "deleted")
446
+ expect(user_set.records).to eq([@record1])
447
+ end
448
+
449
+ it "limits the amount of records" do
450
+ @record1 = FactoryGirl.create(:record, record_id:100, status: "active")
451
+ @record2 = FactoryGirl.create(:record, record_id:101, status: "active")
452
+ expect(user_set.records(1)).to eq([@record1])
453
+ end
454
+
455
+ it "it returns the first active record" do
456
+ @record1 = FactoryGirl.create(:record, record_id:100, status: "deleted")
457
+ @record2 = FactoryGirl.create(:record, record_id:101, status: "active")
458
+ expect(user_set.records(1)).to eq([@record2])
459
+ end
460
+
461
+ it "memoizes the records" do
462
+ expect(Record).to receive(:find_multiple).once { [] }
463
+ user_set.records
464
+ user_set.records
465
+ end
466
+ end
467
+
468
+ describe "#tags=" do
469
+ it "should enforce tags to be a array" do
470
+ user_set.tags = 1234
471
+ expect(user_set.tags).to eq [1234]
472
+ end
473
+ end
474
+
475
+ describe "#tag_list=" do
476
+ it "should convert the comma seperate string to an array of tags" do
477
+ user_set.tag_list = "dogs, animals, cats"
478
+ expect(user_set.tags).to include("dogs", "cats", "animals")
479
+ end
480
+
481
+ it "removes empty tags" do
482
+ user_set.tag_list = "dogs, , animals"
483
+ expect(user_set.tags.size).to eq(2)
484
+ end
485
+
486
+ it "handles a nil tag list" do
487
+ user_set.tag_list = nil
488
+ expect(user_set.tags).to be_empty
489
+ end
490
+
491
+ it "strips tags from punctuations except - and _" do
492
+ user_set.tag_list = "hola! d-a_s_h @#$\%^&*()+=.;: ,something else"
493
+ expect(user_set.tags).to eq ["hola d-a_s_h", "something else"]
494
+ end
495
+ end
496
+
497
+ describe "#tag_list" do
498
+ it "returns a comma seperated list of tags" do
499
+ user_set.tags = ["animal","dog","beast"]
500
+ expect(user_set.tag_list).to eq("animal, dog, beast")
501
+ end
502
+
503
+ it "returns an empty string when tags is nil" do
504
+ user_set.tags = nil
505
+ expect(user_set.tag_list).to be_nil
506
+ end
507
+ end
508
+
509
+ describe "#items_with_records" do
510
+ it "returns an array of set items with record information" do
511
+ record = FactoryGirl.create(:record, record_id: 5)
512
+ fragment = record.fragments.create( title: "Dog", description: "Ugly dog", display_content_partner: "ATL", display_collection: "Tapuhi", large_thumbnail_attributes: {url: "goo.gle/large"}, thumbnail_attributes: {url: "goo.gle/small"})
513
+ user_set.set_items.build(record_id: 5, position: 1)
514
+ expect(user_set.items_with_records.first.record).to eq record
515
+ end
516
+
517
+ it "removes set items which don't have a corresponding record" do
518
+ user_set.set_items.build(record_id: 5, position: 1)
519
+ expect(user_set.items_with_records.size).to eq 0
520
+ end
521
+
522
+ it "returns items_with_records sorted by position" do
523
+ FactoryGirl.create(:record, record_id: 5)
524
+ FactoryGirl.create(:record, record_id: 6)
525
+ user_set.set_items.build(record_id: 5, position: 2)
526
+ user_set.set_items.build(record_id: 6, position: 1)
527
+ expect(user_set.items_with_records[0].record_id).to eq 6
528
+ expect(user_set.items_with_records[1].record_id).to eq 5
529
+ end
530
+
531
+ it "only fetches the amount of records specified" do
532
+ record = FactoryGirl.create(:record, record_id: 6)
533
+ user_set.set_items.build(record_id: 5, position: 2)
534
+ user_set.set_items.build(record_id: 6, position: 1)
535
+ expect(user_set).to receive(:records).with(1) { [record] }
536
+ expect(user_set.items_with_records(1).size).to eq 1
537
+ end
538
+ end
539
+
540
+ describe "reindex_items" do
541
+ let(:record5) {double(:record)}
542
+ let(:record6) {double(:record)}
543
+ before do
544
+ allow(user_set).to receive(:reindex_items).and_call_original
545
+ end
546
+
547
+ it "finds each record can calls index" do
548
+ user_set.set_items.build(record_id: 5, position: 1)
549
+ user_set.set_items.build(record_id: 6, position: 2)
550
+ expect(SupplejackApi::Record).to receive(:custom_find).with(5) { record5 }
551
+ expect(SupplejackApi::Record).to receive(:custom_find).with(6) { record6 }
552
+ expect(record5).to receive(:index)
553
+ expect(record6).to receive(:index)
554
+ user_set.reindex_items
555
+ end
556
+ end
557
+
558
+ end
559
+ end