workarea-api-storefront 4.4.6 → 4.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +52 -0
  3. data/README.md +4 -7
  4. data/app/controllers/workarea/api/storefront/analytics_controller.rb +31 -19
  5. data/app/controllers/workarea/api/storefront/application_controller.rb +15 -2
  6. data/app/controllers/workarea/api/storefront/authentication.rb +6 -9
  7. data/app/controllers/workarea/api/storefront/categories_controller.rb +3 -1
  8. data/app/controllers/workarea/api/storefront/checkouts_controller.rb +0 -1
  9. data/app/controllers/workarea/api/storefront/menus_controller.rb +3 -1
  10. data/app/controllers/workarea/api/storefront/pages_controller.rb +3 -1
  11. data/app/controllers/workarea/api/storefront/products_controller.rb +3 -1
  12. data/app/controllers/workarea/api/storefront/recent_views_controller.rb +13 -26
  13. data/app/controllers/workarea/api/storefront/recommendations_controller.rb +2 -8
  14. data/app/controllers/workarea/api/storefront/searches_controller.rb +0 -12
  15. data/app/views/workarea/api/storefront/categories/show.json.jbuilder +1 -1
  16. data/app/views/workarea/api/storefront/email_signups/show.json.jbuilder +1 -1
  17. data/app/views/workarea/api/storefront/menus/_menu.json.jbuilder +1 -1
  18. data/app/views/workarea/api/storefront/pages/show.json.jbuilder +1 -1
  19. data/app/views/workarea/api/storefront/recent_views/show.json.jbuilder +0 -1
  20. data/app/views/workarea/api/storefront/searches/show.json.jbuilder +1 -1
  21. data/app/views/workarea/api/storefront/system_content/show.json.jbuilder +1 -1
  22. data/config/initializers/config.rb +19 -0
  23. data/lib/workarea/api/storefront.rb +1 -0
  24. data/lib/workarea/api/storefront/visit.decorator +52 -0
  25. data/test/documentation/workarea/api/storefront/checkouts_documentation_test.rb +21 -0
  26. data/test/documentation/workarea/api/storefront/segmentation_documentation_test.rb +104 -0
  27. data/test/documentation/workarea/api/storefront/validation_documentation_test.rb +1 -1
  28. data/test/dummy/config/initializers/session_store.rb +3 -1
  29. data/test/integration/workarea/api/storefront/analytics_integration_test.rb +12 -7
  30. data/test/integration/workarea/api/storefront/recent_views_integration_test.rb +38 -33
  31. data/test/integration/workarea/api/storefront/recommendations_integration_test.rb +1 -1
  32. data/test/integration/workarea/api/storefront/searches_integration_test.rb +0 -36
  33. data/test/integration/workarea/api/storefront/segments_integration_test.rb +218 -0
  34. data/workarea-api-storefront.gemspec +8 -7
  35. metadata +19 -15
  36. data/app/controllers/workarea/api/storefront/user_activity.rb +0 -36
  37. data/app/view_models/workarea/api/storefront/search_suggestion_view_model.rb +0 -21
@@ -13,3 +13,4 @@ end
13
13
 
14
14
  require 'workarea/api/version'
15
15
  require 'workarea/api/storefront/engine'
16
+ require 'workarea/api/storefront/visit.decorator'
@@ -0,0 +1,52 @@
1
+ module Workarea
2
+ decorate Visit, with: 'storefront_api' do
3
+ def api?
4
+ return @api if defined?(@api)
5
+ @api = Workarea.config.is_api_visit.call(request)
6
+ end
7
+
8
+ def cookies
9
+ api? ? {} : super
10
+ end
11
+
12
+ def session
13
+ api? ? {} : super
14
+ end
15
+
16
+ def logged_in?
17
+ return super unless api?
18
+
19
+ regex = ActionController::HttpAuthentication::Token::TOKEN_REGEX
20
+ request.authorization.to_s[regex].present?
21
+ end
22
+
23
+ def current_email
24
+ return super unless api?
25
+ return request.params['email'] unless logged_in?
26
+ return @current_email if defined? @current_email
27
+
28
+ @current_email = current_user&.email
29
+ end
30
+
31
+ def current_user
32
+ token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
33
+ @current_user ||= Api::Storefront::Authentication.find_user(token, options)
34
+ end
35
+
36
+ def sessions
37
+ api? ? request.params['sessions'].to_i : super
38
+ end
39
+
40
+ def current_metrics_id
41
+ return super unless api?
42
+
43
+ return @current_metrics_id if defined?(@current_metrics_id)
44
+ @current_metrics_id = current_email.presence || request.params['session_id']
45
+ end
46
+
47
+ def current_metrics_id=(value)
48
+ return super unless api?
49
+ # Unsupported in the API
50
+ end
51
+ end
52
+ end
@@ -85,6 +85,27 @@ module Workarea
85
85
  end
