helena 0.3.3 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -4
  3. data/Gemfile +1 -2
  4. data/Gemfile.lock +88 -95
  5. data/README.md +10 -25
  6. data/app/controllers/helena/application_controller.rb +0 -10
  7. data/app/controllers/helena/sessions_controller.rb +17 -6
  8. data/app/models/helena/answer.rb +1 -2
  9. data/app/models/helena/concerns/application_model.rb +0 -9
  10. data/app/models/helena/concerns/questions/validates_one_label.rb +1 -1
  11. data/app/models/helena/question.rb +5 -5
  12. data/app/models/helena/question_group.rb +4 -3
  13. data/app/models/helena/session.rb +27 -0
  14. data/app/models/helena/survey.rb +2 -7
  15. data/app/models/helena/version.rb +6 -4
  16. data/app/views/helena/questions/_static_text.html.slim +1 -0
  17. data/app/views/helena/sessions/_progressbar.html.slim +9 -0
  18. data/app/views/helena/sessions/edit.html.slim +18 -0
  19. data/app/views/helena/sessions/{end_message.html.haml → end_message.html.slim} +1 -1
  20. data/config/locales/models/question_group/en.yml +1 -0
  21. data/config/locales/models/session/en.yml +4 -0
  22. data/config/locales/models/survey/en.yml +3 -0
  23. data/config/locales/views/sessions/en.yml +4 -0
  24. data/config/routes.rb +1 -25
  25. data/db/seeds.rb +12 -140
  26. data/db/swls_survey.en.yml +67 -0
  27. data/helena.gemspec +1 -0
  28. data/lib/helena/engine.rb +11 -0
  29. data/lib/helena/survey_importer.rb +52 -0
  30. data/lib/helena/version.rb +1 -1
  31. data/lib/helena/version_publisher.rb +34 -2
  32. data/lib/helena.rb +3 -0
  33. data/spec/controllers/helena/sessions_controller_spec.rb +8 -3
  34. data/spec/dummy/app/controllers/application_controller.rb +0 -4
  35. data/spec/factories/helena/labels.rb +0 -1
  36. data/spec/factories/helena/question_groups.rb +0 -1
  37. data/spec/factories/helena/questions.rb +0 -1
  38. data/spec/factories/helena/sub_questions.rb +0 -1
  39. data/spec/factories/helena/surveys.rb +0 -1
  40. data/spec/features/helena/manage_session_spec.rb +76 -16
  41. data/spec/lib/survey_importer_spec.rb +14 -0
  42. data/spec/lib/version_publisher_spec.rb +5 -4
  43. data/spec/models/helena/answer_spec.rb +0 -1
  44. data/spec/models/helena/question_group_spec.rb +2 -1
  45. data/spec/models/helena/question_spec.rb +12 -4
  46. data/spec/models/helena/questions/checkbox_group_spec.rb +17 -0
  47. data/spec/models/helena/questions/radio_group_spec.rb +6 -0
  48. data/spec/models/helena/questions/radio_matrix_spec.rb +7 -0
  49. data/spec/models/helena/session_spec.rb +50 -0
  50. data/spec/models/helena/survey_spec.rb +12 -1
  51. data/spec/models/helena/version_spec.rb +11 -2
  52. metadata +26 -73
  53. data/app/assets/images/helena/icons/export.svg +0 -29
  54. data/app/assets/stylesheets/helena/admin/labels.css.sass +0 -7
  55. data/app/assets/stylesheets/helena/admin/layout.css.sass +0 -6
  56. data/app/assets/stylesheets/helena/admin/question_groups.css.sass +0 -7
  57. data/app/assets/stylesheets/helena/admin/questions.css.sass +0 -9
  58. data/app/assets/stylesheets/helena/admin/sessions.css.sass +0 -5
  59. data/app/assets/stylesheets/helena/admin/subquestions.css.sass +0 -7
  60. data/app/assets/stylesheets/helena/admin/versions.css.sass +0 -9
  61. data/app/controllers/helena/admin/application_controller.rb +0 -31
  62. data/app/controllers/helena/admin/question_groups_controller.rb +0 -78
  63. data/app/controllers/helena/admin/questions/checkbox_groups_controller.rb +0 -17
  64. data/app/controllers/helena/admin/questions/checkbox_matrix_controller.rb +0 -9
  65. data/app/controllers/helena/admin/questions/long_texts_controller.rb +0 -13
  66. data/app/controllers/helena/admin/questions/radio_groups_controller.rb +0 -17
  67. data/app/controllers/helena/admin/questions/radio_matrix_controller.rb +0 -9
  68. data/app/controllers/helena/admin/questions/short_texts_controller.rb +0 -13
  69. data/app/controllers/helena/admin/questions/static_texts_controller.rb +0 -13
  70. data/app/controllers/helena/admin/questions_controller.rb +0 -105
  71. data/app/controllers/helena/admin/sessions_controller.rb +0 -35
  72. data/app/controllers/helena/admin/surveys_controller.rb +0 -78
  73. data/app/controllers/helena/admin/versions_controller.rb +0 -71
  74. data/app/controllers/helena/surveys_controller.rb +0 -11
  75. data/app/views/helena/admin/question_groups/_form.html.haml +0 -3
  76. data/app/views/helena/admin/question_groups/edit.html.haml +0 -3
  77. data/app/views/helena/admin/question_groups/index.html.haml +0 -41
  78. data/app/views/helena/admin/question_groups/new.html.haml +0 -3
  79. data/app/views/helena/admin/questions/_form.html.haml +0 -15
  80. data/app/views/helena/admin/questions/_labels.html.haml +0 -24
  81. data/app/views/helena/admin/questions/_sub_questions.html.haml +0 -32
  82. data/app/views/helena/admin/questions/edit.html.haml +0 -3
  83. data/app/views/helena/admin/questions/index.html.haml +0 -49
  84. data/app/views/helena/admin/questions/new.html.haml +0 -3
  85. data/app/views/helena/admin/sessions/index.html.haml +0 -46
  86. data/app/views/helena/admin/surveys/_form.html.haml +0 -10
  87. data/app/views/helena/admin/surveys/edit.html.haml +0 -5
  88. data/app/views/helena/admin/surveys/index.html.haml +0 -35
  89. data/app/views/helena/admin/surveys/new.html.haml +0 -3
  90. data/app/views/helena/admin/versions/_form.html.haml +0 -5
  91. data/app/views/helena/admin/versions/default_session_report.html.haml +0 -17
  92. data/app/views/helena/admin/versions/edit.html.haml +0 -3
  93. data/app/views/helena/admin/versions/index.html.haml +0 -35
  94. data/app/views/helena/admin/versions/new.html.haml +0 -3
  95. data/app/views/helena/sessions/edit.html.haml +0 -16
  96. data/app/views/helena/surveys/_survey.html.haml +0 -3
  97. data/app/views/helena/surveys/index.html.haml +0 -2
  98. data/config/locales/views/admin/question_groups/en.yml +0 -12
  99. data/config/locales/views/admin/questions/en.yml +0 -16
  100. data/config/locales/views/admin/sessions/en.yml +0 -11
  101. data/config/locales/views/admin/surveys/en.yml +0 -10
  102. data/config/locales/views/admin/versions/en.yml +0 -8
  103. data/spec/controllers/helena/admin/question_group_controller_spec.rb +0 -59
  104. data/spec/controllers/helena/admin/questions_controller_spec.rb +0 -60
  105. data/spec/controllers/helena/admin/sessions_controller_spec.rb +0 -84
  106. data/spec/controllers/helena/admin/survey_controller_spec.rb +0 -89
  107. data/spec/controllers/helena/admin/versions_controller_spec.rb +0 -19
  108. data/spec/controllers/helena/application_controller_spec.rb +0 -15
  109. data/spec/features/helena/admin/manage_question_group_spec.rb +0 -101
  110. data/spec/features/helena/admin/manage_question_spec.rb +0 -105
  111. data/spec/features/helena/admin/manage_session_spec.rb +0 -40
  112. data/spec/features/helena/admin/manage_survey_spec.rb +0 -141
  113. data/spec/features/helena/admin/manage_version_spec.rb +0 -74
  114. data/spec/features/helena/admin/question_types/manage_checkbox_group_question_spec.rb +0 -55
  115. data/spec/features/helena/admin/question_types/manage_long_text_question_spec.rb +0 -21
  116. data/spec/features/helena/admin/question_types/manage_radio_group_question_spec.rb +0 -59
  117. data/spec/features/helena/admin/question_types/manage_radio_matrix_question_spec.rb +0 -80
  118. data/spec/features/helena/admin/question_types/manage_short_text_question_spec.rb +0 -19
  119. data/spec/features/helena/admin/question_types/manage_static_text_question_spec.rb +0 -17
  120. data/spec/features/helena/manage_survey_spec.rb +0 -24
