workarea-core 3.4.44 → 3.5.0.beta.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 (427) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +52 -0
  3. data/app/assets/javascripts/workarea/core/modules/duplicate_id.js +1 -5
  4. data/app/assets/javascripts/workarea/core/modules/style_guide_autocomplete_fields.js +9 -42
  5. data/app/assets/javascripts/workarea/core/modules/url.js +14 -0
  6. data/app/controllers/workarea/application_controller.rb +5 -1
  7. data/app/controllers/workarea/authentication.rb +15 -26
  8. data/app/controllers/workarea/authorization.rb +3 -3
  9. data/app/controllers/workarea/current_referrer.rb +1 -2
  10. data/app/controllers/workarea/current_release.rb +1 -1
  11. data/app/controllers/workarea/current_segments.rb +52 -0
  12. data/app/controllers/workarea/current_tracking.rb +45 -0
  13. data/app/controllers/workarea/http_caching.rb +30 -0
  14. data/app/controllers/workarea/impersonation.rb +18 -44
  15. data/app/helpers/workarea/schema_org_helper.rb +21 -0
  16. data/app/mailers/workarea/application_mailer.rb +2 -4
  17. data/app/middleware/workarea/application_middleware.rb +44 -0
  18. data/app/middleware/workarea/query_cache_middleware.rb +55 -0
  19. data/app/middleware/workarea/release_server_middleware.rb +1 -1
  20. data/app/models/workarea/application_document.rb +1 -1
  21. data/app/models/workarea/bulk_action/product_edit.rb +6 -6
  22. data/app/models/workarea/calculate_percent_change.rb +1 -1
  23. data/app/models/workarea/catalog/category.rb +0 -2
  24. data/app/models/workarea/catalog/product.rb +19 -2
  25. data/app/models/workarea/checkout.rb +18 -6
  26. data/app/models/workarea/checkout/collect_payment.rb +10 -1
  27. data/app/models/workarea/checkout/fraud/analyzer.rb +44 -0
  28. data/app/models/workarea/checkout/fraud/no_decision_analyzer.rb +14 -0
  29. data/app/models/workarea/checkout/fraud/test_analyzer.rb +26 -0
  30. data/app/models/workarea/configuration/admin.rb +25 -0
  31. data/app/models/workarea/configuration/params.rb +45 -0
  32. data/app/models/workarea/content.rb +12 -82
  33. data/app/models/workarea/content/asset.rb +5 -18
  34. data/app/models/workarea/content/block.rb +8 -2
  35. data/app/models/workarea/content/block_draft.rb +7 -2
  36. data/app/models/workarea/content/block_type.rb +2 -2
  37. data/app/models/workarea/content/block_type_definition.rb +4 -0
  38. data/app/models/workarea/content/preset.rb +1 -1
  39. data/app/models/workarea/data_file/csv.rb +6 -8
  40. data/app/models/workarea/data_file/import.rb +9 -1
  41. data/app/models/workarea/data_file/json.rb +1 -20
  42. data/app/models/workarea/data_file/operation.rb +0 -4
  43. data/app/models/workarea/data_file/tax_rates.rb +3 -0
  44. data/app/models/workarea/featured_products.rb +8 -0
  45. data/app/models/workarea/fulfillment/policies/base.rb +21 -0
  46. data/app/models/workarea/fulfillment/policies/download.rb +21 -0
  47. data/app/models/workarea/fulfillment/policies/ignore.rb +11 -0
  48. data/app/models/workarea/fulfillment/policies/ship.rb +15 -0
  49. data/app/models/workarea/fulfillment/sku.rb +72 -0
  50. data/app/models/workarea/fulfillment/token.rb +36 -0
  51. data/app/models/workarea/inquiry.rb +1 -2
  52. data/app/models/workarea/insights/customer_acquisition.rb +5 -9
  53. data/app/models/workarea/insights/trending_products.rb +2 -2
  54. data/app/models/workarea/insights/trending_searches.rb +2 -2
  55. data/app/models/workarea/inventory/collection.rb +30 -0
  56. data/app/models/workarea/inventory/collection_status.rb +40 -0
  57. data/app/models/workarea/metrics/affinity.rb +33 -0
  58. data/app/models/workarea/metrics/country_by_day.rb +4 -0
  59. data/app/models/workarea/metrics/product_by_day.rb +3 -0
  60. data/app/models/workarea/metrics/product_by_week.rb +2 -0
  61. data/app/models/workarea/metrics/product_for_last_week.rb +8 -12
  62. data/app/models/workarea/metrics/sales_by_day.rb +5 -0
  63. data/app/models/workarea/metrics/search_by_day.rb +1 -3
  64. data/app/models/workarea/metrics/search_for_last_week.rb +5 -11
  65. data/app/models/workarea/metrics/segment_by_day.rb +31 -0
  66. data/app/models/workarea/metrics/sku_by_day.rb +3 -0
  67. data/app/models/workarea/metrics/tender_by_day.rb +11 -0
  68. data/app/models/workarea/metrics/update_user_aggregations.rb +77 -0
  69. data/app/models/workarea/metrics/user.rb +73 -87
  70. data/app/models/workarea/navigation/breadcrumbs.rb +10 -1
  71. data/app/models/workarea/order.rb +47 -4
  72. data/app/models/workarea/order/fraud_decision.rb +18 -0
  73. data/app/models/workarea/order/item.rb +5 -0
  74. data/app/models/workarea/order/queries.rb +1 -0
  75. data/app/models/workarea/order/status.rb +10 -1
  76. data/app/models/workarea/payment.rb +7 -2
  77. data/app/models/workarea/payment/credit_card.rb +12 -0
  78. data/app/models/workarea/pricing/cache_key.rb +9 -3
  79. data/app/models/workarea/pricing/calculator.rb +5 -1
  80. data/app/models/workarea/pricing/calculators/tax_calculator.rb +32 -5
  81. data/app/models/workarea/pricing/discount.rb +2 -3
  82. data/app/models/workarea/pricing/discount/application_group.rb +8 -3
  83. data/app/models/workarea/pricing/discount/free_gift.rb +2 -1
  84. data/app/models/workarea/pricing/discount/redemption.rb +1 -1
  85. data/app/models/workarea/pricing/item_tax_applier.rb +41 -0
  86. data/app/models/workarea/pricing/price.rb +1 -0
  87. data/app/models/workarea/pricing/request.rb +11 -0
  88. data/app/models/workarea/pricing/sku.rb +1 -0
  89. data/app/models/workarea/pricing/tax_application.rb +21 -0
  90. data/app/models/workarea/pricing/tax_applier.rb +12 -15
  91. data/app/models/workarea/pricing/unsupported_segmentation.rb +22 -0
  92. data/app/models/workarea/product_rule.rb +5 -0
  93. data/app/models/workarea/releasable.rb +83 -89
  94. data/app/models/workarea/release.rb +72 -99
  95. data/app/models/workarea/release/activation.rb +45 -0
  96. data/app/models/workarea/release/changes.rb +45 -0
  97. data/app/models/workarea/release/changeset.rb +42 -52
  98. data/app/models/workarea/release/preview.rb +28 -0
  99. data/app/models/workarea/release/status.rb +2 -24
  100. data/app/models/workarea/release_session.rb +11 -11
  101. data/app/models/workarea/search/admin.rb +17 -39
  102. data/app/models/workarea/search/admin/catalog_product.rb +1 -2
  103. data/app/models/workarea/search/admin/fulfillment_sku.rb +27 -0
  104. data/app/models/workarea/search/admin/order.rb +1 -1
  105. data/app/models/workarea/search/admin/pricing_discount.rb +1 -1
  106. data/app/models/workarea/search/admin/release.rb +1 -4
  107. data/app/models/workarea/search/admin/segment.rb +19 -0
  108. data/app/models/workarea/search/order_text.rb +23 -6
  109. data/app/models/workarea/search/storefront.rb +33 -29
  110. data/app/models/workarea/search/storefront/category_query.rb +152 -0
  111. data/app/models/workarea/search/storefront/product/categories.rb +11 -45
  112. data/app/models/workarea/segment.rb +54 -0
  113. data/app/models/workarea/segment/first_time_customer.rb +8 -0
  114. data/app/models/workarea/segment/first_time_visitor.rb +12 -0
  115. data/app/models/workarea/segment/life_cycle.rb +44 -0
  116. data/app/models/workarea/segment/loyal_customer.rb +12 -0
  117. data/app/models/workarea/segment/returning_customer.rb +14 -0
  118. data/app/models/workarea/segment/returning_visitor.rb +12 -0
  119. data/app/models/workarea/segment/rules/base.rb +16 -0
  120. data/app/models/workarea/segment/rules/browser_info.rb +29 -0
  121. data/app/models/workarea/segment/rules/geolocation.rb +29 -0
  122. data/app/models/workarea/segment/rules/geolocation_option.rb +53 -0
  123. data/app/models/workarea/segment/rules/last_order.rb +14 -0
  124. data/app/models/workarea/segment/rules/logged_in.rb +13 -0
  125. data/app/models/workarea/segment/rules/orders.rb +17 -0
  126. data/app/models/workarea/segment/rules/revenue.rb +17 -0
  127. data/app/models/workarea/segment/rules/sessions.rb +17 -0
  128. data/app/models/workarea/segment/rules/tags.rb +14 -0
  129. data/app/models/workarea/segment/rules/traffic_referrer.rb +18 -0
  130. data/app/models/workarea/segmentable.rb +66 -0
  131. data/app/models/workarea/sort.rb +14 -2
  132. data/app/models/workarea/tax/rate.rb +35 -1
  133. data/app/models/workarea/user/authorization.rb +19 -13
  134. data/app/models/workarea/user/login.rb +4 -0
  135. data/app/models/workarea/user/password_reset.rb +1 -3
  136. data/app/queries/workarea/categorization.rb +3 -3
  137. data/app/queries/workarea/featured_categorization.rb +53 -0
  138. data/app/queries/workarea/order_cancellation_metrics.rb +155 -0
  139. data/app/queries/workarea/order_item_details.rb +16 -3
  140. data/app/queries/workarea/order_metrics.rb +32 -3
  141. data/app/queries/workarea/product_primary_navigation.rb +13 -2
  142. data/app/queries/workarea/product_releases.rb +38 -0
  143. data/app/queries/workarea/recommendation/user_activity_based.rb +14 -6
  144. data/app/queries/workarea/reports/average_order_value.rb +1 -1
  145. data/app/queries/workarea/reports/customers.rb +14 -11
  146. data/app/queries/workarea/reports/first_time_vs_returning_sales.rb +1 -1
  147. data/app/queries/workarea/reports/group_by_time.rb +13 -17
  148. data/app/queries/workarea/reports/sales_by_category.rb +1 -1
  149. data/app/queries/workarea/reports/sales_by_country.rb +10 -3
  150. data/app/queries/workarea/reports/sales_by_discount.rb +1 -1
  151. data/app/queries/workarea/reports/sales_by_menu.rb +1 -1
  152. data/app/queries/workarea/reports/sales_by_product.rb +39 -4
  153. data/app/queries/workarea/reports/sales_by_sku.rb +39 -4
  154. data/app/queries/workarea/reports/sales_by_tender.rb +42 -0
  155. data/app/queries/workarea/reports/sales_by_traffic_referrer.rb +1 -1
  156. data/app/queries/workarea/reports/sales_over_time.rb +10 -3
  157. data/app/queries/workarea/reports/searches.rb +1 -1
  158. data/app/queries/workarea/reports/searches_over_time.rb +1 -1
  159. data/app/queries/workarea/reports/searches_without_results_over_time.rb +1 -1
  160. data/app/queries/workarea/search/admin_fulfillment_skus.rb +20 -0
  161. data/app/queries/workarea/search/admin_releases.rb +1 -4
  162. data/app/queries/workarea/search/admin_search.rb +0 -4
  163. data/app/queries/workarea/search/admin_segments.rb +16 -0
  164. data/app/queries/workarea/search/admin_sorting.rb +1 -1
  165. data/app/queries/workarea/search/pagination.rb +1 -4
  166. data/app/queries/workarea/search/product_display_rules.rb +40 -8
  167. data/app/queries/workarea/search/product_entries.rb +15 -1
  168. data/app/queries/workarea/search/product_search.rb +4 -1
  169. data/app/queries/workarea/search/storefront_search.rb +5 -4
  170. data/app/queries/workarea/search/storefront_search/exact_matches.rb +1 -1
  171. data/app/queries/workarea/search/storefront_search/response.rb +6 -4
  172. data/app/seeds/workarea/assets_seeds.rb +2 -1
  173. data/app/seeds/workarea/insights_seeds.rb +0 -23
  174. data/app/seeds/workarea/orders_seeds.rb +7 -6
  175. data/app/seeds/workarea/products_seeds.rb +2 -0
  176. data/app/seeds/workarea/segments_seeds.rb +8 -0
  177. data/app/seeds/workarea/tax_seeds.rb +3 -3
  178. data/app/services/workarea/cancel_order.rb +8 -3
  179. data/app/services/workarea/copy_order.rb +6 -0
  180. data/app/services/workarea/create_fulfillment.rb +5 -3
  181. data/app/services/workarea/direct_upload.rb +11 -19
  182. data/app/services/workarea/hash_update.rb +1 -18
  183. data/app/services/workarea/packaging.rb +1 -1
  184. data/app/services/workarea/save_publishing.rb +5 -1
  185. data/app/workers/sidekiq/callbacks.rb +4 -52
  186. data/app/workers/sidekiq/callbacks_worker.rb +4 -6
  187. data/app/workers/workarea/bulk_index_admin.rb +2 -2
  188. data/app/workers/workarea/bulk_index_products.rb +6 -5
  189. data/app/workers/workarea/bulk_index_searches.rb +5 -5
  190. data/app/workers/workarea/deactivate_stale_discounts.rb +3 -3
  191. data/app/workers/workarea/generate_insights.rb +1 -1
  192. data/app/workers/workarea/index_admin_search.rb +1 -0
  193. data/app/workers/workarea/index_categorization.rb +4 -7
  194. data/app/workers/workarea/index_category.rb +2 -1
  195. data/app/workers/workarea/index_category_changes.rb +11 -6
  196. data/app/workers/workarea/index_fulfillment_changes.rb +2 -1
  197. data/app/workers/workarea/index_help.rb +2 -1
  198. data/app/workers/workarea/index_page.rb +2 -1
  199. data/app/workers/workarea/index_payment_transactions.rb +2 -1
  200. data/app/workers/workarea/index_product.rb +4 -4
  201. data/app/workers/workarea/index_product_children.rb +4 -3
  202. data/app/workers/workarea/index_product_rule.rb +3 -2
  203. data/app/workers/workarea/index_search_customizations.rb +3 -2
  204. data/app/workers/workarea/index_skus.rb +5 -6
  205. data/app/workers/workarea/keep_product_index_fresh.rb +3 -5
  206. data/app/workers/workarea/process_import.rb +3 -3
  207. data/app/workers/workarea/process_search_recommendations.rb +5 -9
  208. data/app/workers/workarea/publish_release.rb +1 -0
  209. data/app/workers/workarea/save_metrics.rb +116 -0
  210. data/app/workers/workarea/save_order_cancellation_metrics.rb +35 -0
  211. data/app/workers/workarea/save_order_metrics.rb +10 -74
  212. data/app/workers/workarea/status_reporter.rb +2 -4
  213. data/app/workers/workarea/synchronize_user_metrics.rb +17 -0
  214. data/app/workers/workarea/update_payment_profile_email.rb +22 -0
  215. data/app/workers/workarea/verify_scheduled_releases.rb +4 -11
  216. data/config/initializers/00_configuration.rb +185 -0
  217. data/config/initializers/02_assets.rb +1 -0
  218. data/config/initializers/05_scheduled_jobs.rb +0 -7
  219. data/config/initializers/10_rack_middleware.rb +2 -5
  220. data/config/initializers/11_payment.rb +4 -0
  221. data/config/initializers/13_rack_attack.rb +2 -4
  222. data/config/initializers/14_content_block_types.rb +16 -16
  223. data/config/initializers/15_endpoint_monitoring.rb +3 -6
  224. data/config/initializers/{21_premailer.rb → 24_premailer.rb} +1 -0
  225. data/config/initializers/{20_i18n_js.rb → 25_i18n_js.rb} +0 -0
  226. data/config/locales/en.yml +13 -24
  227. data/lib/generators/workarea/content_block_type/templates/initializer.rb +1 -1
  228. data/lib/generators/workarea/install/USAGE +0 -1
  229. data/lib/generators/workarea/install/install_generator.rb +0 -21
  230. data/lib/generators/workarea/install/templates/initializer.rb.erb +1 -1
  231. data/lib/tasks/insights.rake +1 -0
  232. data/lib/tasks/migrate.rake +106 -0
  233. data/lib/tasks/search.rake +17 -19
  234. data/lib/tasks/tests.rake +1 -1
  235. data/lib/workarea.rb +102 -3
  236. data/lib/workarea/cache.rb +6 -35
  237. data/lib/workarea/changelog.rake +2 -2
  238. data/lib/workarea/configuration.rb +121 -148
  239. data/lib/workarea/configuration/administrable/definition.rb +42 -0
  240. data/lib/workarea/configuration/administrable/field.rb +79 -0
  241. data/lib/workarea/configuration/administrable/fieldset.rb +44 -0
  242. data/lib/workarea/configuration/administrable_options.rb +24 -0
  243. data/lib/workarea/configuration/cache_store.rb +3 -1
  244. data/lib/workarea/configuration/content_blocks.rb +17 -0
  245. data/lib/workarea/configuration/mongoid.rb +1 -4
  246. data/lib/workarea/configuration/session.rb +36 -0
  247. data/lib/workarea/configuration/sidekiq.rb +3 -1
  248. data/lib/workarea/core.rb +15 -11
  249. data/lib/workarea/core/engine.rb +3 -58
  250. data/lib/workarea/elasticsearch/document.rb +8 -15
  251. data/lib/workarea/ext/freedom_patches/action_view_cache_helper.rb +4 -6
  252. data/lib/workarea/ext/freedom_patches/active_support_duration.rb +14 -0
  253. data/lib/workarea/ext/freedom_patches/money.rb +11 -0
  254. data/lib/workarea/ext/freedom_patches/premailer.rb +6 -0
  255. data/lib/workarea/ext/freedom_patches/string.rb +19 -4
  256. data/lib/workarea/ext/mongoid/find_ordered.rb +2 -2
  257. data/lib/workarea/ext/mongoid/lookup_hash.rb +30 -0
  258. data/lib/workarea/geolocation.rb +24 -6
  259. data/lib/workarea/routes_constraints/super_admin.rb +1 -1
  260. data/lib/workarea/version.rb +3 -4
  261. data/lib/workarea/visit.rb +92 -0
  262. data/lib/workarea/warnings.rb +95 -0
  263. data/test/dummy/config/initializers/session_store.rb +1 -1
  264. data/test/fixtures/tax_rates.csv +3 -3
  265. data/test/generators/workarea/content_block_type_generator_test.rb +1 -1
  266. data/test/generators/workarea/install_generator_test.rb +0 -13
  267. data/test/integration/workarea/authentication_test.rb +27 -4
  268. data/test/integration/workarea/authorization_test.rb +5 -0
  269. data/test/integration/workarea/cache_varies_integration_test.rb +21 -23
  270. data/test/integration/workarea/monitoring_integration_test.rb +5 -10
  271. data/test/javascripts/duplicate_id_spec.js +1 -7
  272. data/test/javascripts/fixtures/{duplicate_id_fail.html.haml → duplicate_id.html.haml} +0 -1
  273. data/test/javascripts/form_submitting_controls_spec.js +0 -1
  274. data/test/lib/workarea/asset_endpoints/favicons_test.rb +11 -13
  275. data/test/lib/workarea/configuration/administrable/definition_test.rb +71 -0
  276. data/test/lib/workarea/configuration/administrable/field_test.rb +128 -0
  277. data/test/lib/workarea/configuration/administrable/fieldset_test.rb +78 -0
  278. data/test/lib/workarea/configuration/configuration_test.rb +20 -0
  279. data/test/lib/workarea/elasticsearch/document_test.rb +0 -20
  280. data/test/lib/workarea/elasticsearch/query_cache_test.rb +7 -7
  281. data/test/lib/workarea/ext/freedom_patches/money_test.rb +11 -0
  282. data/test/lib/workarea/ext/mongoid/lookup_hash_test.rb +86 -0
  283. data/test/lib/workarea/geolocation_test.rb +20 -0
  284. data/test/mailers/workarea/application_mailer_test.rb +1 -11
  285. data/test/middleware/workarea/query_cache_middleware_test.rb +55 -0
  286. data/test/models/workarea/checkout/collect_payment_test.rb +14 -6
  287. data/test/models/workarea/checkout_test.rb +31 -57
  288. data/test/models/workarea/configuration/params_test.rb +37 -0
  289. data/test/models/workarea/data_file/csv_test.rb +8 -73
  290. data/test/models/workarea/data_file/import_test.rb +31 -0
  291. data/test/models/workarea/data_file/json_test.rb +6 -48
  292. data/test/models/workarea/data_file/tax_test.rb +3 -0
  293. data/test/models/workarea/fulfillment/policies/download_test.rb +39 -0
  294. data/test/models/workarea/fulfillment/sku_test.rb +54 -0
  295. data/test/models/workarea/insights/best_customers_test.rb +5 -2
  296. data/test/models/workarea/insights/best_full_price_customers_test.rb +5 -2
  297. data/test/models/workarea/insights/customer_acquisition_test.rb +1 -1
  298. data/test/models/workarea/insights/customers_at_risk_test.rb +1 -1
  299. data/test/models/workarea/insights/low_aov_customers_test.rb +1 -1
  300. data/test/models/workarea/inventory/collection_test.rb +75 -0
  301. data/test/models/workarea/metrics/affinity_test.rb +85 -0
  302. data/test/models/workarea/metrics/product_by_week_test.rb +27 -31
  303. data/test/models/workarea/metrics/search_by_day_test.rb +3 -0
  304. data/test/models/workarea/metrics/search_by_week_test.rb +27 -31
  305. data/test/models/workarea/metrics/update_user_aggregations_test.rb +62 -0
  306. data/test/models/workarea/metrics/user_test.rb +146 -63
  307. data/test/models/workarea/navigation/breadcrumbs_test.rb +12 -2
  308. data/test/models/workarea/order/queries_test.rb +2 -0
  309. data/test/models/workarea/order_test.rb +44 -0
  310. data/test/models/workarea/payment/address_test.rb +109 -111
  311. data/test/models/workarea/payment/credit_card_integration_test.rb +0 -52
  312. data/test/models/workarea/payment/credit_card_test.rb +5 -0
  313. data/test/models/workarea/pricing/cache_key_test.rb +7 -1
  314. data/test/models/workarea/pricing/calculators/tax_calculator_test.rb +41 -1
  315. data/test/models/workarea/pricing/discount/collection_test.rb +27 -29
  316. data/test/models/workarea/pricing/discount_test.rb +22 -24
  317. data/test/models/workarea/pricing/item_tax_applier_test.rb +83 -0
  318. data/test/models/workarea/pricing/price_test.rb +9 -0
  319. data/test/models/workarea/pricing/request_test.rb +13 -0
  320. data/test/models/workarea/pricing/sku_test.rb +9 -0
  321. data/test/models/workarea/releasable_active_test.rb +113 -0
  322. data/test/models/workarea/releasable_test.rb +69 -120
  323. data/test/models/workarea/release/changeset_test.rb +41 -0
  324. data/test/models/workarea/release_jobs_test.rb +52 -0
  325. data/test/models/workarea/release_previewing_test.rb +43 -0
  326. data/test/models/workarea/release_test.rb +59 -153
  327. data/test/models/workarea/search/admin/content_asset_test.rb +26 -28
  328. data/test/models/workarea/search/order_text_test.rb +35 -0
  329. data/test/models/workarea/search/storefront/category_query_test.rb +81 -0
  330. data/test/models/workarea/search/storefront/product/categories_test.rb +10 -70
  331. data/test/models/workarea/search/storefront/product_test.rb +10 -11
  332. data/test/models/workarea/search/storefront_test.rb +1 -13
  333. data/test/models/workarea/segment/life_cycle_test.rb +24 -0
  334. data/test/models/workarea/segment/rules/browser_info_test.rb +33 -0
  335. data/test/models/workarea/segment/rules/geolocation_option_test.rb +16 -0
  336. data/test/models/workarea/segment/rules/geolocation_test.rb +49 -0
  337. data/test/models/workarea/segment/rules/last_order_test.rb +32 -0
  338. data/test/models/workarea/segment/rules/logged_in_test.rb +25 -0
  339. data/test/models/workarea/segment/rules/orders_test.rb +59 -0
  340. data/test/models/workarea/segment/rules/revenue_test.rb +59 -0
  341. data/test/models/workarea/segment/rules/sessions_test.rb +26 -0
  342. data/test/models/workarea/segment/rules/tags_test.rb +27 -0
  343. data/test/models/workarea/segment/rules/traffic_referrer_test.rb +31 -0
  344. data/test/models/workarea/segment_test.rb +80 -0
  345. data/test/models/workarea/segmentable_test.rb +74 -0
  346. data/test/models/workarea/shipping/address_test.rb +109 -111
  347. data/test/models/workarea/shipping/sku_test.rb +8 -12
  348. data/test/models/workarea/user/password_reset_test.rb +4 -12
  349. data/test/models/workarea/user_test.rb +13 -10
  350. data/test/queries/workarea/admin_search_query_wrapper_test.rb +21 -25
  351. data/test/queries/workarea/categorization_test.rb +49 -0
  352. data/test/queries/workarea/featured_categorization_test.rb +66 -0
  353. data/test/queries/workarea/order_cancellation_metrics_test.rb +203 -0
  354. data/test/queries/workarea/order_item_details_test.rb +17 -0
  355. data/test/queries/workarea/order_metrics_test.rb +12 -0
  356. data/test/queries/workarea/product_releases_test.rb +56 -0
  357. data/test/queries/workarea/recommendation/searches_test.rb +3 -3
  358. data/test/queries/workarea/recommendation/user_activity_based_test.rb +4 -4
  359. data/test/queries/workarea/reports/customers_test.rb +12 -8
  360. data/test/queries/workarea/reports/report_test.rb +4 -6
  361. data/test/queries/workarea/reports/sales_by_country_test.rb +18 -3
  362. data/test/queries/workarea/reports/sales_by_product_test.rb +28 -8
  363. data/test/queries/workarea/reports/sales_by_sku_test.rb +28 -8
  364. data/test/queries/workarea/reports/sales_by_tender_test.rb +100 -0
  365. data/test/queries/workarea/reports/sales_by_traffic_referrer_test.rb +6 -6
  366. data/test/queries/workarea/search/admin_releases_test.rb +1 -26
  367. data/test/queries/workarea/search/admin_search_test.rb +0 -10
  368. data/test/queries/workarea/search/admin_users_test.rb +2 -2
  369. data/test/queries/workarea/search/category_browse_test.rb +53 -0
  370. data/test/queries/workarea/search/facet_sorting/size_test.rb +11 -13
  371. data/test/queries/workarea/search/pagination_test.rb +9 -26
  372. data/test/queries/workarea/search/product_entries_test.rb +27 -0
  373. data/test/queries/workarea/search/product_search_test.rb +0 -16
  374. data/test/queries/workarea/search/storefront_search/response_test.rb +26 -0
  375. data/test/queries/workarea/search/storefront_search_test.rb +34 -36
  376. data/test/services/workarea/cancel_order_test.rb +27 -13
  377. data/test/services/workarea/copy_order_test.rb +17 -0
  378. data/test/services/workarea/direct_upload_test.rb +1 -46
  379. data/test/services/workarea/export_report_test.rb +41 -45
  380. data/test/services/workarea/hash_update_test.rb +12 -12
  381. data/test/services/workarea/packaging_test.rb +9 -11
  382. data/test/services/workarea/save_publishing_test.rb +23 -0
  383. data/test/workers/sidekiq/callbacks_test.rb +0 -22
  384. data/test/workers/workarea/deactivate_stale_discounts_test.rb +2 -2
  385. data/test/workers/workarea/index_category_changes_test.rb +5 -7
  386. data/test/workers/workarea/keep_product_index_fresh_test.rb +1 -1
  387. data/test/workers/workarea/process_import_test.rb +0 -6
  388. data/test/workers/workarea/process_search_recommendations_test.rb +4 -5
  389. data/test/workers/workarea/status_reporter_test.rb +2 -1
  390. data/test/workers/workarea/synchronize_user_metrics_test.rb +57 -0
  391. data/test/workers/workarea/update_payment_profile_email_test.rb +27 -0
  392. data/test/workers/workarea/verify_scheduled_releases_test.rb +0 -26
  393. data/workarea-core.gemspec +12 -10
  394. metadata +188 -78
  395. data/app/assets/javascripts/workarea/core/templates/ui_menu_item.jst.ejs +0 -10
  396. data/app/controllers/workarea/admin_guest_browsing.rb +0 -54
  397. data/app/middleware/workarea/rack_cache_config_middleware.rb +0 -19
  398. data/app/queries/workarea/search/search_suggestions.rb +0 -43
  399. data/app/workers/workarea/bust_discount_cache.rb +0 -16
  400. data/app/workers/workarea/clean_user_activity.rb +0 -11
  401. data/app/workers/workarea/undo_release.rb +0 -15
  402. data/app/workers/workarea/update_email.rb +0 -33
  403. data/lib/generators/workarea/docker/USAGE +0 -16
  404. data/lib/generators/workarea/docker/docker_generator.rb +0 -61
  405. data/lib/generators/workarea/docker/templates/.env.erb +0 -6
  406. data/lib/generators/workarea/docker/templates/Dockerfile.erb +0 -48
  407. data/lib/generators/workarea/docker/templates/docker-compose.yml.erb +0 -72
  408. data/lib/generators/workarea/docker/templates/docker-entrypoint.sh.erb +0 -6
  409. data/lib/generators/workarea/docker/templates/docker-sync.yml.erb +0 -8
  410. data/lib/generators/workarea/docker/templates/docker-wait.sh +0 -11
  411. data/lib/generators/workarea/docker/templates/docker.env +0 -16
  412. data/lib/generators/workarea/docker/templates/docker_init.rb.erb +0 -29
  413. data/lib/workarea/configuration/headless_chrome.rb +0 -42
  414. data/lib/workarea/configuration/puma.rb +0 -37
  415. data/lib/workarea/ext/freedom_patches/i18n_js.rb +0 -27
  416. data/lib/workarea/ext/freedom_patches/mongoid_localized_defaults.rb +0 -25
  417. data/lib/workarea/ext/jbuilder/jbuilder_cache.rb +0 -29
  418. data/lib/workarea/ext/referer_parser/parser.decorator +0 -43
  419. data/lib/workarea/queues_pauser.rb +0 -26
  420. data/lib/workarea/robots.rb +0 -9
  421. data/test/generators/workarea/docker_generator_test.rb +0 -156
  422. data/test/javascripts/fixtures/duplicate_id_pass.html.haml +0 -2
  423. data/test/lib/workarea/ext/freedom_patches/mongoid_localized_defaults_test.rb +0 -25
  424. data/test/lib/workarea/ext/referer_parser/parser_test.rb +0 -20
  425. data/test/queries/workarea/search/search_suggestions_test.rb +0 -29
  426. data/test/workers/workarea/undo_release_test.rb +0 -23
  427. data/test/workers/workarea/update_email_test.rb +0 -39