86
86
  end
87
87
 
88
+ def test_and_document_update_failure
89
+ description 'Failure to update a checkout'
90
+ route storefront_api.checkout_path(':id')
91
+ explanation <<-EOS
92
+ This is an example of what occurs when you fail to send in the correct parameters for your checkout.
93
+ EOS
94
+
95
+ record_request do
96
+ patch storefront_api.checkout_path(@order),
97
+ as: :json,
98
+ params: {
99
+ email: 'susanb@workarea.com',
100
+ shipping_address: address.except(:first_name),
101
+ billing_address: address.except(:last_name),
102
+ shipping_service: 'Express'
103
+ }
104
+
105
+ assert_equal(422, response.status)
106
+ end
107
+ end
108
+
88
109
  def test_and_document_complete
89
110
  description 'Completing a checkout'
90
111
  route storefront_api.complete_checkout_path(':id')
@@ -0,0 +1,104 @@
1
+ require 'test_helper'
2
+ require 'workarea/api/documentation_test'
3
+
4
+ module Workarea
5
+ module Api
6
+ module Storefront
7
+ class SegmentationDocumentationTest < DocumentationTest
8
+ resource 'Segmentation'
9
+
10
+ def test_and_document_session_count
11
+ description 'Specifying session count for segmentation'
12
+ route storefront_api.system_content_path('home_page')
13
+ explanation <<~EOS
14
+ Workarea supports segmenting users by number of sessions, e.g.
15
+ first-time vs returning visitors. To support this in the storefront
16
+ API, the client will be responsible for managing this since the API
17
+ is stateless (doesn't have cookies/session).
18
+
19
+ To get session-based segments functioning, you need to pass a
20
+ `sessions` parameter in each request. Workarea will use that as
21
+ the number of sessions for determing the segments for the response.
22
+ This works for all requests across the storefront API.
23
+
24
+ This example shows getting a home page with segmented content based
25
+ on the number of sessions.
26
+ EOS
27
+
28
+ first_time = Segment::FirstTimeVisitor.instance
29
+ returning = Segment::ReturningVisitor.instance
30
+
31
+ content = Content.for('Home Page')
32
+ content.blocks.create!(
33
+ type: 'text',
34
+ data: { text: 'Hello visitor!' },
35
+ active_segment_ids: [first_time.id]
36
+ )
37
+ content.blocks.create!(
38
+ type: 'text',
39
+ data: { text: 'Welcome back!' },
40
+ active_segment_ids: [returning.id]
41
+ )
42
+
43
+ record_request do
44
+ get storefront_api.system_content_path('home_page', sessions: 1)
45
+ assert_match(/Hello visitor!/, response.body)
46
+ assert(response.ok?)
47
+ end
48
+ record_request do
49
+ get storefront_api.system_content_path('home_page', sessions: 2)
50
+ assert_match(/Welcome back!/, response.body)
51
+ assert(response.ok?)
52
+ end
53
+ end
54
+
55
+ def test_and_document_session_ids
56
+ description 'Using session IDs for segmenting non-authenticated users'
57
+ route storefront_api.system_content_path('home_page')
58
+ explanation <<~EOS
59
+ Workarea supports segmenting users by number of orders, revenue, etc.
60
+ For this functionality to work for users without accounts, you'll
61
+ need to maintain and pass a `session_id` consistently throughout calls
62
+ to the API.
63
+
64
+ An instance of `Metrics::User` will be found or created for that
65
+ `session_id`, and data about the user will be tracked there.
66
+
67
+ Assuming use of the `session_id` consistently through checkout, this
68
+ example shows getting home page content for two different anonymous
69
+ users and getting segmented content back.
70
+ EOS
71
+
72
+ first_time = Segment::FirstTimeCustomer.instance
73
+ returning = Segment::ReturningCustomer.instance
74
+
75
+ Metrics::User.create!(id: 'session_1', orders: 1)
76
+ Metrics::User.create!(id: 'session_2', orders: 2)
77
+
78
+ content = Content.for('Home Page')
79
+ content.blocks.create!(
80
+ type: 'text',
81
+ data: { text: 'Thanks for your order!' },
82
+ active_segment_ids: [first_time.id]
83
+ )
84
+ content.blocks.create!(
85
+ type: 'text',
86
+ data: { text: 'Welcome back repeat customer!' },
87
+ active_segment_ids: [returning.id]
88
+ )
89
+
90
+ record_request do
91
+ get storefront_api.system_content_path('home_page', session_id: 'session_1')
92
+ assert_match(/Thanks/, response.body)
93
+ assert(response.ok?)
94
+ end
95
+ record_request do
96
+ get storefront_api.system_content_path('home_page', session_id: 'session_2')
97
+ assert_match(/Welcome back/, response.body)
98
+ assert(response.ok?)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -72,7 +72,7 @@ module Workarea
72
72
  }
