Exemplo n.º 1
0
def build_transfer(**kwargs) -> Transfer:
    return Transfer(
        conversation_id=kwargs.get("conversation_id", a_string(36)),
        sla_duration=kwargs.get("sla_duration", a_duration()),
        requesting_practice=kwargs.get(
            "requesting_practice",
            Practice(asid=a_string(12),
                     supplier=a_string(12),
                     ods_code=a_string(4)),
        ),
        sending_practice=kwargs.get(
            "sending_practice",
            Practice(asid=a_string(12),
                     supplier=a_string(12),
                     ods_code=a_string(4)),
        ),
        sender_error_codes=kwargs.get("sender_error_codes", []),
        final_error_codes=kwargs.get("final_error_codes", []),
        intermediate_error_codes=kwargs.get("intermediate_error_codes", []),
        outcome=kwargs.get(
            "outcome",
            TransferOutcome(status=TransferStatus.INTEGRATED_ON_TIME,
                            failure_reason=None),
        ),
        date_requested=kwargs.get("date_requested", a_datetime()),
        date_completed=kwargs.get("date_completed", None),
        last_sender_message_timestamp=None,
    )
Exemplo n.º 2
0
 def derive_transfer(
     self, conversation: Gp2gpConversation, organisation_lookup: OrganisationLookup
 ) -> Transfer:
     sla_duration = _calculate_sla(conversation, self._probe)
     requesting_practice_asid = conversation.requesting_practice_asid()
     sending_practice_asid = conversation.sending_practice_asid()
     return Transfer(
         conversation_id=conversation.conversation_id(),
         sla_duration=sla_duration,
         requesting_practice=Practice(
             asid=requesting_practice_asid,
             supplier=conversation.requesting_supplier(),
             ods_code=organisation_lookup.practice_ods_code_from_asid(requesting_practice_asid),
         ),
         sending_practice=Practice(
             asid=sending_practice_asid,
             supplier=conversation.sending_supplier(),
             ods_code=organisation_lookup.practice_ods_code_from_asid(sending_practice_asid),
         ),
         sender_error_codes=conversation.sender_error_codes(),
         final_error_codes=conversation.final_error_codes(),
         intermediate_error_codes=conversation.intermediate_error_codes(),
         outcome=TransferOutcome.from_gp2gp_conversation(conversation, sla_duration),
         date_requested=conversation.date_requested(),
         date_completed=conversation.effective_final_acknowledgement_time(),
         last_sender_message_timestamp=conversation.last_sender_message_timestamp(),
     )
Exemplo n.º 3
0
def a_transfer_integrated_beyond_8_days():
    return build_transfer(
        outcome=TransferOutcome(
            status=TransferStatus.PROCESS_FAILURE,
            failure_reason=TransferFailureReason.INTEGRATED_LATE,
        ),
        sla_duration=timedelta(seconds=EIGHT_DAYS_IN_SECONDS + 1),
    )
Exemplo n.º 4
0
def a_supressed_transfer(**kwargs):
    return build_transfer(
        outcome=TransferOutcome(
            status=TransferStatus.INTEGRATED_ON_TIME,
            failure_reason=None,
        ),
        final_error_codes=[15],
        sla_duration=kwargs.get("sla_duration", a_duration(max_length=604800)),
    )
Exemplo n.º 5
0
def test_returns_transfer_status_process_failure_with_reason(
        test_case, expected_reason):
    gp2gp_messages: List[Message] = test_case()
    conversation = Gp2gpConversation(
        gp2gp_messages, probe=mock_gp2gp_conversation_observability_probe)
    actual = TransferOutcome.from_gp2gp_conversation(conversation, None)

    assert actual.status == TransferStatus.PROCESS_FAILURE
    assert actual.failure_reason == expected_reason
