Skip to content

Commit 677b1c8

Browse files
committed
Added more unit tests
1 parent b320e5e commit 677b1c8

3 files changed

Lines changed: 307 additions & 9 deletions

File tree

endpoints/Endpoint.test.ts

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
import fetchMock from 'jest-fetch-mock';
2+
import { Endpoint, EntryEndpoint } from '.';
3+
import { HttpMethod, HttpHeader, HttpStatusCode } from '../http';
4+
import { ActionEndpoint } from './rpc';
5+
import { ConflictError } from '../errors';
6+
7+
class CustomEndpoint extends Endpoint {
8+
async get() { await this.send(HttpMethod.Get); }
9+
10+
isMethodAllowedPublic(method: HttpMethod) { return this.isMethodAllowed(method); }
11+
}
12+
13+
fetchMock.enableMocks();
14+
let endpoint: CustomEndpoint;
15+
16+
beforeEach(() => {
17+
fetchMock.resetMocks();
18+
endpoint = new CustomEndpoint(new EntryEndpoint('http://localhost/'), 'endpoint');
19+
});
20+
21+
test('acceptHeader', async () => {
22+
fetchMock.mockOnceIf(
23+
req => req.url === 'http://localhost/endpoint',
24+
async req => {
25+
expect(req.headers.get(HttpHeader.Accept)).toBe('application/json');
26+
return {};
27+
}
28+
);
29+
30+
await endpoint.get();
31+
});
32+
33+
test('allowHeader', async () => {
34+
fetchMock.mockOnceIf('http://localhost/endpoint',
35+
'{}',
36+
{
37+
headers: {
38+
[HttpHeader.Allow]: HttpMethod.Put + ", " + HttpMethod.Post
39+
}
40+
});
41+
await endpoint.get();
42+
43+
expect(endpoint.isMethodAllowedPublic(HttpMethod.Put)).toBe(true);
44+
expect(endpoint.isMethodAllowedPublic(HttpMethod.Post)).toBe(true);
45+
expect(endpoint.isMethodAllowedPublic(HttpMethod.Delete)).toBe(false);
46+
});
47+
48+
test('link', async () => {
49+
fetchMock.mockOnceIf('http://localhost/endpoint',
50+
'{}',
51+
{
52+
headers: {
53+
[HttpHeader.Link]: '<a>; rel=target1, <b>; rel=target2'
54+
}
55+
});
56+
await endpoint.get();
57+
58+
expect(endpoint.link('target1')).toEqual(new URL('http://localhost/a'));
59+
expect(endpoint.link('target2')).toEqual(new URL('http://localhost/b'));
60+
});
61+
62+
test('linkAbsolute', async () => {
63+
fetchMock.mockOnceIf('http://localhost/endpoint',
64+
'{}',
65+
{
66+
headers: {
67+
[HttpHeader.Link]: '<http://localhost/b>; rel=target1'
68+
}
69+
});
70+
await endpoint.get();
71+
72+
expect(endpoint.link('target1')).toEqual(new URL('http://localhost/b'));
73+
});
74+
75+
test('linkError', async () => {
76+
fetchMock.mockOnceIf('http://localhost/endpoint',
77+
'{}',
78+
{
79+
headers: {
80+
[HttpHeader.Link]: '<http://localhost/a>; rel=target1'
81+
}
82+
});
83+
await endpoint.get();
84+
85+
expect(() => endpoint.link('target2')).toThrow();
86+
});
87+
88+
test('getLinks', async () => {
89+
fetchMock.mockOnceIf('http://localhost/endpoint',
90+
'{}',
91+
{
92+
headers: {
93+
[HttpHeader.Link]: '<target1>; rel=child; title=Title, <target2>; rel=child'
94+
}
95+
});
96+
await endpoint.get();
97+
98+
expect(endpoint.getLinks('child')).toEqual([
99+
{ uri: new URL('http://localhost/target1'), title: 'Title' },
100+
{ uri: new URL('http://localhost/target2') }
101+
]);
102+
});
103+
104+
test('getLinksEscaping', async () => {
105+
fetchMock.mockOnceIf('http://localhost/endpoint',
106+
'{}',
107+
{
108+
headers: {
109+
[HttpHeader.Link]: '<target1>; rel=child; title="Title,= 1", <target2>; rel=child'
110+
}
111+
});
112+
await endpoint.get();
113+
114+
expect(endpoint.getLinks('child')).toEqual([
115+
{ uri: new URL('http://localhost/target1'), title: 'Title,= 1' },
116+
{ uri: new URL('http://localhost/target2') }
117+
]);
118+
});
119+
120+
test('setDefaultLink', () => {
121+
endpoint.setDefaultLink('child', 'target');
122+
expect(endpoint.link('child')).toEqual(new URL('http://localhost/target'));
123+
});
124+
125+
test('linkTemplate', async () => {
126+
fetchMock.mockOnceIf('http://localhost/endpoint',
127+
'{}',
128+
{
129+
headers: {
130+
[HttpHeader.Link]: '<a{?x}>; rel=child; templated=true'
131+
}
132+
});
133+
await endpoint.get();
134+
135+
expect(endpoint.getLinkTemplate('child')).toBe('a{?x}');
136+
});
137+
138+
test('linkTemplateResolve', async () => {
139+
fetchMock.mockOnceIf('http://localhost/endpoint',
140+
'{}',
141+
{
142+
headers: {
143+
[HttpHeader.Link]: '<a{?x}>; rel=child; templated=true'
144+
}
145+
});
146+
await endpoint.get();
147+
148+
expect(endpoint.linkTemplate('child', { x: '1' }))
149+
.toEqual(new URL('http://localhost/a?x=1'));
150+
});
151+
152+
test('linkTemplateResolveAbsolute', async () => {
153+
fetchMock.mockOnceIf('http://localhost/endpoint',
154+
'{}',
155+
{
156+
headers: {
157+
[HttpHeader.Link]: '<http://localhost/b{?x}>; rel=child; templated=true'
158+
}
159+
});
160+
await endpoint.get();
161+
162+
expect(endpoint.linkTemplate('child', { x: '1' }))
163+
.toEqual(new URL('http://localhost/b?x=1'));
164+
});
165+
166+
test('linkTemplateResolveQuery', async () => {
167+
fetchMock.mockOnceIf('http://localhost/endpoint',
168+
'{}',
169+
{
170+
headers: {
171+
[HttpHeader.Link]: '<http://localhost/b{?x,y}>; rel=search; templated=true'
172+
}
173+
});
174+
await endpoint.get();
175+
176+
expect(endpoint.linkTemplate('search', { x: '1', y: '2' }))
177+
.toEqual(new URL('http://localhost/b?x=1&y=2'));
178+
});
179+
180+
test('linkTemplateError', async () => {
181+
fetchMock.mockOnceIf('http://localhost/endpoint',
182+
'{}',
183+
{
184+
headers: {
185+
[HttpHeader.Link]: '<a>; rel=child; templated=true'
186+
}
187+
});
188+
await endpoint.get();
189+
190+
expect(() => endpoint.getLinkTemplate('child2')).toThrow();
191+
});
192+
193+
test('linkHal', async () => {
194+
fetchMock.mockOnceIf('http://localhost/endpoint',
195+
JSON.stringify({
196+
_links: {
197+
single: { href: 'a' },
198+
collection: [{ href: 'b', title: 'Title 1' }, { href: 'c' }],
199+
template: [{ href: '{id}', templated: true }]
200+
}
201+
}),
202+
{
203+
headers: {
204+
[HttpHeader.ContentType]: 'application/hal+json'
205+
}
206+
});
207+
await endpoint.get();
208+
209+
expect(endpoint.link('single')).toEqual(new URL('http://localhost/a'));
210+
expect(endpoint.getLinks('collection')).toEqual([
211+
{ uri: new URL('http://localhost/b'), title: 'Title 1' },
212+
{ uri: new URL('http://localhost/c') }
213+
]);
214+
expect(endpoint.getLinkTemplate('template')).toEqual('{id}');
215+
});
216+
217+
test('setDefaultLinkTemplate', () => {
218+
endpoint.setDefaultLinkTemplate('child', 'a');
219+
expect(endpoint.getLinkTemplate('child')).toBe('a');
220+
});
221+
222+
test('ensureTrailingSlashOnReferrerUri', () => {
223+
expect(new ActionEndpoint(endpoint, 'subresource').uri).toEqual(new URL('http://localhost/subresource'));
224+
expect(new ActionEndpoint(endpoint, './subresource').uri).toEqual(new URL('http://localhost/endpoint/subresource'));
225+
});
226+
227+
test('errorHandlingWithNoContent', async () => {
228+
fetchMock.mockOnceIf('http://localhost/endpoint',
229+
'{}',
230+
{
231+
status: HttpStatusCode.Conflict
232+
});
233+
234+
let errorThrown = false;
235+
try {
236+
await endpoint.get();
237+
} catch (err) {
238+
errorThrown = err instanceof ConflictError;
239+
}
240+
expect(errorThrown).toBe(true);
241+
});
242+
243+
test('errorHandlingWithMessage', async () => {
244+
fetchMock.mockOnceIf('http://localhost/endpoint',
245+
'{"message":"my message"}',
246+
{
247+
status: HttpStatusCode.Conflict,
248+
headers: {
249+
[HttpHeader.ContentType]: 'application/json'
250+
}
251+
});
252+
253+
let errorThrown = false;
254+
try {
255+
await endpoint.get();
256+
} catch (err) {
257+
errorThrown = err instanceof ConflictError && err.message === 'my message';
258+
}
259+
expect(errorThrown).toBe(true);
260+
});
261+
262+
test('errorHandlingWithArray', async () => {
263+
fetchMock.mockOnceIf('http://localhost/endpoint',
264+
'[{"message":"my message"}]',
265+
{
266+
status: HttpStatusCode.Conflict,
267+
headers: {
268+
[HttpHeader.ContentType]: 'application/json'
269+
}
270+
});
271+
272+
let errorThrown = false;
273+
try {
274+
await endpoint.get();
275+
} catch (err) {
276+
errorThrown = err instanceof ConflictError;
277+
}
278+
expect(errorThrown).toBe(true);
279+
});
280+
281+
test('errorHandlingWithUnknownContentType', async () => {
282+
fetchMock.mockOnceIf('http://localhost/endpoint',
283+
'...',
284+
{
285+
status: HttpStatusCode.Conflict,
286+
headers: {
287+
[HttpHeader.ContentType]: 'dummy/type'
288+
}
289+
});
290+
291+
let errorThrown = false;
292+
try {
293+
await endpoint.get();
294+
} catch (err) {
295+
errorThrown = err instanceof ConflictError;
296+
}
297+
expect(errorThrown).toBe(true);
298+
});