73
73
  }
74
74
 
75
- assert_equal(200, response.status)
75
+ assert_equal(422, response.status)
76
76
  end
77
77
  end
78
78
  end
@@ -1,3 +1,5 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Rails.application.config.session_store :cookie_store, key: '_dummy_session'
3
+ Rails.application.config.session_store :cookie_store,
4
+ key: '_dummy_session',
5
+ expire_after: 30.minutes
@@ -7,11 +7,19 @@ module Workarea
7
7
  def test_saving_category_view
8
8
  post storefront_api.analytics_category_view_path(category_id: 'foo')
9
9
  assert_equal(1, Metrics::CategoryByDay.first.views)
10
+
11
+ post storefront_api.analytics_category_view_path(category_id: 'foo', session_id: '1')
12
+ assert_equal(2, Metrics::CategoryByDay.first.views)
13
+ assert_equal(%w(foo), Metrics::User.find('1').viewed.category_ids)
10
14
  end
11
15
 
12
16
  def test_saving_product_view
13
17
  post storefront_api.analytics_product_view_path(product_id: 'foo')
14
18
  assert_equal(1, Metrics::ProductByDay.first.views)
19
+
20
+ post storefront_api.analytics_product_view_path(product_id: 'foo', session_id: '1')
21
+ assert_equal(2, Metrics::ProductByDay.first.views)
22
+ assert_equal(%w(foo), Metrics::User.find('1').viewed.product_ids)
15
23
  end
16
24
 
17
25
  def test_saving_search
@@ -21,14 +29,11 @@ module Workarea
21
29
  insights = Metrics::SearchByDay.first
22
30
  assert_equal(1, insights.searches)
23
31
  assert_equal(5, insights.total_results)
24
- end
25
32
 
26
- def test_saving_search_abandonment
27
- # Saving abandonment is deprecated, and this will be removed in v3.5
28
- end
29
-
30
- def test_saving_filters
31
- # Saving filters is deprecated, and this will be removed in v3.5
33
+ post storefront_api.analytics_search_path,
34
+ params: { q: 'foo', total_results: 5, session_id: '1' }
35
+ assert_equal(2, insights.reload.searches)
36
+ assert_equal(%w(foo), Metrics::User.find('1').viewed.search_ids)
32
37
  end
33
38
  end
34
39
  end
@@ -19,30 +19,38 @@ module Workarea
19
19
 
20
20
  def test_showing_recent_views_with_authentication
21
21
  user = create_user(first_name: 'Ben', last_name: 'Crouse')
22
- set_current_user(user)
22
+ post storefront_api.authentication_tokens_path,
23
+ params: { email: user.email, password: user.password }
24
+ token = JSON.parse(response.body)['token']
23
25
 