@@ -0,0 +1,45 @@
1
+ module Workarea
2
+ class Release
3
+ module Activation
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ around_create :save_activate_with
8
+ attr_accessor :activate_with
9
+ end
10
+
11
+ def save_activate_with
12
+ self.active = false if activate_with?
13
+ yield
14
+ create_activation_changeset(activate_with) if activate_with?
15
+ end
16
+
17
+ def activate_with?
18
+ activate_with.present? && BSON::ObjectId.legal?(activate_with)
19
+ end
20
+
21
+ def create_activation_changeset(release_id)
22
+ set = changesets.find_or_initialize_by(release_id: release_id)
23
+ set.document_path = document_path
24
+
25
+ set.changeset = if Workarea.config.localized_active_fields
26
+ { 'active' => { I18n.locale.to_s => true } }
27
+ else
28
+ { 'active' => true }
29
+ end
30
+ set.original = if Workarea.config.localized_active_fields
31
+ { 'active' => { I18n.locale.to_s => false } }
32
+ else
33
+ { 'active' => false }
34
+ end
35
+
36
+ set.save!
37
+ end
38
+
39
+ def was_active?
40
+ (Workarea.config.localized_active_fields && active_was[I18n.locale.to_s]) ||
41
+ (!Workarea.config.localized_active_fields && active_was)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ module Workarea
2
+ class Release
3
+ class Changes
4
+ attr_reader :releasable
5
+
6
+ def self.tracked_change?(key, old_value, new_value)
7
+ !key.in?(Workarea.config.untracked_release_changes_fields) &&
8
+ (old_value.present? || new_value.present?)
9
+ end
10
+
11
+ def initialize(releasable)
12
+ @releasable = releasable
13
+ end
14
+
15
+ def to_h
16
+ releasable.changes.keys.inject({}) do |memo, key|
17
+ old_value, new_value = *releasable.changes[key]
18
+
19
+ memo[key] = new_value if track_change?(key, old_value, new_value)
20
+ memo
21
+ end
22
+ end
23
+
24
+ def to_originals_h
25
+ releasable.changes.keys.inject({}) do |memo, key|
26
+ old_value, new_value = *releasable.changes[key]
27
+
28
+ memo[key] = old_value if track_change?(key, old_value, new_value)
29
+ memo
30
+ end
31
+ end
32
+
33
+ def track_change?(key, old_value, new_value)
34
+ self.class.tracked_change?(key, old_value, new_value) &&
35
+ !change_appears_in_earlier_release?(key, new_value)
36
+ end
37
+
38
+ def change_appears_in_earlier_release?(key, new_value)
39
+ Release.current.scheduled_before.flat_map(&:changesets).any? do |changeset|
40
+ changeset.releasable == releasable && changeset.includes_change?(key, new_value)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,34 +1,23 @@
1
+ # This fixes Release::Changes == Mongoid::AuditLog::Changes in development
2
+ require_dependency 'workarea/release/changes'
3
+
1
4
  module Workarea