@@ -6,18 +6,20 @@ module Helena
6
6
  field :version, type: Integer, default: 0
7
7
  field :notes, type: String
8
8
  field :session_report, type: String
9
+ field :active, type: Boolean, default: false
10
+ field :settings, type: Hash, default: {}
9
11
 
10
- embedded_in :survey
12
+ belongs_to :survey
11
13
 
12
- embeds_many :question_groups, class_name: 'Helena::QuestionGroup'
13
- embeds_many :sessions, class_name: 'Helena::Session'
14
+ has_many :question_groups, inverse_of: :version, dependent: :destroy, class_name: 'Helena::QuestionGroup'
15
+ has_many :sessions, inverse_of: :version, dependent: :destroy, class_name: 'Helena::Session'
14
16
 
15
17
  embeds_one :survey_detail, class_name: 'Helena::SurveyDetail'
16
18
 
17
19
  accepts_nested_attributes_for :survey_detail
18
20
  accepts_nested_attributes_for :question_groups
19
21
 
20
- scope :without_base, -> { where(:version.gt => 0) }
22
+ scope :active, -> { where active: true }
21
23
 
22
24
  validates :version, presence: true
23
25
  validates :version, uniqueness: { scope: :survey_id }
@@ -0,0 +1 @@
1
+ = question.default_value.html_safe
@@ -0,0 +1,9 @@
1
+ - page = (@question_group.previous_items.size + 1)
2
+ - total_pages = @version.question_groups.size
3
+ - percent = ((page.to_f / total_pages.to_f)*100).round
4
+ #survey_progress
5
+ .text-center
6
+ = t '.count_page', page: page, total_pages: total_pages
7
+ .progress
8
+ .progress-bar aria-valuemax="100" aria-valuemin="0" aria-valuenow="#{percent}" role="progressbar" style="width: #{percent}%"
9
+ = "#{percent}%"
@@ -0,0 +1,18 @@
1
+ = render 'progressbar' if @version.settings && @version.settings[:display_progressbar]
2
+ #survey_content
3
+ h1.survey_title
4
+ = @version.survey_detail.title
5
+ fieldset id="#{dom_id @question_group}"
6
+ legend= @question_group.title
7
+ = simple_form_for(@session, url: helena.session_path(@session.token), as: :session) do |f|
8
+ - @questions.each do |question|
9
+ = render "#{question.class.to_s.underscore}", form: f, question: question, answers: @answers, errors: @errors
10
+
11
+ = hidden_field_tag :question_group, @question_group.id
12
+
13
+ - if @question_group.previous_items.any? && @question_group.allow_to_go_back?
14
+ = link_to t('.back'), edit_session_path(@session.token, question_group: @question_group.previous_item), class: 'btn btn-default'
15
+
16
+ = f.submit class: 'btn btn-success pull-right', value: @question_group.last? ? t('.save') : t('.next')
17
+
18
+ = t('shared.required') if @questions.map{ |question| question.try :required }.any?
@@ -1,4 +1,4 @@
1
- %h1.survey_title
1
+ h1.survey_title
2
2
  = @version.survey_detail.title
