def generate_samples(fraction_missing): """Creates fake sample CSV data in GCS. Args: fraction_missing: This many samples which exist as BiobankStoredSamples will not have rows generated in the fake CSV. """ bucket_name = config.getSetting(config.BIOBANK_SAMPLES_BUCKET_NAME) now = clock.CLOCK.now() file_name = '/%s/fake_%s.csv' % (bucket_name, now.strftime(INPUT_CSV_TIME_FORMAT)) num_rows = 0 sample_id_start = random.randint(1000000, 10000000) with cloudstorage_api.open(file_name, mode='w') as dest: writer = csv.writer(dest, delimiter="\t") writer.writerow(_HEADERS) biobank_order_dao = BiobankOrderDao() with biobank_order_dao.session() as session: rows = biobank_order_dao.get_ordered_samples_sample( session, 1 - fraction_missing, _BATCH_SIZE) for biobank_id, collected_time, test in rows: if collected_time is None: logging.warning( 'biobank_id=%s test=%s skipped (collected=%s)', biobank_id, test, collected_time) continue minutes_delta = random.randint( 0, _MAX_MINUTES_BETWEEN_SAMPLE_COLLECTED_AND_CONFIRMED) confirmed_time = collected_time + datetime.timedelta( minutes=minutes_delta) writer.writerow([ sample_id_start + num_rows, None, # no parent confirmed_time.strftime(_TIME_FORMAT), to_client_biobank_id(biobank_id), test, confirmed_time.strftime(_TIME_FORMAT), 'KIT' ]) # reuse confirmed time as created time num_rows += 1 participant_dao = ParticipantDao() with participant_dao.session() as session: rows = participant_dao.get_biobank_ids_sample( session, _PARTICIPANTS_WITH_ORPHAN_SAMPLES, _BATCH_SIZE) for biobank_id, sign_up_time in rows: minutes_delta = random.randint( 0, _MAX_MINUTES_BETWEEN_PARTICIPANT_CREATED_AND_CONFIRMED) confirmed_time = sign_up_time + datetime.timedelta( minutes=minutes_delta) tests = random.sample(BIOBANK_TESTS, random.randint(1, len(BIOBANK_TESTS))) for test in tests: writer.writerow([ sample_id_start + num_rows, None, confirmed_time.strftime(_TIME_FORMAT), to_client_biobank_id(biobank_id), test, confirmed_time.strftime(_TIME_FORMAT), 'KIT' ]) num_rows += 1 logging.info("Generated %d samples in %s.", num_rows, file_name)
class BigQuerySyncDaoTest(SqlTestBase): TIME_1 = datetime.datetime(2018, 9, 20, 5, 49, 11) TIME_2 = datetime.datetime(2018, 9, 24, 14, 21, 01) site = None hpo = None participant = None summary = None pm_json = None pm = None bio_order = None def setUp(self): super(BigQuerySyncDaoTest, self).setUp(use_mysql=True, with_consent_codes=True) self.dao = ParticipantDao() with self.dao.session() as session: self.site = session.query(Site).filter( Site.googleGroup == 'hpo-site-monroeville').first() self.hpo = session.query(HPO).filter(HPO.name == 'PITT').first() with clock.FakeClock(self.TIME_1): self.participant = Participant(participantId=123, biobankId=555) self.participant.hpoId = self.hpo.hpoId self.participant.siteId = self.site.siteId self.dao.insert(self.participant) ps = ParticipantSummary( participantId=123, biobankId=555, firstName='john', lastName='doe', withdrawalStatus=WithdrawalStatus.NOT_WITHDRAWN, suspensionStatus=SuspensionStatus.NOT_SUSPENDED) ps.hpoId = self.hpo.hpoId ps.siteId = self.site.siteId self.summary = ParticipantSummaryDao().insert(ps) self.pm_json = json.dumps( load_measurement_json(self.participant.participantId, self.TIME_1.isoformat())) self.pm = PhysicalMeasurementsDao().insert( self._make_physical_measurements()) with clock.FakeClock(self.TIME_2): self.dao = BiobankOrderDao() self.bio_order = BiobankOrderDao().insert( self._make_biobank_order( participantId=self.participant.participantId)) def _make_physical_measurements(self, **kwargs): """Makes a new PhysicalMeasurements (same values every time) with valid/complete defaults. Kwargs pass through to PM constructor, overriding defaults. """ for k, default_value in (('physicalMeasurementsId', 1), ('participantId', self.participant.participantId), ('resource', self.pm_json), ('createdSiteId', self.site.siteId), ('finalizedSiteId', self.site.siteId)): if k not in kwargs: kwargs[k] = default_value return PhysicalMeasurements(**kwargs) def _make_biobank_order(self, **kwargs): """Makes a new BiobankOrder (same values every time) with valid/complete defaults. Kwargs pass through to BiobankOrder constructor, overriding defaults. """ for k, default_value in (('biobankOrderId', '1'), ('created', clock.CLOCK.now()), ('participantId', self.participant.participantId), ('sourceSiteId', 1), ('sourceUsername', '*****@*****.**'), ('collectedSiteId', 1), ('collectedUsername', '*****@*****.**'), ('processedSiteId', 1), ('processedUsername', '*****@*****.**'), ('finalizedSiteId', 2), ('finalizedUsername', '*****@*****.**'), ('identifiers', [ BiobankOrderIdentifier(system='a', value='c') ]), ('samples', [ BiobankOrderedSample( biobankOrderId='1', test=BIOBANK_TESTS[0], description=u'description', finalized=self.TIME_1, processingRequired=True) ])): if k not in kwargs: kwargs[k] = default_value return BiobankOrder(**kwargs) def test_participant_summary_gen(self): gen = BQParticipantSummaryGenerator() ps_json = gen.make_bqrecord(self.participant.participantId) self.assertIsNotNone(ps_json) self.assertEqual(ps_json.sign_up_time, self.TIME_1) self.assertEqual(ps_json['pm'][0]['pm_finalized_site'], 'hpo-site-monroeville') self.assertEqual(ps_json.suspension_status, 'NOT_SUSPENDED') self.assertEqual(ps_json.withdrawal_status, 'NOT_WITHDRAWN') self.assertEqual(ps_json['pm'][0]['pm_status'], 'COMPLETED')
class ParticipantSummaryDaoTest(NdbTestBase): def setUp(self): super(ParticipantSummaryDaoTest, self).setUp(use_mysql=True) self.dao = ParticipantSummaryDao() self.order_dao = BiobankOrderDao() self.measurement_dao = PhysicalMeasurementsDao() self.participant_dao = ParticipantDao() self.no_filter_query = Query([], None, 2, None) self.one_filter_query = Query([FieldFilter("participantId", Operator.EQUALS, 1)], None, 2, None) self.two_filter_query = Query([FieldFilter("participantId", Operator.EQUALS, 1), FieldFilter("hpoId", Operator.EQUALS, PITT_HPO_ID)], None, 2, None) self.ascending_biobank_id_query = Query([], OrderBy("biobankId", True), 2, None) self.descending_biobank_id_query = Query([], OrderBy("biobankId", False), 2, None) self.enrollment_status_order_query = Query([], OrderBy("enrollmentStatus", True), 2, None) self.hpo_id_order_query = Query([], OrderBy("hpoId", True), 2, None) self.first_name_order_query = Query([], OrderBy("firstName", True), 2, None) def assert_no_results(self, query): results = self.dao.query(query) self.assertEquals([], results.items) self.assertIsNone(results.pagination_token) def assert_results(self, query, items, pagination_token=None): results = self.dao.query(query) self.assertListAsDictEquals(items, results.items) self.assertEquals(pagination_token, results.pagination_token, "Pagination tokens don't match; decoded = %s, %s" % (_decode_token(pagination_token), _decode_token(results.pagination_token))) def test_query_with_total(self): num_participants = 5 query = Query([], None, 10, None, include_total=True) results = self.dao.query(query) self.assertEqual(results.total, 0) for i in range(num_participants): participant = Participant(participantId=i, biobankId=i) self._insert(participant) results = self.dao.query(query) self.assertEqual(results.total, num_participants) def testQuery_noSummaries(self): self.assert_no_results(self.no_filter_query) self.assert_no_results(self.one_filter_query) self.assert_no_results(self.two_filter_query) self.assert_no_results(self.ascending_biobank_id_query) self.assert_no_results(self.descending_biobank_id_query) def _insert(self, participant, first_name=None, last_name=None): self.participant_dao.insert(participant) summary = self.participant_summary(participant) if first_name: summary.firstName = first_name if last_name: summary.lastName = last_name self.dao.insert(summary) return participant def testQuery_oneSummary(self): participant = Participant(participantId=1, biobankId=2) self._insert(participant) summary = self.dao.get(1) self.assert_results(self.no_filter_query, [summary]) self.assert_results(self.one_filter_query, [summary]) self.assert_no_results(self.two_filter_query) self.assert_results(self.ascending_biobank_id_query, [summary]) self.assert_results(self.descending_biobank_id_query, [summary]) def testUnicodeNameRoundTrip(self): name = self.fake.first_name() with self.assertRaises(UnicodeEncodeError): str(name) # sanity check that the name contains non-ASCII participant = self._insert(Participant(participantId=1, biobankId=2)) summary = self.dao.get(participant.participantId) summary.firstName = name self.dao.update(summary) fetched_summary = self.dao.get(participant.participantId) self.assertEquals(name, fetched_summary.firstName) def testQuery_twoSummaries(self): participant_1 = Participant(participantId=1, biobankId=2) self._insert(participant_1, 'Alice', 'Smith') participant_2 = Participant(participantId=2, biobankId=1) self._insert(participant_2, 'Zed', 'Zebra') ps_1 = self.dao.get(1) ps_2 = self.dao.get(2) self.assert_results(self.no_filter_query, [ps_1, ps_2]) self.assert_results(self.one_filter_query, [ps_1]) self.assert_no_results(self.two_filter_query) self.assert_results(self.ascending_biobank_id_query, [ps_2, ps_1]) self.assert_results(self.descending_biobank_id_query, [ps_1, ps_2]) def testQuery_threeSummaries_paginate(self): participant_1 = Participant(participantId=1, biobankId=4) self._insert(participant_1, 'Alice', 'Aardvark') participant_2 = Participant(participantId=2, biobankId=1) self._insert(participant_2, 'Bob', 'Builder') participant_3 = Participant(participantId=3, biobankId=3) self._insert(participant_3, 'Chad', 'Caterpillar') ps_1 = self.dao.get(1) ps_2 = self.dao.get(2) ps_3 = self.dao.get(3) self.assert_results(self.no_filter_query, [ps_1, ps_2], _make_pagination_token(['Builder', 'Bob', None, 2])) self.assert_results(self.one_filter_query, [ps_1]) self.assert_no_results(self.two_filter_query) self.assert_results(self.ascending_biobank_id_query, [ps_2, ps_3], _make_pagination_token([3, 'Caterpillar', 'Chad', None, 3])) self.assert_results(self.descending_biobank_id_query, [ps_1, ps_3], _make_pagination_token([3, 'Caterpillar', 'Chad', None, 3])) self.assert_results(_with_token(self.no_filter_query, _make_pagination_token(['Builder', 'Bob', None, 2])), [ps_3]) self.assert_results(_with_token(self.ascending_biobank_id_query, _make_pagination_token([3, 'Caterpillar', 'Chad', None, 3])), [ps_1]) self.assert_results(_with_token(self.descending_biobank_id_query, _make_pagination_token([3, 'Caterpillar', 'Chad', None, 3])), [ps_2]) def testQuery_fourFullSummaries_paginate(self): participant_1 = Participant(participantId=1, biobankId=4) self._insert(participant_1, 'Bob', 'Jones') participant_2 = Participant(participantId=2, biobankId=1) self._insert(participant_2, 'Bob', 'Jones') participant_3 = Participant(participantId=3, biobankId=3) self._insert(participant_3, 'Bob', 'Jones') participant_4 = Participant(participantId=4, biobankId=2) self._insert(participant_4, 'Bob', 'Jones') ps_1 = self.dao.get(1) ps_2 = self.dao.get(2) ps_3 = self.dao.get(3) ps_4 = self.dao.get(4) ps_1.lastName = 'Jones' ps_1.firstName = 'Bob' ps_1.dateOfBirth = datetime.date(1978, 10, 9) ps_1.hpoId = PITT_HPO_ID self.dao.update(ps_1) ps_2.lastName = 'Aardvark' ps_2.firstName = 'Bob' ps_2.dateOfBirth = datetime.date(1978, 10, 10) ps_2.enrollmentStatus = EnrollmentStatus.MEMBER self.dao.update(ps_2) ps_3.lastName = 'Jones' ps_3.firstName = 'Bob' ps_3.dateOfBirth = datetime.date(1978, 10, 10) ps_3.hpoId = PITT_HPO_ID ps_3.enrollmentStatus = EnrollmentStatus.MEMBER self.dao.update(ps_3) ps_4.lastName = 'Jones' ps_4.enrollmentStatus = EnrollmentStatus.FULL_PARTICIPANT self.dao.update(ps_4) self.assert_results(self.no_filter_query, [ps_2, ps_4], _make_pagination_token(['Jones', 'Bob', None, 4])) self.assert_results(self.one_filter_query, [ps_1]) self.assert_results(self.two_filter_query, [ps_1]) self.assert_results(self.ascending_biobank_id_query, [ps_2, ps_4], _make_pagination_token([2, 'Jones', 'Bob', None, 4])) self.assert_results(self.descending_biobank_id_query, [ps_1, ps_3], _make_pagination_token([3, 'Jones', 'Bob', datetime.date(1978, 10, 10), 3])) self.assert_results(self.hpo_id_order_query, [ps_2, ps_4], _make_pagination_token([0, 'Jones', 'Bob', None, 4])) self.assert_results(self.enrollment_status_order_query, [ps_1, ps_2], _make_pagination_token(['MEMBER', 'Aardvark', 'Bob', datetime.date(1978, 10, 10), 2])) self.assert_results(_with_token(self.no_filter_query, _make_pagination_token(['Jones', 'Bob', None, 4])), [ps_1, ps_3]) self.assert_results(_with_token(self.ascending_biobank_id_query, _make_pagination_token([2, 'Jones', 'Bob', None, 4])), [ps_3, ps_1]) self.assert_results(_with_token(self.descending_biobank_id_query, _make_pagination_token([3, 'Jones', 'Bob', datetime.date(1978, 10, 10), 3])), [ps_4, ps_2]) self.assert_results(_with_token(self.hpo_id_order_query, _make_pagination_token([0, 'Jones', 'Bob', None, 4])), [ps_1, ps_3]) self.assert_results(_with_token(self.enrollment_status_order_query, _make_pagination_token(['MEMBER', 'Aardvark', 'Bob', datetime.date(1978, 10, 10), 2])), [ps_3, ps_4]) def test_update_from_samples(self): # baseline_tests = ['BASELINE1', 'BASELINE2'] baseline_tests = ["1PST8", "2PST8"] config.override_setting(config.BASELINE_SAMPLE_TEST_CODES, baseline_tests) self.dao.update_from_biobank_stored_samples() # safe noop p_baseline_samples = self._insert(Participant(participantId=1, biobankId=11)) p_mixed_samples = self._insert(Participant(participantId=2, biobankId=22)) p_no_samples = self._insert(Participant(participantId=3, biobankId=33)) p_unconfirmed = self._insert(Participant(participantId=4, biobankId=44)) self.assertEquals(self.dao.get(p_baseline_samples.participantId).numBaselineSamplesArrived, 0) def get_p_baseline_last_modified(): return self.dao.get(p_baseline_samples.participantId).lastModified p_baseline_last_modified1 = get_p_baseline_last_modified() sample_dao = BiobankStoredSampleDao() def add_sample(participant, test_code, sample_id): TIME = datetime.datetime(2018, 3, 2) sample_dao.insert(BiobankStoredSample( biobankStoredSampleId=sample_id, biobankId=participant.biobankId, biobankOrderIdentifier='KIT', test=test_code, confirmed=TIME)) add_sample(p_baseline_samples, baseline_tests[0], '11111') add_sample(p_baseline_samples, baseline_tests[1], '22223') add_sample(p_mixed_samples, baseline_tests[0], '11112') add_sample(p_mixed_samples, 'NOT1', '44441') # add unconfirmed sample sample_dao.insert(BiobankStoredSample(biobankStoredSampleId=55555, biobankId=p_unconfirmed.biobankId, biobankOrderIdentifier='KIT', test=baseline_tests[1], confirmed=None)) # sleep 1 sec to make lastModified different time.sleep(1) self.dao.update_from_biobank_stored_samples() p_baseline_last_modified2 = get_p_baseline_last_modified() self.assertNotEquals(p_baseline_last_modified2, p_baseline_last_modified1) self.assertEquals(self.dao.get(p_baseline_samples.participantId).numBaselineSamplesArrived, 2) self.assertEquals(self.dao.get(p_mixed_samples.participantId).numBaselineSamplesArrived, 1) self.assertEquals(self.dao.get(p_no_samples.participantId).numBaselineSamplesArrived, 0) self.assertEquals(self.dao.get(p_unconfirmed.participantId).numBaselineSamplesArrived, 0) M_baseline_samples = self._insert(Participant(participantId=9, biobankId=99)) add_sample(M_baseline_samples, baseline_tests[0], '999') M_first_update = self.dao.get(M_baseline_samples.participantId) # sleep 1 sec to make lastModified different time.sleep(1) self.dao.update_from_biobank_stored_samples() add_sample(M_baseline_samples, baseline_tests[1], '9999') M_second_update = self.dao.get(M_baseline_samples.participantId) # sleep 1 sec to make lastModified different time.sleep(1) self.dao.update_from_biobank_stored_samples() self.assertNotEqual(M_first_update.lastModified, M_second_update.lastModified) self.assertEquals(get_p_baseline_last_modified(), p_baseline_last_modified2) def test_update_from_samples_changed_tests(self): baseline_tests = ["1PST8", "2PST8"] config.override_setting(config.BASELINE_SAMPLE_TEST_CODES, baseline_tests) self.dao.update_from_biobank_stored_samples() # safe noop participant = self._insert(Participant(participantId=1, biobankId=11)) self.assertEquals(self.dao.get(participant.participantId).numBaselineSamplesArrived, 0) sample_dao = BiobankStoredSampleDao() def add_sample(test_code, sample_id): TIME = datetime.datetime(2018, 3, 2) sample_dao.insert(BiobankStoredSample( biobankStoredSampleId=sample_id, biobankId=participant.biobankId, biobankOrderIdentifier='KIT', test=test_code, confirmed=TIME)) add_sample(baseline_tests[0], '11111') add_sample(baseline_tests[1], '22223') self.dao.update_from_biobank_stored_samples() summary = self.dao.get(participant.participantId) init_last_modified = summary.lastModified self.assertEquals(summary.numBaselineSamplesArrived, 2) # sleep 1 sec to make lastModified different time.sleep(1) # Simulate removal of one of the baseline tests from config.json. baseline_tests.pop() config.override_setting(config.BASELINE_SAMPLE_TEST_CODES, baseline_tests) self.dao.update_from_biobank_stored_samples() summary = self.dao.get(participant.participantId) self.assertEquals(summary.numBaselineSamplesArrived, 1) self.assertNotEqual(init_last_modified, summary.lastModified) def test_only_update_dna_sample(self): dna_tests = ["1ED10", "1SAL2"] config.override_setting(config.DNA_SAMPLE_TEST_CODES, dna_tests) self.dao.update_from_biobank_stored_samples() # safe noop p_dna_samples = self._insert(Participant(participantId=1, biobankId=11)) self.assertEquals(self.dao.get(p_dna_samples.participantId).samplesToIsolateDNA, None) self.assertEquals( self.dao.get(p_dna_samples.participantId).enrollmentStatusCoreStoredSampleTime, None) self.assertEquals( self.dao.get(p_dna_samples.participantId).enrollmentStatusCoreOrderedSampleTime, None) sample_dao = BiobankStoredSampleDao() def add_sample(participant, test_code, sample_id, confirmed_time): sample_dao.insert(BiobankStoredSample( biobankStoredSampleId=sample_id, biobankId=participant.biobankId, biobankOrderIdentifier='KIT', test=test_code, confirmed=confirmed_time)) confirmed_time_0 = datetime.datetime(2018, 3, 1) add_sample(p_dna_samples, dna_tests[0], '11111', confirmed_time_0) self.dao.update_from_biobank_stored_samples() self.assertEquals(self.dao.get(p_dna_samples.participantId).samplesToIsolateDNA, SampleStatus.RECEIVED) # only update dna sample will not update enrollmentStatusCoreStoredSampleTime self.assertEquals( self.dao.get(p_dna_samples.participantId).enrollmentStatusCoreStoredSampleTime, None) self.assertEquals( self.dao.get(p_dna_samples.participantId).enrollmentStatusCoreOrderedSampleTime, None) def test_calculate_enrollment_status(self): self.assertEquals(EnrollmentStatus.FULL_PARTICIPANT, self.dao.calculate_enrollment_status(True, NUM_BASELINE_PPI_MODULES, PhysicalMeasurementsStatus.COMPLETED, SampleStatus.RECEIVED)) self.assertEquals(EnrollmentStatus.MEMBER, self.dao.calculate_enrollment_status(True, NUM_BASELINE_PPI_MODULES - 1, PhysicalMeasurementsStatus.COMPLETED, SampleStatus.RECEIVED)) self.assertEquals(EnrollmentStatus.MEMBER, self.dao.calculate_enrollment_status(True, NUM_BASELINE_PPI_MODULES, PhysicalMeasurementsStatus.UNSET, SampleStatus.RECEIVED)) self.assertEquals(EnrollmentStatus.MEMBER, self.dao.calculate_enrollment_status(True, NUM_BASELINE_PPI_MODULES, PhysicalMeasurementsStatus.COMPLETED, SampleStatus.UNSET)) self.assertEquals(EnrollmentStatus.INTERESTED, self.dao.calculate_enrollment_status(False, NUM_BASELINE_PPI_MODULES, PhysicalMeasurementsStatus.COMPLETED, SampleStatus.RECEIVED)) def testUpdateEnrollmentStatus(self): ehr_consent_time = datetime.datetime(2018, 3, 1) summary = ParticipantSummary( participantId=1, biobankId=2, consentForStudyEnrollment=QuestionnaireStatus.SUBMITTED, consentForElectronicHealthRecords=QuestionnaireStatus.SUBMITTED, consentForElectronicHealthRecordsTime=ehr_consent_time, enrollmentStatus=EnrollmentStatus.INTERESTED) self.dao.update_enrollment_status(summary) self.assertEquals(EnrollmentStatus.MEMBER, summary.enrollmentStatus) self.assertEquals(ehr_consent_time, summary.enrollmentStatusMemberTime) def testUpdateEnrollmentStatusLastModified(self): """DA-631: enrollment_status update should update last_modified.""" participant = self._insert(Participant(participantId=6, biobankId=66)) # collect current modified and enrollment status summary = self.dao.get(participant.participantId) test_dt = datetime.datetime(2018, 11, 1) def reset_summary(): # change summary so enrollment status will be changed from INTERESTED to MEMBER. summary.enrollmentStatus = EnrollmentStatus.INTERESTED summary.lastModified = test_dt summary.consentForStudyEnrollment = QuestionnaireStatus.SUBMITTED summary.consentForElectronicHealthRecords = QuestionnaireStatus.SUBMITTED summary.physicalMeasurementsStatus = PhysicalMeasurementsStatus.COMPLETED summary.samplesToIsolateDNA = SampleStatus.RECEIVED self.dao.update(summary) ## Test Step 1: Validate update_from_biobank_stored_samples() changes lastModified. reset_summary() # Update and reload summary record self.dao.update_from_biobank_stored_samples(participant_id=participant.participantId) summary = self.dao.get(participant.participantId) # Test that status has changed and lastModified is also different self.assertEquals(EnrollmentStatus.MEMBER, summary.enrollmentStatus) self.assertNotEqual(test_dt, summary.lastModified) ## Test Step 2: Validate that update_enrollment_status() changes the lastModified property. reset_summary() summary = self.dao.get(participant.participantId) self.assertEqual(test_dt, summary.lastModified) # update_enrollment_status() does not touch the db, it only modifies object properties. self.dao.update_enrollment_status(summary) self.assertEquals(EnrollmentStatus.MEMBER, summary.enrollmentStatus) self.assertNotEqual(test_dt, summary.lastModified) def testNumberDistinctVisitsCounts(self): self.participant = self._insert(Participant(participantId=7, biobankId=77)) # insert biobank order order = self.order_dao.insert(self._make_biobank_order()) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) cancel_request = cancel_biobank_order() # cancel biobank order self.order_dao.update_with_patch(order.biobankOrderId, cancel_request, order.version) summary = self.dao.get(self.participant.participantId) # distinct count should be 0 self.assertEquals(summary.numberDistinctVisits, 0) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_1.isoformat())) # insert physical measurement measurement = self.measurement_dao.insert(self._make_physical_measurements()) summary = self.dao.get(self.participant.participantId) # count should be 1 self.assertEquals(summary.numberDistinctVisits, 1) # cancel the measurement cancel_measurement = get_restore_or_cancel_info() with self.measurement_dao.session() as session: self.measurement_dao.update_with_patch(measurement.physicalMeasurementsId, session, cancel_measurement) summary = self.dao.get(self.participant.participantId) # count should be 0 self.assertEquals(summary.numberDistinctVisits, 0) with clock.FakeClock(TIME_1): self.order_dao.insert(self._make_biobank_order(biobankOrderId='2', identifiers=[ BiobankOrderIdentifier(system='b', value='d')], samples=[BiobankOrderedSample( biobankOrderId='2', test=BIOBANK_TESTS[0], description='description', processingRequired=True)])) with clock.FakeClock(TIME_2): self.measurement_dao.insert(self._make_physical_measurements( physicalMeasurementsId=2)) summary = self.dao.get(self.participant.participantId) # A PM on another day should add a new distinct count. self.assertEquals(summary.numberDistinctVisits, 2) with clock.FakeClock(TIME_3): self.order_dao.insert(self._make_biobank_order(biobankOrderId='3', identifiers=[ BiobankOrderIdentifier(system='s', value='s')], samples=[BiobankOrderedSample( biobankOrderId ='3', finalized=TIME_3, test=BIOBANK_TESTS[1], description='another description', processingRequired=False)])) # a physical measurement on same day as biobank order does not add distinct visit. self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=6)) # another biobank order on the same day should also not add a distinct visit self.order_dao.insert(self._make_biobank_order(biobankOrderId='7', identifiers=[ BiobankOrderIdentifier(system='x', value='x')], samples=[BiobankOrderedSample( biobankOrderId ='7', finalized=TIME_3, test=BIOBANK_TESTS[1], description='another description', processingRequired=False)])) summary = self.dao.get(self.participant.participantId) # 1 from each of TIME_1 TIME_2 TIME_3 self.assertEquals(summary.numberDistinctVisits, 3) def test_qa_scenarios_for_pmb_visits(self): """ PDR at https://docs.google.com/document/d/1sL54f-I91RvhjIprrdbwD8TlR9Jq91MX2ELf1EtJdxc/edit#heading=h.bqo8kt3igsrw<Paste> """ self.participant = self._insert(Participant(participantId=6, biobankId=66)) # test scenario 1 with clock.FakeClock(TIME_4): self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_4.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=666, participantId=self.participant.participantId, finalized=TIME_4)) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) with clock.FakeClock(TIME_5): self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_5.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=669, finalized=TIME_5)) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 2) # test scenario 2 with clock.FakeClock(TIME_6): self.participant = self._insert(Participant(participantId=9, biobankId=13)) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_6.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=8, finalized=TIME_6)) self.order_dao.insert(self._make_biobank_order(biobankOrderId='2', identifiers=[ BiobankOrderIdentifier(system='b', value='d')], samples=[BiobankOrderedSample( biobankOrderId='2', finalized=TIME_7, test=BIOBANK_TESTS[0], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 2 self.assertEquals(summary.numberDistinctVisits, 2) # test scenario 3 with clock.FakeClock(TIME_6): self.participant = self._insert(Participant(participantId=66, biobankId=42)) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_6.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=12, createdSiteId=2, finalized=TIME_6)) self.order_dao.insert(self._make_biobank_order(biobankOrderId='18', finalizedSiteId=1, identifiers=[ BiobankOrderIdentifier(system='x', value='y')], samples=[BiobankOrderedSample( biobankOrderId='18', finalized=TIME_6, test=BIOBANK_TESTS[0], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 1 self.assertEquals(summary.numberDistinctVisits, 1) # test scenario 4 with clock.FakeClock(TIME_8): self.participant = self._insert(Participant(participantId=6613, biobankId=142)) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_8.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=129, finalized=TIME_8)) order = self.order_dao.insert(self._make_biobank_order(biobankOrderId='999', identifiers=[ BiobankOrderIdentifier(system='s', value='s')], samples=[BiobankOrderedSample( biobankOrderId='999', finalized=TIME_8, test=BIOBANK_TESTS[1], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 1 self.assertEquals(summary.numberDistinctVisits, 1) # change finalized time, recalculating count with self.order_dao.session() as session: existing_order = copy.deepcopy(order) order.samples[0].finalized = TIME_9 self.order_dao._do_update(session, order, existing_order) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) # change test, should not change count. with self.order_dao.session() as session: existing_order = copy.deepcopy(order) order.samples[0].test = BIOBANK_TESTS[0] self.order_dao._do_update(session, order, existing_order) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) # test scenario 5 with clock.FakeClock(TIME_12): self.participant = self._insert(Participant(participantId=3000, biobankId=2019)) self.order_dao.insert(self._make_biobank_order(biobankOrderId='700', identifiers=[ BiobankOrderIdentifier(system='n', value='s')], samples=[BiobankOrderedSample( biobankOrderId='700', finalized=TIME_10, test=BIOBANK_TESTS[1], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 1 self.assertEquals(summary.numberDistinctVisits, 1) other_order = self.order_dao.insert(self._make_biobank_order(biobankOrderId='701', identifiers=[ BiobankOrderIdentifier(system='n', value='t')], samples=[BiobankOrderedSample( biobankOrderId='701', finalized=TIME_11, test=BIOBANK_TESTS[1], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 2 self.assertEquals(summary.numberDistinctVisits, 2) order = self.order_dao.insert(self._make_biobank_order(biobankOrderId='702', identifiers=[ BiobankOrderIdentifier(system='n', value='u')], samples=[BiobankOrderedSample( biobankOrderId='702', finalized=TIME_12, test=BIOBANK_TESTS[1], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) # distinct count should be 3 self.assertEquals(summary.numberDistinctVisits, 3) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_12.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=120, finalized=TIME_12)) summary = self.dao.get(self.participant.participantId) # distinct count should be 3 self.assertEquals(summary.numberDistinctVisits, 3) cancel_request = cancel_biobank_order() # cancel biobank order with PM on same day self.order_dao.update_with_patch(order.biobankOrderId, cancel_request, order.version) summary = self.dao.get(self.participant.participantId) # distinct count should be 3 (the PM on same day still counts) self.assertEquals(summary.numberDistinctVisits, 3) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_1.isoformat())) self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=150, finalized=TIME_1)) summary = self.dao.get(self.participant.participantId) # distinct count should be 4 self.assertEquals(summary.numberDistinctVisits, 4) # cancel order with pm on different day self.order_dao.update_with_patch(other_order.biobankOrderId, cancel_request, order.version) summary = self.dao.get(self.participant.participantId) # distinct count should be 3 self.assertEquals(summary.numberDistinctVisits, 3) def test_pm_restore_cancel_biobank_restore_cancel(self): self.participant = self._insert(Participant(participantId=9, biobankId=13)) self.measurement_json = json.dumps(load_measurement_json(self.participant.participantId, TIME_4.isoformat())) measurement = self.measurement_dao.insert(self._make_physical_measurements(physicalMeasurementsId=669, finalized=TIME_4)) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) with clock.FakeClock(TIME_5): order = self.order_dao.insert(self._make_biobank_order(biobankOrderId='2', identifiers=[ BiobankOrderIdentifier(system='b', value='d')], samples=[BiobankOrderedSample( biobankOrderId='2', finalized=TIME_5, test=BIOBANK_TESTS[0], description='description', processingRequired=True)])) with clock.FakeClock(TIME_7): summary = self.dao.get(self.participant.participantId) # distinct count should be 2 self.assertEquals(summary.numberDistinctVisits, 2) # cancel the measurement cancel_measurement = get_restore_or_cancel_info() with self.measurement_dao.session() as session: self.measurement_dao.update_with_patch(measurement.physicalMeasurementsId, session, cancel_measurement) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) with clock.FakeClock(TIME_7): restore_measurement = get_restore_or_cancel_info(status='restored') with self.measurement_dao.session() as session: self.measurement_dao.update_with_patch(measurement.physicalMeasurementsId, session, restore_measurement) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 2) cancel_request = cancel_biobank_order() order = self.order_dao.update_with_patch(order.biobankOrderId, cancel_request, order.version) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) restore_order = get_restore_or_cancel_info(status='restored') restore_order['amendedReason'] = 'some reason' self.order_dao.update_with_patch(order.biobankOrderId, restore_order, order.version) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 2) def test_amending_biobank_order_distinct_visit_count(self): self.participant = self._insert(Participant(participantId=9, biobankId=13)) with clock.FakeClock(TIME_5): order = self.order_dao.insert(self._make_biobank_order(biobankOrderId='2', identifiers=[ BiobankOrderIdentifier(system='b', value='d')], samples=[BiobankOrderedSample( biobankOrderId='2', finalized=TIME_5, test=BIOBANK_TESTS[0], description='description', processingRequired=True)])) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) with clock.FakeClock(TIME_7): amend_order = self._get_amended_info(order) with self.order_dao.session() as session: self.order_dao._do_update(session, amend_order, order) # Shouldn't change on a simple amendment (unless finalized time on samples change) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 1) with clock.FakeClock(TIME_7_5): cancel_request = cancel_biobank_order() order = self.order_dao.update_with_patch(order.biobankOrderId, cancel_request, order.version) # A cancelled order (even after amending) should reduce count (unless some other valid order on same day) summary = self.dao.get(self.participant.participantId) self.assertEquals(summary.numberDistinctVisits, 0) @staticmethod def _get_amended_info(order): amendment = dict(amendedReason='I had to change something', amendedInfo={ "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }) order.amendedReason = amendment['amendedReason'] order.amendedInfo = amendment['amendedInfo'] return order def _make_biobank_order(self, **kwargs): """Makes a new BiobankOrder (same values every time) with valid/complete defaults. Kwargs pass through to BiobankOrder constructor, overriding defaults. """ for k, default_value in ( ('biobankOrderId', '1'), ('created', clock.CLOCK.now()), ('participantId', self.participant.participantId), ('sourceSiteId', 1), ('sourceUsername', '*****@*****.**'), ('collectedSiteId', 1), ('collectedUsername', '*****@*****.**'), ('processedSiteId', 1), ('processedUsername', '*****@*****.**'), ('finalizedSiteId', 2), ('finalizedUsername', '*****@*****.**'), ('identifiers', [BiobankOrderIdentifier(system='a', value='c')]), ('samples', [BiobankOrderedSample( biobankOrderId='1', test=BIOBANK_TESTS[0], description='description', finalized=TIME_1, processingRequired=True)])): if k not in kwargs: kwargs[k] = default_value return BiobankOrder(**kwargs) def _make_physical_measurements(self, **kwargs): """Makes a new PhysicalMeasurements (same values every time) with valid/complete defaults. Kwargs pass through to PM constructor, overriding defaults. """ for k, default_value in ( ('physicalMeasurementsId', 1), ('participantId', self.participant.participantId), ('resource', self.measurement_json), ('createdSiteId', 1), ('finalized', TIME_3), ('finalizedSiteId', 2)): if k not in kwargs: kwargs[k] = default_value return PhysicalMeasurements(**kwargs)
class BiobankOrderDaoTest(SqlTestBase): _A_TEST = BIOBANK_TESTS[0] _B_TEST = BIOBANK_TESTS[1] TIME_1 = datetime.datetime(2018, 9, 20, 5, 49, 11) TIME_2 = datetime.datetime(2018, 9, 21, 8, 49, 37) def setUp(self): super(BiobankOrderDaoTest, self).setUp(use_mysql=True) self.participant = Participant(participantId=123, biobankId=555) ParticipantDao().insert(self.participant) self.dao = BiobankOrderDao() def _make_biobank_order(self, **kwargs): """Makes a new BiobankOrder (same values every time) with valid/complete defaults. Kwargs pass through to BiobankOrder constructor, overriding defaults. """ for k, default_value in ( ('biobankOrderId', '1'), ('created', clock.CLOCK.now()), ('participantId', self.participant.participantId), ('sourceSiteId', 1), ('sourceUsername', '*****@*****.**'), ('collectedSiteId', 1), ('collectedUsername', '*****@*****.**'), ('processedSiteId', 1), ('processedUsername', '*****@*****.**'), ('finalizedSiteId', 2), ('finalizedUsername', '*****@*****.**'), ('identifiers', [BiobankOrderIdentifier(system='a', value='c')]), ('samples', [BiobankOrderedSample( biobankOrderId='1', test=self._A_TEST, finalized=self.TIME_2, description='description', processingRequired=True)])): if k not in kwargs: kwargs[k] = default_value return BiobankOrder(**kwargs) @staticmethod def _get_cancel_patch(): return { "amendedReason": 'I messed something up :( ', "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "cancelled" } @staticmethod def _get_restore_patch(): return { "amendedReason": 'I didn"t mess something up :( ', "restoredInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "restored" } @staticmethod def _get_amended_info(order): amendment = dict(amendedReason='I had to change something', amendedInfo={ "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }) order.amendedReason = amendment['amendedReason'] order.amendedInfo = amendment['amendedInfo'] return order def test_bad_participant(self): with self.assertRaises(BadRequest): self.dao.insert(self._make_biobank_order(participantId=999)) def test_from_json(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId) order = BiobankOrderDao().from_client_json(order_json, participant_id=self.participant.participantId) self.assertEquals(1, order.sourceSiteId) self.assertEquals('*****@*****.**', order.sourceUsername) self.assertEquals(1, order.collectedSiteId) self.assertEquals('*****@*****.**', order.collectedUsername) self.assertEquals(1, order.processedSiteId) self.assertEquals('*****@*****.**', order.processedUsername) self.assertEquals(2, order.finalizedSiteId) self.assertEquals('*****@*****.**', order.finalizedUsername) # testing finalized_time samples_finalized_time = None for sample in order_json['samples']: samples_finalized_time = parse_date(sample['finalized']) break self.assertEquals(samples_finalized_time, order.finalizedTime) def test_to_json(self): order = self._make_biobank_order() order_json = self.dao.to_client_json(order) expected_order_json = load_biobank_order_json(self.participant.participantId) for key in ('createdInfo', 'collectedInfo', 'processedInfo', 'finalizedInfo'): self.assertEquals(expected_order_json[key], order_json.get(key)) def test_duplicate_insert_ok(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order(created=self.TIME_1)) order_2 = self.dao.insert(self._make_biobank_order(created=self.TIME_1)) self.assertEquals(order_1.asdict(), order_2.asdict()) def test_same_id_different_identifier_not_ok(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) self.dao.insert(self._make_biobank_order( identifiers=[BiobankOrderIdentifier(system='a', value='b')])) with self.assertRaises(Conflict): self.dao.insert(self._make_biobank_order( identifiers=[BiobankOrderIdentifier(system='a', value='c')])) def test_reject_used_identifier(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) self.dao.insert(self._make_biobank_order( biobankOrderId='1', identifiers=[BiobankOrderIdentifier(system='a', value='b')])) with self.assertRaises(BadRequest): self.dao.insert(self._make_biobank_order( biobankOrderId='2', identifiers=[BiobankOrderIdentifier(system='a', value='b')])) def test_order_for_withdrawn_participant_fails(self): self.participant.withdrawalStatus = WithdrawalStatus.NO_USE ParticipantDao().update(self.participant) ParticipantSummaryDao().insert(self.participant_summary(self.participant)) with self.assertRaises(Forbidden): self.dao.insert(self._make_biobank_order(participantId=self.participant.participantId)) def test_get_for_withdrawn_participant_fails(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) self.dao.insert(self._make_biobank_order( biobankOrderId='1', participantId=self.participant.participantId)) self.participant.version += 1 self.participant.withdrawalStatus = WithdrawalStatus.NO_USE ParticipantDao().update(self.participant) with self.assertRaises(Forbidden): self.dao.get(1) def test_store_invalid_test(self): with self.assertRaises(BadRequest): self.dao.insert(self._make_biobank_order( samples=[BiobankOrderedSample( test='InvalidTestName', processingRequired=True, description=u'tested it')])) def test_cancelling_an_order(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) cancelled_request = self._get_cancel_patch() self.assertEqual(order_1.version, 1) self.assertEqual(order_1.orderStatus, None) updated_order = self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) self.assertEqual(updated_order.version, 2) self.assertEqual(updated_order.cancelledUsername, '*****@*****.**') self.assertEqual(updated_order.orderStatus, BiobankOrderStatus.CANCELLED) self.assertEqual(updated_order.amendedReason, cancelled_request['amendedReason']) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.biospecimenFinalizedSiteId, None) def test_cancelled_order_removes_from_participant_summary(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) samples = [BiobankOrderedSample( test=self._B_TEST, processingRequired=True, description=u'new sample')] biobank_order_id = 2 with clock.FakeClock(self.TIME_1): order_1 = self.dao.insert(self._make_biobank_order()) with clock.FakeClock(self.TIME_2): self.dao.insert(self._make_biobank_order(samples=samples, biobankOrderId=biobank_order_id, identifiers=[ BiobankOrderIdentifier(system='z', value='x')])) cancelled_request = self._get_cancel_patch() ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.sampleOrderStatus1ED10, OrderStatus.FINALIZED) self.assertEqual(ps_dao.sampleOrderStatus1ED10Time, self.TIME_2) self.assertEqual(ps_dao.sampleOrderStatus2ED10, OrderStatus.CREATED) self.assertEqual(ps_dao.sampleOrderStatus2ED10Time, self.TIME_2) self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.sampleOrderStatus1ED10, None) self.assertEqual(ps_dao.sampleOrderStatus1ED10Time, None) # should not remove the other order self.assertEqual(ps_dao.sampleOrderStatus2ED10, OrderStatus.CREATED) self.assertEqual(ps_dao.sampleOrderStatus2ED10Time, self.TIME_2) self.assertEqual(ps_dao.biospecimenCollectedSiteId, 1) self.assertEqual(ps_dao.biospecimenFinalizedSiteId, 2) self.assertEqual(ps_dao.biospecimenProcessedSiteId, 1) self.assertEqual(ps_dao.biospecimenStatus, OrderStatus.FINALIZED) def test_restoring_an_order_gets_to_participant_summary(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) cancelled_request = self._get_cancel_patch() cancelled_order = self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) restore_request = self._get_restore_patch() self.dao.update_with_patch(order_1.biobankOrderId, restore_request, cancelled_order.version) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.sampleOrderStatus1ED10, OrderStatus.FINALIZED) self.assertEqual(ps_dao.biospecimenStatus, OrderStatus.FINALIZED) self.assertEqual(ps_dao.biospecimenSourceSiteId, 1) self.assertEqual(ps_dao.biospecimenCollectedSiteId, 1) self.assertEqual(ps_dao.biospecimenFinalizedSiteId, 2) self.assertEqual(ps_dao.biospecimenProcessedSiteId, 1) def test_amending_order_participant_summary(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) amended_info = self._get_amended_info(order_1) amended_info.sourceSiteId = 2 samples = [BiobankOrderedSample( test=self._B_TEST, processingRequired=True, description=u'new sample')] amended_info.samples = samples with self.dao.session() as session: self.dao._do_update(session, amended_info, order_1) amended_order = self.dao.get(1) self.assertEqual(amended_order.version, 2) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.sampleOrderStatus2ED10, OrderStatus.CREATED) self.assertEqual(ps_dao.sampleOrderStatus1ED10, OrderStatus.FINALIZED) self.assertEqual(ps_dao.numberDistinctVisits, 1) def test_cancelling_an_order_missing_reason(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) cancelled_request = self._get_cancel_patch() del cancelled_request['amendedReason'] with self.assertRaises(BadRequest): self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) def test_cancelling_an_order_missing_info(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) # missing cancelled info cancelled_request = self._get_cancel_patch() del cancelled_request['cancelledInfo'] with self.assertRaises(BadRequest): self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) # missing site cancelled_request = self._get_cancel_patch() del cancelled_request['cancelledInfo']['site'] with self.assertRaises(BadRequest): self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) # missing author cancelled_request = self._get_cancel_patch() del cancelled_request['cancelledInfo']['author'] with self.assertRaises(BadRequest): self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) # missing status cancelled_request = self._get_cancel_patch() del cancelled_request['status'] with self.assertRaises(BadRequest): self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) def test_restoring_an_order(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) cancelled_request = self._get_cancel_patch() cancelled_order = self.dao.update_with_patch(order_1.biobankOrderId, cancelled_request, order_1.version) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.numberDistinctVisits, 0) restore_request = self._get_restore_patch() restored_order = self.dao.update_with_patch(order_1.biobankOrderId, restore_request, cancelled_order.version) self.assertEqual(restored_order.version, 3) self.assertEqual(restored_order.restoredUsername, '*****@*****.**') self.assertEqual(restored_order.orderStatus, BiobankOrderStatus.UNSET) self.assertEqual(restored_order.amendedReason, restore_request['amendedReason']) ps_dao = ParticipantSummaryDao().get(self.participant.participantId) self.assertEqual(ps_dao.numberDistinctVisits, 1) def test_amending_an_order(self): ParticipantSummaryDao().insert(self.participant_summary(self.participant)) order_1 = self.dao.insert(self._make_biobank_order()) amended_info = self._get_amended_info(order_1) amended_info.sourceSiteId = 2 with self.dao.session() as session: self.dao._do_update(session, order_1, amended_info) amended_order = self.dao.get(1) self.assertEqual(amended_order.version, 2) self.assertEqual(amended_order.orderStatus, BiobankOrderStatus.AMENDED) self.assertEqual(amended_order.amendedReason, 'I had to change something') self.assertEqual(amended_order.amendedSiteId, 1) self.assertEqual(amended_order.amendedUsername, '*****@*****.**')
class BiobankOrderApiTest(FlaskTestBase): def setUp(self): super(BiobankOrderApiTest, self).setUp(use_mysql=True) self.participant = Participant(participantId=123, biobankId=555) self.participant_dao = ParticipantDao() self.participant_dao.insert(self.participant) self.summary_dao = ParticipantSummaryDao() self.bio_dao = BiobankOrderDao() self.path = ('Participant/%s/BiobankOrder' % to_client_participant_id(self.participant.participantId)) def test_cancel_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) full_order_json = load_biobank_order_json( self.participant.participantId, filename='biobank_order_1.json') _strip_fields(result) _strip_fields(full_order_json) self.assertEquals(full_order_json, result) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all wrong", "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "cancelled" } cancelled_order = self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"1"'}) get_cancelled_order = self.send_get(path) get_summary = self.summary_dao.get(self.participant.participantId) self.assertEqual(get_summary.biospecimenSourceSiteId, None) self.assertEqual(get_summary.biospecimenCollectedSiteId, None) self.assertEqual(get_summary.biospecimenOrderTime, None) self.assertEqual(get_summary.biospecimenStatus, None) self.assertEqual(get_summary.biospecimenFinalizedSiteId, None) self.assertEqual(get_summary.biospecimenProcessedSiteId, None) self.assertEqual(get_summary.sampleOrderStatus2ED10, None) self.assertEqual(get_summary.sampleOrderStatus2ED10Time, None) self.assertEqual(get_summary.sampleStatus2ED10, None) self.assertEqual(get_summary.sampleStatus2ED10Time, None) self.assertEqual(get_summary.sampleOrderStatus1PST8, None) self.assertEqual(get_summary.sampleOrderStatus1PST8Time, None) self.assertEqual(get_summary.sampleStatus1PST8, None) self.assertEqual(get_summary.sampleStatus1PST8Time, None) self.assertEqual(get_summary.sampleOrderStatus1PS08, None) self.assertEqual(get_summary.sampleOrderStatus1PS08Time, None) self.assertEqual(get_summary.sampleStatus1PS08, None) self.assertEqual(get_summary.sampleStatus1PS08Time, None) self.assertEqual(get_summary.sampleOrderStatus2PST8, None) self.assertEqual(get_summary.sampleOrderStatus2PST8Time, None) self.assertEqual(get_summary.sampleStatus2PST8, None) self.assertEqual(get_summary.sampleStatus2PST8Time, None) self.assertEqual(get_summary.sampleOrderStatus1PXR2, None) self.assertEqual(get_summary.sampleOrderStatus1PXR2Time, None) self.assertEqual(get_summary.sampleStatus1PXR2, None) self.assertEqual(get_summary.sampleStatus1PXR2Time, None) self.assertEqual(get_summary.sampleOrderStatus1CFD9, None) self.assertEqual(get_summary.sampleOrderStatus1CFD9Time, None) self.assertEqual(get_summary.sampleStatus1CFD9, None) self.assertEqual(get_summary.sampleStatus1CFD9Time, None) self.assertEqual(get_summary.sampleOrderStatus1ED02, None) self.assertEqual(get_summary.sampleOrderStatus1ED02Time, None) self.assertEqual(get_summary.sampleStatus1ED02, None) self.assertEqual(get_summary.sampleStatus1ED02Time, None) self.assertEqual(cancelled_order, get_cancelled_order) self.assertEqual(get_cancelled_order['status'], 'CANCELLED') self.assertEqual(get_cancelled_order['amendedReason'], 'Its all wrong') self.assertEqual( get_cancelled_order['cancelledInfo']['author']['value'], '*****@*****.**') self.assertEqual(get_cancelled_order['cancelledInfo']['site']['value'], 'hpo-site-monroeville') def test_cancel_one_order_with_another_good_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename="biobank_order_1.json") order_json2 = load_biobank_order_json(self.participant.participantId, filename="biobank_order_2.json") order_json2['identifier'][0]['value'] = 'healthpro-order-id-1231234' order_json2['identifier'][1]['value'] = 'WEB1YLHV1234' result = self.send_post(self.path, order_json) self.send_post(self.path, order_json2) biobank_order_id = result["identifier"][1]["value"] path = self.path + "/" + biobank_order_id request_data = { "amendedReason": "Its all wrong", "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" }, }, "status": "cancelled", } self.send_patch(path, request_data=request_data, headers={"If-Match": 'W/"1"'}) get_summary = self.summary_dao.get(self.participant.participantId) self.assertEqual(get_summary.biospecimenSourceSiteId, 1) self.assertEqual(get_summary.biospecimenCollectedSiteId, 1) self.assertEqual(get_summary.biospecimenFinalizedSiteId, 2) def test_you_can_not_cancel_a_cancelled_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all wrong", "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "cancelled" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"1"'}) self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"2"'}, expected_status=httplib.BAD_REQUEST) def test_you_can_not_restore_a_not_cancelled_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all wrong", "restoredInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "restored" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"1"'}, expected_status=httplib.BAD_REQUEST) def test_restore_an_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) full_order_json = load_biobank_order_json( self.participant.participantId, filename='biobank_order_1.json') _strip_fields(result) _strip_fields(full_order_json) self.assertEquals(full_order_json, result) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all wrong", "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "cancelled" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"1"'}) request_data = { "amendedReason": "I didnt mean to cancel", "restoredInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "restored" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"2"'}) restored_order = self.send_get(path) get_summary = self.summary_dao.get(self.participant.participantId) self.assertEqual(get_summary.sampleOrderStatus1SST8, OrderStatus.CREATED) self.assertEqual(get_summary.sampleOrderStatus2ED10, OrderStatus.CREATED) self.assertEqual(get_summary.sampleOrderStatus1SAL, OrderStatus.CREATED) self.assertEqual(get_summary.sampleOrderStatus1UR10, OrderStatus.CREATED) self.assertEqual(get_summary.sampleOrderStatus1CFD9, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus1ED02, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus2SST8, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus2PST8, OrderStatus.FINALIZED) self.assertEqual(restored_order['status'], 'UNSET') self.assertEqual(restored_order['restoredInfo']['author']['value'], '*****@*****.**') self.assertEqual(restored_order['restoredInfo']['site']['value'], 'hpo-site-monroeville') self.assertEqual(restored_order['amendedReason'], 'I didnt mean to cancel') def test_amending_an_order(self): # pylint: disable=unused-variable self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all better", "amendedInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-bannerphoenix" } } } biobank_order_identifiers = { "created": "2018-02-21T16:25:12", "createdInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-clinic-phoenix" } } } get_order = self.send_get(path) full_order = get_order.copy() full_order.update(request_data) full_order.update(biobank_order_identifiers) self.assertEqual(len(full_order['samples']), 16) del full_order['samples'][0] self.send_put(path, request_data=full_order, headers={'If-Match': 'W/"1"'}) get_amended_order = self.send_get(path) get_summary = self.summary_dao.get(self.participant.participantId) self.assertEqual(get_summary.biospecimenProcessedSiteId, 1) self.assertEqual(get_summary.biospecimenFinalizedSiteId, 2) self.assertEqual(get_summary.biospecimenCollectedSiteId, 1) self.assertEqual(get_summary.sampleOrderStatus2PST8, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus1PS08, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus1PST8, OrderStatus.FINALIZED) self.assertEqual(get_summary.sampleOrderStatus1SST8, OrderStatus.CREATED) self.assertEqual(get_summary.sampleOrderStatus2ED10, OrderStatus.CREATED) self.assertEqual(len(get_amended_order['samples']), 15) self.assertEqual(get_amended_order['meta'], {'versionId': 'W/"2"'}) self.assertEqual(get_amended_order['amendedReason'], 'Its all better') self.assertEqual(get_amended_order['amendedInfo']['author']['value'], '*****@*****.**') self.assertEqual(get_amended_order['amendedInfo']['site']['value'], 'hpo-site-bannerphoenix') self.assertEqual(get_amended_order['createdInfo']['site']['value'], 'hpo-site-clinic-phoenix') self.assertEqual(get_amended_order['createdInfo']['author']['value'], '*****@*****.**') self.assertEqual(get_amended_order['created'], "2018-02-21T16:25:12") self.assertEqual(get_amended_order['status'], "AMENDED") def test_amend_a_restored_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) full_order_json = load_biobank_order_json( self.participant.participantId, filename='biobank_order_1.json') _strip_fields(result) _strip_fields(full_order_json) biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all wrong", "cancelledInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "cancelled" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"1"'}) self.send_get(path) request_data = { "amendedReason": "I didnt mean to cancel", "restoredInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } }, "status": "restored" } self.send_patch(path, request_data=request_data, headers={'If-Match': 'W/"2"'}) request_data = { "amendedReason": "Its all better", "samples": [{ "test": "1ED10", "description": "EDTA 10 mL (1)", "processingRequired": False, "collected": "2016-01-04T09:45:49Z", "finalized": "2016-01-04T10:55:41Z" }, { "test": "1PST8", "description": "Plasma Separator 8 mL", "collected": "2016-01-04T09:45:49Z", "processingRequired": True, "processed": "2016-01-04T10:28:50Z", "finalized": "2016-01-04T10:55:41Z" }], "amendedInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-monroeville" } } } get_order = self.send_get(path) full_order = get_order.copy() full_order.update(request_data) self.send_put(path, request_data=full_order, headers={'If-Match': 'W/"3"'}) get_amended_order = self.send_get(path) self.assertEqual(len(get_amended_order['samples']), 2) self.assertEqual(get_amended_order['amendedInfo']['author']['value'], '*****@*****.**') self.assertEqual(get_amended_order['status'], 'AMENDED') self.assertEqual(get_amended_order.get('restoredSiteId'), None) self.assertEqual(get_amended_order.get('restoredUsername'), None) self.assertEqual(get_amended_order.get('restoredTime'), None) self.assertEqual(get_amended_order['meta'], {'versionId': 'W/"4"'}) def test_insert_and_refetch(self): self.summary_dao.insert(self.participant_summary(self.participant)) self.create_and_verify_created_obj( self.path, load_biobank_order_json(self.participant.participantId)) def test_insert_new_order(self): self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json(self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) full_order_json = load_biobank_order_json( self.participant.participantId, filename='biobank_order_1.json') _strip_fields(result) _strip_fields(full_order_json) self.assertEquals(full_order_json, result) def test_biobank_history_on_insert(self): with self.bio_dao.session() as session: self.summary_dao.insert(self.participant_summary(self.participant)) order_json = load_biobank_order_json( self.participant.participantId, filename='biobank_order_2.json') result = self.send_post(self.path, order_json) load_biobank_order_json(self.participant.participantId, filename='biobank_order_1.json') order_history = session.query(BiobankOrderHistory).first() identifier_history = session.query( BiobankOrderIdentifierHistory).first() sample_history = session.query(BiobankOrderedSampleHistory).first() self.assertEqual(result['id'], order_history.biobankOrderId) self.assertEqual(identifier_history.biobankOrderId, result['id']) self.assertEqual(sample_history.biobankOrderId, result['id']) self.assertEqual(result['meta']['versionId'], 'W/"1"') self.assertEqual(order_history.version, 1) # Test history on updates... biobank_order_id = result['identifier'][1]['value'] path = self.path + '/' + biobank_order_id request_data = { "amendedReason": "Its all better", "amendedInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-bannerphoenix" } } } biobank_order_identifiers = { "created": "2018-02-21T16:25:12", "createdInfo": { "author": { "system": "https://www.pmi-ops.org/healthpro-username", "value": "*****@*****.**" }, "site": { "system": "https://www.pmi-ops.org/site-id", "value": "hpo-site-clinic-phoenix" } } } get_order = self.send_get(path) full_order = get_order.copy() full_order.update(request_data) full_order.update(biobank_order_identifiers) self.assertEqual(len(full_order['samples']), 16) del full_order['samples'][0] self.send_put(path, request_data=full_order, headers={'If-Match': 'W/"1"'}) with self.bio_dao.session() as session: amended_order = self.send_get(path) second_order_history = session.query( BiobankOrderHistory).filter_by(version=2).first() second_order_samples = session.query( BiobankOrderedSampleHistory).filter_by(version=2).first() second_order_identifier = session.query(BiobankOrderIdentifierHistory).filter_by(version=2)\ .first() self.assertEqual(second_order_history.biobankOrderId, amended_order['id']) self.assertEqual(second_order_identifier.biobankOrderId, amended_order['id']) self.assertEqual(second_order_samples.biobankOrderId, amended_order['id']) # Check that original order hasn't changed in history original = session.query(BiobankOrderHistory).filter_by( version=1).first() self.assertEqual(original.asdict(), order_history.asdict()) def test_error_no_summary(self): order_json = load_biobank_order_json(self.participant.participantId) self.send_post(self.path, order_json, expected_status=httplib.BAD_REQUEST) def test_error_missing_required_fields(self): order_json = load_biobank_order_json(self.participant.participantId) del order_json['identifier'] self.send_post(self.path, order_json, expected_status=httplib.BAD_REQUEST) def test_no_duplicate_test_within_order(self): order_json = load_biobank_order_json(self.participant.participantId) order_json['samples'].extend(list(order_json['samples'])) self.send_post(self.path, order_json, expected_status=httplib.BAD_REQUEST) def test_auto_pair_updates_participant_and_summary(self): self.summary_dao.insert(self.participant_summary(self.participant)) # Sanity check: No HPO yet. p_unpaired = self.participant_dao.get(self.participant.participantId) self.assertEquals(p_unpaired.hpoId, UNSET_HPO_ID) self.assertIsNone(p_unpaired.providerLink) s_unpaired = self.summary_dao.get(self.participant.participantId) self.assertEquals(s_unpaired.hpoId, UNSET_HPO_ID) self.send_post(self.path, load_biobank_order_json(self.participant.participantId)) # Some HPO has been set. (ParticipantDao tests cover more detailed cases / specific values.) p_paired = self.participant_dao.get(self.participant.participantId) self.assertNotEqual(p_paired.hpoId, UNSET_HPO_ID) self.assertIsNotNone(p_paired.providerLink) s_paired = self.summary_dao.get(self.participant.participantId) self.assertNotEqual(s_paired.hpoId, UNSET_HPO_ID) self.assertEqual(s_paired.biospecimenCollectedSiteId, s_paired.siteId) self.assertNotEqual(s_paired.biospecimenCollectedSiteId, s_paired.biospecimenFinalizedSiteId) self.assertNotEqual(s_paired.siteId, s_paired.physicalMeasurementsCreatedSiteId) self.assertNotEqual(s_paired.siteId, s_paired.physicalMeasurementsFinalizedSiteId) def test_not_pairing_at_pm_when_has_bio(self): self.participant_id = self.create_participant() _id = int(self.participant_id[1:]) self.path = ('Participant/%s/BiobankOrder' % to_client_participant_id(_id)) pid_numeric = from_client_participant_id(self.participant_id) self.send_consent(self.participant_id) self.send_post(self.path, load_biobank_order_json(pid_numeric)) participant_paired = self.summary_dao.get(pid_numeric) self.assertEqual(participant_paired.siteId, participant_paired.biospecimenCollectedSiteId) self.path = ('Participant/%s/PhysicalMeasurements' % to_client_participant_id(pid_numeric)) self._insert_measurements(datetime.datetime.utcnow().isoformat()) self.assertNotEqual( participant_paired.siteId, participant_paired.physicalMeasurementsFinalizedSiteId) def test_bio_after_cancelled_pm(self): self.participant_id = self.create_participant() self.send_consent(self.participant_id) measurement = load_measurement_json(self.participant_id) measurement2 = load_measurement_json(self.participant_id) # send both PM's pm_path = 'Participant/%s/PhysicalMeasurements' % self.participant_id response = self.send_post(pm_path, measurement) self.send_post(pm_path, measurement2) # cancel the 1st PM pm_path = pm_path + '/' + response['id'] cancel_info = get_restore_or_cancel_info() self.send_patch(pm_path, cancel_info) # set up questionnaires to hit the calculate_max_core_sample_time in participant summary questionnaire_id = self.create_questionnaire('questionnaire3.json') questionnaire_id_1 = self.create_questionnaire( 'all_consents_questionnaire.json') questionnaire_id_2 = self.create_questionnaire('questionnaire4.json') self._submit_consent_questionnaire_response( self.participant_id, questionnaire_id_1, CONSENT_PERMISSION_YES_CODE, time=TIME_6) self.submit_questionnaire_response(self.participant_id, questionnaire_id, RACE_NONE_OF_THESE_CODE, None, None, datetime.date(1978, 10, 10)) self._submit_empty_questionnaire_response(self.participant_id, questionnaire_id_2) # send a biobank order _id = int(self.participant_id[1:]) self.path = ('Participant/%s/BiobankOrder' % to_client_participant_id(_id)) pid_numeric = from_client_participant_id(self.participant_id) self.send_post(self.path, load_biobank_order_json(pid_numeric)) # fetch participant summary ps = self.send_get('ParticipantSummary?participantId=%s' % _id) self.assertTrue( ps['entry'][0]['resource']["physicalMeasurementsFinalizedTime"]) self.assertEquals( ps['entry'][0]['resource']["physicalMeasurementsFinalizedSite"], 'hpo-site-bannerphoenix') self.assertIsNotNone('biobankId', ps['entry'][0]['resource']) def _insert_measurements(self, now=None): measurements_1 = load_measurement_json(self.participant_id, now) path_1 = 'Participant/%s/PhysicalMeasurements' % self.participant_id self.send_post(path_1, measurements_1) def _submit_consent_questionnaire_response(self, participant_id, questionnaire_id, ehr_consent_answer, time=TIME_1): code_answers = [] _add_code_answer(code_answers, "ehrConsent", ehr_consent_answer) qr = make_questionnaire_response_json(participant_id, questionnaire_id, code_answers=code_answers) with FakeClock(time): self.send_post( 'Participant/%s/QuestionnaireResponse' % participant_id, qr) def _submit_empty_questionnaire_response(self, participant_id, questionnaire_id, time=TIME_1): qr = make_questionnaire_response_json(participant_id, questionnaire_id) with FakeClock(time): self.send_post( 'Participant/%s/QuestionnaireResponse' % participant_id, qr)