2
5
  class Release
3
6
  class Changeset
4
7
  include ApplicationDocument
5
8
 
6
9
  field :changeset, type: Hash, default: {}
7
- field :undo, type: Hash, default: {}
10
+ field :original, type: Hash, default: {}
11
+ field :undo, type: Hash, default: {} # TODO deprecated, remove in v3.6
8
12
 
9
13
  embeds_many :document_path, class_name: 'Mongoid::DocumentPath::Node'
10
14
 
11
15
  belongs_to :release, class_name: 'Workarea::Release', index: true
12
16
  belongs_to :releasable, polymorphic: true, index: true, optional: true
13
17
 
14
- index(
15
- { 'document_path.type' => 1, 'document_path.document_id' => 1 },
16
- { name: 'document_path' }
17
- )
18
-
19
- # Whether these value changes to this field should be included when
20
- # saving a changeset. Used in building changeset hashes.
21
- #
22
- # @param attribute [String]
23
- # @param old_value [Object]
24
- # @param new_value [Object]
25
- #
26
- # @return [Boolean]
27
- #
28
- def self.track_change?(attribute, old_value, new_value)
29
- !attribute.in?(Workarea.config.untracked_release_changes_fields) &&
30
- (old_value.present? || new_value.present?)
31
- end
18
+ index({ 'document_path.type' => 1, 'document_path.document_id' => 1 })
19
+ index('changeset.product_ids' => 1)
20
+ index('original.product_ids' => 1)
32
21
 
