Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions test/aggregates/aggregate_lifespan_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule Commanded.Aggregates.AggregateLifespanTest do

alias Commanded.Aggregates.{Aggregate, DefaultLifespanRouter, LifespanAggregate, LifespanRouter}
alias Commanded.Aggregates.LifespanAggregate.{Command, Event}
alias Commanded.TestSupport.Factory
alias Commanded.{DefaultApp, EventStore}
alias Commanded.EventStore.RecordedEvent
alias Commanded.{Registration, UUID}

describe "aggregate lifespan" do
Expand Down Expand Up @@ -375,11 +375,11 @@ defmodule Commanded.Aggregates.AggregateLifespanTest do
ref: ref
} do
events = [
%RecordedEvent{
event_id: UUID.uuid4(),
stream_version: 1,
data: %Event{uuid: aggregate_uuid}
}
Factory.build_recorded_event(
data: %Event{uuid: aggregate_uuid},
event_number: 1,
stream_version: 1
)
]

# Simulate sending an event directly to the aggregate process
Expand Down
22 changes: 5 additions & 17 deletions test/event_store/adapters/in_memory/in_memory_test.exs
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
defmodule Commanded.EventStore.Adapters.InMemoryTest do
use Commanded.EventStore.InMemoryTestCase

alias Commanded.EventStore.AdapterTestData
alias Commanded.EventStore.Adapters.InMemory
alias Commanded.EventStore.EventData
alias Commanded.UUID

defmodule BankAccountOpened do
@derive Jason.Encoder
defstruct [:account_number, :initial_balance]
end

describe "reset!/0" do
test "wipes all data from memory", %{event_store_meta: event_store_meta} do
Expand Down Expand Up @@ -45,17 +39,11 @@ defmodule Commanded.EventStore.Adapters.InMemoryTest do
end
end

defp build_event(account_number) do
%EventData{
causation_id: UUID.uuid4(),
correlation_id: UUID.uuid4(),
event_type: "#{__MODULE__}.BankAccountOpened",
data: %BankAccountOpened{account_number: account_number, initial_balance: 1_000},
metadata: %{"user_id" => "test"}
}
end
defp build_event(account_number),
do:
AdapterTestData.build_opened_events(1, start_account_number: account_number) |> List.first()

defp build_events(count) do
for account_number <- 1..count, do: build_event(account_number)
AdapterTestData.build_opened_events(count)
end
end
28 changes: 18 additions & 10 deletions test/event_store/recorded_event_test.exs
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
defmodule Commanded.EventStore.RecordedEventTest do
use ExUnit.Case

alias Commanded.EventStore.AdapterTestData
alias Commanded.EventStore.EnrichedMetadata
alias Commanded.EventStore.RecordedEvent
alias Commanded.Helpers.EventFactory

defmodule BankAccountOpened do
@derive Jason.Encoder
defstruct [:account_number, :initial_balance]
end

setup do
[event] =
EventFactory.map_to_recorded_events(
[
%BankAccountOpened{account_number: "123", initial_balance: 1_000}
],
AdapterTestData.build_recorded_events(
[AdapterTestData.build_opened_event(account_number: "123")],
1,
metadata: %{"key1" => "value1", "key2" => "value2"}
)
Expand Down Expand Up @@ -56,5 +49,20 @@ defmodule Commanded.EventStore.RecordedEventTest do
metadata: %{"key1" => "value1", "key2" => "value2"}
} = enriched_metadata
end

test "keeps explicit event ids when mapping recorded events" do
transfer_uuid = Commanded.UUID.uuid4()

[event] =
AdapterTestData.build_recorded_events([
AdapterTestData.build_deposited_event(
account_number: "123",
transfer_uuid: transfer_uuid
)
])

assert event.event_id == transfer_uuid
assert event.data.transfer_uuid == transfer_uuid
end
end
end
113 changes: 113 additions & 0 deletions test/event_store/support/adapter_test_data.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
defmodule Commanded.EventStore.AdapterTestData do
alias Commanded.Event.Mapper
alias Commanded.Helpers.EventFactory
alias Commanded.EventStore.SnapshotData
alias Commanded.EventStore.TypeProvider
alias Commanded.ExampleDomain.BankAccount
alias Commanded.ExampleDomain.BankAccount.Events.{BankAccountOpened, MoneyDeposited}
alias Commanded.UUID