3
3
 
4
4
  .well
@@ -9,3 +9,4 @@ en:
9
9
  'helena/question_group':
10
10
  position: Position
11
11
  title: Title
12
+ allow_to_go_back: Allow participants to go back to the previous question group
@@ -8,3 +8,7 @@ en:
8
8
  attributes:
9
9
  'helena/session':
10
10
  completed: Completed?
11
+ last_question_group_id: Last viewed question group
12
+ answers_as_yaml: Answers
13
+ token: Token
14
+ view_token: View token
@@ -4,3 +4,6 @@ en:
4
4
  'helena/survey':
5
5
  one: Survey
6
6
  other: Surveys
7
+ attributes:
8
+ 'helena/survey':
9
+ created_at: Created
@@ -5,5 +5,9 @@ en:
5
5
  next: Next
6
6
  save: Save
7
7
  back: Back
8
+
8
9
  end_message:
9
10
  message: Thank you for participating.
11
+
12
+ progressbar:
13
+ count_page: "Page %{page} of %{total_pages}"
data/config/routes.rb CHANGED
@@ -1,28 +1,4 @@
1
1
  Helena::Engine.routes.draw do
2
2
  resources :surveys
3
- resources :sessions, only: [:show, :edit, :update], param: :token
4
-
5
- scope :admin, as: :admin, module: :admin do
6
- concern :movable do
7
- patch :move_up, on: :member
8
- patch :move_down, on: :member
9
- end
10
-
11
- resources :surveys, concerns: :movable do
12
- resources :sessions, only: [:index, :destroy]
13
- resources :versions
14
- resources :question_groups, concerns: :movable do
15
- resources :questions, concerns: :movable
16
- resource :questions do
17
- resources :short_texts, module: 'questions'
18
- resources :long_texts, module: 'questions'
19
- resources :static_texts, module: 'questions'
20
- resources :radio_groups, module: 'questions'
21
- resources :checkbox_groups, module: 'questions'
22
- resources :radio_matrix, module: 'questions'
23
- resources :checkbox_matrix, module: 'questions'
24
- end
25
- end
26
- end
27
- end
3
+ resources :sessions, param: :token
28
4
  end