33
22
  # Finds changeset by whether the passed document is in the document
34
23
  # path of the changeset. Useful for showing embedded changes in the
@@ -61,6 +50,10 @@ module Workarea
61
50
  changeset.keys
62
51
  end
63
52
 
53
+ def includes_change?(key, new_value)
54
+ changed_fields.include?(key) && changeset[key] == new_value
55
+ end
56
+
64
57
  # Apply (but do not save) the changes represented by this changeset to
65
58
  # the model passed in.
66
59
  #
@@ -73,45 +66,44 @@ module Workarea
73
66
  # Make the changes represented by this changeset live. Used when
74
67
  # publishing a release.
75
68
  #
76
- # Builds and saves the undo in case that's desired later.
77
- #
78
69
  # @return [Boolean]
79
70
  #
80
71
  def publish!
81
72
  return false if releasable_from_document_path.blank?
82
73
 
83
- build_undo
84
74
  apply_to(releasable_from_document_path)
85
75
 
86
76
  releasable_from_document_path.skip_changeset do
87
77
  releasable_from_document_path.save!
88
78
  end
89
79
 
90
- save! # saves undo
80
+ save!
91
81
  end
92
82
 
93
- # Apply the changes in the undo hash on this changeset and save to make
94
- # them live. Used when undoing a release.
95
- #
96
- # @return [Boolean]
97
- #
98
- def undo!
99
- apply_changeset(releasable_from_document_path, undo)
100
-
101
- releasable_from_document_path.skip_changeset do
102
- releasable_from_document_path.save!
83
+ def build_undo(attributes = {})
84
+ # Ensure the appropriate Release.current for building the undo
85
+ # This can be nil, which is essential if there is some other arbitrary
86
+ # release as Release.current.
87
+ Release.with_current(release.previous) do
88
+ releasable_from_document_path.reload
89
+
90
+ Changeset.new(
91
+ attributes.reverse_merge(
92
+ releasable: releasable,
93
+ document_path: document_path,
94
+ changeset: changeset.keys.inject({}) do |memo, key|
95
+ old_value = releasable_from_document_path.attributes[key]
96
+ new_value = changeset[key]
97
+
98
+ memo[key] = old_value if Changes.tracked_change?(key, old_value, new_value)
99
+ memo
100
+ end
101
+ )
102
+ )
103
103
  end
