datashift_journey 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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,18 @@
1
+ module DatashiftJourney
2
+ module Collector
3
+ class DataNode < ActiveRecord::Base
4
+
5
+ self.table_name = 'dsj_data_nodes'
6
+
7
+ # Instance of the DatashiftJourney.journey_plan_class this data was collected for.
8
+ #
9
+ # Model holding the state machine Plan
10
+ belongs_to :plan, polymorphic: true
11
+
12
+ # generic definition of the field this data relates to - card type, street address, profile id etc
13
+ belongs_to :form_field, class_name: 'DatashiftJourney::Collector::FormField', foreign_key: :form_field_id
14
+
15
+ validates_presence_of :field_value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ module DatashiftJourney
2
+ module Collector
3
+
4
+ # Associated with a REFORM class - stores related Form definition data in the DB,
5
+ # such as the fields associated with this form.
6
+ #
7
+ # Each step or state in the plan will have an associated ReForm + FormDefinition
8
+ #
9
+ # Similar in intention to the Page Object Pattern, store and provide helpers for
10
+ # rendering forms and HTML in the associated state View
11
+ #
12
+ class FormDefinition < ActiveRecord::Base
13
+
14
+ self.table_name = 'dsj_form_definitions'
15
+
16
+ has_many :form_fields, class_name: 'DatashiftJourney::Collector::FormField', dependent: :destroy, foreign_key: :form_definition_id
17
+ accepts_nested_attributes_for :form_fields
18
+
19
+ validates_presence_of :state
20
+ validates_uniqueness_of :state
21
+
22
+ def field_ids
23
+ form_fields.collect(&:id)
24
+ end
25
+
26
+ private
27
+
28
+ # N.B Validations are called BEFORE before_create or before_save
29
+ before_validation do |record|
30
+ record.state ||= DatashiftJourney::FormObjectFactory.state_name(self.klass)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ module DatashiftJourney
2
+ module Collector
3
+
4
+ # This DEFINES a single Field in a Form, where a field is generally a form
5
+ # element that collects some kind of data
6
+ #
7
+ class FormField < ActiveRecord::Base
8
+
9
+ self.table_name = 'dsj_form_fields'
10
+
11
+ belongs_to :form_definition, class_name: 'FormDefinition', foreign_key: :form_definition_id
12
+
13
+ validates_presence_of :form_definition, :name, :category
14
+
15
+ # Notes:
16
+ #
17
+ # Cannot use "select" - keyword already defined by Active Record.
18
+ #
19
+ # When assigning a category of - :select_option - the form should also provide a helper method
20
+ # to populate the select dropdown as per https://api.rubyonrails.org/v6.0.3.4/classes/ActionView/Helpers/FormOptionsHelper.html
21
+ #
22
+ # The expected method format is : options_for_select_<field name>
23
+ #
24
+ # So a field definition :
25
+ #
26
+ # journey_plan_form_field name: :run_time, category: :select_option
27
+ #
28
+ # Would also require a select dropdown helper method called options_for_select_run_time, for example,
29
+ # in our Form we could do something like:
30
+ #
31
+ # def options_for_select_run_time
32
+ # options_for_select(run_times, run_times)
33
+ # end
34
+ #
35
+ # private
36
+ #
37
+ # def run_times
38
+ # @run_times ||= %w[PyTorch TensorFlow TensorRT]
39
+ # end
40
+ #
41
+ enum category: [:string, :select_option, :text_area, :number, :date ]
42
+ # :check_box, :radio_button, password range date time datetime_local month week search email telephone url color }
43
+
44
+ scope :for_form_and_field, ->(form_name, field_name) {
45
+ page_state = DatashiftJourney::Collector::FormDefinition.where('state = ?', form_name).first
46
+ return nil unless page_state
47
+ page_state.form_fields.where('name = ?', field_name).first
48
+ }
49
+
50
+ # TODO - revisit snippets
51
+ #
52
+ # many :snippets, class_name: 'FieldSnippet', foreign_key: :form_field_id, dependent: :destroy
53
+ # has_many :field_snippets, foreign_key: :form_field_id
54
+ # has_many :snippets, through: :field_snippets # , foreign_key: :page_state_id
55
+ # def question
56
+ # Snippet.to_sentance(snippets)
57
+ # end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,65 @@
1
+ module DatashiftJourney
2
+ # This handles supplying data for a SUMMARY or REVIEW page or e.g. an email contaning a summary,
3
+ # usually as the key/value data, associated with an Enrollment state.
4
+ #
5
+ # N.B - Our state engine collector the state of the journey (not essentially the state of the journey_plan), hence a state
6
+ # is more analogous to Page
7
+ # So here review data is assigned for DATA collected DURING a particular state - effectively the data
8
+ # saved during the UPDATE on that State
9
+ #
10
+ class JourneyReview
11
+
12
+ extend PrepareDataForReview
13
+ include PrepareDataForReview
14
+
15
+ attr_reader :journey_plan, :root_i18n_scope
16
+ delegate :state, :state_name, to: :journey_plans
17
+
18
+ # This class can be reused anywhere that requires yaml-parsed summary data for an journey_plan.
19
+ # Hence the root_i18n_scope specifies the scope under which there must be a :common key at
20
+ # least. It is recommended that the root_i18n_scopeis a folder under a config/locales
21
+ # directory containing at least a common.en.yml file, and probably organisation-
22
+ # specific yml files too, which override common sections (see #prepare_review_data_list).
23
+ def initialize(journey_plan, root_i18n_scope = '.journey_plan_review')
24
+ @journey_plan = journey_plan
25
+ @root_i18n_scope = root_i18n_scope
26
+ end
27
+
28
+ # Merge common 'sections' in the review data with any app-specific
29
+ # sections; if an app-specific section matches by heading (title) then it replaces
30
+ # the standard one. In this way apps can override discrete sections
31
+ # in the summary data.
32
+ #
33
+ def prepare_review_data_list
34
+ merged_sections = common_sections.each_with_index do |common_section, idx|
35
+ replacement = organisation_specific_sections.find do |org_specific_section|
36
+ org_specific_section.heading == common_section.heading
37
+ end
38
+ common_sections[idx] = replacement if replacement
39
+ end
40
+ merged_sections
41
+ end
42
+
43
+ private
44
+
45
+ def common_sections
46
+ @common_sections ||= prepare_from_locale(journey_plan, common_i18n_key)
47
+ end
48
+
49
+ def app_specific_sections
50
+ @app_specific_review_data ||= begin
51
+ prepare_from_locale(journey_plan, app_type_i18n_key)
52
+ end
53
+ end
54
+
55
+ # e.g. ".journey_plan_review"
56
+ def common_i18n_key
57
+ root_i18n_scope.to_s
58
+ end
59
+
60
+ # e.g. ".journey_plan_review.limited_company"
61
+ def app_type_i18n_key
62
+ "#{root_i18n_scope}.#{@journey_plan.app.type_name}"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,32 @@
1
+ module DatashiftJourney
2
+
3
+ class ReviewDataSection
4
+
5
+ attr_accessor :heading
6
+ attr_accessor :rows
7
+
8
+ # :link_state - The target url for Change This. If not specified, defaults to the section page/state
9
+ # Supports :none to leave column empty
10
+ #
11
+ Struct.new('ReviewDataRow', :title, :data, :link_state, :link_title, :heading) do
12
+ def target(journey_plan)
13
+ return nil if link_state.to_sym == :none
14
+ DatashiftJourney::Engine.routes.url_helpers.review_state_path(link_state, journey_plan)
15
+ end
16
+ end
17
+
18
+ def initialize(heading)
19
+ @heading = heading
20
+ @rows = []
21
+ end
22
+
23
+ # Add a new row to this Section. Returns the ReviewDataRow created
24
+ def add(title, data, link_state, link_title)
25
+ rows << Struct::ReviewDataRow.new(title, data, link_state, link_title, heading)
26
+ rows.last
27
+ end
28
+
29
+ delegate :size, :empty?, to: :rows
30
+
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module DatashiftJourney
2
+ module Collector
3
+ class PageStateSerializer < ActiveModel::Serializer
4
+ attributes :id, :form_name, :created_at
5
+
6
+ link(:self) {page_state_url(object) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module StateMachines
2
+ class StateSerializer < ActiveModel::Serializer
3
+ attributes :name, :value, :initial
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ <header class="text">
2
+ <h1 class="form-title heading-large" id="groupLabel"><%= form.model.header %></h1>
3
+ </header>
4
+
5
+ <fieldset>
6
+
7
+ <% form.model.form_fields.each do |ff| %>
8
+ <%= fields_for :data_nodes do |d| %>
9
+ <legend class="visuallyhidden"><%= ff.question %></legend>
10
+ <%= d.label ff.field, ff.question, class: 'form-label' %>
11
+ <%= d.text_field :field, class: 'form-control form-control-char-50' %>
12
+ <% end %>
13
+ <% end %>
14
+ </fieldset>
@@ -0,0 +1,13 @@
1
+ <% content_for :page_title, create_title('global.401_unauthorized.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.401_unauthorized.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%= t 'global.401_unauthorized.message1' %></p>
12
+
13
+ <p style="max-width: 30em;"><%=t 'global.401_unauthorized.message2'%></p>
@@ -0,0 +1,13 @@
1
+ <% content_for :page_title, create_title('global.403_forbidden.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.403_forbidden.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%=t 'global.403_forbidden.message1'%></p>
12
+
13
+ <p style="max-width: 30em;"><%=t 'global.403_forbidden.message2'%></p>
@@ -0,0 +1,13 @@
1
+ <% content_for :page_title, create_title('global.404_notfound.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.404_notfound.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%=t 'global.404_notfound.message1'%></p>
12
+
13
+ <p style="max-width: 30em;"><%=t 'global.404_notfound.message2'%></p>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title, create_title('global.422_unprocessable_entity.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.422_unprocessable_entity.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%=t 'global.422_unprocessable_entity.message1'%></p>
@@ -0,0 +1,13 @@
1
+ <% content_for :page_title, create_title('global.500_internal_server_error.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.500_internal_server_error.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%=t 'global.500_internal_server_error.message1'%></p>
12
+
13
+ <p style="max-width: 30em;"><%=t 'global.500_internal_server_error.message2'%></p>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title, create_title('global.503_bad_gateway.heading') + " (#{response.status})" %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top:30px; margin-bottom:15px;">
7
+ <%=t 'global.503_bad_gateway.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p style="max-width: 30em;"><%=t 'global.503_bad_gateway.message1'%></p>
@@ -0,0 +1,14 @@
1
+ <% content_for :page_title, create_title('global.invalid_authenticity_token.heading') %>
2
+
3
+ <%= yield :error_header %>
4
+
5
+ <header>
6
+ <h1 style="font-size: 48px; font-weight:bold; margin-top: 30px; margin-bottom: 15px;">
7
+ <%=t 'global.invalid_authenticity_token.heading'%>
8
+ </h1>
9
+ </header>
10
+
11
+ <p>
12
+ <%= t 'global.invalid_authenticity_token.message_html',
13
+ link: link_to('cookies', main_app.page_path('cookies')) %>
14
+ </p>
@@ -0,0 +1,5 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <div class="field">
4
+ COMPLETE - there are no further pages defined
5
+ </div>
@@ -0,0 +1,5 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <div class="field">
4
+ COMPLETE - there are no further pages defined
5
+ </div>
@@ -0,0 +1,14 @@
1
+ <%= render 'datashift_journey/shared/errors', form: form %>
2
+ <%= render 'datashift_journey/state_jumper/toolbar' %>
3
+
4
+ <% state = journey_plan.state %>
5
+
6
+ <% url = local_assigns[:form_url] ? form_url : datashift_journey.edit_journey_plan_path %>
7
+ <% method = local_assigns[:form_method] ? form_method : :post %>
8
+
9
+ <%= form_for form, as: state, url: url, method: method, class: 'form' do |f| %>
10
+
11
+ <%= hidden_field_tag "rendered_state", local_assigns[:rendered_state] || state %>
12
+
13
+ <%= render_if_exists state, form: form, f: f, journey_plan: journey_plan %>
14
+ <% end %>
@@ -0,0 +1,24 @@
1
+ <% ids = form.definition.field_ids %>
2
+
3
+ <% key = form.params_key %>
4
+
5
+ <% form.journey_plan.data_nodes.select { |dn| ids.include?(dn.form_field_id) }.sort.each_with_index do |data_node, i| %>
6
+ <%= f.fields_for :data_nodes, data_node do |a| %>
7
+
8
+ <% name = data_node.form_field.name %>
9
+
10
+ <div class="form-group">
11
+ <%= a.label name %>
12
+ <%= hidden_field_tag "#{key}[data_nodes][form_field][#{i}]", name %>
13
+
14
+ <% if data_node.form_field.select_option? %>
15
+ <%= select_tag "#{key}[data_nodes][field_value][#{i}]", form.send("options_for_select_#{name}"), { class: 'form-control', required: true } %>
16
+ <% elsif data_node.form_field.number? %>
17
+ <%= number_field_tag "#{key}[data_nodes][field_value][#{i}]", data_node.field_value, { class: 'form-control', required: true } %>
18
+ <% else %>
19
+ <%= text_field_tag "#{key}[data_nodes][field_value][#{i}]", data_node.field_value, size: "64", class: "form-control", required: true %>
20
+ <% end %>
21
+
22
+ </div>
23
+ <% end %>
24
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= render 'form',
2
+ form: form,
3
+ journey_plan: journey_plan,
4
+ form_method: :patch,
5
+ form_url: datashift_journey.journey_plan_path(journey_plan)
6
+ %>
@@ -0,0 +1,6 @@
1
+ <%= render 'form',
2
+ form: form,
3
+ journey_plan: journey_plan,
4
+ form_url: url_for(:controller => 'journey_plans', :action => 'create')
5
+ %>
6
+
@@ -0,0 +1,6 @@
1
+ <% css = local_assigns[:form_group_css] ? form_group_css : "col pull-right" %>
2
+
3
+ <div class="form-group <%= css %>">
4
+ <%= f.submit t('.', :default => t("global.continue")), class: "journey-plans-submit-button" %>
5
+ <%= back_a_state_link(@journey_plan) %>
6
+ </div>
@@ -0,0 +1,19 @@
1
+ <% errors = form.errors || [] %>
2
+
3
+ <% if errors.size > 0 %>
4
+ <div class="error-summary" role="group" aria-labelledby="groupLabel" tabindex="-1">
5
+
6
+ <h1 class="heading-medium error-summary-heading" id="error-summary-heading">
7
+ <%= t '.you_have' %> <%= pluralize(errors.count, "error") %>
8
+ </h1>
9
+
10
+ <ul class="error-summary-list">
11
+ <% errors.each do |attr, msg| %>
12
+ <li>
13
+ <%= link_to msg.html_safe, "##{error_link_id(attr)}", class: "error-text" %>
14
+ </li>
15
+ <% end %>
16
+ </ul>
17
+ </div>
18
+ <% end %>
19
+
@@ -0,0 +1,5 @@
1
+ <% css = local_assigns[:form_group_css] ? form_group_css : "col pull-right" %>
2
+
3
+ <div class="form-group <%= css %>">
4
+ <%= f.submit t('.', :default => t("global.continue")), class: "journey-plans-submit-button" %>
5
+ </div>
@@ -0,0 +1,16 @@
1
+ <%
2
+ if( Rails.env.development? &&
3
+ DatashiftJourney::Configuration.call.add_state_jumper_toolbar &&
4
+ DatashiftJourney::Configuration.call.state_jumper_states.size > 0)
5
+ %>
6
+ <%- content_for :datashift_journey_state_jumper do %>
7
+ <div id="datashift_journey_state_jumper">
8
+ <ul>
9
+ <li>DS Journey State Jumper: </li>
10
+ <% DatashiftJourney::Configuration.call.state_jumper_states.each do |entry| %>
11
+ <li> <%= link_to entry.display, datashift_journey.build_and_display_path(entry.state, entry.factory) %></li>
12
+ <% end %>
13
+ </ul>
14
+ </div>
15
+ <% end %>
16
+ <% end %>
@@ -0,0 +1,42 @@
1
+ {
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "Cross Site Scripting",
5
+ "warning_code": 4,
6
+ "fingerprint": "f1fc7068ce25236b1c6f9b137081e044d819fbbc32cb0a5100e86720cd10ba96",
7
+ "message": "Unsafe parameter value in link_to href",
8
+ "file": "app/views/datashift_journey/addresses/edit.html.erb",
9
+ "line": 4,
10
+ "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
11
+ "code": "link_to(\"Show\", datashift_journey.address_path(DatashiftJourney::Address.find(params[:id])))",
12
+ "render_path": ["DatashiftJourney::AddressesController#edit"],
13
+ "location": {
14
+ "type": "template",
15
+ "template": "datashift_journey/addresses/edit (DatashiftJourney::AddressesController#edit)"
16
+ },
17
+ "user_input": "params",
18
+ "confidence": "Medium",
19
+ "note": "Ideally we would pass the instance of @address directly to link_to however because of the namespacing we have to call address_path passing the instance to that. It is still not a user entered value hence this is a false positive by brakeman."
20
+ },
21
+ {
22
+ "warning_type": "Cross Site Scripting",
23
+ "warning_code": 4,
24
+ "fingerprint": "49f08e33accfe24201463ed567cc259387b05b215fdab284d03697d01e013ca1",
25
+ "message": "Unsafe parameter value in link_to href",
26
+ "file": "app/views/datashift_journey/addresses/show.html.erb",
27
+ "line": 2,
28
+ "link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
29
+ "code": "link_to(\"Edit\", datashift_journey.edit_address_path(DatashiftJourney::Address.find(params[:id])))",
30
+ "render_path": ["DatashiftJourney::AddressesController#show"],
31
+ "location": {
32
+ "type": "template",
33
+ "template": "datashift_journey/addresses/show (DatashiftJourney::AddressesController#show)"
34
+ },
35
+ "user_input": "params",
36
+ "confidence": "Medium",
37
+ "note": "Ideally we would pass the instance of @address directly to link_to however because of the namespacing we have to call address_path passing the instance to that. It is still not a user entered value hence this is a false positive by brakeman."
38
+ }
39
+ ],
40
+ "updated": "2015-06-26 15:03:34 +0100",
41
+ "brakeman_version": "3.0.3"
42
+ }
@@ -0,0 +1,103 @@
1
+ # i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
2
+
3
+ # The "main" locale.
4
+ base_locale: en
5
+ ## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
6
+ # locales: [es, fr]
7
+ ## Reporting locale, default: en. Available: en, ru.
8
+ # internal_locale: en
9
+
10
+ # Read and write translations.
11
+ data:
12
+ ## Translations are read from the file system. Supported format: YAML, JSON.
13
+ ## Provide a custom adapter:
14
+ # adapter: I18n::Tasks::Data::FileSystem
15
+
16
+ # Locale files or `File.find` patterns where translations are read from:
17
+ read:
18
+ ## Default:
19
+ - config/locales/%{locale}.yml
20
+ ## More files:
21
+ - config/locales/**/*.%{locale}.yml
22
+ - spec/dummy/config/locales/%{locale}.yml
23
+ ## Another gem:
24
+ # - "<%= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
25
+
26
+ # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
27
+ # `i18n-tasks normalize -p` will force move the keys according to these rules
28
+ write:
29
+ ## For example, write devise and simple form keys to their respective files:
30
+ # - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
31
+ ## Catch-all default:
32
+ # - config/locales/%{locale}.yml
33
+
34
+ ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
35
+ # router: convervative_router
36
+
37
+ yaml:
38
+ write:
39
+ # do not wrap lines at 80 characters
40
+ line_width: -1
41
+
42
+ ## Pretty-print JSON:
43
+ # json:
44
+ # write:
45
+ # indent: ' '
46
+ # space: ' '
47
+ # object_nl: "\n"
48
+ # array_nl: "\n"
49
+
50
+ # Find translate calls
51
+ search:
52
+ ## Paths or `File.find` patterns to search in:
53
+ # paths:
54
+ # - app/
55
+
56
+ ## Root directories for relative keys resolution.
57
+ # relative_roots:
58
+ # - app/views
59
+ # - app/controllers
60
+ # - app/helpers
61
+ # - app/presenters
62
+
63
+ ## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
64
+ ## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
65
+ exclude:
66
+ - app/assets/images
67
+ - app/assets/fonts
68
+
69
+ ## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
70
+ ## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
71
+ # include: ["*.rb", "*.html.slim"]
72
+
73
+ ## Default scanner finds t() and I18n.t() calls.
74
+ # scanner: I18n::Tasks::Scanners::PatternWithScopeScanner
75
+
76
+ ## Google Translate
77
+ # translation:
78
+ # # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
79
+ # api_key: "AbC-dEf5"
80
+
81
+ ## Do not consider these keys missing:
82
+ # ignore_missing:
83
+ # - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
84
+ # - '{devise,simple_form}.*'
85
+
86
+ ## Consider these keys used:
87
+ # ignore_unused:
88
+ # - 'activerecord.attributes.*'
89
+ # - '{devise,kaminari,will_paginate}.*'
90
+ # - 'simple_form.{yes,no}'
91
+ # - 'simple_form.{placeholders,hints,labels}.*'
92
+ # - 'simple_form.{error_notification,required}.:'
93
+
94
+ ## Exclude these keys from the `i18n-tasks eq-base' report:
95
+ # ignore_eq_base:
96
+ # all:
97
+ # - common.ok
98
+ # fr,es:
99
+ # - common.brand
100
+
101
+ ## Ignore these keys completely:
102
+ # ignore:
103
+ # - kaminari.*
@@ -0,0 +1,3 @@
1
+ unless Rails.application.config.consider_all_requests_local
2
+ Rails.application.config.exceptions_app = DatashiftJourney::Engine.routes
3
+ end
@@ -0,0 +1 @@
1
+ Mime::Type.register "application/vnd.api+json", :json
@@ -0,0 +1,14 @@
1
+ Rswag::Api.configure do |c|
2
+
3
+ # Specify a root folder where Swagger JSON files are located
4
+ # This is used by the Swagger middleware to serve requests for API descriptions
5
+ # NOTE: We are using rswag-specs to generate Swagger, sp this PATH is duplicated in spec/swagger_helper.rb
6
+
7
+ c.swagger_root = File.join(DatashiftJourney::Engine.root, 'spec', 'swagger')
8
+
9
+ # Inject a lamda function to alter the returned Swagger prior to serialization
10
+ # The function will have access to the rack env for the current request
11
+ # For example, you could leverage this to dynamically assign the "host" property
12
+ #
13
+ #c.swagger_filter = lambda { |swagger, env| swagger['host'] = env['HTTP_HOST'] }
14
+ end
@@ -0,0 +1,9 @@
1
+ Rswag::Ui.configure do |c|
2
+
3
+ # List the Swagger endpoints that you want to be documented through the swagger-ui
4
+ # The first parameter is the path (absolute or relative to the UI host) to the corresponding
5
+ # JSON endpoint and the second is a title that will be displayed in the document selector
6
+ # NOTE: If you're using rspec-api to expose Swagger files (under swagger_root) as JSON endpoints,
7
+ # then the list below should correspond to the relative paths for those endpoints
8
+ c.swagger_endpoint '/api-docs/v1/swagger.json', 'API V1 Docs'
9
+ end