data/db/seeds.rb CHANGED
@@ -1,167 +1,39 @@
1
1
  require 'factory_girl'
2
2
  require 'ffaker'
3
3
  require 'database_cleaner'
4
+ require 'helena/survey_importer'
4
5
 
5
6
  include FactoryGirl::Syntax::Methods
6
7
 
7
- # TODO: Codes smells because we have to assign the factory path here
8
- FactoryGirl.definition_file_paths += ['spec/factories']
9
- FactoryGirl.find_definitions
10
-
11
- puts 'Cleaning database ...'.green
8
+ puts 'Cleaning database ...'
12
9
  DatabaseCleaner.strategy = :truncation
13
10
  DatabaseCleaner.clean
14
11
 
15
- puts 'Seeding surveys ...'.green
12
+ puts 'Seeding surveys ...'
16
13
 
17
14
  def create_satisfaction_scale_survey
18
- satisfaction_matrix = build :radio_matrix_question, code: :satisfaction,
19
- required: true,
20
- question_text: 'Below are five statements with which you may agree or disagree. Using the 1-7 scale below, indicate your agreement with each item by placing the appropriate number in the line preceding that item. Please be open and honest in your responding.',
21
- required: true,
22
- position: 1
23
-
24
- satisfaction_matrix.labels << build(:label, position: 1, text: 'Strongly Disagree', value: 1)
25
- satisfaction_matrix.labels << build(:label, position: 2, text: 'Disagree', value: 2)
26
- satisfaction_matrix.labels << build(:label, position: 3, text: 'Slightly Disagree', value: 3)
27
- satisfaction_matrix.labels << build(:label, position: 4, text: 'Neither Agree or Disagree', value: 4)
28
- satisfaction_matrix.labels << build(:label, position: 5, text: 'Slightly Agree', value: 5)
29
- satisfaction_matrix.labels << build(:label, position: 6, text: 'Agree', value: 6)
30
- satisfaction_matrix.labels << build(:label, position: 7, text: 'Strongly Agree', value: 7)
31
-
32
- satisfaction_matrix.sub_questions << build(:sub_question, text: 'In most ways my life is close to my ideal.', code: 'life_is_ideal', position: 1)
33
- satisfaction_matrix.sub_questions << build(:sub_question, text: 'The conditions of my life are excellent.', code: 'condition', position: 2)
34
- satisfaction_matrix.sub_questions << build(:sub_question, text: 'I am satisfied with life.', code: 'satisfied_with_life', position: 3)
35
- satisfaction_matrix.sub_questions << build(:sub_question, text: 'So far I have gotten the important things I want in life.', code: 'important_things', position: 4)
36
- satisfaction_matrix.sub_questions << build(:sub_question, text: 'If I could live my life over, I would change almost nothing.', code: 'nothing_to_change', position: 5)
37
-
38
- satisfaction_details = build :question_group, questions: [satisfaction_matrix]
39
-
40
-
41
- survey = create :survey, name: 'The Satisfaction with Life Scale', tag_list: 'satisfaction, psychology'
42
- base_version = survey.versions.create version: 0
43
- base_version.survey_detail = build :survey_detail, title: 'The Satisfaction with Life Scale',
44
- description: 'A 5-item scale designed to measure global cognitive judgments of ones life satisfaction.'
45
-
46
- base_version.question_groups << satisfaction_details
47
- published_version = publish(base_version)
48
-
49
- generate_sessions(survey, published_version)
50
- end
51
-
52
- def create_restaurant_survey
53
- personal_details = build :question_group,title: 'Personal Details', position: 1
54
-
55
- personal_details.questions << build(:short_text_question, code: :name,
56
- question_text: "What's your name?",
57
- required: true,
58
- position: 1)
59
-
60
- personal_details.questions << build(:short_text_question, code: :email,
61
- question_text: "What's your E-Mail-Address?",
62
- position: 2)
63
-
64
- visit_interval = build :radio_group_question, code: :visit_interval,
65
- question_text: 'How often do you visit the Swiss Chees Restaurant?',
66
- required: true,
67
- position: 3
68
-
69
- visit_interval.labels << build(:label, position: 1, text: 'Just once', value: 1)
70
- visit_interval.labels << build(:label, position: 2, text: 'Once a year', value: 2)
71
- visit_interval.labels << build(:label, position: 3, text: 'Once a Month', value: 3)
72
- visit_interval.labels << build(:label, position: 4, text: 'Once a week', value: 4)
73
- visit_interval.labels << build(:label, position: 5, text: 'Daily', value:5)
74
-
75
- food_allergy = build :checkbox_group_question, code: :food_allergy,
76
- question_text: 'What kind of food allergy do you have?',
77
- position: 4
78
-
79
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Garlic', code: 'garlic', position: 1)
80
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Oats', code: 'oat', position: 2)
81
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Meat', code: 'meat', position: 3)
82
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Milk', code: 'milk', position: 4)
83
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Peanut', code: 'peanut', position: 5)
84
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Fish / Shellfish', code: 'fish', position: 6)
85
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Soy', code: 'soy', position: 7)
86
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Wheat', code: 'wheat', position: 9)
87
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Gluten', code: 'gluten', position: 10)
88
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Egg', code: 'egg', position: 11)
89
- food_allergy.sub_questions << build(:sub_question, value: 'true', text: 'Sulfites', code: 'sulfites', position: 12)
90
-
91
- personal_details.questions << visit_interval
92
- personal_details.questions << food_allergy
93
-
94
-
95
- dinner = build :question_group, title: 'About the dinner', position: 2
96
- dinner_satisfaction = build :radio_matrix_question, code: :satisfaction,
97
- required: true,
98
- question_text: 'Please rate the quality for each topic',
99
- required: true,
100
- position: 1
101
-
102
- dinner_satisfaction.labels << build(:label, position: 1, text: ':-(', value: -1)
103
- dinner_satisfaction.labels << build(:label, position: 2, text: ':-|', value: 0, preselected: true)
104
- dinner_satisfaction.labels << build(:label, position: 3, text: ':-)', value: 1)
105
-
106
- dinner_satisfaction.sub_questions << build(:sub_question, text: 'Food', code: 'food', position: 1)
107
- dinner_satisfaction.sub_questions << build(:sub_question, text: 'Beverages', code: 'beverages', position: 2)
108
- dinner_satisfaction.sub_questions << build(:sub_question, text: 'Service', code: 'service', position: 3)
109
- dinner_satisfaction.sub_questions << build(:sub_question, text: 'Snacks', code: 'snacks', position: 4)
110
- dinner_satisfaction.sub_questions << build(:sub_question, text: 'Cleanliness', code: 'cleanliness', position: 4)
111
-
112
- dinner.questions << dinner_satisfaction
113
-
114
- dinner.questions << build(:short_text_question, code: :catchphrase,
115
- question_text: 'How would you describe the dinner with one word?',
116
- required: true,
117
- position: 2)
118
-
119
- dinner.questions << build(:long_text_question, code: :feedback,
120
- question_text: 'Feel free to give us additional feedback ...',
121
- position: 3)
122
-
123
- description = <<EOF
124
- Thank you for your recent stay at our hotel. During your stay you dined at our 5-star Swiss Cheese Restaurant.
125
- We're conducting a short survey to find out about your dining experience and what we might do to improve.
126
- Please help us by completing this short survey."
127
- EOF
128
-
129
- survey = create :survey, name: 'Restaurant customer satisfaction', tag_list: 'restaurant, survey'
130
- base_version = survey.versions.create version: 0, question_groups: [personal_details, dinner]
131
- base_version.survey_detail = create :survey_detail, title: '5-star Swiss Cheese Restaurant customer satisfaction',
132
- version: base_version,
133
- description: description
134
-
135
- published_version = publish(base_version)
136
- generate_sessions(survey, published_version)
137
- end
138
-
139
- def default_session_report
140
- haml = File.read(File.dirname(__FILE__) + '/../app/views/helena/admin/versions/default_session_report.html.haml')
141
- Haml::Engine.new(haml).render
15
+ survey_importer = Helena::SurveyImporter.new File.read(File.dirname(__FILE__) + '/swls_survey.en.yml')
16
+ generate_sessions(survey_importer.survey, survey_importer.survey.newest_version)
142
17
  end