104
- end
105
104
 
106
- def releasable_from_document_path
107
- return @releasable_from_document_path if defined?(@releasable_from_document_path)
108
-
109
- @releasable_from_document_path =
110
- begin
111
- Mongoid::DocumentPath.find(document_path)
112
- rescue Mongoid::Errors::DocumentNotFound
113
- nil
114
- end
105
+ ensure
106
+ releasable_from_document_path.reload
115
107
  end
116
108
 
117
109
  private
@@ -123,17 +115,15 @@ module Workarea
123
115
  end
124
116
  end
125
117
 
126
- def build_undo(model = releasable_from_document_path)
127
- self.undo = changeset.keys.inject({}) do |memo, key|
128
- old_value = model.attributes[key]
129
- new_value = changeset[key]
118
+ def releasable_from_document_path
119
+ return @releasable_from_document_path if defined?(@releasable_from_document_path)
130
120
 
131
- if self.class.track_change?(key, old_value, new_value)
132
- memo[key] = old_value
121
+ @releasable_from_document_path =
122
+ begin
123
+ Mongoid::DocumentPath.find(document_path)
124
+ rescue Mongoid::Errors::DocumentNotFound
125
+ nil
133
126
  end
134
-
135
- memo
136
- end
137
127
  end
138
128
  end
