blob: 1eae4ee07051e9322fb2e058ae5dda9c504a2400 [file] [log] [blame]
Sean McCullough86b56862025-04-18 13:04:03 -07001import { html, fixture, expect } from "@open-wc/testing";
2import "./sketch-container-status";
3import type { SketchContainerStatus } from "./sketch-container-status";
4import { State } from "../types";
5
6describe("SketchContainerStatus", () => {
7 // Mock complete state for testing
8 const mockCompleteState: State = {
9 hostname: "test-host",
10 working_dir: "/test/dir",
11 initial_commit: "abcdef1234567890",
12 message_count: 42,
13 os: "linux",
14 title: "Test Session",
15 total_usage: {
16 input_tokens: 1000,
17 output_tokens: 2000,
18 cache_read_input_tokens: 300,
19 cache_creation_input_tokens: 400,
Sean McCullough71941bd2025-04-18 13:31:48 -070020 total_cost_usd: 0.25,
21 },
Sean McCullough86b56862025-04-18 13:04:03 -070022 };
23
24 it("renders with complete state data", async () => {
25 const el: SketchContainerStatus = await fixture(html`
Sean McCullough71941bd2025-04-18 13:31:48 -070026 <sketch-container-status
27 .state=${mockCompleteState}
28 ></sketch-container-status>
Sean McCullough86b56862025-04-18 13:04:03 -070029 `);
30
31 // Check that all expected elements exist
32 expect(el.shadowRoot!.querySelector("#hostname")).to.exist;
33 expect(el.shadowRoot!.querySelector("#workingDir")).to.exist;
34 expect(el.shadowRoot!.querySelector("#initialCommit")).to.exist;
35 expect(el.shadowRoot!.querySelector("#messageCount")).to.exist;
36 expect(el.shadowRoot!.querySelector("#inputTokens")).to.exist;
37 expect(el.shadowRoot!.querySelector("#outputTokens")).to.exist;
38 expect(el.shadowRoot!.querySelector("#cacheReadInputTokens")).to.exist;
39 expect(el.shadowRoot!.querySelector("#cacheCreationInputTokens")).to.exist;
40 expect(el.shadowRoot!.querySelector("#totalCost")).to.exist;
41
42 // Verify content of displayed elements
Sean McCullough71941bd2025-04-18 13:31:48 -070043 expect(el.shadowRoot!.querySelector("#hostname")!.textContent).to.equal(
44 "test-host",
45 );
46 expect(el.shadowRoot!.querySelector("#workingDir")!.textContent).to.equal(
47 "/test/dir",
48 );
49 expect(
50 el.shadowRoot!.querySelector("#initialCommit")!.textContent,
51 ).to.equal("abcdef12"); // Only first 8 chars
52 expect(el.shadowRoot!.querySelector("#messageCount")!.textContent).to.equal(
53 "42",
54 );
55 expect(el.shadowRoot!.querySelector("#inputTokens")!.textContent).to.equal(
56 "1000",
57 );
58 expect(el.shadowRoot!.querySelector("#outputTokens")!.textContent).to.equal(
59 "2000",
60 );
61 expect(
62 el.shadowRoot!.querySelector("#cacheReadInputTokens")!.textContent,
63 ).to.equal("300");
64 expect(
65 el.shadowRoot!.querySelector("#cacheCreationInputTokens")!.textContent,
66 ).to.equal("400");
67 expect(el.shadowRoot!.querySelector("#totalCost")!.textContent).to.equal(
68 "$0.25",
69 );
Sean McCullough86b56862025-04-18 13:04:03 -070070 });
71
72 it("renders with undefined state", async () => {
73 const el: SketchContainerStatus = await fixture(html`
74 <sketch-container-status></sketch-container-status>
75 `);
76
77 // Elements should exist but be empty
78 expect(el.shadowRoot!.querySelector("#hostname")!.textContent).to.equal("");
Sean McCullough71941bd2025-04-18 13:31:48 -070079 expect(el.shadowRoot!.querySelector("#workingDir")!.textContent).to.equal(
80 "",
81 );
82 expect(
83 el.shadowRoot!.querySelector("#initialCommit")!.textContent,
84 ).to.equal("");
85 expect(el.shadowRoot!.querySelector("#messageCount")!.textContent).to.equal(
86 "",
87 );
88 expect(el.shadowRoot!.querySelector("#inputTokens")!.textContent).to.equal(
89 "",
90 );
91 expect(el.shadowRoot!.querySelector("#outputTokens")!.textContent).to.equal(
92 "",
93 );
94 expect(el.shadowRoot!.querySelector("#totalCost")!.textContent).to.equal(
95 "$0.00",
96 );
Sean McCullough86b56862025-04-18 13:04:03 -070097 });
98
99 it("renders with partial state data", async () => {
100 const partialState: Partial<State> = {
101 hostname: "partial-host",
102 message_count: 10,
103 os: "linux",
104 title: "Partial Test",
105 total_usage: {
Sean McCullough71941bd2025-04-18 13:31:48 -0700106 input_tokens: 500,
107 },
Sean McCullough86b56862025-04-18 13:04:03 -0700108 };
109
110 const el: SketchContainerStatus = await fixture(html`
Sean McCullough71941bd2025-04-18 13:31:48 -0700111 <sketch-container-status
112 .state=${partialState as State}
113 ></sketch-container-status>
Sean McCullough86b56862025-04-18 13:04:03 -0700114 `);
115
116 // Check that elements with data are properly populated
Sean McCullough71941bd2025-04-18 13:31:48 -0700117 expect(el.shadowRoot!.querySelector("#hostname")!.textContent).to.equal(
118 "partial-host",
119 );
120 expect(el.shadowRoot!.querySelector("#messageCount")!.textContent).to.equal(
121 "10",
122 );
123 expect(el.shadowRoot!.querySelector("#inputTokens")!.textContent).to.equal(
124 "500",
125 );
126
Sean McCullough86b56862025-04-18 13:04:03 -0700127 // Check that elements without data are empty
Sean McCullough71941bd2025-04-18 13:31:48 -0700128 expect(el.shadowRoot!.querySelector("#workingDir")!.textContent).to.equal(
129 "",
130 );
131 expect(
132 el.shadowRoot!.querySelector("#initialCommit")!.textContent,
133 ).to.equal("");
134 expect(el.shadowRoot!.querySelector("#outputTokens")!.textContent).to.equal(
135 "",
136 );
137 expect(el.shadowRoot!.querySelector("#totalCost")!.textContent).to.equal(
138 "$0.00",
139 );
Sean McCullough86b56862025-04-18 13:04:03 -0700140 });
141
142 it("handles cost formatting correctly", async () => {
143 // Test with different cost values
144 const testCases = [
145 { cost: 0, expected: "$0.00" },
146 { cost: 0.1, expected: "$0.10" },
147 { cost: 1.234, expected: "$1.23" },
Sean McCullough71941bd2025-04-18 13:31:48 -0700148 { cost: 10.009, expected: "$10.01" },
Sean McCullough86b56862025-04-18 13:04:03 -0700149 ];
150
151 for (const testCase of testCases) {
152 const stateWithCost = {
153 ...mockCompleteState,
154 total_usage: {
155 ...mockCompleteState.total_usage,
Sean McCullough71941bd2025-04-18 13:31:48 -0700156 total_cost_usd: testCase.cost,
157 },
Sean McCullough86b56862025-04-18 13:04:03 -0700158 };
159
160 const el: SketchContainerStatus = await fixture(html`
Sean McCullough71941bd2025-04-18 13:31:48 -0700161 <sketch-container-status
162 .state=${stateWithCost}
163 ></sketch-container-status>
Sean McCullough86b56862025-04-18 13:04:03 -0700164 `);
165
Sean McCullough71941bd2025-04-18 13:31:48 -0700166 expect(el.shadowRoot!.querySelector("#totalCost")!.textContent).to.equal(
167 testCase.expected,
168 );
Sean McCullough86b56862025-04-18 13:04:03 -0700169 }
170 });
171
172 it("truncates commit hash to 8 characters", async () => {
173 const stateWithLongCommit = {
174 ...mockCompleteState,
Sean McCullough71941bd2025-04-18 13:31:48 -0700175 initial_commit: "1234567890abcdef1234567890abcdef12345678",
Sean McCullough86b56862025-04-18 13:04:03 -0700176 };
177
178 const el: SketchContainerStatus = await fixture(html`
Sean McCullough71941bd2025-04-18 13:31:48 -0700179 <sketch-container-status
180 .state=${stateWithLongCommit}
181 ></sketch-container-status>
Sean McCullough86b56862025-04-18 13:04:03 -0700182 `);
183
Sean McCullough71941bd2025-04-18 13:31:48 -0700184 expect(
185 el.shadowRoot!.querySelector("#initialCommit")!.textContent,
186 ).to.equal("12345678");
Sean McCullough86b56862025-04-18 13:04:03 -0700187 });
188
189 it("has correct link elements", async () => {
190 const el: SketchContainerStatus = await fixture(html`
Sean McCullough71941bd2025-04-18 13:31:48 -0700191 <sketch-container-status
192 .state=${mockCompleteState}
193 ></sketch-container-status>
Sean McCullough86b56862025-04-18 13:04:03 -0700194 `);
195
Sean McCullough71941bd2025-04-18 13:31:48 -0700196 const links = Array.from(el.shadowRoot!.querySelectorAll("a"));
Sean McCullough86b56862025-04-18 13:04:03 -0700197 expect(links.length).to.equal(2);
Sean McCullough71941bd2025-04-18 13:31:48 -0700198
Sean McCullough86b56862025-04-18 13:04:03 -0700199 // Check for logs link
Sean McCullough71941bd2025-04-18 13:31:48 -0700200 const logsLink = links.find((link) => link.textContent === "Logs");
Sean McCullough86b56862025-04-18 13:04:03 -0700201 expect(logsLink).to.exist;
Sean McCullough71941bd2025-04-18 13:31:48 -0700202 expect(logsLink!.getAttribute("href")).to.equal("logs");
203
Sean McCullough86b56862025-04-18 13:04:03 -0700204 // Check for download link
Sean McCullough71941bd2025-04-18 13:31:48 -0700205 const downloadLink = links.find((link) => link.textContent === "Download");
Sean McCullough86b56862025-04-18 13:04:03 -0700206 expect(downloadLink).to.exist;
Sean McCullough71941bd2025-04-18 13:31:48 -0700207 expect(downloadLink!.getAttribute("href")).to.equal("download");
Sean McCullough86b56862025-04-18 13:04:03 -0700208 });
209});