@clef-sh/ui 0.1.13-beta.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +38 -0
  2. package/dist/client/assets/index-CVpAmirt.js +26 -0
  3. package/dist/client/favicon-96x96.png +0 -0
  4. package/dist/client/favicon.ico +0 -0
  5. package/dist/client/favicon.svg +16 -0
  6. package/dist/client/index.html +50 -0
  7. package/dist/client-lib/api.d.ts +3 -0
  8. package/dist/client-lib/api.d.ts.map +1 -0
  9. package/dist/client-lib/components/Button.d.ts +10 -0
  10. package/dist/client-lib/components/Button.d.ts.map +1 -0
  11. package/dist/client-lib/components/CopyButton.d.ts +6 -0
  12. package/dist/client-lib/components/CopyButton.d.ts.map +1 -0
  13. package/dist/client-lib/components/EnvBadge.d.ts +7 -0
  14. package/dist/client-lib/components/EnvBadge.d.ts.map +1 -0
  15. package/dist/client-lib/components/MatrixGrid.d.ts +13 -0
  16. package/dist/client-lib/components/MatrixGrid.d.ts.map +1 -0
  17. package/dist/client-lib/components/Sidebar.d.ts +16 -0
  18. package/dist/client-lib/components/Sidebar.d.ts.map +1 -0
  19. package/dist/client-lib/components/StatusDot.d.ts +6 -0
  20. package/dist/client-lib/components/StatusDot.d.ts.map +1 -0
  21. package/dist/client-lib/components/TopBar.d.ts +9 -0
  22. package/dist/client-lib/components/TopBar.d.ts.map +1 -0
  23. package/dist/client-lib/index.d.ts +12 -0
  24. package/dist/client-lib/index.d.ts.map +1 -0
  25. package/dist/client-lib/theme.d.ts +42 -0
  26. package/dist/client-lib/theme.d.ts.map +1 -0
  27. package/dist/server/api.d.ts +11 -0
  28. package/dist/server/api.d.ts.map +1 -0
  29. package/dist/server/api.js +1020 -0
  30. package/dist/server/api.js.map +1 -0
  31. package/dist/server/index.d.ts +12 -0
  32. package/dist/server/index.d.ts.map +1 -0
  33. package/dist/server/index.js +231 -0
  34. package/dist/server/index.js.map +1 -0
  35. package/package.json +74 -0
  36. package/src/client/App.tsx +205 -0
  37. package/src/client/api.test.tsx +94 -0
  38. package/src/client/api.ts +30 -0
  39. package/src/client/components/Button.tsx +52 -0
  40. package/src/client/components/CopyButton.test.tsx +43 -0
  41. package/src/client/components/CopyButton.tsx +36 -0
  42. package/src/client/components/EnvBadge.tsx +32 -0
  43. package/src/client/components/MatrixGrid.tsx +265 -0
  44. package/src/client/components/Sidebar.tsx +337 -0
  45. package/src/client/components/StatusDot.tsx +30 -0
  46. package/src/client/components/TopBar.tsx +50 -0
  47. package/src/client/index.html +50 -0
  48. package/src/client/index.ts +18 -0
  49. package/src/client/main.tsx +15 -0
  50. package/src/client/public/favicon-96x96.png +0 -0
  51. package/src/client/public/favicon.ico +0 -0
  52. package/src/client/public/favicon.svg +16 -0
  53. package/src/client/screens/BackendScreen.test.tsx +611 -0
  54. package/src/client/screens/BackendScreen.tsx +836 -0
  55. package/src/client/screens/DiffView.test.tsx +130 -0
  56. package/src/client/screens/DiffView.tsx +547 -0
  57. package/src/client/screens/GitLogView.test.tsx +113 -0
  58. package/src/client/screens/GitLogView.tsx +192 -0
  59. package/src/client/screens/ImportScreen.tsx +710 -0
  60. package/src/client/screens/LintView.test.tsx +143 -0
  61. package/src/client/screens/LintView.tsx +589 -0
  62. package/src/client/screens/MatrixView.test.tsx +138 -0
  63. package/src/client/screens/MatrixView.tsx +143 -0
  64. package/src/client/screens/NamespaceEditor.test.tsx +694 -0
  65. package/src/client/screens/NamespaceEditor.tsx +1122 -0
  66. package/src/client/screens/RecipientsScreen.tsx +696 -0
  67. package/src/client/screens/ScanScreen.test.tsx +323 -0
  68. package/src/client/screens/ScanScreen.tsx +523 -0
  69. package/src/client/screens/ServiceIdentitiesScreen.tsx +1398 -0
  70. package/src/client/theme.ts +48 -0