139
129
  end
@@ -0,0 +1,28 @@
1
+ module Workarea
2
+ class Release
3
+ class Preview
4
+ attr_reader :release
5
+
6
+ def initialize(release)
7
+ @release = release
8
+ end
9
+
10
+ def releases
11
+ @releases ||= release.scheduled_before + [release]
12
+ end
13
+
14
+ def changesets
15
+ @changesets ||= releases.flat_map(&:changesets)
16
+ end
17
+
18
+ def changesets_for(model)
19
+ changesets.select do |changeset|
20
+ # Check this way because loading the releasable will cause `load_release_changes`
21
+ # to run this, resulting in a stack overflow.
22
+ changeset.releasable_type == model.class.name &&
23
+ changeset.releasable_id.to_s == model.id.to_s
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -5,9 +5,7 @@ module Workarea
5
5
  include StatusCalculator::Status
6
6
 
7
7
  def in_status?
8
- model.publish_at.blank? &&
9
- model.published_at.blank? &&
10
- model.undo_at.blank?
8
+ model.publish_at.blank? && model.published_at.blank?
11
9
  end
12
10
  end
13
11
 
@@ -24,27 +22,7 @@ module Workarea
24
22
  include StatusCalculator::Status
25
23
 
26
24
  def in_status?
27
- model.published_at.present? &&
28
- model.publish_at.blank?
29
- end
30
- end
31
-
32
- class Undone
33
- include StatusCalculator::Status
34
-
35
- def in_status?
36
- model.published_at.present? &&
37
- model.undone_at.present?
38
- end
39
- end
40
-
41
- class ScheduledUndo
42
- include StatusCalculator::Status
43
-
44
- def in_status?
45
- return false unless model.undo_at.present?
46
- model.published_at.present? &&
47
- model.undo_at >= Time.current
25
+ model.published_at.present? && model.publish_at.blank?
48
26
  end
