surveyor_gui 0.0.3

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 (283) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +21 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +159 -0
  8. data/Rakefile +66 -0
  9. data/app/controllers/answers_controller.rb +3 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/dependencys_controller.rb +286 -0
  12. data/app/controllers/question_groups_controller.rb +84 -0
  13. data/app/controllers/questions_controller.rb +187 -0
  14. data/app/controllers/survey_sections_controller.rb +80 -0
  15. data/app/controllers/surveyforms_controller.rb +4 -0
  16. data/app/controllers/surveyor_controller.rb +89 -0
  17. data/app/controllers/surveyor_gui/reports_controller.rb +339 -0
  18. data/app/controllers/surveyor_gui/responses_controller.rb +39 -0
  19. data/app/controllers/surveyor_gui/survey_controller.rb +16 -0
  20. data/app/facades/report_formatter.rb +44 -0
  21. data/app/facades/report_preview_wrapper.rb +11 -0
  22. data/app/facades/report_response_generator.rb +147 -0
  23. data/app/helpers/application_helper.rb +2 -0
  24. data/app/helpers/dependency_helper.rb +5 -0
  25. data/app/helpers/question_helper.rb +22 -0
  26. data/app/helpers/surveyform_helper.rb +179 -0
  27. data/app/helpers/surveyor_gui/report_helper.rb +19 -0
  28. data/app/helpers/surveyor_helper.rb +4 -0
  29. data/app/inputs/currency_input.rb +5 -0
  30. data/app/inputs/date_picker_input.rb +7 -0
  31. data/app/inputs/datetime_picker_input.rb +5 -0
  32. data/app/inputs/percent_input.rb +5 -0
  33. data/app/inputs/time_picker_input.rb +5 -0
  34. data/app/mailers/.gitkeep +0 -0
  35. data/app/models/.gitkeep +0 -0
  36. data/app/models/answer.rb +4 -0
  37. data/app/models/column.rb +3 -0
  38. data/app/models/dependency.rb +4 -0
  39. data/app/models/dependency_condition.rb +4 -0
  40. data/app/models/permitted_params_decorator.rb +80 -0
  41. data/app/models/question.rb +4 -0
  42. data/app/models/question_group.rb +4 -0
  43. data/app/models/question_type.rb +7 -0
  44. data/app/models/response.rb +4 -0
  45. data/app/models/response_set.rb +4 -0
  46. data/app/models/row.rb +3 -0
  47. data/app/models/survey.rb +4 -0
  48. data/app/models/survey_section.rb +4 -0
  49. data/app/models/surveyform.rb +103 -0
  50. data/app/uploaders/blob_uploader.rb +48 -0
  51. data/app/views/dependencys/_column.html.erb +1 -0
  52. data/app/views/dependencys/_dependency.html.erb +22 -0
  53. data/app/views/dependencys/_dependency_condition_fields.html.erb +48 -0
  54. data/app/views/dependencys/_form.html.erb +20 -0
  55. data/app/views/dependencys/blank.html.erb +0 -0
  56. data/app/views/dependencys/edit.html.erb +1 -0
  57. data/app/views/dependencys/new.html.erb +1 -0
  58. data/app/views/layouts/application.html.erb +14 -0
  59. data/app/views/layouts/surveyor_gui_blank.html.erb +12 -0
  60. data/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  61. data/app/views/layouts/surveyor_modified.html.erb +14 -0
  62. data/app/views/partials/_answer.html.haml +33 -0
  63. data/app/views/partials/_question.html.haml +33 -0
  64. data/app/views/partials/_question_group.html.haml +73 -0
  65. data/app/views/partials/_section.html.haml +13 -0
  66. data/app/views/question_groups/_form.html.erb +56 -0
  67. data/app/views/question_groups/_group_inline_field.html.erb +21 -0
  68. data/app/views/question_groups/_group_inline_fields.html.erb +25 -0
  69. data/app/views/question_groups/blank.html.erb +0 -0
  70. data/app/views/question_groups/edit.html.erb +1 -0
  71. data/app/views/question_groups/new.html.erb +1 -0
  72. data/app/views/questions/_answer_fields.html.erb +23 -0
  73. data/app/views/questions/_answer_options.html.erb +28 -0
  74. data/app/views/questions/_form.html.erb +65 -0
  75. data/app/views/questions/_grid_dropdown_columns.html.erb +10 -0
  76. data/app/views/questions/_grid_dropdown_fields.html.erb +42 -0
  77. data/app/views/questions/_grid_fields.html.erb +9 -0
  78. data/app/views/questions/_no_picks.html.erb +29 -0
  79. data/app/views/questions/_pick.html +21 -0
  80. data/app/views/questions/_picks.html.erb +12 -0
  81. data/app/views/questions/blank.html.erb +0 -0
  82. data/app/views/questions/edit.html.erb +1 -0
  83. data/app/views/questions/new.html.erb +1 -0
  84. data/app/views/survey_sections/_form.html.erb +13 -0
  85. data/app/views/survey_sections/blank.html.erb +0 -0
  86. data/app/views/survey_sections/edit.html.erb +1 -0
  87. data/app/views/survey_sections/new.html.erb +1 -0
  88. data/app/views/surveyforms/_form.html.erb +50 -0
  89. data/app/views/surveyforms/_question_field.html.erb +148 -0
  90. data/app/views/surveyforms/_question_group.html.erb +116 -0
  91. data/app/views/surveyforms/_question_group_fields.html.erb +3 -0
  92. data/app/views/surveyforms/_question_name_and_number.html.erb +6 -0
  93. data/app/views/surveyforms/_question_section.html.erb +15 -0
  94. data/app/views/surveyforms/_question_wrapper.html.erb +109 -0
  95. data/app/views/surveyforms/_survey_section_fields.html.erb +138 -0
  96. data/app/views/surveyforms/clone_survey.html.erb +13 -0
  97. data/app/views/surveyforms/edit.html.erb +5 -0
  98. data/app/views/surveyforms/index.html.erb +40 -0
  99. data/app/views/surveyforms/new.html.erb +1 -0
  100. data/app/views/surveyforms/show.html.erb +5 -0
  101. data/app/views/surveyor_gui/reports/_graphs.html.haml +21 -0
  102. data/app/views/surveyor_gui/reports/_grid.html.haml +42 -0
  103. data/app/views/surveyor_gui/reports/_grid_dropdown.html.haml +56 -0
  104. data/app/views/surveyor_gui/reports/_repeater.html.haml +28 -0
  105. data/app/views/surveyor_gui/reports/_show_report.html.haml +33 -0
  106. data/app/views/surveyor_gui/reports/_single_question.html.haml +70 -0
  107. data/app/views/surveyor_gui/reports/show.html.erb +14 -0
  108. data/app/views/surveyor_gui/responses/_grid.html.haml +20 -0
  109. data/app/views/surveyor_gui/responses/_grid_dropdown.html.haml +20 -0
  110. data/app/views/surveyor_gui/responses/_repeater.html.haml +22 -0
  111. data/app/views/surveyor_gui/responses/_survey_results.html.haml +40 -0
  112. data/app/views/surveyor_gui/responses/index.html.haml +24 -0
  113. data/app/views/surveyor_gui/responses/show.html.haml +42 -0
  114. data/app/views/surveyor_gui/shared/_grid_comments.html.haml +10 -0
  115. data/app/views/surveyor_gui/shared/_new_line.html.haml +2 -0
  116. data/app/views/surveyor_gui/shared/_pick_comments.html.haml +15 -0
  117. data/app/views/surveyor_gui/shared/_question_number.html.haml +9 -0
  118. data/app/views/surveyor_gui/shared/_report_data.html.haml +24 -0
  119. data/app/views/surveyor_gui/shared/_stars_report_data.html.haml +14 -0
  120. data/config.ru +4 -0
  121. data/config/environment.rb +0 -0
  122. data/config/routes.rb +71 -0
  123. data/db/migrate/20140307204049_add_template_to_surveys.rb +5 -0
  124. data/db/migrate/20140307235607_add_test_data_to_response_sets.rb +5 -0
  125. data/db/migrate/20140308171947_add_original_choice_to_answers.rb +5 -0
  126. data/db/migrate/20140308172118_add_blob_to_responses.rb +5 -0
  127. data/db/migrate/20140308172417_add_modifiable_to_survey_section.rb +5 -0
  128. data/db/migrate/20140308174532_add_modifiable_to_question.rb +5 -0
  129. data/db/migrate/20140308175305_add_dynamically_generate_to_questions.rb +5 -0
  130. data/db/migrate/20140311032923_add_dummy_blob_to_questions.rb +5 -0
  131. data/db/migrate/20140311160609_add_dynamic_source_to_questions.rb +5 -0
  132. data/db/migrate/20140311161714_add_report_code_to_questions.rb +5 -0
  133. data/db/migrate/20140530181134_add_is_comment_to_questions.rb +5 -0
  134. data/db/migrate/20140531012006_add_is_comment_to_answers.rb +5 -0
  135. data/db/migrate/20140531225529_create_rows.rb +9 -0
  136. data/db/migrate/20140601011151_create_columns.rb +11 -0
  137. data/db/migrate/20140602030330_add_column_id_to_answers.rb +5 -0
  138. data/db/migrate/20140603155606_add_column_id_to_responses.rb +5 -0
  139. data/db/migrate/20140606023527_add_column_id_to_dependency_conditions.rb +5 -0
  140. data/db/migrate/20140815165307_add_user_id_to_survey.rb +5 -0
  141. data/lib/assets/.gitkeep +0 -0
  142. data/lib/assets/images/addicon.png +0 -0
  143. data/lib/assets/images/datepicker.gif +0 -0
  144. data/lib/assets/images/delete.gif +0 -0
  145. data/lib/assets/images/delete.png +0 -0
  146. data/lib/assets/images/images/border.png +0 -0
  147. data/lib/assets/images/images/controls.png +0 -0
  148. data/lib/assets/images/images/loading.gif +0 -0
  149. data/lib/assets/images/images/loading_background.png +0 -0
  150. data/lib/assets/images/images/overlay.png +0 -0
  151. data/lib/assets/images/rails.png +0 -0
  152. data/lib/assets/images/star.gif +0 -0
  153. data/lib/assets/javascripts/.gitkeep +0 -0
  154. data/lib/assets/javascripts/surveyor_gui/jquery.MetaData.js +121 -0
  155. data/lib/assets/javascripts/surveyor_gui/jquery.blockUI.js +619 -0
  156. data/lib/assets/javascripts/surveyor_gui/jquery.rating.js +377 -0
  157. data/lib/assets/javascripts/surveyor_gui/jquery.validate.js +1188 -0
  158. data/lib/assets/javascripts/surveyor_gui/surveyor_add_ons.js +10 -0
  159. data/lib/assets/javascripts/surveyor_gui/surveyor_gui.js +1417 -0
  160. data/lib/assets/stylesheets/.gitkeep +0 -0
  161. data/lib/assets/stylesheets/surveyor_gui/jquery.rating.css +12 -0
  162. data/lib/assets/stylesheets/surveyor_gui/surveyor_add_ons.css +3 -0
  163. data/lib/assets/stylesheets/surveyor_gui/surveyor_gui.sass +650 -0
  164. data/lib/enumerable_extenders.rb +31 -0
  165. data/lib/generators/surveyor_gui/install_generator.rb +57 -0
  166. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_add_ons.js +2 -0
  167. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_gui_all.js +24 -0
  168. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_add_ons.css.sass +1 -0
  169. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_gui_all.css.sass +8 -0
  170. data/lib/generators/surveyor_gui/templates/app/helpers/surveyor_helper.rb +4 -0
  171. data/lib/generators/surveyor_gui/templates/app/models/response_set_user.rb +13 -0
  172. data/lib/generators/surveyor_gui/templates/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  173. data/lib/generators/surveyor_gui/templates/config/initializers/simple_form.rb +140 -0
  174. data/lib/generators/surveyor_gui/templates/config/locales/en.yml +5 -0
  175. data/lib/surveyor_gui.rb +17 -0
  176. data/lib/surveyor_gui/engine.rb +30 -0
  177. data/lib/surveyor_gui/helpers/surveyor_helper_methods.rb +19 -0
  178. data/lib/surveyor_gui/models/answer_methods.rb +24 -0
  179. data/lib/surveyor_gui/models/column_methods.rb +43 -0
  180. data/lib/surveyor_gui/models/dependency_condition_methods.rb +53 -0
  181. data/lib/surveyor_gui/models/dependency_methods.rb +83 -0
  182. data/lib/surveyor_gui/models/question_and_group_shared_methods.rb +11 -0
  183. data/lib/surveyor_gui/models/question_group_methods.rb +55 -0
  184. data/lib/surveyor_gui/models/question_methods.rb +435 -0
  185. data/lib/surveyor_gui/models/question_type_methods.rb +493 -0
  186. data/lib/surveyor_gui/models/response_methods.rb +67 -0
  187. data/lib/surveyor_gui/models/response_set_methods.rb +54 -0
  188. data/lib/surveyor_gui/models/row_methods.rb +11 -0
  189. data/lib/surveyor_gui/models/survey_methods.rb +32 -0
  190. data/lib/surveyor_gui/models/survey_section_methods.rb +32 -0
  191. data/lib/surveyor_gui/surveyforms_controller_methods.rb +258 -0
  192. data/lib/surveyor_gui/version.rb +3 -0
  193. data/lib/tasks/.gitkeep +0 -0
  194. data/lib/tasks/surveyor_gui_tasks.rake +4 -0
  195. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  196. data/spec/controllers/surveyforms_controller_spec.rb +361 -0
  197. data/spec/controllers/surveyor_controller_spec.rb +303 -0
  198. data/spec/factories.rb +181 -0
  199. data/spec/features/create_survey_spec.rb +418 -0
  200. data/spec/features/dependencies_spec.rb +61 -0
  201. data/spec/features/rearrange_survey_spec.rb +118 -0
  202. data/spec/features/ui_spec.rb +469 -0
  203. data/spec/fixtures/REDCapDemoDatabase_DataDictionary.csv +127 -0
  204. data/spec/fixtures/chinese_survey.rb +14 -0
  205. data/spec/fixtures/everything.rb +215 -0
  206. data/spec/fixtures/favorites-ish.rb +22 -0
  207. data/spec/fixtures/favorites.rb +22 -0
  208. data/spec/fixtures/feelings.rb +38 -0
  209. data/spec/fixtures/lifestyle.rb +55 -0
  210. data/spec/fixtures/numbers.rb +21 -0
  211. data/spec/fixtures/redcap_new_headers.csv +1 -0
  212. data/spec/fixtures/redcap_siblings.csv +1 -0
  213. data/spec/fixtures/redcap_whitespace.csv +1 -0
  214. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  215. data/spec/helpers/surveyor_helper_spec.rb +116 -0
  216. data/spec/lib/common_spec.rb +37 -0
  217. data/spec/lib/parser_spec.rb +393 -0
  218. data/spec/lib/rake_kitchen_sink.rb +42 -0
  219. data/spec/lib/redcap_parser_spec.rb +129 -0
  220. data/spec/lib/unparser_spec.rb +126 -0
  221. data/spec/models/answer_spec.rb +144 -0
  222. data/spec/models/dependency_condition_spec.rb +428 -0
  223. data/spec/models/dependency_spec.rb +90 -0
  224. data/spec/models/question_group_spec.rb +66 -0
  225. data/spec/models/question_spec.rb +176 -0
  226. data/spec/models/response_set_spec.rb +452 -0
  227. data/spec/models/response_spec.rb +208 -0
  228. data/spec/models/survey_section_spec.rb +58 -0
  229. data/spec/models/survey_spec.rb +155 -0
  230. data/spec/models/surveyor_gui/question_spec.rb +60 -0
  231. data/spec/models/surveyor_gui/question_type_spec.rb +268 -0
  232. data/spec/models/validation_condition_spec.rb +98 -0
  233. data/spec/models/validation_spec.rb +64 -0
  234. data/spec/spec.opts +4 -0
  235. data/spec/spec_helper.rb +119 -0
  236. data/spec/support/scenario_outline_helper.rb +39 -0
  237. data/spec/support/shared.rb +10 -0
  238. data/spec/support/surveyforms_creation_helpers.rb +312 -0
  239. data/spec/support/surveyforms_rearrangement_helpers.rb +170 -0
  240. data/spec/support/surveyor_api_helpers.rb +15 -0
  241. data/spec/support/surveyor_ui_helpers.rb +108 -0
  242. data/spec/support/wait_for_ajax.rb +11 -0
  243. data/spec/views/questions/edit.html.erb_spec.rb +73 -0
  244. data/spec/views/surveyforms/edit.html.erb_spec.rb +126 -0
  245. data/surveyor_gui.gemspec +52 -0
  246. data/test/dummy/README.rdoc +261 -0
  247. data/test/dummy/Rakefile +7 -0
  248. data/test/dummy/app/assets/javascripts/application.js +15 -0
  249. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  250. data/test/dummy/app/controllers/application_controller.rb +3 -0
  251. data/test/dummy/app/helpers/application_helper.rb +2 -0
  252. data/test/dummy/app/mailers/.gitkeep +0 -0
  253. data/test/dummy/app/models/.gitkeep +0 -0
  254. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  255. data/test/dummy/config.ru +4 -0
  256. data/test/dummy/config/application.rb +59 -0
  257. data/test/dummy/config/boot.rb +10 -0
  258. data/test/dummy/config/database.yml +25 -0
  259. data/test/dummy/config/environment.rb +5 -0
  260. data/test/dummy/config/environments/development.rb +37 -0
  261. data/test/dummy/config/environments/production.rb +67 -0
  262. data/test/dummy/config/environments/test.rb +37 -0
  263. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  264. data/test/dummy/config/initializers/inflections.rb +15 -0
  265. data/test/dummy/config/initializers/mime_types.rb +5 -0
  266. data/test/dummy/config/initializers/secret_token.rb +7 -0
  267. data/test/dummy/config/initializers/session_store.rb +8 -0
  268. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +58 -0
  271. data/test/dummy/lib/assets/.gitkeep +0 -0
  272. data/test/dummy/log/.gitkeep +0 -0
  273. data/test/dummy/public/404.html +26 -0
  274. data/test/dummy/public/422.html +26 -0
  275. data/test/dummy/public/500.html +25 -0
  276. data/test/dummy/public/favicon.ico +0 -0
  277. data/test/dummy/script/rails +6 -0
  278. data/test/surveyor-gui_test.rb +7 -0
  279. data/test/test_helper.rb +15 -0
  280. data/vendor/assets/stylesheets/.gitkeep +0 -0
  281. data/vendor/assets/stylesheets/custom.sass +5 -0
  282. data/vendor/plugins/.gitkeep +0 -0
  283. metadata +664 -0
