@cedarjs/web 6.0.0-canary.2672 → 6.0.0-canary.2675

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.
@@ -1,202 +0,0 @@
1
- import React from "react";
2
- import { useApolloClient, useFragment, useQuery } from "@apollo/client/react";
3
- import { render, screen } from "@testing-library/react";
4
- import { parse } from "graphql";
5
- import { vi, describe, beforeAll, beforeEach, test, expect } from "vitest";
6
- import { fragmentRegistry } from "../../apollo/fragmentRegistry.js";
7
- import { createCell } from "./createCell.js";
8
- vi.mock("@apollo/client/react", async (importOriginal) => {
9
- const actual = await importOriginal();
10
- return {
11
- ...actual,
12
- useApolloClient: vi.fn(),
13
- useFragment: vi.fn(),
14
- useQuery: vi.fn()
15
- };
16
- });
17
- const mockUseApolloClient = useApolloClient;
18
- const mockApolloUseFragment = useFragment;
19
- const mockUseQuery = useQuery;
20
- const AUTHOR_FRAGMENT = parse(`
21
- fragment AuthorCell_author on User {
22
- email
23
- fullName
24
- }
25
- `);
26
- describe("createFragmentCell", () => {
27
- beforeAll(() => {
28
- globalThis.RWJS_ENV = {
29
- RWJS_EXP_STREAMING_SSR: false
30
- };
31
- });
32
- beforeEach(() => {
33
- mockApolloUseFragment.mockReset();
34
- mockUseApolloClient.mockReset();
35
- mockUseApolloClient.mockReturnValue({
36
- cache: {
37
- identify: (obj) => obj.__typename && obj.id !== void 0 ? `${obj.__typename}:${obj.id}` : void 0
38
- }
39
- });
40
- mockApolloUseFragment.mockReturnValue({ data: void 0, complete: false });
41
- });
42
- test("renders Success with data from its data prop", () => {
43
- const TestCell = createCell({
44
- FRAGMENT: AUTHOR_FRAGMENT,
45
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
46
- });
47
- render(
48
- /* @__PURE__ */ React.createElement(
49
- TestCell,
50
- {
51
- author: { __typename: "User", id: 1, fullName: "Story Teller" }
52
- }
53
- )
54
- );
55
- screen.getByText(/^By Story Teller$/);
56
- });
57
- test("prefers complete data from the cache", () => {
58
- const TestCell = createCell({
59
- FRAGMENT: AUTHOR_FRAGMENT,
60
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
61
- });
62
- mockApolloUseFragment.mockImplementation((options) => {
63
- expect(options.fragmentName).toEqual("AuthorCell_author");
64
- expect(options.from).toEqual("User:1");
65
- return {
66
- data: { fullName: "Cache Dweller" },
67
- complete: true
68
- };
69
- });
70
- render(/* @__PURE__ */ React.createElement(TestCell, { author: { __typename: "User", id: 1 } }));
71
- screen.getByText(/^By Cache Dweller$/);
72
- });
73
- test("falls back to the data prop for incomplete cache reads", () => {
74
- const TestCell = createCell({
75
- FRAGMENT: AUTHOR_FRAGMENT,
76
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
77
- });
78
- mockApolloUseFragment.mockReturnValue({ data: void 0, complete: false });
79
- render(
80
- /* @__PURE__ */ React.createElement(
81
- TestCell,
82
- {
83
- author: { __typename: "User", id: 1, fullName: "Ref Reader" }
84
- }
85
- )
86
- );
87
- screen.getByText(/^By Ref Reader$/);
88
- });
89
- test("derives the prop name from the fragment type when there is no underscore", () => {
90
- const TestCell = createCell({
91
- FRAGMENT: parse(`
92
- fragment AuthorBio on User {
93
- bio
94
- }
95
- `),
96
- Success: ({ user }) => /* @__PURE__ */ React.createElement(React.Fragment, null, user.bio)
97
- });
98
- render(
99
- /* @__PURE__ */ React.createElement(TestCell, { user: { __typename: "User", id: 1, bio: "Writes things" } })
100
- );
101
- screen.getByText(/^Writes things$/);
102
- });
103
- test("renders Empty when isEmpty says so", () => {
104
- const TestCell = createCell({
105
- FRAGMENT: AUTHOR_FRAGMENT,
106
- isEmpty: () => true,
107
- Empty: () => /* @__PURE__ */ React.createElement(React.Fragment, null, "Nothing to see"),
108
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
109
- });
110
- render(
111
- /* @__PURE__ */ React.createElement(TestCell, { author: { __typename: "User", id: 1, fullName: "Nobody" } })
112
- );
113
- screen.getByText(/^Nothing to see$/);
114
- });
115
- test("applies afterQuery to the fragment data", () => {
116
- const TestCell = createCell({
117
- FRAGMENT: AUTHOR_FRAGMENT,
118
- afterQuery: (data) => ({
119
- author: { ...data.author, fullName: "Changed Name" }
120
- }),
121
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
122
- });
123
- render(
124
- /* @__PURE__ */ React.createElement(
125
- TestCell,
126
- {
127
- author: { __typename: "User", id: 1, fullName: "Original Name" }
128
- }
129
- )
130
- );
131
- screen.getByText(/^By Changed Name$/);
132
- });
133
- test("renders Empty when the data prop is null", () => {
134
- const TestCell = createCell({
135
- FRAGMENT: AUTHOR_FRAGMENT,
136
- Empty: () => /* @__PURE__ */ React.createElement(React.Fragment, null, "No author"),
137
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
138
- });
139
- render(/* @__PURE__ */ React.createElement(TestCell, { author: null }));
140
- screen.getByText(/^No author$/);
141
- });
142
- test("renders Success with null data when the data prop is null and there is no Empty", () => {
143
- const TestCell = createCell({
144
- FRAGMENT: AUTHOR_FRAGMENT,
145
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author?.fullName ?? "unknown")
146
- });
147
- render(/* @__PURE__ */ React.createElement(TestCell, { author: null }));
148
- screen.getByText(/^By unknown$/);
149
- });
150
- test("throws a helpful error naming the prop when it is not passed", () => {
151
- const TestCell = createCell({
152
- FRAGMENT: AUTHOR_FRAGMENT,
153
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName),
154
- displayName: "AuthorCell"
155
- });
156
- const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {
157
- });
158
- try {
159
- expect(() => {
160
- render(/* @__PURE__ */ React.createElement(TestCell, null));
161
- }).toThrow(/`author` prop/);
162
- } finally {
163
- consoleErrorSpy.mockRestore();
164
- }
165
- });
166
- test("stays a query Cell when both QUERY and FRAGMENT are exported", () => {
167
- const TestCell = createCell({
168
- // @ts-expect-error - Purposefully using a plain string here.
169
- QUERY: "query AuthorQuery { author { fullName } }",
170
- FRAGMENT: AUTHOR_FRAGMENT,
171
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
172
- });
173
- mockUseQuery.mockImplementation(() => {
174
- return { data: { author: { fullName: "Query Result" } } };
175
- });
176
- render(/* @__PURE__ */ React.createElement(TestCell, null));
177
- screen.getByText(/^By Query Result$/);
178
- });
179
- test("registers the FRAGMENT even when the Cell stays a query Cell", () => {
180
- createCell({
181
- // @ts-expect-error - Purposefully using a plain string here.
182
- QUERY: "query MixedExportQuery { author { fullName } }",
183
- // Using a unique fragment name since the registry is shared between
184
- // tests
185
- FRAGMENT: parse(`
186
- fragment MixedExportCell_author on User {
187
- fullName
188
- }
189
- `),
190
- Success: ({ author }) => /* @__PURE__ */ React.createElement(React.Fragment, null, "By ", author.fullName)
191
- });
192
- expect(fragmentRegistry.lookup("MixedExportCell_author")).toBeTruthy();
193
- });
194
- test("throws when the FRAGMENT export is not a fragment", () => {
195
- expect(
196
- () => createCell({
197
- FRAGMENT: parse("query FindAuthor { author { id } }"),
198
- Success: () => /* @__PURE__ */ React.createElement(React.Fragment, null, "hello")
199
- })
200
- ).toThrow(/fragment definition/);
201
- });
202
- });
@@ -1,73 +0,0 @@
1
- import React from "react";
2
- import { loadErrorMessages, loadDevMessages } from "@apollo/client/dev";
3
- import { useBackgroundQuery, useReadQuery } from "@apollo/client/react";
4
- import { render, screen } from "@testing-library/react";
5
- import { vi, describe, beforeAll, beforeEach, test } from "vitest";
6
- import { createSuspendingCell } from "./createSuspendingCell.js";
7
- vi.mock("@apollo/client/react", () => {
8
- return {
9
- useApolloClient: vi.fn(),
10
- useBackgroundQuery: vi.fn(),
11
- useReadQuery: vi.fn()
12
- };
13
- });
14
- const mockUseBackgroundQuery = useBackgroundQuery;
15
- const mockUseReadQuery = useReadQuery;
16
- describe("createSuspendingCell", () => {
17
- beforeAll(() => {
18
- globalThis.RWJS_ENV = {
19
- RWJS_EXP_STREAMING_SSR: true
20
- };
21
- loadDevMessages();
22
- loadErrorMessages();
23
- });
24
- beforeEach(() => {
25
- mockUseReadQuery.mockReset();
26
- mockUseBackgroundQuery.mockReset();
27
- mockUseBackgroundQuery.mockImplementation(() => {
28
- return ["mocked-query-ref", { refetch: vi.fn(), fetchMore: vi.fn() }];
29
- });
30
- });
31
- test("Renders a static Success component", () => {
32
- const TestCell = createSuspendingCell({
33
- // @ts-expect-error - Purposefully using a plain string here.
34
- QUERY: "query TestQuery { answer }",
35
- Success: () => /* @__PURE__ */ React.createElement(React.Fragment, null, "Great success!")
36
- });
37
- mockUseReadQuery.mockImplementation(() => ({ data: {} }));
38
- render(/* @__PURE__ */ React.createElement(TestCell, null));
39
- screen.getByText(/^Great success!$/);
40
- });
41
- test("Renders Success with data", () => {
42
- const TestCell = createSuspendingCell({
43
- // @ts-expect-error - Purposefully using a plain string here.
44
- QUERY: "query TestQuery { answer }",
45
- Success: ({ answer }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("dl", null, /* @__PURE__ */ React.createElement("dt", null, "What's the meaning of life?"), /* @__PURE__ */ React.createElement("dd", null, answer)))
46
- });
47
- mockUseReadQuery.mockImplementation(() => {
48
- return { data: { answer: 42 } };
49
- });
50
- render(/* @__PURE__ */ React.createElement(TestCell, null));
51
- screen.getByText(/^What's the meaning of life\?$/);
52
- screen.getByText(/^42$/);
53
- });
54
- test("Renders Success if any of the fields have data (i.e. not just the first)", () => {
55
- const TestCell = createSuspendingCell({
56
- // @ts-expect-error - Purposefully using a plain string here.
57
- QUERY: "query TestQuery { users { name } posts { title } }",
58
- Empty: () => /* @__PURE__ */ React.createElement(React.Fragment, null, "No users or posts"),
59
- Success: ({ users, posts }) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", null, users.length > 0 ? /* @__PURE__ */ React.createElement("ul", null, users.map(({ name }) => /* @__PURE__ */ React.createElement("li", { key: name }, name))) : "no users"), /* @__PURE__ */ React.createElement("div", null, posts.length > 0 ? /* @__PURE__ */ React.createElement("ul", null, posts.map(({ title }) => /* @__PURE__ */ React.createElement("li", { key: title }, title))) : "no posts"))
60
- });
61
- mockUseReadQuery.mockImplementation(() => {
62
- return {
63
- data: {
64
- users: [],
65
- posts: [{ title: "bazinga" }, { title: "kittens" }]
66
- }
67
- };
68
- });
69
- render(/* @__PURE__ */ React.createElement(TestCell, null));
70
- screen.getByText(/bazinga/);
71
- screen.getByText(/kittens/);
72
- });
73
- });