using Nonemm.Contests; using Nonemm.Contests.Rules; using Nonemm.Core; using Nonemm.Core.Calls; using Nonemm.Core.Country; using Nonemm.Spotting; using Nonemm.Storage; namespace Nonemm.Session.Tests; public class AvailableStationsTests { private const string Countries = """ Germany: 14: 28: EU: 51.00: -10.00: -1.0: DL: DL,DK,DJ; Japan: 25: 45: AS: 36.40: -138.38: -9.0: JA: JA,JH,JR; United States: 05: 08: NA: 37.53: 91.67: 5.0: K: K,W,N; """; private static readonly StationInfo Me = new() { Callsign = "DL1ABC", CqZone = 14, ItuZone = 28, Continent = "EU", CountryPrefix = "DL", }; private static readonly Frequency On20 = Frequency.FromKilohertz(14_030); private static (OperatingPosition Position, Bandmap Bandmap, AvailableStations Available) Station( Contest? contest = null, CallHistory? history = null) { FakeLogStore store = new(); ContestInstance instance = store.AddContest(new ContestInstance { ContestNumber = 0, ContestName = "CQWW", }); ContestSession session = new( store, contest ?? new CqWorldWide(ModeCategory.Cw), instance, Me, CountryFile.Parse(Countries), history); OperatingPosition position = new(session); Bandmap bandmap = new(); return (position, bandmap, new AvailableStations(position, bandmap)); } private static Spot At(string call, Frequency where) => new(Callsign.Parse(call), where, DateTime.UtcNow, SpotSource.Cluster, "OK1TEST"); private static void Work(OperatingPosition position, string call, string zone, Frequency where) { position.Tune(where); position.Entry.Call = call; position.Entry.Set(ExchangeSlot.ReceivedReport, "599"); position.Entry.Set(ExchangeSlot.Zone, zone); position.LogContact(); } /// A mark saying a frequency is busy is not a station to work. [Fact] public void AMarkIsNotOffered() { (_, Bandmap bandmap, AvailableStations available) = Station(); bandmap.Add(Spot.Mark(On20, DateTime.UtcNow)); Assert.Empty(available.All()); } [Fact] public void ASpottedStationThatIsANewCountryIsAMultiplier() { (_, Bandmap bandmap, AvailableStations available) = Station(); bandmap.Add(At("JA1XYZ", On20)); AvailableStation station = Assert.Single(available.All()); Assert.True(station.IsMultiplier); Assert.Equal(Bands.Band20M, station.Band); Assert.Equal("JA", station.MultiplierText); } /// CQ WW counts the zone the station sends, not the one the country file /// guesses, and a spot carries no exchange. So the zone shows only where /// the call history file published it. [Fact] public void TheCallHistoryZoneBringsInTheZoneMultiplier() { CallHistory history = CallHistory.Parse(""" !!Order!!,Call,CQZone JA1XYZ,25 """); (_, Bandmap bandmap, AvailableStations available) = Station(history: history); bandmap.Add(At("JA1XYZ", On20)); AvailableStation station = Assert.Single(available.All()); Assert.Equal("25, JA", station.MultiplierText); } [Fact] public void AStationAlreadyWorkedOnThatBandIsLeftOut() { (OperatingPosition position, Bandmap bandmap, AvailableStations available) = Station(); Work(position, "JA1XYZ", "25", On20); bandmap.Add(At("JA1XYZ", On20)); Assert.Empty(available.All()); } [Fact] public void TheSameStationOnAnotherBandIsStillWorthWorking() { (OperatingPosition position, Bandmap bandmap, AvailableStations available) = Station(); Work(position, "JA1XYZ", "25", On20); bandmap.Add(At("JA1XYZ", Frequency.FromKilohertz(7_030))); AvailableStation station = Assert.Single(available.All()); Assert.Equal(Bands.Band40M, station.Band); Assert.True(station.IsMultiplier); } [Fact] public void AStationThatBringsNoMultiplierIsStillOfferedForItsPoints() { (OperatingPosition position, Bandmap bandmap, AvailableStations available) = Station(); Work(position, "JA1XYZ", "25", On20); bandmap.Add(At("JA2ABC", On20)); AvailableStation station = Assert.Single(available.All()); Assert.False(station.IsMultiplier); Assert.True(station.Verdict.Points > 0); } [Fact] public void MultipliersComeFirst() { (OperatingPosition position, Bandmap bandmap, AvailableStations available) = Station(); Work(position, "JA1XYZ", "25", On20); bandmap.Add(At("JA2ABC", Frequency.FromKilohertz(14_010))); bandmap.Add(At("W1AW", Frequency.FromKilohertz(14_040))); Assert.Equal( ["W1AW", "JA2ABC"], available.All().Select(s => s.Spot.Call.Text).ToList()); } /// A spot carries no exchange, so a section contest can only judge a /// spotted station where the call history file says what it sends. [Fact] public void TheCallHistoryFillsTheExchangeOfASpottedStation() { CallHistory history = CallHistory.Parse(""" !!Order!!,Call,Sect W1AW,CT """); (_, Bandmap bandmap, AvailableStations available) = Station(new Sweepstakes(ModeCategory.Cw), history); bandmap.Add(At("W1AW", Frequency.FromKilohertz(14_080))); AvailableStation station = Assert.Single(available.All()); Assert.True(station.IsMultiplier); Assert.Equal("CT", station.MultiplierText); } [Fact] public void WithNoCallHistoryASpottedStationOfASectionContestIsJustPoints() { (_, Bandmap bandmap, AvailableStations available) = Station(new Sweepstakes(ModeCategory.Cw)); bandmap.Add(At("W1AW", Frequency.FromKilohertz(14_080))); AvailableStation station = Assert.Single(available.All()); Assert.False(station.IsMultiplier); } }