study_engine 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +42 -0
  3. data/app/assets/images/study_engine/spinner.gif +0 -0
  4. data/app/assets/images/study_engine/sprite/delete.png +0 -0
  5. data/app/assets/images/study_engine/sprite/download.png +0 -0
  6. data/app/assets/images/study_engine/sprite/edit.png +0 -0
  7. data/app/assets/images/study_engine/sprite/incomplete.png +0 -0
  8. data/app/assets/images/study_engine/sprite/metrc-sm.png +0 -0
  9. data/app/assets/images/study_engine/sprite/metrc.png +0 -0
  10. data/app/assets/images/study_engine/sprite/new.png +0 -0
  11. data/app/assets/javascripts/study_engine/admin_notes.js.coffee +12 -0
  12. data/app/assets/javascripts/study_engine/assessment_notifications.js.coffee +36 -0
  13. data/app/assets/javascripts/study_engine/assessment_timeout.js.coffee +24 -0
  14. data/app/assets/javascripts/study_engine/disable_buttons_after_click.js.coffee +6 -0
  15. data/app/assets/javascripts/study_engine/fire_click_event_immediately_on_mobile.js.coffee.erb +10 -0
  16. data/app/assets/javascripts/study_engine/response_validation.js.coffee +8 -0
  17. data/app/assets/javascripts/study_engine/restart_assessment_button.js.coffee +3 -0
  18. data/app/assets/javascripts/study_engine/study_engine.js.coffee +9 -0
  19. data/app/assets/javascripts/study_engine/study_id_picker.js.coffee +28 -0
  20. data/app/assets/stylesheets/study_engine.sass +1 -0
  21. data/app/assets/stylesheets/study_engine/_constant.sass +52 -0
  22. data/app/assets/stylesheets/study_engine/_mobile.sass +8 -0
  23. data/app/assets/stylesheets/study_engine/_tablet.sass +36 -0
  24. data/app/assets/stylesheets/study_engine/application.sass +101 -0
  25. data/app/assets/stylesheets/study_engine/base/_form.sass +131 -0
  26. data/app/assets/stylesheets/study_engine/base/_list.sass +38 -0
  27. data/app/assets/stylesheets/study_engine/base/_tables.sass +33 -0
  28. data/app/assets/stylesheets/study_engine/base/_text.sass +78 -0
  29. data/app/assets/stylesheets/study_engine/components/-fields/_login-fields.sass +14 -0
  30. data/app/assets/stylesheets/study_engine/components/-fields/_start-fields.sass +101 -0
  31. data/app/assets/stylesheets/study_engine/components/-nav/_global-nav.sass +19 -0
  32. data/app/assets/stylesheets/study_engine/components/-table/_results-table.sass +75 -0
  33. data/app/assets/stylesheets/study_engine/components/-table/_users-table.sass +11 -0
  34. data/app/assets/stylesheets/study_engine/components/_assessment-questions.sass +30 -0
  35. data/app/assets/stylesheets/study_engine/components/_form-buttons.sass +102 -0
  36. data/app/assets/stylesheets/study_engine/components/_helpt-text.sass +2 -0
  37. data/app/assets/stylesheets/study_engine/components/_method-icons.sass +15 -0
  38. data/app/assets/stylesheets/study_engine/components/_notes-modal.sass +65 -0
  39. data/app/assets/stylesheets/study_engine/components/_progress-bar.sass +25 -0
  40. data/app/assets/stylesheets/study_engine/components/_sortable-columns.sass +26 -0
  41. data/app/assets/stylesheets/study_engine/components/_table-actions.sass +8 -0
  42. data/app/assets/stylesheets/study_engine/components/_table-buttons.sass +17 -0
  43. data/app/assets/stylesheets/study_engine/components/_user-privileges.sass +3 -0
  44. data/app/assets/stylesheets/study_engine/mixins/_actions-table.sass +11 -0
  45. data/app/assets/stylesheets/study_engine/mixins/_buttons.sass +55 -0
  46. data/app/assets/stylesheets/study_engine/mixins/_checkbox-columns.sass +50 -0
  47. data/app/assets/stylesheets/study_engine/mixins/_custom-radios.sass +47 -0
  48. data/app/assets/stylesheets/study_engine/mixins/_icons.sass +38 -0
  49. data/app/assets/stylesheets/study_engine/mixins/_notification-text.sass +23 -0
  50. data/app/controllers/study_engine/admin/application_controller.rb +6 -0
  51. data/app/controllers/study_engine/admin/assessments_controller.rb +79 -0
  52. data/app/controllers/study_engine/admin/notes_controller.rb +17 -0
  53. data/app/controllers/study_engine/application_controller.rb +12 -0
  54. data/app/controllers/study_engine/assessments_controller.rb +94 -0
  55. data/app/helpers/study_engine/helpers.rb +15 -0
  56. data/app/helpers/study_engine/mailer_helpers.rb +11 -0
  57. data/app/mailers/study_engine/mailer.rb +25 -0
  58. data/app/models/study_engine/answer.rb +36 -0
  59. data/app/models/study_engine/assessment.rb +118 -0
  60. data/app/models/study_engine/begin_assessment_form.rb +110 -0
  61. data/app/models/study_engine/existing_assessments_form.rb +99 -0
  62. data/app/models/study_engine/form.rb +59 -0
  63. data/app/models/study_engine/report.rb +69 -0
  64. data/app/models/study_engine/result.rb +46 -0
  65. data/app/models/study_engine/screen_results.rb +54 -0
  66. data/app/models/study_engine/study_id.rb +47 -0
  67. data/app/models/study_engine/study_id/bank.rb +38 -0
  68. data/app/models/study_engine/study_id/sync.rb +52 -0
  69. data/app/models/study_engine/update_assessments_form.rb +53 -0
  70. data/app/views/study_engine/_progress_bar.html.slim +4 -0
  71. data/app/views/study_engine/admin/assessments/_assessment.html.slim +36 -0
  72. data/app/views/study_engine/admin/assessments/domain_results.csv.csvbuilder +17 -0
  73. data/app/views/study_engine/admin/assessments/edit.html.slim +68 -0
  74. data/app/views/study_engine/admin/assessments/index.html.slim +26 -0
  75. data/app/views/study_engine/admin/assessments/item_results.csv.csvbuilder +24 -0
  76. data/app/views/study_engine/admin/assessments/new.html.slim +46 -0
  77. data/app/views/study_engine/admin/assessments/screen_results.csv.csvbuilder +2 -0
  78. data/app/views/study_engine/assessments/complete.html.slim +25 -0
  79. data/app/views/study_engine/assessments/create.html.slim +46 -0
  80. data/app/views/study_engine/assessments/index.html.slim +43 -0
  81. data/app/views/study_engine/assessments/restart.html.slim +28 -0
  82. data/app/views/study_engine/assessments/show.html.slim +60 -0
  83. data/app/views/study_engine/mailer/assessment_recorded_notification.erb +8 -0
  84. data/app/views/study_engine/mailer/assessment_url_notification.erb +6 -0
  85. data/config/routes.rb +15 -0
  86. data/db/migrate/20160422185859_create_tables.rb +52 -0
  87. data/lib/study_engine.rb +5 -0
  88. data/lib/study_engine/config.rb +37 -0
  89. data/lib/study_engine/cucumber.rb +96 -0
  90. data/lib/study_engine/engine.rb +7 -0
  91. data/lib/study_engine/version.rb +3 -0
  92. data/lib/tasks/study_engine_tasks.rake +10 -0
  93. data/spec/ar_helper.rb +30 -0
  94. data/spec/models/study_engine/answer_spec.rb +28 -0
  95. data/spec/models/study_engine/assessment_spec.rb +250 -0
  96. data/spec/models/study_engine/begin_assessment_form_spec.rb +87 -0
  97. data/spec/models/study_engine/existing_assessments_form_spec.rb +171 -0
  98. data/spec/models/study_engine/report_spec.rb +48 -0
  99. data/spec/models/study_engine/result_spec.rb +102 -0
  100. data/spec/models/study_engine/screen_results_spec.rb +69 -0
  101. data/spec/models/study_engine/study_id/bank_spec.rb +72 -0
  102. data/spec/models/study_engine/study_id/sync_spec.rb +61 -0
  103. data/spec/models/study_engine/study_id_spec.rb +7 -0
  104. data/spec/models/study_engine/update_assessments_form_spec.rb +38 -0
  105. data/spec/rails_helper.rb +50 -0
  106. data/spec/schema.rb +65 -0
  107. data/spec/spec_helper.rb +72 -0
  108. data/spec/support/CATEngine3.exe +0 -0
  109. data/spec/support/forms/01. Physical Function Bank.xml +1213 -0
  110. data/spec/support/forms/02. Pain Interference Bank.xml +443 -0
  111. data/spec/support/forms/03. Anxiety Bank.xml +322 -0
  112. data/spec/support/forms/04. Depression Bank.xml +311 -0
  113. data/spec/support/forms/05. Ability to Participate Social bank Version 2.xml +353 -0
  114. data/spec/support/forms/06. Psychosocial Illness Impact Pos Bank.xml +900 -0
  115. data/spec/support/forms/07. Applied Cognition Gen Concerns Bank.xml +377 -0
  116. data/spec/support/forms/08. Satisfaction with Roles and Activities Bank Version 2.xml +443 -0
  117. data/spec/support/forms/09. Sleep Disturbance Bank.xml +300 -0
  118. data/spec/support/forms/10. Emotional Support Bank.xml +163 -0
  119. data/spec/support/forms/A - 07. Psychosocial Illness Impact Pos Bank.xml +471 -0
  120. data/spec/support/forms/A - 08. Pain interference Bank.xml +443 -0
  121. data/spec/support/forms/A - 09. Depression Bank.xml +311 -0
  122. data/spec/support/forms/B - 07. Physical Function Short Form.xml +123 -0
  123. data/spec/support/forms/B - 08. Physical Function Remainder A.xml +543 -0
  124. data/spec/support/forms/B - 09. Ability to Participate Social bank Version 2.xml +353 -0
  125. data/spec/support/forms/C - 07. Physical Function Short Form.xml +123 -0
  126. data/spec/support/forms/C - 08. Physical Function Remainder B.xml +553 -0
  127. data/spec/support/forms/C - 09. Anxiety Bank.xml +322 -0
  128. data/spec/support/parameters/01. Physical Function Bank.xml +682 -0
  129. data/spec/support/parameters/02. Pain Interference Bank.xml +256 -0
  130. data/spec/support/parameters/03. Anxiety Bank.xml +190 -0
  131. data/spec/support/parameters/04. Depression Bank.xml +184 -0
  132. data/spec/support/parameters/05. Ability to Participate Social bank Version 2.xml +226 -0
  133. data/spec/support/parameters/06. Psychosocial Illness Impact Pos Bank.xml +211 -0
  134. data/spec/support/parameters/07. Applied Cognition Gen Concerns Bank.xml +1 -0
  135. data/spec/support/parameters/08. Satisfaction with Roles and Activities Bank Version 2.xml +1 -0
  136. data/spec/support/parameters/09. Sleep Disturbance Bank.xml +1 -0
  137. data/spec/support/parameters/10. Emotional Support Bank.xml +1 -0
  138. metadata +394 -0