Exemplo n.º 6
0
def test_returns_transfer_status_integrated_on_time(test_case):
    gp2gp_messages: List[Message] = test_case()
    conversation = Gp2gpConversation(
        gp2gp_messages, mock_gp2gp_conversation_observability_probe)

    actual = TransferOutcome.from_gp2gp_conversation(conversation,
                                                     timedelta(days=1))

    assert actual.status == TransferStatus.INTEGRATED_ON_TIME
    assert actual.failure_reason is None
Exemplo n.º 7
0
def test_returns_transfer_status_technical_failure_with_reason(
        test_case, expected_reason):
    gp2gp_messages: List[Message] = test_case()
    conversation = Gp2gpConversation(
        gp2gp_messages, mock_gp2gp_conversation_observability_probe)

    actual = TransferOutcome.from_gp2gp_conversation(conversation,
                                                     a_duration())

    assert actual.status == TransferStatus.TECHNICAL_FAILURE
    assert actual.failure_reason == expected_reason
Exemplo n.º 8
0
def test_status_is_converted_to_column():
    integrated_transfer_outcome = TransferOutcome(
        status=TransferStatus.INTEGRATED_ON_TIME, failure_reason=None)
    transfer = build_transfer(transfer_outcome=integrated_transfer_outcome)

    expected_status_column = {"status": ["Integrated on time"]}

    table = convert_transfers_to_table([transfer])
    actual_status_column = table.select(["status"]).to_pydict()

    assert actual_status_column == expected_status_column
Exemplo n.º 9
0
def test_returns_correct_transfer_outcome_if_fatal_sender_error_code_present(
    fatal_sender_error_code, ):
    gp2gp_messages: List[Message] = test_cases.request_acknowledged_with_error(
        error_code=fatal_sender_error_code)
    conversation = Gp2gpConversation(
        gp2gp_messages, mock_gp2gp_conversation_observability_probe)

    actual = TransferOutcome.from_gp2gp_conversation(conversation,
                                                     a_duration())

    assert actual.status == TransferStatus.TECHNICAL_FAILURE
    assert actual.failure_reason == TransferFailureReason.FATAL_SENDER_ERROR
Exemplo n.º 10
0
def test_return_process_failure_given_an_unacknowledged_ehr_with_duplicate_and_no_copc_fragments(
):
    gp2gp_messages: List[
        Message] = test_cases.acknowledged_duplicate_and_waiting_for_integration(
        )
    conversation = Gp2gpConversation(
        gp2gp_messages, mock_gp2gp_conversation_observability_probe)

    actual = TransferOutcome.from_gp2gp_conversation(conversation, None)

    assert actual.status == TransferStatus.PROCESS_FAILURE
    assert actual.failure_reason == TransferFailureReason.TRANSFERRED_NOT_INTEGRATED
Exemplo n.º 11
0
def test_returns_unclassified_given_unacknowledged_ehr_with_duplicate_and_copc_fragments(
):
    conversation = build_mock_gp2gp_conversation()

    conversation.is_integrated.return_value = False
    conversation.has_concluded_with_failure.return_value = False
    conversation.contains_unacknowledged_duplicate_ehr_and_copc_fragments.return_value = True

    actual = TransferOutcome.from_gp2gp_conversation(conversation, None)

    assert actual.status == TransferStatus.UNCLASSIFIED_FAILURE
    assert actual.failure_reason == TransferFailureReason.AMBIGUOUS_COPCS
