def test_pools_to_status(rml_order_to_submit): # GIVEN a rml order with three samples in one pool order = OrderIn.parse_obj(rml_order_to_submit, OrderType.RML) # WHEN parsing for status data = RmlSubmitter.order_to_status(order=order) # THEN it should pick out the general information assert data["customer"] == "cust000" assert data["order"] == "#123456" assert data["comment"] == "order comment" # ... and information about the pool(s) assert len(data["pools"]) == 2 pool = data["pools"][0] assert pool["name"] == "pool-1" assert pool["application"] == "RMLP05R800" assert pool["data_analysis"] == str(Pipeline.FLUFFY) assert pool["data_delivery"] == str(DataDelivery.NIPT_VIEWER) assert len(pool["samples"]) == 2 sample = pool["samples"][0] assert sample["name"] == "sample1" assert sample["comment"] == "test comment" assert pool["priority"] == "research" assert sample["control"] == "negative"
def test_microbial_samples_to_status(microbial_order_to_submit): # GIVEN microbial order with three samples order = OrderIn.parse_obj(microbial_order_to_submit, OrderType.MICROSALT) # WHEN parsing for status data = MicrobialSubmitter.order_to_status(order=order) # THEN it should pick out samples and relevant information assert len(data["samples"]) == 5 assert data["customer"] == "cust002" assert data["order"] == "Microbial samples" assert data["comment"] == "Order comment" assert data["data_analysis"] == str(Pipeline.MICROSALT) assert data["data_delivery"] == str(DataDelivery.FASTQ) # THEN first sample should contain all the relevant data from the microbial order sample_data = data["samples"][0] assert sample_data["priority"] == "research" assert sample_data["name"] == "all-fields" assert sample_data.get("internal_id") is None assert sample_data["organism_id"] == "M.upium" assert sample_data["reference_genome"] == "NC_111" assert sample_data["application"] == "MWRNXTR003" assert sample_data["comment"] == "plate comment" assert sample_data["volume"] == "1"
def test_store_items_in_status_control_has_stored_value( sarscov2_order_to_submit: dict, base_store: Store): # GIVEN sarscov2 order with three samples with control value order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) control_value = ControlEnum.positive sample: SarsCov2Sample for sample in order.samples: sample.control: ControlEnum = control_value submitter: SarsCov2Submitter = SarsCov2Submitter(status=base_store, lims=None) status_data = submitter.order_to_status(order=order) # WHEN storing the order submitter.store_items_in_status( comment="", customer=order.customer, data_analysis=Pipeline.SARS_COV_2, data_delivery=DataDelivery.FASTQ, order="", ordered=dt.datetime.now(), ticket=123456, items=status_data.get("samples"), ) # THEN control should exist on the sample in the store customer = base_store.customer(order.customer) sample: SarsCov2Sample for sample in order.samples: stored_sample: models.Sample = base_store.find_samples( customer=customer, name=sample.name).first() assert stored_sample.control == control_value
def test_cases_to_status_synopsis(mip_order_to_submit): # GIVEN a scout order with a trio case where synopsis is None for sample in mip_order_to_submit["samples"]: sample["synopsis"] = None project: OrderType = OrderType.MIP_DNA order = OrderIn.parse_obj(mip_order_to_submit, project=project) # WHEN parsing for status MipDnaSubmitter.order_to_status(order=order)
def test_submit_scout_legal_sample_customer( all_orders_to_submit: dict, monkeypatch, order_type: OrderType, orders_api: OrdersAPI, sample_store: Store, ticket_number: int, user_mail: str, user_name: str, ): order_data = OrderIn.parse_obj(obj=all_orders_to_submit[order_type], project=order_type) monkeypatch_process_lims(monkeypatch, order_data) # GIVEN we have an order with a customer that is in the same customer group as customer # that the samples originate from customer_group = sample_store.add_customer_group( "customer999only", "customer 999 only group") sample_store.add_commit(customer_group) sample_customer = sample_store.add_customer( "customer1", "customer 1", scout_access=True, invoice_address="dummy street 1", customer_group=customer_group, invoice_reference="dummy nr", ) order_customer = sample_store.add_customer( "customer2", "customer 2", scout_access=True, invoice_address="dummy street 2", customer_group=customer_group, invoice_reference="dummy nr", ) sample_store.add_commit(sample_customer) sample_store.add_commit(order_customer) existing_sample = sample_store.samples().first() existing_sample.customer = sample_customer sample_store.commit() order_data.customer = order_customer.internal_id for sample in order_data.samples: sample.internal_id = existing_sample.internal_id break # WHEN calling submit # THEN an OrderError should not be raised on illegal customer orders_api.submit(project=order_type, order_in=order_data, user_name=user_name, user_mail=user_mail)
def test_order_to_status_control_exists(sarscov2_order_to_submit: dict, base_store: Store): # GIVEN sarscov2 order with three samples order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) # WHEN transforming order to status structure result: dict = SarsCov2Submitter.order_to_status(order=order) # THEN check that control is in the result sample: dict for sample in result.get("samples"): assert "control" in sample
def submit_order(order_type): """Submit an order for samples.""" api = OrdersAPI(lims=lims, status=db, osticket=osticket) error_message: str try: request_json = request.get_json() LOG.info("processing order: %s", request_json) project: OrderType = OrderType(order_type) order_in: OrderIn = OrderIn.parse_obj(request_json, project=project) result = api.submit( project=project, order_in=order_in, user_name=g.current_user.name, user_mail=g.current_user.email, ) except ( # user misbehaviour OrderError, OrderFormError, ValidationError, ValueError, ) as error: error_message = error.message if hasattr(error, "message") else str(error) http_error_response = http.HTTPStatus.BAD_REQUEST LOG.error(error_message) except ( # system misbehaviour AttributeError, ConnectionError, HTTPError, IntegrityError, KeyError, NewConnectionError, MaxRetryError, TimeoutError, TypeError, ) as error: LOG.exception(error) error_message = error.message if hasattr(error, "message") else str(error) http_error_response = http.HTTPStatus.INTERNAL_SERVER_ERROR else: return jsonify( project=result["project"], records=[record.to_dict() for record in result["records"]]) if error_message: return abort( make_response(jsonify(message=error_message), http_error_response))
def test_metagenome_to_status(metagenome_order_to_submit): # GIVEN metagenome order with two samples order = OrderIn.parse_obj(metagenome_order_to_submit, OrderType.METAGENOME) # WHEN parsing for status data = MetagenomeSubmitter.order_to_status(order=order) # THEN it should pick out samples and relevant information assert len(data["samples"]) == 2 first_sample = data["samples"][0] assert first_sample["name"] == "Bristol" assert first_sample["application"] == "METLIFR020" assert first_sample["priority"] == "standard" assert first_sample["volume"] == "1"
def test_validate_submitted_order(sarscov2_order_to_submit: dict, base_store: Store, helpers: StoreHelpers): # GIVEN sarscov2 order with three samples, all in the database order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) sample: SarsCov2Sample for sample in order.samples: helpers.add_sample(store=base_store, name=sample.name, customer_id=order.customer) # WHEN validating the order # THEN it should be regarded as invalid with (pytest.raises(OrderError)): SarsCov2Submitter(status=base_store, lims=None).validate_order(order=order)
def test_to_lims_fastq(fastq_order_to_submit): # GIVEN a fastq order for two samples; normal vs. tumour order_data = OrderIn.parse_obj(obj=fastq_order_to_submit, project=OrderType.FASTQ) # WHEN parsing the order to format for LIMS samples: List[LimsSample] = build_lims_sample(customer="dummyCust", samples=order_data.samples) # THEN should "work" assert len(samples) == 2 normal_sample = samples[0] tumor_sample = samples[1] # ... and pick out relevant UDF values assert normal_sample.udfs.tumour is False assert tumor_sample.udfs.tumour is True assert normal_sample.udfs.volume == "1"
def test_validate_submitted_control_order(sarscov2_order_to_submit: dict, base_store: Store, helpers: StoreHelpers): # GIVEN sarscov2 order with three control samples, all in the database order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) sample: SarsCov2Sample for sample in order.samples: helpers.add_sample(store=base_store, name=sample.name, customer_id=order.customer) sample.control = ControlEnum.positive # WHEN validating the order # THEN it should be regarded as valid SarsCov2Submitter(status=base_store, lims=None).validate_order(order=order)
def test_validate_case_name(rml_order_to_submit: dict, base_store: Store, helpers: StoreHelpers): # GIVEN pool order with a case already all in the database order: OrderIn = OrderIn.parse_obj(rml_order_to_submit, OrderType.RML) sample: RmlSample customer: models.Customer = helpers.ensure_customer( store=base_store, customer_id=order.customer) for sample in order.samples: case = helpers.ensure_case( store=base_store, name=PoolSubmitter.create_case_name(ticket=order.ticket, pool_name=sample.pool), customer=customer, data_analysis=Pipeline.FLUFFY, data_delivery=DataDelivery.STATINA, ) base_store.add_commit(case)
def test_order_to_status_control_has_input_value( sarscov2_order_to_submit: dict, base_store: Store): # GIVEN sarscov2 order with three samples with control value set control_value = ControlEnum.positive order: OrderIn = OrderIn.parse_obj(sarscov2_order_to_submit, OrderType.SARS_COV_2) sample: SarsCov2Sample for sample in order.samples: sample.control: ControlEnum = control_value # WHEN transforming order to status structure result: dict = SarsCov2Submitter.order_to_status(order=order) # THEN check that control is in the result sample: dict for sample in result.get("samples"): assert control_value in sample.get("control")
def test_to_lims_rml(rml_order_to_submit): # GIVEN a rml order for four samples order_data = OrderIn.parse_obj(obj=rml_order_to_submit, project=OrderType.RML) # WHEN parsing for LIMS samples: List[LimsSample] = build_lims_sample(customer="dummyCust", samples=order_data.samples) # THEN it should have found the same number of samples assert len(samples) == 4 # ... and pick out relevant UDFs first_sample = samples[0] assert first_sample.udfs.pool == "pool-1" assert first_sample.udfs.volume == "30" assert first_sample.udfs.concentration == "5.0" assert first_sample.udfs.index == "IDT DupSeq 10 bp Set B" assert first_sample.udfs.index_number == "1"
def test_samples_to_status(fastq_order_to_submit): # GIVEN fastq order with two samples order = OrderIn.parse_obj(fastq_order_to_submit, OrderType.FASTQ) # WHEN parsing for status data = FastqSubmitter.order_to_status(order=order) # THEN it should pick out samples and relevant information assert len(data["samples"]) == 2 first_sample = data["samples"][0] assert first_sample["name"] == "prov1" assert first_sample["application"] == "WGSPCFC060" assert first_sample["priority"] == "priority" assert first_sample["tumour"] is False assert first_sample["volume"] == "1" # ... and the other sample is a tumour assert data["samples"][1]["tumour"] is True
def test_to_lims_balsamic(balsamic_order_to_submit): # GIVEN a cancer order for a sample order_data = OrderIn.parse_obj(obj=balsamic_order_to_submit, project=OrderType.BALSAMIC) # WHEN parsing the order to format for LIMS import samples: List[LimsSample] = build_lims_sample(customer="cust000", samples=order_data.samples) # THEN it should list all samples assert len(samples) == 1 # ... and determine the container, container name, and well position container_names = { sample.container_name for sample in samples if sample.container_name } # ... and pick out relevant UDFs first_sample = samples[0].dict() assert first_sample["name"] == "s1" assert {sample.container for sample in samples} == set(["96 well plate"]) assert first_sample["udfs"]["data_analysis"] == str(Pipeline.BALSAMIC) assert first_sample["udfs"]["application"] == "WGSPCFC030" assert first_sample["udfs"]["sex"] == "M" assert first_sample["udfs"]["family_name"] == "family1" assert first_sample["udfs"]["customer"] == "cust000" assert first_sample["udfs"]["source"] == "blood" assert first_sample["udfs"]["volume"] == "1" assert first_sample["udfs"]["priority"] == "standard" assert container_names == set(["p1"]) assert first_sample["well_position"] == "A:1" assert first_sample["udfs"]["tumour"] is True assert first_sample["udfs"]["capture_kit"] == "other" assert first_sample["udfs"]["tumour_purity"] == "75" assert first_sample["udfs"]["formalin_fixation_time"] == "1" assert first_sample["udfs"]["post_formalin_fixation_time"] == "2" assert first_sample["udfs"]["tissue_block_size"] == "small" assert first_sample["udfs"]["quantity"] == "2" assert first_sample["udfs"]["comment"] == "other Elution buffer"
def test_to_lims_microbial(microbial_order_to_submit): # GIVEN a microbial order for three samples order_data = OrderIn.parse_obj(obj=microbial_order_to_submit, project=OrderType.MICROSALT) # WHEN parsing for LIMS samples: List[LimsSample] = build_lims_sample(customer="cust000", samples=order_data.samples) # THEN it should "work" assert len(samples) == 5 # ... and pick out relevant UDFs first_sample = samples[0].dict() assert first_sample["udfs"]["priority"] == "research" assert first_sample["udfs"]["organism"] == "M.upium" assert first_sample["udfs"]["reference_genome"] == "NC_111" assert (first_sample["udfs"]["extraction_method"] == "MagNaPure 96 (contact Clinical Genomics " "before submission)") assert first_sample["udfs"]["volume"] == "1"
def test_submit_unique_sample_name( all_orders_to_submit: dict, monkeypatch, order_type: OrderType, orders_api: OrdersAPI, ticket_number: int, user_mail: str, user_name: str, ): # GIVEN we have an order with a sample that is not existing in the database order_data = OrderIn.parse_obj(obj=all_orders_to_submit[order_type], project=order_type) store = orders_api.status assert store.samples().first() is None monkeypatch_process_lims(monkeypatch, order_data) # WHEN calling submit orders_api.submit(project=order_type, order_in=order_data, user_name=user_name, user_mail=user_mail)
def test_not_sarscov2_submit_duplicate_sample_name( all_orders_to_submit: dict, helpers: StoreHelpers, monkeypatch, order_type: OrderType, orders_api: OrdersAPI, sample_store: Store, ticket_number: int, user_mail: str, user_name: str, ): # GIVEN we have an order with samples that is already in the database order_data = OrderIn.parse_obj(obj=all_orders_to_submit[order_type], project=order_type) monkeypatch_process_lims(monkeypatch, order_data) store_samples_with_names_from_order(orders_api.status, helpers, order_data) # WHEN calling submit orders_api.submit(project=order_type, order_in=order_data, user_name=user_name, user_mail=user_mail)
def test_cases_to_status(mip_order_to_submit): # GIVEN a scout order with a trio case project: OrderType = OrderType.MIP_DNA order = OrderIn.parse_obj(mip_order_to_submit, project=project) # WHEN parsing for status data = MipDnaSubmitter.order_to_status(order=order) # THEN it should pick out the case assert len(data["families"]) == 2 family = data["families"][0] assert family["name"] == "family1" assert family["data_analysis"] == str(Pipeline.MIP_DNA) assert family["data_delivery"] == str(DataDelivery.SCOUT) assert family["priority"] == Priority.standard.name assert family["cohorts"] == {"Other"} assert family[ "synopsis"] == "Här kommer det att komma en väldigt lång text med för synopsis." assert set(family["panels"]) == {"IEM"} assert len(family["samples"]) == 3 first_sample = family["samples"][0] assert first_sample["age_at_sampling"] == "17.18192" assert first_sample["name"] == "sample1" assert first_sample["application"] == "WGSPCFC030" assert first_sample["phenotype_groups"] == ["Phenotype-group"] assert first_sample["phenotype_terms"] == ["HP:0012747", "HP:0025049"] assert first_sample["sex"] == "female" assert first_sample["status"] == "affected" assert first_sample["subject_id"] == "subject1" assert first_sample["mother"] == "sample2" assert first_sample["father"] == "sample3" # ... second sample has a comment assert isinstance(family["samples"][1]["comment"], str)
def test_submit_duplicate_sample_case_name( all_orders_to_submit: dict, monkeypatch, order_type: OrderType, orders_api: OrdersAPI, ticket_number: int, user_mail: str, user_name: str, ): # GIVEN we have an order with a case that is already in the database order_data = OrderIn.parse_obj(obj=all_orders_to_submit[order_type], project=order_type) store = orders_api.status customer_obj = store.customer(order_data.customer) for sample in order_data.samples: case_id = sample.family_name if not store.find_family(customer=customer_obj, name=case_id): case_obj = store.add_case( data_analysis=Pipeline.MIP_DNA, data_delivery=DataDelivery.SCOUT, name=case_id, ) case_obj.customer = customer_obj store.add_commit(case_obj) assert store.find_family(customer=customer_obj, name=case_id) monkeypatch_process_lims(monkeypatch, order_data) # WHEN calling submit # THEN an OrderError should be raised on duplicate case name with pytest.raises(OrderError): orders_api.submit(project=order_type, order_in=order_data, user_name=user_name, user_mail=user_mail)
def mip_rna_status_data(mip_rna_order_to_submit: dict): """Parse rna order example.""" project: OrderType = OrderType.MIP_RNA order: OrderIn = OrderIn.parse_obj(obj=mip_rna_order_to_submit, project=project) return MipRnaSubmitter.order_to_status(order=order)
def microbial_status_data(microbial_order_to_submit: dict): """Parse microbial order example.""" project: OrderType = OrderType.MICROSALT order: OrderIn = OrderIn.parse_obj(obj=microbial_order_to_submit, project=project) return MicrobialSubmitter.order_to_status(order=order)
def fastq_status_data(fastq_order_to_submit): """Parse fastq order example.""" project: OrderType = OrderType.FASTQ order: OrderIn = OrderIn.parse_obj(obj=fastq_order_to_submit, project=project) return FastqSubmitter.order_to_status(order=order)
def balsamic_status_data(balsamic_order_to_submit: dict): """Parse balsamic order example.""" project: OrderType = OrderType.BALSAMIC order: OrderIn = OrderIn.parse_obj(obj=balsamic_order_to_submit, project=project) return BalsamicSubmitter.order_to_status(order=order)
def fluffy_status_data(fluffy_order_to_submit): """Parse fluffy order example.""" project: OrderType = OrderType.FLUFFY order: OrderIn = OrderIn.parse_obj(obj=fluffy_order_to_submit, project=project) return FluffySubmitter.order_to_status(order=order)
def rml_status_data(rml_order_to_submit): """Parse rml order example.""" project: OrderType = OrderType.RML order: OrderIn = OrderIn.parse_obj(obj=rml_order_to_submit, project=project) return RmlSubmitter.order_to_status(order=order)
def test_validate_normal_order(rml_order_to_submit: dict, base_store: Store): # GIVEN pool order with three samples, none in the database order = OrderIn.parse_obj(rml_order_to_submit, OrderType.RML) # WHEN validating the order PoolSubmitter(status=base_store, lims=None).validate_order(order=order)