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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
  3. data/app/assets/config/decidim_forms_manifest.css +1 -0
  4. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
  5. data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +181 -25
  6. data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
  7. data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +204 -0
  8. data/app/assets/javascripts/decidim/forms/forms.js.es6 +8 -1
  9. data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
  10. data/app/commands/decidim/forms/admin/update_questionnaire.rb +25 -1
  11. data/app/commands/decidim/forms/answer_questionnaire.rb +1 -1
  12. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +47 -1
  13. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
  14. data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
  15. data/app/forms/decidim/forms/admin/question_form.rb +1 -0
  16. data/app/forms/decidim/forms/answer_form.rb +15 -0
  17. data/app/helpers/decidim/forms/admin/application_helper.rb +21 -0
  18. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
  19. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
  20. data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +27 -0
  21. data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
  22. data/app/models/decidim/forms/answer.rb +0 -3
  23. data/app/models/decidim/forms/answer_option.rb +14 -0
  24. data/app/models/decidim/forms/display_condition.rb +51 -0
  25. data/app/models/decidim/forms/question.rb +34 -0
  26. data/app/models/decidim/forms/question_matrix_row.rb +3 -0
  27. data/app/models/decidim/forms/questionnaire.rb +11 -1
  28. data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
  29. data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
  30. data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
  31. data/app/presenters/decidim/forms/question_presenter.rb +16 -0
  32. data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
  33. data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
  34. data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
  35. data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
  36. data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +30 -4
  37. data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +19 -3
  38. data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
  39. data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
  40. data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
  41. data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
  42. data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
  43. data/app/views/decidim/forms/questionnaires/_answer.html.erb +1 -1
  44. data/app/views/decidim/forms/questionnaires/show.html.erb +22 -2
  45. data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
  46. data/config/initializers/wicked_pdf.rb +25 -0
  47. data/config/locales/am-ET.yml +1 -0
  48. data/config/locales/ar.yml +0 -1
  49. data/config/locales/bg-BG.yml +0 -2
  50. data/config/locales/bg.yml +14 -0
  51. data/config/locales/ca.yml +56 -4
  52. data/config/locales/cs.yml +54 -2
  53. data/config/locales/da.yml +1 -0
  54. data/config/locales/de.yml +51 -1
  55. data/config/locales/el.yml +0 -2
  56. data/config/locales/en.yml +54 -2
  57. data/config/locales/eo.yml +1 -0
  58. data/config/locales/es-MX.yml +53 -1
  59. data/config/locales/es-PY.yml +53 -1
  60. data/config/locales/es.yml +54 -2
  61. data/config/locales/et.yml +1 -0
  62. data/config/locales/eu.yml +0 -1
  63. data/config/locales/fi-plain.yml +53 -1
  64. data/config/locales/fi.yml +53 -1
  65. data/config/locales/fr-CA.yml +54 -2
  66. data/config/locales/fr.yml +54 -2
  67. data/config/locales/gl.yml +0 -1
  68. data/config/locales/hr.yml +1 -0
  69. data/config/locales/hu.yml +0 -2
  70. data/config/locales/id-ID.yml +0 -1
  71. data/config/locales/is.yml +1 -0
  72. data/config/locales/it.yml +53 -1
  73. data/config/locales/ja-JP.yml +51 -1
  74. data/config/locales/ja.yml +170 -0
  75. data/config/locales/ko-KR.yml +1 -0
  76. data/config/locales/ko.yml +1 -0
  77. data/config/locales/lt.yml +1 -0
  78. data/config/locales/{lv-LV.yml → lv.yml} +0 -1
  79. data/config/locales/mt.yml +1 -0
  80. data/config/locales/nl.yml +59 -7
  81. data/config/locales/no.yml +47 -2
  82. data/config/locales/om-ET.yml +1 -0
  83. data/config/locales/pl.yml +52 -3
  84. data/config/locales/pt-BR.yml +0 -1
  85. data/config/locales/pt.yml +51 -2
  86. data/config/locales/ro-RO.yml +51 -2
  87. data/config/locales/ru.yml +0 -1
  88. data/config/locales/sk.yml +0 -2
  89. data/config/locales/sl.yml +7 -0
  90. data/config/locales/so-SO.yml +1 -0
  91. data/config/locales/sv.yml +51 -2
  92. data/config/locales/ti-ER.yml +1 -0
  93. data/config/locales/tr-TR.yml +0 -1
  94. data/config/locales/vi-VN.yml +1 -0
  95. data/config/locales/vi.yml +1 -0
  96. data/config/locales/zh-CN.yml +172 -0
  97. data/config/locales/zh-TW.yml +1 -0
  98. data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
  99. data/lib/decidim/exporters/form_pdf.rb +33 -0
  100. data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
  101. data/lib/decidim/forms.rb +5 -0
  102. data/lib/decidim/forms/admin_engine.rb +1 -1
  103. data/lib/decidim/forms/test.rb +6 -0
  104. data/lib/decidim/forms/test/factories.rb +30 -0
  105. data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +619 -38
  106. data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
  107. data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +21 -894
  108. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
  109. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
  110. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
  111. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
  112. data/lib/decidim/forms/version.rb +1 -1
  113. 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("questionnaire_answers_0", with: "My first answer")
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("questionnaire_answers_0_choices_2_custom_body", disabled: true, count: 1)
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("questionnaire_answers_0_choices_2_custom_body", disabled: false, count: 1)
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 "questionnaire_answers_0_choices_2_custom_body", with: "Cacatua"
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 "questionnaire_answers_0_choices_2_custom_body", with: "Cacatua"
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("questionnaire_answers_0_choices_2_custom_body", with: "Cacatua")
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#questionnaire_answers_0")
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]#questionnaire_answers_0")
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" => "idiotas" },
513
- { "body" => "trates" },
514
- { "body" => "No" },
515
- { "body" => "por" },
516
- { "body" => "nos" }
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("idiotas\ntrates\nNo\npor\nnos")
526
+ expect(page).to have_content("chocolate\nlike\nWe\ndark\nall")
527
527
 
528
- check "No"
529
- check "nos"
530
- check "trates"
531
- check "por"
532
- check "idiotas"
528
+ check "We"
529
+ check "all"
530
+ check "like"
531
+ check "dark"
532
+ check "chocolate"
533
533
 
534
- expect(page).to have_content("1. No\n2. nos\n3. trates\n4. por\n5. idiotas")
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 "No"
541
- check "nos"
542
- check "trates"
543
- check "por"
544
- check "idiotas"
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, "No"], [1, "nos"], [2, "trates"], [3, "por"], [4, "idiotas"]]
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 "No"
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
- context "when the question is mandatory and the answer is not complete" do
785
- let!(:mandatory) { true }
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
- it "shows an error" do
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
- checkboxes = page.all(".check-box-collection input[type=checkbox]")
791
- check checkboxes[0][:id]
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
- check "questionnaire_tos_agreement"
794
- accept_confirm { click_button "Submit" }
1294
+ it "is displayed only if all conditions are fulfilled" do
1295
+ expect_question_to_be_visible(false)
795
1296
 
796
- within ".alert.flash" do
797
- expect(page).to have_content("There was a problem answering")
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
- expect(page).to have_content("Choices are not complete")
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