# Path: tests/pgshovel/streams/fixtures.py
# DEFAULT_PUBLISHER = uuid.uuid1().bytes
# def reserialize(message):
# def copy(message, **replacements):
# def make_message(payload, sequence=1, publisher=DEFAULT_PUBLISHER):
# def make_messages(payloads, publisher=DEFAULT_PUBLISHER):
# def make_batch_messages(batch_identifier, payloads, **kwargs):
# def transactions():
# def message():


import itertools
import uuid
import pytest
from collections import namedtuple
from pgshovel.interfaces.streams_pb2 import (
    Message,
    RollbackOperation,
)
from pgshovel.replication.validation.transactions import (
    Committed,
    InTransaction,
    InvalidBatch,
    InvalidEventError,
    InvalidPublisher,
    RolledBack,
    StatefulStreamValidator,
    get_operation,
    require_batch_id_advanced_if_same_node,
    require_batch_id_not_advanced_if_same_node,
    require_different_publisher,
    require_same_batch,
    require_same_publisher,
    validate_transaction_state,
)
from pgshovel.utilities.protobuf import get_oneof_value
from tests.pgshovel.streams.fixtures import (
    batch_identifier,
    begin,
    commit,
    copy,
    make_batch_messages,
    message,
    mutation,
    reserialize,
)
    with pytest.raises(InvalidEventError):
        validator(None, 0, message)


def test_adds_expected_events_to_exception_for_unknown_event_for_state(message):
    receivers = {None: {RollbackOperation: 3}}
    validator = StatefulStreamValidator(lambda **kwargs: None, receivers)

    with pytest.raises(InvalidEventError) as exception:
        validator(None, 0, message)

    assert exception.value.expected == {RollbackOperation}


def test_successful_transaction():
    messages = list(make_batch_messages(batch_identifier, [
        {'begin_operation': begin},
        {'mutation_operation': mutation},
        {'commit_operation': commit},
    ]))

    state = None

    state = reserialize(validate_transaction_state(state, 0, messages[0]))
    assert get_oneof_value(state, 'state') == (
        InTransaction(
            publisher=messages[0].header.publisher,
            batch_identifier=batch_identifier
        )
    )

# Path: tests/pgshovel/streams/fixtures.py
# DEFAULT_PUBLISHER = uuid.uuid1().bytes
# def reserialize(message):
# def copy(message, **replacements):
# def make_message(payload, sequence=1, publisher=DEFAULT_PUBLISHER):
# def make_messages(payloads, publisher=DEFAULT_PUBLISHER):
# def make_batch_messages(batch_identifier, payloads, **kwargs):
# def transactions():
# def message():


# Path: tests/pgshovel/streams/states.py
import itertools
import uuid
import pytest
from collections import namedtuple
from pgshovel.interfaces.streams_pb2 import (
    Message,
    RollbackOperation,
)
from pgshovel.replication.validation.transactions import (
    Committed,
    InTransaction,
    InvalidBatch,
    InvalidEventError,
    InvalidPublisher,
    RolledBack,
    StatefulStreamValidator,
    get_operation,
    require_batch_id_advanced_if_same_node,
    require_batch_id_not_advanced_if_same_node,
    require_different_publisher,
    require_same_batch,
    require_same_publisher,
    validate_transaction_state,
)
from pgshovel.utilities.protobuf import get_oneof_value
from tests.pgshovel.streams.fixtures import (
    batch_identifier,
    begin,
    commit,
    copy,
    make_batch_messages,
    message,
    mutation,
    reserialize,
)

    with pytest.raises(InvalidEventError):
        validator(None, 0, message)


def test_adds_expected_events_to_exception_for_unknown_event_for_state(message):
    receivers = {None: {RollbackOperation: 3}}
    validator = StatefulStreamValidator(lambda **kwargs: None, receivers)

    with pytest.raises(InvalidEventError) as exception:
        validator(None, 0, message)

    assert exception.value.expected == {RollbackOperation}


def test_successful_transaction():
    messages = list(make_batch_messages(batch_identifier, [
        {'begin_operation': begin},
        {'mutation_operation': mutation},
        {'commit_operation': commit},
    ]))

    state = None

    state = reserialize(validate_transaction_state(state, 0, messages[0]))
    assert get_oneof_value(state, 'state') == (
        InTransaction(
            publisher=messages[0].header.publisher,
            batch_identifier=batch_identifier
        )
    )

    state = reserialize(validate_transaction_state(state, 1, messages[1]))