workarea-registries 1.0.0

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