Files
Nonemm/tests/Nonemm.Session.Tests/AvailableStationsTests.cs
ericek111 1c118f9ce4 Lay the menu bar out the way N1MM lays it out, and fill in the Edit menu
The menu tree comes from N1MM's EntryWindow.Designer.cs: File, Edit, View,
Tools, Config, Window, with the items under the names N1MM gives them. The
window list moved out of View into Window; the call history file moved from
Config into File > Import. Ctrl+W, Ctrl+L and Ctrl+M now work, so the keys
printed in the menu are real. Two commands that had no menu item before:
the CW and SSB function key definitions, and the QTC setup area.

The rest of the Edit menu:

- Ctrl+N asks for a note and puts it in the comment of the contact in the
  boxes, or of the last logged contact when nothing is typed.
- Edit Current Contact opens the Edit Contact form over what is typed but
  not logged. Update hands the values back to the entry boxes.
- Ctrl+Q and Ctrl+A load a logged contact into the boxes and paint them
  pale yellow. Enter writes the change back, Esc puts back what was being
  typed, and stepping forward past the newest contact leaves quick edit.
- Ctrl+U raises the received serial, or a numeric exchange box when the
  contest has no serial.
- Ctrl+F shows the call being typed in the log window, then the next
  contact with that call.

RadioPosition is now OperatingPosition: it is the operator at one radio,
not a place on a band.

Looked at under Xvfb on a 3775-contact log: quick edit back and forward,
Esc, the note dialog, find, and Edit Current Contact putting a zone back
into the entry boxes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 12:18:37 +00:00

171 lines
5.8 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();
}
[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);
}
}