datashift_journey 0.1.2

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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +391 -0
  4. data/Rakefile +26 -0
  5. data/app/assets/stylesheets/datashift_journey/partials/_state_jumper_toolbar.scss.erb +27 -0
  6. data/app/controllers/concerns/datashift_journey/error_renderer.rb +9 -0
  7. data/app/controllers/concerns/datashift_journey/review_renderer.rb +21 -0
  8. data/app/controllers/concerns/datashift_journey/token_based_access.rb +23 -0
  9. data/app/controllers/concerns/datashift_journey/validate_state.rb +59 -0
  10. data/app/controllers/datashift_journey/abandon_enrollments_controller.rb +14 -0
  11. data/app/controllers/datashift_journey/abandonments_controller.rb +17 -0
  12. data/app/controllers/datashift_journey/api/v1/states_controller.rb +49 -0
  13. data/app/controllers/datashift_journey/application_controller.rb +53 -0
  14. data/app/controllers/datashift_journey/errors_controller.rb +24 -0
  15. data/app/controllers/datashift_journey/journey_ends_controller.rb +19 -0
  16. data/app/controllers/datashift_journey/journey_plans_controller.rb +166 -0
  17. data/app/controllers/datashift_journey/page_states_controller.rb +49 -0
  18. data/app/controllers/datashift_journey/reviews_controller.rb +32 -0
  19. data/app/controllers/datashift_journey/state_jumper_controller.rb +51 -0
  20. data/app/factories/datashift_journey/form_object_factory.rb +68 -0
  21. data/app/forms/datashift_journey/collector/base_collector_form.rb +60 -0
  22. data/app/forms/datashift_journey/concerns/form_mixin.rb +64 -0
  23. data/app/forms/datashift_journey/null_form.rb +20 -0
  24. data/app/helpers/datashift_journey/application_helper.rb +50 -0
  25. data/app/helpers/datashift_journey/back_link_helper.rb +9 -0
  26. data/app/models/datashift_journey/collector/data_node.rb +18 -0
  27. data/app/models/datashift_journey/collector/form_definition.rb +35 -0
  28. data/app/models/datashift_journey/collector/form_field.rb +61 -0
  29. data/app/models/datashift_journey/journey_review.rb +65 -0
  30. data/app/models/datashift_journey/review_data_section.rb +32 -0
  31. data/app/serializers/datashift_journey/collector/page_state_serializer.rb +9 -0
  32. data/app/serializers/state_machines/state/state_serializer.rb +5 -0
  33. data/app/views/datashift_journey/collector/_generic_form.html.erb +14 -0
  34. data/app/views/datashift_journey/errors/401.html.erb +13 -0
  35. data/app/views/datashift_journey/errors/403.html.erb +13 -0
  36. data/app/views/datashift_journey/errors/404.html.erb +13 -0
  37. data/app/views/datashift_journey/errors/422.html.erb +11 -0
  38. data/app/views/datashift_journey/errors/500.html.erb +13 -0
  39. data/app/views/datashift_journey/errors/503.html.erb +11 -0
  40. data/app/views/datashift_journey/errors/invalid_authenticity_token.html.erb +14 -0
  41. data/app/views/datashift_journey/journey_ends/new.html.erb +5 -0
  42. data/app/views/datashift_journey/journey_ends/show.html.erb +5 -0
  43. data/app/views/datashift_journey/journey_plans/_form.html.erb +14 -0
  44. data/app/views/datashift_journey/journey_plans/_render_fields.html.erb +24 -0
  45. data/app/views/datashift_journey/journey_plans/edit.html.erb +6 -0
  46. data/app/views/datashift_journey/journey_plans/new.html.erb +6 -0
  47. data/app/views/datashift_journey/shared/_default_actions.html.erb +6 -0
  48. data/app/views/datashift_journey/shared/_errors.html.erb +19 -0
  49. data/app/views/datashift_journey/shared/_submit_action.html.erb +5 -0
  50. data/app/views/datashift_journey/state_jumper/_toolbar.html.erb +16 -0
  51. data/config/brakeman.ignore +42 -0
  52. data/config/i18n-tasks.yml +103 -0
  53. data/config/initializers/exceptions_app.rb +3 -0
  54. data/config/initializers/mime_types.rb +1 -0
  55. data/config/initializers/rswag-api.rb +14 -0
  56. data/config/initializers/rswag-ui.rb +9 -0
  57. data/config/locales/en.yml +39 -0
  58. data/config/routes.rb +44 -0
  59. data/lib/datashift_journey/collector/field_snippet.rb +12 -0
  60. data/lib/datashift_journey/collector/page_state_snippet.rb +12 -0
  61. data/lib/datashift_journey/collector/snippet.rb +14 -0
  62. data/lib/datashift_journey/configuration.rb +103 -0
  63. data/lib/datashift_journey/engine.rb +38 -0
  64. data/lib/datashift_journey/exceptions.rb +26 -0
  65. data/lib/datashift_journey/helpers/back_link.rb +58 -0
  66. data/lib/datashift_journey/journey/machine_builder.rb +59 -0
  67. data/lib/datashift_journey/prepare_data_for_review.rb +219 -0
  68. data/lib/datashift_journey/reference_generator.rb +51 -0
  69. data/lib/datashift_journey/state_machines/branch_sequence_map.rb +35 -0
  70. data/lib/datashift_journey/state_machines/extensions.rb +40 -0
  71. data/lib/datashift_journey/state_machines/planner.rb +206 -0
  72. data/lib/datashift_journey/state_machines/sequence.rb +86 -0
  73. data/lib/datashift_journey/state_machines/state_machine_core_ext.rb +72 -0
  74. data/lib/datashift_journey/version.rb +3 -0
  75. data/lib/datashift_journey.rb +57 -0
  76. data/lib/generators/datashift_journey/collector/collector_generator.rb +43 -0
  77. data/lib/generators/datashift_journey/collector/install_collector_generator.rb +61 -0
  78. data/lib/generators/datashift_journey/collector/install_mongo_collector_generator.rb +44 -0
  79. data/lib/generators/datashift_journey/collector/templates/collector_concern.rb.tt +34 -0
  80. data/lib/generators/datashift_journey/collector/templates/collector_migration.rb.tt +46 -0
  81. data/lib/generators/datashift_journey/forms_generator.rb +45 -0
  82. data/lib/generators/datashift_journey/generate_common.rb +33 -0
  83. data/lib/generators/datashift_journey/setup/USAGE +12 -0
  84. data/lib/generators/datashift_journey/setup/setup_generator.rb +44 -0
  85. data/lib/generators/datashift_journey/setup/templates/initializer.rb.tt +17 -0
  86. data/lib/generators/datashift_journey/setup/templates/model_concern.rb.tt +37 -0
  87. data/lib/generators/datashift_journey/templates/base_form.rb.tt +7 -0
  88. data/lib/generators/datashift_journey/templates/collector_form.rb.tt +18 -0
  89. data/lib/generators/datashift_journey/templates/collector_view.rb.tt +15 -0
  90. data/lib/generators/datashift_journey/templates/journey_plan_form.rb.tt +23 -0
  91. data/lib/generators/datashift_journey/templates/journey_plan_view.rb.tt +15 -0
  92. data/lib/generators/datashift_journey/views_generator.rb +35 -0
  93. data/lib/tasks/state_machine.thor +48 -0
  94. data/spec/datashift_journey/complex_journey_spec.rb +132 -0
  95. data/spec/datashift_journey/machine_builder_spec.rb +268 -0
  96. data/spec/datashift_journey/planner_spec.rb +129 -0
  97. data/spec/datashift_journey/sequence_spec.rb +20 -0
  98. data/spec/dummy/Rakefile +6 -0
  99. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  100. data/spec/dummy/app/assets/stylesheets/application.css +16 -0
  101. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  102. data/spec/dummy/app/forms/base_form.rb +8 -0
  103. data/spec/dummy/app/forms/business_details_form.rb +17 -0
  104. data/spec/dummy/app/forms/business_type_form.rb +17 -0
  105. data/spec/dummy/app/forms/contact_details_form.rb +17 -0
  106. data/spec/dummy/app/forms/enter_reg_number_form.rb +17 -0
  107. data/spec/dummy/app/forms/new_or_renew_form.rb +17 -0
  108. data/spec/dummy/app/forms/postal_address_form.rb +17 -0
  109. data/spec/dummy/app/forms/question1_form.rb +9 -0
  110. data/spec/dummy/app/forms/question2_form.rb +12 -0
  111. data/spec/dummy/app/forms/sole_trader_name_form.rb +17 -0
  112. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  113. data/spec/dummy/app/models/payment.rb +5 -0
  114. data/spec/dummy/app/services/datashift_journey/models/collector_journey.rb +51 -0
  115. data/spec/dummy/app/views/_question1.html.erb +13 -0
  116. data/spec/dummy/app/views/_question2.html.erb +9 -0
  117. data/spec/dummy/app/views/layouts/alternative.html.erb +14 -0
  118. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  119. data/spec/dummy/app/views/pages/home.html.erb +6 -0
  120. data/spec/dummy/app/views/pages/start.html.erb +5 -0
  121. data/spec/dummy/bin/bundle +3 -0
  122. data/spec/dummy/bin/rails +4 -0
  123. data/spec/dummy/bin/rake +4 -0
  124. data/spec/dummy/bin/setup +29 -0
  125. data/spec/dummy/config/application.rb +39 -0
  126. data/spec/dummy/config/boot.rb +5 -0
  127. data/spec/dummy/config/database.yml +22 -0
  128. data/spec/dummy/config/environment.rb +5 -0
  129. data/spec/dummy/config/environments/development.rb +47 -0
  130. data/spec/dummy/config/environments/production.rb +79 -0
  131. data/spec/dummy/config/environments/test.rb +47 -0
  132. data/spec/dummy/config/initializers/assets.rb +11 -0
  133. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  134. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  135. data/spec/dummy/config/initializers/datashift_journey.rb +6 -0
  136. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  137. data/spec/dummy/config/initializers/inflections.rb +16 -0
  138. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  139. data/spec/dummy/config/initializers/session_store.rb +3 -0
  140. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  141. data/spec/dummy/config/locales/en.yml +27 -0
  142. data/spec/dummy/config/routes.rb +28 -0
  143. data/spec/dummy/config/secrets.yml +22 -0
  144. data/spec/dummy/config.ru +4 -0
  145. data/spec/dummy/db/migrate/20160101091218_create_dummy_checkout.rb +43 -0
  146. data/spec/dummy/db/migrate/20161221100703_datashift_journey_create_collector.rb +56 -0
  147. data/spec/dummy/db/schema.rb +142 -0
  148. data/spec/dummy/lib/version.rb +1 -0
  149. data/spec/factories/collector_factory.rb +16 -0
  150. data/spec/factories/collector_snippet_factory.rb +9 -0
  151. data/spec/factories/collector_state_page_factory.rb +12 -0
  152. data/spec/factories/data_node_factory.rb +9 -0
  153. data/spec/factories/form_factory.rb +6 -0
  154. data/spec/features/basic_navigation_spec.rb +125 -0
  155. data/spec/helpers/application_helper_spec.rb +40 -0
  156. data/spec/integration/collector/page_state_spec.rb +45 -0
  157. data/spec/models/collector/collector_spec.rb +100 -0
  158. data/spec/models/collector/page_state_spec.rb +30 -0
  159. data/spec/rails_helper.rb +73 -0
  160. data/spec/requests/collector/api/v1/page_state_spec.rb +85 -0
  161. data/spec/requests/collector/api/v1/states_spec.rb +28 -0
  162. data/spec/spec_helper.rb +63 -0
  163. data/spec/support/asserts.rb +27 -0
  164. data/spec/support/mailer_macros.rb +25 -0
  165. data/spec/support/page_objects/base_page_object.rb +77 -0
  166. data/spec/swagger_helper.rb +25 -0
  167. metadata +425 -0
