def test_bad_records(self):
        expected_messages = {
            "sample_type": "Line 2: Invalid sample type: 'invalid_type'",
            "experiment_id": "Line 3: Mismatch in 'experiment_id' value",
            "sample_id": "Line 3: Mismatch in 'sample_id' value",
            "barcode":
            "Line 2: Bad 'barcode' name 'bad'; expected a name like 'barcode01'",
            "internal_barcode":
            "Line 2: Bad 'internal_barcode' name 'bad'; expected a name like 'internal01'",
            "external_barcode":
            "Line 2: Bad 'external_barcode' name 'bad'; expected a name like 'external01'",
            "rapid_barcode":
            "Line 2: Bad 'rapid_barcode' name 'bad'; expected a name like 'barcode01'",
            "fip_barcode":
            "Line 2: Bad 'fip_barcode' name 'bad'; expected a name like 'FIP01'",
            "duplicate_barcode": "Line 3: Duplicate barcode: 'barcode01'",
            "duplicate_alias": "Line 3: Duplicate alias: 'alias'",
        }

        for filename, message in expected_messages.items():
            with self.assertRaisesRegex(
                    SampleSheetParseError,
                    "^" + re.escape(message) + "$",
                    msg="Test file: " + filename,
            ):
                load_sample_sheet_csv(
                    sample_sheet_csv_path("bad_records", filename))
    def test_bad_column_names(self):
        expected_messages = {
            "no_columns":
            "No columns in sample sheet",
            "invalid_columns":
            "Unrecognised columns in sample sheet: 'a', 'b'",
            "duplicate_columns":
            "Duplicate columns in sample sheet: 'sample_id'",
            "no_position_information":
            "Invalid position information in sample sheet. Must have exactly one of 'flow_cell_id' and 'position_id'",
            "both_position_information":
            "Invalid position information in sample sheet. Must have exactly one of 'flow_cell_id' and 'position_id'",
            "conflicting_barcoding_columns":
            "Conflicting barcode column names: 'barcode', 'rapid_barcode', 'fip_barcode'",
            "missing_barcoding_column":
            "Missing barcoding column names: 'external_barcode'",
            "barcoding_no_alias":
            "Missing 'alias' column",
            "alias_no_barcoding":
            "'alias' column supplied, but no other barcode information in sample sheet",
            "type_no_barcoding":
            "'type' column supplied, but no other barcode information in sample sheet",
            "no_user_info_columns":
            "Sample sheet contains no user info. " +
            "Should contain 'sample_id', 'experiment_id' or some barcode information",
        }

        for filename, message in expected_messages.items():
            with self.assertRaisesRegex(
                    SampleSheetParseError,
                    "^" + re.escape(message) + "$",
                    msg="Test file: " + filename,
            ):
                load_sample_sheet_csv(
                    sample_sheet_csv_path("bad_column_names", filename),
                    exception_on_unknown_field=True,
                )

            if filename != "invalid_columns":
                with self.assertRaisesRegex(
                        SampleSheetParseError,
                        "^" + re.escape(message) + "$",
                        msg="Test file: " + filename,
                ):
                    load_sample_sheet_csv(
                        sample_sheet_csv_path("bad_column_names", filename),
                        exception_on_unknown_field=False,
                    )
    def test_multiple_positions(self):
        sample_sheet = load_sample_sheet_csv(
            sample_sheet_csv_path("good", "multiple_positions"))

        self.compare_sample_sheet(
            sample_sheet,
            [
                ParsedSampleSheetEntry(
                    flow_cell_id=None,
                    position_id="A1",
                    protocol_run_user_info=ProtocolRunUserInfo(
                        sample_id=StringValue(value="my_sample_1"),
                        protocol_group_id=StringValue(value="my_experiment"),
                        barcode_user_info=[
                            BarcodeUserData(barcode_name="barcode01",
                                            alias="alias01"),
                        ],
                    ),
                ),
                ParsedSampleSheetEntry(
                    flow_cell_id=None,
                    position_id="A2",
                    protocol_run_user_info=ProtocolRunUserInfo(
                        sample_id=StringValue(value="my_sample_2"),
                        protocol_group_id=StringValue(value="my_experiment"),
                        barcode_user_info=[
                            BarcodeUserData(barcode_name="barcode01",
                                            alias="alias01"),
                        ],
                    ),
                ),
            ],
        )
    def test_lampore_barcoding(self):
        sample_sheet = load_sample_sheet_csv(
            sample_sheet_csv_path("good", "lampore_barcoding"))

        self.compare_sample_sheet(
            sample_sheet,
            [
                ParsedSampleSheetEntry(
                    flow_cell_id="FC001",
                    position_id=None,
                    protocol_run_user_info=ProtocolRunUserInfo(
                        barcode_user_info=[
                            BarcodeUserData(
                                barcode_name="barcode01",
                                lamp_barcode_id="FIP01",
                                alias="alias01",
                            ),
                            BarcodeUserData(
                                barcode_name="barcode02",
                                lamp_barcode_id="FIP01",
                                alias="alias02",
                            ),
                        ]),
                ),
            ],
        )
    def test_no_error_on_unknown_fields(self):
        sample_sheet = load_sample_sheet_csv(
            sample_sheet_csv_path("bad_column_names", "invalid_columns"),
            exception_on_unknown_field=False,
        )

        # Should have an empty sample sheet, since no entries
        self.assertFalse(sample_sheet)
 def test_no_barcoding(self):
     sample_sheet = load_sample_sheet_csv(
         sample_sheet_csv_path("good", "no_barcoding"))
     self.compare_sample_sheet(
         sample_sheet,
         [
             ParsedSampleSheetEntry(
                 flow_cell_id="FC001",
                 position_id=None,
                 protocol_run_user_info=ProtocolRunUserInfo(
                     sample_id=StringValue(value="my_sample"),
                     protocol_group_id=StringValue(value="my_experiment"),
                 ),
             ),
         ],
     )
    def test_single_barcoding(self):
        sample_sheet = load_sample_sheet_csv(
            sample_sheet_csv_path("good", "single_barcoding"))
        SampleType = BarcodeUserData.SampleType

        self.compare_sample_sheet(
            sample_sheet,
            [
                ParsedSampleSheetEntry(
                    flow_cell_id="FC001",
                    position_id=None,
                    protocol_run_user_info=ProtocolRunUserInfo(
                        barcode_user_info=[
                            BarcodeUserData(
                                barcode_name="barcode01",
                                alias="alias01",
                                type=SampleType.test_sample,
                            ),
                            BarcodeUserData(
                                barcode_name="barcode02",
                                alias="alias02",
                                type=SampleType.positive_control,
                            ),
                            BarcodeUserData(
                                barcode_name="barcode03",
                                alias="alias03",
                                type=SampleType.negative_control,
                            ),
                            BarcodeUserData(
                                barcode_name="barcode04",
                                alias="alias04",
                                type=SampleType.no_template_control,
                            ),
                        ]),
                ),
            ],
        )