rapidfire 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -13
  3. data/app/controllers/rapidfire/attempts_controller.rb +29 -0
  4. data/app/controllers/rapidfire/questions_controller.rb +35 -34
  5. data/app/controllers/rapidfire/surveys_controller.rb +60 -0
  6. data/app/models/rapidfire/answer.rb +3 -3
  7. data/app/models/rapidfire/attempt.rb +11 -0
  8. data/app/models/rapidfire/question.rb +3 -3
  9. data/app/models/rapidfire/{question_group.rb → survey.rb} +1 -1
  10. data/app/services/rapidfire/{answer_group_builder.rb → attempt_builder.rb} +12 -12
  11. data/app/services/rapidfire/base_service.rb +1 -1
  12. data/app/services/rapidfire/question_form.rb +4 -4
  13. data/app/services/rapidfire/{question_group_results.rb → survey_results.rb} +3 -3
  14. data/app/views/rapidfire/{answer_groups → attempts}/new.html.erb +2 -2
  15. data/app/views/rapidfire/questions/_question.html.erb +2 -2
  16. data/app/views/rapidfire/questions/edit.html.erb +1 -1
  17. data/app/views/rapidfire/questions/index.html.erb +1 -1
  18. data/app/views/rapidfire/questions/new.html.erb +1 -1
  19. data/app/views/rapidfire/surveys/_form.html.erb +15 -0
  20. data/app/views/rapidfire/surveys/_survey.html.erb +18 -0
  21. data/app/views/rapidfire/{question_groups → surveys}/index.html.erb +4 -4
  22. data/app/views/rapidfire/surveys/new.html.erb +1 -0
  23. data/app/views/rapidfire/{question_groups → surveys}/results.html.erb +1 -1
  24. data/config/routes.rb +3 -3
  25. data/db/migrate/20130502170733_create_rapidfire_question_groups.rb +1 -1
  26. data/db/migrate/20130502195310_create_rapidfire_questions.rb +2 -2
  27. data/db/migrate/20130502195415_create_rapidfire_answer_groups.rb +4 -4
  28. data/db/migrate/20130502195504_create_rapidfire_answers.rb +2 -2
  29. data/lib/generators/rapidfire/templates/migrations/rename_answer_groups_and_question_groups.rb +9 -0
  30. data/lib/generators/rapidfire/upgrade_migration_generator.rb +18 -0
  31. data/lib/generators/rapidfire/views_generator.rb +4 -4
  32. data/lib/rapidfire/version.rb +1 -1
  33. data/lib/tasks/rapidfire.rake +10 -0
  34. data/spec/controllers/rapidfire/attempts_controller_spec.rb +20 -0
  35. data/spec/dummy/README.rdoc +261 -0
  36. data/spec/dummy/Rakefile +7 -0
  37. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  38. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  39. data/spec/dummy/app/controllers/application_controller.rb +11 -0
  40. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  41. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  42. data/spec/dummy/config.ru +4 -0
  43. data/spec/dummy/config/application.rb +61 -0
  44. data/spec/dummy/config/boot.rb +10 -0
  45. data/spec/dummy/config/database.yml +25 -0
  46. data/spec/dummy/config/environment.rb +5 -0
  47. data/spec/dummy/config/environments/development.rb +41 -0
  48. data/spec/dummy/config/environments/production.rb +72 -0
  49. data/spec/dummy/config/environments/test.rb +41 -0
  50. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  51. data/spec/dummy/config/initializers/inflections.rb +15 -0
  52. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  53. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  54. data/spec/dummy/config/initializers/session_store.rb +8 -0
  55. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  56. data/spec/dummy/config/locales/en.yml +5 -0
  57. data/spec/dummy/config/routes.rb +4 -0
  58. data/spec/dummy/db/development.sqlite3 +0 -0
  59. data/spec/dummy/db/schema.rb +53 -0
  60. data/spec/dummy/db/test.sqlite3 +0 -0
  61. data/spec/dummy/log/development.log +394 -0
  62. data/spec/dummy/log/test.log +2380 -0
  63. data/spec/dummy/public/404.html +26 -0
  64. data/spec/dummy/public/422.html +26 -0
  65. data/spec/dummy/public/500.html +25 -0
  66. data/spec/dummy/public/favicon.ico +0 -0
  67. data/spec/dummy/script/rails +6 -0
  68. data/spec/factories/answers_factory.rb +7 -0
  69. data/spec/factories/attempts_factory.rb +5 -0
  70. data/spec/factories/questions_factory.rb +30 -0
  71. data/spec/factories/surveys_factory.rb +5 -0
  72. data/spec/features/rapidfire/answering_questions_spec.rb +55 -0
  73. data/spec/features/rapidfire/managing_questions_spec.rb +95 -0
  74. data/spec/features/rapidfire/managing_surveys_spec.rb +141 -0
  75. data/spec/models/rapidfire/answer_spec.rb +23 -0
  76. data/spec/models/rapidfire/attempt_spec.rb +9 -0
  77. data/spec/models/rapidfire/question_spec.rb +123 -0
  78. data/spec/models/rapidfire/questions/checkbox_spec.rb +90 -0
  79. data/spec/models/rapidfire/questions/date_spec.rb +78 -0
  80. data/spec/models/rapidfire/questions/numeric_spec.rb +114 -0
  81. data/spec/models/rapidfire/questions/select_spec.rb +90 -0
  82. data/spec/models/rapidfire/survey_spec.rb +11 -0
  83. data/spec/serializers/rapidfire/question_result_serializer_spec.rb +44 -0
  84. data/spec/services/rapidfire/attempt_builder_spec.rb +88 -0
  85. data/spec/services/rapidfire/question_form_spec.rb +93 -0
  86. data/spec/services/rapidfire/survey_results_spec.rb +63 -0
  87. data/spec/spec_helper.rb +68 -0
  88. data/spec/support/rapidfire/answer_spec_helper.rb +23 -0
  89. data/spec/support/rapidfire/question_spec_helper.rb +13 -0
  90. data/spec/tasks/change_delimiter_from_comma_to_srsn_spec.rb +31 -0
  91. metadata +133 -30
  92. data/app/controllers/rapidfire/answer_groups_controller.rb +0 -29
  93. data/app/controllers/rapidfire/question_groups_controller.rb +0 -59
  94. data/app/models/rapidfire/answer_group.rb +0 -11
  95. data/app/views/rapidfire/question_groups/_form.html.erb +0 -15
  96. data/app/views/rapidfire/question_groups/_question_group.html.erb +0 -18
  97. data/app/views/rapidfire/question_groups/new.html.erb +0 -1
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/404.html -->
21
+ <div class="dialog">
22
+ <h1>The page you were looking for doesn't exist.</h1>
23
+ <p>You may have mistyped the address or the page may have moved.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :answer, :class => "Rapidfire::Answer" do
3
+ attempt { FactoryGirl.create(:attempt) }
4
+ question { FactoryGirl.create(:q_long) }
5
+ answer_text "hello world"
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :attempt, :class => "Rapidfire::Attempt" do
3
+ survey { FactoryGirl.create(:survey) }
4
+ end
5
+ end
@@ -0,0 +1,30 @@
1
+ FactoryGirl.define do
2
+ factory :question do
3
+ survey { FactoryGirl.create(:survey) }
4
+ question_text "Sample Question"
5
+
6
+ factory :q_checkbox, :class => "Rapidfire::Questions::Checkbox" do
7
+ answer_options "hindi\r\ntelugu\r\nkannada\r\n"
8
+ end
9
+
10
+ factory :q_date, :class => "Rapidfire::Questions::Date" do
11
+ end
12
+
13
+ factory :q_long, :class => "Rapidfire::Questions::Long" do
14
+ end
15
+
16
+ factory :q_numeric, :class => "Rapidfire::Questions::Numeric" do
17
+ end
18
+
19
+ factory :q_radio, :class => "Rapidfire::Questions::Radio" do
20
+ answer_options "male\r\nfemale\r\n"
21
+ end
22
+
23
+ factory :q_select, :class => "Rapidfire::Questions::Select" do
24
+ answer_options "mac\r\nwindows\r\n"
25
+ end
26
+
27
+ factory :q_short, :class => "Rapidfire::Questions::Short" do
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :survey, :class => "Rapidfire::Survey" do
3
+ name "Survey"
4
+ end
5
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Surveys" do
4
+ let(:survey) { FactoryGirl.create(:survey, name: "Question Set") }
5
+ let(:question1) { FactoryGirl.create(:q_long, survey: survey, question_text: "Long Question", validation_rules: { presence: "1" }) }
6
+ let(:question2) { FactoryGirl.create(:q_short, survey: survey, question_text: "Short Question") }
7
+ before do
8
+ [question1, question2]
9
+ visit rapidfire.new_survey_attempt_path(survey)
10
+ end
11
+
12
+ describe "Answering Questions" do
13
+ context "when all questions are answered" do
14
+ before do
15
+ fill_in "attempt_#{question1.id}_answer_text", with: "Long Answer"
16
+ fill_in "attempt_#{question2.id}_answer_text", with: "Short Answer"
17
+ click_button "Save"
18
+ end
19
+
20
+ it "persists 2 answers" do
21
+ expect(Rapidfire::Answer.count).to eq(2)
22
+ end
23
+
24
+ it "persists 2 answers with answer values" do
25
+ expected_answers = ["Long Answer", "Short Answer"]
26
+ expect(Rapidfire::Answer.all.map(&:answer_text)).to match(expected_answers)
27
+ end
28
+
29
+ it "redirects to question groups path" do
30
+ expect(current_path).to eq(rapidfire.surveys_path)
31
+ end
32
+ end
33
+
34
+ context "when all questions are not answered" do
35
+ before do
36
+ fill_in "attempt_#{question1.id}_answer_text", with: ""
37
+ fill_in "attempt_#{question2.id}_answer_text", with: "Short Answer"
38
+ click_button "Save"
39
+ end
40
+
41
+ it "fails to persits answers" do
42
+ expect(Rapidfire::Answer.count).to eq(0)
43
+ end
44
+
45
+ it "shows error for missing answers" do
46
+ expect(page).to have_content "can't be blank"
47
+ end
48
+
49
+ it "shows already populated answers" do
50
+ short_answer = page.find("#attempt_#{question2.id}_answer_text").value
51
+ expect(short_answer).to have_content "Short Answer"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Questions" do
4
+ let(:survey) { FactoryGirl.create(:survey, name: "Question Set") }
5
+ let(:question1) { FactoryGirl.create(:q_long, survey: survey, question_text: "Long Question") }
6
+ let(:question2) { FactoryGirl.create(:q_short, survey: survey, question_text: "Short Question") }
7
+ before do
8
+ [question1, question2]
9
+ end
10
+
11
+ describe "DELETE Question" do
12
+ before do
13
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
14
+ visit rapidfire.survey_questions_path(survey)
15
+
16
+ page.within("#question_#{question1.id}") do
17
+ click_link "Delete"
18
+ end
19
+ end
20
+
21
+ it "deletes the questions" do
22
+ expect(page).not_to have_content question1.question_text
23
+ end
24
+ end
25
+
26
+ describe "CREATING Question" do
27
+ before do
28
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
29
+ visit rapidfire.survey_questions_path(survey)
30
+ click_link "New Question"
31
+ end
32
+
33
+ context "when name is present" do
34
+ before do
35
+ page.within("#new_question") do
36
+ fill_in "question_question_text", with: "Which OS?"
37
+ fill_in "question_answer_options", with: "mac\r\nwindows"
38
+ click_button "Create Question"
39
+ end
40
+ end
41
+
42
+ it "creates question" do
43
+ expect(page).to have_content "Which OS?"
44
+ end
45
+ end
46
+
47
+ context "when name is not present" do
48
+ before do
49
+ page.within("#new_question") do
50
+ click_button "Create Question"
51
+ end
52
+ end
53
+
54
+ it "fails to create survey" do
55
+ page.within("#new_question") do
56
+ expect(page).to have_content "can't be blank"
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "UPDATING Question" do
63
+ before do
64
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
65
+ visit rapidfire.survey_questions_path(survey)
66
+ page.within("#question_#{question1.id}") do
67
+ click_link "Edit"
68
+ end
69
+ end
70
+
71
+ context "when name is modified" do
72
+ before do
73
+ fill_in "question_question_text", with: "Updated Question"
74
+ click_button "Update Question"
75
+ end
76
+
77
+ it "updates question" do
78
+ page.within("#question_#{question1.id}") do
79
+ expect(page).to have_content "Updated Question"
80
+ end
81
+ end
82
+ end
83
+
84
+ context "when name is not present" do
85
+ before do
86
+ fill_in "question_question_text", with: ""
87
+ click_button "Update Question"
88
+ end
89
+
90
+ it "fails to update question" do
91
+ expect(page).to have_content "can't be blank"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Surveys" do
4
+ include Rapidfire::QuestionSpecHelper
5
+ include Rapidfire::AnswerSpecHelper
6
+
7
+ let(:survey) { FactoryGirl.create(:survey, name: "Question Set") }
8
+ let(:question1) { FactoryGirl.create(:q_long, survey: survey, question_text: "Long Question") }
9
+ let(:question2) { FactoryGirl.create(:q_short, survey: survey, question_text: "Short Question") }
10
+ before do
11
+ [question1, question2]
12
+ end
13
+
14
+ describe "INDEX surveys" do
15
+ before do
16
+ visit rapidfire.root_path
17
+ end
18
+
19
+ it "lists all surveys" do
20
+ expect(page).to have_content survey.name
21
+ end
22
+ end
23
+
24
+ describe "DELETE surveys" do
25
+ context "when user can administer" do
26
+ before do
27
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
28
+
29
+ visit rapidfire.root_path
30
+ click_link "Delete"
31
+ end
32
+
33
+ it "deletes the question group" do
34
+ expect(page).not_to have_content survey.name
35
+ end
36
+ end
37
+
38
+ context "when user cannot administer" do
39
+ before do
40
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(false)
41
+ visit rapidfire.root_path
42
+ end
43
+
44
+ it "doesn't show option to delete question group" do
45
+ expect(page).not_to have_link "Delete"
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "CREATING Survey" do
51
+ context "when user can create groups" do
52
+ before do
53
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
54
+
55
+ visit rapidfire.root_path
56
+ click_link "New Survey"
57
+ end
58
+
59
+ context "when name is present" do
60
+ before do
61
+ page.within("#new_survey") do
62
+ fill_in "survey_name", with: "New Survey"
63
+ click_button "Create Survey"
64
+ end
65
+ end
66
+
67
+ it "creates question group" do
68
+ expect(page).to have_content "New Survey"
69
+ end
70
+ end
71
+
72
+ context "when name is not present" do
73
+ before do
74
+ page.within("#new_survey") do
75
+ click_button "Create Survey"
76
+ end
77
+ end
78
+
79
+ it "fails to create question group" do
80
+ page.within("#new_survey") do
81
+ expect(page).to have_content "can't be blank"
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ context "when user cannot create groups" do
88
+ before do
89
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(false)
90
+ visit rapidfire.root_path
91
+ end
92
+
93
+ it "page shouldnot have link to create groups" do
94
+ expect(page).not_to have_link "New Survey"
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "EDITING Surveys" do
100
+ context "when user can manage questions" do
101
+ before do
102
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(true)
103
+
104
+ visit rapidfire.root_path
105
+ click_link survey.name
106
+ end
107
+
108
+ it "shows set of questions" do
109
+ expect(page).to have_content question1.question_text
110
+ expect(page).to have_content question2.question_text
111
+ end
112
+ end
113
+
114
+ context "when user cannot manage questions" do
115
+ before do
116
+ allow_any_instance_of(ApplicationController).to receive(:can_administer?).and_return(false)
117
+ end
118
+
119
+ it "fails to access the page" do
120
+ expect(page).not_to have_link survey.name
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "GET survey results" do
126
+ before do
127
+ create_questions(survey)
128
+ create_answers
129
+
130
+ visit rapidfire.root_path
131
+ page.within("#survey_#{survey.id}") do
132
+ click_link "Results"
133
+ end
134
+ end
135
+
136
+ it "shows results for particular question group" do
137
+ expect(page).to have_content "Results"
138
+ expect(page).to have_content "hindi 3"
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rapidfire::Answer do
4
+ describe "Validations" do
5
+ subject { FactoryGirl.build(:answer) }
6
+ it { is_expected.to validate_presence_of(:question) }
7
+ it { is_expected.to validate_presence_of(:attempt) }
8
+
9
+ context "when validations are run" do
10
+ let(:answer) { FactoryGirl.build(:answer) }
11
+
12
+ it "delegates validation of answer text to question" do
13
+ expect(answer.question).to receive(:validate_answer).with(answer).once
14
+ expect(answer.valid?).to be_truthy
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "Associations" do
20
+ it { is_expected.to belong_to(:question) }
21
+ it { is_expected.to belong_to(:attempt) }
22
+ end
23
+ end