| 1 | using System.Text.Json; |
| 2 | using CascadeIDE.Cockpit; |
| 3 | using CascadeIDE.Cockpit.Cds; |
| 4 | using CascadeIDE.Cockpit.Composition.HostSurface; |
| 5 | using CascadeIDE.ViewModels; |
| 6 | using Xunit; |
| 7 | |
| 8 | namespace CascadeIDE.Tests; |
| 9 | |
| 10 | public sealed class CockpitSurfaceSnapshotBuilderTests |
| 11 | { |
| 12 | [Fact] |
| 13 | public void Build_sets_schema_0_3_and_maps_surface_kind_docked_grid_by_default() |
| 14 | { |
| 15 | var vm = new MainWindowViewModel(); |
| 16 | var state = CockpitSurfaceSnapshotBuilder.Build(vm); |
| 17 | |
| 18 | Assert.Equal(CockpitSurfaceSnapshotBuilder.CurrentSchemaVersion, state.SchemaVersion); |
| 19 | Assert.False(string.IsNullOrWhiteSpace(state.UiMode)); |
| 20 | Assert.Equal("main_window_docked_grid", state.Topology.SurfaceKind); |
| 21 | Assert.False(state.Topology.MfdHostWindowOpen); |
| 22 | Assert.False(state.Topology.PfdHostWindowOpen); |
| 23 | Assert.True(state.Zones.ForwardVisible); |
| 24 | var pfdCount = state.Instruments.Count(x => x.SlotId == CockpitSlotIds.Pfd); |
| 25 | var mfdCount = state.Instruments.Count(x => x.SlotId == CockpitSlotIds.Mfd); |
| 26 | Assert.True(pfdCount <= 1 && mfdCount <= 1); |
| 27 | Assert.Equal(state.Zones.PfdVisible ? 1 : 0, pfdCount); |
| 28 | Assert.Equal(state.Zones.MfdVisible ? 1 : 0, mfdCount); |
| 29 | if (pfdCount == 1) |
| 30 | { |
| 31 | Assert.Contains( |
| 32 | state.Instruments, |
| 33 | x => x.InstrumentId == CockpitStandardInstrumentIds.WorkspaceNavigationMap && x.SlotId == CockpitSlotIds.Pfd); |
| 34 | } |
| 35 | |
| 36 | Assert.Equal(vm.EffectivePresentationLine, state.PresentationEffectiveLine); |
| 37 | } |
| 38 | |
| 39 | [Fact] |
| 40 | public void Json_roundtrip_preserves_contract_property_names() |
| 41 | { |
| 42 | var state = new CockpitSurfaceState( |
| 43 | SchemaVersion: "0.2", |
| 44 | UiMode: "Flight", |
| 45 | PresentationEffectiveLine: "(PFD|Forward|MFD)", |
| 46 | PresentationParseSuccess: true, |
| 47 | Topology: new CockpitSurfaceTopology( |
| 48 | "main_window_docked_grid", |
| 49 | MfdHostWindowOpen: false, |
| 50 | PfdHostWindowOpen: false, |
| 51 | MfdColumnVisibleInMain: true), |
| 52 | MfdShell: new CockpitSurfaceMfdShell("Terminal"), |
| 53 | Zones: new CockpitSurfaceZones( |
| 54 | PfdVisible: true, |
| 55 | ForwardVisible: true, |
| 56 | MfdVisible: true, |
| 57 | PfdRequiredByPresentation: true, |
| 58 | ForwardRequiredByPresentation: true, |
| 59 | MfdRequiredByPresentation: true), |
| 60 | Instruments: |
| 61 | [ |
| 62 | new CockpitSurfaceInstrument("solution_explorer_tree", "pfd", "0.2"), |
| 63 | ]); |
| 64 | |
| 65 | var json = JsonSerializer.Serialize(state); |
| 66 | Assert.Contains("\"schema_version\":\"0.2\"", json); |
| 67 | Assert.Contains("\"ui_mode\":\"Flight\"", json); |
| 68 | Assert.Contains("\"presentation_effective_line\"", json); |
| 69 | Assert.Contains("\"surface_kind\":\"main_window_docked_grid\"", json); |
| 70 | Assert.Contains("\"mfd_host_window_open\":false", json); |
| 71 | Assert.Contains("\"pfd_host_window_open\":false", json); |
| 72 | Assert.Contains("\"current_page\":\"Terminal\"", json); |
| 73 | Assert.Contains("\"pfd_visible\":true", json); |
| 74 | Assert.Contains("\"forward_visible\":true", json); |
| 75 | Assert.Contains("\"mfd_visible\":true", json); |
| 76 | Assert.Contains("\"pfd_required_by_presentation\":true", json); |
| 77 | Assert.Contains("\"forward_required_by_presentation\":true", json); |
| 78 | Assert.Contains("\"mfd_required_by_presentation\":true", json); |
| 79 | Assert.Contains("\"instruments\":[", json); |
| 80 | Assert.Contains("\"instrument_id\":\"solution_explorer_tree\"", json); |
| 81 | Assert.Contains("\"slot_id\":\"pfd\"", json); |
| 82 | |
| 83 | var back = JsonSerializer.Deserialize<CockpitSurfaceState>(json); |
| 84 | Assert.NotNull(back); |
| 85 | Assert.Equal("0.2", back!.SchemaVersion); |
| 86 | Assert.Equal("Terminal", back.MfdShell.CurrentPage); |
| 87 | Assert.Single(back.Instruments); |
| 88 | } |
| 89 | |
| 90 | /// <summary> |
| 91 | /// Паритет MCP <c>ide_get_ide_state</c> с CDS: вложенный объект сериализуется так же, как отдельный снимок. |
| 92 | /// </summary> |
| 93 | [Fact] |
| 94 | public void Workspace_state_shape_serializes_cockpit_surface_like_standalone_snapshot() |
| 95 | { |
| 96 | var vm = new MainWindowViewModel(); |
| 97 | var cockpit = vm.BuildCockpitSurfaceSnapshot(); |
| 98 | var wrapped = new { cockpit_surface = cockpit }; |
| 99 | var json = JsonSerializer.Serialize(wrapped); |
| 100 | using var doc = JsonDocument.Parse(json); |
| 101 | Assert.True(doc.RootElement.TryGetProperty("cockpit_surface", out var el)); |
| 102 | var roundtrip = JsonSerializer.Deserialize<CockpitSurfaceState>(el.GetRawText()); |
| 103 | Assert.NotNull(roundtrip); |
| 104 | Assert.Equal(cockpit.SchemaVersion, roundtrip!.SchemaVersion); |
| 105 | Assert.Equal(JsonSerializer.Serialize(cockpit), JsonSerializer.Serialize(roundtrip)); |
| 106 | } |
| 107 | } |
| 108 | |