1import * as React from 'react';
2import { executeExchange } from '@urql/exchange-execute';
3import { buildSchema } from 'graphql';
4import { mount } from '@cypress/react';
5
6import {
7 Provider,
8 createClient,
9 gql,
10 useQuery,
11 useMutation,
12 debugExchange,
13} from 'urql';
14
15import { cacheExchange } from '../src';
16
17const schema = buildSchema(`
18 type Todo {
19 id: ID!
20 text: String!
21 }
22
23 type Query {
24 todos: [Todo]!
25 }
26
27 type Mutation {
28 updateTodo(id: ID! text: String!): Todo!
29 }
30`);
31
32const todos: Array<{ id: string; text: string }> = [
33 { id: '1', text: 'testing urql' },
34];
35
36const rootValue = {
37 todos: () => {
38 return todos;
39 },
40 updateTodo: args => {
41 const todo = todos.find(x => x.id === args.id);
42 if (!todo) throw new Error("Can't find todo!");
43 todo.text = args.text;
44 return todo;
45 },
46};
47
48describe('Graphcache updates', () => {
49 let client;
50 beforeEach(() => {
51 client = createClient({
52 url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
53 exchanges: [
54 cacheExchange({}),
55 debugExchange,
56 executeExchange({ schema, rootValue }),
57 ],
58 });
59 });
60
61 const TodosQuery = gql`
62 query {
63 todos {
64 id
65 text
66 }
67 }
68 `;
69
70 const UpdateMutation = gql`
71 mutation ($id: ID!, $text: String!) {
72 updateTodo(id: $id, text: $text) {
73 id
74 text
75 }
76 }
77 `;
78
79 it('Can automatically update entities who have been queried', () => {
80 const Todos = () => {
81 const [result] = useQuery({ query: TodosQuery });
82 const [, update] = useMutation(UpdateMutation);
83
84 if (result.fetching) return <p>Loading...</p>;
85
86 return (
87 <main>
88 <ul id="todos-list">
89 {result.data.todos.map(todo => (
90 <li key={todo.id}>
91 {todo.text}
92 <button
93 id={`update-${todo.id}`}
94 onClick={() => {
95 update({ id: todo.id, text: todo.text + '_foo' });
96 }}
97 >
98 Update {todo.id}
99 </button>
100 </li>
101 ))}
102 </ul>
103 </main>
104 );
105 };
106
107 mount(
108 <Provider value={client}>
109 <Todos />
110 </Provider>
111 );
112
113 const target = { ...todos[0] };
114 cy.get('#todos-list > li').then(items => {
115 expect(items.length).to.equal(todos.length);
116 });
117 cy.get('#update-' + target.id).click();
118
119 cy.wait(500);
120 cy.get('#todos-list > li').then(items => {
121 expect(items.length).to.equal(todos.length);
122 expect(items[0].innerText).to.contain(target.text + '_foo');
123 });
124 });
125});