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,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