diff options
| author | netop://ウィビ <paul@webb.page> | 2026-04-24 16:37:33 -0700 |
|---|---|---|
| committer | netop://ウィビ <paul@webb.page> | 2026-04-24 16:37:33 -0700 |
| commit | 510fd8cbe53abb39cba2c7cbaaefcf2783dc0066 (patch) | |
| tree | 8f753a33c475b285f2a297785d34cda3b0a8faed /tests/session-io.test.ts | |
| parent | 261f3bdb77799009344aab4a60686b7186ebd3b0 (diff) | |
| download | graphiql-510fd8cbe53abb39cba2c7cbaaefcf2783dc0066.tar.gz graphiql-510fd8cbe53abb39cba2c7cbaaefcf2783dc0066.zip | |
Implement v0.6-1.0: shortcuts, format, export/import, splitter, timing, APQ
- v0.6: matchShortcut + format(); Cmd+Shift+Enter/W/F + Cmd+Alt+arrows
- v0.7: SessionStore.exportAll/importTabs with version-1 validator
- v0.8: Splitter component + four resize handles persisted under layout.*
- v0.10: createApqFetcher (HTTP-only) wrapping shared http-body helpers
- Drop .svelte re-exports from index.ts for multi-entry JSR/npm publishing
Diffstat (limited to 'tests/session-io.test.ts')
| -rw-r--r-- | tests/session-io.test.ts | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/tests/session-io.test.ts b/tests/session-io.test.ts new file mode 100644 index 0000000..6de919b --- /dev/null +++ b/tests/session-io.test.ts @@ -0,0 +1,201 @@ + + + + +/*** IMPORT ------------------------------------------- ***/ + +import { expect, test } from "vitest"; + +/*** UTILITY ------------------------------------------ ***/ + +import { + tabToExport, + validateSessionExport, + type SessionExport +} from "../source/library/state/session-io.ts"; + +type TabInput = Parameters<typeof tabToExport>[0]; + +function validExport(): SessionExport { + return { + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [ + { + headers: "{}", + operationName: "MyOp", + query: "query MyOp { hello }", + title: "MyOp", + variables: "{}" + } + ], + version: 1 + }; +} + +function isError(result: unknown): result is { error: string } { + return typeof result === "object" && + result !== null && + "error" in result; +} + +/*** TESTS -------------------------------------------- ***/ + +test("validateSessionExport round-trips a valid payload unchanged", () => { + const data = validExport(); + const result = validateSessionExport(data); + + expect(isError(result)).toBe(false); + expect(result).toEqual(data); +}); + +test("validateSessionExport rejects non-object input", () => { + expect(isError(validateSessionExport(null))).toBe(true); + expect(isError(validateSessionExport("nope"))).toBe(true); + expect(isError(validateSessionExport(42))).toBe(true); + expect(isError(validateSessionExport([]))).toBe(true); +}); + +test("validateSessionExport rejects wrong version", () => { + const zero = validateSessionExport({ ...validExport(), version: 0 }); + const two = validateSessionExport({ ...validExport(), version: 2 }); + const missing = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [] + }); + + expect(isError(zero)).toBe(true); + expect(isError(two)).toBe(true); + expect(isError(missing)).toBe(true); +}); + +test("validateSessionExport rejects missing or non-string exportedAt", () => { + const missing = validateSessionExport({ tabs: [], version: 1 }); + const wrongType = validateSessionExport({ exportedAt: 0, tabs: [], version: 1 }); + + expect(isError(missing)).toBe(true); + expect(isError(wrongType)).toBe(true); +}); + +test("validateSessionExport rejects non-array tabs", () => { + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: "not-an-array", + version: 1 + }); + + expect(isError(result)).toBe(true); +}); + +test("validateSessionExport rejects tab with non-string query", () => { + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [ + { + headers: "{}", + operationName: null, + query: 42, + title: "t", + variables: "{}" + } + ], + version: 1 + }); + + expect(isError(result)).toBe(true); +}); + +test("validateSessionExport rejects tab with wrong-typed operationName", () => { + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [ + { + headers: "{}", + operationName: 42, + query: "", + title: "t", + variables: "{}" + } + ], + version: 1 + }); + + expect(isError(result)).toBe(true); +}); + +test("validateSessionExport accepts null operationName", () => { + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [ + { + headers: "{}", + operationName: null, + query: "", + title: "t", + variables: "{}" + } + ], + version: 1 + }); + + expect(isError(result)).toBe(false); +}); + +test("validateSessionExport rejects string field > 1 MB", () => { + const big = "x".repeat(1024 * 1024 + 1); + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs: [ + { + headers: "{}", + operationName: null, + query: big, + title: "t", + variables: "{}" + } + ], + version: 1 + }); + + expect(isError(result)).toBe(true); +}); + +test("validateSessionExport rejects > 50 tabs", () => { + const tabs = Array.from({ length: 51 }, () => ({ + headers: "{}", + operationName: null, + query: "", + title: "t", + variables: "{}" + })); + const result = validateSessionExport({ + exportedAt: "2026-04-24T00:00:00.000Z", + tabs, + version: 1 + }); + + expect(isError(result)).toBe(true); +}); + +test("tabToExport strips id, result, operations, titleDirty", () => { + const tab: TabInput = { + headers: "{\"x\":1}", + id: "abc-123", + operationName: "MyOp", + operations: [{ name: "MyOp", type: "query" }], + query: "query MyOp { hello }", + result: "{\"data\":{}}", + streamIntervals: [], + timing: null, + title: "MyOp", + titleDirty: true, + variables: "{}" + }; + + expect(tabToExport(tab)).toEqual({ + headers: "{\"x\":1}", + operationName: "MyOp", + query: "query MyOp { hello }", + title: "MyOp", + variables: "{}" + }); +}); |