@@ -0,0 +1,85 @@
1
+ require 'rails_helper'
2
+
3
+ module DatashiftJourney
4
+
5
+ describe 'Collector::PageState API' do
6
+
7
+ RSpec.configure do |config|
8
+ config.render_views = true
9
+ end
10
+
11
+ context "API" do
12
+
13
+ let(:expected_page_states) { 3 }
14
+
15
+ before :each do
16
+ create_list(:collector_page_state, 3)
17
+ end
18
+
19
+ it 'sends a list of page states' do
20
+
21
+ get '/api/v1/page_states'
22
+
23
+ json = parse(response)
24
+
25
+ # test for the 200 status-code
26
+ expect(response).to be_success
27
+
28
+ # check to make sure the right amount of messages are returned
29
+ expect(json['data'].length).to eq(expected_page_states)
30
+ end
31
+
32
+ it 'creates a new page state and responds with JSON body containing expected PageState' do
33
+ expect {
34
+ post '/api/v1/page_states', params: { page_state: { form_name: 'BrandNewPage' } }
35
+ }.to change(Collector::PageState, :count).by(1)
36
+
37
+ # test for the 200 status-code
38
+ expect(response).to be_success
39
+
40
+ jdata = parse_attribs(response)
41
+
42
+ expect(jdata).to have_key 'form-name'
43
+ expect(jdata['form-name']).to eq 'BrandNewPage'
44
+ end
45
+
46
+ it 'rejects badly defined page state and responds with Unprocesable entity' do
47
+ expect {
48
+ post '/api/v1/page_states', params: { page_state: {} }
49
+ }.to_not change(Collector::PageState, :count)
50
+
51
+ expect(response.status).to eq(422)
52
+
53
+ json = parse(response)
54
+
55
+ expect(json).to have_key 'errors'
56
+
57
+ e = json['errors'][0]
58
+ expect(e).to have_key "source"
59
+ expect(e).to have_key "detail"
60
+ expect(e['detail']).to eq "can't be blank"
61
+ end
62
+
63
+ it "should get a valid page state" do
64
+ page_state = Collector::PageState.first
65
+ get "/api/v1/page_states/#{page_state.id}"
66
+ expect(response).to be_success
67
+ jdata = parse response
68
+
69
+ expect( page_state.id.to_s).to eq jdata['data']['id']
70
+ expect( page_state.form_name).to eq jdata['data']['attributes']['form-name']
71
+
72
+ #see Rails.application.routes.default_url_options = {
73
+ expect( page_state_url(page_state, { host: "localhost", port: 3000 }) ).to eq jdata['data']['links']['self']
74
+ end
75
+
76
+ it "Should get JSON:API error block when requesting page state data with invalid ID" do
77
+ get '/api/v1/page_states/zzz'
78
+ expect(response.status).to eq(404)
79
+ jdata = parse response
80
+ expect( "Wrong ID provided").to eq jdata['errors'][0]['detail']
81
+ expect( '/data/attributes/id').to eq jdata['errors'][0]['source']['pointer']
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,28 @@
1
+ require 'rails_helper'
2
+
3
+ module DatashiftJourney
4
+
5
+ describe 'States API' do
6
+
7
+ RSpec.configure do |config|
8
+ config.render_views = true
9
+ end
10
+
11
+ context "list" do
12
+
13
+ it 'sends a list of states of current JourneyPlan model' do
14
+
15
+ get '/api/v1/states'
16
+
17
+ json = parse(response)
18
+
19
+ dump_json response
20
+
21
+ # test for the 200 status-code
22
+ expect(response).to be_success
23
+ expect(json['data']).to have_key 'states'
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,63 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+
5
+ require "simplecov"
6
+
7
+ SimpleCov.start do
8
+ add_filter "spec/factories"
9
+ add_filter "spec/dummy"
10
+ add_filter "app"
11
+ end
12
+
13
+ require 'rspec/rails'
14
+ require 'factory_girl_rails'
15
+ require 'capybara/rails'
16
+ require 'capybara/rspec'
17
+ require 'shoulda-matchers'
18
+ require "shoulda/matchers"
19
+
20
+ Rails.backtrace_cleaner.remove_silencers!
21
+
22
+ # Load our Engine
23
+ require File.expand_path("../../lib/datashift_journey", __FILE__)
24
+
25
+ RSpec.configure do |config|
26
+
27
+ config.mock_with :rspec
28
+ config.use_transactional_fixtures = true
29
+ config.infer_base_class_for_anonymous_controllers = false
30
+
31
+ config.include FactoryGirl::Syntax::Methods
32
+
33
+ config.filter_run :focus
34
+ config.run_all_when_everything_filtered = true
35
+
36
+ def parse(response)
37
+ JSON.parse(response.body)
38
+ end
39
+
40
+ def parse_attribs(response)
41
+ JSON.parse(response.body)['data']['attributes']
42
+ end
43
+
44
+ def dump_json(response)
45
+ puts response.body
46
+ end
47
+
48
+ end
49
+
50
+ # Decorate model with helper methods required for BRANCHING in Test journey plans
51
+
52
+ DatashiftJourney::Collector::Collector.class_eval do
53
+ def construction_demolition_value
54
+ 'yes'
55
+ end
56
+
57
+ def registration_type_value
58
+ # carrier_dealer_sequence:
59
+ 'carrier_dealer'
60
+ # broker_dealer_sequence: 'broker_dealer',
61
+ # carrier_broker_dealer_sequence: 'carrier_broker_dealer')
62
+ end
63
+ end
@@ -0,0 +1,27 @@
1
+ RSpec.configure do |_config|
2
+ # Set of standard checks
3
+ #
4
+ # Is our current state == expected_state
5
+ #
6
+ def expect_state_matches(journey, expected_state, message = nil)
7
+ expect(journey.state_name).to eq(expected_state), message
8
+ expect(journey.state).to eq(expected_state.to_s), message
9
+ expect(journey.state?(expected_state)).to eq(true), message
10
+ end
11
+
12
+ # Set of standard checks
13
+ #
14
+ # Is our current state == expected_state
15
+ # We can transition to back
16
+ # We can transition to next
17
+ # Fire next
18
+ #
19
+ def expect_state_canback_cannext_and_next!(journey, expected_state, message = nil)
20
+ expect_state_matches(journey, expected_state, message)
21
+
22
+ expect(journey.can_back?).to eq(true), 'Expected can_back? to be true'
23
+ expect(journey.can_next?).to eq(true), 'Expected can_next? to be true'
24
+
25
+ journey.next!
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module MailerMacros
2
+
3
+ def last_email
4
+ ActionMailer::Base.deliveries.last
5
+ end
6
+
7
+ def last_email_text
8
+ ActionMailer::Base.deliveries.last.body.raw_source
9
+ end
10
+
11
+ # for multi-part e-mails, first need to select the correct part
12
+
13
+ def last_multipart_raw(index)
14
+ ActionMailer::Base.deliveries.last.parts[index].body.raw_source
15
+ end
16
+
17
+ def reset_email
18
+ ActionMailer::Base.deliveries = []
19
+ end
20
+ end
21
+
22
+ RSpec.configure do |config|
23
+ config.include(MailerMacros)
24
+ config.before(:each) { reset_email }
25
+ end
@@ -0,0 +1,77 @@
1
+ require 'capybara/dsl'
2
+
3
+ class BasePageObject
4
+
5
+ RSpec.configure do |_config|
6
+ # this suggested form dont seems to work for latest version of Rails/rspec
7
+ # config.include Rails.application.routes.url_helpers
8
+ # but simply using standard module inclusion does the trick
9
+ include Rails.application.routes.url_helpers
10
+
11
+ Rails.application.routes.default_url_options = { host: 'www.example.com' }
12
+ end
13
+
14
+ include RSpec::Matchers
15
+ include Capybara::DSL
16
+
17
+ # In RSpec the Engine routing proxy method may not be available,
18
+ # Use this helper to prefix Engine paths in your specs :dsj_url_helper.page_state_path
19
+ #
20
+ def dsj_url_helper
21
+ DatashiftJourney::Engine.routes.url_helpers
22
+ end
23
+
24
+ # Default - relies on PageObject utilising the 'state' method
25
+ # so we can create correct journey_plan object and jump straight to right page
26
+ def visit_page
27
+ begin
28
+ @journey_plan ||= DatashiftJourney.journey_plan_class.new
29
+ rescue => e
30
+ puts 'WARNING -RSPEC Setup Issue - No create_related_journey_plan - '\
31
+ "did you call 'state :<state>' in your PageObject ?"
32
+ puts 'See PageObjectHelpers for more details'
33
+ raise e
34
+ end
35
+
36
+ Rails.logger.debug("RSPEC : VISITING state [#{journey_plan.state}] with #{journey_plan.inspect}")
37
+
38
+ visit dsj_url_helper.journey_plan_state_path(journey_plan.state, journey_plan)
39
+
40
+ self
41
+ end
42
+
43
+ def visit_state(state)
44
+ visit dsj_url_helper.journey_plan_state_path(state, journey_plan)
45
+ end
46
+
47
+ def submit
48
+ click_button('Continue')
49
+ end
50
+
51
+ def click_back_link
52
+ click_link(I18n.t('back'))
53
+ end
54
+
55
+ # Default advance - fill out page and click submit
56
+ # fill_page - expect derived to define this - this should not call Submit
57
+ #
58
+ def advance_page
59
+ visit_page unless current_path && has_text?(self.class.on_page_text)
60
+ fill_page
61
+ submit
62
+ find_journey_plan
63
+ end
64
+
65
+ def dump
66
+ print page.html
67
+ end
68
+
69
+ # requires test has : js: true
70
+ # rubocop:disable Debugger
71
+ def screenshot(timestamp = '%H%M%S%L')
72
+ file = "/tmp/rspec_po_#{Time.zone.now.strftime(timestamp)}.png"
73
+ save_screenshot(file, full: true)
74
+ puts "RSPEC created screenshot of current page #{file}"
75
+ end
76
+
77
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.configure do |config|
4
+ # Specify a root folder where Swagger JSON files are generated
5
+ # NOTE: If you're using the rswag-api to serve API descriptions, you'll need
6
+ # to ensure that it's confiugred to server Swagger from the same folder
7
+ config.swagger_root = File.join(DatashiftJourney::Engine.root, 'spec', 'swagger')
8
+
9
+ # Define one or more Swagger documents and provide global metadata for each one
10
+ # When you run the 'rswag:specs:to_swagger' rake task, the complete Swagger will
11
+ # be generated at the provided relative path under swagger_root
12
+ # By default, the operations defined in spec files are added to the first
13
+ # document below. You can override this behavior by adding a swagger_doc tag to the
14
+ # the root example_group in your specs, e.g. describe '...', swagger_doc: 'v2/swagger.json'
15
+ config.swagger_docs = {
16
+ 'v1/swagger.json' => {
17
+ swagger: '2.0',
18
+ info: {
19
+ title: 'API V1',
20
+ version: 'v1'
21
+ },
22
+ paths: {}
23
+ }
24
+ }
25
+ end