quickbase-js 1.0.1-beta.0 → 1.1.0-beta.0

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 (47) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{quickbaseClient.d.ts → quickbase.d.ts} +344 -339
  3. package/dist/{quickbaseClient.js → quickbase.js} +350 -266
  4. package/dist/quickbase.js.map +1 -0
  5. package/log-gen.yaml +3565 -0
  6. package/package.json +11 -7
  7. package/rollup.config.js +2 -2
  8. package/src/code-generation/fix-spec-definitions.ts +417 -68
  9. package/src/code-generation/fix-spec-paths.ts +207 -2
  10. package/src/code-generation/output/quickbase-fixed.json +646 -1122
  11. package/src/generated-unified/QuickbaseClient.ts +9 -8
  12. package/src/log-gen.ts +82 -35
  13. package/src/quickbaseClient.ts +39 -42
  14. package/test-artifacts/test-results.json +173 -1145
  15. package/tests/playwright/qb/auth/cacheSwitching.test.ts +2 -2
  16. package/tests/playwright/qb/auth/fetchTempToken401.test.ts +2 -2
  17. package/tests/playwright/qb/auth/getAppWithUserToken.test.ts +2 -2
  18. package/tests/playwright/qb/auth/getTempToken.test.ts +2 -2
  19. package/tests/playwright/qb/auth/tokenPrefetch.test.ts +2 -2
  20. package/tests/playwright/qb/auth/tokenRenewal.test.ts +2 -2
  21. package/tests/setup.ts +16 -8
  22. package/tests/vitest/qb/apps/getApp.test.ts +37 -43
  23. package/tests/vitest/qb/records/deleteRecords.test.ts +78 -0
  24. package/tests/vitest/qb/records/upsert.test.ts +72 -0
  25. package/tests/vitest/qb/tables/createTable.test.ts +55 -0
  26. package/tests/vitest/qb/tables/deleteTable.test.ts +50 -0
  27. package/tests/vitest/qb/tables/getAppTables.test.ts +43 -64
  28. package/tests/vitest/qb/tables/getTable.test.ts +26 -0
  29. package/tests/vitest/qb/tables/updateTable.test.ts +48 -0
  30. package/tests/vitest/unit/apps/getApp.test.ts +1 -1
  31. package/tests/vitest/unit/auth/fetchTempToken401.test.ts +4 -3
  32. package/tests/vitest/unit/auth/getTempToken.test.ts +8 -9
  33. package/tests/vitest/unit/auth/retryOn401.test.ts +1 -1
  34. package/tests/vitest/unit/auth/two401s.test.ts +1 -1
  35. package/tests/vitest/unit/fields/getFields.test.ts +1 -1
  36. package/tests/vitest/unit/records/deleteRecords.test.ts +118 -0
  37. package/tests/vitest/unit/records/upsert.test.ts +228 -0
  38. package/tests/vitest/unit/tables/createTable.test.ts +62 -0
  39. package/tests/vitest/unit/tables/deleteTable.test.ts +68 -0
  40. package/tests/vitest/unit/tables/getAppTables.test.ts +1 -1
  41. package/tests/vitest/unit/tables/getTable.test.ts +212 -0
  42. package/tests/vitest/unit/tables/updateTable.test.ts +74 -0
  43. package/tsconfig.json +3 -2
  44. package/vitest.config.ts +3 -2
  45. package/dist/quickbaseClient.js.map +0 -1
  46. package/logGen.yaml +0 -1820
  47. package/src/utils.ts +0 -5
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - getApp (Unit)", () => {
5
5
  const client = createClient(mockFetch);
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, vi } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - 401 with fetchTempToken 401", () => {
5
5
  let client: ReturnType<typeof createClient>;
