decidim-forms 0.22.0 → 0.23.0
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.
- checksums.yaml +4 -4
- data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
- data/app/assets/config/decidim_forms_manifest.css +1 -0
- data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
- data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +181 -25
- 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 +8 -1
- data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
- data/app/commands/decidim/forms/admin/update_questionnaire.rb +25 -1
- data/app/commands/decidim/forms/answer_questionnaire.rb +1 -1
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +47 -1
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
- data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
- data/app/forms/decidim/forms/admin/question_form.rb +1 -0
- data/app/forms/decidim/forms/answer_form.rb +15 -0
- data/app/helpers/decidim/forms/admin/application_helper.rb +21 -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 +0 -3
- 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 +34 -0
- data/app/models/decidim/forms/question_matrix_row.rb +3 -0
- data/app/models/decidim/forms/questionnaire.rb +11 -1
- 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/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 +30 -4
- data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +19 -3
- 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 +1 -1
- data/app/views/decidim/forms/questionnaires/show.html.erb +22 -2
- 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 +0 -1
- data/config/locales/bg-BG.yml +0 -2
- data/config/locales/bg.yml +14 -0
- data/config/locales/ca.yml +56 -4
- data/config/locales/cs.yml +54 -2
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +51 -1
- data/config/locales/el.yml +0 -2
- data/config/locales/en.yml +54 -2
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +53 -1
- data/config/locales/es-PY.yml +53 -1
- data/config/locales/es.yml +54 -2
- data/config/locales/et.yml +1 -0
- data/config/locales/eu.yml +0 -1
- data/config/locales/fi-plain.yml +53 -1
- data/config/locales/fi.yml +53 -1
- data/config/locales/fr-CA.yml +54 -2
- data/config/locales/fr.yml +54 -2
- data/config/locales/gl.yml +0 -1
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +0 -2
- data/config/locales/id-ID.yml +0 -1
- data/config/locales/is.yml +1 -0
- data/config/locales/it.yml +53 -1
- data/config/locales/ja-JP.yml +51 -1
- 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.yml +1 -0
- data/config/locales/{lv-LV.yml → lv.yml} +0 -1
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +59 -7
- data/config/locales/no.yml +47 -2
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +52 -3
- data/config/locales/pt-BR.yml +0 -1
- data/config/locales/pt.yml +51 -2
- data/config/locales/ro-RO.yml +51 -2
- data/config/locales/ru.yml +0 -1
- data/config/locales/sk.yml +0 -2
- data/config/locales/sl.yml +7 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sv.yml +51 -2
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +0 -1
- 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/20200130194123_create_decidim_forms_display_conditions.rb +20 -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 +5 -0
- data/lib/decidim/forms/admin_engine.rb +1 -1
- data/lib/decidim/forms/test.rb +6 -0
- data/lib/decidim/forms/test/factories.rb +30 -0
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +619 -38
- data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +21 -894
- 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/version.rb +1 -1
- metadata +91 -11
data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
shared_examples_for "update display conditions" do
|
|
6
|
+
context "when loading a saved display condition" do
|
|
7
|
+
let!(:condition_question_type) { "short_answer" }
|
|
8
|
+
let!(:condition_question) { create(:questionnaire_question, questionnaire: questionnaire, question_type: condition_question_type, position: 1) }
|
|
9
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, question_type: "short_answer", position: 2) }
|
|
10
|
+
let!(:condition_type) { :answered }
|
|
11
|
+
let!(:answer_option) { nil }
|
|
12
|
+
|
|
13
|
+
let!(:display_condition) do
|
|
14
|
+
create(:display_condition,
|
|
15
|
+
question: question,
|
|
16
|
+
condition_question: condition_question,
|
|
17
|
+
condition_type: condition_type,
|
|
18
|
+
answer_option: answer_option)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
before do
|
|
22
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "the related form appears" do
|
|
26
|
+
expect(page).to have_selector(".questionnaire-question-display-condition")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "loads condition_question in select" do
|
|
30
|
+
within ".questionnaire-question-display-condition" do
|
|
31
|
+
expect(page).to have_select("Question", selected: condition_question.body["en"])
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "loads condition_type in select" do
|
|
36
|
+
within ".questionnaire-question-display-condition" do
|
|
37
|
+
expect(page).to have_select("Condition", selected: "Answered")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "when condition_type is :equal" do
|
|
42
|
+
let!(:condition_question_type) { "single_option" }
|
|
43
|
+
let!(:answer_options) { create_list(:answer_option, 3, question: condition_question) }
|
|
44
|
+
let!(:answer_option) { answer_options.third }
|
|
45
|
+
let!(:condition_type) { :equal }
|
|
46
|
+
|
|
47
|
+
it "loads answer_option in select" do
|
|
48
|
+
within ".questionnaire-question-display-condition" do
|
|
49
|
+
expect(page).to have_select("Condition", selected: "Equal")
|
|
50
|
+
expect(page).to have_select("Answer option", selected: answer_option.body["en"])
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "can be removed" do
|
|
56
|
+
within ".questionnaire-question-display-condition:last-of-type" do
|
|
57
|
+
click_button "Remove"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
click_button "Save"
|
|
61
|
+
|
|
62
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
63
|
+
|
|
64
|
+
expect(page).to have_selector(".questionnaire-question-display-condition", count: 0)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "still removes the question even if previous editions rendered the conditions invalid" do
|
|
68
|
+
within "form.edit_questionnaire" do
|
|
69
|
+
expect(page).to have_selector(".questionnaire-question", count: 2)
|
|
70
|
+
|
|
71
|
+
within ".questionnaire-question-display-condition:first-of-type" do
|
|
72
|
+
select condition_question.body["en"], from: "Question"
|
|
73
|
+
select "Includes text", from: "Condition"
|
|
74
|
+
fill_in find_nested_form_field_locator("condition_value_en"), with: ""
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
within ".questionnaire-question:last-of-type" do
|
|
78
|
+
click_button "Remove", match: :first
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
click_button "Save"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
expect(page).to have_admin_callout("successfully")
|
|
85
|
+
|
|
86
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
87
|
+
|
|
88
|
+
within "form.edit_questionnaire" do
|
|
89
|
+
expect(page).to have_selector(".questionnaire-question", count: 1)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
shared_examples_for "update questions" do
|
|
6
|
+
context "when a questionnaire has an existing question" do
|
|
7
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, body: body) }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
visit questionnaire_edit_path
|
|
11
|
+
expand_all_questions
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "modifies the question when the information is valid" do
|
|
15
|
+
within "form.edit_questionnaire" do
|
|
16
|
+
within ".questionnaire-question" do
|
|
17
|
+
fill_in "questionnaire_questions_#{question.id}_body_en", with: "Modified question"
|
|
18
|
+
check "Mandatory"
|
|
19
|
+
select "Long answer", from: "Type"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
click_button "Save"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
expect(page).to have_admin_callout("successfully")
|
|
26
|
+
|
|
27
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
28
|
+
|
|
29
|
+
expect(page).to have_selector("input[value='Modified question']")
|
|
30
|
+
expect(page).to have_no_selector("input[value='This is the first question']")
|
|
31
|
+
expect(page).to have_selector("input#questionnaire_questions_#{question.id}_mandatory[checked]")
|
|
32
|
+
expect(page).to have_selector("select#questionnaire_questions_#{question.id}_question_type option[value='long_answer'][selected]")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "re-renders the form when the information is invalid and displays errors" do
|
|
36
|
+
expand_all_questions
|
|
37
|
+
|
|
38
|
+
within "form.edit_questionnaire" do
|
|
39
|
+
within ".questionnaire-question" do
|
|
40
|
+
expect(page).to have_content("Statement*")
|
|
41
|
+
fill_in "questionnaire_questions_#{question.id}_body_en", with: ""
|
|
42
|
+
check "Mandatory"
|
|
43
|
+
select "Matrix (Multiple option)", from: "Type"
|
|
44
|
+
select "2", from: "Maximum number of choices"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
click_button "Save"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
expand_all_questions
|
|
51
|
+
|
|
52
|
+
expect(page).to have_admin_callout("There was a problem saving")
|
|
53
|
+
expect(page).to have_content("can't be blank", count: 5) # emtpy question, 2 empty default answer options, 2 empty default matrix rows
|
|
54
|
+
|
|
55
|
+
expect(page).to have_selector("input[value='']")
|
|
56
|
+
expect(page).to have_no_selector("input[value='This is the first question']")
|
|
57
|
+
expect(page).to have_selector("input#questionnaire_questions_#{question.id}_mandatory[checked]")
|
|
58
|
+
expect(page).to have_select("Maximum number of choices", selected: "2")
|
|
59
|
+
expect(page).to have_selector("select#questionnaire_questions_#{question.id}_question_type option[value='matrix_multiple'][selected]")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "preserves deleted status across submission failures" do
|
|
63
|
+
within "form.edit_questionnaire" do
|
|
64
|
+
within ".questionnaire-question" do
|
|
65
|
+
click_button "Remove"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
click_button "Add question"
|
|
70
|
+
|
|
71
|
+
click_button "Save"
|
|
72
|
+
|
|
73
|
+
expect(page).to have_selector(".questionnaire-question", count: 1)
|
|
74
|
+
|
|
75
|
+
within ".questionnaire-question" do
|
|
76
|
+
expect(page).to have_selector(".card-title", text: "#1")
|
|
77
|
+
expect(page).to have_no_button("Up")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "removes the question" do
|
|
82
|
+
within "form.edit_questionnaire" do
|
|
83
|
+
within ".questionnaire-question" do
|
|
84
|
+
click_button "Remove"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
click_button "Save"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
expect(page).to have_admin_callout("successfully")
|
|
91
|
+
|
|
92
|
+
visit questionnaire_edit_path
|
|
93
|
+
|
|
94
|
+
within "form.edit_questionnaire" do
|
|
95
|
+
expect(page).to have_selector(".questionnaire-question", count: 0)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "cannot be moved up" do
|
|
100
|
+
within "form.edit_questionnaire" do
|
|
101
|
+
within ".questionnaire-question" do
|
|
102
|
+
expect(page).to have_no_button("Up")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "cannot be moved down" do
|
|
108
|
+
within "form.edit_questionnaire" do
|
|
109
|
+
within ".questionnaire-question" do
|
|
110
|
+
expect(page).to have_no_button("Down")
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "when a questionnaire has an existing question with answer options" do
|
|
117
|
+
let!(:question) do
|
|
118
|
+
create(
|
|
119
|
+
:questionnaire_question,
|
|
120
|
+
questionnaire: questionnaire,
|
|
121
|
+
body: body,
|
|
122
|
+
question_type: "single_option",
|
|
123
|
+
options: [
|
|
124
|
+
{ "body" => { "en" => "cacatua" } },
|
|
125
|
+
{ "body" => { "en" => "cat" } },
|
|
126
|
+
{ "body" => { "en" => "dog" } }
|
|
127
|
+
|
|
128
|
+
]
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
before do
|
|
133
|
+
visit questionnaire_edit_path
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "allows deleting answer options" do
|
|
137
|
+
expand_all_questions
|
|
138
|
+
|
|
139
|
+
within ".questionnaire-question-answer-option:last-of-type" do
|
|
140
|
+
click_button "Remove"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
click_button "Save"
|
|
144
|
+
|
|
145
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
146
|
+
|
|
147
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 2)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "still removes the question even if previous editions rendered the options invalid" do
|
|
151
|
+
within "form.edit_questionnaire" do
|
|
152
|
+
expect(page).to have_selector(".questionnaire-question", count: 1)
|
|
153
|
+
|
|
154
|
+
expand_all_questions
|
|
155
|
+
|
|
156
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
|
157
|
+
fill_in find_nested_form_field_locator("body_en"), with: ""
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
within ".questionnaire-question" do
|
|
161
|
+
click_button "Remove", match: :first
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
click_button "Save"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
expect(page).to have_admin_callout("successfully")
|
|
168
|
+
|
|
169
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
170
|
+
|
|
171
|
+
within "form.edit_questionnaire" do
|
|
172
|
+
expect(page).to have_selector(".questionnaire-question", count: 0)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "when a questionnaire has an existing question with matrix rows" do
|
|
178
|
+
let!(:other_question) { create(:questionnaire_question, questionnaire: questionnaire, position: 1) }
|
|
179
|
+
let!(:question) do
|
|
180
|
+
create(
|
|
181
|
+
:questionnaire_question,
|
|
182
|
+
questionnaire: questionnaire,
|
|
183
|
+
body: body,
|
|
184
|
+
question_type: "matrix_single",
|
|
185
|
+
position: 2,
|
|
186
|
+
options: [
|
|
187
|
+
{ "body" => { "en" => "cacatua" } },
|
|
188
|
+
{ "body" => { "en" => "cat" } },
|
|
189
|
+
{ "body" => { "en" => "dog" } }
|
|
190
|
+
],
|
|
191
|
+
rows: [
|
|
192
|
+
{ "body" => { "en" => "cute" } },
|
|
193
|
+
{ "body" => { "en" => "ugly" } },
|
|
194
|
+
{ "body" => { "en" => "meh" } }
|
|
195
|
+
]
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
before do
|
|
200
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "allows deleting matrix rows" do
|
|
204
|
+
within ".questionnaire-question-matrix-row:last-of-type" do
|
|
205
|
+
click_button "Remove"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
click_button "Save"
|
|
209
|
+
|
|
210
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
211
|
+
|
|
212
|
+
within ".questionnaire-question:last-of-type" do
|
|
213
|
+
expect(page).to have_selector(".questionnaire-question-matrix-row", count: 2)
|
|
214
|
+
expect(page).to have_selector(".questionnaire-question-answer-option", count: 3)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "still removes the question even if previous editions rendered the rows invalid" do
|
|
219
|
+
within "form.edit_questionnaire" do
|
|
220
|
+
expect(page).to have_selector(".questionnaire-question", count: 2)
|
|
221
|
+
|
|
222
|
+
within ".questionnaire-question-matrix-row:first-of-type" do
|
|
223
|
+
fill_in find_nested_form_field_locator("body_en"), with: ""
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
within ".questionnaire-question:last-of-type" do
|
|
227
|
+
click_button "Remove", match: :first
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
click_button "Save"
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
expect(page).to have_admin_callout("successfully")
|
|
234
|
+
|
|
235
|
+
visit_questionnaire_edit_path_and_expand_all
|
|
236
|
+
|
|
237
|
+
within "form.edit_questionnaire" do
|
|
238
|
+
expect(page).to have_selector(".questionnaire-question", count: 1)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
context "when a questionnaire has multiple existing questions" do
|
|
244
|
+
let!(:question_1) do
|
|
245
|
+
create(:questionnaire_question, questionnaire: questionnaire, body: first_body, position: 0)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
let!(:question_2) do
|
|
249
|
+
create(:questionnaire_question, questionnaire: questionnaire, body: second_body, position: 1)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
let(:first_body) do
|
|
253
|
+
{ en: "First", ca: "Primera", es: "Primera" }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
let(:second_body) do
|
|
257
|
+
{ en: "Second", ca: "Segona", es: "Segunda" }
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
before do
|
|
261
|
+
visit questionnaire_edit_path
|
|
262
|
+
expand_all_questions
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
shared_examples_for "switching questions order" do
|
|
266
|
+
it "properly reorders the questions" do
|
|
267
|
+
within ".questionnaire-question:first-of-type" do
|
|
268
|
+
expect(page).to have_nested_field("body_en", with: "Second")
|
|
269
|
+
expect(page).to look_like_first_question
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
within ".questionnaire-question:last-of-type" do
|
|
273
|
+
expect(page).to have_nested_field("body_en", with: "First")
|
|
274
|
+
expect(page).to look_like_last_question
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
context "when moving a question up" do
|
|
280
|
+
before do
|
|
281
|
+
within ".questionnaire-question:last-of-type" do
|
|
282
|
+
click_button "Up"
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it_behaves_like "switching questions order"
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context "when moving a question down" do
|
|
290
|
+
before do
|
|
291
|
+
within ".questionnaire-question:first-of-type" do
|
|
292
|
+
click_button "Down"
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it_behaves_like "switching questions order"
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
describe "collapsible questions" do
|
|
300
|
+
context "when clicking on Expand all button" do
|
|
301
|
+
it "expands all questions" do
|
|
302
|
+
click_button "Expand all questions"
|
|
303
|
+
expect(page).to have_selector(".collapsible", visible: :all)
|
|
304
|
+
expect(page).to have_selector(".question--collapse .icon-collapse", count: questionnaire.questions.count)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
context "when clicking on Collapse all button" do
|
|
309
|
+
it "collapses all questions" do
|
|
310
|
+
click_button "Collapse all questions"
|
|
311
|
+
expect(page).not_to have_selector(".collapsible", visible: :visible)
|
|
312
|
+
expect(page).to have_selector(".question--collapse .icon-expand", count: questionnaire.questions.count)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
shared_examples_for "collapsing a question" do
|
|
317
|
+
it "changes the toggle button" do
|
|
318
|
+
within ".questionnaire-question:last-of-type" do
|
|
319
|
+
expect(page).to have_selector(".icon-expand")
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
it "hides the question card section" do
|
|
324
|
+
within ".questionnaire-question:last-of-type" do
|
|
325
|
+
expect(page).not_to have_selector(".collapsible", visible: :visible)
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
shared_examples_for "uncollapsing a question" do
|
|
331
|
+
it "changes the toggle button" do
|
|
332
|
+
within ".questionnaire-question:last-of-type" do
|
|
333
|
+
expect(page).to have_selector(".icon-collapse")
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it "shows the question card section" do
|
|
338
|
+
expect(page).to have_selector(".collapsible", visible: :visible)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
context "when collapsing an existing question" do
|
|
343
|
+
before do
|
|
344
|
+
expand_all_questions
|
|
345
|
+
within ".questionnaire-question:last-of-type" do
|
|
346
|
+
page.find(".question--collapse").click
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it_behaves_like "collapsing a question"
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
context "when adding a new question" do
|
|
354
|
+
before do
|
|
355
|
+
click_button "Add question"
|
|
356
|
+
expand_all_questions
|
|
357
|
+
|
|
358
|
+
within ".questionnaire-question:last-of-type" do
|
|
359
|
+
page.find(".question--collapse").click
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it_behaves_like "collapsing a question"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
context "when submitting a new question with an error" do
|
|
367
|
+
before do
|
|
368
|
+
click_button "Add question"
|
|
369
|
+
click_button "Save"
|
|
370
|
+
|
|
371
|
+
within ".questionnaire-question:last-of-type" do
|
|
372
|
+
page.find(".question--collapse").click
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it_behaves_like "collapsing a question"
|
|
377
|
+
|
|
378
|
+
it "can be expanded" do
|
|
379
|
+
within ".questionnaire-question:last-of-type" do
|
|
380
|
+
page.find(".question--collapse").click
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
within ".questionnaire-question:last-of-type" do
|
|
384
|
+
expect(page).to have_selector(".icon-collapse")
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
it "properly decides which button to show after adding/removing questions" do
|
|
391
|
+
click_button "Add question"
|
|
392
|
+
expand_all_questions
|
|
393
|
+
|
|
394
|
+
expect(page.find(".questionnaire-question:nth-of-type(1)")).to look_like_first_question
|
|
395
|
+
expect(page.find(".questionnaire-question:nth-of-type(2)")).to look_like_intermediate_question
|
|
396
|
+
expect(page.find(".questionnaire-question:nth-of-type(3)")).to look_like_last_question
|
|
397
|
+
|
|
398
|
+
within ".questionnaire-question:first-of-type" do
|
|
399
|
+
click_button "Remove"
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
expect(page.all(".questionnaire-question").first).to look_like_first_question
|
|
403
|
+
expect(page.all(".questionnaire-question").last).to look_like_last_question
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
it "does not duplicate editors when adding new questions" do
|
|
407
|
+
expect do
|
|
408
|
+
click_button "Add question"
|
|
409
|
+
expand_all_questions
|
|
410
|
+
end.to change { page.all(".ql-toolbar").size }.by(1)
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it "properly decides which button to show after adding/removing answer options" do
|
|
414
|
+
click_button "Add question"
|
|
415
|
+
expand_all_questions
|
|
416
|
+
|
|
417
|
+
within ".questionnaire-question:last-of-type" do
|
|
418
|
+
select "Single option", from: "Type"
|
|
419
|
+
|
|
420
|
+
within ".questionnaire-question-answer-options-list" do
|
|
421
|
+
expect(page).to have_no_button("Remove")
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
click_button "Add answer option"
|
|
425
|
+
|
|
426
|
+
expect(page.all(".questionnaire-question-answer-option")).to all(have_button("Remove"))
|
|
427
|
+
|
|
428
|
+
within ".questionnaire-question-answer-option:first-of-type" do
|
|
429
|
+
click_button "Remove"
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
within ".questionnaire-question-answer-options-list" do
|
|
433
|
+
expect(page).to have_no_button("Remove")
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
click_button "Save"
|
|
438
|
+
expand_all_questions
|
|
439
|
+
|
|
440
|
+
within ".questionnaire-question:last-of-type" do
|
|
441
|
+
within ".questionnaire-question-answer-options-list" do
|
|
442
|
+
expect(page).to have_no_button("Remove")
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
private
|
|
448
|
+
|
|
449
|
+
def look_like_first_question
|
|
450
|
+
have_no_button("Up").and have_button("Down")
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def look_like_intermediate_question
|
|
454
|
+
have_button("Up").and have_button("Down")
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def look_like_last_question
|
|
458
|
+
have_button("Up").and have_no_button("Down")
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
end
|