datashift_journey 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +391 -0
- data/Rakefile +26 -0
- data/app/assets/stylesheets/datashift_journey/partials/_state_jumper_toolbar.scss.erb +27 -0
- data/app/controllers/concerns/datashift_journey/error_renderer.rb +9 -0
- data/app/controllers/concerns/datashift_journey/review_renderer.rb +21 -0
- data/app/controllers/concerns/datashift_journey/token_based_access.rb +23 -0
- data/app/controllers/concerns/datashift_journey/validate_state.rb +59 -0
- data/app/controllers/datashift_journey/abandon_enrollments_controller.rb +14 -0
- data/app/controllers/datashift_journey/abandonments_controller.rb +17 -0
- data/app/controllers/datashift_journey/api/v1/states_controller.rb +49 -0
- data/app/controllers/datashift_journey/application_controller.rb +53 -0
- data/app/controllers/datashift_journey/errors_controller.rb +24 -0
- data/app/controllers/datashift_journey/journey_ends_controller.rb +19 -0
- data/app/controllers/datashift_journey/journey_plans_controller.rb +166 -0
- data/app/controllers/datashift_journey/page_states_controller.rb +49 -0
- data/app/controllers/datashift_journey/reviews_controller.rb +32 -0
- data/app/controllers/datashift_journey/state_jumper_controller.rb +51 -0
- data/app/factories/datashift_journey/form_object_factory.rb +68 -0
- data/app/forms/datashift_journey/collector/base_collector_form.rb +60 -0
- data/app/forms/datashift_journey/concerns/form_mixin.rb +64 -0
- data/app/forms/datashift_journey/null_form.rb +20 -0
- data/app/helpers/datashift_journey/application_helper.rb +50 -0
- data/app/helpers/datashift_journey/back_link_helper.rb +9 -0
- data/app/models/datashift_journey/collector/data_node.rb +18 -0
- data/app/models/datashift_journey/collector/form_definition.rb +35 -0
- data/app/models/datashift_journey/collector/form_field.rb +61 -0
- data/app/models/datashift_journey/journey_review.rb +65 -0
- data/app/models/datashift_journey/review_data_section.rb +32 -0
- data/app/serializers/datashift_journey/collector/page_state_serializer.rb +9 -0
- data/app/serializers/state_machines/state/state_serializer.rb +5 -0
- data/app/views/datashift_journey/collector/_generic_form.html.erb +14 -0
- data/app/views/datashift_journey/errors/401.html.erb +13 -0
- data/app/views/datashift_journey/errors/403.html.erb +13 -0
- data/app/views/datashift_journey/errors/404.html.erb +13 -0
- data/app/views/datashift_journey/errors/422.html.erb +11 -0
- data/app/views/datashift_journey/errors/500.html.erb +13 -0
- data/app/views/datashift_journey/errors/503.html.erb +11 -0
- data/app/views/datashift_journey/errors/invalid_authenticity_token.html.erb +14 -0
- data/app/views/datashift_journey/journey_ends/new.html.erb +5 -0
- data/app/views/datashift_journey/journey_ends/show.html.erb +5 -0
- data/app/views/datashift_journey/journey_plans/_form.html.erb +14 -0
- data/app/views/datashift_journey/journey_plans/_render_fields.html.erb +24 -0
- data/app/views/datashift_journey/journey_plans/edit.html.erb +6 -0
- data/app/views/datashift_journey/journey_plans/new.html.erb +6 -0
- data/app/views/datashift_journey/shared/_default_actions.html.erb +6 -0
- data/app/views/datashift_journey/shared/_errors.html.erb +19 -0
- data/app/views/datashift_journey/shared/_submit_action.html.erb +5 -0
- data/app/views/datashift_journey/state_jumper/_toolbar.html.erb +16 -0
- data/config/brakeman.ignore +42 -0
- data/config/i18n-tasks.yml +103 -0
- data/config/initializers/exceptions_app.rb +3 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/rswag-api.rb +14 -0
- data/config/initializers/rswag-ui.rb +9 -0
- data/config/locales/en.yml +39 -0
- data/config/routes.rb +44 -0
- data/lib/datashift_journey/collector/field_snippet.rb +12 -0
- data/lib/datashift_journey/collector/page_state_snippet.rb +12 -0
- data/lib/datashift_journey/collector/snippet.rb +14 -0
- data/lib/datashift_journey/configuration.rb +103 -0
- data/lib/datashift_journey/engine.rb +38 -0
- data/lib/datashift_journey/exceptions.rb +26 -0
- data/lib/datashift_journey/helpers/back_link.rb +58 -0
- data/lib/datashift_journey/journey/machine_builder.rb +59 -0
- data/lib/datashift_journey/prepare_data_for_review.rb +219 -0
- data/lib/datashift_journey/reference_generator.rb +51 -0
- data/lib/datashift_journey/state_machines/branch_sequence_map.rb +35 -0
- data/lib/datashift_journey/state_machines/extensions.rb +40 -0
- data/lib/datashift_journey/state_machines/planner.rb +206 -0
- data/lib/datashift_journey/state_machines/sequence.rb +86 -0
- data/lib/datashift_journey/state_machines/state_machine_core_ext.rb +72 -0
- data/lib/datashift_journey/version.rb +3 -0
- data/lib/datashift_journey.rb +57 -0
- data/lib/generators/datashift_journey/collector/collector_generator.rb +43 -0
- data/lib/generators/datashift_journey/collector/install_collector_generator.rb +61 -0
- data/lib/generators/datashift_journey/collector/install_mongo_collector_generator.rb +44 -0
- data/lib/generators/datashift_journey/collector/templates/collector_concern.rb.tt +34 -0
- data/lib/generators/datashift_journey/collector/templates/collector_migration.rb.tt +46 -0
- data/lib/generators/datashift_journey/forms_generator.rb +45 -0
- data/lib/generators/datashift_journey/generate_common.rb +33 -0
- data/lib/generators/datashift_journey/setup/USAGE +12 -0
- data/lib/generators/datashift_journey/setup/setup_generator.rb +44 -0
- data/lib/generators/datashift_journey/setup/templates/initializer.rb.tt +17 -0
- data/lib/generators/datashift_journey/setup/templates/model_concern.rb.tt +37 -0
- data/lib/generators/datashift_journey/templates/base_form.rb.tt +7 -0
- data/lib/generators/datashift_journey/templates/collector_form.rb.tt +18 -0
- data/lib/generators/datashift_journey/templates/collector_view.rb.tt +15 -0
- data/lib/generators/datashift_journey/templates/journey_plan_form.rb.tt +23 -0
- data/lib/generators/datashift_journey/templates/journey_plan_view.rb.tt +15 -0
- data/lib/generators/datashift_journey/views_generator.rb +35 -0
- data/lib/tasks/state_machine.thor +48 -0
- data/spec/datashift_journey/complex_journey_spec.rb +132 -0
- data/spec/datashift_journey/machine_builder_spec.rb +268 -0
- data/spec/datashift_journey/planner_spec.rb +129 -0
- data/spec/datashift_journey/sequence_spec.rb +20 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +16 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/forms/base_form.rb +8 -0
- data/spec/dummy/app/forms/business_details_form.rb +17 -0
- data/spec/dummy/app/forms/business_type_form.rb +17 -0
- data/spec/dummy/app/forms/contact_details_form.rb +17 -0
- data/spec/dummy/app/forms/enter_reg_number_form.rb +17 -0
- data/spec/dummy/app/forms/new_or_renew_form.rb +17 -0
- data/spec/dummy/app/forms/postal_address_form.rb +17 -0
- data/spec/dummy/app/forms/question1_form.rb +9 -0
- data/spec/dummy/app/forms/question2_form.rb +12 -0
- data/spec/dummy/app/forms/sole_trader_name_form.rb +17 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/payment.rb +5 -0
- data/spec/dummy/app/services/datashift_journey/models/collector_journey.rb +51 -0
- data/spec/dummy/app/views/_question1.html.erb +13 -0
- data/spec/dummy/app/views/_question2.html.erb +9 -0
- data/spec/dummy/app/views/layouts/alternative.html.erb +14 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/pages/home.html.erb +6 -0
- data/spec/dummy/app/views/pages/start.html.erb +5 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config/application.rb +39 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +47 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +47 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/datashift_journey.rb +6 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +27 -0
- data/spec/dummy/config/routes.rb +28 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20160101091218_create_dummy_checkout.rb +43 -0
- data/spec/dummy/db/migrate/20161221100703_datashift_journey_create_collector.rb +56 -0
- data/spec/dummy/db/schema.rb +142 -0
- data/spec/dummy/lib/version.rb +1 -0
- data/spec/factories/collector_factory.rb +16 -0
- data/spec/factories/collector_snippet_factory.rb +9 -0
- data/spec/factories/collector_state_page_factory.rb +12 -0
- data/spec/factories/data_node_factory.rb +9 -0
- data/spec/factories/form_factory.rb +6 -0
- data/spec/features/basic_navigation_spec.rb +125 -0
- data/spec/helpers/application_helper_spec.rb +40 -0
- data/spec/integration/collector/page_state_spec.rb +45 -0
- data/spec/models/collector/collector_spec.rb +100 -0
- data/spec/models/collector/page_state_spec.rb +30 -0
- data/spec/rails_helper.rb +73 -0
- data/spec/requests/collector/api/v1/page_state_spec.rb +85 -0
- data/spec/requests/collector/api/v1/states_spec.rb +28 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/support/asserts.rb +27 -0
- data/spec/support/mailer_macros.rb +25 -0
- data/spec/support/page_objects/base_page_object.rb +77 -0
- data/spec/swagger_helper.rb +25 -0
- metadata +425 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
class DatashiftJourneyCreateCollector < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
|
4
|
+
# The Container - one per journey - in most situations this would belong to a user account
|
5
|
+
# of person logged in and taking journey
|
6
|
+
|
7
|
+
create_table :dsj_collectors do |t|
|
8
|
+
t.string :state, index: true, null: false
|
9
|
+
t.string :reference, index: true, unique: true, null: false
|
10
|
+
t.timestamps null: false
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table :dsj_page_states do |t|
|
14
|
+
t.string :form_name, index: true, null: false
|
15
|
+
t.timestamps null: false
|
16
|
+
end
|
17
|
+
|
18
|
+
create_table :dsj_form_fields do |t|
|
19
|
+
t.references :page_state, index: true, null: false
|
20
|
+
t.string :field, index: true, null: false, :limit => 100
|
21
|
+
t.string :field_type, null: false
|
22
|
+
t.string :field_presentation, limit: 100
|
23
|
+
t.timestamps null: false
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table :dsj_collectors_data_nodes do |t|
|
27
|
+
t.references :collector, null: false
|
28
|
+
t.references :form_field, null: false
|
29
|
+
t.text :field_value
|
30
|
+
t.timestamps null: false
|
31
|
+
end
|
32
|
+
|
33
|
+
create_table :dsj_snippets do |t|
|
34
|
+
t.text :raw_text
|
35
|
+
t.string :I18n_key, index: true
|
36
|
+
t.timestamps null: false
|
37
|
+
end
|
38
|
+
|
39
|
+
create_table :dsj_page_states_snippets do |t|
|
40
|
+
t.references :page_state, null: false
|
41
|
+
t.references :snippet, null: false
|
42
|
+
end
|
43
|
+
|
44
|
+
create_table :dsj_fields_snippets do |t|
|
45
|
+
t.references :form_field, null: false
|
46
|
+
t.references :snippet, null: false
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
add_foreign_key :collectors_data_nodes, :dsj_collectors, column: :form_field_id
|
51
|
+
|
52
|
+
add_index :dsj_collectors_data_nodes, [:collector_id, :form_field_id], unique: true,
|
53
|
+
name: 'collectors_data_nodes_collector_id_form_field_id'
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 20161221100703) do
|
14
|
+
|
15
|
+
create_table "addresses", force: :cascade do |t|
|
16
|
+
t.string "premises", limit: 200
|
17
|
+
t.string "street_address", limit: 160
|
18
|
+
t.string "locality", limit: 70
|
19
|
+
t.string "city", limit: 30
|
20
|
+
t.string "postcode", limit: 8
|
21
|
+
t.string "country_iso", limit: 3
|
22
|
+
t.datetime "created_at", null: false
|
23
|
+
t.datetime "updated_at", null: false
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table "datashift_journey_checkout_as", force: :cascade do |t|
|
27
|
+
t.string "checkout_a"
|
28
|
+
t.datetime "created_at", null: false
|
29
|
+
t.datetime "updated_at", null: false
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table "datashift_journey_checkout_bs", force: :cascade do |t|
|
33
|
+
t.string "checkout_b"
|
34
|
+
t.datetime "created_at", null: false
|
35
|
+
t.datetime "updated_at", null: false
|
36
|
+
end
|
37
|
+
|
38
|
+
create_table "datashift_journey_checkout_cs", force: :cascade do |t|
|
39
|
+
t.string "checkout_c"
|
40
|
+
t.datetime "created_at", null: false
|
41
|
+
t.datetime "updated_at", null: false
|
42
|
+
end
|
43
|
+
|
44
|
+
create_table "datashift_journey_checkout_ds", force: :cascade do |t|
|
45
|
+
t.string "checkout_d"
|
46
|
+
t.datetime "created_at", null: false
|
47
|
+
t.datetime "updated_at", null: false
|
48
|
+
end
|
49
|
+
|
50
|
+
create_table "datashift_journey_checkout_empties", force: :cascade do |t|
|
51
|
+
t.string "checkout_empty"
|
52
|
+
t.datetime "created_at", null: false
|
53
|
+
t.datetime "updated_at", null: false
|
54
|
+
end
|
55
|
+
|
56
|
+
create_table "datashift_journey_checkout_es", force: :cascade do |t|
|
57
|
+
t.string "checkout_e"
|
58
|
+
t.datetime "created_at", null: false
|
59
|
+
t.datetime "updated_at", null: false
|
60
|
+
end
|
61
|
+
|
62
|
+
create_table "datashift_journey_checkout_fs", force: :cascade do |t|
|
63
|
+
t.string "checkout_f"
|
64
|
+
t.datetime "created_at", null: false
|
65
|
+
t.datetime "updated_at", null: false
|
66
|
+
end
|
67
|
+
|
68
|
+
create_table "datashift_journey_checkouts", force: :cascade do |t|
|
69
|
+
t.string "state"
|
70
|
+
t.datetime "created_at", null: false
|
71
|
+
t.datetime "updated_at", null: false
|
72
|
+
t.string "token"
|
73
|
+
t.integer "bill_address_id"
|
74
|
+
t.integer "ship_address_id"
|
75
|
+
t.integer "payment_id"
|
76
|
+
t.index ["bill_address_id"], name: "index_datashift_journey_checkouts_on_bill_address_id"
|
77
|
+
t.index ["payment_id"], name: "index_datashift_journey_checkouts_on_payment_id"
|
78
|
+
t.index ["ship_address_id"], name: "index_datashift_journey_checkouts_on_ship_address_id"
|
79
|
+
end
|
80
|
+
|
81
|
+
create_table "datashift_journey_payments", force: :cascade do |t|
|
82
|
+
t.string "name"
|
83
|
+
t.string "card"
|
84
|
+
t.datetime "created_at", null: false
|
85
|
+
t.datetime "updated_at", null: false
|
86
|
+
end
|
87
|
+
|
88
|
+
create_table "dsj_collectors", force: :cascade do |t|
|
89
|
+
t.string "state", null: false
|
90
|
+
t.string "reference", null: false
|
91
|
+
t.datetime "created_at", null: false
|
92
|
+
t.datetime "updated_at", null: false
|
93
|
+
t.index ["reference"], name: "index_dsj_collectors_on_reference"
|
94
|
+
t.index ["state"], name: "index_dsj_collectors_on_state"
|
95
|
+
end
|
96
|
+
|
97
|
+
create_table "dsj_collectors_data_nodes", force: :cascade do |t|
|
98
|
+
t.integer "collector_id", null: false
|
99
|
+
t.integer "form_field_id", null: false
|
100
|
+
t.text "field_value"
|
101
|
+
t.datetime "created_at", null: false
|
102
|
+
t.datetime "updated_at", null: false
|
103
|
+
t.index ["collector_id", "form_field_id"], name: "collectors_data_nodes_collector_id_form_field_id", unique: true
|
104
|
+
end
|
105
|
+
|
106
|
+
create_table "dsj_fields_snippets", force: :cascade do |t|
|
107
|
+
t.integer "form_field_id", null: false
|
108
|
+
t.integer "snippet_id", null: false
|
109
|
+
end
|
110
|
+
|
111
|
+
create_table "dsj_form_fields", force: :cascade do |t|
|
112
|
+
t.integer "page_state_id", null: false
|
113
|
+
t.string "field", limit: 100, null: false
|
114
|
+
t.string "field_type", null: false
|
115
|
+
t.string "field_presentation", limit: 100
|
116
|
+
t.datetime "created_at", null: false
|
117
|
+
t.datetime "updated_at", null: false
|
118
|
+
t.index ["field"], name: "index_dsj_form_fields_on_field"
|
119
|
+
t.index ["page_state_id"], name: "index_dsj_form_fields_on_page_state_id"
|
120
|
+
end
|
121
|
+
|
122
|
+
create_table "dsj_page_states", force: :cascade do |t|
|
123
|
+
t.string "form_name", null: false
|
124
|
+
t.datetime "created_at", null: false
|
125
|
+
t.datetime "updated_at", null: false
|
126
|
+
t.index ["form_name"], name: "index_dsj_page_states_on_form_name"
|
127
|
+
end
|
128
|
+
|
129
|
+
create_table "dsj_page_states_snippets", force: :cascade do |t|
|
130
|
+
t.integer "page_state_id", null: false
|
131
|
+
t.integer "snippet_id", null: false
|
132
|
+
end
|
133
|
+
|
134
|
+
create_table "dsj_snippets", force: :cascade do |t|
|
135
|
+
t.text "raw_text"
|
136
|
+
t.string "I18n_key"
|
137
|
+
t.datetime "created_at", null: false
|
138
|
+
t.datetime "updated_at", null: false
|
139
|
+
t.index ["I18n_key"], name: "index_dsj_snippets_on_I18n_key"
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = "0.0.1".freeze
|
@@ -0,0 +1,16 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :collector, class: DatashiftJourney::Collector::Collector do
|
3
|
+
reference FFaker::Product.model
|
4
|
+
# N.B state must be a valid state from the defined journey
|
5
|
+
# state :new_or_renew
|
6
|
+
|
7
|
+
# TODO: - Good way to define a journey for RSepc
|
8
|
+
# DatashiftJourney::Journey::MachineBuilder.create_journey_plan(initial: :new_or_renew) do
|
9
|
+
#
|
10
|
+
# branch_sequence :new_sequence, [:business_type]
|
11
|
+
#
|
12
|
+
# branch_sequence :renew_sequence, [:enter_reg_number]
|
13
|
+
# ...
|
14
|
+
# end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :collector_page_state, class: DatashiftJourney::Collector::PageState do
|
3
|
+
form_name { FFaker::Book.title }
|
4
|
+
|
5
|
+
trait :with_snippets do
|
6
|
+
after(:create) do |object|
|
7
|
+
object.snippets = create_list(:snippet, 3)
|
8
|
+
object.save!
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
module DatashiftJourney
|
3
|
+
|
4
|
+
RSpec.describe 'Basic Navigation Feature' do
|
5
|
+
before(:all) do
|
6
|
+
DatashiftJourney.journey_plan_class = 'DatashiftJourney::Collector::Collector'
|
7
|
+
end
|
8
|
+
|
9
|
+
scenario 'home page' do
|
10
|
+
visit root_path
|
11
|
+
expect(page).to have_text 'New or renew'
|
12
|
+
end
|
13
|
+
|
14
|
+
scenario 'move on from home page by clicking Continue' do
|
15
|
+
visit root_path
|
16
|
+
click_button('Continue')
|
17
|
+
expect(page).to have_text 'New or renew'
|
18
|
+
end
|
19
|
+
|
20
|
+
scenario 'move on from home page by clicking Continue' do
|
21
|
+
visit root_path
|
22
|
+
fill_in 'data_nodes_field', with: "My Company Name"
|
23
|
+
click_button('Continue')
|
24
|
+
expect(page).to have_text 'Business type'
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# scenario "happy path straight through Other journey and back" do
|
29
|
+
# journey.each_with_index do |po, _i|
|
30
|
+
# po.advance_page
|
31
|
+
# po
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# expect(page).to be_on_page_object reviewing_page
|
35
|
+
#
|
36
|
+
# (journey.size..0).each do |i|
|
37
|
+
# click_link(I18n.t("back"))
|
38
|
+
# expect(page).to be_on_page_object journey[i]
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# context "Given I'm on the Correspondence (Main) Contact Email page" do
|
44
|
+
# before(:each) do
|
45
|
+
# page_object.visit_page
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# scenario "When I enter my valid email address" do
|
49
|
+
# page_object.advance_page
|
50
|
+
# expect(Enrollment.last.correspondence_contact.email_address).to eq page_object.field_filled_wth
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# context "When revisiting this page (after a succesful submission), via back button or review page " do
|
55
|
+
# scenario "Then the email confirmation field should display the current email" do
|
56
|
+
# page_object.advance_page
|
57
|
+
#
|
58
|
+
# expect(page).to_not be_on_page_object page_object
|
59
|
+
#
|
60
|
+
# page_object.click_back_link
|
61
|
+
#
|
62
|
+
# expect(page).to be_on_page_object page_object
|
63
|
+
#
|
64
|
+
# page_object.confirmation_field_matches_email
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# scenario "Then if I don't enter an email in correct format, Then I expect to see error" do
|
68
|
+
# page_object.advance_page
|
69
|
+
#
|
70
|
+
# expect(page).to_not be_on_page_object page_object
|
71
|
+
#
|
72
|
+
# page_object.click_back_link
|
73
|
+
#
|
74
|
+
# ["t@", "@env.com", "e@e"].each do |e|
|
75
|
+
# page_object.advance_page_with e
|
76
|
+
# expect(page).to be_on_page_object page_object
|
77
|
+
#
|
78
|
+
# expect(page).to have_text I18n.t("#{form_class.locale_key}.errors.email_address.format")
|
79
|
+
#
|
80
|
+
# expect(page).to have_error_anchors :email_address
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# context "Validation" do
|
86
|
+
# scenario "When I don't enter an email, Then I expect to see error" do
|
87
|
+
# page_object.advance_page_with("")
|
88
|
+
# expect(page).to be_on_page_object page_object
|
89
|
+
#
|
90
|
+
# expect(page).to have_text I18n.t("#{form_class.locale_key}.errors.email_address.blank")
|
91
|
+
#
|
92
|
+
# expect(page).to have_error_anchors :email_address
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# scenario "When I don't enter an email in correct format, Then I expect to see error" do
|
96
|
+
# ["t@", "@env.com", "e@e"].each do |e|
|
97
|
+
# page_object.advance_page_with e
|
98
|
+
# expect(page).to be_on_page_object page_object
|
99
|
+
#
|
100
|
+
# expect(page).to have_text I18n.t("#{form_class.locale_key}.errors.email_address.format")
|
101
|
+
#
|
102
|
+
# expect(page).to have_error_anchors :email_address
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# scenario "When I don't enter a confirmation, Then I expect to see error" do
|
107
|
+
# page_object.advance_page_with(page_object.generate_data, "")
|
108
|
+
# expect(page).to be_on_page_object page_object
|
109
|
+
#
|
110
|
+
# expect(page).to have_text I18n.t("#{form_class.locale_key}.errors.email_address_confirmation.blank")
|
111
|
+
#
|
112
|
+
# expect(page).to have_error_anchors :email_address_confirmation
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# scenario "When I don't enter a confirmation that matches email, Then I expect to see error" do
|
116
|
+
# page_object.advance_page_with(page_object.generate_data, "blah#{Time.current}@blah.co.uk")
|
117
|
+
# expect(page).to be_on_page_object page_object
|
118
|
+
#
|
119
|
+
# expect(page).to have_text I18n.t("#{form_class.locale_key}.errors.email_address_confirmation.format")
|
120
|
+
#
|
121
|
+
# expect(page).to have_error_anchors :email_address_confirmation
|
122
|
+
# end
|
123
|
+
# end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe DatashiftJourney::ApplicationHelper, type: :helper do
|
4
|
+
describe '#journey_plan_partial_location' do
|
5
|
+
it 'returns partial location for a state' do
|
6
|
+
state = 'site_address'
|
7
|
+
DatashiftJourney::Configuration.call.partial_location = ''
|
8
|
+
expect(helper.journey_plan_partial_location(state)).to eq "/#{state}"
|
9
|
+
|
10
|
+
DatashiftJourney::Configuration.call.partial_location = nil
|
11
|
+
expect(helper.journey_plan_partial_location(state)).to eq "/#{state}"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns partial location, correctly joining paths for a state' do
|
15
|
+
state = 'site_address'
|
16
|
+
DatashiftJourney::Configuration.call.partial_location = 'shared/states'
|
17
|
+
expect(helper.journey_plan_partial_location(state)).to eq "shared/states/#{state}"
|
18
|
+
|
19
|
+
DatashiftJourney::Configuration.call.partial_location = 'states/'
|
20
|
+
expect(helper.journey_plan_partial_location(state)).to eq "states/#{state}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#error_link_anchor' do
|
25
|
+
it 'still returns basic string from empty string' do
|
26
|
+
attribute = ''
|
27
|
+
expect(helper.error_link_id(attribute)).to eq 'form_group_'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns attribute from plain attribute' do
|
31
|
+
attribute = 'full_name'
|
32
|
+
expect(helper.error_link_id(attribute)).to eq 'form_group_full_name'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns field only from nested attribute' do
|
36
|
+
attribute = 'journey_plan.applicant_contact.full_name'
|
37
|
+
expect(helper.error_link_id(attribute)).to eq 'form_group_full_name'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'swagger_helper'
|
3
|
+
|
4
|
+
require 'page_state'
|
5
|
+
|
6
|
+
module DatashiftJourney
|
7
|
+
describe Collector::PageState do
|
8
|
+
|
9
|
+
path '/api/v1/page_states' do
|
10
|
+
|
11
|
+
post 'Creates a page_state' do
|
12
|
+
tags 'PageState'
|
13
|
+
consumes 'application/json', 'application/xml'
|
14
|
+
parameter name: :page_state, in: :body, schema: {
|
15
|
+
type: :object,
|
16
|
+
properties: {
|
17
|
+
form_name: { type: :string }
|
18
|
+
},
|
19
|
+
required: [ 'form_name' ]
|
20
|
+
}
|
21
|
+
|
22
|
+
response '201', 'page_state created' do
|
23
|
+
let(:page_state) { { form_name: 'BrandNewPage' } }
|
24
|
+
|
25
|
+
#before do |example|
|
26
|
+
# pp example.metadata
|
27
|
+
#end
|
28
|
+
|
29
|
+
pending("can rwsag support modules?")
|
30
|
+
# To fix - does not seem to handle namespaces
|
31
|
+
# Failure/Error: raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
|
32
|
+
# LoadError:
|
33
|
+
# Unable to autoload constant PageState, expected /data/users/thomas.statter/SoftwareDev/git/datashift_journey/lib/datashift_journey/collector/page_state.rb to define it
|
34
|
+
#run_test!
|
35
|
+
end
|
36
|
+
|
37
|
+
response '422', 'invalid request' do
|
38
|
+
let(:page_state) { { for: 'foo' } }
|
39
|
+
#run_test!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module DatashiftJourney
|
4
|
+
RSpec.describe Collector::Collector, type: :model do
|
5
|
+
context('Empty') do
|
6
|
+
let(:collector) { create(:collector, state: :contact_details) }
|
7
|
+
|
8
|
+
it { is_expected.to have_many(:form_fields).dependent(false) }
|
9
|
+
it { is_expected.to have_many(:data_nodes).dependent(:destroy) }
|
10
|
+
|
11
|
+
it 'can save nodes for any given PageState and Field', duff: true do
|
12
|
+
name_field = Collector::FormField.new(
|
13
|
+
page_state: create(:collector_page_state),
|
14
|
+
field: :name,
|
15
|
+
field_presentation: 'Enter your Name',
|
16
|
+
field_type: :string
|
17
|
+
)
|
18
|
+
|
19
|
+
expect(name_field).to be_valid
|
20
|
+
|
21
|
+
collector.form_fields << name_field
|
22
|
+
collector.save
|
23
|
+
collector.reload
|
24
|
+
expect(collector.form_fields.size).to eq 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context('Populated') do
|
29
|
+
let(:collector) { create(:collector) }
|
30
|
+
|
31
|
+
let(:page_state) { Collector::PageState.create(form_name: 'BusinessDetailsForm') }
|
32
|
+
|
33
|
+
let(:page_snippet) {
|
34
|
+
Collector::FieldSnippet.create(
|
35
|
+
form_field: page_state,
|
36
|
+
snippet: Collector::Snippet.create(raw_text: 'Enter your Company Name')
|
37
|
+
)
|
38
|
+
}
|
39
|
+
|
40
|
+
let(:form_field) do
|
41
|
+
Collector::FormField.create(
|
42
|
+
page_state: page_state,
|
43
|
+
field: :company_name,
|
44
|
+
field_presentation: 'Enter your Company Name',
|
45
|
+
field_type: :string
|
46
|
+
)
|
47
|
+
end
|
48
|
+
let(:email_form_field) do
|
49
|
+
Collector::FormField.create(
|
50
|
+
page_state: page_state,
|
51
|
+
field: :company_email,
|
52
|
+
field_presentation: 'Enter your Company Email',
|
53
|
+
field_type: :string
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
context('PageState Fields') do
|
58
|
+
before(:each) do
|
59
|
+
collector.form_fields << form_field
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns the node for a given PageState and Field', duff: true do
|
63
|
+
node = collector.node_for_form_and_field('BusinessDetailsForm', 'company_name')
|
64
|
+
expect(node).to be_a Collector::CollectorDataNode
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'can store multiple Fields against the same PageState' do
|
68
|
+
collector.form_fields << Collector::FormField.create(
|
69
|
+
page_state: page_state,
|
70
|
+
field: :company_email,
|
71
|
+
field_presentation: 'Enter your Company Email',
|
72
|
+
field_type: :string
|
73
|
+
)
|
74
|
+
|
75
|
+
collector.reload
|
76
|
+
expect(collector.form_fields.size).to eq 2
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context('Populated - Data Nodes') do
|
81
|
+
it 'can store store data against a Field in a DataNode' do
|
82
|
+
email = FFaker::Internet.email
|
83
|
+
collector.data_nodes.create(form_field: email_form_field, field_value: email)
|
84
|
+
|
85
|
+
collector.reload
|
86
|
+
expect(collector.form_fields.size).to eq 1
|
87
|
+
|
88
|
+
expect(collector.form_fields.first.page_state.form_name).to eq 'BusinessDetailsForm'
|
89
|
+
|
90
|
+
data_nodes = collector.nodes_for_form('BusinessDetailsForm')
|
91
|
+
|
92
|
+
expect(data_nodes).to be_a Array
|
93
|
+
expect(data_nodes.size).to eq 1
|
94
|
+
|
95
|
+
expect(data_nodes.first.field_value).to eq email
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
module DatashiftJourney
|
4
|
+
module Collector
|
5
|
+
RSpec.describe PageState, type: :model do
|
6
|
+
context('Empty') do
|
7
|
+
let(:collector) { create(:collector, state: :contact_details) }
|
8
|
+
|
9
|
+
it { is_expected.to have_many(:snippets).dependent(false) }
|
10
|
+
|
11
|
+
it { is_expected.to validate_presence_of(:form_name) }
|
12
|
+
|
13
|
+
it 'is valid when the associated Form name supplied' do
|
14
|
+
business_details_form = PageState.new(form_name: 'BusinessDetailsForm')
|
15
|
+
expect(business_details_form).to be_valid
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context('Populated') do
|
20
|
+
let(:page_state) { create(:collector_page_state, :with_snippets) }
|
21
|
+
|
22
|
+
it 'returns the snippets as a single header paragraph' do
|
23
|
+
expect(page_state.snippets.size).to eq 3
|
24
|
+
expect(page_state.header).to include page_state.snippets.first.raw_text
|
25
|
+
expect(page_state.header).to include page_state.snippets.last.raw_text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV['RAILS_ENV'] ||= 'test'
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# Load support files
|
6
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
StateMachines::Machine.ignore_method_conflicts = true
|
10
|
+
|
11
|
+
config.use_transactional_fixtures = false
|
12
|
+
|
13
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
14
|
+
# based on their file location, for example enabling you to call `get` and
|
15
|
+
# `post` in specs under `spec/controllers`.
|
16
|
+
#
|
17
|
+
# You can disable this behaviour by removing the line below, and instead
|
18
|
+
# explicitly tag your specs with their type, e.g.:
|
19
|
+
#
|
20
|
+
# RSpec.describe UsersController, :type => :controller do
|
21
|
+
# # ...
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# The different available types are documented in the features, such as in
|
25
|
+
# https://relishapp.com/rspec/rspec-rails/docs
|
26
|
+
config.infer_spec_type_from_file_location!
|
27
|
+
|
28
|
+
config.include FactoryGirl::Syntax::Methods
|
29
|
+
|
30
|
+
ActiveRecord::Migration.maintain_test_schema!
|
31
|
+
|
32
|
+
# Use seed data in some places rather than Factories so don't clean
|
33
|
+
# certain 'static' tables
|
34
|
+
config.before(:suite) do
|
35
|
+
DatabaseCleaner.strategy = :truncation
|
36
|
+
DatabaseCleaner.clean_with :truncation, except: %w(ar_internal_metadata)
|
37
|
+
# DatabaseCleaner.clean
|
38
|
+
end
|
39
|
+
|
40
|
+
config.before do |example|
|
41
|
+
md = example.metadata
|
42
|
+
DatabaseCleaner.strategy = :transaction
|
43
|
+
|
44
|
+
Capybara.current_driver =
|
45
|
+
if md[:driver].present?
|
46
|
+
md[:driver]
|
47
|
+
elsif md[:js] || md[:javascript]
|
48
|
+
:poltergeist
|
49
|
+
else
|
50
|
+
:rack_test
|
51
|
+
end
|
52
|
+
|
53
|
+
unless Capybara.current_driver == :rack_test
|
54
|
+
DatabaseCleaner.strategy = :truncation, DB_CLEANER_TRUNCATION_OPTS
|
55
|
+
end
|
56
|
+
|
57
|
+
DatabaseCleaner.start
|
58
|
+
end
|
59
|
+
|
60
|
+
config.after do
|
61
|
+
DatabaseCleaner.clean_with :truncation, except: %w(ar_internal_metadata)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Enables shortcut, t() instead of I18n.t() in tests
|
65
|
+
config.include AbstractController::Translation
|
66
|
+
end
|
67
|
+
|
68
|
+
Shoulda::Matchers.configure do |config|
|
69
|
+
config.integrate do |with|
|
70
|
+
with.test_framework :rspec
|
71
|
+
with.library :rails
|
72
|
+
end
|
73
|
+
end
|