decidim-forms 0.19.1 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
- data/app/assets/config/admin/decidim_forms_manifest.js +1 -0
- data/app/assets/config/decidim_forms_manifest.css +1 -0
- data/app/assets/images/decidim/surveys/icon.svg +1 -19
- data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
- data/app/assets/javascripts/decidim/forms/admin/collapsible_questions.js.es6 +13 -0
- data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +260 -16
- data/app/assets/javascripts/decidim/forms/admin/live_text_update.component.js.es6 +52 -0
- data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
- data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +204 -0
- data/app/assets/javascripts/decidim/forms/forms.js.es6 +49 -1
- data/app/assets/javascripts/decidim/forms/max_choices_alert.component.js.es6 +44 -0
- data/app/assets/stylesheets/decidim/forms/forms.scss +39 -0
- data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
- data/app/cells/decidim/forms/matrix_readonly/show.erb +5 -0
- data/app/cells/decidim/forms/matrix_readonly_cell.rb +12 -0
- data/app/cells/decidim/forms/question_readonly/show.erb +5 -1
- data/app/cells/decidim/forms/question_readonly_cell.rb +5 -0
- data/app/cells/decidim/forms/step_navigation/show.erb +35 -0
- data/app/cells/decidim/forms/step_navigation_cell.rb +46 -0
- data/app/commands/decidim/forms/admin/update_questionnaire.rb +33 -1
- data/app/commands/decidim/forms/answer_questionnaire.rb +7 -2
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +52 -2
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
- data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +58 -2
- data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
- data/app/forms/decidim/forms/admin/question_form.rb +21 -1
- data/app/forms/decidim/forms/admin/question_matrix_row_form.rb +26 -0
- data/app/forms/decidim/forms/answer_choice_form.rb +1 -0
- data/app/forms/decidim/forms/answer_form.rb +31 -2
- data/app/forms/decidim/forms/questionnaire_form.rb +33 -3
- data/app/helpers/decidim/forms/admin/application_helper.rb +37 -0
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
- data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +27 -0
- data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
- data/app/models/decidim/forms/answer.rb +2 -5
- data/app/models/decidim/forms/answer_choice.rb +7 -0
- data/app/models/decidim/forms/answer_option.rb +14 -0
- data/app/models/decidim/forms/display_condition.rb +51 -0
- data/app/models/decidim/forms/question.rb +52 -2
- data/app/models/decidim/forms/question_matrix_row.rb +15 -0
- data/app/models/decidim/forms/questionnaire.rb +13 -2
- data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
- data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
- data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
- data/app/presenters/decidim/forms/question_presenter.rb +16 -0
- data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
- data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
- data/app/queries/decidim/forms/questionnaire_user_answers.rb +1 -1
- data/app/types/decidim/forms/answer_option_type.rb +14 -0
- data/app/types/decidim/forms/question_type.rb +23 -0
- data/app/types/decidim/forms/questionnaire_type.rb +22 -0
- data/app/views/decidim/forms/admin/questionnaires/_answer_option_template.html.erb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
- data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
- data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +67 -8
- data/app/views/decidim/forms/admin/questionnaires/_matrix_row.html.erb +34 -0
- data/app/views/decidim/forms/admin/questionnaires/_matrix_row_template.html.erb +7 -0
- data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +45 -6
- data/app/views/decidim/forms/admin/questionnaires/_separator.html.erb +41 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
- data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
- data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
- data/app/views/decidim/forms/questionnaires/_answer.html.erb +28 -99
- data/app/views/decidim/forms/questionnaires/answers/_long_answer.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_matrix_multiple.html.erb +43 -0
- data/app/views/decidim/forms/questionnaires/answers/_matrix_single.html.erb +43 -0
- data/app/views/decidim/forms/questionnaires/answers/_multiple_option.html.erb +23 -0
- data/app/views/decidim/forms/questionnaires/answers/_separator.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_short_answer.html.erb +1 -0
- data/app/views/decidim/forms/questionnaires/answers/_single_option.html.erb +30 -0
- data/app/views/decidim/forms/questionnaires/answers/_sorting.html.erb +23 -0
- data/app/views/decidim/forms/questionnaires/show.html.erb +81 -28
- data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
- data/config/initializers/wicked_pdf.rb +25 -0
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/ar.yml +12 -4
- data/config/locales/bg-BG.yml +14 -0
- data/config/locales/bg.yml +14 -0
- data/config/locales/ca.yml +98 -8
- data/config/locales/cs.yml +94 -4
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +92 -4
- data/config/locales/el-GR.yml +1 -0
- data/config/locales/el.yml +118 -0
- data/config/locales/en.yml +94 -4
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +94 -4
- data/config/locales/es-PY.yml +94 -4
- data/config/locales/es.yml +94 -4
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/et.yml +1 -0
- data/config/locales/eu.yml +7 -4
- data/config/locales/fi-plain.yml +94 -4
- data/config/locales/fi.yml +94 -4
- data/config/locales/fr-CA.yml +172 -0
- data/config/locales/fr.yml +94 -4
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/gl.yml +7 -4
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +16 -4
- data/config/locales/id-ID.yml +7 -4
- data/config/locales/is-IS.yml +1 -0
- data/config/locales/is.yml +1 -0
- data/config/locales/it.yml +95 -5
- data/config/locales/ja-JP.yml +170 -0
- data/config/locales/ja.yml +170 -0
- data/config/locales/ko-KR.yml +1 -0
- data/config/locales/ko.yml +1 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lt.yml +1 -0
- data/config/locales/lv.yml +118 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +97 -7
- data/config/locales/no.yml +98 -1
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +113 -26
- data/config/locales/pt-BR.yml +8 -5
- data/config/locales/pt.yml +111 -24
- data/config/locales/ro-RO.yml +167 -0
- data/config/locales/ru.yml +4 -2
- data/config/locales/sk-SK.yml +88 -0
- data/config/locales/sk.yml +90 -0
- data/config/locales/sl.yml +12 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sr-CS.yml +1 -0
- data/config/locales/sv.yml +91 -4
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +7 -4
- data/config/locales/vi-VN.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +172 -0
- data/config/locales/zh-TW.yml +1 -0
- data/db/migrate/20190315203056_add_session_token_to_decidim_forms_answers.rb +17 -0
- data/db/migrate/20190930094710_add_ip_hash_to_decidim_form_answers.rb +12 -0
- data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
- data/db/migrate/20200225123810_create_decidim_forms_question_matrix_rows.rb +11 -0
- data/db/migrate/20200304152939_add_matrix_row_id_to_decidim_forms_answer_choices.rb +11 -0
- data/lib/decidim/api/questionnaire_entity_interface.rb +18 -0
- data/lib/decidim/exporters/form_pdf.rb +33 -0
- data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
- data/lib/decidim/forms.rb +6 -0
- data/lib/decidim/forms/admin_engine.rb +1 -1
- data/lib/decidim/forms/api.rb +7 -0
- data/lib/decidim/forms/test.rb +6 -0
- data/lib/decidim/forms/test/factories.rb +80 -6
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +924 -66
- data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +33 -575
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
- data/lib/decidim/forms/user_answers_serializer.rb +23 -4
- data/lib/decidim/forms/version.rb +1 -1
- metadata +136 -9
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "add display conditions" do
|
6
|
+
context "when adding display conditions to a question" do
|
7
|
+
let!(:answer_options) do
|
8
|
+
3.times.to_a.map do |x|
|
9
|
+
{
|
10
|
+
"body" => Decidim::Faker::Localized.sentence,
|
11
|
+
"free_text" => x == 2
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when questionnaire has only one question" do
|
17
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, body: body, question_type: "short_answer") }
|
18
|
+
|
19
|
+
before do
|
20
|
+
visit_questionnaire_edit_path_and_expand_all
|
21
|
+
end
|
22
|
+
|
23
|
+
it "doesn't display an add display condition button" do
|
24
|
+
expect(page).to have_no_button("Add display condition")
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when creating a new question" do
|
28
|
+
it "disables the add display condition button if the question hasn't been saved" do
|
29
|
+
within "form.edit_questionnaire" do
|
30
|
+
click_button "Add question"
|
31
|
+
expand_all_questions
|
32
|
+
|
33
|
+
expect(page).to have_button("Add display condition", disabled: true)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when questionnaire has more than one question" do
|
40
|
+
let!(:question_short_answer) do
|
41
|
+
create(:questionnaire_question,
|
42
|
+
questionnaire: questionnaire,
|
43
|
+
body: Decidim::Faker::Localized.sentence,
|
44
|
+
question_type: "short_answer")
|
45
|
+
end
|
46
|
+
let!(:question_long_answer) do
|
47
|
+
create(:questionnaire_question,
|
48
|
+
questionnaire: questionnaire,
|
49
|
+
body: Decidim::Faker::Localized.sentence,
|
50
|
+
question_type: "long_answer")
|
51
|
+
end
|
52
|
+
let!(:question_single_option) do
|
53
|
+
create(:questionnaire_question,
|
54
|
+
questionnaire: questionnaire,
|
55
|
+
body: Decidim::Faker::Localized.sentence,
|
56
|
+
question_type: "single_option",
|
57
|
+
options: answer_options)
|
58
|
+
end
|
59
|
+
let!(:question_multiple_option) do
|
60
|
+
create(:questionnaire_question,
|
61
|
+
questionnaire: questionnaire,
|
62
|
+
body: Decidim::Faker::Localized.sentence,
|
63
|
+
question_type: "multiple_option",
|
64
|
+
options: answer_options)
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:questions) { [question_short_answer, question_long_answer, question_single_option, question_multiple_option] }
|
68
|
+
|
69
|
+
before do
|
70
|
+
visit_questionnaire_edit_path_and_expand_all
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when clicking add display condition button" do
|
74
|
+
it "adds a new display condition form with all correct elements" do
|
75
|
+
within "form.edit_questionnaire" do
|
76
|
+
within_add_display_condition do
|
77
|
+
expect(page).to have_select("Question")
|
78
|
+
expect(page).to have_select("Condition")
|
79
|
+
expect(page).to have_selector("[id$=mandatory]")
|
80
|
+
|
81
|
+
select question_single_option.body["en"], from: "Question"
|
82
|
+
select "Answered", from: "Condition"
|
83
|
+
|
84
|
+
expect(page).to have_no_select("Answer option")
|
85
|
+
expect(page).to have_no_css("[id$=condition_value_en]", visible: :visible)
|
86
|
+
|
87
|
+
select question_single_option.body["en"], from: "Question"
|
88
|
+
select "Equal", from: "Condition"
|
89
|
+
|
90
|
+
expect(page).to have_select("Answer option")
|
91
|
+
expect(page).to have_no_css("[id$=condition_value_en]", visible: :visible)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "fills condition_question select with saved questions from questionnaire" do
|
97
|
+
within_add_display_condition do
|
98
|
+
options = questions.map { |question| question["body"]["en"] }
|
99
|
+
options << "Select a question"
|
100
|
+
expect(page).to have_select("Question", options: options)
|
101
|
+
|
102
|
+
within "select[id$=decidim_condition_question_id]" do
|
103
|
+
elements = page.all("option[data-type]")
|
104
|
+
expect(elements.map { |element| element[:"data-type"] }).to eq(questions.map(&:question_type))
|
105
|
+
expect(page.find("option[value='#{questions.last.id}']")).to be_disabled
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when a text question is selected" do
|
111
|
+
it "fills condition_type select with correct options" do
|
112
|
+
within_add_display_condition do
|
113
|
+
select question_short_answer.body["en"], from: "Question"
|
114
|
+
|
115
|
+
options = ["Select a condition type", "Answered", "Not answered", "Includes text"]
|
116
|
+
|
117
|
+
option_elements = page.all("select[id$=condition_type] option")
|
118
|
+
option_elements = option_elements.to_a.reject { |option| option[:style].match? "display: none" }
|
119
|
+
|
120
|
+
expect(option_elements.map(&:text)).to eq(options)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when an options question is selected" do
|
126
|
+
it "fills condition_type select with correct options" do
|
127
|
+
within_add_display_condition do
|
128
|
+
select question_single_option.body["en"], from: "Question"
|
129
|
+
|
130
|
+
options = ["Select a condition type", "Answered", "Not answered", "Equal", "Not equal", "Includes text"]
|
131
|
+
|
132
|
+
option_elements = page.all("select[id$=condition_type] option")
|
133
|
+
option_elements = option_elements.to_a.reject { |option| option[:style].match? "display: none" }
|
134
|
+
|
135
|
+
expect(option_elements.map(&:text)).to eq(options)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "fills answer_options select with correct options" do
|
141
|
+
within_add_display_condition do
|
142
|
+
select question_single_option.body["en"], from: "Question"
|
143
|
+
select "Equal", from: "Condition"
|
144
|
+
|
145
|
+
options = answer_options.map { |option| option["body"]["en"] }
|
146
|
+
options << "Select answer option"
|
147
|
+
|
148
|
+
expect(page).to have_select("Answer option", options: options, wait: 5)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it "loads an empty value field" do
|
153
|
+
within_add_display_condition do
|
154
|
+
select question_single_option.body["en"], from: "Question"
|
155
|
+
select "Includes text", from: "Condition"
|
156
|
+
expect(page).to have_nested_field("condition_value_en", with: "")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
it "loads a mandatory field with false value" do
|
161
|
+
within_add_display_condition do
|
162
|
+
expect(page).to have_selector("[id$=mandatory]")
|
163
|
+
expect(page).to have_no_selector("[id$=mandatory][checked]")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it "can be removed" do
|
168
|
+
within_add_display_condition do
|
169
|
+
click_button "Remove"
|
170
|
+
end
|
171
|
+
|
172
|
+
click_button "Save"
|
173
|
+
|
174
|
+
expect(page).to have_admin_callout("successfully")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,463 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "add questions" do
|
6
|
+
it "adds a few questions and separators to the questionnaire" do
|
7
|
+
questions_body = ["This is the first question", "This is the second question"]
|
8
|
+
|
9
|
+
within "form.edit_questionnaire" do
|
10
|
+
click_button "Add question"
|
11
|
+
click_button "Add separator"
|
12
|
+
click_button "Add question"
|
13
|
+
|
14
|
+
expect(page).to have_selector(".questionnaire-question", count: 3)
|
15
|
+
|
16
|
+
expand_all_questions
|
17
|
+
|
18
|
+
page.all(".questionnaire-question .collapsible").each_with_index do |question, idx|
|
19
|
+
within question do
|
20
|
+
fill_in find_nested_form_field_locator("body_en"), with: questions_body[idx]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
click_button "Save"
|
25
|
+
end
|
26
|
+
|
27
|
+
expect(page).to have_admin_callout("successfully")
|
28
|
+
|
29
|
+
visit_questionnaire_edit_path_and_expand_all
|
30
|
+
|
31
|
+
expect(page).to have_selector("input[value='This is the first question']")
|
32
|
+
expect(page).to have_selector("input[value='This is the second question']")
|
33
|
+
expect(page).to have_content("Separator #2")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "adds a question with a rich text description" do
|
37
|
+
within "form.edit_questionnaire" do
|
38
|
+
click_button "Add question"
|
39
|
+
expand_all_questions
|
40
|
+
|
41
|
+
within ".questionnaire-question" do
|
42
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Body"
|
43
|
+
|
44
|
+
fill_in_editor find_nested_form_field_locator("description_en", visible: false), with: "<b>Superkalifragilistic description</b>"
|
45
|
+
end
|
46
|
+
|
47
|
+
click_button "Save"
|
48
|
+
end
|
49
|
+
|
50
|
+
expect(page).to have_admin_callout("successfully")
|
51
|
+
|
52
|
+
component.update!(
|
53
|
+
step_settings: {
|
54
|
+
component.participatory_space.active_step.id => {
|
55
|
+
allow_answers: true
|
56
|
+
}
|
57
|
+
}
|
58
|
+
)
|
59
|
+
|
60
|
+
visit questionnaire_public_path
|
61
|
+
|
62
|
+
expect(page).to have_selector("strong", text: "Superkalifragilistic description")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "adds a question with answer options" do
|
66
|
+
question_body = ["This is the first question", "This is the second question"]
|
67
|
+
answer_options_body = [
|
68
|
+
[
|
69
|
+
"This is the Q1 first option",
|
70
|
+
"This is the Q1 second option",
|
71
|
+
"This is the Q1 third option"
|
72
|
+
],
|
73
|
+
[
|
74
|
+
"This is the Q2 first option",
|
75
|
+
"This is the Q2 second option",
|
76
|
+
"This is the Q2 third option"
|
77
|
+
]
|
78
|
+
]
|
79
|
+
|
80
|
+
within "form.edit_questionnaire" do
|
81
|
+
click_button "Add question"
|
82
|
+
click_button "Add question"
|
83
|
+
expand_all_questions
|
84
|
+
|
85
|
+
page.all(".questionnaire-question").each_with_index do |question, idx|
|
86
|
+
within question do
|
87
|
+
fill_in find_nested_form_field_locator("body_en"), with: question_body[idx]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
expect(page).to have_no_content "Add answer option"
|
92
|
+
|
93
|
+
page.all(".questionnaire-question").each do |question|
|
94
|
+
within question do
|
95
|
+
select "Single option", from: "Type"
|
96
|
+
click_button "Add answer option"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
page.all(".questionnaire-question").each_with_index do |question, question_idx|
|
101
|
+
question.all(".questionnaire-question-answer-option").each_with_index do |question_answer_option, answer_option_idx|
|
102
|
+
within question_answer_option do
|
103
|
+
fill_in find_nested_form_field_locator("body_en"), with: answer_options_body[question_idx][answer_option_idx]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
click_button "Save"
|
109
|
+
end
|
110
|
+
|
111
|
+
expect(page).to have_admin_callout("successfully")
|
112
|
+
|
113
|
+
visit_questionnaire_edit_path_and_expand_all
|
114
|
+
|
115
|
+
expect(page).to have_selector("input[value='This is the first question']")
|
116
|
+
expect(page).to have_selector("input[value='This is the Q1 first option']")
|
117
|
+
expect(page).to have_selector("input[value='This is the Q1 second option']")
|
118
|
+
expect(page).to have_selector("input[value='This is the Q1 third option']")
|
119
|
+
expect(page).to have_selector("input[value='This is the second question']")
|
120
|
+
expect(page).to have_selector("input[value='This is the Q2 first option']")
|
121
|
+
expect(page).to have_selector("input[value='This is the Q2 second option']")
|
122
|
+
expect(page).to have_selector("input[value='This is the Q2 third option']")
|
123
|
+
end
|
124
|
+
|
125
|
+
it "adds a sane number of options for each attribute type" do
|
126
|
+
click_button "Add question"
|
127
|
+
expand_all_questions
|
128
|
+
|
129
|
+
select "Long answer", from: "Type"
|
130
|
+
expect(page).to have_no_selector(".questionnaire-question-answer-option")
|
131
|
+
expect(page).to have_no_selector(".questionnaire-question-matrix-row")
|
132
|
+
|
133
|
+
select "Single option", from: "Type"
|
134
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 2)
|
135
|
+
expect(page).to have_no_selector(".questionnaire-question-matrix-row")
|
136
|
+
|
137
|
+
select "Multiple option", from: "Type"
|
138
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 2)
|
139
|
+
expect(page).to have_no_selector(".questionnaire-question-matrix-row")
|
140
|
+
|
141
|
+
select "Matrix (Multiple option)", from: "Type"
|
142
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 2)
|
143
|
+
expect(page).to have_selector(".questionnaire-question-matrix-row", count: 2)
|
144
|
+
|
145
|
+
select "Short answer", from: "Type"
|
146
|
+
expect(page).to have_no_selector(".questionnaire-question-answer-option")
|
147
|
+
expect(page).to have_no_selector(".questionnaire-question-matrix-row")
|
148
|
+
|
149
|
+
select "Matrix (Single option)", from: "Type"
|
150
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 2)
|
151
|
+
expect(page).to have_selector(".questionnaire-question-matrix-row", count: 2)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "does not incorrectly reorder when clicking answer options" do
|
155
|
+
click_button "Add question"
|
156
|
+
expand_all_questions
|
157
|
+
|
158
|
+
select "Single option", from: "Type"
|
159
|
+
2.times { click_button "Add answer option" }
|
160
|
+
|
161
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
162
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
163
|
+
end
|
164
|
+
|
165
|
+
within ".questionnaire-question-answer-option:last-of-type" do
|
166
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Else"
|
167
|
+
end
|
168
|
+
|
169
|
+
# If JS events for option reordering are incorrectly bound, clicking on
|
170
|
+
# the field to gain focus can cause the options to get inverted... :S
|
171
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
172
|
+
find_nested_form_field("body_en").click
|
173
|
+
end
|
174
|
+
|
175
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
176
|
+
expect(page).to have_nested_field("body_en", with: "Something")
|
177
|
+
end
|
178
|
+
|
179
|
+
within ".questionnaire-question-answer-option:last-of-type" do
|
180
|
+
expect(page).to have_nested_field("body_en", with: "Else")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
it "does not incorrectly reorder when clicking matrix rows" do
|
185
|
+
click_button "Add question"
|
186
|
+
expand_all_questions
|
187
|
+
|
188
|
+
select "Matrix (Multiple option)", from: "Type"
|
189
|
+
2.times { click_button "Add row" }
|
190
|
+
|
191
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
192
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
193
|
+
end
|
194
|
+
|
195
|
+
within ".questionnaire-question-matrix-row:last-of-type" do
|
196
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Else"
|
197
|
+
end
|
198
|
+
|
199
|
+
# If JS events for option reordering are incorrectly bound, clicking on
|
200
|
+
# the field to gain focus can cause the options to get inverted... :S
|
201
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
202
|
+
find_nested_form_field("body_en").click
|
203
|
+
end
|
204
|
+
|
205
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
206
|
+
expect(page).to have_nested_field("body_en", with: "Something")
|
207
|
+
end
|
208
|
+
|
209
|
+
within ".questionnaire-question-matrix-row:last-of-type" do
|
210
|
+
expect(page).to have_nested_field("body_en", with: "Else")
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
it "preserves question form across submission failures" do
|
215
|
+
click_button "Add question"
|
216
|
+
expand_all_questions
|
217
|
+
|
218
|
+
select "Long answer", from: "Type"
|
219
|
+
click_button "Save"
|
220
|
+
|
221
|
+
expand_all_questions
|
222
|
+
expect(page).to have_select("Type", selected: "Long answer")
|
223
|
+
end
|
224
|
+
|
225
|
+
it "does not preserve spurious answer options from previous type selections" do
|
226
|
+
click_button "Add question"
|
227
|
+
expand_all_questions
|
228
|
+
|
229
|
+
select "Single option", from: "Type"
|
230
|
+
|
231
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
232
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
233
|
+
end
|
234
|
+
|
235
|
+
select "Long answer", from: "Type"
|
236
|
+
|
237
|
+
click_button "Save"
|
238
|
+
expand_all_questions
|
239
|
+
|
240
|
+
select "Single option", from: "Type"
|
241
|
+
|
242
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
243
|
+
expect(page).to have_no_nested_field("body_en", with: "Something")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it "does not preserve spurious matrix rows from previous type selections" do
|
248
|
+
click_button "Add question"
|
249
|
+
expand_all_questions
|
250
|
+
|
251
|
+
select "Matrix (Single option)", from: "Type"
|
252
|
+
|
253
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
254
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
255
|
+
end
|
256
|
+
|
257
|
+
select "Long answer", from: "Type"
|
258
|
+
|
259
|
+
click_button "Save"
|
260
|
+
expand_all_questions
|
261
|
+
|
262
|
+
select "Matrix (Single option)", from: "Type"
|
263
|
+
|
264
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
265
|
+
expect(page).to have_no_nested_field("body_en", with: "Something")
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it "preserves answer options form across submission failures" do
|
270
|
+
click_button "Add question"
|
271
|
+
expand_all_questions
|
272
|
+
|
273
|
+
select "Multiple option", from: "Type"
|
274
|
+
|
275
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
276
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
277
|
+
end
|
278
|
+
|
279
|
+
click_button "Add answer option"
|
280
|
+
|
281
|
+
within ".questionnaire-question-answer-option:last-of-type" do
|
282
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Else"
|
283
|
+
end
|
284
|
+
|
285
|
+
select "3", from: "Maximum number of choices"
|
286
|
+
|
287
|
+
click_button "Save"
|
288
|
+
expand_all_questions
|
289
|
+
|
290
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
291
|
+
expect(page).to have_nested_field("body_en", with: "Something")
|
292
|
+
end
|
293
|
+
|
294
|
+
within ".questionnaire-question-answer-option:last-of-type" do
|
295
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Else"
|
296
|
+
end
|
297
|
+
|
298
|
+
expect(page).to have_select("Maximum number of choices", selected: "3")
|
299
|
+
end
|
300
|
+
|
301
|
+
it "preserves matrix rows form across submission failures" do
|
302
|
+
click_button "Add question"
|
303
|
+
expand_all_questions
|
304
|
+
|
305
|
+
select "Matrix (Multiple option)", from: "Type"
|
306
|
+
|
307
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
308
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Something"
|
309
|
+
end
|
310
|
+
|
311
|
+
click_button "Add row"
|
312
|
+
|
313
|
+
click_button "Save"
|
314
|
+
expand_all_questions
|
315
|
+
|
316
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
317
|
+
expect(page).to have_nested_field("body_en", with: "Something")
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
it "allows switching translated field tabs after form failures" do
|
322
|
+
click_button "Add question"
|
323
|
+
click_button "Save"
|
324
|
+
|
325
|
+
expand_all_questions
|
326
|
+
|
327
|
+
within ".questionnaire-question:first-of-type" do
|
328
|
+
fill_in find_nested_form_field_locator("body_en"), with: "Bye"
|
329
|
+
click_link "Català", match: :first
|
330
|
+
|
331
|
+
fill_in find_nested_form_field_locator("body_ca"), with: "Adeu"
|
332
|
+
click_link "English", match: :first
|
333
|
+
|
334
|
+
expect(page).to have_nested_field("body_en", with: "Bye")
|
335
|
+
expect(page).to have_no_selector(nested_form_field_selector("body_ca"))
|
336
|
+
expect(page).to have_no_content("Adeu")
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context "when adding a multiple option question" do
|
341
|
+
before do
|
342
|
+
visit questionnaire_edit_path
|
343
|
+
|
344
|
+
within "form.edit_questionnaire" do
|
345
|
+
click_button "Add question"
|
346
|
+
|
347
|
+
expand_all_questions
|
348
|
+
|
349
|
+
within ".questionnaire-question" do
|
350
|
+
fill_in find_nested_form_field_locator("body_en"), with: "This is the first question"
|
351
|
+
end
|
352
|
+
|
353
|
+
expect(page).to have_no_content "Add answer option"
|
354
|
+
expect(page).to have_no_select("Maximum number of choices")
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
it "updates the free text option selector according to the selected question type" do
|
359
|
+
expect(page).to have_no_selector("input[type=checkbox][id$=_free_text]")
|
360
|
+
|
361
|
+
select "Multiple option", from: "Type"
|
362
|
+
expect(page).to have_selector("input[type=checkbox][id$=_free_text]")
|
363
|
+
|
364
|
+
select "Short answer", from: "Type"
|
365
|
+
expect(page).to have_no_selector("input[type=checkbox][id$=_free_text]")
|
366
|
+
|
367
|
+
select "Single option", from: "Type"
|
368
|
+
expect(page).to have_selector("input[type=checkbox][id$=_free_text]")
|
369
|
+
end
|
370
|
+
|
371
|
+
it "updates the max choices selector according to the configured options" do
|
372
|
+
expect(page).to have_no_select("Maximum number of choices")
|
373
|
+
|
374
|
+
select "Multiple option", from: "Type"
|
375
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
376
|
+
|
377
|
+
click_button "Add answer option"
|
378
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3))
|
379
|
+
|
380
|
+
click_button "Add answer option"
|
381
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3 4))
|
382
|
+
|
383
|
+
within(".questionnaire-question-answer-option:last-of-type") { click_button "Remove" }
|
384
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3))
|
385
|
+
|
386
|
+
within(".questionnaire-question-answer-option:last-of-type") { click_button "Remove" }
|
387
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
388
|
+
|
389
|
+
click_button "Add question"
|
390
|
+
expand_all_questions
|
391
|
+
|
392
|
+
within(".questionnaire-question:last-of-type") do
|
393
|
+
select "Multiple option", from: "Type"
|
394
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
395
|
+
|
396
|
+
select "Single option", from: "Type"
|
397
|
+
expect(page).to have_no_select("Maximum number of choices")
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context "when adding a matrix question" do
|
403
|
+
before do
|
404
|
+
visit questionnaire_edit_path
|
405
|
+
|
406
|
+
within "form.edit_questionnaire" do
|
407
|
+
click_button "Add question"
|
408
|
+
expand_all_questions
|
409
|
+
|
410
|
+
within ".questionnaire-question" do
|
411
|
+
fill_in find_nested_form_field_locator("body_en"), with: "This is the first question"
|
412
|
+
end
|
413
|
+
|
414
|
+
expect(page).to have_no_content "Add answer option"
|
415
|
+
expect(page).to have_no_content "Add row"
|
416
|
+
expect(page).to have_no_select("Maximum number of choices")
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
it "updates the free text option selector according to the selected question type" do
|
421
|
+
expect(page).to have_no_selector("input[type=checkbox][id$=_free_text]")
|
422
|
+
|
423
|
+
select "Matrix (Multiple option)", from: "Type"
|
424
|
+
expect(page).to have_selector("input[type=checkbox][id$=_free_text]")
|
425
|
+
|
426
|
+
select "Short answer", from: "Type"
|
427
|
+
expect(page).to have_no_selector("input[type=checkbox][id$=_free_text]")
|
428
|
+
|
429
|
+
select "Matrix (Single option)", from: "Type"
|
430
|
+
expect(page).to have_selector("input[type=checkbox][id$=_free_text]")
|
431
|
+
end
|
432
|
+
|
433
|
+
it "updates the max choices selector according to the configured options" do
|
434
|
+
expect(page).to have_no_select("Maximum number of choices")
|
435
|
+
|
436
|
+
select "Matrix (Multiple option)", from: "Type"
|
437
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
438
|
+
|
439
|
+
click_button "Add answer option"
|
440
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3))
|
441
|
+
|
442
|
+
click_button "Add answer option"
|
443
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3 4))
|
444
|
+
|
445
|
+
within(".questionnaire-question-answer-option:last-of-type") { click_button "Remove" }
|
446
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2 3))
|
447
|
+
|
448
|
+
within(".questionnaire-question-answer-option:last-of-type") { click_button "Remove" }
|
449
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
450
|
+
|
451
|
+
click_button "Add question"
|
452
|
+
expand_all_questions
|
453
|
+
|
454
|
+
within(".questionnaire-question:last-of-type") do
|
455
|
+
select "Matrix (Multiple option)", from: "Type"
|
456
|
+
expect(page).to have_select("Maximum number of choices", options: %w(Any 2))
|
457
|
+
|
458
|
+
select "Matrix (Single option)", from: "Type"
|
459
|
+
expect(page).to have_no_select("Maximum number of choices")
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|