workarea-registries 1.0.0

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 (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +21 -0
  5. data/README.md +1 -0
  6. data/Rakefile +58 -0
  7. data/app/assets/images/workarea/storefront/registries/icons/email.svg +4 -0
  8. data/app/assets/images/workarea/storefront/registries/icons/link.svg +1 -0
  9. data/app/assets/javascripts/workarea/storefront/registries/modules/add_to_registry_button.js +49 -0
  10. data/app/assets/javascripts/workarea/storefront/registries/modules/copy_registry_url_button.js +51 -0
  11. data/app/assets/javascripts/workarea/storefront/registries/modules/toggle_registry_address.js +58 -0
  12. data/app/assets/javascripts/workarea/storefront/registries/templates/add_to_registry_button.jst.ejs +3 -0
  13. data/app/controllers/workarea/admin/registries_controller.rb +28 -0
  14. data/app/controllers/workarea/storefront/cart_items_controller.decorator +14 -0
  15. data/app/controllers/workarea/storefront/registries_controller.rb +47 -0
  16. data/app/controllers/workarea/storefront/users/registries_controller.rb +94 -0
  17. data/app/controllers/workarea/storefront/users/registry_items_controller.rb +67 -0
  18. data/app/controllers/workarea/storefront/users/registry_shares_controller.rb +43 -0
  19. data/app/controllers/workarea/storefront/users/registry_thanks_controller.rb +41 -0
  20. data/app/helpers/workarea/registries_helper.rb +41 -0
  21. data/app/mailers/workarea/storefront/registries_mailer.rb +52 -0
  22. data/app/models/workarea/checkout/steps/addresses.decorator +28 -0
  23. data/app/models/workarea/order.decorator +7 -0
  24. data/app/models/workarea/order/item.decorator +11 -0
  25. data/app/models/workarea/registry.rb +129 -0
  26. data/app/models/workarea/registry/item.rb +39 -0
  27. data/app/models/workarea/registry/public_search.rb +23 -0
  28. data/app/models/workarea/registry/share.rb +46 -0
  29. data/app/models/workarea/registry/thank.rb +26 -0
  30. data/app/models/workarea/search/admin/registry.rb +29 -0
  31. data/app/queries/workarea/search/admin_orders.decorator +7 -0
  32. data/app/queries/workarea/search/admin_registries.rb +16 -0
  33. data/app/seeds/workarea/registry_content_seeds.rb +50 -0
  34. data/app/services/workarea/inventory_adjustment.decorator +43 -0
  35. data/app/view_models/workarea/admin/registry_view_model.rb +19 -0
  36. data/app/view_models/workarea/storefront/checkout/addresses_view_model.decorator +17 -0
  37. data/app/view_models/workarea/storefront/order_item_view_model.decorator +9 -0
  38. data/app/view_models/workarea/storefront/order_view_model.decorator +8 -0
  39. data/app/view_models/workarea/storefront/registry_email_view_model.rb +37 -0
  40. data/app/view_models/workarea/storefront/registry_item_view_model.rb +72 -0
  41. data/app/view_models/workarea/storefront/registry_share_view_model.rb +6 -0
  42. data/app/view_models/workarea/storefront/registry_thank_view_model.rb +6 -0
  43. data/app/view_models/workarea/storefront/registry_view_model.rb +74 -0
  44. data/app/view_models/workarea/storefront/user_view_model.decorator +12 -0
  45. data/app/views/workarea/admin/registries/_menu.html.haml +1 -0
  46. data/app/views/workarea/admin/registries/index.html.haml +70 -0
  47. data/app/views/workarea/storefront/carts/_registry_details.html.haml +3 -0
  48. data/app/views/workarea/storefront/checkouts/_registry_address.html.haml +13 -0
  49. data/app/views/workarea/storefront/checkouts/_registry_address_fields.html.haml +28 -0
  50. data/app/views/workarea/storefront/checkouts/_registry_details.html.haml +3 -0
  51. data/app/views/workarea/storefront/products/_add_to_registry_placeholder.html.haml +1 -0
  52. data/app/views/workarea/storefront/registries/_registries_link.html.haml +4 -0
  53. data/app/views/workarea/storefront/registries/index.html.haml +39 -0
  54. data/app/views/workarea/storefront/registries/search.html.haml +35 -0
  55. data/app/views/workarea/storefront/registries/show.html.haml +63 -0
  56. data/app/views/workarea/storefront/registries_mailer/creation.html.haml +13 -0
  57. data/app/views/workarea/storefront/registries_mailer/gift_receipt.html.haml +51 -0
  58. data/app/views/workarea/storefront/registries_mailer/share.html.haml +21 -0
  59. data/app/views/workarea/storefront/registries_mailer/thank.html.haml +19 -0
  60. data/app/views/workarea/storefront/users/_registry_count.json.jbuilder +3 -0
  61. data/app/views/workarea/storefront/users/accounts/_registries.html.haml +14 -0
  62. data/app/views/workarea/storefront/users/registries/_form.html.haml +56 -0
  63. data/app/views/workarea/storefront/users/registries/_radio_list.html.haml +8 -0
  64. data/app/views/workarea/storefront/users/registries/_summary.html.haml +12 -0
  65. data/app/views/workarea/storefront/users/registries/edit.html.haml +4 -0
  66. data/app/views/workarea/storefront/users/registries/index.html.haml +24 -0
  67. data/app/views/workarea/storefront/users/registries/new.html.haml +4 -0
  68. data/app/views/workarea/storefront/users/registries/show.html.haml +75 -0
  69. data/app/views/workarea/storefront/users/registry_items/new.html.haml +10 -0
  70. data/app/views/workarea/storefront/users/registry_items/templates/_purchased.html.haml +29 -0
  71. data/app/views/workarea/storefront/users/registry_items/templates/_unpurchased.html.haml +35 -0
  72. data/app/views/workarea/storefront/users/registry_shares/_share_buttons.html.haml +18 -0
  73. data/app/views/workarea/storefront/users/registry_shares/new.html.haml +49 -0
  74. data/app/views/workarea/storefront/users/registry_thanks/new.html.haml +47 -0
  75. data/app/workers/workarea/send_gift_receipt.rb +15 -0
  76. data/app/workers/workarea/send_registry_creation_email.rb +12 -0
  77. data/app/workers/workarea/update_registry_items.rb +24 -0
  78. data/bin/rails +20 -0
  79. data/config/initializers/appends.rb +54 -0
  80. data/config/initializers/fields.rb +19 -0
  81. data/config/locales/en.yml +133 -0
  82. data/config/routes.rb +26 -0
  83. data/lib/workarea/mailer_previews/storefront/registry_mailer_preview.rb +25 -0
  84. data/lib/workarea/registries.rb +11 -0
  85. data/lib/workarea/registries/engine.rb +17 -0
  86. data/lib/workarea/registries/version.rb +5 -0
  87. data/test/dummy/config/application.rb +27 -0
  88. data/test/factories/workarea/registry.rb +67 -0
  89. data/test/integration/workarea/storefront/cart_item_registry_integration_test.rb +104 -0
  90. data/test/integration/workarea/storefront/checkout_registry_integration_test.rb +156 -0
  91. data/test/integration/workarea/storefront/registry_privacy_integration_test.rb +48 -0
  92. data/test/integration/workarea/storefront/user_registries_integration_test.rb +50 -0
  93. data/test/integration/workarea/storefront/user_registry_items_integration_test.rb +106 -0
  94. data/test/models/workarea/registry/item_test.rb +22 -0
  95. data/test/models/workarea/registry/public_search_test.rb +48 -0
  96. data/test/models/workarea/registry_test.rb +113 -0
  97. data/test/system/workarea/admin/registry_system_test.rb +20 -0
  98. data/test/workers/update_registry_items_test.rb +45 -0
  99. data/workarea-registries.gemspec +20 -0
  100. metadata +156 -0
@@ -0,0 +1,156 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class CheckoutRegistryIntegrationTest < Workarea::IntegrationTest
6
+ include Storefront::IntegrationTest
7
+ setup :setup_registry_checkout
8
+
9
+ def setup_registry_checkout
10
+ create_checkout_with_registry_item
11
+ end
12
+
13
+ def order
14
+ Order.first
15
+ end
16
+
17
+ def registry
18
+ Registry.first
19
+ end
20
+
21
+ def test_checkout_ship_to_registrant
22
+ patch storefront.checkout_addresses_path,
23
+ params: {
24
+ ship_to_registrant: true,
25
+ email: 'bcrouse@workarea.com',
26
+ billing_address: {
27
+ first_name: 'Ben',
28
+ last_name: 'Crouse',
29
+ street: '12 N. 3rd St.',
30
+ city: 'Philadelphia',
31
+ region: 'PA',
32
+ postal_code: '19106',
33
+ country: 'US',
34
+ phone_number: '2159251800'
35
+ },
36
+ registry_shipping_address: {
37
+ first_name: 'Ben',
38
+ last_name: 'Crouse',
39
+ street: '22 S. 3rd St.',
40
+ city: 'Philadelphia',
41
+ region: 'PA',
42
+ postal_code: '19106',
43
+ country: 'US',
44
+ phone_number: '2159251800'
45
+ }
46
+ }
47
+
48
+ patch storefront.checkout_shipping_path
49
+
50
+ patch storefront.checkout_place_order_path,
51
+ params: {
52
+ payment: 'new_card',
53
+ credit_card: {
54
+ number: '1',
55
+ month: 1,
56
+ year: next_year,
57
+ cvv: '999'
58
+ }
59
+ }
60
+
61
+ assert_equal(true, order.ship_to_registrant)
62
+ assert(order.placed?)
63
+ end
64
+
65
+ def test_checkout_ship_to_another_address
66
+ patch storefront.checkout_addresses_path,
67
+ params: {
68
+ ship_to_registrant: false,
69
+ email: 'bcrouse@workarea.com',
70
+ billing_address: {
71
+ first_name: 'Ben',
72
+ last_name: 'Crouse',
73
+ street: '12 N. 3rd St.',
74
+ city: 'Philadelphia',
75
+ region: 'PA',
76
+ postal_code: '19106',
77
+ country: 'US',
78
+ phone_number: '2159251800'
79
+ },
80
+ shipping_address: {
81
+ first_name: 'Ben',
82
+ last_name: 'Crouse',
83
+ street: '22 S. 3rd St.',
84
+ city: 'Philadelphia',
85
+ region: 'PA',
86
+ postal_code: '19106',
87
+ country: 'US',
88
+ phone_number: '2159251800'
89
+ }
90
+ }
91
+
92
+ patch storefront.checkout_shipping_path
93
+
94
+ patch storefront.checkout_place_order_path,
95
+ params: {
96
+ payment: 'new_card',
97
+ credit_card: {
98
+ number: '1',
99
+ month: 1,
100
+ year: next_year,
101
+ cvv: '999'
102
+ }
103
+ }
104
+
105
+ assert_equal(false, order.ship_to_registrant)
106
+ assert(order.placed?)
107
+ end
108
+
109
+ def test_mark_registry_items_as_purchased
110
+ patch storefront.checkout_addresses_path,
111
+ params: {
112
+ ship_to_registrant: true,
113
+ email: 'bcrouse@workarea.com',
114
+ billing_address: {
115
+ first_name: 'Ben',
116
+ last_name: 'Crouse',
117
+ street: '12 N. 3rd St.',
118
+ city: 'Philadelphia',
119
+ region: 'PA',
120
+ postal_code: '19106',
121
+ country: 'US',
122
+ phone_number: '2159251800'
123
+ },
124
+ registry_shipping_address: {
125
+ first_name: 'Ben',
126
+ last_name: 'Crouse',
127
+ street: '22 S. 3rd St.',
128
+ city: 'Philadelphia',
129
+ region: 'PA',
130
+ postal_code: '19106',
131
+ country: 'US',
132
+ phone_number: '2159251800'
133
+ }
134
+ }
135
+
136
+ patch storefront.checkout_shipping_path
137
+
138
+ patch storefront.checkout_place_order_path,
139
+ params: {
140
+ payment: 'new_card',
141
+ credit_card: {
142
+ number: '1',
143
+ month: 1,
144
+ year: next_year,
145
+ cvv: '999'
146
+ }
147
+ }
148
+
149
+ assert(2, registry.items.count)
150
+ assert(1, registry.items.first.received)
151
+ assert('bcrouse@workarea.com', registry.items.last.purchased_by)
152
+ assert(1, registry.purchased_items)
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,48 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class RegistryPrivacyIntegrationTest < Workarea::IntegrationTest
6
+ setup :user, :registry
7
+
8
+ def user
9
+ @user ||= create_user(password: 'w0rkArea!')
10
+ end
11
+
12
+ def registry
13
+ @registry ||= create_registry({ user_id: @user.id })
14
+ end
15
+
16
+ def test_navigate_to_public_registry
17
+ get storefront.registry_path(registry)
18
+
19
+ assert(response.ok?)
20
+ end
21
+
22
+ def test_navigate_to_shared_registry
23
+ registry.update(privacy: 'shared')
24
+ get storefront.registry_path(registry)
25
+
26
+ assert(response.ok?)
27
+ end
28
+
29
+ def test_navigate_to_private_registry
30
+ registry.update(privacy: 'private')
31
+ get storefront.registry_path(registry)
32
+
33
+ assert_redirected_to(storefront.registries_path)
34
+ end
35
+
36
+ def test_navigating_to_private_registry_as_owner
37
+ registry.update(privacy: 'private')
38
+
39
+ post storefront.login_path,
40
+ params: { email: user.email, password: 'w0rkArea!' }
41
+
42
+ get storefront.registry_path(registry)
43
+
44
+ assert(response.ok?)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class UserRegistriesIntegrationTest < Workarea::IntegrationTest
6
+ setup :user, :registry, :login
7
+
8
+ def user
9
+ @user ||= create_user(password: 'w0rkArea!')
10
+ end
11
+
12
+ def registry
13
+ @registry ||= create_registry({ user_id: @user.id })
14
+ end
15
+
16
+ def login
17
+ post storefront.login_path,
18
+ params: { email: user.email, password: 'w0rkArea!' }
19
+ end
20
+
21
+ def test_update
22
+ patch storefront.users_registry_path(registry),
23
+ params: {
24
+ registry: {
25
+ name: 'Changed'
26
+ },
27
+ registry_address: {
28
+ first_name: 'Ben',
29
+ last_name: 'Crouse',
30
+ street: '22 S. 3rd St.',
31
+ street_2: 'Second Floor',
32
+ city: 'Philadelphia',
33
+ region: 'PA',
34
+ postal_code: '19106',
35
+ country: 'US'
36
+ }
37
+ }
38
+
39
+ assert_redirected_to(storefront.users_registry_path(registry))
40
+
41
+ registry.reload
42
+ assert_equal('Changed', registry.name)
43
+ assert_equal(
44
+ I18n.t('workarea.storefront.flash_messages.registry_updated'),
45
+ flash[:success]
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,106 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Storefront
5
+ class UserRegistryItemsIntegrationTest < Workarea::IntegrationTest
6
+ setup :user, :registry, :product, :login
7
+
8
+ def user
9
+ @user ||= create_user(password: 'w0rkArea!')
10
+ end
11
+
12
+ def registry
13
+ @registry ||= create_registry({ user_id: @user.id })
14
+ end
15
+
16
+ def product
17
+ @product ||= create_product(id: 'PROD1', variants: [{ sku: 'SKU1' }])
18
+ end
19
+
20
+ def login
21
+ post storefront.login_path,
22
+ params: { email: user.email, password: 'w0rkArea!' }
23
+ end
24
+
25
+ def test_create
26
+ post storefront.users_registry_items_path,
27
+ params: {
28
+ registry_id: registry.id,
29
+ product_id: product.id,
30
+ sku: product.variants.first.sku,
31
+ quantity: 2
32
+ }
33
+
34
+ assert_redirected_to(storefront.users_registry_path(registry))
35
+ assert_equal(
36
+ t('workarea.storefront.flash_messages.registry_item_created'),
37
+ flash[:success]
38
+ )
39
+
40
+ item = registry.reload.items.first
41
+ assert_equal(product.id, item.product_id)
42
+ assert_equal(product.variants.first.sku, item.sku)
43
+ assert_equal(2, item.quantity)
44
+ end
45
+
46
+ def test_update
47
+ item = registry.items.create!(
48
+ product_id: 'PROD1',
49
+ sku: 'SKU1',
50
+ quantity: 2
51
+ )
52
+
53
+ patch storefront.users_registry_item_path(registry, item),
54
+ params: { product_id: 'PROD1', sku: 'SKU1', quantity: 1 }
55
+
56
+ assert_redirected_to(storefront.users_registry_path(registry))
57
+ assert_equal(
58
+ t('workarea.storefront.flash_messages.registry_item_updated'),
59
+ flash[:success]
60
+ )
61
+
62
+ item = registry.reload.items.first
63
+ assert_equal('PROD1', item.product_id)
64
+ assert_equal('SKU1', item.sku)
65
+ assert_equal(1, item.quantity)
66
+ end
67
+
68
+ def test_destroy
69
+ item = registry.items.create!(
70
+ product_id: 'PROD1',
71
+ sku: 'SKU1',
72
+ quantity: 2,
73
+ )
74
+
75
+ delete storefront.users_registry_item_path(registry, item)
76
+
77
+ assert_redirected_to(storefront.users_registry_path(registry))
78
+ assert_equal(
79
+ t('workarea.storefront.flash_messages.registry_item_destroyed'),
80
+ flash[:success]
81
+ )
82
+
83
+ assert_equal(0, registry.reload.items.count)
84
+ end
85
+
86
+ def test_cannot_destroy_purchased_items
87
+ item = registry.items.create!(
88
+ product_id: 'PROD1',
89
+ sku: 'SKU1',
90
+ quantity: 2,
91
+ received: 1
92
+ )
93
+
94
+ delete storefront.users_registry_item_path(registry, item)
95
+
96
+ assert_redirected_to(storefront.users_registry_path(registry))
97
+ assert_equal(
98
+ t('workarea.storefront.flash_messages.registry_item_not_destroyed'),
99
+ flash[:error]
100
+ )
101
+
102
+ assert_equal(1, registry.reload.items.count)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ class Registry
5
+ class ItemTest < TestCase
6
+ def test_validation
7
+ item = Registry::Item.new(quantity: 0)
8
+
9
+ refute(item.valid?)
10
+ assert(item.errors[:quantity].present?)
11
+ assert(item.errors[:product_id].present?)
12
+ assert(item.errors[:sku].present?)
13
+
14
+ item.product_id = '123'
15
+ item.sku = 'SKU'
16
+ item.quantity = 1
17
+
18
+ assert(item.valid?)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ class Registry
5
+ class PublicSearchTest < TestCase
6
+ setup :registry
7
+
8
+ def email
9
+ 'test@workarea.com'
10
+ end
11
+
12
+ def registry_name
13
+ 'Test Registry'
14
+ end
15
+
16
+ def another_email
17
+ 'test-other@workarea.com'
18
+ end
19
+
20
+ def registry
21
+ @registry ||= create_registry(
22
+ email: email,
23
+ name: registry_name
24
+ )
25
+ end
26
+
27
+ def test_results
28
+ search = Workarea::Registry::PublicSearch.new(registry_name)
29
+ assert_equal([registry], search.results.to_a)
30
+
31
+ search = Workarea::Registry::PublicSearch.new(email)
32
+ assert_equal([registry], search.results.to_a)
33
+
34
+ search = Workarea::Registry::PublicSearch.new(another_email)
35
+ assert_empty(search.results)
36
+
37
+ search = Workarea::Registry::PublicSearch.new('bogus')
38
+ assert(search.results.to_a.empty?)
39
+
40
+ registry.update_attributes(privacy: 'private')
41
+ assert(Workarea::Registry::PublicSearch.new(registry_name).results.empty?)
42
+
43
+ registry.update_attributes(privacy: 'shared')
44
+ assert(Workarea::Registry::PublicSearch.new(registry_name).results.empty?)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,113 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ class RegistryTest < TestCase
5
+ setup :registry, :product, :registry_item
6
+
7
+ def registry
8
+ @registry ||= create_registry
9
+ end
10
+
11
+ def product
12
+ @product ||= create_product(
13
+ name: 'Integration Product',
14
+ variants: [
15
+ { sku: 'SKU1', regular: 5.to_m },
16
+ { sku: 'SKU2', regular: 6.to_m }
17
+ ]
18
+ )
19
+ end
20
+
21
+ def registry_item
22
+ @registry_item = create_registry_item({
23
+ registry: registry,
24
+ product_id: product.id,
25
+ sku: product.variants.first.sku
26
+ })
27
+ end
28
+
29
+ def order
30
+ @order ||= Workarea::Order.new(email: 'test@workarea.com')
31
+ end
32
+
33
+ def test_with_items
34
+ assert_equal(1, registry.items.size)
35
+
36
+ second_registry_item = create_registry_item({
37
+ registry: registry,
38
+ product_id: product.id,
39
+ sku: product.variants.last.sku
40
+ })
41
+
42
+ assert_equal(2, registry.items.size)
43
+ end
44
+
45
+ def test_update_item
46
+ registry.update_item(
47
+ registry.items.first.id,
48
+ quantity: 3
49
+ )
50
+
51
+ assert_equal(3, registry.items.first.quantity)
52
+ end
53
+
54
+ def test_remove_item
55
+ assert_equal(1, registry.items.count)
56
+
57
+ assert(registry.remove_item('fake_id'))
58
+ assert_equal(1, registry.items.count)
59
+
60
+ assert(registry.remove_item(registry.items.first.id))
61
+ assert_equal(0, registry.items.count)
62
+ end
63
+
64
+ def test_public
65
+ registry.update_attributes(privacy: 'public')
66
+
67
+ assert(registry.public?)
68
+ refute(registry.shared?)
69
+ refute(registry.private?)
70
+ end
71
+
72
+ def test_shared
73
+ registry.update_attributes(privacy: 'shared')
74
+
75
+ refute(registry.public?)
76
+ assert(registry.shared?)
77
+ refute(registry.private?)
78
+ end
79
+
80
+ def test_private
81
+ registry.update_attributes(privacy: 'private')
82
+
83
+ refute(registry.public?)
84
+ refute(registry.shared?)
85
+ assert(registry.private?)
86
+ end
87
+
88
+ def test_mark_item_received
89
+ order_item = order.items.build(product_id: product.id, sku: product.variants.first.sku, quantity: 1)
90
+
91
+ registry.mark_item_received(order_item)
92
+
93
+ assert_equal(1, registry.items.count)
94
+ assert_equal(1, registry.items.first.received)
95
+ end
96
+
97
+ def test_add_purchased_registry_item
98
+ order_item = order.items.build(product_id: product.id, sku: product.variants.first.sku, quantity: 1)
99
+
100
+ registry.add_purchased_item({
101
+ sku: order_item.sku,
102
+ product_id: order_item.product_id,
103
+ quantity: order_item.quantity,
104
+ purchased_by: order.email
105
+ })
106
+
107
+ assert(2, registry.items.count)
108
+ assert('test@workarea.com', registry.items.last.purchased_by)
109
+ assert(1, registry.unpurchased_items)
110
+ assert(1, registry.purchased_items)
111
+ end
112
+ end
113
+ end