Ctrl+O asks who is at the radio, as it does in N1MM, and the callsign goes on
every contact logged from then on. A multi-operator station changes hands every
few hours, so each operator also keeps what he wants the program to look like:
where the windows sit, the theme, and the folder his recordings are in.
The windows on the screen are stored against the operator leaving, before the
dialog opens, and the operator taking over gets his own back. A window he opens
later is placed as it appears. An operator who is new to the list starts with
whatever is on the screen.
Nothing plays the recordings yet, so the folder is stored and waits on voice
keying. {OPERATOR} in a message sends the callsign.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
136 lines
3.9 KiB
C#
136 lines
3.9 KiB
C#
using Nonemm.App.Configuration;
|
|
|
|
namespace Nonemm.App.Tests;
|
|
|
|
public class SettingsTests : IDisposable
|
|
{
|
|
private readonly string path = Path.Combine(Path.GetTempPath(), $"nonemm-{Guid.NewGuid():N}.json");
|
|
|
|
public void Dispose() => File.Delete(path);
|
|
|
|
private Settings Load(string json)
|
|
{
|
|
File.WriteAllText(path, json);
|
|
return Settings.Load(path);
|
|
}
|
|
|
|
[Fact]
|
|
public void AFileWithNullsInItReadsAsTheDefaults()
|
|
{
|
|
Settings settings = Load(
|
|
"""
|
|
{
|
|
"ClusterHost": null,
|
|
"ClusterCommands": null,
|
|
"ClusterNodes": null,
|
|
"TelnetButtons": null,
|
|
"SpotFilter": null,
|
|
"Radios": null,
|
|
"Station": null,
|
|
"CwMessages": null
|
|
}
|
|
""");
|
|
|
|
Assert.Equal("", settings.ClusterHost);
|
|
Assert.Empty(settings.ClusterCommands);
|
|
Assert.Empty(settings.ClusterNodes);
|
|
Assert.Empty(settings.TelnetButtons);
|
|
Assert.Empty(settings.SpotFilter.Bands);
|
|
Assert.Empty(settings.Radios);
|
|
Assert.Equal("", settings.Station.Callsign);
|
|
Assert.Empty(settings.CwMessages);
|
|
}
|
|
|
|
[Fact]
|
|
public void ANullInsideAStoredNodeIsFilledInToo()
|
|
{
|
|
Settings settings = Load(
|
|
"""
|
|
{
|
|
"ClusterNodes": [ { "Name": null, "Host": "dxc.example.net", "Commands": null } ]
|
|
}
|
|
""");
|
|
|
|
StoredClusterNode node = Assert.Single(settings.ClusterNodes);
|
|
Assert.Equal("", node.Name);
|
|
Assert.Empty(node.Commands);
|
|
}
|
|
|
|
[Fact]
|
|
public void WhatTheFileSaysIsKept()
|
|
{
|
|
Settings settings = Load("""{ "ClusterHost": "dxc.example.net", "ClusterPort": 7300 }""");
|
|
|
|
Assert.Equal("dxc.example.net", settings.ClusterHost);
|
|
Assert.Equal(7300, settings.ClusterPort);
|
|
}
|
|
|
|
[Fact]
|
|
public void TheTwelveMessagesAnOlderFileHoldsBecomeAFunctionKeyFile()
|
|
{
|
|
Settings settings = Load(
|
|
"""
|
|
{
|
|
"CwMessages": [ "CQ TEST {MYCALL}", "5NN {EXCH}" ]
|
|
}
|
|
""");
|
|
|
|
Assert.Empty(settings.CwMessages);
|
|
Assert.Equal("F1 CQ,CQ TEST {MYCALL}\nF2 Exch,5NN {EXCH}", settings.CwMessageFile);
|
|
}
|
|
|
|
[Fact]
|
|
public void AFileTextThatIsAlreadyThereIsLeftAlone()
|
|
{
|
|
Settings settings = Load(
|
|
"""
|
|
{
|
|
"CwMessageFile": "F1 CQ,CQ",
|
|
"CwMessages": [ "old" ]
|
|
}
|
|
""");
|
|
|
|
Assert.Equal("F1 CQ,CQ", settings.CwMessageFile);
|
|
}
|
|
|
|
/// An operator's windows and colours survive a trip through the file, and a
|
|
/// file written before operators existed reads as a station with none.
|
|
[Fact]
|
|
public void OperatorsAreStoredAndReadBack()
|
|
{
|
|
Settings settings = new()
|
|
{
|
|
CurrentOperator = "OM3KFF",
|
|
Operators =
|
|
[
|
|
new StoredOperator
|
|
{
|
|
Callsign = "OM3KFF",
|
|
Theme = "dark",
|
|
WavPath = "/home/erik/wav/om3kff",
|
|
Windows = [new StoredWindow { Name = "BandmapWindow", X = 10, Y = 20, Width = 300, Height = 400 }],
|
|
},
|
|
],
|
|
};
|
|
settings.Save(path);
|
|
|
|
Settings read = Settings.Load(path);
|
|
|
|
StoredOperator stored = Assert.Single(read.Operators);
|
|
Assert.Equal("OM3KFF", read.CurrentOperator);
|
|
Assert.Equal("dark", stored.Theme);
|
|
Assert.Equal("/home/erik/wav/om3kff", stored.WavPath);
|
|
StoredWindow window = Assert.Single(stored.Windows);
|
|
Assert.Equal(("BandmapWindow", 10, 20), (window.Name, window.X, window.Y));
|
|
}
|
|
|
|
[Fact]
|
|
public void AFileFromBeforeOperatorsHasNone()
|
|
{
|
|
Settings read = Load("""{ "Theme": "light" }""");
|
|
|
|
Assert.Empty(read.Operators);
|
|
Assert.Equal("", read.CurrentOperator);
|
|
}
|
|
}
|