@@ -28,14 +28,15 @@ describe("QuickbaseClient - 401 with fetchTempToken 401", () => {
28
28
  return Promise.resolve({
29
29
  ok: false,
30
30
  status: 401,
31
- text: () => Promise.resolve("Unauthorized"),
31
+ json: () => Promise.resolve({ message: "Unauthorized" }),
32
32
  });
33
33
  }
34
34
  if (url.includes("auth/temporary") && callCount === 3) {
35
35
  return Promise.resolve({
36
36
  ok: false,
37
37
  status: 401,
38
- text: () => Promise.resolve("Unauthorized in fetchTempToken"),
38
+ json: () =>
39
+ Promise.resolve({ message: "Unauthorized in fetchTempToken" }),
39
40
  });
40
41
  }
41
42
  return Promise.reject(new Error(`Unexpected fetch call: ${url}`));
@@ -1,12 +1,12 @@
1
1
  import { describe, it, expect, beforeEach } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - getTempTokenDBID (Unit)", () => {
5
5
  let client: ReturnType<typeof createClient>;
6
6
 
7
7
  beforeEach(() => {
8
8
  mockFetch.mockClear();
9
- client = createClient(mockFetch, { useTempTokens: true, debug: false }); // Keep debug off for unit test clarity
9
+ client = createClient(mockFetch, { useTempTokens: true, debug: false });
10
10
  });
11
11
 
12
12
  it("initializes without errors", () => {
@@ -25,7 +25,7 @@ describe("QuickbaseClient - getTempTokenDBID (Unit)", () => {
25
25
  ok: true,
26
26
  status: 200,
27
27
  json: () => Promise.resolve({ temporaryAuthorization: mockToken }),
28
- } as Response);
28
+ });
29
29
 
30
30
  const result = await client.getTempTokenDBID({ dbid: mockDbid });
31
31
  expect(result).toEqual({ temporaryAuthorization: mockToken });
@@ -50,7 +50,7 @@ describe("QuickbaseClient - getTempTokenDBID (Unit)", () => {
50
50
  ok: true,
51
51
  status: 200,
52
52
  json: () => Promise.resolve({ temporaryAuthorization: mockToken }),
53
- } as Response);
53
+ });
54
54
 
55
55
  const firstResult = await client.getTempTokenDBID({ dbid: mockDbid });
56
56
  expect(firstResult).toEqual({ temporaryAuthorization: mockToken });