143
18
 
144
19
  def publish(version)
145
20
  published_version = Helena::VersionPublisher.publish(version)
146
21
  published_version.notes = Faker::Lorem.paragraph(1)
147
- published_version.session_report = default_session_report
148
22
  published_version.save
149
23
  published_version
150
24
  end
151
-
25
+ # rubocop:disable Metrics/MethodLength
152
26
  def generate_sessions(survey, version)
153
- 3.times {
154
- survey.sessions << build(:session, version: version, updated_at: DateTime.now - rand(999), completed: false)
155
- }
27
+ 3.times { survey.sessions << build(:session, version: version, updated_at: DateTime.now - rand(999), completed: false) }
156
28
 
157
- 3.times {
29
+ 3.times do
158
30
  session = build :session, version: version, updated_at: DateTime.now - rand(999), completed: true
159
31
  version.question_groups.map(&:questions).flatten.each do |question|
160
32
  case question
161
33
  when Helena::Questions::ShortText
162
- session.answers << build(:string_answer, code: question.code, value: Faker::Skill.tech_skill )
34
+ session.answers << build(:string_answer, code: question.code, value: Faker::Skill.tech_skill)
163
35
  when Helena::Questions::LongText
164
- session.answers << build(:string_answer, code: question.code, value: Faker::Skill.tech_skill )
36
+ session.answers << build(:string_answer, code: question.code, value: Faker::Skill.tech_skill)
165
37
  when Helena::Questions::RadioGroup
166
38
  session.answers << Helena::Answer.build_generic(question.code, question.labels.sample.value, Faker::Internet.ip_v4_address)
167
39
  when Helena::Questions::CheckboxGroup
@@ -175,8 +47,8 @@ def generate_sessions(survey, version)
175
47
  end
176
48
  end
177
49
  survey.sessions << session
178
- }
50
+ end
179
51
  end
