Files
Nonemm/tests/Nonemm.Session.Tests/AvailableStationsTests.cs
ericek111 9b84b103ac Add N1MM's Mark and Store buttons
Both put something on our own bandmap and nothing on the cluster, which is
what separates them from Spot It.

Mark, Alt+M, leaves a mark where the radio is to say the frequency is busy.
The label is N1MM's, Busy@ and the time. It is not a station, so Spot carries
IsStation: nothing judges it, the check window does not offer it as a call,
available mults and Qs leaves it out, space does not take it into the callsign
box, and the bandmap paints it like a station already worked, which is how
N1MM marks it. The station count under the bandmap counts stations.

Store, Alt+O, puts the call being typed on the bandmap at this frequency so it
can be worked later. N1MM writes "Local spot" in the comment and this does the
same.

The action row now holds the eight buttons N1MM has, in N1MM's order and at
N1MM's widths: 23 per cent to Esc: Stop and 11 to each of the rest.

Left out of Store: N1MM also adds the call to what the check window's Master
column offers for the rest of the session. The call is on the bandmap, which
the check window already reads, so it is offered either way.

Driven under Xvfb: Alt+M leaving BUSY@22:32:27 on 14000, Alt+O storing
SP9XYZ there, and both drawn on the bandmap in the worked colour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
2026-08-30 22:34:32 +00:00

181 lines
6.1 KiB
C#

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);
}
}