304 lines
9.2 KiB
C#
304 lines
9.2 KiB
C#
using Microsoft.Data.Sqlite;
|
|
using Scry.Core.Data;
|
|
using Scry.Core.Models;
|
|
using Xunit;
|
|
|
|
namespace Scry.Tests;
|
|
|
|
public class CardDatabaseTests : IDisposable
|
|
{
|
|
private readonly string _dbPath;
|
|
private readonly CardDatabase _database;
|
|
|
|
public CardDatabaseTests()
|
|
{
|
|
_dbPath = Path.Combine(Path.GetTempPath(), $"scry_test_{Guid.NewGuid()}.db");
|
|
_database = new CardDatabase(_dbPath);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InsertCard_ThenRetrieve_ReturnsMatch()
|
|
{
|
|
// First insert oracle and set (foreign keys)
|
|
var oracle = new Oracle
|
|
{
|
|
Id = "oracle-1",
|
|
Name = "Test Card",
|
|
ManaCost = "{1}{U}",
|
|
TypeLine = "Creature"
|
|
};
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set
|
|
{
|
|
Id = "set-1",
|
|
Code = "TST",
|
|
Name = "Test Set"
|
|
};
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var card = new Card
|
|
{
|
|
Id = "test-id",
|
|
OracleId = "oracle-1",
|
|
SetId = "set-1",
|
|
SetCode = "TST",
|
|
Name = "Test Card",
|
|
CollectorNumber = "1",
|
|
Hash = new byte[] { 0x01, 0x02, 0x03 },
|
|
ImageUri = "https://example.com/image.jpg"
|
|
};
|
|
|
|
await _database.InsertCardAsync(card);
|
|
var retrieved = await _database.GetCardByIdAsync("test-id");
|
|
|
|
Assert.NotNull(retrieved);
|
|
Assert.Equal("Test Card", retrieved.Name);
|
|
Assert.Equal("TST", retrieved.SetCode);
|
|
Assert.Equal(card.Hash, retrieved.Hash);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InsertCardBatch_InsertsAllCards()
|
|
{
|
|
// Insert oracle first
|
|
var oracle = new Oracle { Id = "oracle-batch", Name = "Batch Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set { Id = "set-batch", Code = "TST", Name = "Test Set" };
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var cards = Enumerable.Range(0, 100).Select(i => new Card
|
|
{
|
|
Id = $"card-{i}",
|
|
OracleId = "oracle-batch",
|
|
SetId = "set-batch",
|
|
SetCode = "TST",
|
|
Name = $"Card {i}",
|
|
Hash = new byte[] { (byte)i }
|
|
}).ToList();
|
|
|
|
await _database.InsertCardBatchAsync(cards);
|
|
var count = await _database.GetCardCountAsync();
|
|
|
|
Assert.Equal(100, count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetAllCards_ReturnsAllCards()
|
|
{
|
|
var oracle = new Oracle { Id = "oracle-all", Name = "All Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set { Id = "set-all", Code = "TST", Name = "Test Set" };
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var cards = Enumerable.Range(0, 10).Select(i => new Card
|
|
{
|
|
Id = $"card-{i}",
|
|
OracleId = "oracle-all",
|
|
SetId = "set-all",
|
|
SetCode = "TST",
|
|
Name = $"Card {i}",
|
|
Hash = new byte[] { (byte)i }
|
|
}).ToList();
|
|
|
|
await _database.InsertCardBatchAsync(cards);
|
|
var all = await _database.GetAllCardsAsync();
|
|
|
|
Assert.Equal(10, all.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetCardsByOracleId_ReturnsAllPrintings()
|
|
{
|
|
var oracle = new Oracle { Id = "oracle-multi", Name = "Multi Print Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set1 = new Set { Id = "set-1", Code = "S1", Name = "Set 1" };
|
|
var set2 = new Set { Id = "set-2", Code = "S2", Name = "Set 2" };
|
|
await _database.InsertSetAsync(set1);
|
|
await _database.InsertSetAsync(set2);
|
|
|
|
var cards = new[]
|
|
{
|
|
new Card { Id = "print-1", OracleId = "oracle-multi", SetId = "set-1", SetCode = "S1", Name = "Multi Print Card", Hash = new byte[] { 0x01 } },
|
|
new Card { Id = "print-2", OracleId = "oracle-multi", SetId = "set-2", SetCode = "S2", Name = "Multi Print Card", Hash = new byte[] { 0x02 } },
|
|
};
|
|
|
|
await _database.InsertCardBatchAsync(cards);
|
|
var printings = await _database.GetCardsByOracleIdAsync("oracle-multi");
|
|
|
|
Assert.Equal(2, printings.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Metadata_SetAndGet()
|
|
{
|
|
await _database.SetMetadataAsync("test_key", "test_value");
|
|
var value = await _database.GetMetadataAsync("test_key");
|
|
|
|
Assert.Equal("test_value", value);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClearCards_RemovesAllCards()
|
|
{
|
|
var oracle = new Oracle { Id = "oracle-clear", Name = "Clear Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set { Id = "set-clear", Code = "TST", Name = "Test Set" };
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var cards = Enumerable.Range(0, 10).Select(i => new Card
|
|
{
|
|
Id = $"card-{i}",
|
|
OracleId = "oracle-clear",
|
|
SetId = "set-clear",
|
|
SetCode = "TST",
|
|
Name = $"Card {i}",
|
|
Hash = new byte[] { (byte)i }
|
|
}).ToList();
|
|
|
|
await _database.InsertCardBatchAsync(cards);
|
|
await _database.ClearCardsAsync();
|
|
var count = await _database.GetCardCountAsync();
|
|
|
|
Assert.Equal(0, count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InsertCard_DuplicateId_Updates()
|
|
{
|
|
var oracle = new Oracle { Id = "oracle-dup", Name = "Dup Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set { Id = "set-dup", Code = "TST", Name = "Test Set" };
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var card1 = new Card
|
|
{
|
|
Id = "duplicate-id",
|
|
OracleId = "oracle-dup",
|
|
SetId = "set-dup",
|
|
SetCode = "TST",
|
|
Name = "Original Name",
|
|
Hash = new byte[] { 0x01 }
|
|
};
|
|
|
|
var card2 = new Card
|
|
{
|
|
Id = "duplicate-id",
|
|
OracleId = "oracle-dup",
|
|
SetId = "set-dup",
|
|
SetCode = "TST",
|
|
Name = "Updated Name",
|
|
Hash = new byte[] { 0x02 }
|
|
};
|
|
|
|
await _database.InsertCardAsync(card1);
|
|
await _database.InsertCardAsync(card2);
|
|
|
|
var retrieved = await _database.GetCardByIdAsync("duplicate-id");
|
|
|
|
Assert.NotNull(retrieved);
|
|
Assert.Equal("Updated Name", retrieved.Name);
|
|
Assert.Equal(new byte[] { 0x02 }, retrieved.Hash);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InsertOracle_ThenRetrieveByName()
|
|
{
|
|
var oracle = new Oracle
|
|
{
|
|
Id = "oracle-name",
|
|
Name = "Lightning Bolt",
|
|
ManaCost = "{R}",
|
|
Cmc = 1,
|
|
TypeLine = "Instant",
|
|
OracleText = "Lightning Bolt deals 3 damage to any target."
|
|
};
|
|
|
|
await _database.InsertOracleAsync(oracle);
|
|
var retrieved = await _database.GetOracleByNameAsync("Lightning Bolt");
|
|
|
|
Assert.NotNull(retrieved);
|
|
Assert.Equal("{R}", retrieved.ManaCost);
|
|
Assert.Equal(1, retrieved.Cmc);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task InsertSet_ThenRetrieveByCode()
|
|
{
|
|
var set = new Set
|
|
{
|
|
Id = "set-lea",
|
|
Code = "lea",
|
|
Name = "Limited Edition Alpha",
|
|
SetType = "expansion",
|
|
ReleasedAt = "1993-08-05",
|
|
CardCount = 295
|
|
};
|
|
|
|
await _database.InsertSetAsync(set);
|
|
var retrieved = await _database.GetSetByCodeAsync("lea");
|
|
|
|
Assert.NotNull(retrieved);
|
|
Assert.Equal("Limited Edition Alpha", retrieved.Name);
|
|
Assert.Equal(295, retrieved.CardCount);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetCardsWithHash_OnlyReturnsCardsWithHash()
|
|
{
|
|
var oracle = new Oracle { Id = "oracle-hash", Name = "Hash Card" };
|
|
await _database.InsertOracleAsync(oracle);
|
|
|
|
var set = new Set { Id = "set-hash", Code = "TST", Name = "Test Set" };
|
|
await _database.InsertSetAsync(set);
|
|
|
|
var cardWithHash = new Card
|
|
{
|
|
Id = "card-with-hash",
|
|
OracleId = "oracle-hash",
|
|
SetId = "set-hash",
|
|
SetCode = "TST",
|
|
Name = "Has Hash",
|
|
Hash = new byte[] { 0x01 }
|
|
};
|
|
|
|
var cardWithoutHash = new Card
|
|
{
|
|
Id = "card-no-hash",
|
|
OracleId = "oracle-hash",
|
|
SetId = "set-hash",
|
|
SetCode = "TST",
|
|
Name = "No Hash",
|
|
Hash = null
|
|
};
|
|
|
|
await _database.InsertCardAsync(cardWithHash);
|
|
await _database.InsertCardAsync(cardWithoutHash);
|
|
|
|
var cardsWithHash = await _database.GetCardsWithHashAsync();
|
|
|
|
Assert.Single(cardsWithHash);
|
|
Assert.Equal("card-with-hash", cardsWithHash[0].Id);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_database.Dispose();
|
|
SqliteConnection.ClearAllPools();
|
|
try
|
|
{
|
|
if (File.Exists(_dbPath))
|
|
{
|
|
File.Delete(_dbPath);
|
|
}
|
|
}
|
|
catch (IOException)
|
|
{
|
|
}
|
|
}
|
|
}
|