File size: 4,036 Bytes
9de795a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";
import type { KatalogItem, Placement, Room } from "./api";
import { loeseFlaechen2D } from "./flaechen2d";
import { Viewer2D } from "./Viewer2D.tsx";

// Minimaler 3.0×2.4-Raum mit einer Tür – nur die von Viewer2D gelesenen Felder.
const room = {
  shell: {
    walls: [
      { id: "w1", start: [0, 0], end: [3, 0], kind: "massiv", openings: ["d1"] },
      { id: "w2", start: [3, 0], end: [3, 2.4], kind: "massiv", openings: [] },
      { id: "w3", start: [3, 2.4], end: [0, 2.4], kind: "massiv", openings: [] },
      { id: "w4", start: [0, 2.4], end: [0, 0], kind: "massiv", openings: [] },
    ],
    floor: {
      polygon: [
        [0, 0],
        [3, 0],
        [3, 2.4],
        [0, 2.4],
      ],
    },
  },
  openings: [{ id: "d1", type: "door", hostWall: "w1", offset: 1.9, width: 0.8 }],
} as unknown as Room;

const catalog = [
  {
    id: "c1",
    funktionsTyp: "wc",
    masse: { w: 0.4, d: 0.6, h: 0.4 },
    mount: "boden",
    priorityClass: "P1",
  },
] as unknown as KatalogItem[];

const placements: Placement[] = [
  {
    id: "p1",
    catalogItemId: "c1",
    pose: { pos: [1.5, 1.2], yawDeg: 0 },
    gewerk: "sanitaer",
    locked: false,
    source: "solver",
  },
];

describe("Viewer2D (Render-Smoke)", () => {
  it("rendert Hülle, Wände, Footprint, Label und die Norm-Status-Farbe", () => {
    const html = renderToStaticMarkup(
      <Viewer2D
        room={room}
        placements={placements}
        catalog={catalog}
        gewaehltId={null}
        statusById={new Map([["p1", "verletzt"]])}
        onSelect={() => {}}
      />,
    );
    expect(html).toContain("<svg");
    expect(html).toContain("<line"); // Wände
    expect(html).toContain("<polygon"); // Boden + Footprint
    expect(html).toContain("wc"); // Label des Objekts
    expect(html).toContain("#c0392b"); // «verletzt»-Farbe angewendet
  });

  it("ohne Plan keine Footprints, aber die Hülle steht", () => {
    const html = renderToStaticMarkup(
      <Viewer2D
        room={room}
        placements={[]}
        catalog={catalog}
        gewaehltId={null}
        statusById={new Map()}
        onSelect={() => {}}
      />,
    );
    expect(html).toContain("<polygon"); // Bodenfläche
    expect(html).not.toContain("wc");
  });
});

describe("Viewer2D – Flächen-Layer + Einzelwand-Highlight (Welle C)", () => {
  const basis = {
    room,
    placements: [] as Placement[],
    catalog,
    gewaehltId: null,
    statusById: new Map<string, "verletzt" | "knapp">(),
    onSelect: () => {},
  };
  const flaechen2d = loeseFlaechen2D(
    "bad",
    null,
    null,
    {
      boden: { material: "fliesen-anthrazit" },
      waende: [{ wandIndex: 1, material: "fliesen-gruen", bereich: "voll", akzent: true }],
    },
    room.shell.walls.length,
  );

  it("ohne Flächen-Daten = exakt heutige Darstellung (null ≙ Prop weggelassen)", () => {
    const ohneProp = renderToStaticMarkup(<Viewer2D {...basis} />);
    const mitNull = renderToStaticMarkup(<Viewer2D {...basis} flaechen2d={null} />);
    expect(mitNull).toBe(ohneProp);
    expect(ohneProp).not.toContain("Boden:"); // keine Flächen-Legende
    expect(ohneProp).not.toContain("fp-boden-struktur");
  });

  it("Flächen-Layer (Default AN): Boden-Tönung/Struktur + Material-Legende", () => {
    const html = renderToStaticMarkup(<Viewer2D {...basis} flaechen2d={flaechen2d} />);
    expect(html).toContain("Boden: Fliesen anthrazit");
    expect(html).toContain("Wand: Fliesen grün (Akzent)");
    expect(html).toContain("fp-boden-struktur"); // Fugen-Struktur des Bodens
  });

  it("hervorgehobeneWand markiert die Wandbänder dezent CI-orange", () => {
    const ohne = renderToStaticMarkup(<Viewer2D {...basis} />);
    const mit = renderToStaticMarkup(<Viewer2D {...basis} hervorgehobeneWand={1} />);
    expect(ohne).not.toContain("#D6914F");
    expect(mit).toContain("#D6914F"); // THEME.orange als Highlight-Kante
  });
});