Files
wanderer/test/unit/tracking_utils_test.exs
2025-07-15 14:48:20 +02:00

350 lines
10 KiB
Elixir

# Test for the check_tracking_consistency function in WandererApp.Character.TrackingUtils
#
# This file can be run directly with:
# elixir test/unit/tracking_consistency_test.exs
#
# It doesn't require any database connections or external dependencies.
# Start ExUnit
ExUnit.start()
defmodule WandererApp.Character.TrackingConsistencyTest do
use ExUnit.Case
require Logger
import ExUnit.CaptureIO
# This is a copy of the function from TrackingUtils
def check_tracking_consistency(tracking_data) do
# Find any characters that are followed but not tracked
inconsistent_characters =
Enum.filter(tracking_data, fn data ->
data.followed && !data.tracked
end)
# Log a warning for each inconsistent character
Enum.each(inconsistent_characters, fn data ->
character = data.character
# Use IO.puts instead of Logger to avoid dependencies
eve_id = Map.get(character, :eve_id, "unknown")
name = Map.get(character, :name, "unknown")
IO.puts(
"WARNING: Inconsistent state detected: Character is followed but not tracked. Character ID: #{eve_id}, Name: #{name}"
)
end)
# Return the original tracking data
tracking_data
end
describe "check_tracking_consistency/1" do
test "logs a warning when a character is followed but not tracked" do
# Create test data with inconsistent state
tracking_data = [
%{
character: %{eve_id: "test-eve-id", name: "Test Character"},
tracked: false,
followed: true
}
]
# Call the function and capture output
output =
capture_io(fn ->
check_tracking_consistency(tracking_data)
end)
# Assert that the warning was logged
assert output =~ "Inconsistent state detected: Character is followed but not tracked"
assert output =~ "test-eve-id"
assert output =~ "Test Character"
end
test "does not log a warning when all followed characters are also tracked" do
# Create test data with consistent state
tracking_data = [
%{
character: %{eve_id: "test-eve-id", name: "Test Character"},
tracked: true,
followed: true
}
]
# Call the function and capture output
output =
capture_io(fn ->
check_tracking_consistency(tracking_data)
end)
# Assert that no warning was logged
refute output =~ "Inconsistent state detected"
end
test "does not log a warning when no characters are followed" do
# Create test data with no followed characters
tracking_data = [
%{
character: %{eve_id: "test-eve-id", name: "Test Character"},
tracked: true,
followed: false
}
]
# Call the function and capture output
output =
capture_io(fn ->
check_tracking_consistency(tracking_data)
end)
# Assert that no warning was logged
refute output =~ "Inconsistent state detected"
end
test "handles multiple characters with mixed states correctly" do
# Create test data with multiple characters in different states
tracking_data = [
%{
character: %{eve_id: "character-1", name: "Character 1"},
tracked: true,
followed: true
},
%{
character: %{eve_id: "character-2", name: "Character 2"},
tracked: false,
followed: true
},
%{
character: %{eve_id: "character-3", name: "Character 3"},
tracked: true,
followed: false
},
%{
character: %{eve_id: "character-4", name: "Character 4"},
tracked: false,
followed: false
}
]
# Call the function and capture output
output =
capture_io(fn ->
check_tracking_consistency(tracking_data)
end)
# Assert that only the inconsistent character triggered a warning
assert output =~ "Inconsistent state detected: Character is followed but not tracked"
assert output =~ "character-2"
assert output =~ "Character 2"
refute output =~ "character-1"
refute output =~ "character-3"
refute output =~ "character-4"
end
test "returns the original tracking data unchanged" do
# Create test data
tracking_data = [
%{
character: %{eve_id: "test-eve-id", name: "Test Character"},
tracked: false,
followed: true
}
]
# Call the function and get the result
result = check_tracking_consistency(tracking_data)
# Assert that the returned data is the same as the input data
assert result == tracking_data
end
test "handles empty tracking data without errors" do
# Create empty tracking data
tracking_data = []
# Call the function and capture output
output =
capture_io(fn ->
result = check_tracking_consistency(tracking_data)
# Assert that the returned data is the same as the input data
assert result == tracking_data
end)
# Assert that no warning was logged
refute output =~ "Inconsistent state detected"
end
test "handles multiple inconsistent characters correctly" do
# Create test data with multiple inconsistent characters
tracking_data = [
%{
character: %{eve_id: "character-1", name: "Character 1"},
tracked: false,
followed: true
},
%{
character: %{eve_id: "character-2", name: "Character 2"},
tracked: false,
followed: true
},
%{
character: %{eve_id: "character-3", name: "Character 3"},
tracked: true,
followed: true
}
]
# Call the function and capture output
output =
capture_io(fn ->
check_tracking_consistency(tracking_data)
end)
# Assert that warnings were logged for both inconsistent characters
assert output =~ "Character ID: character-1"
assert output =~ "Name: Character 1"
assert output =~ "Character ID: character-2"
assert output =~ "Name: Character 2"
refute output =~ "Character ID: character-3"
end
test "handles characters with missing fields gracefully" do
# Create test data with missing fields
tracking_data = [
%{
# Missing name
character: %{eve_id: "character-1"},
tracked: false,
followed: true
},
%{
# Missing eve_id
character: %{name: "Character 2"},
tracked: false,
followed: true
}
]
# Call the function and capture output
output =
capture_io(fn ->
result = check_tracking_consistency(tracking_data)
# Assert that the returned data is the same as the input data
assert result == tracking_data
end)
# Assert that warnings were logged with available information
assert output =~ "Character ID: character-1"
assert output =~ "Name: unknown"
assert output =~ "Character ID: unknown"
assert output =~ "Name: Character 2"
end
test "handles characters with nil tracked or followed values" do
# Create test data with nil values
tracking_data = [
%{
character: %{eve_id: "character-1", name: "Character 1"},
tracked: nil,
followed: true
},
%{
character: %{eve_id: "character-2", name: "Character 2"},
tracked: false,
followed: nil
}
]
# Call the function and capture output
output =
capture_io(fn ->
result = check_tracking_consistency(tracking_data)
# Assert that the returned data is the same as the input data
assert result == tracking_data
end)
# Assert that a warning was logged for the first character (nil tracked is treated as false)
assert output =~ "Character ID: character-1"
assert output =~ "Name: Character 1"
# No warning for the second character (nil followed is treated as false)
refute output =~ "Character ID: character-2"
end
test "handles malformed tracking data gracefully" do
# Create malformed tracking data (missing required fields)
tracking_data = [
%{
# Missing character field
tracked: false,
followed: true
}
]
# Call the function and capture output, expecting it to handle errors gracefully
assert_raise(KeyError, fn ->
check_tracking_consistency(tracking_data)
end)
end
end
# Additional tests for edge cases in the filter logic
describe "filter logic in check_tracking_consistency/1" do
test "correctly identifies characters that are followed but not tracked" do
# Create test data with various combinations
tracking_data = [
%{
character: %{eve_id: "char-1", name: "Character 1"},
tracked: false,
followed: true
},
%{
character: %{eve_id: "char-2", name: "Character 2"},
tracked: true,
followed: true
},
%{
character: %{eve_id: "char-3", name: "Character 3"},
tracked: false,
followed: false
},
%{
character: %{eve_id: "char-4", name: "Character 4"},
tracked: true,
followed: false
}
]
# Extract the filter logic from the function
inconsistent_characters =
Enum.filter(tracking_data, fn data ->
data.followed && !data.tracked
end)
# Assert that only the first character is identified as inconsistent
assert length(inconsistent_characters) == 1
assert hd(inconsistent_characters).character.eve_id == "char-1"
end
test "handles boolean-like values correctly in filter logic" do
# Create test data with various boolean-like values
tracking_data = [
%{
character: %{eve_id: "char-1", name: "Character 1"},
tracked: false,
# String instead of boolean - in Elixir, only false and nil are falsy
followed: "true"
}
]
# Extract the filter logic from the function
inconsistent_characters =
Enum.filter(tracking_data, fn data ->
data.followed && !data.tracked
end)
# Assert that the character is identified as inconsistent
# (since in Elixir, only false and nil are falsy, everything else is truthy)
assert length(inconsistent_characters) == 1
end
end
end