52
+ # rubocop:enable Metrics/MethodLength
180
53
 
181
54
  create_satisfaction_scale_survey
182
- create_restaurant_survey
@@ -0,0 +1,67 @@
1
+ # Helena survey template for "The Satisfaction with Life Scale"
2
+ # http://internal.psychology.illinois.edu/~ediener/SWLS.html
3
+ # Ed Diener, Robert A. Emmons, Randy J. Larsen and Sharon Griffin as noted in the 1985 article in the Journal of Personality Assessment.
4
+
5
+ name: The Satisfaction with Life Scale
6
+ tags:
7
+ - others
8
+ language: en
9
+
10
+ versions:
11
+ 0:
12
+ notes: initial version
13
+ survey_detail:
14
+ title: The Satisfaction with Life Scale
15
+ description: A 5-item scale designed to measure global cognitive judgments of ones life satisfaction. – Ed Diener
16
+
17
+ question_groups:
18
+ 1:
19
+ questions:
20
+ 1:
21
+ code: satisfaction
22
+ _type: Helena::Questions::RadioMatrix
23
+ required: true
24
+ question_text: 'Below are five statements with which you may agree or disagree.
25
+ Using the 1-7 scale below, indicate your agreement with each item by placing the
26
+ appropriate number in the line preceding that item. Please be open and honest in
27
+ your responding.'
28
+ required: true
29
+ labels:
30
+ 1:
31
+ text: Strongly Disagree
32
+ value: 0
33
+ 2:
34
+ text: Disagree
35
+ value: 1
36
+ 3:
37
+ text: Slightly Disagree
38
+ value: 2
39
+ 4:
40
+ text: Neither Agree or Disagree
41
+ value: 3
42
+ 5:
43
+ text: Slightly Agree
44
+ value: 4
45
+ 6:
46
+ text: Agree
47
+ value: 5
48
+ 7:
49
+ text: Strongly Agree
50
+ value: 6
51
+
52
+ sub_questions:
53
+ 1:
54
+ text: In most ways my life is close to my ideal.
55
+ code: life_is_ideal
56
+ 2:
57
+ text: The conditions of my life are excellent.
58
+ code: condition
59
+ 3:
60
+ text: I am satisfied with life.
61
+ code: satisfied_with_life
62
+ 4:
63
+ text: So far I have gotten the important things I want in life.
64
+ code: important_things
65
+ 5:
66
+ text: If I could live my life over, I would change almost nothing.
67
+ code: nothing_to_change
data/helena.gemspec CHANGED
@@ -24,6 +24,7 @@ survey/test development, longitudinal studies and instant feedback.'
24
24
  s.add_dependency 'mongoid_orderable', '~> 4.1'