24
- activity = create_user_activity(
25
- id: user.id,
26
+ Metrics::User.save_affinity(
27
+ id: user.email,
28
+ action: 'viewed',
26
29
  product_ids: [@product.id],
27
30
  category_ids: [@category.id],
28
- searches: ['foo']
31
+ at: Time.current,
32
+ search_ids: %w(foo)
29
33
  )
30
34
 
31
- get storefront_api.recent_views_path
35
+ get storefront_api.recent_views_path,
36
+ headers: { 'HTTP_AUTHORIZATION' => encode_credentials(token) }
32
37
 
33
38
  assert(response.ok?)
34
39
  result = JSON.parse(response.body)
35
40
 
36
- assert_equal(activity.id, result['id'])
41
+ assert_equal(user.email, result['id'])
37
42
  assert_equal(@product.id, result['products'].first['id'])
38
43
  assert_equal(@category.id.to_s, result['categories'].first['id'])
39
- assert_includes(result['searches'], 'foo')
40
44
  end
41
45
 
42
46
  def test_adding_recent_views_for_authentication
43
47
  user = create_user(first_name: 'Ben', last_name: 'Crouse')
44
- set_current_user(user)
48
+ post storefront_api.authentication_tokens_path,
49
+ params: { email: user.email, password: user.password }
50
+ token = JSON.parse(response.body)['token']
51
+
45
52
  patch storefront_api.recent_views_path,
53
+ headers: { 'HTTP_AUTHORIZATION' => encode_credentials(token) },
46
54
  params: {
47
55
  product_id: @product.id,
48
56
  category_id: @category.id,
@@ -51,54 +59,51 @@ module Workarea
51
59
 
52
60
  assert(response.ok?)
53
61
 
54
- user_activity = Recommendation::UserActivity.first
55
- assert_equal(user.id.to_s, user_activity.id.to_s)
56
- assert_includes(user_activity.product_ids, @product.id)
57
- assert_includes(user_activity.category_ids, @category.id.to_s)
58
- assert_includes(user_activity.searches, 'foo')
62
+ user_activity = Workarea::Storefront::UserActivityViewModel.wrap(
63
+ Metrics::User.first
64
+ )
65
+ assert_equal(user.email, user_activity.id)
66
+ assert_includes(user_activity.products, @product)
67
+ assert_includes(user_activity.categories, @category)
59
68
  end
60
69
 
61
70
  def test_showing_recent_views_with_session_id
62
- activity = create_user_activity(
71
+ Metrics::User.save_affinity(
72
+ id: BSON::ObjectId.new.to_s,
73
+ action: 'viewed',
63
74
  product_ids: [@product.id],
64
75
  category_ids: [@category.id],
65
- searches: ['bar']
76
+ search_ids: %w(foo)
66
77
  )
78
+ activity = Metrics::User.last
67
79
 
68
80
  get storefront_api.recent_views_path,
69
81
  params: { session_id: activity.id }
70
82
 
71
- assert(response.ok?)
83
+ assert_response(:success)
72
84
  result = JSON.parse(response.body)
73
85
 
74
- assert_equal(activity.id, result['id'])
75
- assert_equal(@product.id, result['products'].first['id'])
86
+ assert_equal(activity.id.to_s, result['id'])
87
+ assert_equal(@product.id.to_s, result['products'].first['id'])
76
88
  assert_equal(@category.id.to_s, result['categories'].first['id'])
77
- assert_includes(result['searches'], 'bar')
78
89
  end
79
90
 
80
91
  def test_adding_recent_views_for_session_id
81
- activity = create_user_activity(
82
- product_ids: [@product.id],
83
- category_ids: [@category.id],
84
- searches: ['bar']
85
- )
86
-
87
92
  patch storefront_api.recent_views_path,
88
93
  params: {
89
- session_id: activity.id,
94
+ session_id: BSON::ObjectId.new.to_s,
90
95
  product_id: @product.id,
91
96
  category_id: @category.id,
92
97
  search: 'bar'
93
98
  }
94
99
 
95
- assert(response.ok?)
100
+ assert_response(:success)
96
101
 
97
- user_activity = Recommendation::UserActivity.first
98
- assert_equal(activity.id, user_activity.id)
99
- assert_includes(user_activity.product_ids, @product.id)
100
- assert_includes(user_activity.category_ids, @category.id.to_s)
101
- assert_includes(user_activity.searches, 'bar')
102
+ user_activity = Workarea::Storefront::UserActivityViewModel.wrap(
103
+ Metrics::User.first
104
+ )
105
+ assert_includes(user_activity.products, @product)
106
+ assert_includes(user_activity.categories, @category)
102
107
  end
103
108
 
104
109
  def test_adding_without_id
@@ -110,7 +115,7 @@ module Workarea
110
115
  }
111
116
 
112
117
  refute(response.ok?)
113
- assert_equal(0, Recommendation::UserActivity.count)
118
+ assert_equal(0, Metrics::User.count)
114
119
  end
115
120
  end
116
121
  end
@@ -23,7 +23,7 @@ module Workarea
23
23
  end
24
24
 
25
25
  def set_user_activity
26
- @activity = create_user_activity
26
+ @activity = Metrics::User.create!
27
27
  end
28
28
 
29
29
  def test_showing_recommendations_with_authentication
@@ -4,42 +4,6 @@ module Workarea
4
4
  module Api
5
5
  module Storefront
6
6
  class SearchesIntegrationTest < IntegrationTest
7
- def test_showing_search_autocomplete
8
- create_product(name: 'Foo')
9
- create_category(name: 'Foo Category')
10
- create_page(name: 'Foo Page')
11
-
12
- Metrics::SearchByDay.save_search('foo', 3)
13
- travel_to 1.weeks.from_now
14
- GenerateInsights.generate_all!
15
- BulkIndexSearches.perform
16
-
17
- get storefront_api.searches_path(q: 'foo')
18
- results = JSON.parse(response.body)['results']
19
- assert_equal(4, results.length)
20
-
21
- search = results.detect { |r| r['type'] == 'Searches' }
22
- assert(search.present?)
23
- assert_equal('foo', search['value'])
24
- assert_equal(storefront_api.search_path(q: 'foo'), search['url'])
25
-
26
- product = results.detect { |r| r['type'] == 'Products' }
27
- assert(product.present?)
28
- assert_equal('Foo', product['value'])
29
- assert_match(/product_images/, product['image'])
30
- assert_equal(storefront_api.product_path('foo'), product['url'])
31
-
32
- category = results.detect { |r| r['type'] == 'Categories' }
33
- assert(category.present?)
34
- assert_equal('Foo Category', category['value'])
35
- assert_equal(storefront_api.category_path('foo-category'), category['url'])
36
-
37
- page = results.detect { |r| r['type'] == 'Pages' }
38
- assert(page.present?)
39
- assert_equal('Foo Page', page['value'])
40
- assert_equal(storefront_api.page_path('foo-page'), page['url'])
41
- end
42
-
43
7
  def test_shows_search_results
44
8
  Search::Settings.current.update_attributes!(terms_facets: %w(Color Size))
45
9
  create_product(
@@ -0,0 +1,218 @@
1
+ require 'test_helper'
2
+
3
+ module Workarea
4
+ module Api
5
+ module Storefront
6
+ class SegmentsIntegrationTest < IntegrationTest
7
+ include AuthenticationTest
8
+
9
+ def test_sessions_functionality
10
+ first_time = Segment::FirstTimeVisitor.instance
11
+ returning = Segment::ReturningVisitor.instance
12
+
13
+ get storefront_api.system_content_path('home_page')
14
+ assert_equal(first_time.id.to_s, response.headers['X-Workarea-Segments'])
15
+
16
+ get storefront_api.system_content_path('home_page'), params: { sessions: 1 }
17
+ assert_equal(first_time.id.to_s, response.headers['X-Workarea-Segments'])
18
+
19
+ get storefront_api.system_content_path('home_page'), params: { sessions: 2 }
20
+ assert_equal(returning.id.to_s, response.headers['X-Workarea-Segments'])
21
+ end
22
+
23
+ def test_current_email_functionality
24
+ first_time = Segment::FirstTimeCustomer.instance
25
+ returning = Segment::ReturningCustomer.instance
26
+
27
+ Metrics::User.save_order(email: 'first-time@workarea.com', revenue: 1.to_m)
28
+ Metrics::User.save_order(email: 'returning@workarea.com', revenue: 1.to_m)
29
+ Metrics::User.save_order(email: 'returning@workarea.com', revenue: 1.to_m)
30
+
31
+ get storefront_api.system_content_path('home_page')
32
+ assert(response.headers['X-Workarea-Segments'].blank?)
33
+
34
+ get storefront_api.system_content_path('home_page'), params: { email: 'first-time@workarea.com' }
35
+ assert_equal(first_time.id.to_s, response.headers['X-Workarea-Segments'])
36
+
37
+ get storefront_api.system_content_path('home_page'), params: { email: 'returning@workarea.com' }
38
+ assert_equal(returning.id.to_s, response.headers['X-Workarea-Segments'])
39
+ end
40
+
41
+ def test_session_ids_for_metrics
42
+ first_time = Segment::FirstTimeCustomer.instance
43
+ returning = Segment::ReturningCustomer.instance
44
+
45
+ Metrics::User.create!(id: '1', orders: 1)
46
+ Metrics::User.create!(id: '2', orders: 2)
47
+
48
+ get storefront_api.system_content_path('home_page')
49
+ assert(response.headers['X-Workarea-Segments'].blank?)
50
+
51
+ get storefront_api.system_content_path('home_page'), params: { session_id: '1' }
52
+ assert_equal(first_time.id.to_s, response.headers['X-Workarea-Segments'])
53
+
54
+ get storefront_api.system_content_path('home_page'), params: { session_id: '2' }
55
+ assert_equal(returning.id.to_s, response.headers['X-Workarea-Segments'])
56
+ end
57
+
58
+ def test_products_active_by_segment
59
+ segment_one = create_segment(rules: [Segment::Rules::Sessions.new(minimum: 1, maximum: 1)])
60
+ segment_two = create_segment(rules: [Segment::Rules::Sessions.new(minimum: 2, maximum: 2)])
61
+ product_one = create_product(active: true, active_segment_ids: [segment_two.id])
62
+ product_two = create_product(active: true, active_segment_ids: [segment_one.id])
63
+
64
+ assert_raise InvalidDisplay do
65
+ get storefront_api.product_path(product_one), params: { sessions: 0 }
66
+ assert(response.not_found?)
67
+ end
68
+
69
+ assert_raise InvalidDisplay do
70
+ get storefront_api.product_path(product_two), params: { sessions: 0 }
71
+ assert(response.not_found?)
72
+ end
73
+
74
+ get storefront_api.search_path(q: '*'), params: { sessions: 0 }
75
+ assert(JSON.parse(response.body)['products'].empty?)
76
+
77
+ assert_raise InvalidDisplay do
78
+ get storefront_api.product_path(product_one), params: { sessions: 1 }
79
+ assert(response.not_found?)
80
+ end
81
+
82
+ get storefront_api.product_path(product_two), params: { sessions: 1 }
83
+ assert(response.ok?)
84
+
85
+ get storefront_api.search_path(q: '*'), params: { sessions: 1 }
86
+ products = JSON.parse(response.body)['products']
87
+ assert_equal([product_two.id], products.map { |p| p['id'] })
88
+
89
+ get storefront_api.product_path(product_one), params: { sessions: 2 }
90
+ assert(response.ok?)
91
+
92
+ assert_raise InvalidDisplay do
93
+ get storefront_api.product_path(product_two), params: { sessions: 2 }
94
+ assert(response.not_found?)
95
+ end
96
+
97
+ get storefront_api.search_path(q: '*'), params: { sessions: 2 }
98
+ products = JSON.parse(response.body)['products']
99
+ assert_equal([product_one.id], products.map { |p| p['id'] })
100
+
101
+ segment_one.rules.first.update!(minimum: 1, maximum: nil)
102
+ segment_two.rules.first.update!(minimum: 1, maximum: nil)
103
+
104
+ get storefront_api.product_path(product_one), params: { sessions: 1 }
105
+ assert(response.ok?)
106
+
107
+ get storefront_api.product_path(product_two), params: { sessions: 1 }
108
+ assert(response.ok?)
109
+
110
+ get storefront_api.search_path(q: '*'), params: { sessions: 1 }
111
+ products = JSON.parse(response.body)['products']
112
+ assert_equal(2, products.count)
113
+ assert_includes(products.map { |r| r['id'] }, product_one.id)
114
+ assert_includes(products.map { |r| r['id'] }, product_two.id)
115
+ end
116
+
117
+ def test_content_active_by_segment
118
+ segment_one = create_segment(rules: [Segment::Rules::Sessions.new(minimum: 1, maximum: 1)])
119
+ segment_two = create_segment(rules: [Segment::Rules::Sessions.new(minimum: 2, maximum: 2)])
120
+
121
+ content = Content.for('home_page')
122
+ foo = content.blocks.create!(
123
+ type: 'html',
124
+ data: { 'html' => '<p>Foo</p>' },
125
+ active_segment_ids: [segment_one.id]
126
+ )
127
+ bar = content.blocks.create!(
128
+ type: 'html',
129
+ data: { 'html' => '<p>Bar</p>' },
130
+ active_segment_ids: [segment_two.id]
131
+ )
132
+
133
+ get storefront_api.system_content_path('home_page'), params: { sessions: 1 }
134
+ content_blocks = JSON.parse(response.body)['content_blocks']
135
+ assert_equal([foo.id.to_s], content_blocks.map { |cb| cb['id'] })
136
+
137
+ get storefront_api.system_content_path('home_page'), params: { sessions: 2 }
138
+ content_blocks = JSON.parse(response.body)['content_blocks']
139
+ assert_equal([bar.id.to_s], content_blocks.map { |cb| cb['id'] })
140
+
141
+ segment_one.rules.first.update!(minimum: 1, maximum: nil)
142
+ segment_two.rules.first.update!(minimum: 1, maximum: nil)
143
+
144
+ get storefront_api.system_content_path('home_page'), params: { sessions: 1 }
145
+ content_blocks = JSON.parse(response.body)['content_blocks']
146
+ assert_equal([foo.id.to_s, bar.id.to_s], content_blocks.map { |cb| cb['id'] })
147
+ end
148
+
149
+ def test_logged_in_based_segments
150
+ logged_in = create_segment(rules: [Segment::Rules::LoggedIn.new(logged_in: true)])
151
+ logged_out = create_segment(rules: [Segment::Rules::LoggedIn.new(logged_in: false)])
152
+
153
+ get storefront_api.system_content_path('home_page')
154
+ assert_equal(logged_out.id.to_s, response.headers['X-Workarea-Segments'])
155
+
156
+ user = create_user
157
+ post storefront_api.authentication_tokens_path,
158
+ params: { email: user.email, password: user.password }
159
+
160
+ token = JSON.parse(response.body)['token']
161
+ get storefront_api.system_content_path('home_page'),
162
+ headers: { 'HTTP_AUTHORIZATION' => encode_credentials(token) }
163
+ assert_equal(logged_in.id.to_s, response.headers['X-Workarea-Segments'])
164
+ end
165
+
166
+ def test_http_caching_headers_for_segmented_content
167
+ Workarea.config.strip_http_caching_in_tests = false
168
+ segment = create_segment(rules: [Segment::Rules::Sessions.new(maximum: 999)])
169
+
170
+ get storefront_api.system_content_path('home_page')
171
+ refute_match(/private/, response.headers['Cache-Control'])
172
+ assert_match(/public/, response.headers['Cache-Control'])
173
+ assert(response.headers['X-Workarea-Segmented-Content'].blank?)
174
+
175
+ content = Content.for('home_page')
176
+ content.blocks.create!(
177
+ type: 'html',
178
+ data: { 'html' => '<p>Foo</p>' },
179
+ active_segment_ids: [segment.id]
180
+ )
181
+
182
+ get storefront_api.system_content_path('home_page')
183
+ assert_match(/private/, response.headers['Cache-Control'])
184
+ refute_match(/public/, response.headers['Cache-Control'])
185
+ assert_equal('true', response.headers['X-Workarea-Segmented-Content'])
186
+
187
+ product = create_product(active: true, active_segment_ids: [])
188
+ get storefront_api.product_path(product)
189
+ assert(response.ok?)
190
+ refute_match(/private/, response.headers['Cache-Control'])
191
+ assert_match(/public/, response.headers['Cache-Control'])
192
+ assert(response.headers['X-Workarea-Segmented-Content'].blank?)
193
+
194
+ product.update!(active_segment_ids: [segment.id])
195
+ get storefront_api.product_path(product)
196
+ assert(response.ok?)
197
+ assert_match(/private/, response.headers['Cache-Control'])
198
+ refute_match(/public/, response.headers['Cache-Control'])
199
+ assert_equal('true', response.headers['X-Workarea-Segmented-Content'])
200
+
201
+ category = create_category(active: true, active_segment_ids: [])
202
+ get storefront_api.category_path(category)
203
+ assert(response.ok?)
204
+ refute_match(/private/, response.headers['Cache-Control'])
205
+ assert_match(/public/, response.headers['Cache-Control'])
206
+ assert(response.headers['X-Workarea-Segmented-Content'].blank?)
207
+
208
+ category.update!(product_ids: [product.id])
209
+ get storefront_api.category_path(category)
210
+ assert(response.ok?)
211
+ assert_match(/private/, response.headers['Cache-Control'])
212
+ refute_match(/public/, response.headers['Cache-Control'])
213
+ assert_equal('true', response.headers['X-Workarea-Segmented-Content'])
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end