49
27
  end
50
28
  end
@@ -1,7 +1,7 @@
1
1
  module Workarea
2
2
  class ReleaseSession
3
- def initialize(cookies)
4
- @cookies = cookies
3
+ def initialize(session)
4
+ @session = session
5
5
  end
6
6
 
7
7
  def remind?
@@ -9,8 +9,8 @@ module Workarea
9
9
  end
10
10
 
11
11
  def expired_by_time?
12
- @cookies.permanent[:release_changed_at].present? &&
13
- Time.zone.parse(@cookies.permanent[:release_changed_at]) < timeout
12
+ @session[:release_changed_at].present? &&
13
+ Time.zone.parse(@session[:release_changed_at]) < timeout
14
14
  end
15
15
 
16
16
  def timeout
@@ -18,8 +18,8 @@ module Workarea
18
18
  end
19
19
 
20
20
  def expired_by_page_views?
21
- @cookies.permanent[:release_page_views].present? &&
22
- @cookies.permanent[:release_page_views].to_i > max_page_views
21
+ @session[:release_page_views].present? &&
22
+ @session[:release_page_views].to_i > max_page_views
23
23
  end
24
24
 
25
25
  def max_page_views
@@ -27,19 +27,19 @@ module Workarea
27
27
  end
28
28
 
