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
|
@@ -75,7 +75,7 @@ shared_examples_for "has questionnaire" do
|
|
|
75
75
|
click_link "Back"
|
|
76
76
|
|
|
77
77
|
expect(page).to have_content("STEP 1 OF 2")
|
|
78
|
-
expect(page).to have_field("
|
|
78
|
+
expect(page).to have_field("questionnaire_responses_0", with: "My first answer")
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
it "finishes the submission when answering the last questionnaire" do
|
|
@@ -257,7 +257,7 @@ shared_examples_for "has questionnaire" do
|
|
|
257
257
|
end
|
|
258
258
|
|
|
259
259
|
context "when a question has a rich text description" do
|
|
260
|
-
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, position: 0, description: "<b>This question is important</b>") }
|
|
260
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, position: 0, description: { en: "<b>This question is important</b>" }) }
|
|
261
261
|
|
|
262
262
|
it "properly interprets HTML descriptions" do
|
|
263
263
|
visit questionnaire_public_path
|
|
@@ -308,16 +308,16 @@ shared_examples_for "has questionnaire" do
|
|
|
308
308
|
it "renders them as radio buttons with attached text fields disabled by default" do
|
|
309
309
|
expect(page).to have_selector(".radio-button-collection input[type=radio]", count: 3)
|
|
310
310
|
|
|
311
|
-
expect(page).to have_field("
|
|
311
|
+
expect(page).to have_field("questionnaire_responses_0_choices_2_custom_body", disabled: true, count: 1)
|
|
312
312
|
|
|
313
313
|
choose answer_option_bodies[2]["en"]
|
|
314
314
|
|
|
315
|
-
expect(page).to have_field("
|
|
315
|
+
expect(page).to have_field("questionnaire_responses_0_choices_2_custom_body", disabled: false, count: 1)
|
|
316
316
|
end
|
|
317
317
|
|
|
318
318
|
it "saves the free text in a separate field if submission correct" do
|
|
319
319
|
choose answer_option_bodies[2]["en"]
|
|
320
|
-
fill_in "
|
|
320
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "Cacatua"
|
|
321
321
|
|
|
322
322
|
check "questionnaire_tos_agreement"
|
|
323
323
|
accept_confirm { click_button "Submit" }
|
|
@@ -335,7 +335,7 @@ shared_examples_for "has questionnaire" do
|
|
|
335
335
|
check other_question.answer_options.third.body["en"]
|
|
336
336
|
|
|
337
337
|
choose answer_option_bodies[2]["en"]
|
|
338
|
-
fill_in "
|
|
338
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "Cacatua"
|
|
339
339
|
|
|
340
340
|
check "questionnaire_tos_agreement"
|
|
341
341
|
accept_confirm { click_button "Submit" }
|
|
@@ -344,7 +344,7 @@ shared_examples_for "has questionnaire" do
|
|
|
344
344
|
expect(page).to have_content("There was a problem answering")
|
|
345
345
|
end
|
|
346
346
|
|
|
347
|
-
expect(page).to have_field("
|
|
347
|
+
expect(page).to have_field("questionnaire_responses_0_choices_2_custom_body", with: "Cacatua")
|
|
348
348
|
end
|
|
349
349
|
end
|
|
350
350
|
|
|
@@ -401,7 +401,7 @@ shared_examples_for "has questionnaire" do
|
|
|
401
401
|
it "renders the answer as a textarea" do
|
|
402
402
|
visit questionnaire_public_path
|
|
403
403
|
|
|
404
|
-
expect(page).to have_selector("textarea#
|
|
404
|
+
expect(page).to have_selector("textarea#questionnaire_responses_0")
|
|
405
405
|
end
|
|
406
406
|
end
|
|
407
407
|
|
|
@@ -411,7 +411,7 @@ shared_examples_for "has questionnaire" do
|
|
|
411
411
|
it "renders the answer as a text field" do
|
|
412
412
|
visit questionnaire_public_path
|
|
413
413
|
|
|
414
|
-
expect(page).to have_selector("input[type=text]#
|
|
414
|
+
expect(page).to have_selector("input[type=text]#questionnaire_responses_0")
|
|
415
415
|
end
|
|
416
416
|
end
|
|
417
417
|
|
|
@@ -509,11 +509,11 @@ shared_examples_for "has questionnaire" do
|
|
|
509
509
|
questionnaire: questionnaire,
|
|
510
510
|
question_type: "sorting",
|
|
511
511
|
options: [
|
|
512
|
-
{ "body" => "
|
|
513
|
-
{ "body" => "
|
|
514
|
-
{ "body" => "
|
|
515
|
-
{ "body" => "
|
|
516
|
-
{ "body" => "
|
|
512
|
+
{ "body" => { "en" => "chocolate" } },
|
|
513
|
+
{ "body" => { "en" => "like" } },
|
|
514
|
+
{ "body" => { "en" => "We" } },
|
|
515
|
+
{ "body" => { "en" => "dark" } },
|
|
516
|
+
{ "body" => { "en" => "all" } }
|
|
517
517
|
]
|
|
518
518
|
)
|
|
519
519
|
end
|
|
@@ -523,25 +523,25 @@ shared_examples_for "has questionnaire" do
|
|
|
523
523
|
|
|
524
524
|
expect(page).to have_selector(".sortable-check-box-collection input[type=checkbox]", count: 5)
|
|
525
525
|
|
|
526
|
-
expect(page).to have_content("
|
|
526
|
+
expect(page).to have_content("chocolate\nlike\nWe\ndark\nall")
|
|
527
527
|
|
|
528
|
-
check "
|
|
529
|
-
check "
|
|
530
|
-
check "
|
|
531
|
-
check "
|
|
532
|
-
check "
|
|
528
|
+
check "We"
|
|
529
|
+
check "all"
|
|
530
|
+
check "like"
|
|
531
|
+
check "dark"
|
|
532
|
+
check "chocolate"
|
|
533
533
|
|
|
534
|
-
expect(page).to have_content("1.
|
|
534
|
+
expect(page).to have_content("1. We\n2. all\n3. like\n4. dark\n5. chocolate")
|
|
535
535
|
end
|
|
536
536
|
|
|
537
537
|
it "properly saves valid sortings" do
|
|
538
538
|
visit questionnaire_public_path
|
|
539
539
|
|
|
540
|
-
check "
|
|
541
|
-
check "
|
|
542
|
-
check "
|
|
543
|
-
check "
|
|
544
|
-
check "
|
|
540
|
+
check "We"
|
|
541
|
+
check "all"
|
|
542
|
+
check "like"
|
|
543
|
+
check "dark"
|
|
544
|
+
check "chocolate"
|
|
545
545
|
|
|
546
546
|
check "questionnaire_tos_agreement"
|
|
547
547
|
|
|
@@ -552,14 +552,46 @@ shared_examples_for "has questionnaire" do
|
|
|
552
552
|
end
|
|
553
553
|
|
|
554
554
|
expect(Decidim::Forms::Answer.first.choices.pluck(:position, :body)).to eq(
|
|
555
|
-
[[0, "
|
|
555
|
+
[[0, "We"], [1, "all"], [2, "like"], [3, "dark"], [4, "chocolate"]]
|
|
556
556
|
)
|
|
557
557
|
end
|
|
558
558
|
|
|
559
559
|
it "displays errors on incomplete sortings" do
|
|
560
560
|
visit questionnaire_public_path
|
|
561
561
|
|
|
562
|
-
check "
|
|
562
|
+
check "We"
|
|
563
|
+
|
|
564
|
+
accept_confirm { click_button "Submit" }
|
|
565
|
+
|
|
566
|
+
within ".alert.flash" do
|
|
567
|
+
expect(page).to have_content("problem")
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
expect(page).to have_content("are not complete")
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
it "displays maintains sorting order if errors" do
|
|
574
|
+
visit questionnaire_public_path
|
|
575
|
+
|
|
576
|
+
check "We"
|
|
577
|
+
check "dark"
|
|
578
|
+
check "chocolate"
|
|
579
|
+
|
|
580
|
+
accept_confirm { click_button "Submit" }
|
|
581
|
+
|
|
582
|
+
within ".alert.flash" do
|
|
583
|
+
expect(page).to have_content("problem")
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# Check the next round to ensure a re-submission conserves status
|
|
587
|
+
expect(page).to have_content("are not complete")
|
|
588
|
+
expect(page).to have_content("1. We\n2. dark\n3. chocolate\nlike\nall")
|
|
589
|
+
|
|
590
|
+
checkboxes = page.all("input[type=checkbox]")
|
|
591
|
+
|
|
592
|
+
checkboxes[0].uncheck
|
|
593
|
+
check "We"
|
|
594
|
+
check "all"
|
|
563
595
|
|
|
564
596
|
accept_confirm { click_button "Submit" }
|
|
565
597
|
|
|
@@ -568,6 +600,7 @@ shared_examples_for "has questionnaire" do
|
|
|
568
600
|
end
|
|
569
601
|
|
|
570
602
|
expect(page).to have_content("are not complete")
|
|
603
|
+
expect(page).to have_content("1. dark\n2. chocolate\n3. We\n4. all\nlike")
|
|
571
604
|
end
|
|
572
605
|
end
|
|
573
606
|
|
|
@@ -757,6 +790,26 @@ shared_examples_for "has questionnaire" do
|
|
|
757
790
|
end
|
|
758
791
|
end
|
|
759
792
|
|
|
793
|
+
context "when the question is mandatory and the answer is not complete" do
|
|
794
|
+
let!(:mandatory) { true }
|
|
795
|
+
|
|
796
|
+
it "shows an error" do
|
|
797
|
+
visit questionnaire_public_path
|
|
798
|
+
|
|
799
|
+
checkboxes = page.all(".check-box-collection input[type=checkbox]")
|
|
800
|
+
check checkboxes[0][:id]
|
|
801
|
+
|
|
802
|
+
check "questionnaire_tos_agreement"
|
|
803
|
+
accept_confirm { click_button "Submit" }
|
|
804
|
+
|
|
805
|
+
within ".alert.flash" do
|
|
806
|
+
expect(page).to have_content("There was a problem answering")
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
expect(page).to have_content("Choices are not complete")
|
|
810
|
+
end
|
|
811
|
+
end
|
|
812
|
+
|
|
760
813
|
context "when the submission is not correct" do
|
|
761
814
|
let!(:max_choices) { 2 }
|
|
762
815
|
|
|
@@ -780,26 +833,554 @@ shared_examples_for "has questionnaire" do
|
|
|
780
833
|
expect(checkboxes.map { |c| c[:checked] }).to eq(["true", "true", "true", nil, nil, "true"])
|
|
781
834
|
end
|
|
782
835
|
end
|
|
836
|
+
end
|
|
783
837
|
|
|
784
|
-
|
|
785
|
-
|
|
838
|
+
describe "display conditions" do
|
|
839
|
+
let(:answer_options) do
|
|
840
|
+
3.times.to_a.map do |x|
|
|
841
|
+
{
|
|
842
|
+
"body" => Decidim::Faker::Localized.sentence,
|
|
843
|
+
"free_text" => x == 2
|
|
844
|
+
}
|
|
845
|
+
end
|
|
846
|
+
end
|
|
847
|
+
let(:condition_question_options) { [] }
|
|
848
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, position: 2) }
|
|
849
|
+
let!(:conditioned_question_id) { "#questionnaire_responses_1" }
|
|
850
|
+
let!(:condition_question) do
|
|
851
|
+
create(:questionnaire_question,
|
|
852
|
+
questionnaire: questionnaire,
|
|
853
|
+
question_type: condition_question_type,
|
|
854
|
+
position: 1,
|
|
855
|
+
options: condition_question_options)
|
|
856
|
+
end
|
|
786
857
|
|
|
787
|
-
|
|
858
|
+
context "when a question has a display condition" do
|
|
859
|
+
context "when condition is of type 'answered'" do
|
|
860
|
+
let!(:display_condition) do
|
|
861
|
+
create(:display_condition,
|
|
862
|
+
condition_type: "answered",
|
|
863
|
+
question: question,
|
|
864
|
+
condition_question: condition_question)
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
before do
|
|
868
|
+
visit questionnaire_public_path
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
context "when the condition_question type is short answer" do
|
|
872
|
+
let!(:condition_question_type) { "short_answer" }
|
|
873
|
+
|
|
874
|
+
it "shows the question only if the condition is fulfilled" do
|
|
875
|
+
expect_question_to_be_visible(false)
|
|
876
|
+
|
|
877
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
878
|
+
change_focus
|
|
879
|
+
|
|
880
|
+
expect_question_to_be_visible(true)
|
|
881
|
+
|
|
882
|
+
fill_in "questionnaire_responses_0", with: ""
|
|
883
|
+
change_focus
|
|
884
|
+
|
|
885
|
+
expect_question_to_be_visible(false)
|
|
886
|
+
end
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
context "when the condition_question type is long answer" do
|
|
890
|
+
let!(:condition_question_type) { "long_answer" }
|
|
891
|
+
|
|
892
|
+
it "shows the question only if the condition is fulfilled" do
|
|
893
|
+
expect_question_to_be_visible(false)
|
|
894
|
+
|
|
895
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
896
|
+
change_focus
|
|
897
|
+
|
|
898
|
+
expect_question_to_be_visible(true)
|
|
899
|
+
|
|
900
|
+
fill_in "questionnaire_responses_0", with: ""
|
|
901
|
+
change_focus
|
|
902
|
+
|
|
903
|
+
expect_question_to_be_visible(false)
|
|
904
|
+
end
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
context "when the condition_question type is single option" do
|
|
908
|
+
let!(:condition_question_type) { "single_option" }
|
|
909
|
+
let!(:condition_question_options) { answer_options }
|
|
910
|
+
|
|
911
|
+
it "shows the question only if the condition is fulfilled" do
|
|
912
|
+
expect_question_to_be_visible(false)
|
|
913
|
+
|
|
914
|
+
choose condition_question.answer_options.first.body["en"]
|
|
915
|
+
|
|
916
|
+
expect_question_to_be_visible(true)
|
|
917
|
+
|
|
918
|
+
choose condition_question.answer_options.second.body["en"]
|
|
919
|
+
|
|
920
|
+
expect_question_to_be_visible(false)
|
|
921
|
+
end
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
context "when the condition_question type is multiple option" do
|
|
925
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
926
|
+
let!(:condition_question_options) { answer_options }
|
|
927
|
+
|
|
928
|
+
it "shows the question only if the condition is fulfilled" do
|
|
929
|
+
expect_question_to_be_visible(false)
|
|
930
|
+
|
|
931
|
+
check condition_question.answer_options.first.body["en"]
|
|
932
|
+
|
|
933
|
+
expect_question_to_be_visible(true)
|
|
934
|
+
|
|
935
|
+
uncheck condition_question.answer_options.first.body["en"]
|
|
936
|
+
|
|
937
|
+
expect_question_to_be_visible(false)
|
|
938
|
+
|
|
939
|
+
check condition_question.answer_options.second.body["en"]
|
|
940
|
+
|
|
941
|
+
expect_question_to_be_visible(false)
|
|
942
|
+
|
|
943
|
+
check condition_question.answer_options.first.body["en"]
|
|
944
|
+
|
|
945
|
+
expect_question_to_be_visible(true)
|
|
946
|
+
end
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
context "when a question has a display condition of type 'not_answered'" do
|
|
951
|
+
let!(:display_condition) do
|
|
952
|
+
create(:display_condition,
|
|
953
|
+
condition_type: "not_answered",
|
|
954
|
+
question: question,
|
|
955
|
+
condition_question: condition_question)
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
before do
|
|
959
|
+
visit questionnaire_public_path
|
|
960
|
+
end
|
|
961
|
+
|
|
962
|
+
context "when the condition_question type is short answer" do
|
|
963
|
+
let!(:condition_question_type) { "short_answer" }
|
|
964
|
+
|
|
965
|
+
it "shows the question only if the condition is fulfilled" do
|
|
966
|
+
expect_question_to_be_visible(true)
|
|
967
|
+
|
|
968
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
969
|
+
change_focus
|
|
970
|
+
|
|
971
|
+
expect_question_to_be_visible(false)
|
|
972
|
+
|
|
973
|
+
fill_in "questionnaire_responses_0", with: ""
|
|
974
|
+
change_focus
|
|
975
|
+
|
|
976
|
+
expect_question_to_be_visible(true)
|
|
977
|
+
end
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
context "when the condition_question type is long answer" do
|
|
981
|
+
let!(:condition_question_type) { "long_answer" }
|
|
982
|
+
|
|
983
|
+
it "shows the question only if the condition is fulfilled" do
|
|
984
|
+
expect_question_to_be_visible(true)
|
|
985
|
+
|
|
986
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
987
|
+
change_focus
|
|
988
|
+
|
|
989
|
+
expect_question_to_be_visible(false)
|
|
990
|
+
|
|
991
|
+
fill_in "questionnaire_responses_0", with: ""
|
|
992
|
+
change_focus
|
|
993
|
+
|
|
994
|
+
expect_question_to_be_visible(true)
|
|
995
|
+
end
|
|
996
|
+
end
|
|
997
|
+
|
|
998
|
+
context "when the condition_question type is single option" do
|
|
999
|
+
let!(:condition_question_type) { "single_option" }
|
|
1000
|
+
let!(:condition_question_options) { answer_options }
|
|
1001
|
+
|
|
1002
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1003
|
+
expect_question_to_be_visible(true)
|
|
1004
|
+
|
|
1005
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1006
|
+
|
|
1007
|
+
expect_question_to_be_visible(false)
|
|
1008
|
+
end
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
context "when the condition_question type is multiple option" do
|
|
1012
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
1013
|
+
let!(:condition_question_options) { answer_options }
|
|
1014
|
+
|
|
1015
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1016
|
+
expect_question_to_be_visible(true)
|
|
1017
|
+
|
|
1018
|
+
check condition_question.answer_options.first.body["en"]
|
|
1019
|
+
|
|
1020
|
+
expect_question_to_be_visible(false)
|
|
1021
|
+
|
|
1022
|
+
uncheck condition_question.answer_options.first.body["en"]
|
|
1023
|
+
|
|
1024
|
+
expect_question_to_be_visible(true)
|
|
1025
|
+
end
|
|
1026
|
+
end
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
context "when a question has a display condition of type 'equal'" do
|
|
1030
|
+
let!(:display_condition) do
|
|
1031
|
+
create(:display_condition,
|
|
1032
|
+
condition_type: "equal",
|
|
1033
|
+
question: question,
|
|
1034
|
+
condition_question: condition_question,
|
|
1035
|
+
answer_option: condition_question.answer_options.first)
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
before do
|
|
1039
|
+
visit questionnaire_public_path
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
context "when the condition_question type is single option" do
|
|
1043
|
+
let!(:condition_question_type) { "single_option" }
|
|
1044
|
+
let!(:condition_question_options) { answer_options }
|
|
1045
|
+
|
|
1046
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1047
|
+
expect_question_to_be_visible(false)
|
|
1048
|
+
|
|
1049
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1050
|
+
|
|
1051
|
+
expect_question_to_be_visible(true)
|
|
1052
|
+
|
|
1053
|
+
choose condition_question.answer_options.second.body["en"]
|
|
1054
|
+
|
|
1055
|
+
expect_question_to_be_visible(false)
|
|
1056
|
+
end
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
context "when the condition_question type is multiple option" do
|
|
1060
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
1061
|
+
let!(:condition_question_options) { answer_options }
|
|
1062
|
+
|
|
1063
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1064
|
+
expect_question_to_be_visible(false)
|
|
1065
|
+
|
|
1066
|
+
check condition_question.answer_options.first.body["en"]
|
|
1067
|
+
|
|
1068
|
+
expect_question_to_be_visible(true)
|
|
1069
|
+
|
|
1070
|
+
uncheck condition_question.answer_options.first.body["en"]
|
|
1071
|
+
|
|
1072
|
+
expect_question_to_be_visible(false)
|
|
1073
|
+
|
|
1074
|
+
check condition_question.answer_options.second.body["en"]
|
|
1075
|
+
|
|
1076
|
+
expect_question_to_be_visible(false)
|
|
1077
|
+
|
|
1078
|
+
check condition_question.answer_options.first.body["en"]
|
|
1079
|
+
|
|
1080
|
+
expect_question_to_be_visible(true)
|
|
1081
|
+
end
|
|
1082
|
+
end
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
context "when a question has a display condition of type 'not_equal'" do
|
|
1086
|
+
let!(:display_condition) do
|
|
1087
|
+
create(:display_condition,
|
|
1088
|
+
condition_type: "not_equal",
|
|
1089
|
+
question: question,
|
|
1090
|
+
condition_question: condition_question,
|
|
1091
|
+
answer_option: condition_question.answer_options.first)
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
before do
|
|
1095
|
+
visit questionnaire_public_path
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
context "when the condition_question type is single option" do
|
|
1099
|
+
let!(:condition_question_type) { "single_option" }
|
|
1100
|
+
let!(:condition_question_options) { answer_options }
|
|
1101
|
+
|
|
1102
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1103
|
+
expect_question_to_be_visible(false)
|
|
1104
|
+
|
|
1105
|
+
choose condition_question.answer_options.second.body["en"]
|
|
1106
|
+
|
|
1107
|
+
expect_question_to_be_visible(true)
|
|
1108
|
+
|
|
1109
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1110
|
+
|
|
1111
|
+
expect_question_to_be_visible(false)
|
|
1112
|
+
end
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
context "when the condition_question type is multiple option" do
|
|
1116
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
1117
|
+
let!(:condition_question_options) { answer_options }
|
|
1118
|
+
|
|
1119
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1120
|
+
expect_question_to_be_visible(false)
|
|
1121
|
+
|
|
1122
|
+
check condition_question.answer_options.second.body["en"]
|
|
1123
|
+
|
|
1124
|
+
expect_question_to_be_visible(true)
|
|
1125
|
+
|
|
1126
|
+
uncheck condition_question.answer_options.second.body["en"]
|
|
1127
|
+
|
|
1128
|
+
expect_question_to_be_visible(false)
|
|
1129
|
+
|
|
1130
|
+
check condition_question.answer_options.first.body["en"]
|
|
1131
|
+
|
|
1132
|
+
expect_question_to_be_visible(false)
|
|
1133
|
+
|
|
1134
|
+
check condition_question.answer_options.second.body["en"]
|
|
1135
|
+
|
|
1136
|
+
expect_question_to_be_visible(true)
|
|
1137
|
+
end
|
|
1138
|
+
end
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
context "when a question has a display condition of type 'match'" do
|
|
1142
|
+
let!(:condition_value) { { en: "something" } }
|
|
1143
|
+
let!(:display_condition) do
|
|
1144
|
+
create(:display_condition,
|
|
1145
|
+
condition_type: "match",
|
|
1146
|
+
question: question,
|
|
1147
|
+
condition_question: condition_question,
|
|
1148
|
+
condition_value: condition_value)
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
before do
|
|
1152
|
+
visit questionnaire_public_path
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
context "when the condition_question type is short answer" do
|
|
1156
|
+
let!(:condition_question_type) { "short_answer" }
|
|
1157
|
+
|
|
1158
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1159
|
+
expect_question_to_be_visible(false)
|
|
1160
|
+
|
|
1161
|
+
fill_in "questionnaire_responses_0", with: "Aren't we all expecting #{condition_value[:en]}?"
|
|
1162
|
+
change_focus
|
|
1163
|
+
|
|
1164
|
+
expect_question_to_be_visible(true)
|
|
1165
|
+
|
|
1166
|
+
fill_in "questionnaire_responses_0", with: "Now upcase #{condition_value[:en].upcase}!"
|
|
1167
|
+
change_focus
|
|
1168
|
+
|
|
1169
|
+
expect_question_to_be_visible(true)
|
|
1170
|
+
|
|
1171
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
1172
|
+
change_focus
|
|
1173
|
+
|
|
1174
|
+
expect_question_to_be_visible(false)
|
|
1175
|
+
end
|
|
1176
|
+
end
|
|
1177
|
+
|
|
1178
|
+
context "when the condition_question type is long answer" do
|
|
1179
|
+
let!(:condition_question_type) { "long_answer" }
|
|
1180
|
+
|
|
1181
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1182
|
+
expect_question_to_be_visible(false)
|
|
1183
|
+
|
|
1184
|
+
fill_in "questionnaire_responses_0", with: "Aren't we all expecting #{condition_value[:en]}?"
|
|
1185
|
+
change_focus
|
|
1186
|
+
|
|
1187
|
+
expect_question_to_be_visible(true)
|
|
1188
|
+
|
|
1189
|
+
fill_in "questionnaire_responses_0", with: "Now upcase #{condition_value[:en].upcase}!"
|
|
1190
|
+
change_focus
|
|
1191
|
+
|
|
1192
|
+
expect_question_to_be_visible(true)
|
|
1193
|
+
|
|
1194
|
+
fill_in "questionnaire_responses_0", with: "Cacatua"
|
|
1195
|
+
change_focus
|
|
1196
|
+
|
|
1197
|
+
expect_question_to_be_visible(false)
|
|
1198
|
+
end
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
context "when the condition_question type is single option" do
|
|
1202
|
+
let!(:condition_question_type) { "single_option" }
|
|
1203
|
+
let!(:condition_question_options) { answer_options }
|
|
1204
|
+
let!(:condition_value) { { en: condition_question.answer_options.first.body["en"].split.second.upcase } }
|
|
1205
|
+
|
|
1206
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1207
|
+
expect_question_to_be_visible(false)
|
|
1208
|
+
|
|
1209
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1210
|
+
|
|
1211
|
+
expect_question_to_be_visible(true)
|
|
1212
|
+
end
|
|
1213
|
+
end
|
|
1214
|
+
|
|
1215
|
+
context "when the condition_question type is single option with free text" do
|
|
1216
|
+
let!(:condition_question_type) { "single_option" }
|
|
1217
|
+
let!(:condition_question_options) { answer_options }
|
|
1218
|
+
let!(:condition_value) { { en: "forty two" } }
|
|
1219
|
+
|
|
1220
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1221
|
+
expect_question_to_be_visible(false)
|
|
1222
|
+
|
|
1223
|
+
choose condition_question.answer_options.third.body["en"]
|
|
1224
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "The answer is #{condition_value[:en]}"
|
|
1225
|
+
change_focus
|
|
1226
|
+
|
|
1227
|
+
expect_question_to_be_visible(true)
|
|
1228
|
+
|
|
1229
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1230
|
+
expect_question_to_be_visible(false)
|
|
1231
|
+
|
|
1232
|
+
choose condition_question.answer_options.third.body["en"]
|
|
1233
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "oh no not 42 again"
|
|
1234
|
+
change_focus
|
|
1235
|
+
|
|
1236
|
+
expect_question_to_be_visible(false)
|
|
1237
|
+
end
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
context "when the condition_question type is multiple option" do
|
|
1241
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
1242
|
+
let!(:condition_question_options) { answer_options }
|
|
1243
|
+
let!(:condition_value) { { en: "forty two" } }
|
|
1244
|
+
|
|
1245
|
+
it "shows the question only if the condition is fulfilled" do
|
|
1246
|
+
expect_question_to_be_visible(false)
|
|
1247
|
+
|
|
1248
|
+
check condition_question.answer_options.third.body["en"]
|
|
1249
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "The answer is #{condition_value[:en]}"
|
|
1250
|
+
change_focus
|
|
1251
|
+
|
|
1252
|
+
expect_question_to_be_visible(true)
|
|
1253
|
+
|
|
1254
|
+
check condition_question.answer_options.first.body["en"]
|
|
1255
|
+
expect_question_to_be_visible(true)
|
|
1256
|
+
|
|
1257
|
+
uncheck condition_question.answer_options.third.body["en"]
|
|
1258
|
+
expect_question_to_be_visible(false)
|
|
1259
|
+
|
|
1260
|
+
check condition_question.answer_options.third.body["en"]
|
|
1261
|
+
fill_in "questionnaire_responses_0_choices_2_custom_body", with: "oh no not 42 again"
|
|
1262
|
+
change_focus
|
|
1263
|
+
|
|
1264
|
+
expect_question_to_be_visible(false)
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
end
|
|
1268
|
+
end
|
|
1269
|
+
|
|
1270
|
+
context "when a question has multiple display conditions" do
|
|
1271
|
+
before do
|
|
788
1272
|
visit questionnaire_public_path
|
|
1273
|
+
end
|
|
789
1274
|
|
|
790
|
-
|
|
791
|
-
|
|
1275
|
+
context "when all conditions are mandatory" do
|
|
1276
|
+
let!(:condition_question_type) { "single_option" }
|
|
1277
|
+
let!(:condition_question_options) { answer_options }
|
|
1278
|
+
let!(:display_conditions) do
|
|
1279
|
+
[
|
|
1280
|
+
create(:display_condition,
|
|
1281
|
+
condition_type: "answered",
|
|
1282
|
+
question: question,
|
|
1283
|
+
condition_question: condition_question,
|
|
1284
|
+
mandatory: true),
|
|
1285
|
+
create(:display_condition,
|
|
1286
|
+
condition_type: "not_equal",
|
|
1287
|
+
question: question,
|
|
1288
|
+
condition_question: condition_question,
|
|
1289
|
+
mandatory: true,
|
|
1290
|
+
answer_option: condition_question.answer_options.second)
|
|
1291
|
+
]
|
|
1292
|
+
end
|
|
792
1293
|
|
|
793
|
-
|
|
794
|
-
|
|
1294
|
+
it "is displayed only if all conditions are fulfilled" do
|
|
1295
|
+
expect_question_to_be_visible(false)
|
|
795
1296
|
|
|
796
|
-
|
|
797
|
-
|
|
1297
|
+
choose condition_question.answer_options.second.body["en"]
|
|
1298
|
+
|
|
1299
|
+
expect_question_to_be_visible(false)
|
|
1300
|
+
|
|
1301
|
+
choose condition_question.answer_options.first.body["en"]
|
|
1302
|
+
|
|
1303
|
+
expect_question_to_be_visible(true)
|
|
798
1304
|
end
|
|
1305
|
+
end
|
|
799
1306
|
|
|
800
|
-
|
|
1307
|
+
context "when all conditions are non-mandatory" do
|
|
1308
|
+
let!(:condition_question_type) { "multiple_option" }
|
|
1309
|
+
let!(:condition_question_options) { answer_options }
|
|
1310
|
+
let!(:display_conditions) do
|
|
1311
|
+
[
|
|
1312
|
+
create(:display_condition,
|
|
1313
|
+
condition_type: "equal",
|
|
1314
|
+
question: question,
|
|
1315
|
+
condition_question: condition_question,
|
|
1316
|
+
mandatory: false,
|
|
1317
|
+
answer_option: condition_question.answer_options.first),
|
|
1318
|
+
create(:display_condition,
|
|
1319
|
+
condition_type: "not_equal",
|
|
1320
|
+
question: question,
|
|
1321
|
+
condition_question: condition_question,
|
|
1322
|
+
mandatory: false,
|
|
1323
|
+
answer_option: condition_question.answer_options.third)
|
|
1324
|
+
]
|
|
1325
|
+
end
|
|
1326
|
+
|
|
1327
|
+
it "is displayed if any of the conditions is fulfilled" do
|
|
1328
|
+
expect_question_to_be_visible(false)
|
|
1329
|
+
|
|
1330
|
+
check condition_question.answer_options.first.body["en"]
|
|
1331
|
+
|
|
1332
|
+
expect_question_to_be_visible(true)
|
|
1333
|
+
|
|
1334
|
+
uncheck condition_question.answer_options.first.body["en"]
|
|
1335
|
+
check condition_question.answer_options.second.body["en"]
|
|
1336
|
+
|
|
1337
|
+
expect_question_to_be_visible(true)
|
|
1338
|
+
|
|
1339
|
+
check condition_question.answer_options.first.body["en"]
|
|
1340
|
+
|
|
1341
|
+
expect_question_to_be_visible(true)
|
|
1342
|
+
end
|
|
1343
|
+
end
|
|
1344
|
+
|
|
1345
|
+
context "when a mandatory question has conditions that have not been fulfilled" do
|
|
1346
|
+
let!(:condition_question_type) { "short_answer" }
|
|
1347
|
+
let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, position: 2, mandatory: true) }
|
|
1348
|
+
let!(:display_conditions) do
|
|
1349
|
+
[
|
|
1350
|
+
create(:display_condition,
|
|
1351
|
+
condition_type: "match",
|
|
1352
|
+
question: question,
|
|
1353
|
+
condition_question: condition_question,
|
|
1354
|
+
condition_value: { en: "hey", es: "ey", ca: "ei" },
|
|
1355
|
+
mandatory: true)
|
|
1356
|
+
]
|
|
1357
|
+
end
|
|
1358
|
+
|
|
1359
|
+
it "doesn't throw error" do
|
|
1360
|
+
visit questionnaire_public_path
|
|
1361
|
+
|
|
1362
|
+
fill_in condition_question.body["en"], with: "My first answer"
|
|
1363
|
+
|
|
1364
|
+
check "questionnaire_tos_agreement"
|
|
1365
|
+
|
|
1366
|
+
accept_confirm { click_button "Submit" }
|
|
1367
|
+
|
|
1368
|
+
within ".success.flash" do
|
|
1369
|
+
expect(page).to have_content("successfully")
|
|
1370
|
+
end
|
|
1371
|
+
end
|
|
801
1372
|
end
|
|
802
1373
|
end
|
|
803
1374
|
end
|
|
1375
|
+
|
|
1376
|
+
private
|
|
1377
|
+
|
|
1378
|
+
def expect_question_to_be_visible(visible)
|
|
1379
|
+
expect(page).to have_css(conditioned_question_id, visible: visible)
|
|
1380
|
+
end
|
|
1381
|
+
|
|
1382
|
+
def change_focus
|
|
1383
|
+
check "questionnaire_tos_agreement"
|
|
1384
|
+
end
|
|
804
1385
|
end
|
|
805
1386
|
end
|