@@ -0,0 +1,208 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Response, "when saving a response" do
4
+ before(:each) do
5
+ # @response = Response.new(:question_id => 314, :response_set_id => 159, :answer_id => 1)
6
+ @response = FactoryGirl.create(:response, :question => FactoryGirl.create(:question), :answer => FactoryGirl.create(:answer))
7
+ end
8
+
9
+ it "should be valid" do
10
+ @response.should be_valid
11
+ end
12
+
13
+ it "should be invalid without a question" do
14
+ @response.question_id = nil
15
+ @response.should have(1).error_on(:question_id)
16
+ end
17
+
18
+ it "should be correct if the question has no correct_answer_id" do
19
+ @response.question.correct_answer_id.should be_nil
20
+ @response.correct?.should be_true
21
+ end
22
+
23
+ it "should be correct if the answer's response class != answer" do
24
+ @response.answer.response_class.should_not == "answer"
25
+ @response.correct?.should be_true
26
+ end
27
+
28
+ it "should be (in)correct if answer_id is (not) equal to question's correct_answer_id" do
29
+ @answer = FactoryGirl.create(:answer, :response_class => "answer")
30
+ @question = FactoryGirl.create(:question, :correct_answer => @answer)
31
+ @response = FactoryGirl.create(:response, :question => @question, :answer => @answer)
32
+ @response.correct?.should be_true
33
+ @response.answer = FactoryGirl.create(:answer, :response_class => "answer").tap { |a| a.id = 143 }
34
+ @response.correct?.should be_false
35
+ end
36
+
37
+ it "should be in order by created_at" do
38
+ @response.response_set.should_not be_nil
39
+ response2 = FactoryGirl.create(:response, :question => FactoryGirl.create(:question), :answer => FactoryGirl.create(:answer), :response_set => @response.response_set, :created_at => (@response.created_at + 1))
40
+ Response.all.should == [@response, response2]
41
+ end
42
+
43
+ describe "returns the response as the type requested" do
44
+ it "returns 'string'" do
45
+ @response.string_value = "blah"
46
+ @response.as("string").should == "blah"
47
+ @response.as(:string).should == "blah"
48
+ end
49
+
50
+ it "returns 'integer'" do
51
+ @response.integer_value = 1001
52
+ @response.as(:integer).should == 1001
53
+ end
54
+
55
+ it "returns 'float'" do
56
+ @response.float_value = 3.14
57
+ @response.as(:float).should == 3.14
58
+ end
59
+
60
+ it "returns 'answer'" do
61
+ @response.answer_id = 14
62
+ @response.as(:answer).should == 14
63
+ end
64
+
65
+ it "default returns answer type if not specified" do
66
+ @response.answer_id =18
67
+ @response.as(:stuff).should == 18
68
+ end
69
+
70
+ it "returns empty elements if the response is cast as a type that is not present" do
71
+ resp = Response.new(:question_id => 314, :response_set_id => 156)
72
+ resp.as(:string).should == nil
73
+ resp.as(:integer).should == nil
74
+ resp.as(:float).should == nil
75
+ resp.as(:answer).should == nil
76
+ resp.as(:stuff).should == nil
77
+ end
78
+ end
79
+ end
80
+
81
+ describe Response, "applicable_attributes" do
82
+ before(:each) do
83
+ @who = FactoryGirl.create(:question, :text => "Who rules?")
84
+ @odoyle = FactoryGirl.create(:answer, :text => "Odoyle", :response_class => "answer")
85
+ @other = FactoryGirl.create(:answer, :text => "Other", :response_class => "string")
86
+ end
87
+
88
+ it "should have string_value if response_type is string" do
89
+ good = {"question_id" => @who.id, "answer_id" => @other.id, "string_value" => "Frank"}
90
+ Response.applicable_attributes(good).should == good
91
+ end
92
+
93
+ it "should not have string_value if response_type is answer" do
94
+ bad = {"question_id"=>@who.id, "answer_id"=>@odoyle.id, "string_value"=>"Frank"}
95
+ Response.applicable_attributes(bad).
96
+ should == {"question_id" => @who.id, "answer_id"=> @odoyle.id}
97
+ end
98
+
99
+ it "should have string_value if response_type is string and answer_id is an array (in the case of checkboxes)" do
100
+ good = {"question_id"=>@who.id, "answer_id"=>["", @odoyle.id], "string_value"=>"Frank"}
101
+ Response.applicable_attributes(good).
102
+ should == {"question_id" => @who.id, "answer_id"=> ["", @odoyle.id]}
103
+ end
104
+
105
+ it "should have ignore attribute if missing answer_id" do
106
+ ignore = {"question_id"=>@who.id, "answer_id"=>"", "string_value"=>"Frank"}
107
+ Response.applicable_attributes(ignore).
108
+ should == {"question_id"=>@who.id, "answer_id"=>"", "string_value"=>"Frank"}
109
+ end
110
+
111
+ it "should have ignore attribute if missing answer_id is an array" do
112
+ ignore = {"question_id"=>@who.id, "answer_id"=>[""], "string_value"=>"Frank"}
113
+ Response.applicable_attributes(ignore).
114
+ should == {"question_id"=>@who.id, "answer_id"=>[""], "string_value"=>"Frank"}
115
+ end
116
+ end
117
+
118
+ describe Response, '#to_formatted_s' do
119
+ context "when datetime" do
120
+ let(:r) { Response.new(:answer => Answer.new(:response_class => 'datetime')) }
121
+
122
+ it 'returns "" when nil' do
123
+ pending "bug fix in a37c4e1d99ce7fda39bf292584730ae6af640915 issue 459"
124
+ r.datetime_value = nil
125
+
126
+ r.to_formatted_s.should == ""
127
+ end
128
+ end
129
+ end
130
+
131
+ describe Response, '#json_value' do
132
+ context "when integer" do
133
+ let(:r) {Response.new(:integer_value => 2, :answer => Answer.new(:response_class => 'integer'))}
134
+ it "should be 2" do
135
+ r.json_value.should == 2
136
+ end
137
+ end
138
+
139
+ context "when float" do
140
+ let(:r) {Response.new(:float_value => 3.14, :answer => Answer.new(:response_class => 'float'))}
141
+ it "should be 3.14" do
142
+ r.json_value.should == 3.14
143
+ end
144
+ end
145
+
146
+ context "when string" do
147
+ let(:r) {Response.new(:string_value => 'bar', :answer => Answer.new(:response_class => 'string'))}
148
+ it "should be 'bar'" do
149
+ r.json_value.should == 'bar'
150
+ end
151
+ end
152
+
153
+ context "when datetime" do
154
+ let(:r) {Response.new(:datetime_value => DateTime.strptime('2010-04-08T10:30+00:00', '%Y-%m-%dT%H:%M%z'), :answer => Answer.new(:response_class => 'datetime'))}
155
+ it "should be '2010-04-08T10:30+00:00'" do
156
+ r.json_value.should == '2010-04-08T10:30+00:00'
157
+ r.json_value.to_json.should == '"2010-04-08T10:30+00:00"'
158
+ end
159
+ end
160
+
161
+ context "when date" do
162
+ let(:r) {Response.new(:datetime_value => DateTime.strptime('2010-04-08', '%Y-%m-%d'), :answer => Answer.new(:response_class => 'date'))}
163
+ it "should be '2010-04-08'" do
164
+ r.json_value.should == '2010-04-08'
165
+ r.json_value.to_json.should == '"2010-04-08"'
166
+ end
167
+ end
168
+
169
+ context "when time" do
170
+ let(:r) {Response.new(:datetime_value => DateTime.strptime('10:30', '%H:%M'), :answer => Answer.new(:response_class => 'time'))}
171
+ it "should be '10:30'" do
172
+ r.json_value.should == '10:30'
173
+ r.json_value.to_json.should == '"10:30"'
174
+ end
175
+ end
176
+ end
177
+
178
+ describe Response, 'value methods' do
179
+ let(:response) { Response.new }
180
+
181
+ describe '#date_value=' do
182
+ it 'accepts a parseable date string' do
183
+ response.date_value = '2010-01-15'
184
+ response.datetime_value.strftime('%Y %m %d').should == '2010 01 15'
185
+ end
186
+
187
+ it 'clears when given nil' do
188
+ pending "bug fix in 04b9dd4c71cc6e1c1df546d81b0f46aa2f0b7a04"
189
+ response.datetime_value = Time.new
190
+ response.date_value = nil
191
+ response.datetime_value.should be_nil
192
+ end
193
+ end
194
+
195
+ describe 'time_value=' do
196
+ it 'accepts a parseable time string' do
197
+ response.time_value = '11:30'
198
+ response.datetime_value.strftime('%H %M %S').should == '11 30 00'
199
+ end
200
+
201
+ it 'clears when given nil' do
202
+ pending "bug fix in 04b9dd4c71cc6e1c1df546d81b0f46aa2f0b7a04"
203
+ response.datetime_value = Time.new
204
+ response.time_value = nil
205
+ response.datetime_value.should be_nil
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe SurveySection do
5
+ let(:survey_section){ FactoryGirl.create(:survey_section) }
6
+
7
+ context "when creating" do
8
+ it "is invalid without #title" do
9
+ survey_section.title = nil
10
+ survey_section.should have(1).error_on(:title)
11
+ end
12
+ end
13
+
14
+ context "with questions" do
15
+ let(:question_1){ FactoryGirl.create(:question, :survey_section => survey_section, :display_order => 3, :text => "Peep")}
16
+ let(:question_2){ FactoryGirl.create(:question, :survey_section => survey_section, :display_order => 1, :text => "Little")}
17
+ let(:question_3){ FactoryGirl.create(:question, :survey_section => survey_section, :display_order => 2, :text => "Bo")}
18
+ before do
19
+ [question_1, question_2, question_3].each{|q| survey_section.questions << q }
20
+ end
21
+ it{ survey_section.should have(3).questions}
22
+ it "gets questions in order" do
23
+ survey_section.questions.order("display_order asc").should == [question_2, question_3, question_1]
24
+ survey_section.questions.order("display_order asc").map(&:display_order).should == [1,2,3]
25
+ end
26
+ it "deletes child questions when deleted" do
27
+ question_ids = survey_section.questions.map(&:id)
28
+ survey_section.destroy
29
+ question_ids.each{|id| Question.find_by_id(id).should be_nil}
30
+ end
31
+ end
32
+
33
+ context "with translations" do
34
+ require 'yaml'
35
+ let(:survey){ FactoryGirl.create(:survey) }
36
+ let(:survey_translation){
37
+ FactoryGirl.create(:survey_translation, :locale => :es, :translation => {
38
+ :survey_sections => {
39
+ :one => {
40
+ :title => "Uno"
41
+ }
42
+ }
43
+ }.to_yaml)
44
+ }
45
+ before do
46
+ survey_section.reference_identifier = "one"
47
+ survey_section.survey = survey
48
+ survey.translations << survey_translation
49
+ end
50
+ it "returns its own translation" do
51
+ YAML.load(survey_translation.translation).should_not be_nil
52
+ survey_section.translation(:es)[:title].should == "Uno"
53
+ end
54
+ it "returns its own default values" do
55
+ survey_section.translation(:de).should == {"title" => survey_section.title, "description" => survey_section.description}
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,155 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Survey do
5
+ let(:survey){ FactoryGirl.create(:survey) }
6
+
7
+ context "when creating" do
8
+ it "is invalid without #title" do
9
+ survey.title = nil
10
+ survey.should have(1).error_on :title
11
+ end
12
+ it "adjust #survey_version" do
13
+ original = Survey.new(:title => "Foo")
14
+ original.save.should be_true
15
+ original.survey_version.should == 0
16
+ imposter = Survey.new(:title => "Foo")
17
+ imposter.save.should be_true
18
+ imposter.title.should == "Foo"
19
+ imposter.survey_version.should == 1
20
+ bandwagoneer = Survey.new(:title => "Foo")
21
+ bandwagoneer.save.should be_true
22
+ bandwagoneer.title.should == "Foo"
23
+ bandwagoneer.survey_version.should == 2
24
+ end
25
+ it "prevents duplicate #survey_version" do
26
+ original = Survey.new(:title => "Foo")
27
+ original.save.should be_true
28
+ imposter = Survey.new(:title => "Foo")
29
+ imposter.save.should be_true
30
+ imposter.survey_version = 0
31
+ imposter.save.should be_false
32
+ imposter.should have(1).error_on(:survey_version)
33
+ end
34
+ it "doesn't adjust #title when" do
35
+ original = FactoryGirl.create(:survey, :title => "Foo")
36
+ original.save.should be_true
37
+ original.update_attributes(:title => "Foo")
38
+ original.title.should == "Foo"
39
+ end
40
+ it "has #api_id with 36 characters by default" do
41
+ survey.api_id.length.should == 36
42
+ end
43
+ end
44
+
45
+ context "activating" do
46
+ it { survey.active?.should }
47
+ it "both #inactive_at and #active_at == nil by default" do
48
+ survey.active_at.should be_nil
49
+ survey.inactive_at.should be_nil
50
+ end
51
+ it "#active_at on a certain date/time" do
52
+ survey.inactive_at = 2.days.from_now
53
+ survey.active_at = 2.days.ago
54
+ survey.active?.should be_true
55
+ end
56
+ it "#inactive_at on a certain date/time" do
57
+ survey.active_at = 3.days.ago
58
+ survey.inactive_at = 1.days.ago
59
+ survey.active?.should be_false
60
+ end
61
+ it "#activate! and #deactivate!" do
62
+ survey.activate!
63
+ survey.active?.should be_true
64
+ survey.deactivate!
65
+ survey.active?.should be_false
66
+ end
67
+ it "nils out past values of #inactive_at on #activate!" do
68
+ survey.inactive_at = 5.days.ago
69
+ survey.active?.should be_false
70
+ survey.activate!
71
+ survey.active?.should be_true
72
+ survey.inactive_at.should be_nil
73
+ end
74
+ it "nils out pas values of #active_at on #deactivate!" do
75
+ survey.active_at = 5.days.ago
76
+ survey.active?.should be_true
77
+ survey.deactivate!
78
+ survey.active?.should be_false
79
+ survey.active_at.should be_nil
80
+ end
81
+ end
82
+
83
+ context "with survey_sections" do
84
+ let(:s1){ FactoryGirl.create(:survey_section, :survey => survey, :title => "wise", :display_order => 2)}
85
+ let(:s2){ FactoryGirl.create(:survey_section, :survey => survey, :title => "er", :display_order => 3)}
86
+ let(:s3){ FactoryGirl.create(:survey_section, :survey => survey, :title => "bud", :display_order => 1)}
87
+ let(:q1){ FactoryGirl.create(:question, :survey_section => s1, :text => "what is wise?", :display_order => 2)}
88
+ let(:q2){ FactoryGirl.create(:question, :survey_section => s2, :text => "what is er?", :display_order => 4)}
89
+ let(:q3){ FactoryGirl.create(:question, :survey_section => s2, :text => "what is mill?", :display_order => 3)}
90
+ let(:q4){ FactoryGirl.create(:question, :survey_section => s3, :text => "what is bud?", :display_order => 1)}
91
+ before do
92
+ [s1, s2, s3].each{|s| survey.sections << s }
93
+ s1.questions << q1
94
+ s2.questions << q2
95
+ s2.questions << q3
96
+ s3.questions << q4
97
+ end
98
+
99
+ it{ survey.should have(3).sections}
100
+ it "gets survey_sections in order" do
101
+ survey.sections.order("display_order asc").should == [s3, s1, s2]
102
+ survey.sections.order("display_order asc").map(&:display_order).should == [1,2,3]
103
+ end
104
+ it "gets survey_sections_with_questions in order" do
105
+ survey.sections.order("display_order asc").map{|ss| ss.questions.order("display_order asc")}.flatten.should have(4).questions
106
+ survey.sections.order("display_order asc").map{|ss| ss.questions.order("display_order asc")}.flatten.should == [q4,q1,q3,q2]
107
+ end
108
+ it "deletes child survey_sections when deleted" do
109
+ survey_section_ids = survey.sections.map(&:id)
110
+ survey.destroy
111
+ survey_section_ids.each{|id| SurveySection.find_by_id(id).should be_nil}
112
+ end
113
+ end
114
+
115
+ context "serialization" do
116
+ let(:s1){ FactoryGirl.create(:survey_section, :survey => survey, :title => "wise") }
117
+ let(:s2){ FactoryGirl.create(:survey_section, :survey => survey, :title => "er") }
118
+ let(:q1){ FactoryGirl.create(:question, :survey_section => s1, :text => "what is wise?") }
119
+ let(:q2){ FactoryGirl.create(:question, :survey_section => s2, :text => "what is er?") }
120
+ let(:q3){ FactoryGirl.create(:question, :survey_section => s2, :text => "what is mill?") }
121
+ before do
122
+ [s1, s2].each{|s| survey.sections << s }
123
+ s1.questions << q1
124
+ s2.questions << q2
125
+ s2.questions << q3
126
+ end
127
+
128
+ it "includes title, sections, and questions" do
129
+ actual = survey.as_json
130
+ actual[:title].should == 'Simple survey'
131
+ actual[:sections].size.should == 2
132
+ actual[:sections][0][:questions_and_groups].size.should == 1
133
+ actual[:sections][1][:questions_and_groups].size.should == 2
134
+ end
135
+ end
136
+
137
+ context "with translations" do
138
+ require 'yaml'
139
+ let(:survey_translation){
140
+ FactoryGirl.create(:survey_translation, :locale => :es, :translation => {
141
+ :title => "Un idioma nunca es suficiente"
142
+ }.to_yaml)
143
+ }
144
+ before do
145
+ survey.translations << survey_translation
146
+ end
147
+ it "returns its own translation" do
148
+ YAML.load(survey_translation.translation).should_not be_nil
149
+ survey.translation(:es)[:title].should == "Un idioma nunca es suficiente"
150
+ end
151
+ it "returns its own default values" do
152
+ survey.translation(:de).should == {"title" => survey.title, "description" => survey.description}
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+
4
+ describe Question do
5
+ let(:question){ FactoryGirl.create(:question) }
6
+ let(:question2){ FactoryGirl.create(:question, question_type_id: "pick_one")}
7
+
8
+ def build_answers_from_answers_textbox
9
+ question2.answers_textbox = "blue\nred\ngreen"
10
+ question2.save
11
+ question2.reload
12
+ expect(question2.answers.count).to eq 3
13
+ expect(question2.answers.where('text=?','blue').first.display_order).to eq 0
14
+ expect(question2.answers.where('text=?','red').first.display_order).to eq 1
15
+ expect(question2.answers.where('text=?','green').first.display_order).to eq 2
16
+ end
17
+
18
+ context "without answers" do
19
+
20
+ it "builds answers from the answers_textbox field" do
21
+ build_answers_from_answers_textbox
22
+ end
23
+
24
+ end
25
+
26
+ context "with answers" do
27
+ let(:answer_1){ FactoryGirl.create(:answer, :question => question2, :display_order => 3, response_class: "answer", :text => "blue")}
28
+ let(:answer_2){ FactoryGirl.create(:answer, :question => question2, :display_order => 1, response_class: "answer", :text => "red")}
29
+ let(:answer_3){ FactoryGirl.create(:answer, :question => question2, :display_order => 2, response_class: "answer", :text => "green")}
30
+ before do
31
+ [answer_1, answer_2, answer_3].each{|a| question2.answers << a }
32
+ end
33
+
34
+ it "builds an answers_textbox field sorted by display_order" do
35
+ expect(question2.answers_textbox).to match /red\ngreen\nblue/
36
+ end
37
+
38
+ it "does not duplicate answers with lines from answers_textbox" do
39
+ build_answers_from_answers_textbox
40
+ end
41
+
42
+ context "when deleting" do
43
+ before do
44
+ question2.answers_textbox = "blue\ngreen"
45
+ question2.save
46
+ question2.reload
47
+ end
48
+
49
+ it "deletes answers that are not in answers_textbox" do
50
+ expect(question2.answers.to_s).not_to match "red"
51
+ end
52
+
53
+ it "maintains the correct display order after deleting an answer" do
54
+ expect(question2.answers.where('text=?','blue').first.display_order).to eq 0
55
+ expect(question2.answers.where('text=?','green').first.display_order).to eq 1
56
+ end
57
+ end
58
+ end
59
+
60
+ end