ccls-ccls_engine 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. data/README.rdoc +182 -0
  2. data/app/models/abstract.rb +181 -0
  3. data/app/models/abstract_search.rb +50 -0
  4. data/app/models/abstract_validations.rb +324 -0
  5. data/app/models/address.rb +70 -0
  6. data/app/models/address_type.rb +15 -0
  7. data/app/models/addressing.rb +147 -0
  8. data/app/models/aliquot.rb +44 -0
  9. data/app/models/aliquot_sample_format.rb +13 -0
  10. data/app/models/analysis.rb +14 -0
  11. data/app/models/bc_request.rb +20 -0
  12. data/app/models/candidate_control.rb +101 -0
  13. data/app/models/context.rb +23 -0
  14. data/app/models/context_data_source.rb +4 -0
  15. data/app/models/county.rb +16 -0
  16. data/app/models/data_source.rb +24 -0
  17. data/app/models/diagnosis.rb +23 -0
  18. data/app/models/document_type.rb +16 -0
  19. data/app/models/document_version.rb +27 -0
  20. data/app/models/enrollment.rb +78 -0
  21. data/app/models/enrollment_validations.rb +167 -0
  22. data/app/models/follow_up.rb +16 -0
  23. data/app/models/follow_up_type.rb +18 -0
  24. data/app/models/gift_card.rb +22 -0
  25. data/app/models/gift_card_search.rb +137 -0
  26. data/app/models/home_exposure_response.rb +24 -0
  27. data/app/models/homex_outcome.rb +75 -0
  28. data/app/models/hospital.rb +22 -0
  29. data/app/models/icf_master_id.rb +30 -0
  30. data/app/models/icf_master_tracker.rb +217 -0
  31. data/app/models/icf_master_tracker_change.rb +9 -0
  32. data/app/models/icf_master_tracker_update.rb +50 -0
  33. data/app/models/ineligible_reason.rb +26 -0
  34. data/app/models/instrument.rb +26 -0
  35. data/app/models/instrument_type.rb +17 -0
  36. data/app/models/instrument_version.rb +28 -0
  37. data/app/models/interview.rb +122 -0
  38. data/app/models/interview_method.rb +17 -0
  39. data/app/models/interview_outcome.rb +16 -0
  40. data/app/models/language.rb +28 -0
  41. data/app/models/live_birth_data_update.rb +142 -0
  42. data/app/models/operational_event.rb +99 -0
  43. data/app/models/operational_event_type.rb +31 -0
  44. data/app/models/organization.rb +28 -0
  45. data/app/models/patient.rb +63 -0
  46. data/app/models/patient_validations.rb +118 -0
  47. data/app/models/person.rb +28 -0
  48. data/app/models/phone_number.rb +105 -0
  49. data/app/models/phone_type.rb +15 -0
  50. data/app/models/project.rb +39 -0
  51. data/app/models/project_outcome.rb +19 -0
  52. data/app/models/race.rb +31 -0
  53. data/app/models/refusal_reason.rb +23 -0
  54. data/app/models/sample.rb +168 -0
  55. data/app/models/sample_kit.rb +14 -0
  56. data/app/models/sample_outcome.rb +16 -0
  57. data/app/models/sample_temperature.rb +14 -0
  58. data/app/models/sample_type.rb +37 -0
  59. data/app/models/search.rb +195 -0
  60. data/app/models/section.rb +18 -0
  61. data/app/models/state.rb +25 -0
  62. data/app/models/study_subject.rb +237 -0
  63. data/app/models/study_subject_abstracts.rb +47 -0
  64. data/app/models/study_subject_addresses.rb +34 -0
  65. data/app/models/study_subject_associations.rb +38 -0
  66. data/app/models/study_subject_duplicates.rb +111 -0
  67. data/app/models/study_subject_enrollments.rb +17 -0
  68. data/app/models/study_subject_homex_outcome.rb +22 -0
  69. data/app/models/study_subject_identifier.rb +153 -0
  70. data/app/models/study_subject_interviews.rb +25 -0
  71. data/app/models/study_subject_languages.rb +21 -0
  72. data/app/models/study_subject_operational_events.rb +66 -0
  73. data/app/models/study_subject_patient.rb +177 -0
  74. data/app/models/study_subject_pii.rb +74 -0
  75. data/app/models/study_subject_races.rb +25 -0
  76. data/app/models/study_subject_search.rb +260 -0
  77. data/app/models/study_subject_validations.rb +116 -0
  78. data/app/models/subject_language.rb +11 -0
  79. data/app/models/subject_race.rb +11 -0
  80. data/app/models/subject_relationship.rb +21 -0
  81. data/app/models/subject_type.rb +22 -0
  82. data/app/models/tracing_status.rb +20 -0
  83. data/app/models/transfer.rb +40 -0
  84. data/app/models/unit.rb +14 -0
  85. data/app/models/vital_status.rb +19 -0
  86. data/app/models/zip_code.rb +36 -0
  87. data/config/abstract_fields.yml +1038 -0
  88. data/config/abstract_sections.yml +77 -0
  89. data/config/home_exposure_response_fields.yml +583 -0
  90. data/config/icf_master_tracker_update.yml +56 -0
  91. data/config/live_birth_data_update.yml +56 -0
  92. data/config/shared_use_db.yml +4 -0
  93. data/generators/ccls_engine/USAGE +2 -0
  94. data/generators/ccls_engine/ccls_engine_generator.rb +123 -0
  95. data/generators/ccls_engine/templates/autotest_ccls_engine.rb +3 -0
  96. data/generators/ccls_engine/templates/ccls_engine.rake +12 -0
  97. data/generators/ccls_engine/templates/fixtures/address_types.yml +30 -0
  98. data/generators/ccls_engine/templates/fixtures/context_data_sources.yml +54 -0
  99. data/generators/ccls_engine/templates/fixtures/contexts.yml +19 -0
  100. data/generators/ccls_engine/templates/fixtures/data_sources.yml +40 -0
  101. data/generators/ccls_engine/templates/fixtures/diagnoses.yml +40 -0
  102. data/generators/ccls_engine/templates/fixtures/document_types.yml +65 -0
  103. data/generators/ccls_engine/templates/fixtures/document_versions.csv +155 -0
  104. data/generators/ccls_engine/templates/fixtures/follow_up_types.yml +16 -0
  105. data/generators/ccls_engine/templates/fixtures/hospitals.yml +114 -0
  106. data/generators/ccls_engine/templates/fixtures/ineligible_reasons.yml +35 -0
  107. data/generators/ccls_engine/templates/fixtures/instrument_types.yml +26 -0
  108. data/generators/ccls_engine/templates/fixtures/instrument_versions.yml +22 -0
  109. data/generators/ccls_engine/templates/fixtures/instruments.yml +22 -0
  110. data/generators/ccls_engine/templates/fixtures/interview_methods.yml +30 -0
  111. data/generators/ccls_engine/templates/fixtures/interview_outcomes.yml +31 -0
  112. data/generators/ccls_engine/templates/fixtures/languages.yml +34 -0
  113. data/generators/ccls_engine/templates/fixtures/operational_event_types.yml +141 -0
  114. data/generators/ccls_engine/templates/fixtures/organizations.yml +198 -0
  115. data/generators/ccls_engine/templates/fixtures/people.yml +130 -0
  116. data/generators/ccls_engine/templates/fixtures/phone_types.yml +30 -0
  117. data/generators/ccls_engine/templates/fixtures/project_outcomes.yml +25 -0
  118. data/generators/ccls_engine/templates/fixtures/projects.yml +59 -0
  119. data/generators/ccls_engine/templates/fixtures/races.yml +52 -0
  120. data/generators/ccls_engine/templates/fixtures/refusal_reasons.yml +55 -0
  121. data/generators/ccls_engine/templates/fixtures/sample_outcomes.yml +36 -0
  122. data/generators/ccls_engine/templates/fixtures/sample_temperatures.yml +16 -0
  123. data/generators/ccls_engine/templates/fixtures/sample_types.yml +147 -0
  124. data/generators/ccls_engine/templates/fixtures/sections.yml +31 -0
  125. data/generators/ccls_engine/templates/fixtures/states.yml +363 -0
  126. data/generators/ccls_engine/templates/fixtures/subject_relationships.yml +46 -0
  127. data/generators/ccls_engine/templates/fixtures/subject_types.yml +30 -0
  128. data/generators/ccls_engine/templates/fixtures/tracing_statuses.yml +30 -0
  129. data/generators/ccls_engine/templates/fixtures/units.yml +13 -0
  130. data/generators/ccls_engine/templates/fixtures/vital_statuses.yml +28 -0
  131. data/generators/ccls_engine/templates/functional/roles_controller_test.rb +142 -0
  132. data/generators/ccls_engine/templates/functional/sessions_controller_test.rb +19 -0
  133. data/generators/ccls_engine/templates/functional/users_controller_test.rb +94 -0
  134. data/generators/ccls_engine/templates/images/sort_down.png +0 -0
  135. data/generators/ccls_engine/templates/images/sort_up.png +0 -0
  136. data/generators/ccls_engine/templates/initializer.rb +28 -0
  137. data/generators/ccls_engine/templates/javascripts/ccls_engine.js +24 -0
  138. data/generators/ccls_engine/templates/javascripts/jquery-ui.js +763 -0
  139. data/generators/ccls_engine/templates/javascripts/jquery.js +154 -0
  140. data/generators/ccls_engine/templates/javascripts/jrails.js +1 -0
  141. data/generators/ccls_engine/templates/migrations/create_user_invitations.rb +18 -0
  142. data/generators/ccls_engine/templates/migrations/create_users.rb +33 -0
  143. data/generators/ccls_engine/templates/migrations/drop_user_invitations.rb +18 -0
  144. data/generators/ccls_engine/templates/stylesheets/ccls_engine.css +180 -0
  145. data/generators/ccls_engine/templates/stylesheets/user.css +35 -0
  146. data/generators/ccls_engine/templates/stylesheets/users.css +23 -0
  147. data/generators/ccls_engine/templates/unit/core_extension_test.rb +18 -0
  148. data/generators/ccls_engine/templates/unit/role_test.rb +30 -0
  149. data/generators/ccls_engine/templates/unit/user_test.rb +321 -0
  150. data/lib/ccls-ccls_engine.rb +1 -0
  151. data/lib/ccls_engine.rb +135 -0
  152. data/lib/ccls_engine/action_view_extension.rb +3 -0
  153. data/lib/ccls_engine/action_view_extension/base.rb +53 -0
  154. data/lib/ccls_engine/action_view_extension/form_builder.rb +39 -0
  155. data/lib/ccls_engine/active_record_extension.rb +2 -0
  156. data/lib/ccls_engine/active_record_extension/base.rb +70 -0
  157. data/lib/ccls_engine/active_record_shared.rb +8 -0
  158. data/lib/ccls_engine/assertions.rb +69 -0
  159. data/lib/ccls_engine/autotest.rb +54 -0
  160. data/lib/ccls_engine/ccls_user.rb +117 -0
  161. data/lib/ccls_engine/core_extension.rb +14 -0
  162. data/lib/ccls_engine/date_and_time_formats.rb +30 -0
  163. data/lib/ccls_engine/factories.rb +880 -0
  164. data/lib/ccls_engine/factory_test_helper.rb +276 -0
  165. data/lib/ccls_engine/helper.rb +112 -0
  166. data/lib/ccls_engine/icf_master_tracker_update_test_helper.rb +121 -0
  167. data/lib/ccls_engine/live_birth_data_update_test_helper.rb +110 -0
  168. data/lib/ccls_engine/package_test_helper.rb +49 -0
  169. data/lib/ccls_engine/shared_database.rb +20 -0
  170. data/lib/ccls_engine/tasks.rb +1 -0
  171. data/lib/ccls_engine/test_tasks.rb +52 -0
  172. data/lib/ccls_engine/translation_table.rb +86 -0
  173. data/lib/shared_migration.rb +5 -0
  174. data/lib/surveyor/survey_extensions.rb +125 -0
  175. data/lib/tasks/application.rake +286 -0
  176. data/lib/tasks/calnet_authenticated.rake +6 -0
  177. data/lib/tasks/common_lib.rake +7 -0
  178. data/lib/tasks/database.rake +288 -0
  179. data/lib/tasks/documentation.rake +71 -0
  180. data/lib/tasks/homex_import.rake +723 -0
  181. data/lib/tasks/odms_import.rake +1116 -0
  182. data/lib/tasks/simply_authorized.rake +6 -0
  183. data/lib/tasks/ucb_ccls_engine_tasks.rake +4 -0
  184. data/lib/tasks/use_db.rake +4 -0
  185. data/rails/init.rb +4 -0
  186. data/test/unit/ccls/abstract_search_test.rb +150 -0
  187. data/test/unit/ccls/abstract_test.rb +674 -0
  188. data/test/unit/ccls/address_test.rb +155 -0
  189. data/test/unit/ccls/address_type_test.rb +25 -0
  190. data/test/unit/ccls/addressing_test.rb +466 -0
  191. data/test/unit/ccls/aliquot_sample_format_test.rb +20 -0
  192. data/test/unit/ccls/aliquot_test.rb +156 -0
  193. data/test/unit/ccls/analysis_test.rb +31 -0
  194. data/test/unit/ccls/bc_request_test.rb +43 -0
  195. data/test/unit/ccls/candidate_control_test.rb +712 -0
  196. data/test/unit/ccls/context_data_source_test.rb +26 -0
  197. data/test/unit/ccls/context_test.rb +40 -0
  198. data/test/unit/ccls/core_extension_test.rb +17 -0
  199. data/test/unit/ccls/county_test.rb +34 -0
  200. data/test/unit/ccls/data_source_test.rb +41 -0
  201. data/test/unit/ccls/diagnosis_test.rb +51 -0
  202. data/test/unit/ccls/document_type_test.rb +35 -0
  203. data/test/unit/ccls/document_version_test.rb +68 -0
  204. data/test/unit/ccls/enrollment_test.rb +575 -0
  205. data/test/unit/ccls/follow_up_test.rb +23 -0
  206. data/test/unit/ccls/follow_up_type_test.rb +34 -0
  207. data/test/unit/ccls/gift_card_search_test.rb +153 -0
  208. data/test/unit/ccls/gift_card_test.rb +40 -0
  209. data/test/unit/ccls/home_exposure_response_test.rb +83 -0
  210. data/test/unit/ccls/homex_outcome_test.rb +199 -0
  211. data/test/unit/ccls/hospital_test.rb +102 -0
  212. data/test/unit/ccls/icf_master_id_test.rb +30 -0
  213. data/test/unit/ccls/icf_master_tracker_change_test.rb +14 -0
  214. data/test/unit/ccls/icf_master_tracker_test.rb +132 -0
  215. data/test/unit/ccls/icf_master_tracker_update_test.rb +176 -0
  216. data/test/unit/ccls/ineligible_reason_test.rb +48 -0
  217. data/test/unit/ccls/instrument_test.rb +62 -0
  218. data/test/unit/ccls/instrument_type_test.rb +39 -0
  219. data/test/unit/ccls/instrument_version_test.rb +71 -0
  220. data/test/unit/ccls/interview_method_test.rb +44 -0
  221. data/test/unit/ccls/interview_outcome_test.rb +34 -0
  222. data/test/unit/ccls/interview_test.rb +298 -0
  223. data/test/unit/ccls/language_test.rb +47 -0
  224. data/test/unit/ccls/live_birth_data_update_test.rb +358 -0
  225. data/test/unit/ccls/operational_event_test.rb +187 -0
  226. data/test/unit/ccls/operational_event_type_test.rb +51 -0
  227. data/test/unit/ccls/organization_test.rb +64 -0
  228. data/test/unit/ccls/patient_test.rb +538 -0
  229. data/test/unit/ccls/person_test.rb +55 -0
  230. data/test/unit/ccls/phone_number_test.rb +244 -0
  231. data/test/unit/ccls/phone_type_test.rb +32 -0
  232. data/test/unit/ccls/project_outcome_test.rb +34 -0
  233. data/test/unit/ccls/project_test.rb +60 -0
  234. data/test/unit/ccls/race_test.rb +37 -0
  235. data/test/unit/ccls/refusal_reason_test.rb +52 -0
  236. data/test/unit/ccls/role_test.rb +26 -0
  237. data/test/unit/ccls/sample_kit_test.rb +35 -0
  238. data/test/unit/ccls/sample_outcome_test.rb +34 -0
  239. data/test/unit/ccls/sample_temperature_test.rb +25 -0
  240. data/test/unit/ccls/sample_test.rb +363 -0
  241. data/test/unit/ccls/sample_type_test.rb +58 -0
  242. data/test/unit/ccls/section_test.rb +34 -0
  243. data/test/unit/ccls/state_test.rb +31 -0
  244. data/test/unit/ccls/study_subject_abstracts_test.rb +115 -0
  245. data/test/unit/ccls/study_subject_addresses_test.rb +93 -0
  246. data/test/unit/ccls/study_subject_duplicates_test.rb +407 -0
  247. data/test/unit/ccls/study_subject_enrollments_test.rb +65 -0
  248. data/test/unit/ccls/study_subject_homex_outcome_test.rb +64 -0
  249. data/test/unit/ccls/study_subject_identifier_test.rb +439 -0
  250. data/test/unit/ccls/study_subject_interviews_test.rb +26 -0
  251. data/test/unit/ccls/study_subject_languages_test.rb +142 -0
  252. data/test/unit/ccls/study_subject_operational_events_test.rb +53 -0
  253. data/test/unit/ccls/study_subject_patient_test.rb +249 -0
  254. data/test/unit/ccls/study_subject_pii_test.rb +278 -0
  255. data/test/unit/ccls/study_subject_races_test.rb +203 -0
  256. data/test/unit/ccls/study_subject_search_test.rb +704 -0
  257. data/test/unit/ccls/study_subject_test.rb +770 -0
  258. data/test/unit/ccls/subject_language_test.rb +43 -0
  259. data/test/unit/ccls/subject_race_test.rb +35 -0
  260. data/test/unit/ccls/subject_relationship_test.rb +43 -0
  261. data/test/unit/ccls/subject_type_test.rb +40 -0
  262. data/test/unit/ccls/tracing_status_test.rb +32 -0
  263. data/test/unit/ccls/transfer_test.rb +81 -0
  264. data/test/unit/ccls/translation_table_test.rb +40 -0
  265. data/test/unit/ccls/unit_test.rb +21 -0
  266. data/test/unit/ccls/user_test.rb +156 -0
  267. data/test/unit/ccls/vital_status_test.rb +36 -0
  268. data/test/unit/ccls/zip_code_test.rb +55 -0
  269. metadata +633 -0
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ class Ccls::SampleTypeTest < ActiveSupport::TestCase
4
+
5
+ assert_should_behave_like_a_hash
6
+
7
+ assert_should_create_default_object
8
+ assert_should_act_as_list( :scope => :parent_id )
9
+ assert_should_have_many( :samples )
10
+ assert_should_belong_to( :parent,
11
+ :class_name => 'SampleType' )
12
+ assert_should_have_many( :children,
13
+ :class_name => 'SampleType',
14
+ :foreign_key => 'parent_id' )
15
+ assert_should_not_require_attributes( :position, :parent_id )
16
+
17
+ test "should return description as to_s" do
18
+ object = create_object(:description => "Description")
19
+ assert_equal object.description,
20
+ "#{object}"
21
+ end
22
+
23
+ test "explicit Factory sample_type test" do
24
+ # creates sample_type and a parent sample_type
25
+ assert_difference('SampleType.count',2) {
26
+ sample_type = Factory(:sample_type)
27
+ assert_not_nil sample_type.parent
28
+ assert_match /Key\d*/, sample_type.key
29
+ assert_match /Desc\d*/, sample_type.description
30
+ assert sample_type.is_child?
31
+ }
32
+ end
33
+
34
+ test "explicit Factory sample_type parent test" do
35
+ assert_difference('SampleType.count',1) {
36
+ sample_type = Factory(:sample_type_parent)
37
+ assert_nil sample_type.parent
38
+ assert_match /Key\d*/, sample_type.key
39
+ assert_match /Desc\d*/, sample_type.description
40
+ assert sample_type.is_root?
41
+ }
42
+ end
43
+
44
+ protected
45
+
46
+ # The common assertions use create_object, so leave this alone.
47
+
48
+ def create_object(options = {})
49
+ # record = Factory.build(:sample_type,options)
50
+ # The normal sample_type factory creates a parent
51
+ # which seems to cause some testing issues unless
52
+ # this was expected so ....
53
+ record = Factory.build(:sample_type_parent,options)
54
+ record.save
55
+ record
56
+ end
57
+
58
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class Ccls::SectionTest < ActiveSupport::TestCase
4
+
5
+ assert_should_behave_like_a_hash
6
+
7
+ assert_should_create_default_object
8
+ assert_should_act_as_list
9
+ assert_should_have_many(:follow_ups)
10
+ assert_should_not_require_attributes( :position )
11
+ # assert_should_require_attribute_length( :event_category, :in => 4..250 )
12
+
13
+ test "explicit Factory section test" do
14
+ assert_difference('Section.count',1) {
15
+ section = Factory(:section)
16
+ assert_match /Key\d*/, section.key
17
+ assert_match /Desc\d*/, section.description
18
+ }
19
+ end
20
+
21
+ test "should return description as to_s" do
22
+ section = create_section
23
+ assert_equal section.description, "#{section}"
24
+ end
25
+
26
+ #protected
27
+ #
28
+ # def create_section(options={})
29
+ # section = Factory.build(:section,options)
30
+ # section.save
31
+ # section
32
+ # end
33
+
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class Ccls::StateTest < ActiveSupport::TestCase
4
+
5
+ assert_should_create_default_object
6
+ assert_should_act_as_list
7
+ assert_should_require_attributes( :code, :name, :fips_state_code, :fips_country_code )
8
+ assert_should_require_unique_attributes( :code, :name, :fips_state_code )
9
+ assert_should_not_require_attributes( :position )
10
+ assert_should_require_attribute_length( :code, :name,
11
+ :fips_state_code, :fips_country_code,
12
+ :maximum => 250 )
13
+
14
+ test "explicit Factory state test" do
15
+ assert_difference('State.count',1) {
16
+ state = Factory(:state)
17
+ assert_match /Code\d*/, state.code
18
+ assert_match /Name\d*/, state.name
19
+ assert_not_nil state.fips_state_code
20
+ assert_equal 'US', state.fips_country_code
21
+ }
22
+ end
23
+
24
+ test "should return an array of state abbreviations" do
25
+ abbreviations = State.abbreviations
26
+ assert_not_nil abbreviations
27
+ assert abbreviations.is_a?(Array)
28
+ assert abbreviations.length > 50
29
+ end
30
+
31
+ end
@@ -0,0 +1,115 @@
1
+ require 'test_helper'
2
+
3
+ # This is just a collection of abstract related tests
4
+ # for StudySubject separated only for clarity due
5
+ # to the size of the StudySubjectTest class.
6
+ class Ccls::StudySubjectAbstractsTest < ActiveSupport::TestCase
7
+
8
+ assert_should_have_many( :abstracts, :model => 'StudySubject')
9
+
10
+ test "should NOT destroy abstracts with study_subject" do
11
+ assert_difference('StudySubject.count',1) {
12
+ assert_difference('Abstract.count',1) {
13
+ @study_subject = Factory(:study_subject)
14
+ Factory(:abstract, :study_subject => @study_subject)
15
+ } }
16
+ assert_difference('StudySubject.count',-1) {
17
+ assert_difference('Abstract.count',0) {
18
+ @study_subject.destroy
19
+ } }
20
+ end
21
+
22
+ test "should raise StudySubject::NotTwoAbstracts with 0 abstracts" <<
23
+ " on abstracts_the_same?" do
24
+ study_subject = Factory(:study_subject)
25
+ assert_equal 0, study_subject.abstracts.length
26
+ assert_raise(StudySubject::NotTwoAbstracts) {
27
+ study_subject.abstracts_the_same?
28
+ }
29
+ end
30
+
31
+ test "should raise StudySubject::NotTwoAbstracts with 1 abstracts" <<
32
+ " on abstracts_the_same?" do
33
+ study_subject = Factory(:study_subject)
34
+ Factory(:abstract, :study_subject => study_subject)
35
+ study_subject.reload
36
+ assert_equal 1, study_subject.abstracts.length
37
+ assert_raise(StudySubject::NotTwoAbstracts) {
38
+ study_subject.abstracts_the_same?
39
+ }
40
+ end
41
+
42
+ test "should return true if abstracts are the same on abstracts_the_same?" do
43
+ study_subject = Factory(:study_subject)
44
+ Factory(:abstract, :study_subject => study_subject)
45
+ Factory(:abstract, :study_subject => study_subject)
46
+ study_subject.reload
47
+ assert_equal 2, study_subject.abstracts.length
48
+ assert study_subject.abstracts_the_same?
49
+ end
50
+
51
+ test "should raise StudySubject::NotTwoAbstracts with 3 abstracts" <<
52
+ " on abstracts_the_same?" do
53
+ study_subject = Factory(:study_subject)
54
+ Factory(:abstract, :study_subject => study_subject)
55
+ Factory(:abstract, :study_subject => study_subject)
56
+ Factory(:abstract, :study_subject => study_subject)
57
+ study_subject.reload
58
+ assert_equal 3, study_subject.abstracts.length
59
+ assert_raise(StudySubject::NotTwoAbstracts) {
60
+ study_subject.abstracts_the_same?
61
+ }
62
+ end
63
+
64
+ test "should raise StudySubject::NotTwoAbstracts with 0 abstracts" <<
65
+ " on abstract_diffs" do
66
+ study_subject = Factory(:study_subject)
67
+ assert_equal 0, study_subject.abstracts.length
68
+ assert_raise(StudySubject::NotTwoAbstracts) {
69
+ study_subject.abstract_diffs
70
+ }
71
+ end
72
+
73
+ test "should raise StudySubject::NotTwoAbstracts with 1 abstracts" <<
74
+ " on abstract_diffs" do
75
+ study_subject = Factory(:study_subject)
76
+ Factory(:abstract, :study_subject => study_subject)
77
+ study_subject.reload
78
+ assert_equal 1, study_subject.abstracts.length
79
+ assert_raise(StudySubject::NotTwoAbstracts) {
80
+ study_subject.abstract_diffs
81
+ }
82
+ end
83
+
84
+ test "should return true if abstracts are the same on abstract_diffs" do
85
+ study_subject = Factory(:study_subject)
86
+ Factory(:abstract, :study_subject => study_subject)
87
+ Factory(:abstract, :study_subject => study_subject)
88
+ study_subject.reload
89
+ assert_equal 2, study_subject.abstracts.length
90
+ assert_equal Hash.new, study_subject.abstract_diffs
91
+ assert study_subject.abstract_diffs.empty?
92
+ end
93
+
94
+ test "should raise StudySubject::NotTwoAbstracts with 3 abstracts" <<
95
+ " on abstract_diffs" do
96
+ study_subject = Factory(:study_subject)
97
+ Factory(:abstract, :study_subject => study_subject)
98
+ Factory(:abstract, :study_subject => study_subject)
99
+ Factory(:abstract, :study_subject => study_subject)
100
+ study_subject.reload
101
+ assert_equal 3, study_subject.abstracts.length
102
+ assert_raise(StudySubject::NotTwoAbstracts) {
103
+ study_subject.abstract_diffs
104
+ }
105
+ end
106
+
107
+ protected
108
+
109
+ def create_object
110
+ study_subject = Factory.build(:study_subject)
111
+ study_subject.save
112
+ study_subject
113
+ end
114
+
115
+ end
@@ -0,0 +1,93 @@
1
+ require 'test_helper'
2
+
3
+ class Ccls::StudySubjectAddressesTest < ActiveSupport::TestCase
4
+
5
+ assert_should_have_many(:addressings, :model => 'StudySubject')
6
+
7
+ test "should create study_subject and accept_nested_attributes_for addressings" do
8
+ assert_difference( 'Address.count', 1) {
9
+ assert_difference( 'Addressing.count', 1) {
10
+ assert_difference( "StudySubject.count", 1 ) {
11
+ study_subject = create_study_subject(
12
+ :addressings_attributes => [Factory.attributes_for(:addressing,
13
+ :address_attributes => Factory.attributes_for(:address,
14
+ :address_type => AddressType['residence'] ) )])
15
+ assert !study_subject.new_record?,
16
+ "#{study_subject.errors.full_messages.to_sentence}"
17
+ } } }
18
+ end
19
+
20
+ test "should create study_subject and ignore blank address" do
21
+ assert_difference( 'Address.count', 0) {
22
+ assert_difference( 'Addressing.count', 0) {
23
+ assert_difference( "StudySubject.count", 1 ) {
24
+ study_subject = create_study_subject(
25
+ :addressings_attributes => [Factory.attributes_for(:addressing,
26
+ :address_attributes => { :address_type => AddressType['residence'] } )])
27
+ assert !study_subject.new_record?,
28
+ "#{study_subject.errors.full_messages.to_sentence}"
29
+ } } }
30
+ end
31
+
32
+ test "should create study_subject and require address with flag" do
33
+ assert_difference( 'Address.count', 0) {
34
+ assert_difference( 'Addressing.count', 0) {
35
+ assert_difference( "StudySubject.count", 0 ) {
36
+ study_subject = create_study_subject(
37
+ :addressings_attributes => [Factory.attributes_for(:addressing,
38
+ :address_required => true,
39
+ :address_attributes => { :address_type => AddressType['residence'] } )])
40
+ assert study_subject.errors.on_attr_and_type?('addressings.address.line_1',:blank)
41
+ assert study_subject.errors.on_attr_and_type?('addressings.address.city',:blank)
42
+ assert study_subject.errors.on_attr_and_type?('addressings.address.state',:blank)
43
+ assert study_subject.errors.on_attr_and_type?('addressings.address.zip',:blank)
44
+ } } }
45
+ end
46
+
47
+ test "should respond to residence_addresses_count" do
48
+ study_subject = create_study_subject
49
+ assert study_subject.respond_to?(:residence_addresses_count)
50
+ assert_equal 0, study_subject.residence_addresses_count
51
+ study_subject.update_attributes(
52
+ :addressings_attributes => [Factory.attributes_for(:addressing,
53
+ :address_attributes => Factory.attributes_for(:address,
54
+ { :address_type => AddressType['residence'] } ))])
55
+ assert_equal 1, study_subject.reload.residence_addresses_count
56
+ study_subject.update_attributes(
57
+ :addressings_attributes => [Factory.attributes_for(:addressing,
58
+ :address_attributes => Factory.attributes_for(:address,
59
+ { :address_type => AddressType['residence'] } ))])
60
+ assert_equal 2, study_subject.reload.residence_addresses_count
61
+ end
62
+
63
+ test "should NOT destroy addressings with study_subject" do
64
+ assert_difference('StudySubject.count',1) {
65
+ assert_difference('Addressing.count',1) {
66
+ @study_subject = Factory(:addressing).study_subject
67
+ } }
68
+ assert_difference('StudySubject.count',-1) {
69
+ assert_difference('Addressing.count',0) {
70
+ @study_subject.destroy
71
+ } }
72
+ end
73
+
74
+ test "should NOT destroy addresses with study_subject" do
75
+ assert_difference('StudySubject.count',1) {
76
+ assert_difference('Address.count',1) {
77
+ @study_subject = Factory(:addressing).study_subject
78
+ } }
79
+ assert_difference('StudySubject.count',-1) {
80
+ assert_difference('Address.count',0) {
81
+ @study_subject.destroy
82
+ } }
83
+ end
84
+
85
+ protected
86
+
87
+ def create_object
88
+ study_subject = Factory.build(:study_subject)
89
+ study_subject.save
90
+ study_subject
91
+ end
92
+
93
+ end
@@ -0,0 +1,407 @@
1
+ require 'test_helper'
2
+
3
+ # This is just a collection of duplicate related tests
4
+ # for StudySubject separated only for clarity due
5
+ # to the size of the StudySubjectTest class.
6
+ class Ccls::StudySubjectDuplicatesTest < ActiveSupport::TestCase
7
+
8
+ test "should respond to duplicates" do
9
+ @duplicates = StudySubject.duplicates
10
+ assert_no_duplicates_found
11
+ end
12
+
13
+ test "create_case_study_subject_for_duplicate_search test" do
14
+ subject = create_case_study_subject_for_duplicate_search
15
+ assert_equal subject.sex, 'M'
16
+ assert_equal subject.subject_type, SubjectType['Case']
17
+ assert_not_nil subject.dob
18
+ assert_not_nil subject.patient
19
+ assert_not_nil subject.admit_date
20
+ assert_equal 'matchthis', subject.hospital_no
21
+ assert_nil subject.mother_maiden_name
22
+ end
23
+
24
+ test "should return no subjects as duplicates with no params" do
25
+ create_case_study_subject_for_duplicate_search
26
+ @duplicates = StudySubject.duplicates
27
+ assert_no_duplicates_found
28
+ end
29
+
30
+ test "should return no subjects as duplicates with minimal params" do
31
+ create_case_study_subject_for_duplicate_search
32
+ @duplicates = Factory.build(:study_subject).duplicates
33
+ assert_no_duplicates_found
34
+ end
35
+
36
+ # All subjects: Have the same birth date (piis.dob) and sex (subject.sex) as the new subject and
37
+ # (same mother’s maiden name or existing mother’s maiden name is null)
38
+
39
+ test "should return subject as duplicate if has matching " <<
40
+ "dob and sex and blank mother_maiden_names" do
41
+ study_subject = create_case_study_subject_for_duplicate_search
42
+ new_study_subject = new_case_study_subject_for_duplicate_search(
43
+ :sex => 'M',
44
+ :dob => study_subject.dob )
45
+ @duplicates = new_study_subject.duplicates
46
+ assert_duplicates_found
47
+ end
48
+
49
+ test "should return subject as duplicate if has matching " <<
50
+ "dob and sex and mother_maiden_name" do
51
+ study_subject = create_case_study_subject_for_duplicate_search(
52
+ :mother_maiden_name => 'Smith' )
53
+ new_study_subject = new_case_study_subject_for_duplicate_search(
54
+ :sex => 'M', :dob => study_subject.dob, :mother_maiden_name => 'Smith' )
55
+ @duplicates = new_study_subject.duplicates
56
+ assert_duplicates_found
57
+ end
58
+
59
+ test "should return subject as duplicate if has matching " <<
60
+ "dob and sex and existing mother_maiden_name is nil" do
61
+ study_subject = create_case_study_subject_for_duplicate_search
62
+ new_study_subject = new_case_study_subject_for_duplicate_search(
63
+ :sex => 'M', :dob => study_subject.dob, :mother_maiden_name => 'Smith' )
64
+ @duplicates = new_study_subject.duplicates
65
+ assert_duplicates_found
66
+ end
67
+
68
+ test "should return subject as duplicate if has matching " <<
69
+ "dob and sex and existing mother_maiden_name is blank" do
70
+ study_subject = create_case_study_subject_for_duplicate_search(
71
+ :mother_maiden_name => '' )
72
+ new_study_subject = new_case_study_subject_for_duplicate_search(
73
+ :sex => 'M', :dob => study_subject.dob, :mother_maiden_name => 'Smith' )
74
+ @duplicates = new_study_subject.duplicates
75
+ assert_duplicates_found
76
+ end
77
+
78
+ test "should NOT return subject as duplicate if has matching " <<
79
+ "dob and sex and explicitly excluded" do
80
+ study_subject = create_case_study_subject_for_duplicate_search
81
+ new_study_subject = new_case_study_subject_for_duplicate_search(
82
+ :sex => 'M', :dob => study_subject.dob )
83
+ @duplicates = new_study_subject.duplicates(:exclude_id => study_subject.id)
84
+ assert_no_duplicates_found
85
+ end
86
+
87
+ test "should NOT return subject as duplicate if has matching " <<
88
+ "dob and sex and differing mother_maiden_name" do
89
+ study_subject = create_case_study_subject_for_duplicate_search(
90
+ :mother_maiden_name => 'Smith' )
91
+ new_study_subject = new_case_study_subject_for_duplicate_search(
92
+ :sex => 'M', :dob => study_subject.dob, :mother_maiden_name => 'Jones' )
93
+ @duplicates = new_study_subject.duplicates
94
+ assert_no_duplicates_found
95
+ end
96
+
97
+ test "should NOT return subject as duplicate if just has matching dob" do
98
+ study_subject = create_case_study_subject_for_duplicate_search
99
+ new_study_subject = new_case_study_subject_for_duplicate_search(
100
+ :dob => study_subject.dob )
101
+ @duplicates = new_study_subject.duplicates
102
+ assert_no_duplicates_found
103
+ end
104
+
105
+ test "should NOT return subject as duplicate if has matching dob and blank sex" do
106
+ study_subject = create_case_study_subject_for_duplicate_search
107
+ new_study_subject = new_case_study_subject_for_duplicate_search(
108
+ :sex => ' ', :dob => study_subject.dob )
109
+ @duplicates = new_study_subject.duplicates
110
+ assert_no_duplicates_found
111
+ end
112
+
113
+ test "should NOT return subject as duplicate if just has matching sex" do
114
+ study_subject = create_case_study_subject_for_duplicate_search
115
+ new_study_subject = new_case_study_subject_for_duplicate_search(
116
+ :sex => study_subject.sex )
117
+ @duplicates = new_study_subject.duplicates
118
+ assert_no_duplicates_found
119
+ end
120
+
121
+ test "should NOT return subject as duplicate if just matching sex and blank dob" do
122
+ study_subject = create_case_study_subject_for_duplicate_search
123
+ new_study_subject = new_case_study_subject_for_duplicate_search(
124
+ :sex => study_subject.sex, :dob => ' ' )
125
+ @duplicates = new_study_subject.duplicates
126
+ assert_no_duplicates_found
127
+ end
128
+
129
+ # Case subjects: Have the same hospital_no (patient.hospital_no) as the new subject
130
+ # Only cases have a patient record, so not explicit check for Case is done.
131
+
132
+ test "should return subject as duplicate if has matching hospital_no" do
133
+ study_subject = create_case_study_subject_for_duplicate_search
134
+ new_study_subject = new_case_study_subject_for_duplicate_search(
135
+ :patient_attributes => { :hospital_no => study_subject.hospital_no })
136
+ @duplicates = new_study_subject.duplicates
137
+ assert_duplicates_found
138
+ end
139
+
140
+ test "should NOT return subject as duplicate if has matching " <<
141
+ "hospital_no and explicitly excluded" do
142
+ study_subject = create_case_study_subject_for_duplicate_search
143
+ new_study_subject = new_case_study_subject_for_duplicate_search(
144
+ :patient_attributes => { :hospital_no => study_subject.hospital_no })
145
+ @duplicates = new_study_subject.duplicates(:exclude_id => study_subject.id)
146
+ assert_no_duplicates_found
147
+ end
148
+
149
+ # Case subjects: Are admitted the same admit date (patients.admit_date) at the same institution (patients.organization_id)
150
+ # Only cases have a patient record, so not explicit check for Case is done.
151
+
152
+ test "should return subject as duplicate if has matching " <<
153
+ "admit_date and organization" do
154
+ study_subject = create_case_study_subject_for_duplicate_search
155
+ new_study_subject = new_case_study_subject_for_duplicate_search(
156
+ :patient_attributes => {
157
+ :admit_date => study_subject.admit_date,
158
+ :organization_id => study_subject.organization_id })
159
+ @duplicates = new_study_subject.duplicates
160
+ assert_duplicates_found
161
+ end
162
+
163
+ test "should NOT return subject as duplicate if has matching " <<
164
+ "admit_date and organization and explicitly excluded" do
165
+ study_subject = create_case_study_subject_for_duplicate_search
166
+ new_study_subject = new_case_study_subject_for_duplicate_search(
167
+ :patient_attributes => {
168
+ :admit_date => study_subject.admit_date,
169
+ :organization_id => study_subject.organization_id })
170
+ @duplicates = new_study_subject.duplicates(:exclude_id => study_subject.id)
171
+ assert_no_duplicates_found
172
+ end
173
+
174
+ test "should NOT return subject as duplicate if just has matching admit_date" do
175
+ study_subject = create_case_study_subject_for_duplicate_search
176
+ new_study_subject = new_case_study_subject_for_duplicate_search(
177
+ :patient_attributes => {
178
+ :admit_date => study_subject.admit_date,
179
+ :organization_id => '0' })
180
+ @duplicates = new_study_subject.duplicates
181
+ assert_no_duplicates_found
182
+ end
183
+
184
+ test "should NOT return subject as duplicate if has matching " <<
185
+ "admit_date and blank organization_id" do
186
+ study_subject = create_case_study_subject_for_duplicate_search
187
+ new_study_subject = new_case_study_subject_for_duplicate_search(
188
+ :patient_attributes => {
189
+ :admit_date => study_subject.admit_date,
190
+ :organization_id => ' ' })
191
+ @duplicates = new_study_subject.duplicates
192
+ assert_no_duplicates_found
193
+ end
194
+
195
+ test "should NOT return subject as duplicate if just has matching organization" do
196
+ study_subject = create_case_study_subject_for_duplicate_search
197
+ new_study_subject = new_case_study_subject_for_duplicate_search(
198
+ :patient_attributes => {
199
+ :organization_id => study_subject.organization_id })
200
+ @duplicates = new_study_subject.duplicates
201
+ assert_no_duplicates_found
202
+ end
203
+
204
+ test "should NOT return subject as duplicate if has matching " <<
205
+ "organization and blank admit_date" do
206
+ study_subject = create_case_study_subject_for_duplicate_search
207
+ new_study_subject = new_case_study_subject_for_duplicate_search(
208
+ :patient_attributes => {
209
+ :admit_date => ' ',
210
+ :organization_id => study_subject.organization_id })
211
+ @duplicates = new_study_subject.duplicates
212
+ assert_no_duplicates_found
213
+ end
214
+
215
+ test "should create operational event for raf duplicate" do
216
+ study_subject = create_case_study_subject_for_duplicate_search
217
+ new_study_subject = new_case_study_subject_for_duplicate_search(
218
+ :patient_attributes => { :hospital_no => study_subject.hospital_no })
219
+ @duplicates = new_study_subject.duplicates
220
+ assert_duplicates_found
221
+ assert_difference('OperationalEvent.count',1) {
222
+ study_subject.raf_duplicate_creation_attempted(new_study_subject)
223
+ }
224
+ end
225
+
226
+ # class level duplicates search tests (used in candidate_control)
227
+
228
+ test "class should return subject as duplicate if has matching " <<
229
+ "admit_date and organization_id" do
230
+ study_subject = create_case_study_subject_for_duplicate_search
231
+ @duplicates = StudySubject.duplicates(
232
+ :admit_date => study_subject.admit_date,
233
+ :organization_id => study_subject.organization_id)
234
+ assert_duplicates_found
235
+ end
236
+
237
+ test "class should NOT return subject as duplicate if has matching " <<
238
+ "admit_date and organization_id if excluded" do
239
+ study_subject = create_case_study_subject_for_duplicate_search
240
+ @duplicates = StudySubject.duplicates(
241
+ :exclude_id => study_subject.id,
242
+ :admit_date => study_subject.admit_date,
243
+ :organization_id => study_subject.organization_id)
244
+ assert_no_duplicates_found
245
+ end
246
+
247
+ test "class should return subject as duplicate if has matching hospital_no" do
248
+ study_subject = create_case_study_subject_for_duplicate_search
249
+ @duplicates = StudySubject.duplicates(
250
+ :hospital_no => study_subject.hospital_no )
251
+ assert_duplicates_found
252
+ end
253
+
254
+ test "class should NOT return subject as duplicate if has matching " <<
255
+ "hospital_no if excluded" do
256
+ study_subject = create_case_study_subject_for_duplicate_search
257
+ @duplicates = StudySubject.duplicates(
258
+ :exclude_id => study_subject.id,
259
+ :hospital_no => study_subject.hospital_no )
260
+ assert_no_duplicates_found
261
+ end
262
+
263
+ test "class should return subject as duplicate if has matching " <<
264
+ "sex, dob and mother_maiden_name" do
265
+ study_subject = create_case_study_subject_for_duplicate_search
266
+ @duplicates = StudySubject.duplicates(
267
+ :sex => 'M',
268
+ :dob => study_subject.dob,
269
+ :mother_maiden_name => study_subject.mother_maiden_name )
270
+ assert_duplicates_found
271
+ end
272
+
273
+ test "class should NOT return subject as duplicate if has matching " <<
274
+ "sex, dob and mother_maiden_name if excluded" do
275
+ study_subject = create_case_study_subject_for_duplicate_search
276
+ @duplicates = StudySubject.duplicates(
277
+ :exclude_id => study_subject.id,
278
+ :sex => 'M',
279
+ :dob => study_subject.dob,
280
+ :mother_maiden_name => study_subject.mother_maiden_name )
281
+ assert_no_duplicates_found
282
+ end
283
+
284
+ test "class should return subject as duplicate when all of these params " <<
285
+ "are passed and all match" do
286
+ study_subject = create_case_study_subject_for_duplicate_search
287
+ @duplicates = StudySubject.duplicates(
288
+ :mother_maiden_name => study_subject.mother_maiden_name,
289
+ :hospital_no => study_subject.hospital_no,
290
+ :sex => 'M',
291
+ :dob => study_subject.dob,
292
+ :admit_date => study_subject.admit_date,
293
+ :organization_id => study_subject.organization_id)
294
+ assert_duplicates_found
295
+ end
296
+
297
+ test "class should NOT return subject as duplicate when all of these params " <<
298
+ "are passed and all match if excluded" do
299
+ study_subject = create_case_study_subject_for_duplicate_search
300
+ @duplicates = StudySubject.duplicates(
301
+ :exclude_id => study_subject.id,
302
+ :mother_maiden_name => study_subject.mother_maiden_name,
303
+ :hospital_no => study_subject.hospital_no,
304
+ :sex => 'M',
305
+ :dob => study_subject.dob,
306
+ :admit_date => study_subject.admit_date,
307
+ :organization_id => study_subject.organization_id)
308
+ assert_no_duplicates_found
309
+ end
310
+
311
+ test "class should NOT return subject as duplicate when all of these params " <<
312
+ "are passed and none match" do
313
+ study_subject = create_case_study_subject_for_duplicate_search
314
+ @duplicates = StudySubject.duplicates(
315
+ :mother_maiden_name => 'somethingdifferent',
316
+ :hospital_no => 'somethingdifferent',
317
+ :sex => 'F',
318
+ :dob => Date.today,
319
+ :admit_date => Date.today,
320
+ :organization_id => 0 )
321
+ assert_no_duplicates_found
322
+ end
323
+
324
+ test "class should NOT return subject as duplicate when all of these params " <<
325
+ "are passed only sex matches" do
326
+ study_subject = create_case_study_subject_for_duplicate_search
327
+ @duplicates = StudySubject.duplicates(
328
+ :mother_maiden_name => 'somethingdifferent',
329
+ :hospital_no => 'somethingdifferent',
330
+ :sex => 'M',
331
+ :dob => Date.today,
332
+ :admit_date => Date.today,
333
+ :organization_id => 0 )
334
+ assert_no_duplicates_found
335
+ end
336
+
337
+ test "class should NOT return subject as duplicate when all of these params " <<
338
+ "are passed only dob matches" do
339
+ study_subject = create_case_study_subject_for_duplicate_search
340
+ @duplicates = StudySubject.duplicates(
341
+ :mother_maiden_name => 'somethingdifferent',
342
+ :hospital_no => 'somethingdifferent',
343
+ :sex => 'F',
344
+ :dob => study_subject.dob,
345
+ :admit_date => Date.today,
346
+ :organization_id => 0 )
347
+ assert_no_duplicates_found
348
+ end
349
+
350
+ test "class should NOT return subject as duplicate when all of these params " <<
351
+ "are passed only admit_date matches" do
352
+ study_subject = create_case_study_subject_for_duplicate_search
353
+ @duplicates = StudySubject.duplicates(
354
+ :mother_maiden_name => 'somethingdifferent',
355
+ :hospital_no => 'somethingdifferent',
356
+ :sex => 'F',
357
+ :dob => Date.today,
358
+ :admit_date => study_subject.admit_date,
359
+ :organization_id => 0 )
360
+ assert_no_duplicates_found
361
+ end
362
+
363
+ test "class should NOT return subject as duplicate when all of these params " <<
364
+ "are passed only organization matches" do
365
+ study_subject = create_case_study_subject_for_duplicate_search
366
+ @duplicates = StudySubject.duplicates(
367
+ :mother_maiden_name => 'somethingdifferent',
368
+ :hospital_no => 'somethingdifferent',
369
+ :sex => 'F',
370
+ :dob => Date.today,
371
+ :admit_date => Date.today,
372
+ :organization_id => study_subject.organization_id )
373
+ assert_no_duplicates_found
374
+ end
375
+
376
+ protected
377
+
378
+ def assert_no_duplicates_found
379
+ assert_not_nil @duplicates
380
+ assert @duplicates.is_a?(Array)
381
+ assert @duplicates.empty?
382
+ end
383
+
384
+ def assert_duplicates_found
385
+ assert_not_nil @duplicates
386
+ assert @duplicates.is_a?(Array)
387
+ assert !@duplicates.empty?
388
+ end
389
+
390
+ def create_case_study_subject_for_duplicate_search(options={})
391
+ Factory(:case_study_subject, { :sex => 'M',
392
+ :dob => Date.yesterday,
393
+ :patient_attributes => Factory.attributes_for(:patient,
394
+ :hospital_no => 'matchthis',
395
+ :admit_date => Date.yesterday ) }.deep_merge(options) )
396
+ end
397
+
398
+ def new_case_study_subject_for_duplicate_search(options={})
399
+ Factory.build(:case_study_subject, { :sex => 'F',
400
+ :dob => Date.today,
401
+ :patient_attributes => Factory.attributes_for(:patient,
402
+ :hospital_no => 'somethingdifferent',
403
+ # :organization_id => 0, # Why 0? was for just matching admit_date
404
+ :admit_date => Date.today ) }.deep_merge(options) )
405
+ end
406
+
407
+ end