using Nonemm.Contests; using Nonemm.Contests.Rules; using Nonemm.Core; using Nonemm.Core.Calls; using Nonemm.Core.Country; using Nonemm.Storage; namespace Nonemm.Session.Tests; public class StationPathTests { private static readonly DateTime Now = new(2026, 8, 28, 12, 0, 0, DateTimeKind.Utc); /// Two entities far enough apart to check a heading against a map. private static readonly CountryFile Countries = CountryFile.Parse( """ Slovak Republic: 15: 28: EU: 48.67: -19.50: -1.0: OM: OM; Japan: 25: 45: AS: 36.40: -138.38: -9.0: JA: JA; """); private static RadioPosition Session(string myGrid = "", CallHistory? history = null) { FakeLogStore store = new(); ContestInstance instance = store.AddContest(new ContestInstance { ContestNumber = 0, ContestName = "CQWW", SentExchange = "15", }); return new RadioPosition(new ContestSession( store, new CqWorldWide(ModeCategory.Cw), instance, new StationInfo { Callsign = "OM5M", CqZone = 15, GridSquare = myGrid }, Countries, history)); } [Fact] public void WithNothingInTheCallsignBoxThereIsNoPath() => Assert.Null(StationPath.For(Session(), Now)); [Fact] public void TheCountryFilePlacesAStationWhoseGridIsNotKnown() { RadioPosition session = Session(); session.Entry.Call = "JA1XYZ"; StationPath path = Assert.IsType(StationPath.For(session, Now)); // Slovakia to Japan is a little north of east, about nine thousand km Assert.InRange(path.Heading, 40, 60); Assert.InRange(path.DistanceKm, 8_500, 9_500); Assert.Equal((path.Heading + 180) % 360, path.LongPath); } [Fact] public void AGridFromTheCallHistoryBeatsTheCountryFile() { RadioPosition known = Session( myGrid: "JN88", history: CallHistory.Parse("!!Order!!,Call,LOC1\nJA1XYZ,PM95")); known.Entry.Call = "JA1XYZ"; RadioPosition unknown = Session(myGrid: "JN88"); unknown.Entry.Call = "JA1XYZ"; StationPath fromGrid = Assert.IsType(StationPath.For(known, Now)); StationPath fromCountry = Assert.IsType(StationPath.For(unknown, Now)); Assert.NotEqual(Math.Round(fromGrid.DistanceKm), Math.Round(fromCountry.DistanceKm)); Assert.InRange(fromGrid.DistanceKm, 9_000, 9_600); } [Fact] public void TheSunTimesAreTheOtherStationsOwn() { RadioPosition session = Session(); session.Entry.Call = "JA1XYZ"; StationPath path = Assert.IsType(StationPath.For(session, Now)); // Japan is nine hours ahead, so the sun rises there late the evening // before, in UTC, and sets in the morning Assert.Equal(20, Assert.IsType(path.Sunrise).Hour); Assert.Equal(9, Assert.IsType(path.Sunset).Hour); } }