@@ -0,0 +1,87 @@
1
+ require "ar_helper"
2
+ require "study_engine/begin_assessment_form"
3
+ require "study_engine/result"
4
+
5
+ module StudyEngine
6
+ describe BeginAssessmentForm do
7
+ before { StudyEngine.events = ["Baseline", "6 month", "12 month"] }
8
+
9
+ let(:assessment) { Assessment.new }
10
+ subject { described_class.new({}, assessment) }
11
+
12
+ describe "#study_id_site=" do
13
+ it "upcases input" do
14
+ subject.study_id_site = "aaa"
15
+ subject.study_id_site.should == "AAA"
16
+ end
17
+ end
18
+
19
+ describe "validations" do
20
+ describe "study_id" do
21
+ it "enforces format" do
22
+ subject.study_id_site = "aaa"
23
+ subject.study_id_study = "bbb"
24
+ subject.study_id_id = "ccc"
25
+ subject.valid?
26
+ subject.errors.full_messages.should include("METRC study ID must be in the following format: XXX-XXX-####")
27
+ end
28
+
29
+ it "enforces presence" do
30
+ subject.valid?
31
+ subject.errors.full_messages.should include("METRC study ID can not be blank. Enter ID in the following format: XXX-XXX-####")
32
+ end
33
+
34
+ it "enforces uniqueness" do
35
+ subject.stub existing_assessment: double
36
+ subject.valid?
37
+ subject.errors.full_messages.should include("Assessment data has already been collected for this ID number and event. Please check these fields to confirm you are beginning an assessment for the correct ID and event.")
38
+ end
39
+ end
40
+
41
+ describe "event" do
42
+ it "enforces presence" do
43
+ subject.valid?
44
+ subject.errors.full_messages.should include("Study event can not be blank. Choose Baseline, 6 Month, or 12 Month assessment.")
45
+ end
46
+ end
47
+
48
+ describe "baseline" do
49
+ it "if six month is selected" do
50
+ subject.event = "6 month"
51
+ subject.valid?
52
+ subject.errors.full_messages.should include("Baseline assessment must already exist to administer 6 month assessment")
53
+ end
54
+ end
55
+
56
+ describe "baseline" do
57
+ it "if twelve month is selected" do
58
+ subject.event = "12 month"
59
+ subject.valid?
60
+ subject.errors.full_messages.should include("Baseline assessment must already exist to administer 12 month assessment")
61
+ end
62
+ end
63
+
64
+ describe "six month" do
65
+ it "if twelve month is selected" do
66
+ subject.event = "12 month"
67
+ subject.valid?
68
+ subject.errors.full_messages.should include("6 month assessment must already exist to administer 12 month assessment")
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#save" do
74
+ it "creates an assessment with the relevant fields copied over" do
75
+ subject.study_id_study = "FIX"
76
+ subject.study_id_site = "AAA"
77
+ subject.study_id_id = "1000"
78
+ subject.event = "Baseline"
79
+ subject.should be_valid
80
+ subject.save.should be_truthy
81
+ Assessment.first.attributes.symbolize_keys.should include(\
82
+ { id: 1, study_id: StudyID.new("FIX-AAA-1000"), event: "Baseline" })
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,171 @@
1
+ require "ar_helper"
2
+ require "study_engine/existing_assessments_form"
3
+ require "study_engine/result"
4
+ require "study_engine/config"
5
+
6
+ module StudyEngine
7
+ describe ExistingAssessmentsForm do
8
+ before do
9
+ stub_const "StudyID::Bank", double(studies: %w(FIX OUT PAN TAO OXY))
10
+ StudyEngine.events = ["Baseline", "6 month", "12 month"]
11
+ end
12
+
13
+ describe "#study_id_site=" do
14
+ it "upcases input" do
15
+ subject.study_id_site = "aaa"
16
+ subject.study_id_site.should == "AAA"
17
+ end
18
+ end
19
+
20
+ describe "study_id" do
21
+ it "enforces format" do
22
+ subject.study_id_study = "omg"
23
+ subject.study_id_site = "wtf"
24
+ subject.study_id_id = "bbq"
25
+ subject.valid?
26
+ subject.errors.full_messages.should include("METRC study ID must be in the following format: XXX-XXX-####")
27
+ end
28
+
29
+ it "enforces presence" do
30
+ subject.valid?
31
+ subject.errors.full_messages.should include("METRC study ID can not be blank. Enter ID in the following format: XXX-XXX-####")
32
+ end
33
+ end
34
+
35
+ context "with no events" do
36
+ it "is cool with a baseline event being created" do
37
+ subject.study_id_study = "OUT"
38
+ subject.study_id_site = "BBB"
39
+ subject.study_id_id = "1234"
40
+ subject.event_datetimes = ["2000-01-01 12:00:00", "", ""]
41
+
42
+ subject.should be_valid
43
+ subject.save.should be_truthy
44
+ a, _ = Assessment.all.map(&:attributes).map(&:symbolize_keys)
45
+ a.should include({ id: 1, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
46
+ end
47
+
48
+ it "is cool with both baseline and six month events being created" do
49
+ subject.study_id_study = "OUT"
50
+ subject.study_id_site = "BBB"
51
+ subject.study_id_id = "1234"
52
+ subject.event_datetimes = ["2000-01-01 12:00:00", "2001-01-01 13:00:00", ""]
53
+
54
+ subject.should be_valid
55
+ subject.save.should be_truthy
56
+ a1, a2 = Assessment.all.map(&:attributes).map(&:symbolize_keys)
57
+ a1.should include({ id: 1, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
58
+ a2.should include({ id: 2, created_at: Time.parse("2001-01-01 13:00:00 UTC"), assessment_updated_at: Time.parse("2001-01-01 13:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "6 month" })
59
+ end
60
+
61
+ it "is cool with baseline, six month, and twelve month events being created" do
62
+ subject.study_id_study = "OUT"
63
+ subject.study_id_site = "BBB"
64
+ subject.study_id_id = "1234"
65
+ subject.event_datetimes = ["2000-01-01 12:00:00", "2001-01-01 13:00:00", "2002-01-01 14:00:00"]
66
+
67
+ subject.should be_valid
68
+ subject.save.should be_truthy
69
+ a1, a2, a3 = Assessment.all.map(&:attributes).map(&:symbolize_keys)
70
+ a1.should include({ id: 1, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
71
+ a2.should include({ id: 2, created_at: Time.parse("2001-01-01 13:00:00 UTC"), assessment_updated_at: Time.parse("2001-01-01 13:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "6 month" })
72
+ a3.should include({ id: 3, created_at: Time.parse("2002-01-01 14:00:00 UTC"), assessment_updated_at: Time.parse("2002-01-01 14:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "12 month", group_index: nil })
73
+ end
74
+
75
+ it "complains about at least one event being specified" do
76
+ subject.valid?
77
+ subject.errors.full_messages.should include("A baseline, 6 month, or 12 month timestamp must be present")
78
+ end
79
+
80
+ it "complains if a six month is specified without a baseline" do
81
+ subject.study_id_study = "OUT"
82
+ subject.study_id_site = "BBB"
83
+ subject.study_id_id = "1234"
84
+ subject.event_datetimes = ["", "2000-01-01 12:00:00", ""]
85
+
86
+ subject.valid?
87
+ subject.errors.full_messages.should include("Cannot add a 6 month assessment when baseline assessment does not exist")
88
+ end
89
+
90
+ it "complains if a twelve month is specified without a six month" do
91
+ subject.study_id_study = "OUT"
92
+ subject.study_id_site = "BBB"
93
+ subject.study_id_id = "1234"
94
+ subject.event_datetimes = ["", "", "2000-01-01 12:00:00"]
95
+
96
+ subject.valid?
97
+ subject.errors.full_messages.should include("Cannot add a 12 month assessment when 6 month assessment does not exist")
98
+ end
99
+ end
100
+
101
+ context "with a baseline event" do
102
+ before do
103
+ Assessment.create!({
104
+ study_id: "OUT-BBB-1234",
105
+ event: "Baseline",
106
+ created_at: "1999-01-01 00:00:00 UTC",
107
+ assessment_updated_at: "1999-01-01 00:00:00 UTC",
108
+ })
109
+ end
110
+
111
+ it "is cool with a six month event being created" do
112
+ subject.study_id_study = "OUT"
113
+ subject.study_id_site = "BBB"
114
+ subject.study_id_id = "1234"
115
+ subject.event_datetimes = ["", "2000-01-01 12:00:00", ""]
116
+
117
+ subject.should be_valid
118
+ subject.save.should be_truthy
119
+ a1, a2 = Assessment.all.map(&:attributes).map(&:symbolize_keys)
120
+ a1.should include({ id: 1, created_at: Time.parse("1999-01-01 00:00:00 UTC"), assessment_updated_at: Time.parse("1999-01-01 00:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
121
+ a2.should include({ id: 2, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "6 month" })
122
+ end
123
+
124
+ it "is cool with a six month and twelve month event being created" do
125
+ subject.study_id_study = "OUT"
126
+ subject.study_id_site = "BBB"
127
+ subject.study_id_id = "1234"
128
+ subject.event_datetimes = ["", "2000-01-01 12:00:00", "2001-01-01 13:00:00"]
129
+
130
+ subject.should be_valid
131
+ subject.save.should be_truthy
132
+ a1, a2, a3 = Assessment.all.map(&:attributes).map(&:symbolize_keys)
133
+ a1.should include({ id: 1, created_at: Time.parse("1999-01-01 00:00:00 UTC"), assessment_updated_at: Time.parse("1999-01-01 00:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
134
+ a2.should include({ id: 2, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "6 month" })
135
+ a3.should include({ id: 3, created_at: Time.parse("2001-01-01 13:00:00 UTC"), assessment_updated_at: Time.parse("2001-01-01 13:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "12 month" })
136
+ end
137
+ end
138
+
139
+ context "with both baseline and six month events" do
140
+ before do
141
+ Assessment.create!({
142
+ study_id: "OUT-BBB-1234",
143
+ event: "Baseline",
144
+ created_at: "1999-01-01 00:00:00 UTC",
145
+ assessment_updated_at: "1999-01-01 00:00:00 UTC",
146
+ })
147
+ Assessment.create!({
148
+ study_id: "OUT-BBB-1234",
149
+ event: "6 month",
150
+ created_at: "2000-01-01 12:00:00 UTC",
151
+ assessment_updated_at: "2000-01-01 12:00:00 UTC",
152
+ })
153
+ end
154
+
155
+ it "is cool with a twelve month event being created" do
156
+ subject.study_id_study = "OUT"
157
+ subject.study_id_site = "BBB"
158
+ subject.study_id_id = "1234"
159
+ subject.event_datetimes = ["", "", "2001-01-01 13:00:00"]
160
+
161
+ subject.should be_valid
162
+ subject.save.should be_truthy
163
+ a1, a2, a3 = Assessment.all.map(&:attributes).map(&:symbolize_keys)
164
+ a1.should include({ id: 1, created_at: Time.parse("1999-01-01 00:00:00 UTC"), assessment_updated_at: Time.parse("1999-01-01 00:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "Baseline" })
165
+ a2.should include({ id: 2, created_at: Time.parse("2000-01-01 12:00:00 UTC"), assessment_updated_at: Time.parse("2000-01-01 12:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "6 month" })
166
+ a3.should include({ id: 3, created_at: Time.parse("2001-01-01 13:00:00 UTC"), assessment_updated_at: Time.parse("2001-01-01 13:00:00 UTC"), study_id: StudyID.new("OUT-BBB-1234"), event: "12 month" })
167
+ end
168
+ end
169
+ end
170
+ end
171
+
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+ require "study_engine/report"
3
+ require "study_engine/config"
4
+
5
+ module StudyEngine
6
+ describe Report do
7
+ before do
8
+ StudyEngine.events = ["Baseline", "6 month", "12 month"]
9
+ end
10
+
11
+ describe "#groups" do
12
+ let(:a1ai) { double("a1ai", study_id: "a1", event: "Baseline", completed_at: false) }
13
+ let(:a1bi) { double("a1bi", study_id: "a1", event: "6 month", completed_at: false) }
14
+
15
+ let(:a2ai) { double("a2ai", study_id: "a2", event: "Baseline", completed_at: false) }
16
+
17
+ let(:a1a) { double("a1a", study_id: "a1", event: "Baseline", completed_at: Time.new) }
18
+ let(:a1b) { double("a1b", study_id: "a1", event: "6 month", completed_at: Time.new) }
19
+ let(:a1c) { double("a1c", study_id: "a1", event: "12 month", completed_at: Time.new) }
20
+
21
+ let(:a2a) { double("a2a", study_id: "a2", event: "Baseline", completed_at: Time.new) }
22
+ let(:a2b) { double("a2b", study_id: "a2", event: "6 month", completed_at: Time.new) }
23
+
24
+ let(:a3a) { double("a3a", study_id: "a3", event: "Baseline", completed_at: Time.new) }
25
+
26
+ let(:assessments) do
27
+ [a1ai, a1a, a1b, a1bi, a1c, a2ai, a2a, a2b, a3a]
28
+ end
29
+
30
+ it "returns a data structure assessments grouped by study id ordered by event and preferring complete" do
31
+ Report.new(assessments, "study_id", "ASC").groups.should == [
32
+ Report.group_class.new("a1", [a1a, a1ai], [a1b, a1bi], [a1c]),
33
+ Report.group_class.new("a2", [a2a, a2ai], [a2b], []),
34
+ Report.group_class.new("a3", [a3a], [], []),
35
+ ]
36
+ end
37
+
38
+ it "can order by study_id descending" do
39
+ Report.new(assessments, "study_id", "DESC").groups.should == [
40
+ Report.group_class.new("a3", [a3a], [], []),
41
+ Report.group_class.new("a2", [a2a, a2ai], [a2b], []),
42
+ Report.group_class.new("a1", [a1a, a1ai], [a1b, a1bi], [a1c]),
43
+ ]
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,102 @@
1
+ require "ar_helper"
2
+ require "study_engine/result"
3
+ require "study_engine/answer" # FIXME
4
+ require "ostruct"
5
+
6
+ module StudyEngine
7
+ describe Result do
8
+ describe "#current_question" do
9
+ it "delegates to bank" do
10
+ question = double
11
+ bank = double(current_question: question)
12
+ subject.stub bank: bank
13
+ subject.current_question.should == question
14
+ end
15
+ end
16
+
17
+ describe "#bank" do
18
+ it "returns the cat assessment initialized with the history" do
19
+ stub_const "CatEngine::Bank", double
20
+ bank = double
21
+
22
+ subject.bank_id = "01. Alpha"
23
+ subject.stub history: "OMG WTF BBQ"
24
+ subject.stub assessment: double(full_history: %w(a b c))
25
+
26
+ CatEngine::Bank.should receive(:new).with("01. Alpha", "OMG WTF BBQ", %w(a b c)).and_return(bank)
27
+
28
+ subject.bank.should == bank
29
+ end
30
+ end
31
+
32
+ describe "#name" do
33
+ it "returns the cat assessment id" do
34
+ subject.bank_id = "OMG"
35
+ subject.name.should == "OMG"
36
+ end
37
+ end
38
+
39
+ describe "#save_answer" do
40
+ before do
41
+ subject.stub bank: bank
42
+ end
43
+
44
+ let(:bank) { OpenStruct.new(finished: true, theta: 3.14159, standard_error: 0.5) }
45
+ let(:answer) { Answer.new(response_id: "OMG") }
46
+
47
+ context "with valid answer" do
48
+ before { def bank.valid_answer?(*); true; end }
49
+
50
+ it "updates the history attribute" do
51
+ subject.save_answer answer
52
+ subject.history.should == "OMG"
53
+ end
54
+
55
+ it "creates an answer record" do
56
+ subject.save_answer answer
57
+ subject.answers.should == [answer]
58
+ end
59
+
60
+ it "updates the attributes when finished" do
61
+ subject.save_answer answer
62
+ subject.should be_finished
63
+ subject.theta.should == 3.14159
64
+ subject.standard_error.should == 0.5
65
+ end
66
+
67
+ it "persists the record" do
68
+ subject.should_not be_persisted
69
+ subject.save_answer answer
70
+ subject.should be_persisted
71
+ end
72
+ end
73
+
74
+ context "with invalid answer" do
75
+ before { def bank.valid_answer?(*); false; end }
76
+
77
+ it "updates the history attribute" do
78
+ subject.save_answer answer
79
+ subject.history.should == ""
80
+ end
81
+
82
+ it "creates an answer record" do
83
+ subject.save_answer answer
84
+ subject.answers.should == []
85
+ end
86
+
87
+ it "updates the attributes when finished" do
88
+ subject.save_answer answer
89
+ subject.should_not be_finished
90
+ subject.theta.should be_nil
91
+ subject.standard_error.should be_nil
92
+ end
93
+
94
+ it "persists the record" do
95
+ subject.save_answer answer
96
+ subject.should_not be_persisted
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
@@ -0,0 +1,69 @@
1
+ require "ar_helper"
2
+ require "study_engine/screen_results"
3
+ require "timecop"
4
+
5
+ require "study_engine/report"
6
+ require "study_engine/assessment"
7
+ require "study_engine/result"
8
+
9
+ module StudyEngine
10
+ describe ScreenResults do
11
+ before do
12
+ StudyEngine.configure do |config|
13
+ config.cat_path = "spec/support"
14
+ config.groups = { "12 month" => %w(A B C) }
15
+ config.bank_finder = -> (assessment) {
16
+ if assessment.event == "12 month"
17
+ (0..8).to_a
18
+ else
19
+ (0..9).to_a
20
+ end
21
+ }
22
+ end
23
+ end
24
+
25
+ after do
26
+ StudyEngine.bank_finder = -> (_) { StudyEngine.banks }
27
+ end
28
+
29
+ before do
30
+ Timecop.freeze "2011-01-01 11:11:11 UTC" do
31
+ Assessment.by_event("Baseline").create! study_id: "FIX-AAA-1234", method_applied: "In-person", notes: "note 1-b"
32
+ Assessment.by_event("6 month").create! study_id: "FIX-AAA-1234", method_applied: "In-person", notes: "note 1-6"
33
+ Assessment.by_event("12 month").create! study_id: "FIX-AAA-1234", method_applied: "In-person", notes: "note 1-12"
34
+ end
35
+
36
+ Timecop.freeze "2012-02-02 12:12:12 UTC" do
37
+ Assessment.by_event("6 month").create! study_id: "FIX-AAA-1234", method_applied: "In-person", notes: "note 2-6"
38
+ end
39
+
40
+ Timecop.freeze "2013-03-03 13:13:13 UTC" do
41
+ Assessment.by_event("Baseline").create! study_id: "FIX-AAA-2345", method_applied: "In-person", notes: "note 3-b"
42
+ Assessment.by_event("6 month").create! study_id: "FIX-AAA-2345", method_applied: "In-person", notes: "note 3-6"
43
+ Assessment.by_event("12 month").create! study_id: "FIX-AAA-2345", method_applied: "In-person", notes: "note 3-12"
44
+ end
45
+ end
46
+
47
+ let(:report) do
48
+ Report.new(Assessment.all, "study_id", "ASC")
49
+ end
50
+
51
+ subject do
52
+ ScreenResults.new(report.groups)
53
+ end
54
+
55
+ describe "#each" do
56
+ it "yields the header and body" do
57
+ results = []
58
+ subject.each { |row| results << row }
59
+ results.should == [
60
+ ["Study ID", "Baseline incomplete", "Baseline timestamp", "Baseline method", "Baseline coordinator", "Baseline note", "6 month incomplete", "6 month timestamp", "6 month method", "6 month coordinator", "6 month note", "12 month incomplete", "12 month timestamp", "12 month method", "12 month coordinator", "12 month note", "12 month set"],
61
+ ["FIX-AAA-1234", "0/10", "2011-01-01 11:11:11 UTC", "In-person", nil, "note 1-b", "0/10", "2011-01-01 11:11:11 UTC", "In-person", nil, "note 1-6", "0/9", "2011-01-01 11:11:11 UTC", "In-person", nil, "note 1-12", "A"],
62
+ ["FIX-AAA-1234", "", "", "", "", "", "0/10", "2012-02-02 12:12:12 UTC", "In-person", nil, "note 2-6", "", "", "", "", "", "" ],
63
+ ["FIX-AAA-2345", "0/10", "2013-03-03 13:13:13 UTC", "In-person", nil, "note 3-b", "0/10", "2013-03-03 13:13:13 UTC", "In-person", nil, "note 3-6", "0/9", "2013-03-03 13:13:13 UTC", "In-person", nil, "note 3-12", "B"],
64
+ ]
65
+ end
66
+ end
67
+ end
68
+ end
69
+