endpoints/generic/CollectionEndpoint.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ beforeEach(() => {
1616
});
1717

1818
test('getById', () => {
19-
expect(endpoint.get('x/y').uri.href).toBe('http://localhost/endpoint/x%2Fy');
19+
expect(endpoint.get('x/y').uri).toEqual(new URL('http://localhost/endpoint/x%2Fy'));
2020
});
2121

2222
test('getByIdWithLinkHeaderRelative', async () => {
@@ -31,7 +31,7 @@ test('getByIdWithLinkHeaderRelative', async () => {
3131
);
3232
await endpoint.readAll();
3333

34-
expect(endpoint.get('1').uri.href).toBe('http://localhost/children?id=1');
34+
expect(endpoint.get('1').uri).toEqual(new URL('http://localhost/children?id=1'));
3535
});
3636

3737
test('getByIdWithLinkHeaderAbsolute', async () => {
@@ -46,11 +46,11 @@ test('getByIdWithLinkHeaderAbsolute', async () => {
4646
);
4747
await endpoint.readAll();
4848

49-
expect(endpoint.get('1').uri.href).toBe('http://localhost/children?id=1');
49+
expect(endpoint.get('1').uri).toEqual(new URL('http://localhost/children?id=1'));
5050
});
5151

5252
test('getByEntity', () => {
53-
expect(endpoint.get(new MockEntity(1, 'test')).uri.href).toBe('http://localhost/endpoint/1');
53+
expect(endpoint.get(new MockEntity(1, 'test')).uri).toEqual(new URL('http://localhost/endpoint/1'));
5454
});
5555

5656
test('getByEntityWithLinkHeaderRelative', async () => {
@@ -65,7 +65,7 @@ test('getByEntityWithLinkHeaderRelative', async () => {
6565
);
6666
await endpoint.readAll();
6767

68-
expect(endpoint.get('1').uri.href).toBe('http://localhost/children/1');
68+
expect(endpoint.get('1').uri).toEqual(new URL('http://localhost/children/1'));
6969
});
7070

7171
test('getByEntityWithLinkHeaderAbsolute', async () => {
@@ -80,7 +80,7 @@ test('getByEntityWithLinkHeaderAbsolute', async () => {
8080
);
8181
await endpoint.readAll();
8282

83-
expect(endpoint.get('1').uri.href).toBe('http://localhost/children/1');
83+
expect(endpoint.get('1').uri).toEqual(new URL('http://localhost/children/1'));
8484
});
8585

8686
test('readAll', async () => {
@@ -131,7 +131,7 @@ test('create', async () => {
131131

132132
const element = await endpoint.create(new MockEntity(0, 'test'));
133133
expect(element.response).toEqual(new MockEntity(5, 'test'));
134-
expect(element.uri.href).toBe('http://localhost/endpoint/5');
134+
expect(element.uri).toEqual(new URL('http://localhost/endpoint/5'));
135135
});
136136

137137
test('createLocation', async () => {
@@ -151,7 +151,7 @@ test('createLocation', async () => {
151151

152152
const element = await endpoint.create(new MockEntity(0, 'test'));
153153
expect(element.response).toEqual(new MockEntity(5, 'test'));
154-
expect(element.uri.href).toBe('http://localhost/endpoint/new');
154+
expect(element.uri).toEqual(new URL('http://localhost/endpoint/new'));
155155
});
156156

157157
test('createAll', async () => {

endpoints/generic/IndexerEndpoint.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ beforeEach(() => {
88
});
99

1010
test('getById', () => {
11-
expect(endpoint.get('x/y').uri.href).toBe('http://localhost/endpoint/x%2Fy');
11+
expect(endpoint.get('x/y').uri).toEqual(new URL('http://localhost/endpoint/x%2Fy'));
1212
});

0 commit comments

Comments
 (0)