Exemplo n.º 12
0
def test_write_transfers_correctly_writes_all_fields():
    mock_s3 = MockS3()
    s3_data_manager = S3DataManager(mock_s3)
    io = TransferClassifierIO(s3_data_manager)

    transfer = Transfer(
        conversation_id="1234",
        sla_duration=timedelta(days=1),
        requesting_practice=Practice(asid="123",
                                     supplier="Supplier A",
                                     ods_code="A12"),
        sending_practice=Practice(asid="456",
                                  supplier="Supplier B",
                                  ods_code="B12"),
        sender_error_codes=[1, None],
        final_error_codes=[None, 32],
        intermediate_error_codes=[],
        outcome=TransferOutcome(
            status=TransferStatus.PROCESS_FAILURE,
            failure_reason=TransferFailureReason.FINAL_ERROR),
        date_requested=datetime(year=2021, month=3, day=5),
        date_completed=None,
        last_sender_message_timestamp=None,
    )

    io.write_transfers(transfers=[transfer],
                       s3_uri="s3://a_bucket/some_data.parquet",
                       metadata=_SOME_METADATA)

    expected_table = {
        "conversation_id": ["1234"],
        "sla_duration": [86400],
        "requesting_practice_asid": ["123"],
        "requesting_practice_ods_code": ["A12"],
        "sending_practice_asid": ["456"],
        "sending_practice_ods_code": ["B12"],
        "requesting_supplier": ["Supplier A"],
        "sending_supplier": ["Supplier B"],
        "sender_error_codes": [[1, None]],
        "final_error_codes": [[None, 32]],
        "intermediate_error_codes": [[]],
        "status": ["Process failure"],
        "failure_reason": ["Final error"],
        "date_requested": [datetime(year=2021, month=3, day=5)],
        "date_completed": [None],
        "last_sender_message_timestamp": [None],
    }

    actual_table = mock_s3.object(
        "a_bucket", "some_data.parquet").read_parquet().to_pydict()

    assert actual_table == expected_table
Exemplo n.º 13
0
def test_returns_correct_transfer_outcome_given_multiple_conflicting_sender_acks(
):
    a_fatal_sender_error = choice(FATAL_SENDER_ERROR_CODES)

    gp2gp_messages: List[
        Message] = test_cases.multiple_sender_acknowledgements(
            error_codes=[None, a_fatal_sender_error])
    conversation = Gp2gpConversation(
        gp2gp_messages, mock_gp2gp_conversation_observability_probe)

    actual = TransferOutcome.from_gp2gp_conversation(conversation,
                                                     a_duration())

    assert actual.status == TransferStatus.TECHNICAL_FAILURE
    assert actual.failure_reason == TransferFailureReason.FATAL_SENDER_ERROR
Exemplo n.º 14
0
def test_returns_transferred_not_integrated_with_error_given_stalled_with_copc_error(
):
    conversation = build_mock_gp2gp_conversation()

    conversation.is_integrated.return_value = False
    conversation.has_concluded_with_failure.return_value = False
    conversation.contains_copc_fragments.return_value = True
    conversation.contains_unacknowledged_duplicate_ehr_and_copc_fragments.return_value = False
    conversation.contains_copc_error.return_value = True
    conversation.is_missing_copc_ack.return_value = False

    actual = TransferOutcome.from_gp2gp_conversation(conversation, None)

    assert actual.status == TransferStatus.UNCLASSIFIED_FAILURE
    assert actual.failure_reason == TransferFailureReason.TRANSFERRED_NOT_INTEGRATED_WITH_ERROR
Exemplo n.º 15
0
def an_integrated_transfer(**kwargs):
    return build_transfer(
        outcome=TransferOutcome(status=TransferStatus.INTEGRATED_ON_TIME,
                                failure_reason=None),
        sla_duration=kwargs.get("sla_duration", a_duration(max_length=604800)),
    )
Exemplo n.º 16
0
def a_transfer_with_a_final_error():
    return build_transfer(outcome=TransferOutcome(
        status=TransferStatus.TECHNICAL_FAILURE,
        failure_reason=TransferFailureReason.FINAL_ERROR,
    ))
Exemplo n.º 17
0
def a_transfer_where_no_core_ehr_was_sent():
    return build_transfer(outcome=TransferOutcome(
        status=TransferStatus.TECHNICAL_FAILURE,
        failure_reason=TransferFailureReason.CORE_EHR_NOT_SENT,
    ))