Skip to content

Commit 7cdb573

Browse files
committed
chore: add tests
1 parent 2b95b0e commit 7cdb573

File tree

6 files changed

+228
-1
lines changed

6 files changed

+228
-1
lines changed

src/routes/auth/update.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function updateToken(ctx, token = generateToken()) {
2727
await ctx.env.KEYS.put(config.siteKey, token);
2828
} catch (e) {
2929
ctx.log.error('failed to update token', e);
30-
throw errorWithResponse(500, 'failed to update token');
30+
throw errorWithResponse(503, 'failed to update token');
3131
}
3232
return token;
3333
}

test/fixtures/context.js

+15
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export const DEFAULT_CONTEXT = (
2929
) => ({
3030
url: new URL(`${baseUrl}${path}`),
3131
log: console,
32+
// @ts-ignore
33+
config: {
34+
siteKey: 'org--site',
35+
},
3236
...overrides,
3337
attributes: {
3438
key: 'test-key',
@@ -51,6 +55,17 @@ export const DEFAULT_CONTEXT = (
5155
headers: {},
5256
...(overrides.info ?? {}),
5357
},
58+
data: typeof overrides.data === 'string' ? overrides.data : {
59+
...(overrides.data ?? {}),
60+
},
61+
});
62+
63+
export const SUPERUSER_CONTEXT = (overrides = {}) => DEFAULT_CONTEXT({
64+
...overrides,
65+
attributes: {
66+
key: 'su-test-key',
67+
...(overrides.attributes ?? {}),
68+
},
5469
});
5570

5671
/**

test/routes/auth/fetch.test.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
// @ts-nocheck
14+
15+
import assert from 'node:assert';
16+
import { SUPERUSER_CONTEXT } from '../../fixtures/context.js';
17+
import handler from '../../../src/routes/auth/fetch.js';
18+
19+
describe('routes/auth fetch tests', () => {
20+
it('no token in storage, responds 404', async () => {
21+
const ctx = SUPERUSER_CONTEXT({
22+
env: {
23+
KEYS: {
24+
get: async () => undefined,
25+
},
26+
},
27+
url: { pathname: '/org/site/auth/token' },
28+
});
29+
const resp = await handler(ctx);
30+
assert.equal(resp.status, 404);
31+
});
32+
33+
it('retrieves token from storage', async () => {
34+
const ctx = SUPERUSER_CONTEXT({
35+
env: {
36+
KEYS: {
37+
get: async () => 'foo',
38+
},
39+
},
40+
url: { pathname: '/org/site/auth/token' },
41+
});
42+
const resp = await handler(ctx);
43+
assert.equal(resp.status, 200);
44+
assert.equal(resp.headers.get('Content-Type'), 'application/json');
45+
const { token } = await resp.json();
46+
assert.equal(token, 'foo');
47+
});
48+
});

test/routes/auth/handler.test.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
// @ts-nocheck
14+
15+
import assert from 'node:assert';
16+
import esmock from 'esmock';
17+
import { DEFAULT_CONTEXT } from '../../fixtures/context.js';
18+
import handler from '../../../src/routes/auth/handler.js';
19+
20+
describe('routes/auth handler tests', () => {
21+
it('should 404 on invalid route', async () => {
22+
const ctx = DEFAULT_CONTEXT({ url: { pathname: '/org/site/auth/invalid' } });
23+
const resp = await handler(ctx);
24+
assert.equal(resp.status, 404);
25+
});
26+
27+
it('should respond on valid route', async () => {
28+
const mocked = await esmock('../../../src/routes/auth/handler.js', {
29+
'../../../src/routes/auth/fetch.js': async () => ({ status: 200 }),
30+
});
31+
const ctx = DEFAULT_CONTEXT({ url: { pathname: '/org/site/auth/token' } });
32+
const resp = await mocked.default(ctx);
33+
assert.equal(resp.status, 200);
34+
});
35+
});

test/routes/auth/rotate.test.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
// @ts-nocheck
14+
15+
import assert from 'node:assert';
16+
import esmock from 'esmock';
17+
import { DEFAULT_CONTEXT, SUPERUSER_CONTEXT } from '../../fixtures/context.js';
18+
import handler from '../../../src/routes/auth/rotate.js';
19+
20+
describe('routes/auth rotate tests', () => {
21+
let ogUUID;
22+
beforeEach(() => {
23+
ogUUID = crypto.randomUUID;
24+
crypto.randomUUID = () => 'foo-uuid';
25+
});
26+
afterEach(() => {
27+
crypto.randomUUID = ogUUID;
28+
});
29+
30+
it('should reject body with token', async () => {
31+
const ctx = DEFAULT_CONTEXT({
32+
data: { token: '123' },
33+
});
34+
const resp = await handler(ctx);
35+
assert.equal(resp.status, 400);
36+
assert.equal(resp.headers.get('x-error'), 'token can not be provided on rotate');
37+
});
38+
39+
it('rotates token', async () => {
40+
const mocked = await esmock('../../../src/routes/auth/rotate.js', {
41+
'../../../src/routes/auth/update.js': { updateToken: async () => 'foo' },
42+
});
43+
const ctx = SUPERUSER_CONTEXT({
44+
env: {
45+
KEYS: {
46+
get: async () => 'test-key',
47+
put: async () => undefined,
48+
},
49+
},
50+
});
51+
const resp = await mocked.default(ctx);
52+
assert.equal(resp.status, 200);
53+
assert.equal(resp.headers.get('Content-Type'), 'application/json');
54+
const { token } = await resp.json();
55+
assert.equal(token, 'foo');
56+
});
57+
});

test/routes/auth/update.test.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
// @ts-nocheck
14+
15+
import assert from 'node:assert';
16+
import { DEFAULT_CONTEXT } from '../../fixtures/context.js';
17+
import handler from '../../../src/routes/auth/update.js';
18+
19+
describe('routes/auth update tests', () => {
20+
it('should reject invalid token', async () => {
21+
const ctx = DEFAULT_CONTEXT({
22+
data: { token: null },
23+
env: {
24+
KEYS: {
25+
// @ts-ignore
26+
get: async () => 'test-key',
27+
},
28+
},
29+
});
30+
const resp = await handler(ctx);
31+
assert.equal(resp.status, 400);
32+
assert.equal(resp.headers.get('x-error'), 'missing or invalid token');
33+
});
34+
35+
it('should update token', async () => {
36+
const ctx = DEFAULT_CONTEXT({
37+
data: { token: 'new-key' },
38+
env: {
39+
KEYS: {
40+
get: async () => 'test-key',
41+
put: async () => undefined,
42+
},
43+
},
44+
});
45+
const resp = await handler(ctx);
46+
assert.equal(resp.status, 200);
47+
assert.equal(resp.headers.get('Content-Type'), 'application/json');
48+
const { token } = await resp.json();
49+
assert.equal(token, 'new-key');
50+
});
51+
52+
it('should handle errors during token put', async () => {
53+
const ctx = DEFAULT_CONTEXT({
54+
data: { token: 'new-key' },
55+
env: {
56+
KEYS: {
57+
get: async () => 'test-key',
58+
put: async () => { throw Error('bad'); },
59+
},
60+
},
61+
});
62+
63+
let e;
64+
try {
65+
await handler(ctx);
66+
} catch (ee) {
67+
e = ee;
68+
}
69+
assert.equal(e.response.status, 503);
70+
assert.equal(e.response.headers.get('x-error'), 'failed to update token');
71+
});
72+
});

0 commit comments

Comments
 (0)