def build_opened_event(opts \\ []) do
%BankAccountOpened{
account_number: Keyword.get(opts, :account_number, 1),
initial_balance: Keyword.get(opts, :initial_balance, 1_000)
}
end

def build_opened_event_data(opts \\ []) do
correlation_id = Keyword.get_lazy(opts, :correlation_id, &UUID.uuid4/0)
causation_id = Keyword.get_lazy(opts, :causation_id, &UUID.uuid4/0)
metadata = Keyword.get(opts, :metadata, default_metadata())

build_opened_event(opts)
|> Mapper.map_to_event_data(
correlation_id: correlation_id,
causation_id: causation_id,
metadata: metadata
)
end

def build_opened_events(count, opts \\ []) do
correlation_id = Keyword.get_lazy(opts, :correlation_id, &UUID.uuid4/0)
causation_id = Keyword.get_lazy(opts, :causation_id, &UUID.uuid4/0)
initial_balance = Keyword.get(opts, :initial_balance, 1_000)
metadata = Keyword.get(opts, :metadata, default_metadata())
start_account_number = Keyword.get(opts, :start_account_number, 1)

start_account_number..(start_account_number + count - 1)
|> Enum.map(fn account_number ->
build_opened_event(account_number: account_number, initial_balance: initial_balance)
end)
|> Mapper.map_to_event_data(
correlation_id: correlation_id,
causation_id: causation_id,
metadata: metadata
)
end

def build_deposited_event(opts \\ []) do
transfer_uuid = Keyword.get_lazy(opts, :transfer_uuid, &UUID.uuid4/0)

%MoneyDeposited{
account_number: Keyword.get(opts, :account_number, 1),
transfer_uuid: transfer_uuid,
amount: Keyword.get(opts, :amount, 250),
balance: Keyword.get(opts, :balance, 1_250)
}
end

def build_deposited_event_data(opts \\ []) do
correlation_id = Keyword.get_lazy(opts, :correlation_id, &UUID.uuid4/0)
causation_id = Keyword.get_lazy(opts, :causation_id, &UUID.uuid4/0)
metadata = Keyword.get(opts, :metadata, default_metadata())

build_deposited_event(opts)
|> Mapper.map_to_event_data(
correlation_id: correlation_id,
causation_id: causation_id,
metadata: metadata
)
end

def build_deposit_event(account_number, opts \\ []) do
build_deposited_event_data(Keyword.put(opts, :account_number, account_number))
end

def build_recorded_events(events, initial_event_number \\ 1, opts \\ []) do
EventFactory.map_to_recorded_events(events, initial_event_number, opts)
end

def build_snapshot_data(source_version, opts \\ []) do
created_at = Keyword.get(opts, :created_at, DateTime.utc_now())
metadata = Keyword.get(opts, :metadata, nil)
source_uuid = Keyword.get_lazy(opts, :source_uuid, &UUID.uuid4/0)

account_state =
Keyword.get_lazy(opts, :data, fn ->
%BankAccount{
account_number: Keyword.get(opts, :account_number, source_version),
state: :active,
balance: Keyword.get(opts, :balance, 1_000)
}
end)

%SnapshotData{
source_uuid: source_uuid,
source_version: source_version,
source_type: TypeProvider.to_string(account_state),
data: account_state,
metadata: metadata,
created_at: created_at
}
end

def default_metadata do
%{
"channel" => "web",
"request" => %{
"actor_id" => "customer-123",
"actor_type" => "customer"
}
}
end
end
59 changes: 40 additions & 19 deletions test/event_store/support/append_events_test_case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@ defmodule Commanded.EventStore.AppendEventsTestCase do
define_tests do
import Commanded.Enumerable, only: [pluck: 2]

alias Commanded.EventStore.EventData
alias Commanded.EventStore.AdapterTestData
alias Commanded.UUID

defmodule BankAccountOpened do
@derive Jason.Encoder
defstruct [:account_number, :initial_balance]
end