@@ -0,0 +1,143 @@
1
+ import React from "react";
2
+ import { render, screen, fireEvent, act } from "@testing-library/react";
3
+ import "@testing-library/jest-dom";
4
+ import { LintView } from "./LintView";
5
+ import type { LintResult } from "@clef-sh/core";
6
+
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ declare let global: any;
9
+
10
+ const mockLintResult: LintResult = {
11
+ issues: [
12
+ {
13
+ severity: "error",
14
+ category: "matrix",
15
+ file: "storage/staging.enc.yaml",
16
+ message: "File declared in manifest but does not exist",
17
+ fixCommand: "clef init",
18
+ },
19
+ {
20
+ severity: "error",
21
+ category: "schema",
22
+ file: "database/production.enc.yaml",
23
+ key: "DB_REPLICA_URL",
24
+ message: "Required key missing from file",
25
+ fixCommand: "clef set database/production DB_REPLICA_URL",
26
+ },
27
+ {
28
+ severity: "warning",
29
+ category: "schema",
30
+ file: "payments/staging.enc.yaml",
31
+ key: "STRIPE_LEGACY_KEY",
32
+ message: "Key not declared in schema",
33
+ },
34
+ {
35
+ severity: "info",
36
+ category: "sops",
37
+ file: "payments/production.enc.yaml",
38
+ message: "Single recipient — consider adding backup key",
39
+ },
40
+ ],
41
+ fileCount: 15,
42
+ pendingCount: 0,
43
+ };
44
+
45
+ const emptyLintResult: LintResult = { issues: [], fileCount: 15, pendingCount: 0 };
46
+
47
+ beforeEach(() => {
48
+ jest.clearAllMocks();
49
+ jest.restoreAllMocks();
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ delete (global as any).fetch;
52
+ });
53
+
54
+ describe("LintView", () => {
55
+ it("renders issues grouped by severity", async () => {
56
+ global.fetch = jest.fn().mockResolvedValue({
57
+ ok: true,
58
+ json: () => Promise.resolve(mockLintResult),
59
+ } as Response);
60
+
61
+ await act(async () => {
62
+ render(<LintView setView={jest.fn()} setNs={jest.fn()} />);
63
+ });
64
+
65
+ expect(screen.getByText(/Required key missing/)).toBeInTheDocument();
66
+ expect(screen.getByText(/Key not declared/)).toBeInTheDocument();
67
+ });
68
+
69
+ it("shows all-clear state when no issues", async () => {
70
+ global.fetch = jest.fn().mockResolvedValue({
71
+ ok: true,
72
+ json: () => Promise.resolve(emptyLintResult),
73
+ } as Response);
74
+
75
+ await act(async () => {
76
+ render(<LintView setView={jest.fn()} setNs={jest.fn()} />);
77
+ });
78
+
79
+ expect(screen.getByTestId("all-clear")).toBeInTheDocument();
80
+ expect(screen.getByText("All clear")).toBeInTheDocument();
81
+ expect(screen.getByText(/15 files/)).toBeInTheDocument();
82
+ });
83
+
84
+ it("filters issues by severity", async () => {
85
+ global.fetch = jest.fn().mockResolvedValue({
86
+ ok: true,
87
+ json: () => Promise.resolve(mockLintResult),
88
+ } as Response);
89
+
90
+ await act(async () => {
91
+ render(<LintView setView={jest.fn()} setNs={jest.fn()} />);
92
+ });
93
+
94
+ expect(screen.getByText(/Required key missing/)).toBeInTheDocument();
95
+
96
+ // Click Warnings filter button
97
+ await act(async () => {
98
+ fireEvent.click(screen.getByTestId("filter-warning"));
99
+ });
100
+
101
+ expect(screen.getByText(/Key not declared/)).toBeInTheDocument();
102
+ expect(screen.queryByText(/Required key missing/)).not.toBeInTheDocument();
103
+ });
104
+
105
+ it("dismisses an issue when dismiss button is clicked", async () => {
106
+ global.fetch = jest.fn().mockResolvedValue({
107
+ ok: true,
108
+ json: () => Promise.resolve(mockLintResult),
109
+ } as Response);
110
+
111
+ await act(async () => {
112
+ render(<LintView setView={jest.fn()} setNs={jest.fn()} />);
113
+ });
114
+
115
+ expect(screen.getByText(/File declared in manifest/)).toBeInTheDocument();
116
+
117
+ const dismissButtons = screen.getAllByLabelText("Dismiss issue");
118
+ await act(async () => {
119
+ fireEvent.click(dismissButtons[0]);
120
+ });
121
+
122
+ expect(screen.queryByText(/File declared in manifest/)).not.toBeInTheDocument();
123
+ });
124
+
125
+ it("navigates to editor when file reference is clicked", async () => {
126
+ global.fetch = jest.fn().mockResolvedValue({
127
+ ok: true,
128
+ json: () => Promise.resolve(mockLintResult),
129
+ } as Response);
130
+
131
+ const setView = jest.fn();
132
+ const setNs = jest.fn();
133
+
134
+ await act(async () => {
135
+ render(<LintView setView={setView} setNs={setNs} />);
136
+ });
137
+
138
+ fireEvent.click(screen.getByTestId("file-ref-database/production.enc.yaml"));
139
+
140
+ expect(setView).toHaveBeenCalledWith("editor");
141
+ expect(setNs).toHaveBeenCalledWith("database");
142
+ });
143
+ });