29
29
  def save_page_view
30
- incremented = @cookies.permanent[:release_page_views].to_i + 1
31
- @cookies.permanent[:release_page_views] = incremented
30
+ incremented = @session[:release_page_views].to_i + 1
31
+ @session[:release_page_views] = incremented
32
32
  end
33
33
 
34
34
  def save_release_change
35
35
  reset!
36
- @cookies.permanent[:release_changed_at] = Time.current.to_s
36
+ @session[:release_changed_at] = Time.current.to_s
37
37
  end
38
38
  alias_method :touch, :save_release_change
39
39
 
40
40
  def reset!
41
- @cookies.permanent[:release_page_views] = nil
42
- @cookies.permanent[:release_changed_at] = nil
41
+ @session.delete(:release_page_views)
42
+ @session.delete(:release_changed_at)
43
43
  end
44
44
  end
45
45
  end
@@ -5,49 +5,27 @@ module Workarea
5
5
 
6
6
  def self.jump_to(params, size = Workarea.config.default_admin_jump_to_result_count)
7
7
  query = {
8
- aggs: {
9
- grouped_by_type: {
10
- filter: {
11
- match_phrase_prefix: {
12
- jump_to_search_text: {
13
- query: params[:q],
14
- max_expansions: 10
15
- }
16
- }
17
- },
18
- aggs: {
19
- type: {
20
- terms: { field: 'facets.type', size: Workarea.config.jump_to_type_limit },
21
- aggs: {
22
- top: {
23
- top_hits: {
24
- size: Workarea.config.jump_to_results_per_type,
25
- sort: [
26
- { _score: { order: 'desc' } },
27
- { updated_at: { order: 'desc' } }
28
- ]
29
- }
30
- }
31
- }
32
- }
8
+ query: {
9
+ match_phrase_prefix: {
10
+ jump_to_search_text: {
11
+ query: params[:q],
12
+ max_expansions: 10
33
13
  }
34
14
  }
35
- }
15
+ },
16
+ size: size,
17
+ sort: [{ jump_to_position: :asc }]
36
18
  }
37
19
 
38
- aggregation = search(query)['aggregations']['grouped_by_type']['type']
39
- aggregation['buckets']
40
- .reduce([]) { |m, b| m + b['top']['hits']['hits'] }
41
- .sort_by { |r| [r['_source']['jump_to_position'] || 999, r['_score'] || 0] }
42
- .map do |result|
43
- {
44
- label: result['_source']['jump_to_text'],
45
- type: result['_source']['facets']['type'],
46
- model_class: result['_source']['model_class'],
47
- route_helper: result['_source']['jump_to_route_helper'],
48
- to_param: result['_source']['jump_to_param']
49
- }
50
- end
20
+ search(query)['hits']['hits'].map do |result|
21
+ {
22
+ label: result['_source']['jump_to_text'],
23
+ type: result['_source']['facets']['type'],
24
+ model_class: result['_source']['model_class'],
25
+ route_helper: result['_source']['jump_to_route_helper'],
26
+ to_param: result['_source']['jump_to_param']
27
+ }
28
+ end
51
29
  end
52
30
 
53
31
  def self.for(model)
@@ -80,8 +80,7 @@ module Workarea
80
80
  end
81
81
 
82
82
  def low_inventory?
83
- available = Inventory::Sku.in(id: model.skus).sum(&:available_to_sell)
84
- available < Workarea.config.low_inventory_threshold
83
+ Inventory::Collection.new(model.skus).low_inventory?
85
84
  end
86
85
 
87
86
  def variant_missing_details?
@@ -0,0 +1,27 @@
1
+ module Workarea
2
+ module Search
3
+ class Admin
4
+ class FulfillmentSku < Search::Admin
5
+ def type
6
+ 'fulfillment_sku'
7
+ end
8
+
9
+ def search_text
10
+ model.name
11
+ end
12
+
13
+ def jump_to_text
14
+ "#{model.id} - (#{model.policy})"
15
+ end
16
+
17
+ def jump_to_position
18
+ 12
19
+ end
20
+
21
+ def facets
22
+ super.merge(policy: model.policy)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end