1import { gql } from '@urql/core';
2import { it, afterEach, expect } from 'vitest';
3import { __initAnd_query as query } from '../operations/query';
4import { __initAnd_write as write } from '../operations/write';
5import { Store } from '../store/store';
6
7const Item = gql`
8 {
9 todo {
10 __typename
11 id
12 complete
13 text
14 }
15 }
16`;
17
18const ItemDetailed = gql`
19 {
20 todo {
21 __typename
22 id
23 details {
24 __typename
25 authors {
26 __typename
27 id
28 }
29 }
30 }
31 }
32`;
33
34const Pagination = gql`
35 query {
36 todos {
37 __typename
38 edges {
39 __typename
40 node {
41 __typename
42 id
43 complete
44 text
45 }
46 }
47 pageInfo {
48 __typename
49 hasNextPage
50 endCursor
51 }
52 }
53 }
54`;
55
56afterEach(() => {
57 expect(console.warn).not.toHaveBeenCalled();
58});
59
60it('allows custom resolvers to resolve nested, unkeyed data', () => {
61 const store = new Store({
62 resolvers: {
63 Query: {
64 todos: () => ({
65 __typename: 'TodosConnection',
66 edges: [
67 {
68 __typename: 'TodoEdge',
69 node: {
70 __typename: 'Todo',
71 id: '1',
72 // The `complete` field will be overwritten here, but we're
73 // leaving out the `text` field
74 complete: true,
75 },
76 },
77 ],
78 pageInfo: {
79 __typename: 'PageInfo',
80 hasNextPage: true,
81 endCursor: '1',
82 },
83 }),
84 },
85 },
86 });
87
88 write(
89 store,
90 { query: Item },
91 {
92 __typename: 'Query',
93 todo: {
94 __typename: 'Todo',
95 id: '1',
96 complete: false,
97 text: 'Example',
98 },
99 }
100 );
101
102 const res = query(store, { query: Pagination });
103
104 expect(res.partial).toBe(false);
105
106 expect(res.data).toEqual({
107 todos: {
108 __typename: 'TodosConnection',
109 edges: [
110 {
111 __typename: 'TodoEdge',
112 node: {
113 __typename: 'Todo',
114 id: '1',
115 complete: true, // This is now true and not false!
116 text: 'Example', // This is still present
117 },
118 },
119 ],
120 pageInfo: {
121 __typename: 'PageInfo',
122 hasNextPage: true,
123 endCursor: '1',
124 },
125 },
126 });
127});
128
129it('allows custom resolvers to resolve nested, unkeyed data with embedded links', () => {
130 const store = new Store({
131 resolvers: {
132 Query: {
133 todos: (_, __, cache) => ({
134 __typename: 'TodosConnection',
135 edges: [
136 {
137 __typename: 'TodoEdge',
138 // This is a key instead of the full entity:
139 node: cache.keyOfEntity({ __typename: 'Todo', id: '1' }),
140 },
141 ],
142 pageInfo: {
143 __typename: 'PageInfo',
144 hasNextPage: true,
145 endCursor: '1',
146 },
147 }),
148 },
149 },
150 });
151
152 write(
153 store,
154 { query: Item },
155 {
156 __typename: 'Query',
157 todo: {
158 __typename: 'Todo',
159 id: '1',
160 complete: false,
161 text: 'Example',
162 },
163 }
164 );
165
166 const res = query(store, { query: Pagination });
167 expect(res.partial).toBe(false);
168 expect(res.data).toEqual({
169 todos: {
170 __typename: 'TodosConnection',
171 edges: [
172 {
173 __typename: 'TodoEdge',
174 node: {
175 __typename: 'Todo',
176 id: '1',
177 complete: false,
178 text: 'Example',
179 },
180 },
181 ],
182 pageInfo: {
183 __typename: 'PageInfo',
184 hasNextPage: true,
185 endCursor: '1',
186 },
187 },
188 });
189});
190
191it('allows custom resolvers to resolve mixed data (keyable and unkeyable)', () => {
192 const store = new Store({
193 keys: {
194 TodoDetails: () => null,
195 },
196 resolvers: {
197 Query: {
198 todo: () => ({
199 __typename: 'Todo',
200 id: '1',
201 details: {
202 __typename: 'TodoDetails',
203 },
204 }),
205 },
206 },
207 });
208
209 write(
210 store,
211 { query: ItemDetailed },
212 {
213 __typename: 'Query',
214 todo: {
215 __typename: 'Todo',
216 id: '1',
217 details: {
218 __typename: 'TodoDetails',
219 authors: [
220 {
221 __typename: 'Author',
222 id: 'x',
223 },
224 ],
225 },
226 },
227 }
228 );
229
230 const res = query(store, { query: ItemDetailed });
231 expect(res.partial).toBe(false);
232 expect(res.dependencies.has('Author:x')).toBeTruthy();
233 expect(res.data).toEqual({
234 todo: {
235 __typename: 'Todo',
236 id: '1',
237 details: {
238 __typename: 'TodoDetails',
239 authors: [
240 {
241 __typename: 'Author',
242 id: 'x',
243 },
244 ],
245 },
246 },
247 });
248});