-
Notifications
You must be signed in to change notification settings - Fork 145
Expand file tree
/
Copy pathdocs.spec.ts
More file actions
140 lines (113 loc) · 4.14 KB
/
Copy pathdocs.spec.ts
File metadata and controls
140 lines (113 loc) · 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// @vitest-environment happy-dom
import { buildSchema } from 'graphql';
import { act, renderHook } from '@testing-library/react';
import { docsTargetFromPath, useDocs } from './docs';
const schema = buildSchema(`
interface Node { id: ID! }
type Address { city: String }
type Profile implements Node { id: ID!, address: Address }
type User implements Node { id: ID!, profile: Profile }
type Query { me: User }
type Mutation { signIn: User }
`);
describe('docsTargetFromPath', () => {
it('resolves a root field to its operation type', () => {
expect(docsTargetFromPath(['query', 'me'], schema)).toEqual({
kind: 'field',
typeName: 'Query',
fieldName: 'me',
});
});
it('resolves a nested field to its immediate parent type', () => {
expect(docsTargetFromPath(['query', 'me', 'profile', 'address'], schema)).toEqual({
kind: 'field',
typeName: 'Profile',
fieldName: 'address',
});
});
it('walks through interfaces', () => {
expect(docsTargetFromPath(['query', 'me', 'profile', 'id'], schema)).toEqual({
kind: 'field',
typeName: 'Profile',
fieldName: 'id',
});
});
it('resolves mutation roots', () => {
expect(docsTargetFromPath(['mutation', 'signIn'], schema)).toEqual({
kind: 'field',
typeName: 'Mutation',
fieldName: 'signIn',
});
});
it('returns null for an unknown field', () => {
expect(docsTargetFromPath(['query', 'nope'], schema)).toBeNull();
});
it('returns null for an operation the schema does not define', () => {
expect(docsTargetFromPath(['subscription', 'anything'], schema)).toBeNull();
});
it('returns null without a schema or a field segment', () => {
expect(docsTargetFromPath(['query', 'me'], null)).toBeNull();
expect(docsTargetFromPath(['query'], schema)).toBeNull();
});
});
describe('useDocs', () => {
it('starts on the root view', () => {
const { result } = renderHook(() => useDocs({}));
expect(result.current.docsNavStack).toEqual([]);
expect(result.current.activePanel).toBeNull();
});
it('honours the default active panel', () => {
const { result } = renderHook(() => useDocs({ defaultActivePanel: 'collections' }));
expect(result.current.activePanel).toBe('collections');
});
it('opens the pane and pushes the target in one step', () => {
const { result } = renderHook(() => useDocs({}));
act(() => {
result.current.openDocs({ kind: 'type', name: 'User' });
});
expect(result.current.activePanel).toBe('docs');
expect(result.current.docsNavStack).toEqual([{ kind: 'type', name: 'User' }]);
});
it('opens the pane without a target, leaving the stack alone', () => {
const { result } = renderHook(() => useDocs({}));
act(() => {
result.current.openDocs();
});
expect(result.current.activePanel).toBe('docs');
expect(result.current.docsNavStack).toEqual([]);
});
it('pops back one level at a time', () => {
const { result } = renderHook(() => useDocs({}));
act(() => {
result.current.pushDocs({ kind: 'type', name: 'User' });
});
act(() => {
result.current.pushDocs({ kind: 'field', typeName: 'User', fieldName: 'id' });
});
act(() => {
result.current.popDocs();
});
expect(result.current.docsNavStack).toEqual([{ kind: 'type', name: 'User' }]);
});
it('resets all the way to the root', () => {
const { result } = renderHook(() => useDocs({}));
act(() => {
result.current.pushDocs({ kind: 'type', name: 'User' });
});
act(() => {
result.current.resetDocs();
});
expect(result.current.docsNavStack).toEqual([]);
});
it('holds targets by name so a schema swap cannot strand the stack', () => {
const { result } = renderHook(() => useDocs({}));
act(() => {
result.current.pushDocs({ kind: 'field', typeName: 'User', fieldName: 'id' });
});
// Nothing in the stack references a GraphQLSchema object, so a new schema
// instance leaves it re-resolvable rather than pointing at a detached type.
expect(result.current.docsNavStack).toEqual([
{ kind: 'field', typeName: 'User', fieldName: 'id' },
]);
});
});