Warning screen, smarter license re-validation, version reporting
Warning screen - New reusable WarningPage (word-wrapped message, ENTER acknowledges and continues to the screen you were about to enter). - First use: pressing Play while the selected audio is still downloading. Dynamic Audio requires every file; a fixed track requires its own file. License re-validation - No longer re-verifies on every Home render. Checks now run only when the email/license key is entered or changed, on the manual option, at startup when already due, and hourly while valid. - Invalid + unchanged credentials are never re-checked (persisted pair). - Valid re-checks at most once per hour, anchored on a DB timestamp so an overdue check runs immediately after a power cycle. - New system_kv keys track the checked pair, outcome, and last-check time. - Added a System Settings row "Manually Validate License Key OK|Invalid" (OK green, Invalid red, label white) that runs a check immediately. Portal / local integration - License validation request now sends the app version as `appVersion`. - The entered license key is mirrored to ~/.local/radiantwave/license.txt. Misc - "Please connect to WiFi" only shows when no WiFi is joined AND the internet is unreachable (fixes the NetworkManager-missing and Ethernet cases). - Added unit tests for the audio-download warning, license scheduling policy, license request shape, and the new settings-menu entry.
This commit is contained in:
@@ -96,6 +96,41 @@ TEST(ApiClientTest, ParseLicenseJsonRejectsMalformed) {
|
||||
EXPECT_FALSE(parseLicenseJson(R"({"key":""})", info));
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, BuildLicenseRequestJsonIncludesVersionAndSystemName) {
|
||||
const std::string body = buildLicenseRequestJson(
|
||||
"ABCD-EFGH-IJKL-MNOP", "user@example.com", "Living Room", "1.2.3");
|
||||
|
||||
// Round-trips through the parser used for the request body shape.
|
||||
radiantwave::json::JsonValue root;
|
||||
ASSERT_TRUE(radiantwave::json::parseDocument(body, root));
|
||||
EXPECT_EQ(root.stringField("license_key"), "ABCD-EFGH-IJKL-MNOP");
|
||||
EXPECT_EQ(root.stringField("email_address"), "user@example.com");
|
||||
EXPECT_EQ(root.stringField("appVersion"), "1.2.3");
|
||||
EXPECT_EQ(root.stringField("systemName"), "Living Room");
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, BuildLicenseRequestJsonOmitsEmptyOptionalFields) {
|
||||
const std::string body =
|
||||
buildLicenseRequestJson("ABCD-EFGH-IJKL-MNOP", "user@example.com", "", "");
|
||||
|
||||
radiantwave::json::JsonValue root;
|
||||
ASSERT_TRUE(radiantwave::json::parseDocument(body, root));
|
||||
EXPECT_EQ(root.stringField("license_key"), "ABCD-EFGH-IJKL-MNOP");
|
||||
EXPECT_EQ(root.stringField("appVersion"), "");
|
||||
EXPECT_EQ(root.stringField("systemName"), "");
|
||||
EXPECT_EQ(root.find("appVersion"), nullptr);
|
||||
EXPECT_EQ(root.find("systemName"), nullptr);
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, BuildLicenseRequestJsonEscapesValues) {
|
||||
const std::string body =
|
||||
buildLicenseRequestJson("k\"ey", "a@b.com", "N\"ame", "1.0");
|
||||
radiantwave::json::JsonValue root;
|
||||
ASSERT_TRUE(radiantwave::json::parseDocument(body, root));
|
||||
EXPECT_EQ(root.stringField("license_key"), "k\"ey");
|
||||
EXPECT_EQ(root.stringField("systemName"), "N\"ame");
|
||||
}
|
||||
|
||||
TEST(ApiClientTest, ParseCreateAccountJson) {
|
||||
const std::string body =
|
||||
R"({"success":true,"message":"Account and license key created","user_id":"abc-123"})";
|
||||
|
||||
Reference in New Issue
Block a user