@@ -64,13 +64,12 @@ describe("QuickbaseClient - getTempTokenDBID (Unit)", () => {
64
64
 
65
65
  it("handles API error", async () => {
66
66
  const mockDbid = "mockDbid123";
67
- const errorResponse = {
67
+
68
+ mockFetch.mockResolvedValueOnce({
68
69
  ok: false,
69
70
  status: 401,
70
- text: () => Promise.resolve("Unauthorized"),
71
- } as Response;
72
-
73
- mockFetch.mockResolvedValueOnce(errorResponse);
71
+ json: () => Promise.resolve({ message: "Unauthorized" }),
72
+ });
74
73
 
75
74
  await expect(client.getTempTokenDBID({ dbid: mockDbid })).rejects.toSatisfy(
76
75
  (error: Error) => {
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, vi } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - 401 Retry Creates New Token", () => {
5
5
  let client: ReturnType<typeof createClient>;
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, beforeEach, vi } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - Two 401s in a Row", () => {
5
5
  let client: ReturnType<typeof createClient>;
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - getFields (Unit)", () => {
5
5
  it("calls getFields successfully", async () => {
@@ -0,0 +1,118 @@
1
+ // tests/vitest/unit/records/deleteRecords.test.ts
2
+ import { describe, expect, test, beforeEach } from "vitest"; // Added 'describe'
3
+ import { createClient, mockFetch } from "@tests/setup.ts";
4
+
5
+ describe("QuickbaseClient - deleteRecords (Unit)", () => {
6
+ beforeEach(() => {
7
+ mockFetch.mockClear(); // Clear mock state between tests
8
+ });
9
+
10
+ test("deleteRecords - sends correct DELETE request and handles success", async () => {
11
+ const qb = createClient(mockFetch, {
12
+ realm: "test-realm",
13
+ userToken: "test-token",
14
+ });
15
+
16
+ mockFetch.mockResolvedValueOnce({
17
+ ok: true,
18
+ status: 200,
19
+ json: () => Promise.resolve({ numberDeleted: 1 }),
20
+ });
21
+
22
+ const result = await qb.deleteRecords({
23
+ body: {
24
+ from: "test-table-id",
25
+ where: "{3.EX.'5'}", // Simulate deleting Record ID 5
26
+ },
27
+ });
28
+
29
+ expect(mockFetch).toHaveBeenCalledWith(
30
+ "https://api.quickbase.com/v1/records",
31
+ expect.objectContaining({
32
+ method: "DELETE",
33
+ headers: expect.objectContaining({
34
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
35
+ Authorization: "QB-USER-TOKEN test-token",
36
+ "Content-Type": "application/json",
37
+ }),
38
+ body: JSON.stringify({ from: "test-table-id", where: "{3.EX.'5'}" }),
39
+ })
40
+ );
41
+ expect(result).toEqual({ numberDeleted: 1 });
42
+ });
43
+
44
+ test("deleteRecords - handles no records deleted", async () => {
45
+ const qb = createClient(mockFetch, {
46
+ realm: "test-realm",
47
+ userToken: "test-token",
48
+ });
49
+
50
+ mockFetch.mockResolvedValueOnce({
51
+ ok: true,
52
+ status: 200,
53
+ json: () => Promise.resolve({ numberDeleted: 0 }),
54
+ });
55
+
56
+ const result = await qb.deleteRecords({
57
+ body: {
58
+ from: "test-table-id",
59
+ where: "{3.EX.'999999'}", // Non-existent Record ID
60
+ },
61
+ });
62
+
63
+ expect(mockFetch).toHaveBeenCalledWith(
64
+ "https://api.quickbase.com/v1/records",
65
+ expect.objectContaining({
66
+ method: "DELETE",
67
+ headers: expect.objectContaining({
68
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
69
+ Authorization: "QB-USER-TOKEN test-token",
70
+ "Content-Type": "application/json",
71
+ }),
72
+ body: JSON.stringify({
73
+ from: "test-table-id",
74
+ where: "{3.EX.'999999'}",
75
+ }),
76
+ })
77
+ );
78
+ expect(result).toEqual({ numberDeleted: 0 });
79
+ });
80
+
81
+ test("deleteRecords - throws error on API failure", async () => {
82
+ const qb = createClient(mockFetch, {
83
+ realm: "test-realm",
84
+ userToken: "test-token",
85
+ });
86
+
87
+ mockFetch.mockResolvedValueOnce({
88
+ ok: false,
89
+ status: 400,
90
+ json: () => Promise.resolve({ message: "Invalid query" }),
91
+ });
92
+
93
+ await expect(() =>
94
+ qb.deleteRecords({
95
+ body: {
96
+ from: "test-table-id",
97
+ where: "{3.EX.'invalid'}",
98
+ },
99
+ })
100
+ ).rejects.toThrow("API Error: Invalid query (Status: 400)");
101
+
102
+ expect(mockFetch).toHaveBeenCalledWith(
103
+ "https://api.quickbase.com/v1/records",
104
+ expect.objectContaining({
105
+ method: "DELETE",
106
+ headers: expect.objectContaining({
107
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
108
+ Authorization: "QB-USER-TOKEN test-token",
109
+ "Content-Type": "application/json",
110
+ }),
111
+ body: JSON.stringify({
112
+ from: "test-table-id",
113
+ where: "{3.EX.'invalid'}",
114
+ }),
115
+ })
116
+ );
117
+ });
118
+ });
@@ -0,0 +1,228 @@
1
+ // tests/vitest/unit/records/upsert.test.ts
2
+ import { describe, expect, test, beforeEach } from "vitest";
3
+ import { createClient, mockFetch } from "@tests/setup.ts";
4
+ import { vi } from "vitest";
5
+
6
+ // Note: Type augmentation moved to src/types.d.ts
7
+ describe("QuickbaseClient - upsert (Unit)", () => {
8
+ beforeEach(() => {
9
+ vi.resetModules(); // Reset module cache
10
+ mockFetch.mockClear();
11
+ });
12
+
13
+ test("sends correct POST request and handles successful upsert", async () => {
14
+ const qb = createClient(mockFetch, {
15
+ realm: "test-realm",
16
+ userToken: "test-token",
17
+ debug: true,
18
+ });
19
+
20
+ mockFetch.mockResolvedValueOnce({
21
+ ok: true,
22
+ status: 200,
23
+ json: () =>
24
+ Promise.resolve({
25
+ data: [{ id: 1, "6": { value: "value1" } }],
26
+ metadata: {
27
+ createdRecordIds: [1],
28
+ updatedRecordIds: [],
29
+ unchangedRecordIds: [],
30
+ totalNumberOfRecordsProcessed: 1,
31
+ },
32
+ }),
33
+ });
34
+
35
+ console.log("[Test] Calling qb.upsert with:", {
36
+ body: { to: "test-table-id", data: [{ "6": { value: "value1" } }] },
37
+ });
38
+ const result = await qb.upsert({
39
+ body: { to: "test-table-id", data: [{ "6": { value: "value1" } }] },
40
+ });
41
+
42
+ console.log("[Test] mockFetch calls:", mockFetch.mock.calls);
43
+ expect(mockFetch).toHaveBeenCalledWith(
44
+ "https://api.quickbase.com/v1/records",
45
+ expect.objectContaining({
46
+ method: "POST",
47
+ headers: expect.objectContaining({
48
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
49
+ Authorization: "QB-USER-TOKEN test-token",
50
+ "Content-Type": "application/json",
51
+ }),
52
+ body: JSON.stringify({
53
+ to: "test-table-id",
54
+ data: [{ "6": { value: "value1" } }],
55
+ }),
56
+ })
57
+ );
58
+
59
+ expect(result).toEqual({
60
+ data: [{ id: 1, "6": { value: "value1" } }],
61
+ metadata: {
62
+ createdRecordIds: [1],
63
+ updatedRecordIds: [],
64
+ unchangedRecordIds: [],
65
+ totalNumberOfRecordsProcessed: 1,
66
+ },
67
+ });
68
+ });
69
+
70
+ test("handles API error with invalid data", async () => {
71
+ const qb = createClient(mockFetch, {
72
+ realm: "test-realm",
73
+ userToken: "test-token",
74
+ debug: true,
75
+ });
76
+
77
+ mockFetch.mockResolvedValueOnce({
78
+ ok: false,
79
+ status: 400,
80
+ json: () => Promise.resolve({ message: "Invalid data format" }),
81
+ });
82
+
83
+ await expect(
84
+ qb.upsert({
85
+ body: { to: "test-table-id", data: [{ "999": { value: "invalid" } }] },
86
+ })
87
+ ).rejects.toThrow("API Error: Invalid data format (Status: 400)");
88
+
89
+ expect(mockFetch).toHaveBeenCalledWith(
90
+ "https://api.quickbase.com/v1/records",
91
+ expect.objectContaining({
92
+ method: "POST",
93
+ headers: expect.objectContaining({
94
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
95
+ Authorization: "QB-USER-TOKEN test-token",
96
+ "Content-Type": "application/json",
97
+ }),
98
+ body: JSON.stringify({
99
+ to: "test-table-id",
100
+ data: [{ "999": { value: "invalid" } }],
101
+ }),
102
+ })
103
+ );
104
+ });
105
+
106
+ test("handles upsert with temp token", async () => {
107
+ const qb = createClient(mockFetch, {
108
+ realm: "test-realm",
109
+ useTempTokens: true,
110
+ debug: true,
111
+ });
112
+
113
+ mockFetch
114
+ .mockResolvedValueOnce({
115
+ ok: true,
116
+ status: 200,
117
+ json: () => Promise.resolve({ temporaryAuthorization: "temp-token" }),
118
+ })
119
+ .mockResolvedValueOnce({
120
+ ok: true,
121
+ status: 200,
122
+ json: () =>
123
+ Promise.resolve({
124
+ data: [{ id: 2, "7": { value: "value2" } }],
125
+ metadata: {
126
+ createdRecordIds: [2],
127
+ updatedRecordIds: [],
128
+ unchangedRecordIds: [],
129
+ totalNumberOfRecordsProcessed: 1,
130
+ },
131
+ }),
132
+ });
133
+
134
+ const result = await qb.upsert({
135
+ body: { to: "test-table-id", data: [{ "7": { value: "value2" } }] },
136
+ dbid: "test-dbid",
137
+ } as any); // Temporary type assertion until types.d.ts is applied
138
+
139
+ expect(mockFetch).toHaveBeenCalledTimes(2);
140
+ expect(mockFetch).toHaveBeenNthCalledWith(
141
+ 1,
142
+ "https://api.quickbase.com/v1/auth/temporary/test-dbid",
143
+ expect.objectContaining({
144
+ method: "GET",
145
+ headers: expect.objectContaining({
146
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
147
+ "Content-Type": "application/json",
148
+ }),
149
+ credentials: "include",
150
+ })
151
+ );
152
+ expect(mockFetch).toHaveBeenNthCalledWith(
153
+ 2,
154
+ "https://api.quickbase.com/v1/records",
155
+ expect.objectContaining({
156
+ method: "POST",
157
+ headers: expect.objectContaining({
158
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
159
+ Authorization: "QB-TEMP-TOKEN temp-token",
160
+ "Content-Type": "application/json",
161
+ }),
162
+ body: JSON.stringify({
163
+ to: "test-table-id",
164
+ data: [{ "7": { value: "value2" } }],
165
+ }),
166
+ })
167
+ );
168
+
169
+ expect(result).toEqual({
170
+ data: [{ id: 2, "7": { value: "value2" } }],
171
+ metadata: {
172
+ createdRecordIds: [2],
173
+ updatedRecordIds: [],
174
+ unchangedRecordIds: [],
175
+ totalNumberOfRecordsProcessed: 1,
176
+ },
177
+ });
178
+ });
179
+
180
+ test("sends correct POST request with data fields", async () => {
181
+ const qb = createClient(mockFetch, {
182
+ realm: "test-realm",
183
+ userToken: "test-token",
184
+ debug: true,
185
+ });
186
+
187
+ mockFetch.mockResolvedValueOnce({
188
+ ok: true,
189
+ status: 200,
190
+ json: () =>
191
+ Promise.resolve({
192
+ data: [{ id: 1, "6": { value: "value1" } }],
193
+ metadata: {
194
+ createdRecordIds: [1],
195
+ updatedRecordIds: [],
196
+ unchangedRecordIds: [],
197
+ totalNumberOfRecordsProcessed: 1,
198
+ },
199
+ }),
200
+ });
201
+
202
+ const result = await qb.upsert({
203
+ body: { to: "test-table-id", data: [{ "6": { value: "value1" } }] },
204
+ });
205
+
206
+ expect(mockFetch).toHaveBeenCalledWith(
207
+ "https://api.quickbase.com/v1/records",
208
+ expect.objectContaining({
209
+ method: "POST",
210
+ headers: expect.objectContaining({
211
+ "QB-Realm-Hostname": "test-realm.quickbase.com",
212
+ Authorization: "QB-USER-TOKEN test-token",
213
+ "Content-Type": "application/json",
214
+ }),
215
+ body: JSON.stringify({
216
+ to: "test-table-id",
217
+ data: [{ "6": { value: "value1" } }],
218
+ }),
219
+ })
220
+ );
221
+
222
+ if (result.data && result.data.length > 0) {
223
+ expect((result.data[0]["6"] as { value: any }).value).toBe("value1");
224
+ } else {
225
+ throw new Error("Expected data array to have at least one element");
226
+ }
227
+ });
228
+ });
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
+
4
+ describe("QuickbaseClient - createTable (Unit)", () => {
5
+ let client: ReturnType<typeof createClient>;
6
+
7
+ beforeEach(() => {
8
+ mockFetch.mockClear();
9
+ client = createClient(mockFetch, { debug: true });
10
+ });
11
+
12
+ it("calls createTable successfully with user token", async () => {
13
+ const appId = "buwai2zpe";
14
+ const mockBody = {
15
+ name: "TestTable",
16
+ description: "Unit test table",
17
+ singleRecordName: "Test",
18
+ pluralRecordName: "Tests",
19
+ };
20
+ const mockResponse = {
21
+ id: "buya8h9iz",
22
+ name: "TestTable",
23
+ alias: "_DBID_TESTTABLE",
24
+ description: "Unit test table",
25
+ created: new Date("2025-03-10T21:00:00.000Z"),
26
+ updated: new Date("2025-03-10T21:00:00.000Z"),
27
+ nextRecordId: 1,
28
+ nextFieldId: 6,
29
+ defaultSortFieldId: 2,
30
+ defaultSortOrder: "DESC",
31
+ keyFieldId: 3,
32
+ singleRecordName: "Test",
33
+ pluralRecordName: "Tests",
34
+ sizeLimit: "500 MB",
35
+ spaceUsed: "0 KB",
36
+ spaceRemaining: "500 MB",
37
+ };
38
+
39
+ mockFetch.mockResolvedValueOnce({
40
+ ok: true,
41
+ status: 200,
42
+ json: () => Promise.resolve(mockResponse),
43
+ });
44
+
45
+ const response = await client.createTable({ appId, body: mockBody });
46
+ expect(response).toEqual(mockResponse);
47
+ expect(mockFetch).toHaveBeenCalledTimes(1);
48
+ expect(mockFetch).toHaveBeenCalledWith(
49
+ `https://api.quickbase.com/v1/tables?appId=${appId}`,
50
+ expect.objectContaining({
51
+ method: "POST",
52
+ headers: expect.objectContaining({
53
+ "Content-Type": "application/json",
54
+ "QB-Realm-Hostname": "builderprogram-dbradford6815.quickbase.com",
55
+ Authorization:
56
+ "QB-USER-TOKEN b9f3pk_q4jd_0_b4qu5eebyvuix3xs57ysd7zn3",
57
+ }),
58
+ body: JSON.stringify(mockBody),
59
+ })
60
+ );
61
+ });
62
+ });
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
+
4
+ describe("QuickbaseClient - deleteTable (Unit)", () => {
5
+ let client: ReturnType<typeof createClient>;
6
+
7
+ beforeEach(() => {
8
+ mockFetch.mockClear();
9
+ client = createClient(mockFetch, { debug: true });
10
+ });
11
+
12
+ it("calls deleteTable successfully with user token", async () => {
13
+ const appId = "buwai2zpe";
14
+ const tableId = "buya8h9iz";
15
+ const mockResponse = {
16
+ deletedTableId: tableId,
17
+ };
18
+
19
+ mockFetch.mockResolvedValueOnce({
20
+ ok: true,
21
+ status: 200,
22
+ json: () => Promise.resolve(mockResponse),
23
+ });
24
+
25
+ const response = await client.deleteTable({ tableId, appId });
26
+ expect(response).toEqual(mockResponse);
27
+ expect(mockFetch).toHaveBeenCalledTimes(1);
28
+ expect(mockFetch).toHaveBeenCalledWith(
29
+ `https://api.quickbase.com/v1/tables/${tableId}?appId=${appId}`,
30
+ expect.objectContaining({
31
+ method: "DELETE",
32
+ headers: expect.objectContaining({
33
+ "Content-Type": "application/json",
34
+ "QB-Realm-Hostname": "builderprogram-dbradford6815.quickbase.com",
35
+ Authorization:
36
+ "QB-USER-TOKEN b9f3pk_q4jd_0_b4qu5eebyvuix3xs57ysd7zn3",
37
+ }),
38
+ })
39
+ );
40
+ });
41
+
42
+ it("handles 404 error for non-existent table", async () => {
43
+ const appId = "buwai2zpe";
44
+ const tableId = "nonexistent";
45
+
46
+ mockFetch.mockResolvedValueOnce({
47
+ ok: false,
48
+ status: 404,
49
+ json: () =>
50
+ Promise.resolve({
51
+ message: "Invalid DBID",
52
+ description: "Table not found in app.",
53
+ }),
54
+ });
55
+
56
+ await expect(client.deleteTable({ tableId, appId })).rejects.toThrow(
57
+ "API Error: Invalid DBID (Status: 404)"
58
+ );
59
+ expect(mockFetch).toHaveBeenCalledTimes(1);
60
+ expect(mockFetch).toHaveBeenCalledWith(
61
+ `https://api.quickbase.com/v1/tables/${tableId}?appId=${appId}`,
62
+ expect.objectContaining({
63
+ method: "DELETE",
64
+ headers: expect.any(Object),
65
+ })
66
+ );
67
+ });
68
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { createClient, mockFetch } from "@/tests/setup.ts";
2
+ import { createClient, mockFetch } from "@tests/setup.ts";
3
3
 
4
4
  describe("QuickbaseClient - getAppTables (Unit)", () => {
5
5
  it("calls getAppTables successfully", async () => {