describe "event store adapter" do
test "should implement `Commanded.EventStore.Adapter` behaviour", %{
event_store: event_store
Expand Down Expand Up @@ -147,6 +142,35 @@ defmodule Commanded.EventStore.AppendEventsTestCase do

assert :ok == event_store.append_to_stream(event_store_meta, "stream", 3, build_events(1))
end

test "should preserve explicit event ids and reject duplicates across streams", %{
event_store: event_store,
event_store_meta: event_store_meta
} do
transfer_uuid = UUID.uuid4()

assert :ok ==
event_store.append_to_stream(
event_store_meta,
"stream-1",
0,
[build_deposit_event(101, transfer_uuid: transfer_uuid)]
)

[recorded_event] =
event_store.stream_forward(event_store_meta, "stream-1") |> Enum.to_list()

assert recorded_event.event_id == transfer_uuid
assert recorded_event.data.transfer_uuid == transfer_uuid

assert {:error, :duplicate_event} ==
event_store.append_to_stream(
event_store_meta,
"stream-2",
0,
[build_deposit_event(202, transfer_uuid: transfer_uuid)]
)
end
end

describe "stream events from an unknown stream" do
Expand Down Expand Up @@ -177,7 +201,7 @@ defmodule Commanded.EventStore.AppendEventsTestCase do
assert event.stream_id == "stream"
assert event.correlation_id == correlation_id
assert event.causation_id == causation_id
assert event.metadata == %{"metadata" => "value"}
assert event.metadata == AdapterTestData.default_metadata()
assert %DateTime{} = event.created_at
end)

Expand Down Expand Up @@ -225,21 +249,17 @@ defmodule Commanded.EventStore.AppendEventsTestCase do
end
end

defp build_event(account_number, correlation_id, causation_id) do
%EventData{
correlation_id: correlation_id,
causation_id: causation_id,
event_type: "#{__MODULE__}.BankAccountOpened",
data: %BankAccountOpened{account_number: account_number, initial_balance: 1_000},
metadata: %{"metadata" => "value"}
}
end

defp build_events(count, correlation_id \\ UUID.uuid4(), causation_id \\ UUID.uuid4())

defp build_events(count, correlation_id, causation_id) do
for account_number <- 1..count,
do: build_event(account_number, correlation_id, causation_id)
AdapterTestData.build_opened_events(count,
correlation_id: correlation_id,
causation_id: causation_id
)
end

defp build_deposit_event(account_number, opts) do
AdapterTestData.build_deposit_event(account_number, opts)
end

defp assert_is_uuid(uuid) do
Expand All @@ -259,6 +279,7 @@ defmodule Commanded.EventStore.AppendEventsTestCase do
&%{
causation_id: &1.causation_id,
correlation_id: &1.correlation_id,
event_type: &1.event_type,
data: &1.data,
metadata: &1.metadata
}
Expand Down
21 changes: 4 additions & 17 deletions test/event_store/support/event_store_prefix_test_case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@ defmodule Commanded.EventStore.EventStorePrefixTestCase do
import Commanded.SharedTestCase

define_tests do
alias Commanded.EventStore.EventData
alias Commanded.EventStore.AdapterTestData
alias Commanded.UUID

defmodule BankAccountOpened do
@derive Jason.Encoder
defstruct [:account_number, :initial_balance]
end

describe "event store prefix" do
setup do
{:ok, event_store_meta1} = start_event_store(name: :prefix1, prefix: "prefix1")
Expand All @@ -35,18 +30,10 @@ defmodule Commanded.EventStore.EventStorePrefixTestCase do
defp build_events(count, correlation_id \\ UUID.uuid4(), causation_id \\ UUID.uuid4())

defp build_events(count, correlation_id, causation_id) do
for account_number <- 1..count,
do: build_event(account_number, correlation_id, causation_id)
end

defp build_event(account_number, correlation_id, causation_id) do
%EventData{
AdapterTestData.build_opened_events(count,
correlation_id: correlation_id,
causation_id: causation_id,
event_type: "#{__MODULE__}.BankAccountOpened",
data: %BankAccountOpened{account_number: account_number, initial_balance: 1_000},
metadata: %{"metadata" => "value"}
}
causation_id: causation_id
)
end
end
end
Loading