Files
SVSimServer/SVSim.UnitTests/Repositories/ViewerRepositoryTutorialDefaultTests.cs
gamer147 1af0e03eeb fix(viewer): fresh signup defaults match prod tutorial capture
Three corrections to BuildDefaultViewer + RegisterAnonymousViewer
verified against data_dumps/traffic_prod_tutorial.ndjson:

- TutorialState now 1 (TUTORIAL_STEP0), not 0 (PRE_TUTORIAL_STEP).
  Wizard.Title.NextSceneSwitcher routes step==1 to the Prologue scene;
  any other non-{31,41,100} step routes to AreaSelect at section 0,
  which has no chapter data and crashes the client with a LINQ
  Single() "Sequence contains no matching element" from
  AreaSelectUI.SelectChapter. Prod's first /check/game_start returns
  now_tutorial_step="1"; step 0 is a pre-existence state we never
  want to expose on the wire.

- DisplayName " - " (literal space-dash-space), not "Player".
  Wizard.Title.UserNameInput.Start short-circuits with
  IsFinished=true on !string.IsNullOrEmpty(PlayerStaticData.UserName),
  silently skipping the name dialog AND the tutorial sub-step it
  drives (/tutorial/update_action #1 + /account/update_name). Prod
  uses " - " as the unset placeholder.

- viewer.Info.SelectedEmblem/SelectedDegree assigned from the default
  emblem/degree the loadout grants. Without this, /load/index emits
  selected_emblem_id=0 and selected_degree_id=0 for a fresh viewer
  that owns those cosmetics — prod sends the real granted IDs.

Also surfaces the actual Postgres constraint name in the unique-
violation re-raise (ExtractConstraintName), instead of always
saying "UDID" — the original message was misleading whenever the
real constraint was on owned-collection rows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 18:02:52 -04:00

29 lines
1.2 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using SVSim.Database;
using SVSim.Database.Repositories.Viewer;
using SVSim.UnitTests.Infrastructure;
namespace SVSim.UnitTests.Repositories;
public class ViewerRepositoryTutorialDefaultTests
{
[Test]
public async Task RegisterAnonymousViewer_starts_at_tutorial_step_1()
{
using var factory = new SVSimTestFactory();
using var scope = factory.Services.CreateScope();
var repo = scope.ServiceProvider.GetRequiredService<IViewerRepository>();
var viewer = await repo.RegisterAnonymousViewer(Guid.NewGuid());
Assert.That(viewer.MissionData.TutorialState, Is.EqualTo(1),
"Fresh signups start at TUTORIAL_STEP0=1 (matches the prod capture in " +
"traffic_prod_tutorial.ndjson where game_start returned now_tutorial_step=\"1\"). " +
"Step 0 (PRE_TUTORIAL_STEP) is a pre-existence state — NextSceneSwitcher would " +
"route it to AreaSelect at section 0, which has no chapter data and crashes the " +
"client. Tests that want a pre-completed tutorial should use SeedViewerAsync " +
"(which defaults to 100).");
}
}