예제 #1
0
def test_calculate_sla_by_practice_calculates_sla_given_transfers_for_2_practices(
):
    practice_list = [
        PracticeDetails(asids=["121212121212"],
                        ods_code="A12345",
                        name="A Practice"),
        PracticeDetails(asids=["343434343434"],
                        ods_code="B12345",
                        name="Another Practice"),
    ]
    transfers = [
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=8, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="343434343434",
            sla_duration=timedelta(days=4, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=0, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="343434343434",
            sla_duration=timedelta(days=8, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="343434343434",
            sla_duration=timedelta(days=5, hours=1, minutes=10),
        ),
    ]

    expected = [
        PracticeMetrics(
            ods_code="A12345",
            name="A Practice",
            integrated=IntegratedPracticeMetrics(transfer_count=2,
                                                 within_3_days=1,
                                                 within_8_days=0,
                                                 beyond_8_days=1),
        ),
        PracticeMetrics(
            ods_code="B12345",
            name="Another Practice",
            integrated=IntegratedPracticeMetrics(transfer_count=3,
                                                 within_3_days=0,
                                                 within_8_days=2,
                                                 beyond_8_days=1),
        ),
    ]

    actual = calculate_sla_by_practice(practice_list, transfers)
    actual_sorted = sorted(actual, key=lambda p: p.ods_code)

    assert actual_sorted == expected
def test_excludes_transfers_missing_sla_duration():
    integrated_transfer_1 = build_transfer(status=TransferStatus.INTEGRATED)
    integrated_transfer_2 = build_transfer(status=TransferStatus.INTEGRATED, sla_duration=None)
    failed_transfer = build_transfer(status=TransferStatus.FAILED)
    transfers = [integrated_transfer_1, integrated_transfer_2, failed_transfer]

    actual = filter_for_successful_transfers(transfers)

    expected = [integrated_transfer_1]

    assert list(actual) == expected
def test_excludes_failed_transfers():
    integrated_transfer_1 = build_transfer(status=TransferStatus.INTEGRATED)
    integrated_transfer_2 = build_transfer(status=TransferStatus.INTEGRATED)
    failed_transfer = build_transfer(status=TransferStatus.FAILED)
    transfers = [integrated_transfer_1, integrated_transfer_2, failed_transfer]

    actual = filter_for_successful_transfers(transfers)

    expected = [integrated_transfer_1, integrated_transfer_2]

    assert list(actual) == expected
예제 #4
0
def test_groups_by_asid_given_single_practice_and_transfers_from_the_same_practice(
):
    practices = [
        PracticeDetails(asids=["121212121212"],
                        ods_code="A12345",
                        name=a_string())
    ]
    transfers = [
        build_transfer(requesting_practice_asid="121212121212"),
        build_transfer(requesting_practice_asid="121212121212"),
    ]

    actual = calculate_sla_by_practice(practices, transfers)

    _assert_has_ods_codes(actual, {"A12345"})
예제 #5
0
def test_table_has_correct_schema():
    transfers = [build_transfer()]

    expected_schema = pa.schema([
        ("conversation_id", pa.string()),
        ("sla_duration", pa.uint64()),
        ("requesting_practice_asid", pa.string()),
        ("requesting_practice_ods_code", pa.string()),
        ("sending_practice_asid", pa.string()),
        ("sending_practice_ods_code", pa.string()),
        ("requesting_supplier", pa.string()),
        ("sending_supplier", pa.string()),
        ("sender_error_codes", pa.list_(pa.int64())),
        ("final_error_codes", pa.list_(pa.int64())),
        ("intermediate_error_codes", pa.list_(pa.int64())),
        ("status", pa.string()),
        ("failure_reason", pa.string()),
        ("date_requested", pa.timestamp("us")),
        ("date_completed", pa.timestamp("us")),
        ("last_sender_message_timestamp", pa.timestamp("us")),
    ])

    table = convert_transfers_to_table(transfers)
    actual_schema = table.schema

    assert actual_schema == expected_schema
예제 #6
0
def test_converts_multiple_rows_into_table():
    transfers = [
        build_transfer(conversation_id="123", final_error_codes=[1]),
        build_transfer(conversation_id="456", final_error_codes=[2]),
        build_transfer(conversation_id="789", final_error_codes=[3]),
    ]

    expected_columns = {
        "conversation_id": ["123", "456", "789"],
        "final_error_codes": [[1], [2], [3]],
    }

    table = convert_transfers_to_table(transfers)
    actual_columns = table.select(["conversation_id",
                                   "final_error_codes"]).to_pydict()

    assert actual_columns == expected_columns
예제 #7
0
def test_date_completed_is_converted_to_column_when_missing():
    transfer = build_transfer(date_completed=None)

    expected_date_column = {"date_completed": [None]}

    table = convert_transfers_to_table([transfer])
    actual_date_column = table.select(["date_completed"]).to_pydict()

    assert actual_date_column == expected_date_column
예제 #8
0
def test_sla_duration_is_converted_to_column_when_missing():
    transfer = build_transfer(sla_duration=None)

    expected_sla_duration_column = {"sla_duration": [None]}

    table = convert_transfers_to_table([transfer])
    actual_sla_duration_column = table.select(["sla_duration"]).to_pydict()

    assert actual_sla_duration_column == expected_sla_duration_column
예제 #9
0
def test_final_error_code_is_converted_to_column():
    transfer = build_transfer(final_error_code=5)

    expected_error_code_column = {"final_error_code": [5]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["final_error_code"]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
예제 #10
0
def test_sender_error_code_is_converted_to_column():
    transfer = build_transfer(sender_error_code=10)

    expected_error_code_column = {"sender_error_code": [10]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["sender_error_code"]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
예제 #11
0
def test_sending_practice_asid_is_converted_to_column():
    transfer = build_transfer(sending_practice_asid="001112345678")

    expected_asid_column = {"sending_practice_asid": ["001112345678"]}

    table = convert_transfers_to_table([transfer])
    actual_asid_column = table.select(["sending_practice_asid"]).to_pydict()

    assert actual_asid_column == expected_asid_column
def test_excludes_pending_transfers():
    pending_transfer = build_transfer(status=TransferStatus.PENDING)

    transfers = [pending_transfer]

    actual = filter_for_successful_transfers(transfers)
    expected = []

    assert list(actual) == expected
예제 #13
0
def test_groups_by_asid_given_two_practices_and_two_transfers_from_different_practices(
):
    practices = [
        PracticeDetails(asids=["121212121212"],
                        ods_code="A12345",
                        name=a_string()),
        PracticeDetails(asids=["343434343434"],
                        ods_code="X67890",
                        name=a_string()),
    ]
    transfers = [
        build_transfer(requesting_practice_asid="121212121212"),
        build_transfer(requesting_practice_asid="343434343434"),
    ]

    actual = calculate_sla_by_practice(practices, transfers)

    _assert_has_ods_codes(actual, {"A12345", "X67890"})
예제 #14
0
def test_conversation_id_is_converted_to_column():
    transfer = build_transfer(conversation_id="123")

    expected_conversation_column = {"conversation_id": ["123"]}

    table = convert_transfers_to_table([transfer])
    actual_conversation_column = table.select(["conversation_id"]).to_pydict()

    assert actual_conversation_column == expected_conversation_column
예제 #15
0
def test_final_error_codes_are_converted_to_column_when_missing():
    transfer = build_transfer(final_error_codes=[])

    expected_error_code_column: dict = {"final_error_codes": [[]]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["final_error_codes"]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
예제 #16
0
def test_status_is_converted_to_column():
    transfer = build_transfer(status=TransferStatus.INTEGRATED)

    expected_status_column = {"status": ["INTEGRATED"]}

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

    assert actual_status_column == expected_status_column
예제 #17
0
def test_sender_error_codes_are_converted_to_column_when_missing():
    transfer = build_transfer(sender_error_codes=[None])

    expected_error_code_column = {"sender_error_codes": [[None]]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["sender_error_codes"]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
def test_calculates_correct_national_metrics_given_series_of_messages():
    sla_duration_within_3_days = timedelta(seconds=THREE_DAYS_IN_SECONDS)
    sla_duration_within_8_days = timedelta(seconds=EIGHT_DAYS_IN_SECONDS)
    sla_duration_beyond_8_days = timedelta(seconds=EIGHT_DAYS_IN_SECONDS + 1)

    transfers = [
        build_transfer(status=TransferStatus.PENDING),
        build_transfer(status=TransferStatus.PENDING_WITH_ERROR),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_within_3_days),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_within_8_days),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_within_8_days),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_beyond_8_days),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_beyond_8_days),
        build_transfer(status=TransferStatus.INTEGRATED,
                       sla_duration=sla_duration_beyond_8_days),
        build_transfer(status=TransferStatus.FAILED),
    ]

    time_range = DateTimeRange(start=datetime(2019, 12, 1, tzinfo=UTC),
                               end=datetime(2020, 1, 1, tzinfo=UTC))
    current_datetime = datetime.now(tzutc())

    expected_national_metrics = MonthlyNationalMetrics(
        transfer_count=9,
        integrated=IntegratedMetrics(
            transfer_percentage=66.67,
            transfer_count=6,
            within_3_days=1,
            within_8_days=2,
            beyond_8_days=3,
        ),
        failed=FailedMetrics(transfer_count=1, transfer_percentage=11.11),
        pending=PendingMetrics(transfer_count=2, transfer_percentage=22.22),
        paper_fallback=PaperFallbackMetrics(transfer_count=6,
                                            transfer_percentage=66.67),
        year=2019,
        month=12,
    )

    expected = NationalMetricsPresentation(generated_on=current_datetime,
                                           metrics=[expected_national_metrics])
    actual = calculate_national_metrics_data(transfers, time_range)

    assert actual == expected
