From d53628f8cc27838d13fa2c7789a41888b0534914 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 23 Jun 2026 19:30:05 -0400 Subject: [PATCH] import_viewer: round-trip ViewerMissionData scalars (mission_meta) --- .../Controllers/AdminController.cs | 12 +++++++ .../Requests/Admin/ImportViewerRequest.cs | 14 ++++++++ .../Controllers/AdminControllerTests.cs | 34 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/SVSim.EmulatedEntrypoint/Controllers/AdminController.cs b/SVSim.EmulatedEntrypoint/Controllers/AdminController.cs index 8b5c28c2..1bee862c 100644 --- a/SVSim.EmulatedEntrypoint/Controllers/AdminController.cs +++ b/SVSim.EmulatedEntrypoint/Controllers/AdminController.cs @@ -253,6 +253,18 @@ public class AdminController : SVSimController } } + // Pass A: MissionMeta scalars + if (request.MissionMeta is { } meta) + { + viewer.MissionData ??= new ViewerMissionData(); + if (meta.HasReceivedPickTwoMission is { } hrptm) + viewer.MissionData.HasReceivedPickTwoMission = hrptm; + if (meta.MissionReceiveType is { } mrt) + viewer.MissionData.MissionReceiveType = mrt; + if (meta.MissionChangeTime is { } mct) + viewer.MissionData.MissionChangeTime = DateTimeOffset.FromUnixTimeSeconds(mct).UtcDateTime; + } + await _dbContext.SaveChangesAsync(); if (skippedCardIds.Count > 0) diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/Admin/ImportViewerRequest.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/Admin/ImportViewerRequest.cs index 9f17994b..340ec114 100644 --- a/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/Admin/ImportViewerRequest.cs +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/Admin/ImportViewerRequest.cs @@ -33,6 +33,8 @@ public class ImportViewerRequest [JsonPropertyName("items")] public List? Items { get; set; } [JsonPropertyName("decks")] public List? Decks { get; set; } + + [JsonPropertyName("mission_meta")] public ImportMissionMeta? MissionMeta { get; set; } } public class ImportDeck @@ -78,3 +80,15 @@ public class ImportItem [JsonPropertyName("item_id")] public int ItemId { get; set; } [JsonPropertyName("count")] public int Count { get; set; } } + +public class ImportMissionMeta +{ + [JsonPropertyName("has_received_pick_two_mission")] + public bool? HasReceivedPickTwoMission { get; set; } + + [JsonPropertyName("mission_receive_type")] + public int? MissionReceiveType { get; set; } + + [JsonPropertyName("mission_change_time")] + public long? MissionChangeTime { get; set; } +} diff --git a/SVSim.UnitTests/Controllers/AdminControllerTests.cs b/SVSim.UnitTests/Controllers/AdminControllerTests.cs index 6c544fbf..b8051d7d 100644 --- a/SVSim.UnitTests/Controllers/AdminControllerTests.cs +++ b/SVSim.UnitTests/Controllers/AdminControllerTests.cs @@ -450,4 +450,38 @@ public class AdminControllerTests "Empty deck slots must be skipped; only the real (non-empty) deck imports."); Assert.That(stored.Decks.Single().Name, Is.EqualTo("Real")); } + + [Test] + public async Task ImportViewer_MissionMeta_RoundTrips() + { + using var factory = new SVSimTestFactory(); + var client = factory.CreateClient(); + ulong steamId = 70000000000000001UL; + + var resp = await client.PostAsJsonAsync("/admin/import_viewer", new ImportViewerRequest + { + SteamId = steamId, + MissionMeta = new ImportMissionMeta + { + HasReceivedPickTwoMission = true, + MissionReceiveType = 2, + MissionChangeTime = 1_700_000_000L + } + }); + resp.EnsureSuccessStatusCode(); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var viewer = await db.Viewers + .Include(v => v.MissionData) + .SingleAsync(v => v.SocialAccountConnections + .Any(s => s.AccountType == SocialAccountType.Steam && s.AccountId == steamId)); + + Assert.That(viewer.MissionData, Is.Not.Null); + Assert.That(viewer.MissionData!.HasReceivedPickTwoMission, Is.True); + Assert.That(viewer.MissionData.MissionReceiveType, Is.EqualTo(2)); + // MissionChangeTime is DateTime in storage; verify it survives the round-trip from unix seconds. + Assert.That(viewer.MissionData.MissionChangeTime, + Is.EqualTo(DateTimeOffset.FromUnixTimeSeconds(1_700_000_000L).UtcDateTime)); + } }