def test_execute___with_no_split_rows_not_looped___pipette_volumes_ok(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_vol=40,
                                  dilute_factor=2,
                                  target_vol=10)
        builder.add_artifact_pair(source_vol=40,
                                  dilute_factor=3,
                                  target_vol=10)
        builder.add_artifact_pair(source_conc=60,
                                  source_vol=40,
                                  dilute_factor=4,
                                  target_vol=10)

        # Act
        builder.extension.execute()

        # Assert
        transfers = builder.transfers
        self.assertEqual(5, transfers[0].pipette_sample_volume)
        self.assertEqual(5, transfers[0].pipette_buffer_volume)
        self.assertEqual(3.3, transfers[1].pipette_sample_volume)
        self.assertEqual(6.7, transfers[1].pipette_buffer_volume)
        self.assertEqual(2.5, transfers[2].pipette_sample_volume)
        self.assertEqual(7.5, transfers[2].pipette_buffer_volume)
    def test_run_execute__with_two_controls_and_one_normal_sample__examine_variables(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_dna_extension()
        builder.with_control_id_prefix("101C-")
        builder.add_artifact_pair(source_container_name="source1")
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)

        # Act
        builder.extension.execute()

        # Assert
        metadata_info = builder.metadata_info("Metadata filename",
                                              HamiltonRobotSettings())
        print_list(metadata_info.container_mappings, "container_mappings")
        container_to_container_slot = metadata_info.transfer_batches[
            0].container_to_container_slot
        print_out_dict(container_to_container_slot.values(),
                       "Container to container slot")
        print("Length of dict: {}".format(len(container_to_container_slot)))
        print("Type that is mapped: {}".format(
            type(container_to_container_slot[
                container_to_container_slot.keys()[0]])))
        self.assertEqual(1, 1)
    def test_run_execute__with_two_previous_added_controls_and_one_normal__controls_included_in_container_mapping(
            self):
        """
        In this test, lims-id for control artifacts are updated with prefix 2- 
        """
        # Arrange
        builder = ExtensionBuilder.create_with_dna_extension()
        builder.with_control_id_prefix("2-")
        builder.add_artifact_pair(source_container_name="source1")
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)

        # Act
        builder.extension.execute()

        # Assert
        metadata_info = builder.metadata_info("Metadata filename",
                                              HamiltonRobotSettings())
        self.assertTrue(
            "source1" in
            [m[0].container.name for m in metadata_info.container_mappings])
        self.assertTrue(
            "control container" in
            [m[0].container.name for m in metadata_info.container_mappings])
    def test_execute___with_single_transfer_looped_dilution___exception_cast(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_vol=80,
                                  dilute_factor=35,
                                  target_vol=10)

        # Act
        # Assert
        self.assertRaises(UsageError, lambda: builder.extension.execute())
    def test_execute___with_one_transfer_lacking_dilute_factor___exception_cast(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_conc=10,
                                  source_vol=10,
                                  dilute_factor=None,
                                  target_vol=40)

        # Act
        # Assert
        self.assertRaises(UsageError, lambda: builder.extension.execute())
    def test_execute___without_source_conc___target_conc_is_none(self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_vol=40,
                                  dilute_factor=4,
                                  target_vol=10)

        # Act
        builder.extension.execute()

        # Assert
        update_queue = list(builder.extension.context._update_queue)
        output_artifact = update_queue[0]
        self.assertIsNone(output_artifact.udf_dil_calc_target_conc)
    def test_execute___with_split_row___updates_ok(self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_conc=80,
                                  source_vol=80,
                                  dilute_factor=10,
                                  target_vol=80)

        # Act
        builder.extension.execute()

        # Assert
        output_artifact = builder.update_queue[0]
        self.assertEqual(-9, output_artifact.udf_dil_calc_source_vol)
        self.assertEqual(8, round(output_artifact.udf_dil_calc_target_conc, 1))
        self.assertEqual(80, round(output_artifact.udf_dil_calc_target_vol, 1))
    def test_execute___with_split_row___pipette_volume_ok(self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_conc=80,
                                  source_vol=80,
                                  dilute_factor=10,
                                  target_vol=80)

        # Act
        builder.extension.execute()

        # Assert
        transfers = builder.transfers
        self.assertEqual(2, len(transfers))
        self.assertEqual(8, transfers[0].pipette_sample_volume)
        self.assertEqual(36, transfers[0].pipette_buffer_volume)
        self.assertEqual(0, transfers[1].pipette_sample_volume)
        self.assertEqual(36, transfers[1].pipette_buffer_volume)
    def test_execute___with_no_split_rows_not_looped___updates_ok(self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_conc=80,
                                  source_vol=40,
                                  dilute_factor=3,
                                  target_vol=10)
        # Act
        builder.extension.execute()

        # Assert
        update_queue = list(builder.extension.context._update_queue)
        output_artifact = update_queue[0]
        self.assertEqual(1, len(update_queue))
        self.assertEqual(-4.3, output_artifact.udf_dil_calc_source_vol)
        self.assertEqual(26.7,
                         round(output_artifact.udf_dil_calc_target_conc, 1))
        self.assertEqual(10, round(output_artifact.udf_dil_calc_target_vol))
    def test_execute___with_one_transfer_exceeding_source_volume___warning(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_factor_extension()
        builder.add_artifact_pair(source_conc=10,
                                  source_vol=10,
                                  dilute_factor=3,
                                  target_vol=40)

        # Act
        builder.extension.execute()

        # Assert
        self.assertEqual(
            2,
            builder.ext_wrapper.context_wrapper.
            count_logged_validation_results_with_msg(
                "Volume from sample exceeds current sample volume"))
    def test_run_execute__with_two_added_controls_and_one_normal_sample__control_excluded_in_container_mappings(
            self):
        """
        container_mappings controls what is shown under source containers and target containers
        in the xml metadata file
        
        Negative controls are taken from the through and should not be included in the source 
        container list.
        
        In future there will be a problem with several types of controls! 
        """

        # Arrange
        builder = ExtensionBuilder.create_with_dna_extension()
        builder.with_control_id_prefix("101C-")
        builder.add_artifact_pair(source_container_name="source1")
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)

        # Act
        builder.extension.execute()

        # Assert
        metadata_info = builder.metadata_info("Metadata filename",
                                              HamiltonRobotSettings())
        print_list(metadata_info.container_mappings, "container_mappings")
        print_list(
            [m[0].container.name for m in metadata_info.container_mappings],
            "source containers in container_mappings")
        self.assertTrue(
            "source1" in
            [m[0].container.name for m in metadata_info.container_mappings])
        self.assertFalse(
            "control container" in
            [m[0].container.name for m in metadata_info.container_mappings])
    def test_run_execute__with_two_controls_and_one_normal_sample__save_file_on_harddisk(
            self):
        # Arrange
        builder = ExtensionBuilder.create_with_dna_extension()
        builder.with_control_id_prefix("101C-")
        builder.add_artifact_pair(source_container_name="source1")
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)
        builder.add_artifact_pair(source_container_name="control container",
                                  is_control=True)

        # Act
        builder.extension.execute()

        # Arrange save to harddisk
        artifact_service = builder.extension.context.artifact_service
        upload_file_service = UploadFileService(
            OSService(),
            artifact_service=artifact_service,
            disable_commits=True,
            upload_dir=r"C:\Smajobb\2017\April\Run clarity\test_runs")

        # Modified code taken from DilutionSession.execute()
        today = datetime.date.today().strftime("%y%m%d")
        metadata_file_handle = "Metadata"
        metadata_files = list()
        dilution_session = builder.extension.dilution_session
        for robot in dilution_session.robot_settings:
            metadata_file_name = "{}_{}_{}_{}.xml".format(
                robot.name, today, "EE", "1234")
            metadata_files.append((metadata_file_name,
                                   builder.extension.generate_metadata_file(
                                       robot, metadata_file_name)))

        # Upload the metadata file:
        upload_file_service.upload_files(metadata_file_handle, metadata_files)