feat(import): import consumable item inventory
This commit is contained in:
@@ -163,6 +163,25 @@ public class AdminController : SVSimController
|
||||
}
|
||||
}
|
||||
|
||||
if (request.Items is not null)
|
||||
{
|
||||
var wanted = request.Items
|
||||
.GroupBy(i => i.ItemId)
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
var ids = wanted.Select(i => i.ItemId).ToList();
|
||||
var itemMaster = await _dbContext.Items
|
||||
.Where(i => ids.Contains(i.Id))
|
||||
.ToDictionaryAsync(i => i.Id);
|
||||
|
||||
viewer.Items.Clear();
|
||||
foreach (var i in wanted)
|
||||
{
|
||||
if (!itemMaster.TryGetValue(i.ItemId, out var item)) continue; // unknown master id
|
||||
viewer.Items.Add(new OwnedItemEntry { Item = item, Count = i.Count, Viewer = viewer });
|
||||
}
|
||||
}
|
||||
|
||||
// Clone the 8 starter decks into the viewer when freshly created — workaround for a
|
||||
// client-side NRE in the deck-edit menu (DeckListUI.IsVisibleCreateNewButton at
|
||||
// decompile Wizard/DeckListUI.cs:316 unconditionally reads `_deckGroup.DeckFormat`, but
|
||||
|
||||
@@ -28,6 +28,8 @@ public class ImportViewerRequest
|
||||
[JsonPropertyName("classes")] public List<ImportClassData>? Classes { get; set; }
|
||||
|
||||
[JsonPropertyName("owned_cards")] public List<ImportCard>? OwnedCards { get; set; }
|
||||
|
||||
[JsonPropertyName("items")] public List<ImportItem>? Items { get; set; }
|
||||
}
|
||||
|
||||
public class ImportCurrency
|
||||
@@ -50,3 +52,9 @@ public class ImportCard
|
||||
[JsonPropertyName("count")] public int Count { get; set; }
|
||||
[JsonPropertyName("is_protected")] public bool IsProtected { get; set; }
|
||||
}
|
||||
|
||||
public class ImportItem
|
||||
{
|
||||
[JsonPropertyName("item_id")] public int ItemId { get; set; }
|
||||
[JsonPropertyName("count")] public int Count { get; set; }
|
||||
}
|
||||
|
||||
@@ -195,4 +195,32 @@ public class AdminControllerTests
|
||||
Assert.That(stored.Cards.Select(c => c.Card.Id), Is.EquivalentTo(new[] { 10001002L }),
|
||||
"Full replace: the pre-seeded 10001001 must be gone, only 10001002 present.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ImportViewer_imports_items_and_replaces_existing()
|
||||
{
|
||||
using var factory = new SVSimTestFactory();
|
||||
const ulong steamId = 76_561_198_111_222_336UL;
|
||||
long viewerId = await factory.SeedViewerAsync(steamId: steamId);
|
||||
// Registers the ItemEntry master row (70001) and gives an initial owned count to be replaced.
|
||||
await factory.SeedOwnedItemAsync(viewerId, itemId: 70001, count: 1);
|
||||
|
||||
using var client = factory.CreateClient();
|
||||
var response = await client.PostAsJsonAsync("/admin/import_viewer", new ImportViewerRequest
|
||||
{
|
||||
SteamId = steamId,
|
||||
Items = new List<ImportItem>
|
||||
{
|
||||
new() { ItemId = 70001, Count = 5 },
|
||||
new() { ItemId = 88888, Count = 9 }, // unknown master id -> skipped silently
|
||||
}
|
||||
});
|
||||
|
||||
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK),
|
||||
await response.Content.ReadAsStringAsync());
|
||||
Assert.That(await factory.GetOwnedItemCountAsync(viewerId, 70001), Is.EqualTo(5),
|
||||
"Full replace: 70001 count updated to 5.");
|
||||
Assert.That(await factory.GetOwnedItemCountAsync(viewerId, 88888), Is.EqualTo(0),
|
||||
"Unknown item master id must not be inserted.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user