@multiplatform.one/frappe 7.10.0 → 7.15.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.
- package/README.md +59 -1
- package/dist/cjs/auth.native.js.map +1 -1
- package/dist/cjs/call.native.js.map +1 -1
- package/dist/cjs/collection.native.js.map +1 -1
- package/dist/cjs/common/types.native.js.map +1 -1
- package/dist/cjs/core/http.native.js.map +1 -1
- package/dist/cjs/core/types.native.js.map +1 -1
- package/dist/cjs/core/wire.native.js.map +1 -1
- package/dist/cjs/db.native.js.map +1 -1
- package/dist/cjs/devtools/FrappeDevtoolsPanel.native.js.map +1 -1
- package/dist/cjs/devtools/index.native.js.map +1 -1
- package/dist/cjs/devtools/plugin.native.js.map +1 -1
- package/dist/cjs/devtools/theme.native.js.map +1 -1
- package/dist/cjs/doctype.cjs +25 -43
- package/dist/cjs/doctype.native.js +27 -43
- package/dist/cjs/doctype.native.js.map +1 -1
- package/dist/cjs/file.native.js.map +1 -1
- package/dist/cjs/fixtureDb.native.js.map +1 -1
- package/dist/cjs/fixtures.cjs +3 -0
- package/dist/cjs/fixtures.native.js +3 -0
- package/dist/cjs/fixtures.native.js.map +1 -1
- package/dist/cjs/frappeApp.native.js.map +1 -1
- package/dist/cjs/frappeReact.cjs +67 -31
- package/dist/cjs/frappeReact.native.js +87 -34
- package/dist/cjs/frappeReact.native.js.map +1 -1
- package/dist/cjs/index.cjs +7 -0
- package/dist/cjs/index.native.js +9 -2
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/optimistic.native.js.map +1 -1
- package/dist/cjs/pacer.native.js.map +1 -1
- package/dist/cjs/plugin/index.native.js.map +1 -1
- package/dist/cjs/realtime.native.js.map +1 -1
- package/dist/cjs/serverLoaders.cjs +74 -0
- package/dist/cjs/serverLoaders.native.js +88 -0
- package/dist/cjs/serverLoaders.native.js.map +1 -0
- package/dist/cjs/sync/backfill.native.js.map +1 -1
- package/dist/cjs/sync/filters.native.js.map +1 -1
- package/dist/cjs/sync/index.cjs +99 -14
- package/dist/cjs/sync/index.native.js +129 -14
- package/dist/cjs/sync/index.native.js.map +1 -1
- package/dist/cjs/sync/merge.native.js.map +1 -1
- package/dist/cjs/sync/mutationEngine.native.js.map +1 -1
- package/dist/cjs/sync/mutationJournal.native.js.map +1 -1
- package/dist/cjs/sync/normalizedCache.native.js.map +1 -1
- package/dist/cjs/sync/persistence.native.js.map +1 -1
- package/dist/cjs/sync/realtime.native.js.map +1 -1
- package/dist/cjs/sync/rehydration.cjs +4 -0
- package/dist/cjs/sync/rehydration.native.js +6 -0
- package/dist/cjs/sync/rehydration.native.js.map +1 -1
- package/dist/cjs/sync/storage.native.js.map +1 -1
- package/dist/cjs/sync/subscriptionManager.native.js.map +1 -1
- package/dist/cjs/sync/types.native.js.map +1 -1
- package/dist/cjs/sync/virtualPageManager.native.js.map +1 -1
- package/dist/cjs/syncOptionsKey.cjs +59 -0
- package/dist/cjs/syncOptionsKey.native.js +82 -0
- package/dist/cjs/syncOptionsKey.native.js.map +1 -0
- package/dist/cjs/useLiveQuery.cjs +2 -20
- package/dist/cjs/useLiveQuery.native.js +1 -22
- package/dist/cjs/useLiveQuery.native.js.map +1 -1
- package/dist/cjs/util.native.js.map +1 -1
- package/dist/esm/auth.native.js.map +1 -1
- package/dist/esm/call.native.js.map +1 -1
- package/dist/esm/collection.native.js.map +1 -1
- package/dist/esm/common/types.native.js.map +1 -1
- package/dist/esm/core/http.native.js.map +1 -1
- package/dist/esm/core/types.native.js.map +1 -1
- package/dist/esm/core/wire.native.js.map +1 -1
- package/dist/esm/db.native.js.map +1 -1
- package/dist/esm/devtools/FrappeDevtoolsPanel.native.js.map +1 -1
- package/dist/esm/devtools/index.native.js.map +1 -1
- package/dist/esm/devtools/plugin.native.js.map +1 -1
- package/dist/esm/devtools/theme.native.js.map +1 -1
- package/dist/esm/doctype.mjs +23 -44
- package/dist/esm/doctype.mjs.map +1 -1
- package/dist/esm/doctype.native.js +25 -44
- package/dist/esm/doctype.native.js.map +1 -1
- package/dist/esm/file.native.js.map +1 -1
- package/dist/esm/fixtureDb.native.js.map +1 -1
- package/dist/esm/fixtures.mjs +3 -0
- package/dist/esm/fixtures.mjs.map +1 -1
- package/dist/esm/fixtures.native.js +3 -0
- package/dist/esm/fixtures.native.js.map +1 -1
- package/dist/esm/frappeApp.native.js.map +1 -1
- package/dist/esm/frappeReact.mjs +68 -33
- package/dist/esm/frappeReact.mjs.map +1 -1
- package/dist/esm/frappeReact.native.js +87 -35
- package/dist/esm/frappeReact.native.js.map +1 -1
- package/dist/esm/index.mjs +4 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +4 -3
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/optimistic.native.js.map +1 -1
- package/dist/esm/pacer.native.js.map +1 -1
- package/dist/esm/plugin/index.native.js.map +1 -1
- package/dist/esm/realtime.native.js.map +1 -1
- package/dist/esm/serverLoaders.mjs +48 -0
- package/dist/esm/serverLoaders.mjs.map +1 -0
- package/dist/esm/serverLoaders.native.js +59 -0
- package/dist/esm/serverLoaders.native.js.map +1 -0
- package/dist/esm/sync/backfill.native.js.map +1 -1
- package/dist/esm/sync/filters.native.js.map +1 -1
- package/dist/esm/sync/index.mjs +99 -14
- package/dist/esm/sync/index.mjs.map +1 -1
- package/dist/esm/sync/index.native.js +129 -14
- package/dist/esm/sync/index.native.js.map +1 -1
- package/dist/esm/sync/merge.native.js.map +1 -1
- package/dist/esm/sync/mutationEngine.native.js.map +1 -1
- package/dist/esm/sync/mutationJournal.native.js.map +1 -1
- package/dist/esm/sync/normalizedCache.native.js.map +1 -1
- package/dist/esm/sync/persistence.native.js.map +1 -1
- package/dist/esm/sync/realtime.native.js.map +1 -1
- package/dist/esm/sync/rehydration.mjs +4 -0
- package/dist/esm/sync/rehydration.mjs.map +1 -1
- package/dist/esm/sync/rehydration.native.js +6 -0
- package/dist/esm/sync/rehydration.native.js.map +1 -1
- package/dist/esm/sync/storage.native.js.map +1 -1
- package/dist/esm/sync/subscriptionManager.native.js.map +1 -1
- package/dist/esm/sync/types.mjs.map +1 -1
- package/dist/esm/sync/types.native.js.map +1 -1
- package/dist/esm/sync/virtualPageManager.native.js.map +1 -1
- package/dist/esm/syncOptionsKey.mjs +34 -0
- package/dist/esm/syncOptionsKey.mjs.map +1 -0
- package/dist/esm/syncOptionsKey.native.js +54 -0
- package/dist/esm/syncOptionsKey.native.js.map +1 -0
- package/dist/esm/useLiveQuery.mjs +1 -19
- package/dist/esm/useLiveQuery.mjs.map +1 -1
- package/dist/esm/useLiveQuery.native.js +1 -22
- package/dist/esm/useLiveQuery.native.js.map +1 -1
- package/dist/esm/util.native.js.map +1 -1
- package/dist/jsx/auth.native.js.map +1 -1
- package/dist/jsx/call.native.js.map +1 -1
- package/dist/jsx/collection.native.js.map +1 -1
- package/dist/jsx/common/types.native.js.map +1 -1
- package/dist/jsx/core/http.native.js.map +1 -1
- package/dist/jsx/core/types.native.js.map +1 -1
- package/dist/jsx/core/wire.native.js.map +1 -1
- package/dist/jsx/db.native.js.map +1 -1
- package/dist/jsx/devtools/FrappeDevtoolsPanel.native.js.map +1 -1
- package/dist/jsx/devtools/index.native.js.map +1 -1
- package/dist/jsx/devtools/plugin.native.js.map +1 -1
- package/dist/jsx/devtools/theme.native.js.map +1 -1
- package/dist/jsx/doctype.mjs +23 -44
- package/dist/jsx/doctype.mjs.map +1 -1
- package/dist/jsx/doctype.native.js +27 -43
- package/dist/jsx/doctype.native.js.map +1 -1
- package/dist/jsx/file.native.js.map +1 -1
- package/dist/jsx/fixtureDb.native.js.map +1 -1
- package/dist/jsx/fixtures.mjs +3 -0
- package/dist/jsx/fixtures.mjs.map +1 -1
- package/dist/jsx/fixtures.native.js +3 -0
- package/dist/jsx/fixtures.native.js.map +1 -1
- package/dist/jsx/frappeApp.native.js.map +1 -1
- package/dist/jsx/frappeReact.mjs +68 -33
- package/dist/jsx/frappeReact.mjs.map +1 -1
- package/dist/jsx/frappeReact.native.js +87 -34
- package/dist/jsx/frappeReact.native.js.map +1 -1
- package/dist/jsx/index.js +4 -3
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +4 -3
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +9 -2
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/optimistic.native.js.map +1 -1
- package/dist/jsx/pacer.native.js.map +1 -1
- package/dist/jsx/plugin/index.native.js.map +1 -1
- package/dist/jsx/realtime.native.js.map +1 -1
- package/dist/jsx/serverLoaders.mjs +48 -0
- package/dist/jsx/serverLoaders.mjs.map +1 -0
- package/dist/jsx/serverLoaders.native.js +88 -0
- package/dist/jsx/serverLoaders.native.js.map +1 -0
- package/dist/jsx/sync/backfill.native.js.map +1 -1
- package/dist/jsx/sync/filters.native.js.map +1 -1
- package/dist/jsx/sync/index.mjs +99 -14
- package/dist/jsx/sync/index.mjs.map +1 -1
- package/dist/jsx/sync/index.native.js +129 -14
- package/dist/jsx/sync/index.native.js.map +1 -1
- package/dist/jsx/sync/merge.native.js.map +1 -1
- package/dist/jsx/sync/mutationEngine.native.js.map +1 -1
- package/dist/jsx/sync/mutationJournal.native.js.map +1 -1
- package/dist/jsx/sync/normalizedCache.native.js.map +1 -1
- package/dist/jsx/sync/persistence.native.js.map +1 -1
- package/dist/jsx/sync/realtime.native.js.map +1 -1
- package/dist/jsx/sync/rehydration.mjs +4 -0
- package/dist/jsx/sync/rehydration.mjs.map +1 -1
- package/dist/jsx/sync/rehydration.native.js +6 -0
- package/dist/jsx/sync/rehydration.native.js.map +1 -1
- package/dist/jsx/sync/storage.native.js.map +1 -1
- package/dist/jsx/sync/subscriptionManager.native.js.map +1 -1
- package/dist/jsx/sync/types.mjs.map +1 -1
- package/dist/jsx/sync/types.native.js.map +1 -1
- package/dist/jsx/sync/virtualPageManager.native.js.map +1 -1
- package/dist/jsx/syncOptionsKey.mjs +34 -0
- package/dist/jsx/syncOptionsKey.mjs.map +1 -0
- package/dist/jsx/syncOptionsKey.native.js +82 -0
- package/dist/jsx/syncOptionsKey.native.js.map +1 -0
- package/dist/jsx/useLiveQuery.mjs +1 -19
- package/dist/jsx/useLiveQuery.mjs.map +1 -1
- package/dist/jsx/useLiveQuery.native.js +1 -22
- package/dist/jsx/useLiveQuery.native.js.map +1 -1
- package/dist/jsx/util.native.js.map +1 -1
- package/package.json +12 -12
- package/src/doctype.spec.ts +148 -5
- package/src/doctype.ts +202 -173
- package/src/fixtures.ts +1 -0
- package/src/frappeReact.catchUp.spec.tsx +105 -0
- package/src/frappeReact.hydration.spec.tsx +164 -0
- package/src/frappeReact.spec.ts +56 -0
- package/src/frappeReact.ts +93 -43
- package/src/index.ts +14 -0
- package/src/serverLoaders.ts +77 -0
- package/src/sync/catchUp.spec.ts +142 -0
- package/src/sync/index.ts +106 -9
- package/src/sync/rehydration.ts +5 -0
- package/src/sync/syncModule.spec.ts +20 -0
- package/src/sync/types.ts +9 -1
- package/src/syncOptionsKey.spec.ts +46 -0
- package/src/syncOptionsKey.ts +45 -0
- package/src/useLiveQuery.hydration.spec.tsx +129 -0
- package/src/useLiveQuery.spec.ts +3 -11
- package/src/useLiveQuery.ts +3 -57
- package/types/doctype.d.ts +117 -33
- package/types/doctype.d.ts.map +1 -1
- package/types/fixtures.d.ts.map +1 -1
- package/types/frappeReact.d.ts +9 -3
- package/types/frappeReact.d.ts.map +1 -1
- package/types/index.d.ts +6 -5
- package/types/index.d.ts.map +1 -1
- package/types/serverLoaders.d.ts +40 -0
- package/types/serverLoaders.d.ts.map +1 -0
- package/types/sync/index.d.ts +15 -1
- package/types/sync/index.d.ts.map +1 -1
- package/types/sync/rehydration.d.ts +2 -0
- package/types/sync/rehydration.d.ts.map +1 -1
- package/types/sync/types.d.ts +8 -1
- package/types/sync/types.d.ts.map +1 -1
- package/types/syncOptionsKey.d.ts +3 -0
- package/types/syncOptionsKey.d.ts.map +1 -0
- package/types/useLiveQuery.d.ts +3 -13
- package/types/useLiveQuery.d.ts.map +1 -1
package/src/doctype.spec.ts
CHANGED
|
@@ -2,8 +2,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
2
2
|
import { act, renderHook, waitFor } from "@testing-library/react";
|
|
3
3
|
import type { DocTypeField, FrappeFieldType } from "./doctype";
|
|
4
4
|
import {
|
|
5
|
+
customFieldTypes,
|
|
6
|
+
frappeFieldTypes,
|
|
5
7
|
parseDependsOn,
|
|
6
8
|
parseFormLayout,
|
|
9
|
+
stockFieldTypes,
|
|
7
10
|
useDocTypeMeta,
|
|
8
11
|
useLinkSearch,
|
|
9
12
|
useLinkTitle,
|
|
@@ -53,6 +56,18 @@ describe("FrappeFieldType", () => {
|
|
|
53
56
|
const action = field("make_payment_entry", "Button", { label: "Make Payment Entry" });
|
|
54
57
|
expect(action.fieldtype).toBe("Button");
|
|
55
58
|
});
|
|
59
|
+
|
|
60
|
+
it("is the one list of fieldtypes: every stock type plus the registry's custom ones", () => {
|
|
61
|
+
expect(frappeFieldTypes).toEqual([...stockFieldTypes, ...customFieldTypes]);
|
|
62
|
+
expect(new Set(frappeFieldTypes).size).toBe(frappeFieldTypes.length);
|
|
63
|
+
expect(stockFieldTypes).toContain("Fold");
|
|
64
|
+
expect(stockFieldTypes).toHaveLength(43);
|
|
65
|
+
const fold: FrappeFieldType = "Fold";
|
|
66
|
+
const toggle: FrappeFieldType = "Toggle Group";
|
|
67
|
+
expect([fold, toggle].every((t) => frappeFieldTypes.includes(t))).toBe(true);
|
|
68
|
+
// @ts-expect-error a fieldtype outside the union is not a DocTypeField
|
|
69
|
+
field("bogus", "Not A Fieldtype");
|
|
70
|
+
});
|
|
56
71
|
});
|
|
57
72
|
|
|
58
73
|
// ---------------------------------------------------------------------------
|
|
@@ -141,7 +156,7 @@ describe("parseFormLayout", () => {
|
|
|
141
156
|
});
|
|
142
157
|
|
|
143
158
|
it("skips hidden fields", () => {
|
|
144
|
-
const fields = [field("visible", "Data"), field("secret", "Data", { hidden:
|
|
159
|
+
const fields = [field("visible", "Data"), field("secret", "Data", { hidden: 1 })];
|
|
145
160
|
const sections = parseFormLayout(fields);
|
|
146
161
|
expect(sections[0].columns[0].fields).toHaveLength(1);
|
|
147
162
|
expect(sections[0].columns[0].fields[0].fieldname).toBe("visible");
|
|
@@ -150,7 +165,7 @@ describe("parseFormLayout", () => {
|
|
|
150
165
|
it("starts a new section on Section Break", () => {
|
|
151
166
|
const fields = [
|
|
152
167
|
field("field1", "Data"),
|
|
153
|
-
field("sec", "Section Break", { label: "Details", collapsible:
|
|
168
|
+
field("sec", "Section Break", { label: "Details", collapsible: 1 }),
|
|
154
169
|
field("field2", "Data"),
|
|
155
170
|
];
|
|
156
171
|
const sections = parseFormLayout(fields);
|
|
@@ -227,7 +242,7 @@ describe("parseFormLayout", () => {
|
|
|
227
242
|
|
|
228
243
|
it("drops a leading section whose fields are all hidden", () => {
|
|
229
244
|
const fields = [
|
|
230
|
-
field("secret", "Data", { hidden:
|
|
245
|
+
field("secret", "Data", { hidden: 1 }),
|
|
231
246
|
field("sec", "Section Break", { label: "Details" }),
|
|
232
247
|
field("field1", "Data"),
|
|
233
248
|
];
|
|
@@ -250,7 +265,7 @@ describe("parseFormLayout", () => {
|
|
|
250
265
|
});
|
|
251
266
|
|
|
252
267
|
it("keeps one section for a fieldless doctype", () => {
|
|
253
|
-
const sections = parseFormLayout([field("secret", "Data", { hidden:
|
|
268
|
+
const sections = parseFormLayout([field("secret", "Data", { hidden: 1 })]);
|
|
254
269
|
expect(sections).toHaveLength(1);
|
|
255
270
|
expect(sections[0].columns[0].fields).toHaveLength(0);
|
|
256
271
|
});
|
|
@@ -295,7 +310,58 @@ describe("useDocTypeMeta", () => {
|
|
|
295
310
|
expect(result.current.meta).toBeDefined();
|
|
296
311
|
expect(result.current.meta!.name).toBe(doctype);
|
|
297
312
|
expect(result.current.meta!.fields).toHaveLength(2);
|
|
298
|
-
expect(result.current.meta!.permissions[0]
|
|
313
|
+
expect(result.current.meta!.permissions?.[0]?.read).toBe(1);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// FrappeForm read this hook's meta, and the old parse copied seventeen keys
|
|
317
|
+
// and dropped the rest, so permlevel, fetch_from, set_only_once and the
|
|
318
|
+
// *_depends_on chains never reached a form. The meta is the server's own
|
|
319
|
+
// now, keys and 0|1 flags alike.
|
|
320
|
+
it("keeps every key the server sends, on the fields and on the meta", async () => {
|
|
321
|
+
const doctype = `DocLossless${testId}`;
|
|
322
|
+
const config = { baseURL: `https://meta-lossless-${testId}.example.com` };
|
|
323
|
+
const raw = {
|
|
324
|
+
...rawDocType(doctype),
|
|
325
|
+
is_submittable: 1,
|
|
326
|
+
links: [{ link_doctype: "Payment Entry", link_fieldname: "reference_name", group: null }],
|
|
327
|
+
fields: [
|
|
328
|
+
{
|
|
329
|
+
fieldname: "customer",
|
|
330
|
+
fieldtype: "Link",
|
|
331
|
+
options: "Customer",
|
|
332
|
+
reqd: 1,
|
|
333
|
+
set_only_once: 1,
|
|
334
|
+
permlevel: 1,
|
|
335
|
+
},
|
|
336
|
+
{ fieldname: "customer_name", fieldtype: "Data", fetch_from: "customer.customer_name" },
|
|
337
|
+
{
|
|
338
|
+
fieldname: "po_no",
|
|
339
|
+
fieldtype: "Data",
|
|
340
|
+
mandatory_depends_on: "eval:doc.is_export",
|
|
341
|
+
read_only_depends_on: "eval:doc.docstatus==1",
|
|
342
|
+
allow_on_submit: 1,
|
|
343
|
+
},
|
|
344
|
+
{ fieldname: "more", fieldtype: "Section Break", collapsible_depends_on: "po_no" },
|
|
345
|
+
],
|
|
346
|
+
};
|
|
347
|
+
mockGetFn.mockResolvedValueOnce({ payload: { docs: [raw] } });
|
|
348
|
+
|
|
349
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
350
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
351
|
+
|
|
352
|
+
const meta = result.current.meta!;
|
|
353
|
+
expect(meta.is_submittable).toBe(1);
|
|
354
|
+
expect(meta.links?.[0]?.link_doctype).toBe("Payment Entry");
|
|
355
|
+
const byName = Object.fromEntries(meta.fields.map((f) => [f.fieldname, f]));
|
|
356
|
+
expect(byName.customer).toMatchObject({ reqd: 1, set_only_once: 1, permlevel: 1 });
|
|
357
|
+
expect(byName.customer_name.fetch_from).toBe("customer.customer_name");
|
|
358
|
+
expect(byName.po_no).toMatchObject({
|
|
359
|
+
mandatory_depends_on: "eval:doc.is_export",
|
|
360
|
+
read_only_depends_on: "eval:doc.docstatus==1",
|
|
361
|
+
allow_on_submit: 1,
|
|
362
|
+
});
|
|
363
|
+
expect(byName.more.collapsible_depends_on).toBe("po_no");
|
|
364
|
+
expect(meta.fields[0]).not.toBe(raw.fields[0]);
|
|
299
365
|
});
|
|
300
366
|
|
|
301
367
|
// The REST route reads the DocType *document* — System-Manager-only, so
|
|
@@ -391,6 +457,83 @@ describe("useDocTypeMeta", () => {
|
|
|
391
457
|
expect(result.current.error!.message).toBe("Not found");
|
|
392
458
|
});
|
|
393
459
|
|
|
460
|
+
// MPO-322: getdoctype and the DocType document are closed to Guest, so a
|
|
461
|
+
// signed-out visitor's meta read was a certain 403 in the browser log.
|
|
462
|
+
describe("signed out", () => {
|
|
463
|
+
const signedOut = { useToken: true, type: "Bearer", token: async () => "" };
|
|
464
|
+
|
|
465
|
+
afterEach(() => {
|
|
466
|
+
document.cookie = "user_id=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it("never asks for meta when the token source resolves empty", async () => {
|
|
470
|
+
const doctype = `DocGuest${testId}`;
|
|
471
|
+
const config = { baseURL: `https://meta-guest-${testId}.example.com`, auth: signedOut };
|
|
472
|
+
|
|
473
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
474
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
475
|
+
|
|
476
|
+
expect(mockGetFn).not.toHaveBeenCalled();
|
|
477
|
+
expect(result.current.meta).toBeUndefined();
|
|
478
|
+
expect(result.current.error).toMatchObject({ status: 403 });
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("still reads fixture meta", async () => {
|
|
482
|
+
const doctype = `DocGuestFix${testId}`;
|
|
483
|
+
const fixtures = {
|
|
484
|
+
getDoc: vi.fn(async () => rawDocType(doctype)),
|
|
485
|
+
} as unknown as NonNullable<Parameters<typeof useDocTypeMeta>[0]>["fixtures"];
|
|
486
|
+
const config = {
|
|
487
|
+
baseURL: `https://meta-guest-fix-${testId}.example.com`,
|
|
488
|
+
auth: signedOut,
|
|
489
|
+
fixtures,
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
493
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
494
|
+
|
|
495
|
+
expect(result.current.meta!.name).toBe(doctype);
|
|
496
|
+
expect(mockGetFn).not.toHaveBeenCalled();
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it("asks when a token resolves", async () => {
|
|
500
|
+
const doctype = `DocSignedIn${testId}`;
|
|
501
|
+
const config = {
|
|
502
|
+
baseURL: `https://meta-signed-in-${testId}.example.com`,
|
|
503
|
+
auth: { ...signedOut, token: async () => "jwt" },
|
|
504
|
+
};
|
|
505
|
+
mockGetFn.mockResolvedValueOnce({ payload: { docs: [rawDocType(doctype)] } });
|
|
506
|
+
|
|
507
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
508
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
509
|
+
|
|
510
|
+
expect(result.current.meta!.name).toBe(doctype);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it("asks when a Frappe desk session names a user", async () => {
|
|
514
|
+
document.cookie = "user_id=desk%40example.com; path=/";
|
|
515
|
+
const doctype = `DocDesk${testId}`;
|
|
516
|
+
const config = { baseURL: `https://meta-desk-${testId}.example.com`, auth: signedOut };
|
|
517
|
+
mockGetFn.mockResolvedValueOnce({ payload: { docs: [rawDocType(doctype)] } });
|
|
518
|
+
|
|
519
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
520
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
521
|
+
|
|
522
|
+
expect(result.current.meta!.name).toBe(doctype);
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it("asks on a cookie connection, which names no token source", async () => {
|
|
526
|
+
const doctype = `DocCookie${testId}`;
|
|
527
|
+
const config = { baseURL: `https://meta-cookie-${testId}.example.com` };
|
|
528
|
+
mockGetFn.mockRejectedValueOnce(Object.assign(new Error("Not permitted"), { status: 403 }));
|
|
529
|
+
|
|
530
|
+
const { result } = renderHook(() => useDocTypeMeta(config, doctype));
|
|
531
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
532
|
+
|
|
533
|
+
expect(mockGetFn).toHaveBeenCalledTimes(1);
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
|
|
394
537
|
it("returns undefined meta and isLoading=false when config is undefined", () => {
|
|
395
538
|
const { result } = renderHook(() => useDocTypeMeta(undefined, "AnyDoc"));
|
|
396
539
|
|