XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using Microsoft.Data.Sqlite;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Models;

namespace XFEEDToolBox.Test;

[TestFixture]
public class MarketSearchTests
{
    [Test]public async Task OptimizedQueriesPreserveDisplayAliasesLocationsSortingAndPages()
    {
        using var temporary=new TemporaryDirectory();var repository=temporary.Repository();var at=DateTimeOffset.UtcNow.AddMinutes(-1);
        var stations=new[]{Check.Station(1) with{SystemName="Alpha",Name="Homer Platform"},Check.Station(2) with{SystemName="Beta",Name="Watershed"},Check.Station(3) with{SystemName="Gamma",Name="Custom Port"}};
        foreach(var station in stations)
        {
            var quotes=new[]{Check.Quote(station.MarketId,"water",30+station.MarketId,20) with{DisplayName="Collector Gold Leaf",Supply=10+station.MarketId,Demand=40-station.MarketId},
                Check.Quote(station.MarketId,"gold",90-station.MarketId,70) with{DisplayName="Royal Auric",Supply=30-station.MarketId,Demand=10+station.MarketId},
                Check.Quote(station.MarketId,"customsymbol",40+station.MarketId,30) with{DisplayName="Uncatalogued Water Alias",Supply=5,Demand=9}};
            await repository.SaveSnapshotAsync(new(station,quotes,at.AddSeconds(station.MarketId),DataSource.Journal));
        }
        using var connection=new SqliteConnection(new SqliteConnectionStringBuilder{DataSource=repository.DatabasePath,Mode=SqliteOpenMode.ReadOnly}.ToString());connection.Open();
        foreach(var term in new[]{"gold","WATER","Homer","Gamma","custom","not-found","%","_","' OR 1=1 --"})
        foreach(var sort in Enum.GetValues<MarketSort>())foreach(long? station in new long?[]{null,1})
        {
            using var query=connection.CreateCommand();
            var order=sort switch{MarketSort.Newest=>"q.timestamp DESC",MarketSort.BuyDescending=>"q.buy DESC",MarketSort.SellDescending=>"q.sell DESC",MarketSort.SupplyDescending=>"q.supply DESC",MarketSort.DemandDescending=>"q.demand DESC",_=>"s.system,s.name,q.commodity"};
            query.CommandText=$"SELECT s.id,q.commodity FROM quotes q JOIN stations s ON s.id=q.station WHERE ($id IS NULL OR s.id=$id) AND(q.name LIKE $q OR q.commodity LIKE $q OR s.name LIKE $q OR s.system LIKE $q) ORDER BY {order},s.system,s.name,q.commodity";
            query.Parameters.AddWithValue("$id",(object?)station??DBNull.Value);query.Parameters.AddWithValue("$q","%"+term.Replace("%","").Replace("_","")+"%");
            var expected=new List<string>();using(var reader=query.ExecuteReader())while(reader.Read())expected.Add(reader.GetInt64(0)+":"+reader.GetString(1));
            foreach(var offset in new[]{0,1,4})
            {
                var actual=repository.Search(term,station,offset,2,sort).Select(row=>row.Station.MarketId+":"+row.Quote.Commodity);
                Check.Equal(string.Join('|',expected.Skip(offset).Take(2)),string.Join('|',actual));
            }
        }
    }
    [Test]public void PreCancelledSearchDoesNotOpenOrCreateADatabase()
    {
        using var temporary=new TemporaryDirectory();var path=Path.Combine(temporary.Path,"not-created.db");
        using var cancellation=new CancellationTokenSource();cancellation.Cancel();
        Check.Throws<OperationCanceledException>(()=>new MarketRepository(path).Search("water",null,token:cancellation.Token));
        Check.That(!File.Exists(path));
    }
    [Test]public void SearchOpensOnlyAnExistingReadOnlyDatabase()
    {
        using var temporary=new TemporaryDirectory();var path=Path.Combine(temporary.Path,"not-created.db");
        Check.Throws<SqliteException>(()=>new MarketRepository(path).Search("water",null));Check.That(!File.Exists(path));
    }
    [Test]public void NonpositiveSearchBudgetIsRejectedBeforeReading()
    {
        using var temporary=new TemporaryDirectory();var path=Path.Combine(temporary.Path,"not-created.db");
        Check.Throws<ArgumentOutOfRangeException>(()=>new MarketRepository(path).Search("water",null,budget:TimeSpan.Zero));Check.That(!File.Exists(path));
    }
}