def test_filter_conversations_by_request_started_time_rejects_conversations_outside_of_range(
):
    date_range = DateTimeRange(start=datetime(year=2020, month=6, day=1),
                               end=datetime(year=2020, month=7, day=1))

    conversation_within_range = build_parsed_conversation(
        request_started=build_message(
            time=datetime(year=2020, month=6, day=15)))
    conversation_before_range = build_parsed_conversation(
        request_started=build_message(
            time=datetime(year=2020, month=5, day=28)))
    conversation_after_range = build_parsed_conversation(
        request_started=build_message(
            time=datetime(year=2020, month=7, day=28)))

    parsed_conversations = [
        conversation_before_range,
        conversation_within_range,
        conversation_after_range,
    ]

    expected = [conversation_within_range]

    actual = filter_conversations_by_request_started_time(
        parsed_conversations, date_range)

    assert list(actual) == expected
def test_parses_transfer_correctly_given_valid_message_list():
    time_range = DateTimeRange(start=datetime(2019, 12, 1, tzinfo=UTC),
                               end=datetime(2020, 1, 1, tzinfo=UTC))

    requesting_asid_with_transfer = "343434343434"
    sending_asid_with_transfer = "111134343434"
    requesting_supplier = "EMIS"
    sending_supplier = "Vision"
    conversation_id = "abcdefg_1234"

    spine_messages = _build_successful_conversation(
        conversation_id=conversation_id,
        requesting_asid=requesting_asid_with_transfer,
        sending_asid=sending_asid_with_transfer,
        requesting_supplier=requesting_supplier,
        sending_supplier=sending_supplier,
        ehr_request_started_on=datetime(2019, 12, 30, 18, 2, 29, tzinfo=UTC),
        ehr_request_completed_on=datetime(2019, 12, 30, 18, 3, 21, tzinfo=UTC),
        ehr_request_started_acknowledged_on=datetime(2019,
                                                     12,
                                                     30,
                                                     18,
                                                     3,
                                                     23,
                                                     tzinfo=UTC),
        ehr_request_completed_acknowledged_on=datetime(2020,
                                                       1,
                                                       1,
                                                       8,
                                                       41,
                                                       48,
                                                       tzinfo=UTC),
    )

    expected = [
        Transfer(
            conversation_id=conversation_id,
            sla_duration=timedelta(days=1, seconds=52707),
            requesting_practice_asid=requesting_asid_with_transfer,
            sending_practice_asid=sending_asid_with_transfer,
            requesting_supplier=requesting_supplier,
            sending_supplier=sending_supplier,
            status=TransferStatus.INTEGRATED,
            date_requested=datetime(2019, 12, 30, 18, 2, 29, tzinfo=UTC),
            date_completed=datetime(2020, 1, 1, 8, 41, 48, tzinfo=UTC),
            sender_error_code=None,
            final_error_code=None,
            intermediate_error_codes=[],
        )
    ]

    actual = list(parse_transfers_from_messages(spine_messages, time_range))

    assert actual == expected
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
def test_filter_conversations_by_request_started_time_accepts_conversation_on_range_start(
):
    date_range = DateTimeRange(start=datetime(year=2020, month=6, day=1),
                               end=datetime(year=2020, month=7, day=1))
    parsed_conversations = [
        build_parsed_conversation(request_started=build_message(
            time=datetime(year=2020, month=6, day=1)))
    ]

    expected = parsed_conversations

    actual = filter_conversations_by_request_started_time(
        parsed_conversations, date_range)

    assert list(actual) == expected
def _get_time_range(year, month):
    metric_month = datetime(year, month, 1, tzinfo=tzutc())
    next_month = metric_month + relativedelta(months=1)
    return DateTimeRange(metric_month, next_month)
    EHR_REQUEST_STARTED,
    EHR_REQUEST_COMPLETED,
    COMMON_POINT_TO_POINT,
    APPLICATION_ACK,
)
from prmdata.utils.date.range import DateTimeRange
from prmdata.utils.io.csv import read_gzip_csv_files

input_files = [
    "./Jan-2021.csv.gz",
    "./Feb-2021.csv.gz",
]

metric_month = datetime(2021, 1, 1, tzinfo=tzutc())
next_month = metric_month + relativedelta(months=1)
date_range = DateTimeRange(metric_month, next_month)

abbreviations = {
    EHR_REQUEST_STARTED: "RQS",
    EHR_REQUEST_COMPLETED: "RQC",
    COMMON_POINT_TO_POINT: "P2P",
    APPLICATION_ACK: "ACK"
}


def read_spine_csv_gz_files(file_paths):
    items = read_gzip_csv_files(file_paths)
    return construct_messages_from_splunk_items(items)


def conversation_is_started_in(conversation, date_range):
def test_calculates_correct_metrics_given_a_successful_transfer():
    time_range = DateTimeRange(start=datetime(2019, 12, 1, tzinfo=UTC),
                               end=datetime(2020, 1, 1, tzinfo=UTC))

    requesting_practice_name = "Test GP"
    requesting_ods_code = "A12345"
    requesting_asid_with_transfer = "343434343434"
    sending_asid_with_transfer = "111134343434"
    requesting_supplier = "SystemOne"
    sending_supplier = "Unknown"
    conversation_id = "abcdefg_1234"

    transfers = [
        Transfer(
            conversation_id=conversation_id,
            sla_duration=timedelta(days=1, seconds=52707),
            requesting_practice_asid=requesting_asid_with_transfer,
            sending_practice_asid=sending_asid_with_transfer,
            requesting_supplier=requesting_supplier,
            sending_supplier=sending_supplier,
            status=TransferStatus.INTEGRATED,
            date_requested=datetime(2019, 12, 30, 18, 2, 29, tzinfo=UTC),
            date_completed=datetime(2020, 1, 1, 8, 41, 48, tzinfo=UTC),
            sender_error_code=None,
            final_error_code=None,
            intermediate_error_codes=[],
        )
    ]

    practice_list = [
        PracticeDetails(
            asids=[requesting_asid_with_transfer],
            ods_code=requesting_ods_code,
            name=requesting_practice_name,
        )
    ]

    expected = PracticeMetricsPresentation(
        generated_on=datetime(year=2020,
                              month=1,
                              day=15,
                              hour=23,
                              second=42,
                              tzinfo=UTC),
        practices=[
            PracticeSummary(
                ods_code=requesting_ods_code,
                name=requesting_practice_name,
                metrics=[
                    MonthlyMetrics(
                        year=2019,
                        month=12,
                        requester=RequesterMetrics(
                            integrated=IntegratedPracticeMetrics(
                                transfer_count=1,
                                within_3_days_percentage=100,
                                within_8_days_percentage=0,
                                beyond_8_days_percentage=0,
                            ), ),
                    )
                ],
            )
        ],
    )

    actual = calculate_practice_metrics_data(transfers, practice_list,
                                             time_range)

    assert actual == expected
def filter_conversations_by_request_started_time(
        conversations: Iterable[ParsedConversation],
        time_range: DateTimeRange) -> Iterator[ParsedConversation]:
    return (conversation for conversation in conversations
            if time_range.contains(conversation.request_started.time))