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,8 @@
1
+ This email confirms that a <%= @study_name %> assessment has been recorded for a study participant. Assessment details are located below:
2
+
3
+ Study ID: <%= @assessment.study_id %>
4
+ Assessment: <%= @assessment.event %>
5
+ Domains: <%= domains_and_group_summary(@assessment) %>
6
+ Date and time: <%= @assessment.assessment_updated_at %>
7
+ Method applied: <%= @assessment.method_applied %>
8
+ Coordinator: <%= @assessment.coordinator_email %>
@@ -0,0 +1,6 @@
1
+ This email confirms your request for a URL that will provide access to an assessment for a study participant. Details pertaining to your request are located below:
2
+
3
+ Study ID: <%= @assessment.study_id %>
4
+ Assessment: <%= @assessment.event %>
5
+ URL: <%= assessment_url(@assessment) %>
6
+ Date and time requested: <%= @assessment.created_at %>
data/config/routes.rb ADDED
@@ -0,0 +1,15 @@
1
+ StudyEngine::Engine.routes.draw do
2
+ namespace :admin do
3
+ root to: "assessments#index"
4
+ resources :assessments do
5
+ resource :notes
6
+ end
7
+ end
8
+
9
+ resources :assessments do
10
+ get :timeout, on: :member
11
+ post :notification, on: :member
12
+ end
13
+ root to: "assessments#index"
14
+ end
15
+
@@ -0,0 +1,52 @@
1
+ class CreateTables < ActiveRecord::Migration
2
+ def change
3
+ create_table "study_engine_answers" do |t|
4
+ t.integer "result_id", limit: 4
5
+ t.string "question_context", limit: 255
6
+ t.string "response_title", limit: 255
7
+ t.string "response_id", limit: 255
8
+ t.datetime "created_at", null: false
9
+ t.datetime "updated_at", null: false
10
+ t.string "question_id", limit: 255
11
+ t.string "question_title", limit: 255
12
+ t.string "question_promis_id", limit: 255
13
+ t.string "response_promis_id", limit: 255
14
+ t.string "response_before", limit: 255
15
+ end
16
+
17
+ create_table "study_engine_assessments" do |t|
18
+ t.text "finished_cat_assessment_ids", limit: 65535
19
+ t.datetime "created_at", null: false
20
+ t.datetime "updated_at", null: false
21
+ t.string "study_id", limit: 255
22
+ t.string "event", limit: 255
23
+ t.integer "group_index", limit: 4
24
+ t.string "method_applied", limit: 255
25
+ t.integer "coordinator_id", limit: 4
26
+ t.datetime "assessment_updated_at", null: false
27
+ t.text "notes", limit: 65535
28
+ t.datetime "completed_at"
29
+ end
30
+
31
+ create_table "study_engine_results" do |t|
32
+ t.integer "assessment_id", limit: 4
33
+ t.string "bank_id", limit: 255
34
+ t.boolean "finished", default: false
35
+ t.decimal "theta", precision: 10, scale: 5
36
+ t.decimal "standard_error", precision: 10, scale: 5
37
+ t.datetime "created_at", null: false
38
+ t.datetime "updated_at", null: false
39
+ end
40
+
41
+ add_index "study_engine_results", ["assessment_id"], name: "index_study_engine_results_on_assessment_id", using: :btree
42
+ add_index "study_engine_results", ["bank_id"], name: "index_results_on_cat_assessment_id", using: :btree
43
+
44
+ create_table "study_engine_study_ids" do |t|
45
+ t.string "study_id_study", limit: 255
46
+ t.string "study_id_site", limit: 255
47
+ t.string "study_id_id", limit: 255
48
+ t.datetime "created_at"
49
+ t.datetime "updated_at"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ require "study_engine/config"
2
+ require "study_engine/engine" if defined?(Rails)
3
+
4
+ module StudyEngine
5
+ end
@@ -0,0 +1,37 @@
1
+ require "active_support/core_ext/module/attribute_accessors"
2
+ require "cat_engine/config"
3
+
4
+ module StudyEngine
5
+ def self.configure
6
+ yield self
7
+ end
8
+
9
+ mattr_accessor(:study_name) { "" }
10
+ mattr_accessor(:study_url) { "" }
11
+ mattr_accessor(:notification_email) { "" }
12
+ mattr_accessor(:welcome_content) { "" }
13
+
14
+ mattr_accessor(:groups) { Hash.new }
15
+ mattr_accessor(:banks) { [] }
16
+ mattr_accessor(:bank_finder) { Proc.new { banks } }
17
+ mattr_accessor(:events) { ["Baseline", "6 month", "12 month"] }
18
+ mattr_accessor(:enabled_application_methods) {
19
+ [
20
+ "In-person",
21
+ "By phone",
22
+ "By URL",
23
+ "By mail",
24
+ "Paper form",
25
+ ]
26
+ }
27
+
28
+ mattr_accessor(:redcap_token) { "" }
29
+
30
+ class << self
31
+ delegate :cat_path, :cat_path=,
32
+ :cat_engine_source_path, :cat_engine_source_path=,
33
+ :cat_engine_executable_path, :cat_engine_executable_path=,
34
+ to: CatEngine
35
+ end
36
+ end
37
+
@@ -0,0 +1,96 @@
1
+ Given "the assessment timeout interval is set to $count seconds" do |count|
2
+ @original_assessment_timeout_interval = StudyEngine::Assessment.timeout_interval
3
+ StudyEngine::Assessment.timeout_interval = count.to_i
4
+ end
5
+
6
+ After do
7
+ if defined?(@original_assessment_timeout_interval)
8
+ StudyEngine::Assessment.timeout_interval = @original_assessment_timeout_interval
9
+ end
10
+ end
11
+
12
+ Given "the following study ids exist:" do |table|
13
+ table.raw.each do |row|
14
+ StudyEngine::StudyID::Bank.find_or_create_from_full_study_id row.first
15
+ end
16
+ end
17
+
18
+ Given "the following assessment results exist:" do |table|
19
+ table.hashes.each do |attributes|
20
+ study_id = attributes["study_id"]
21
+ baseline = attributes["baseline"]
22
+ three_month = attributes["3 month"]
23
+ six_month = attributes["6 month"]
24
+ twelve_month = attributes["12 month"]
25
+
26
+ create_stub_assessment study_id, "Baseline", baseline if baseline.present?
27
+ create_stub_assessment study_id, "3 month", three_month if three_month.present?
28
+ create_stub_assessment study_id, "6 month", six_month if six_month.present?
29
+ create_stub_assessment study_id, "12 month", twelve_month if twelve_month.present?
30
+ end
31
+ end
32
+
33
+ def create_stub_assessment study_id, event, time
34
+ assessment = StudyEngine::Assessment.create!({
35
+ study_id: study_id,
36
+ event: event,
37
+ method_applied: "In-person",
38
+ })
39
+ assessment.results.each do |result|
40
+ result.update_attribute :finished, true
41
+ end
42
+ assessment.update({
43
+ created_at: time,
44
+ assessment_updated_at: time,
45
+ completed_at: time,
46
+ })
47
+ assessment
48
+ end
49
+
50
+ When /^I choose "(.+?)" and "(.+?)" for the question pair$/ do |before, after|
51
+ within all(".paired-bank")[0] do
52
+ choose before
53
+ end
54
+ within all(".paired-bank")[1] do
55
+ choose after
56
+ end
57
+ end
58
+
59
+ When /^I should see the progress bar at (\d+%)$/ do |percent|
60
+ begin
61
+ find(".percentage", text: percent)
62
+ rescue Capybara::ElementNotFound
63
+ find(".percentage").text.should == percent
64
+ end
65
+ end
66
+
67
+ Then 'I should see the "Start Assessment" form' do
68
+ page.should have_css("form input[value='Start Assessment']")
69
+ end
70
+
71
+ Then "I should see the following assessment results:" do |table|
72
+ assessments = all(".results-table tr").map do |row|
73
+ row.all("th,td").map(&:text)
74
+ end
75
+ table.diff! assessments
76
+ end
77
+
78
+ Then "I should see that notes are present" do
79
+ find("label.note.-saved")
80
+ end
81
+
82
+ Then 'I should download a csv named "$filename" with the following contents:' do |filename, table|
83
+ page.response_headers['Content-Disposition'].should include("filename=\"#{filename}\"")
84
+ page.execute_script """
85
+ window.xhrDownload = function(url) {
86
+ var xhr = new XMLHttpRequest();
87
+ xhr.open('GET', url, false);
88
+ xhr.send(null);
89
+ return xhr.responseText;
90
+ };
91
+ """
92
+ csv = page.evaluate_script("xhrDownload('#{@last_path}');")
93
+ csv_table = CSV.parse(csv)
94
+ table.diff! csv_table
95
+ end
96
+
@@ -0,0 +1,7 @@
1
+ require "csv_builder"
2
+
3
+ module StudyEngine
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace StudyEngine
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module StudyEngine
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,10 @@
1
+ namespace :study_engine do
2
+ desc "compile the CAT Engine"
3
+ task :compile_cat_engine => "cat_engine:compile_cat_engine"
4
+
5
+ desc "sync study ids from REDCap"
6
+ task :sync_study_ids => :environment do
7
+ StudyEngine::StudyID::Sync.call
8
+ end
9
+ end
10
+
data/spec/ar_helper.rb ADDED
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+ require "active_record"
3
+ require "database_cleaner"
4
+ require "byebug"
5
+
6
+ ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
7
+
8
+ # sqlite3 hates our mysql indexes
9
+ ActiveRecord::Migration.class_eval do
10
+ def add_index *; end
11
+ end
12
+
13
+ DatabaseCleaner.strategy = :transaction
14
+ silence_stream(STDOUT) do
15
+ load "spec/schema.rb"
16
+ end
17
+
18
+ RSpec.configure do |config|
19
+ config.before(:each) do
20
+ DatabaseCleaner.start
21
+ end
22
+
23
+ config.after(:each) do
24
+ DatabaseCleaner.clean
25
+ end
26
+ end
27
+
28
+ # silence deprecation warning
29
+ I18n.enforce_available_locales = true
30
+
@@ -0,0 +1,28 @@
1
+ require "ar_helper"
2
+ require "study_engine/answer"
3
+
4
+ module StudyEngine
5
+ describe Answer do
6
+ its(:result) { should be_nil }
7
+
8
+ describe "#response" do
9
+ it "returns a value object" do
10
+ subject.response_id = "OMG"
11
+ subject.response_promis_id = "1"
12
+ subject.response_title = "WTF"
13
+ subject.response.should == CatEngine::Response.new(id: "OMG", promis_id: "1", title: "WTF")
14
+ end
15
+ end
16
+
17
+ describe "#question" do
18
+ it "returns a value object" do
19
+ subject.question_id = "OMG"
20
+ subject.question_promis_id = "123"
21
+ subject.question_context = "WTF"
22
+ subject.question_title = "BBQ"
23
+ subject.question.should == CatEngine::Question.new(id: "OMG", promis_id: "123", context: "WTF", title: "BBQ", responses: [])
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,250 @@
1
+ require "ar_helper"
2
+ require "study_engine/assessment"
3
+ require "study_engine/config"
4
+ require "study_engine/result" # FIXME
5
+
6
+ module StudyEngine
7
+ describe Assessment do
8
+ let(:ids) { %w(Alpha Bravo Charlie Delta Echos) }
9
+
10
+ before { StudyEngine.banks = ids }
11
+
12
+ context "new" do
13
+ its(:stream_id) { should be_nil }
14
+ its(:study_id) { should be_nil }
15
+ its(:event) { should be_nil }
16
+ its(:percent_complete) { should == 0 }
17
+
18
+ its(:group_index) { should be_nil }
19
+ its(:group_index_name) { should == "" }
20
+
21
+ describe "#results" do
22
+ it "pads the list with unpersisted results for each cat assessment" do
23
+ results = subject.results.map do |result|
24
+ [result.bank_id, result.persisted?]
25
+ end
26
+
27
+ results.should == [
28
+ ["Alpha", false],
29
+ ["Bravo", false],
30
+ ["Charlie", false],
31
+ ["Delta", false],
32
+ ["Echos", false],
33
+ ]
34
+ end
35
+ end
36
+
37
+ describe "#results_summary" do
38
+ it "is a string of how many banks are completed" do
39
+ subject.results_summary.should == "0/5"
40
+ end
41
+ end
42
+
43
+ # straight up comparison fails
44
+ its(:"current_result.bank_id") { should == "Alpha" }
45
+
46
+ describe "#current_question" do
47
+ it "delegates to current_result" do
48
+ question = double
49
+ result = double(current_question: question)
50
+ subject.stub current_result: result
51
+
52
+ subject.current_question.should == question
53
+ end
54
+ end
55
+
56
+
57
+ describe "#save_answer" do
58
+ it "delegates to current_result" do
59
+ result = double
60
+ answer = double
61
+ subject.stub(current_result: result)
62
+
63
+ result.should_receive(:save_answer).with(answer)
64
+
65
+ # make valid
66
+ subject.study_id = "OUT-BBB-1234"
67
+ subject.event = "Baseline"
68
+ subject.save_answer answer
69
+
70
+ subject.should be_persisted
71
+ end
72
+ end
73
+
74
+ it { should_not be_complete }
75
+ it { should be_incomplete }
76
+ end
77
+
78
+ context "in progress" do
79
+ before do
80
+ subject.study_id = "OUT-BBB-1234"
81
+ subject.event = "Baseline" # make valid
82
+ subject.save!
83
+
84
+ subject.results[0].update_attribute :finished, true
85
+ subject.results[1].update_attribute :finished, true
86
+ end
87
+
88
+ its(:stream_id) { should == StudyID.new("STR-BBB-1001") }
89
+ its(:study_id) { should == StudyID.new("OUT-BBB-1234") }
90
+
91
+ its(:percent_complete) { should == 40 }
92
+
93
+ its(:group_index) { should be_nil }
94
+
95
+ # straight up comparison fails
96
+ its(:"current_result.bank_id") { should == "Charlie" }
97
+
98
+ describe "#results" do
99
+ it "pads the list with unpersisted results for each cat assessment" do
100
+
101
+ results = subject.results.map do |result|
102
+ [result.bank_id, result.persisted?]
103
+ end
104
+
105
+ results.should == [
106
+ ["Alpha", true],
107
+ ["Bravo", true],
108
+ ["Charlie", false],
109
+ ["Delta", false],
110
+ ["Echos", false],
111
+ ]
112
+ end
113
+ end
114
+
115
+ it { should_not be_complete }
116
+ it { should be_incomplete }
117
+ end
118
+
119
+ context "complete" do
120
+ before do
121
+ subject.study_id = "OUT-BBB-1234"
122
+ subject.event = "Baseline" # make valid
123
+
124
+ subject.save!
125
+ subject.results.each do |result|
126
+ result.update_attribute :finished, true
127
+ end
128
+ end
129
+
130
+ describe "#results" do
131
+ it "pads the list with unpersisted results for each cat assessment" do
132
+ results = subject.results.map do |result|
133
+ [result.bank_id, result.persisted?]
134
+ end
135
+
136
+ results.should == [
137
+ ["Alpha", true],
138
+ ["Bravo", true],
139
+ ["Charlie", true],
140
+ ["Delta", true],
141
+ ["Echos", true],
142
+ ]
143
+ end
144
+ end
145
+
146
+ its(:percent_complete) { should == 100 }
147
+
148
+ its(:group_index) { should be_nil }
149
+ its(:current_result) { should be_nil }
150
+
151
+ describe "#current_question" do
152
+ it "raises an error" do
153
+ lambda { subject.current_question }.should raise_exception(StandardError)
154
+ end
155
+ end
156
+
157
+ describe "#history=" do
158
+ it "raises an error" do
159
+ lambda { subject.history = double }.should raise_exception(StandardError)
160
+ end
161
+ end
162
+
163
+ it { should be_complete }
164
+ it { should_not be_incomplete }
165
+ end
166
+
167
+ describe "#study_id=" do
168
+ it "assigns the parts" do
169
+ subject.study_id = "FIX-BBB-0000"
170
+ subject.study_id.study.should == "FIX"
171
+ subject.study_id.site.should == "BBB"
172
+ subject.study_id.id.should == "0000"
173
+ subject.study_id.should == StudyID.new("FIX-BBB-0000")
174
+ end
175
+ end
176
+
177
+ describe "groups" do
178
+ def create_assessment attributes = {}
179
+ attributes.reverse_merge! event: "12 month"
180
+ described_class.new(attributes).tap do |assessment|
181
+ assessment.save(validate: false)
182
+ end
183
+ end
184
+
185
+ before do
186
+ StudyEngine.groups = { "12 month" => %w(A B C) }
187
+ end
188
+
189
+ describe "#group_index" do
190
+ it "is 0 when there is one twelve month assessment" do
191
+ create_assessment.group_index.should == 0
192
+ end
193
+
194
+ it "is 1 when there are two twelve month assessments" do
195
+ create_assessment
196
+ create_assessment.group_index.should == 1
197
+ end
198
+
199
+ it "is 2 when there are three twelve month assessments" do
200
+ 2.times { create_assessment }
201
+ create_assessment.group_index.should == 2
202
+ end
203
+
204
+ it "is 0 when there are four twelve month assessments" do
205
+ 3.times { create_assessment }
206
+ create_assessment.group_index.should == 0
207
+ end
208
+
209
+ it "is nil when subject is not a twelve month assessment" do
210
+ assessment = create_assessment(event: "baseline")
211
+ assessment.group_index.should be_nil
212
+ end
213
+
214
+ it "doesnt change after subsequent assessments are added" do
215
+ assessment = create_assessment
216
+ assessment.group_index.should == 0
217
+ create_assessment
218
+ assessment.group_index.should == 0
219
+ end
220
+
221
+ it "retains previous group index if restarted" do
222
+ a1 = create_assessment study_id: "ABC-DEF-1234"
223
+ a2 = create_assessment study_id: "ABC-DEF-1234"
224
+ a2.group_index.should == a1.group_index
225
+ end
226
+ end
227
+
228
+ describe "#group_index_name" do
229
+ it "is A when group_index is 0" do
230
+ assessment = create_assessment
231
+ assessment.group_index = 0
232
+ assessment.group_index_name.should == "A"
233
+ end
234
+
235
+ it "is B when group_index is 1" do
236
+ assessment = create_assessment
237
+ assessment.group_index = 1
238
+ assessment.group_index_name.should == "B"
239
+ end
240
+
241
+ it "is C when group_index is 2" do
242
+ assessment = create_assessment
243
+ assessment.group_index = 2
244
+ assessment.group_index_name.should == "C"
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
250
+