25
25
  s.add_dependency 'mongoid-simple-tags', '~> 0.1'
26
26
  s.add_dependency 'haml-rails', '~> 0.5'
27
+ s.add_dependency 'slim', '~> 2.1.0'
27
28
  s.add_dependency 'jquery-rails', '~> 3.1'
28
29
  s.add_dependency 'sass-rails', '~> 4.0.3' # version needed here http://stackoverflow.com/questions/22392862/undefined-method-environment-for-nilnilclass-when-importing-bootstrap
29
30
  s.add_dependency 'bootstrap-sass', '~> 3.2'
data/lib/helena/engine.rb CHANGED
@@ -2,5 +2,16 @@ module Helena
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace Helena
4
4
  config.i18n.load_path += Dir[config.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
5
+
6
+ # Thanks to https://github.com/thoughtbot/factory_girl_rails/pull/42
7
+ initializer 'helena.factories', after: 'factory_girl.set_factory_paths' do
8
+ FactoryGirl.definition_file_paths << File.expand_path('../../../spec/factories', __FILE__) if defined?(FactoryGirl)
9
+ end
10
+
11
+ config.to_prepare do
12
+ Dir.glob(Rails.root + 'app/decorators/**/*_decorator*.rb').each do |c|
13
+ require_dependency c
14
+ end
15
+ end
5
16
  end
6
17
  end
@@ -0,0 +1,52 @@
1
+ require 'yaml'
2
+
3
+ module Helena
4
+ class SurveyImporter
5
+ attr_accessor :survey
6
+
7
+ def initialize(yaml_string)
8
+ @parsed = YAML.load yaml_string
9
+
10
+ create_survey
11
+ end
12
+
13
+ private
14
+
15
+ def create_survey
16
+ @survey = Helena::Survey.new @parsed.except('versions')
17
+ return unless @survey.save
18
+ return unless @parsed['versions']
19
+ @parsed['versions'].each { |parsed_version| create_version parsed_version }
20
+ end
21
+
22
+ def create_version(parsed_version)
23
+ version = build_version(parsed_version)
24
+
25
+ return unless version.save
26
+ return unless parsed_version.last['question_groups']
27
+ parsed_version.last['question_groups'].each { |parsed_question_group| create_question_group version, parsed_question_group }
28
+ end
29
+
30
+ def create_question_group(version, parsed_question_group)
31
+ question_group = version.question_groups.build parsed_question_group.last.except('questions')
32
+ question_group.position = parsed_question_group.first
33
+ return unless question_group.save
34
+ return unless parsed_question_group.last['questions']
35
+ parsed_question_group.last['questions'].each { |parsed_question| create_question question_group, parsed_question }
36
+ end
37
+
38
+ def create_question(question_group, parsed_question)
39
+ question = question_group.questions.build parsed_question.last
40
+ question.position = parsed_question.first
41
+ question.save
42
+ question
43
+ end
44
+
45
+ def build_version(parsed_version)
46
+ version = @survey.versions.build parsed_version.last.except('question_groups')
47
+ version.version = parsed_version.first
48
+ version.survey_detail = parsed_version.last['survey_detail']
49
+ version
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module Helena
2
- VERSION = '0.3.3'
2
+ VERSION = '1.0.0.rc1'
3
3
  end
@@ -1,16 +1,48 @@
1
1
  module Helena
2
2
  class VersionPublisher
3
3
  def self.publish(version)
4
- copied_version = version.dup
5
- copied_version.survey = version.survey
4
+ copied_version = create_copied_version_from(version)
5
+
6
+ version.question_groups.each do |original_question_group|
7
+ question_group = copied_version.question_groups.create reset_ids(original_question_group.attributes)
8
+ original_question_group.questions.each do |original_question|
9
+ question = question_group.questions.create reset_ids(original_question.attributes)
10
+ question.labels = original_question.labels
11
+ question.sub_questions = original_question.sub_questions
12
+ end
13
+ end
14
+ copied_version
15
+ end
16
+
17
+ def self.adjust_copied_attributes(version, copied_version)
6
18
  copied_version.version = newest_version_of(version.survey) + 1
7
19
  copied_version.created_at = DateTime.now
8
20
  copied_version.updated_at = DateTime.now
21
+ copied_version.active = false
9
22
  copied_version
10
23
  end
11
24
 
12
25
  def self.newest_version_of(survey)
13
26
  survey.newest_version.version
14
27
  end
28
+
29
+ def self.create_copied_version_from(version)
30
+ copied_version = Helena::Version.new reset_ids(version.attributes)
31
+ copied_version = adjust_copied_attributes(version, copied_version)
32
+ copied_version.survey_detail = reset_ids(version.survey_detail.attributes) if version.survey_detail
33
+ copied_version.save
34
+ copied_version
35
+ end
36
+
37
+ def self.reset_ids(attributes)
38
+ attributes.each do |key, value|
39
+ if key == '_id' && value.is_a?(BSON::ObjectId)
40
+ attributes[key] = BSON::ObjectId.new
41
+ elsif value.is_a?(Hash) || value.is_a?(Array)
42
+ attributes[key] = reset_ids(value)
43
+ end
44
+ end
45
+ attributes
46
+ end
15
47
  end
16
48
  end
data/lib/helena.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  require 'helena/engine'
2
2
  require 'haml'
3
3
  require 'helena/version_publisher'
4
+ require 'helena/survey_importer'
4
5
  require 'mongoid'
6
+ require 'simple_form' # TODO: Remove this when amdin interface is finally moved
5
7
  require 'mongoid_orderable'
6
8
  require 'mongoid-simple-tags'
7
9
  require 'csv'
10
+ require 'slim'
8
11
 
9
12
  module Helena
10
13
  end
@@ -4,10 +4,8 @@ describe Helena::SessionsController do
4
4
  routes { Helena::Engine.routes }
5
5
 
6
6
  let(:survey) { create :survey }
7
+ let(:version) { survey.versions.create version: 0 }
7
8
  let(:session) do
8
- baseversion = survey.versions.create version: 0
9
- version = Helena::VersionPublisher.publish(baseversion)
10
- version.save
11
9
  create :session, survey: survey, version: version, answers: [
12
10
  build(:string_answer, code: 'string_answer_1', value: 'abc'),
13
11
  build(:integer_answer, code: 'integer_answer_1', value: '123')
@@ -21,4 +19,11 @@ describe Helena::SessionsController do
21
19
  expect(result['answer']['string_answer_1']).to eq 'abc'
22
20
  expect(result['answer']['integer_answer_1']).to eq 123
23
21
  end
22
+
23
+ it 'renders session_report as slim template' do
24
+ session.version.update_attribute :session_report, 'h1 make it slim!'
25
+ get :show, token: session.view_token
26
+
27
+ expect(response.body).to eq '<h1>make it slim!</h1>'
28
+ end
24
29
  end
@@ -2,8 +2,4 @@ class ApplicationController < ActionController::Base
2
2
  # Prevent CSRF attacks by raising an exception.
3
3
  # For APIs, you may want to use :null_session instead.
4
4
  protect_from_forgery with: :exception
5
-
6
- def can_administer?
7
- true
8
- end
9
5
  end
@@ -2,6 +2,5 @@ FactoryGirl.define do
2
2
  factory :label, class: Helena::Label do
3
3
  sequence(:text) { |n| "Option #{n}" }
4
4
  sequence(:value)
5
- sequence(:position)
6
5
  end
7
6
  end
@@ -1,6 +1,5 @@
1
1
  FactoryGirl.define do
2
2
  factory :question_group, class: Helena::QuestionGroup do
3
3
  sequence(:title) { |n| "Page #{n}" }
4
- sequence(:position)
5
4
  end
6
5
  end
@@ -1,7 +1,6 @@
1
1
  FactoryGirl.define do
2
2
  factory :question, class: Helena::Question do
3
3
  sequence(:question_text) { |n| "Question #{n}, #{Faker::Lorem.words(3).join(' ')}?" }
4
- sequence(:position)
5
4
  sequence(:code) { |n| "x#{n}" }
6
5
 
7
6
  factory :short_text_question, class: Helena::Questions::ShortText
@@ -2,6 +2,5 @@ FactoryGirl.define do
2
2
  factory :sub_question, class: Helena::SubQuestion do
3
3
  sequence(:text) { |n| "Question #{n}, #{Faker::Lorem.words(3).join(' ')}?" }
4
4
  sequence(:code) { |n| "y#{n}" }
5
- sequence(:position)
6
5
  end
7
6
  end
@@ -1,7 +1,6 @@
1
1
  FactoryGirl.define do
2
2
  factory :survey, class: Helena::Survey do
3
3
  sequence(:name) { |n| "Survey #{n}" }
4
- sequence(:position)
5
4
  language 'en'
6
5
  end
7
6
  end