예제 #19
0
def test_intermediate_error_codes_are_converted_to_column_when_empty():
    transfer = build_transfer(intermediate_error_codes=[])

    expected_error_code_column: dict = {"intermediate_error_codes": [[]]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["intermediate_error_codes"
                                             ]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
예제 #20
0
def test_intermediate_error_codes_is_converted_to_column():
    transfer = build_transfer(intermediate_error_codes=[6])

    expected_error_code_column = {"intermediate_error_codes": [[6]]}

    table = convert_transfers_to_table([transfer])
    actual_error_code_column = table.select(["intermediate_error_codes"
                                             ]).to_pydict()

    assert actual_error_code_column == expected_error_code_column
예제 #21
0
def test_sending_practice_ods_is_converted_to_column():
    transfer = build_transfer(sending_practice=Practice(
        asid="001112345678", supplier="supplier", ods_code="A12"))

    expected_ods_column = {"sending_practice_ods_code": ["A12"]}

    table = convert_transfers_to_table([transfer])
    actual_ods_column = table.select(["sending_practice_ods_code"]).to_pydict()

    assert actual_ods_column == expected_ods_column
예제 #22
0
def test_sla_duration_is_rounded_to_integer():
    transfer = build_transfer(sla_duration=timedelta(
        days=2, hours=1, minutes=3, seconds=6, milliseconds=1))

    expected_sla_duration_column = {"sla_duration": [176586]}

    table = convert_transfers_to_table([transfer])
    actual_sla_duration_column = table.select(["sla_duration"]).to_pydict()

    assert actual_sla_duration_column == expected_sla_duration_column
예제 #23
0
def test_requesting_practice_asid_is_converted_to_column():
    transfer = build_transfer(requesting_practice=Practice(
        asid="003212345678", supplier="supplier", ods_code="A12"))

    expected_asid_column = {"requesting_practice_asid": ["003212345678"]}

    table = convert_transfers_to_table([transfer])
    actual_asid_column = table.select(["requesting_practice_asid"]).to_pydict()

    assert actual_asid_column == expected_asid_column
예제 #24
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
예제 #25
0
def test_date_completed_is_converted_to_column():
    transfer = build_transfer(
        date_completed=datetime(year=2020, month=7, day=28, hour=17))

    expected_date_column = {
        "date_completed": [datetime(year=2020, month=7, day=28, hour=17)]
    }

    table = convert_transfers_to_table([transfer])
    actual_date_column = table.select(["date_completed"]).to_pydict()

    assert actual_date_column == expected_date_column
예제 #26
0
def test_write_transfers_correctly_writes_multiple_rows():
    mock_s3 = MockS3()
    s3_data_manager = S3DataManager(mock_s3)
    io = TransferClassifierIO(s3_data_manager)

    transfers = [
        build_transfer(conversation_id="a"),
        build_transfer(conversation_id="b"),
        build_transfer(conversation_id="c"),
    ]

    io.write_transfers(transfers=transfers,
                       s3_uri="s3://a_bucket/multi_row.parquet",
                       metadata=_SOME_METADATA)

    expected_conversation_ids = ["a", "b", "c"]

    actual_conversation_ids = (mock_s3.object(
        "a_bucket",
        "multi_row.parquet").read_parquet().to_pydict().get("conversation_id"))

    assert actual_conversation_ids == expected_conversation_ids
예제 #27
0
def test_counts_both_asids_for_practice_with_two_asids():
    practice_list = [
        PracticeDetails(asids=["121212121212", "343434343434"],
                        ods_code="A12345",
                        name=a_string())
    ]
    transfers = [
        build_transfer(
            requesting_practice_asid="343434343434",
            sla_duration=timedelta(hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=5, hours=1, minutes=10),
        ),
    ]
    actual = calculate_sla_by_practice(practice_list, transfers)

    _assert_first_summary_has_sla_counts(actual,
                                         within_3_days=1,
                                         within_8_days=1,
                                         beyond_8_days=0)
예제 #28
0
def test_returns_sum_of_all_integrated_transfers():
    practice_list = [
        PracticeDetails(asids=["121212121212"],
                        ods_code="A12345",
                        name=a_string())
    ]
    transfers = [
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=0, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=7, hours=1, minutes=10),
        ),
        build_transfer(
            requesting_practice_asid="121212121212",
            sla_duration=timedelta(days=10, hours=1, minutes=10),
        ),
    ]
    actual = list(calculate_sla_by_practice(practice_list, transfers))

    assert actual[0].integrated.transfer_count == 3
예제 #29
0
def test_calculate_sla_by_practice_calculates_sla_given_one_transfer_within_3_days(
):
    practice_list = [
        PracticeDetails(asids=["121212121212"],
                        ods_code="A12345",
                        name=a_string())
    ]
    transfer = build_transfer(requesting_practice_asid="121212121212",
                              sla_duration=timedelta(hours=1, minutes=10))
    actual = calculate_sla_by_practice(practice_list, [transfer])

    _assert_first_summary_has_sla_counts(actual,
                                         within_3_days=1,
                                         within_8_days=0,
                                         beyond_8_days=0)
예제 #30
0
def test_write_transfers_writes_metadata():
    mock_s3 = MockS3()
    s3_data_manager = S3DataManager(mock_s3)

    metadata = {a_string(): a_string()}

    io = TransferClassifierIO(s3_data_manager)

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

    actual_meta_data = mock_s3.object("a_bucket",
                                      "some_data.parquet").get_metadata()

    assert actual_meta_data == metadata