def retrieve_diagnostics_by_kit_id(self, supplied_kit_id): kit_repo = KitRepo(self._transaction) kit = kit_repo.get_kit_all_samples(supplied_kit_id) if kit is None: return None sample_assoc = [] for sample in kit.samples: sample_assoc.append( self.retrieve_diagnostics_by_barcode(sample.barcode, grab_kit=False)) with self._transaction.dict_cursor() as cur: cur.execute( "SELECT " "ag_login_id as account_id " "FROM " "ag_kit " "WHERE " "supplied_kit_id = %s", (supplied_kit_id,)) row = cur.fetchone() pre_microsetta_acct = None if row['account_id'] is not None: acct_repo = AccountRepo(self._transaction) # This kit predated the microsetta migration, let's pull in the # account info associated with it pre_microsetta_acct = acct_repo.get_account(row['account_id']) # obtain information on any accounts created using the kit ID with self._transaction.dict_cursor() as cur: cur.execute( "SELECT id as account_id " "FROM " "account " "WHERE " "created_with_kit_id = %s", (supplied_kit_id, )) rows = cur.fetchall() accounts_created = None if len(rows) > 0: acct_repo = AccountRepo(self._transaction) accounts_created = [acct_repo.get_account(row['account_id']) for row in rows] diagnostic = { 'accounts_created': accounts_created, 'kit_id': kit.id, 'supplied_kit_id': supplied_kit_id, 'kit': kit, 'pre_microsetta_acct': pre_microsetta_acct, 'sample_diagnostic_info': sample_assoc } return diagnostic
def get_samples_by_source(self, account_id, source_id, allow_revoked=False): sql = "{0}{1}".format( self.PARTIAL_SQL, " WHERE" " source.account_id = %s" " AND source.id = %s" " ORDER BY ag_kit_barcodes.barcode asc") with self._transaction.cursor() as cur: acct_repo = AccountRepo(self._transaction) if acct_repo.get_account(account_id) is None: raise NotFound("No such account") source_repo = SourceRepo(self._transaction) if source_repo.get_source(account_id, source_id, allow_revoked=allow_revoked) is None: raise NotFound("No such source") cur.execute(sql, (account_id, source_id)) samples = [] for sample_row in cur.fetchall(): samples.append(self._create_sample_obj(sample_row)) return samples
def test_email_stats(self): with Transaction() as t: accts = AccountRepo(t) acct1 = accts.get_account("65dcd6c8-69fa-4de8-a33a-3de4957a0c79") acct2 = accts.get_account("556f5dc4-8cf2-49ae-876c-32fbdfb005dd") # execute articles get for project in [None, "American Gut Project", "NotAProj"]: response = self.client.post( "/api/admin/account_email_summary", headers=MOCK_HEADERS, content_type='application/json', data=json.dumps({ "emails": [acct1.email, acct2.email], "project": project }) ) self.assertEqual(200, response.status_code) result = json.loads(response.data) self.assertEqual(result[0]["account_id"], "65dcd6c8-69fa-4de8-a33a-3de4957a0c79") self.assertEqual(result[1]["account_id"], "556f5dc4-8cf2-49ae-876c-32fbdfb005dd") if project is None or project == "American Gut Project": self.assertEqual(result[0]["sample-is-valid"], 1) else: self.assertEqual(result[0].get("sample-is-valid", 0), 0)
def _validate_account_access(token_info, account_id): with Transaction() as t: account_repo = AccountRepo(t) token_associated_account = account_repo.find_linked_account( token_info['iss'], token_info['sub']) account = account_repo.get_account(account_id) if account is None: raise NotFound(ACCT_NOT_FOUND_MSG) else: # Whether or not the token_info is associated with an admin acct token_authenticates_admin = \ token_associated_account is not None and \ token_associated_account.account_type == 'admin' # Enum of how closely token info matches requested account_id auth_match = account.account_matches_auth( token_info[JWT_EMAIL_CLAIM_KEY], token_info[JWT_ISS_CLAIM_KEY], token_info[JWT_SUB_CLAIM_KEY]) # If token doesn't match requested account id, and doesn't grant # admin access to the system, deny. if auth_match == AuthorizationMatch.NO_MATCH and \ not token_authenticates_admin: raise Unauthorized() return account
def _remote_survey_url_vioscreen(transaction, account_id, source_id, language_tag, survey_redirect_url, vioscreen_ext_sample_id): # assumes an instance of Transaction is already available acct_repo = AccountRepo(transaction) survey_template_repo = SurveyTemplateRepo(transaction) if vioscreen_ext_sample_id: # User is about to start a vioscreen survey for this sample # record this in the database. db_vioscreen_id = survey_template_repo.create_vioscreen_id( account_id, source_id, vioscreen_ext_sample_id) else: raise ValueError("Vioscreen Template requires " "vioscreen_ext_sample_id parameter.") (birth_year, gender, height, weight) = \ survey_template_repo.fetch_user_basic_physiology( account_id, source_id) account = acct_repo.get_account(account_id) country_code = account.address.country_code url = vioscreen.gen_survey_url(db_vioscreen_id, language_tag, survey_redirect_url, birth_year=birth_year, gender=gender, height=height, weight=weight, country_code=country_code) return url
def retrieve_diagnostics_by_email(self, email): acct_repo = AccountRepo(self._transaction) ids = acct_repo.get_account_ids_by_email(email) accts = [acct_repo.get_account(acct_id) for acct_id in ids] diagnostic = { "accounts": accts } return diagnostic
def delete_account(account_id, token_info): validate_admin_access(token_info) with Transaction() as t: acct_repo = AccountRepo(t) src_repo = SourceRepo(t) samp_repo = SampleRepo(t) sar_repo = SurveyAnswersRepo(t) acct = acct_repo.get_account(account_id) if acct is None: return jsonify(message="Account not found", code=404), 404 else: # the account is already scrubbed so let's stop early if acct.account_type == 'deleted': return None, 204 sample_count = 0 sources = src_repo.get_sources_in_account(account_id) for source in sources: samples = samp_repo.get_samples_by_source(account_id, source.id) has_samples = len(samples) > 0 sample_count += len(samples) for sample in samples: # we scrub rather than disassociate in the event that the # sample is in our freezers but not with an up-to-date scan samp_repo.scrub(account_id, source.id, sample.id) surveys = sar_repo.list_answered_surveys(account_id, source.id) if has_samples: # if we have samples, we need to scrub survey / source # free text for survey_id in surveys: sar_repo.scrub(account_id, source.id, survey_id) src_repo.scrub(account_id, source.id) else: # if we do not have associated samples, then the source # is safe to delete for survey_id in surveys: sar_repo.delete_answered_survey(account_id, survey_id) src_repo.delete_source(account_id, source.id) # an account is safe to delete if there are no associated samples if sample_count > 0: acct_repo.scrub(account_id) else: acct_repo.delete_account(account_id) t.commit() return None, 204
def create_source(self, source): with self._transaction.cursor() as cur: acct_repo = AccountRepo(self._transaction) if acct_repo.get_account(source.account_id) is None: raise NotFound("No such account_id") cur.execute( "INSERT INTO source (" + SourceRepo.write_cols + ") " "VALUES(" "%s, %s, %s, " "%s, %s, " "%s, %s, %s, " "%s, %s, %s, " "%s, %s, %s)", _source_to_row(source)) return cur.rowcount == 1
def register_account(body, token_info): # First register with AuthRocket, then come here to make the account new_acct_id = str(uuid.uuid4()) body["id"] = new_acct_id # Account.from_dict requires a kit_name, even if blank kit_name = body.get("kit_name", "") body["kit_name"] = kit_name code = body.get("code", "") body["code"] = code account_obj = Account.from_dict(body, token_info[JWT_ISS_CLAIM_KEY], token_info[JWT_SUB_CLAIM_KEY]) if kit_name == "" and code == "": return jsonify(code=400, message="Account registration requires " "valid kit ID or activation code"), 400 with Transaction() as t: activation_repo = ActivationRepo(t) if code != "": can_activate, cause = activation_repo.can_activate_with_cause( body["email"], code) if not can_activate: return jsonify(code=404, message=cause), 404 else: activation_repo.use_activation_code(body["email"], code) if kit_name != "": kit_repo = KitRepo(t) kit = kit_repo.get_kit_all_samples(kit_name) if kit is None: return jsonify(code=404, message="Kit name not found"), 404 acct_repo = AccountRepo(t) acct_repo.create_account(account_obj) new_acct = acct_repo.get_account(new_acct_id) t.commit() response = jsonify(new_acct.to_api()) response.status_code = 201 response.headers['Location'] = '/api/accounts/%s' % new_acct_id return response
def test_scrub(self): with Transaction() as t: ar = AccountRepo(t) ar.scrub(ACCOUNT_ID) obs = ar.get_account(ACCOUNT_ID) self.assertEqual(obs.id, self.untouched.id) self.assertNotEqual(obs.email, self.untouched.email) self.assertEqual(obs.account_type, 'deleted') self.assertEqual(obs.auth_issuer, None) self.assertEqual(obs.auth_sub, None) self.assertEqual(obs.first_name, 'scrubbed') self.assertEqual(obs.last_name, 'scrubbed') self.assertEqual(obs.address.street, 'scrubbed') self.assertEqual(obs.address.city, 'scrubbed') self.assertEqual(obs.address.state, 'NA') self.assertEqual(obs.address.post_code, 'scrubbed') # keeping country is reasonable as it's so broad self.assertEqual(obs.address.country_code, self.untouched.address.country_code) self.assertEqual(obs.created_with_kit_id, self.untouched.created_with_kit_id) self.assertEqual(obs.creation_time, self.untouched.creation_time) self.assertNotEqual(obs.update_time, self.untouched.update_time) self.assertEqual(obs.language, self.untouched.language) email = obs.email date, remainder = email.split('@', 1) date = date.split('T')[0].strip('"') obs_date = datetime.datetime.strptime(date, "%Y-%m-%d") today = datetime.datetime.now() today = datetime.datetime(year=today.year, month=today.month, day=today.day) self.assertEqual(obs_date, today) self.assertEqual(remainder, 'microsetta.ucsd.edu')
def register_account(body, token_info): # First register with AuthRocket, then come here to make the account new_acct_id = str(uuid.uuid4()) body["id"] = new_acct_id account_obj = Account.from_dict(body, token_info[JWT_ISS_CLAIM_KEY], token_info[JWT_SUB_CLAIM_KEY]) with Transaction() as t: kit_repo = KitRepo(t) kit = kit_repo.get_kit_all_samples(body['kit_name']) if kit is None: return jsonify(code=404, message="Kit name not found"), 404 acct_repo = AccountRepo(t) acct_repo.create_account(account_obj) new_acct = acct_repo.get_account(new_acct_id) t.commit() response = jsonify(new_acct.to_api()) response.status_code = 201 response.headers['Location'] = '/api/accounts/%s' % new_acct_id return response
def get_samples_by_source(self, account_id, source_id): with self._transaction.cursor() as cur: acct_repo = AccountRepo(self._transaction) if acct_repo.get_account(account_id) is None: raise NotFound("No such account") source_repo = SourceRepo(self._transaction) if source_repo.get_source(account_id, source_id) is None: raise NotFound("No such source") cur.execute( "SELECT " "ag_kit_barcodes.ag_kit_barcode_id, " "ag_kit_barcodes.sample_date, " "ag_kit_barcodes.sample_time, " "ag_kit_barcodes.site_sampled, " "ag_kit_barcodes.notes, " "ag_kit_barcodes.barcode, " "barcode.scan_date " "FROM ag_kit_barcodes " "LEFT JOIN barcode " "USING (barcode) " "LEFT JOIN source " "ON ag_kit_barcodes.source_id = source.id " "WHERE " "source.account_id = %s AND " "source.id = %s " "ORDER BY barcode.barcode asc", (account_id, source_id)) samples = [] for sample_row in cur.fetchall(): barcode = sample_row[5] sample_projects = self._retrieve_projects(barcode) s = Sample.from_db(*sample_row, sample_projects) samples.append(s) return samples
def get_survey_metadata(self, sample_barcode, survey_template_id=None): ids = self._get_ids_relevant_to_barcode(sample_barcode) if ids is None: raise NotFound("No such barcode") account_id = ids.get('account_id') source_id = ids.get('source_id') sample_id = ids.get('sample_id') account = None source = None sample = None if sample_id is not None: sample_repo = SampleRepo(self._transaction) sample = sample_repo._get_sample_by_id(sample_id) if source_id is not None and account_id is not None: source_repo = SourceRepo(self._transaction) account_repo = AccountRepo(self._transaction) account = account_repo.get_account(account_id) source = source_repo.get_source(account_id, source_id) if source is None: raise RepoException("Barcode is not associated with a source") # TODO: This is my best understanding of how the data must be # transformed to get the host_subject_id, needs verification that it # generates the expected values for preexisting samples. prehash = account_id + source.name.lower() host_subject_id = sha512(prehash.encode()).hexdigest() survey_answers_repo = SurveyAnswersRepo(self._transaction) answer_ids = survey_answers_repo.list_answered_surveys_by_sample( account_id, source_id, sample_id) answer_to_template_map = {} for answer_id in answer_ids: template_id = survey_answers_repo.find_survey_template_id( answer_id) answer_to_template_map[answer_id] = template_id # if a survey template is specified, filter the returned surveys if survey_template_id is not None: # TODO: This schema is so awkward for this type of query... answers = [] for answer_id in answer_ids: if answer_to_template_map[answer_id] == survey_template_id: answers.append(answer_id) if len(answers) == 0: raise NotFound("This barcode is not associated with any " "surveys matching this template id") if len(answers) > 1: # I really hope this can't happen. (x . x) raise RepoException("This barcode is associated with more " "than one survey matching this template" " id") answer_ids = answers metadata_map = survey_answers_repo.build_metadata_map() all_survey_answers = [] for answer_id in answer_ids: answer_model = survey_answers_repo.get_answered_survey( account_id, source_id, answer_id, "en-US") survey_answers = {} for k in answer_model: new_k = metadata_map[int(k)] survey_answers[k] = [new_k, answer_model[k]] all_survey_answers.append({ "template": answer_to_template_map[answer_id], "response": survey_answers }) pulldown = { "sample_barcode": sample_barcode, "host_subject_id": host_subject_id, "account": account, "source": source, "sample": sample, "survey_answers": all_survey_answers } return pulldown
def retrieve_diagnostics_by_barcode(self, sample_barcode, grab_kit=True): def _rows_to_dicts_list(rows): return [dict(x) for x in rows] with self._transaction.dict_cursor() as cur: ids = self._get_ids_relevant_to_barcode(sample_barcode) if ids is None: ids = {} # default for not found is None sample_id = ids.get("sample_id") source_id = ids.get("source_id") account_id = ids.get("account_id") # NB: this is the true UUID kit id (the primary key of # ag.ag_kit), NOT the kit's participant-facing string "id" kit_id = ids.get("kit_id") account = None source = None sample = None kit = None # get sample object for this barcode, if any if sample_id is not None: sample_repo = SampleRepo(self._transaction) sample = sample_repo._get_sample_by_id(sample_id) # get account object for this barcode, if any if account_id is not None: account_repo = AccountRepo(self._transaction) account = account_repo.get_account(account_id) # and source object for this barcode, if any if source_id is not None: source_repo = SourceRepo(self._transaction) source = source_repo.get_source(account_id, source_id) # get (partial) projects_info list for this barcode query = f""" SELECT {p.DB_PROJ_NAME_KEY}, {p.IS_MICROSETTA_KEY}, {p.BANK_SAMPLES_KEY}, {p.PLATING_START_DATE_KEY} FROM barcodes.project INNER JOIN barcodes.project_barcode USING (project_id) WHERE barcode=%s;""" cur.execute(query, (sample_barcode, )) # this can't be None; worst-case is an empty list projects_info = _rows_to_dicts_list(cur.fetchall()) # get scans_info list for this barcode # NB: ORDER MATTERS here. Do not change the order unless you # are positive you know what already depends on it. cur.execute( "SELECT barcode_scan_id, barcode, " "scan_timestamp, sample_status, " "technician_notes " "FROM barcodes.barcode_scans " "WHERE barcode=%s " "ORDER BY scan_timestamp asc", (sample_barcode, )) # this can't be None; worst-case is an empty list scans_info = _rows_to_dicts_list(cur.fetchall()) latest_scan = None if len(scans_info) > 0: # NB: the correctness of this depends on the scans (queried # right above) being in ascending order by timestamp latest_scan = scans_info[len(scans_info) - 1] # get details about this barcode itself; CAN be None if the # barcode doesn't exist in db barcode_info = None cur.execute( "SELECT barcode, assigned_on, status, " "sample_postmark_date, biomass_remaining, " "sequencing_status, obsolete, " "create_date_time, kit_id " "FROM barcodes.barcode " "WHERE barcode = %s", (sample_barcode, )) barcode_row = cur.fetchone() if barcode_row is not None: barcode_info = dict(barcode_row) if account is None and source is None and sample is None and \ len(projects_info) == 0 and len(scans_info) == 0 \ and barcode_info is None: return None diagnostic = { "account": account, "source": source, "sample": sample, "latest_scan": latest_scan, "scans_info": scans_info, "barcode_info": barcode_info, "projects_info": projects_info } if grab_kit: # get kit object if kit_id is not None: kit_repo = KitRepo(self._transaction) kit = kit_repo.get_kit_all_samples_by_kit_id(kit_id) diagnostic["kit"] = kit return diagnostic
def retrieve_diagnostics_by_barcode(self, sample_barcode, grab_kit=True): with self._transaction.dict_cursor() as cur: ids = self._get_ids_relevant_to_barcode(sample_barcode) if ids is None: sample_id = None source_id = None account_id = None kit_id = None else: sample_id = ids["sample_id"] source_id = ids["source_id"] account_id = ids["account_id"] kit_id = ids["kit_id"] account = None source = None sample = None kit = None if sample_id is not None: sample_repo = SampleRepo(self._transaction) sample = sample_repo._get_sample_by_id(sample_id) if source_id is not None and account_id is not None: account_repo = AccountRepo(self._transaction) source_repo = SourceRepo(self._transaction) account = account_repo.get_account(account_id) source = source_repo.get_source(account_id, source_id) if kit_id is not None and grab_kit: kit_repo = KitRepo(self._transaction) kit = kit_repo.get_kit_all_samples_by_kit_id(kit_id) cur.execute("SELECT * from barcodes.barcode " "LEFT OUTER JOIN barcodes.project_barcode " "USING (barcode) " "LEFT OUTER JOIN barcodes.project " "USING (project_id) " "where barcode=%s", (sample_barcode,)) barcode_info = cur.fetchall() # How to unwrap a psycopg2 DictRow. I feel dirty. barcode_info = [{k: v for k, v in x.items()} for x in barcode_info] # Get Inceptioned!! # Collapse info from joined project_barcode and project tables # into array within barcode_info if barcode_info: first = barcode_info[0] first['projects'] = [ { 'project_id': r['project_id'], 'project': r['project'] } for r in barcode_info] del first['project_id'] del first['project'] barcode_info = first else: barcode_info = None if account is None and \ source is None and \ sample is None and \ barcode_info is None: return None diagnostic = { "barcode": sample_barcode, "account": account, "source": source, "sample": sample, "barcode_info": barcode_info } if grab_kit: diagnostic["kit"] = kit return diagnostic
def retrieve_diagnostics_by_barcode(self, sample_barcode, grab_kit=True): def _rows_to_dicts_list(rows): return [dict(x) for x in rows] with self._transaction.dict_cursor() as cur: ids = self._get_ids_relevant_to_barcode(sample_barcode) if ids is None: sample_id = None source_id = None account_id = None kit_id = None else: sample_id = ids["sample_id"] source_id = ids["source_id"] account_id = ids["account_id"] kit_id = ids["kit_id"] account = None source = None sample = None kit = None # get sample object for this barcode if sample_id is not None: sample_repo = SampleRepo(self._transaction) sample = sample_repo._get_sample_by_id(sample_id) # get account and source objects for this barcode if source_id is not None and account_id is not None: account_repo = AccountRepo(self._transaction) source_repo = SourceRepo(self._transaction) account = account_repo.get_account(account_id) source = source_repo.get_source(account_id, source_id) # get projects_info list for this barcode cur.execute("SELECT project, is_microsetta, " "bank_samples, plating_start_date " "FROM barcodes.project " "INNER JOIN barcodes.project_barcode " "USING (project_id) " "WHERE barcode=%s", (sample_barcode,)) # this can't be None; worst-case is an empty list projects_info = _rows_to_dicts_list(cur.fetchall()) # get scans_info list for this barcode # NB: ORDER MATTERS here. Do not change the order unless you # are positive you know what already depends on it. cur.execute("SELECT barcode_scan_id, barcode, " "scan_timestamp, sample_status, " "technician_notes " "FROM barcodes.barcode_scans " "WHERE barcode=%s " "ORDER BY scan_timestamp asc", (sample_barcode,)) # this can't be None; worst-case is an empty list scans_info = _rows_to_dicts_list(cur.fetchall()) latest_scan = None if len(scans_info) > 0: # NB: the correctness of this depends on the scans (queried # right above) being in ascending order by timestamp latest_scan = scans_info[len(scans_info)-1] # get details about this barcode itself; CAN be None if the # barcode doesn't exist in db barcode_info = None cur.execute("SELECT barcode, assigned_on, status, " "sample_postmark_date, biomass_remaining, " "sequencing_status, obsolete, " "create_date_time, kit_id " "FROM barcodes.barcode " "WHERE barcode = %s", (sample_barcode,)) barcode_row = cur.fetchone() if barcode_row is not None: barcode_info = dict(barcode_row) if account is None and source is None and sample is None and \ len(projects_info) == 0 and len(scans_info) == 0 \ and barcode_info is None: return None diagnostic = { "account": account, "source": source, "sample": sample, "latest_scan": latest_scan, "scans_info": scans_info, "barcode_info": barcode_info, "projects_info": projects_info } if grab_kit: # get kit object if kit_id is not None: kit_repo = KitRepo(self._transaction) kit = kit_repo.get_kit_all_samples_by_kit_id(kit_id) diagnostic["kit"] = kit return diagnostic
def test_create_daklapack_order(self): with Transaction() as t: # need a valid submitter id from the account table to input with t.dict_cursor() as cur: cur.execute("SELECT id, first_name, last_name " "FROM ag.account " "WHERE account_type = 'admin' " "ORDER BY id " "LIMIT 1;") submitter_record = cur.fetchone() submitter_id = submitter_record[0] submitter_name = f"{submitter_record[1]} " \ f"{submitter_record[2]}" # need real project ids to show can link order to project cur.execute("SELECT project_id " "FROM barcodes.project " "ORDER BY project_id " "LIMIT 2;") project_id_records = cur.fetchall() project_ids = [x[0] for x in project_id_records] order_struct = { 'orderId': '7ed917ef-0c4d-431a-9aa0-0a1f4f41f44b', 'articles': [ { 'articleCode': '350102', 'addresses': [ { 'firstName': 'Jane', 'lastName': 'Doe', 'address1': '123 Main St', 'insertion': 'Apt 2', 'address2': '', 'postalCode': 92210, 'city': 'San Diego', 'state': 'CA', 'country': 'USA', 'countryCode': 'us', 'phone': '(858) 555-1212', 'creationDate': '2020-10-09T22:43:52.219328Z', 'companyName': submitter_name }, { 'firstName': 'Tom', 'lastName': 'Thumb', 'address1': '29 Side St', 'insertion': '', 'address2': 'Kew Gardens', 'postalCode': 'KG7-448', 'city': 'Gananoque', 'state': 'Ontario', 'country': 'Canada', 'countryCode': 'ca', 'phone': '(858) 555-1212', 'creationDate': '2020-10-09T22:43:52.219350Z', 'companyName': submitter_name } ] } ], 'shippingProvider': 'FedEx', 'shippingType': 'FEDEX_2_DAY', 'shippingProviderMetadata': [ {'key': 'Reference 1', 'value': 'Bill Ted'} ] } acct_repo = AccountRepo(t) submitter_acct = acct_repo.get_account(submitter_id) input_id = '7ed917ef-0c4d-431a-9aa0-0a1f4f41f44b' creation_timestamp = dateutil.parser.isoparse( "2020-10-09T22:43:52.219328Z") last_polling_timestamp = dateutil.parser.isoparse( "2020-10-19T12:40:19.219328Z") desc = "a description" hold_msg = "hold this order" last_status = "accepted" # create dummy daklapack order object input = DaklapackOrder(input_id, submitter_acct, list(project_ids), order_struct, desc, hold_msg, creation_timestamp, last_polling_timestamp, last_status) # call create_daklapack_order admin_repo = AdminRepo(t) returned_id = admin_repo.create_daklapack_order(input) self.assertEqual(input_id, returned_id) expected_record = [input_id, submitter_id, desc, hold_msg, order_struct, creation_timestamp, last_polling_timestamp, last_status] # check db to show new records exist with t.dict_cursor() as cur: # need real project ids to show can link order to project cur.execute("SELECT * " "FROM barcodes.daklapack_order " "WHERE dak_order_id = %s", (input_id, )) curr_records = cur.fetchall() self.assertEqual(len(curr_records), 1) self.assertEqual(expected_record, curr_records[0]) cur.execute("SELECT project_id " "FROM barcodes.daklapack_order_to_project " "WHERE dak_order_id = %s", (input_id, )) curr_proj_records = cur.fetchall() self.assertEqual(len(curr_proj_records), 2) for curr_proj_rec in curr_proj_records: self.assertTrue(curr_proj_rec[0] in project_ids)
def setUp(self): with Transaction() as t: ar = AccountRepo(t) self.untouched = ar.get_account(ACCOUNT_ID)