我想测试这个文件:
import { Request, Response } from 'express';
import { DocumentObject, ExistingResourceObject, ResourceObject } from 'jsonapi-fractal';
import path from 'path';
import jwt, { Secret } from 'jsonwebtoken';
import fs from 'fs';
import { fetchKey } from '../auth/jwt';
import makeAuthRequest from '../makeAuthRequest';
import getToken from '../getToken';
const authApiPublicKey = path.join(__dirname, '../../assets/keys/auth_api_public_key.cer');
const transformSupplier = (data: ExistingResourceObject) => ({
id: data.id,
type: data.type,
attributes: {
name: data.attributes.name,
},
});
const transformResponse = (response: DocumentObject): DocumentObject => {
if (Array.isArray(response.data)) {
const transformedData: ResourceObject[] = response.data
.filter((data) => data.attributes.active)
.map((data: ExistingResourceObject) => transformSupplier(data));
return {
data: transformedData,
};
}
return {
data: transformSupplier(response.data as ExistingResourceObject),
};
};
function verifyToken(token: string) {
return (
Promise.resolve(token)
// eslint-disable-next-line consistent-return
.then((t) => {
try {
jwt.decode(t, { complete: true }) as { payload: jwt.JwtPayload };
} catch (error) {
return Promise.resolve(false);
}
})
.then((decodedToken) => {
if (decodedToken.payload.kid) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
return fetchKey(decodedToken.payload.kid) as Promise<Secret>;
}
return fs.readFileSync(authApiPublicKey);
})
.then((key: Secret | Buffer) => {
try {
return jwt.verify(token, key, {
algorithms: ['RS256'],
});
} catch (err) {
throw new Error('Error verifying the token');
}
})
.then((payload: jwt.JwtPayload) => {
if (!payload || !payload.exp || !payload.email) {
throw new Error('Payload was malformed');
}
return payload;
})
.catch((err: string) => {
throw new Error(err);
})
);
}
export default async (request: Request, response: Response) => {
const token: string = getToken(request);
try {
const payload = await verifyToken(token);
if (!payload) {
response.status(401).send('Not authenticated for this endpoint');
} else {
await makeAuthRequest(
request,
response,
() => ({
endpointKey: 'affiliate.suppliers',
method: 'GET',
headers: {
Accept: 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json',
},
gzip: true,
}),
transformResponse,
);
response.end();
}
} catch (error) {
response.status(401).send('Not authenticated for this endpoint');
}
};
此文件的目的是在制作
makeAuthRequest
之前验证/验证 JWT 令牌。代码按预期工作,但是一个测试(第一个)失败了
Supplier › should reply with list of suppliers
expect(jsonp mock default).toHaveBeenCalledWith(...expected)
Expected: ObjectContaining {"data": [{"attributes": {"active": true, "name": "Abbycar"}, "id": "430", "type": "suppliers"}]}
Number of calls: 0
33 |
34 | await suppliers(req, res);
> 35 | expect(res.jsonp).toHaveBeenCalledWith(
| ^
36 | expect.objectContaining(supplierMock.transformedResponse),
37 | );
38 | });
at Object.toHaveBeenCalledWith (tests/server/endpoints/supplier/supplier.test.ts:35:23
这是测试文件:
import { getMockReq, getMockRes } from '@jest-mock/express';
import nock from 'nock';
import suppliers from '../../../../src/endpoints/suppliers';
import supplierMock from '../../mocks/supplier/supplier.response';
const { res, mockClear } = getMockRes();
describe('Supplier', () => {
beforeEach(() => {
mockClear();
});
it('should reply with list of suppliers', async () => {
const req = getMockReq({
headers: {
host: 'localhost',
authorization:
'Bearer this.is.valid',
},
IS_BRIDGE: 'true',
});
nock('http://localhost:8001')
.get(`/api/suppliers`)
.matchHeader(
'authorization',
'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImNlNmQzYTJhLTMzNTctNDRjOS1hOGZkLTRiZDVhYTNiMzk0NCIsImVtYWlsIjoiY254LWFkbWluQGNhcm5lY3QuY29tIiwiYWZmaWxpYXRlSWRzIjpbXSwic2NvcGUiOlsiYm9va2luZzoqIiwiZ3JvdXA6KiIsIm9yZ2FuaXphdGlvbjoqIiwicHJpY2luZzp0cmFuc2FjdGlvbi1mZWU6KiIsInByaWNpbmc6dHJhbnNhY3Rpb24tZmVlOnJlYWQtb25seSIsInByaWNpbmc6dXBzZWxsLXJ1bGU6KiIsInByaWNpbmc6dXBzZWxsLXJ1bGU6cmVhZC1vbmx5Iiwicm9sZToqIiwic2hvcDoqIiwic3VwZXJ1c2VyOioiLCJ1c2VyOioiXSwiYXNzb2NpYXRpb24iOnsic2hvcElkIjpudWxsLCJncm91cElkIjpudWxsLCJvcmdhbml6YXRpb25JZCI6IjE0NWZkNWY4LWUzOTYtNGM5MC1hNGM2LWRmMGY0ZDU0NGM5YiJ9LCJraWQiOiI4ZjBjYjQ0MC1kODEwLTRkMDYtYjliYS01Nzk0OThiNmIwMTciLCJpYXQiOjE2OTA0NDI2OTEsImV4cCI6MTY5MDQ0Mzg5MSwiYXVkIjoiY2FybmVjdC5hdXRoLmFwaSIsImlzcyI6ImNhcm5lY3QuYXV0aC5hcGkiLCJqdGkiOiI2MWViYjFjNi1lYmYxLTQwYTktOThhZC02ZjYwYmU0NjFmZTAifQ.FPjPxTBrIh2jJUNfVSitkKsl2CRpBWhHhEx-rQXuTreIqb9eQ9Sz4cReNpfHro0EKvNjS_uVA_WbtTWoyudzgqZJH-BteAyorzp92tvOurLhY0Drfn1qMTh80AK1fjYlpeYEC3gq9wz3ddBxcpCm3wfsm4hBwBPsFJKV8_c6mD7Qunjw9N4LCsjx-tS5SQzabrf9rBHSKOiJk4VyhSK467slEYap02SzmktnbTNCfEK6qAKv3XWynvnLzXXKTjRrgV-RJS1lcow0wQ_wM7Xcas-JKrCd535rW9MzOEay4kvETLFjnKK3ZmhwW-lhgIF_sQ0tD0FkYcAIznmjLBcfPg',
)
.matchHeader('content-type', 'application/vnd.api+json')
.matchHeader('accept', 'application/vnd.api+json')
.reply(200, supplierMock.apiResponse);
await suppliers(req, res);
expect(res.jsonp).toHaveBeenCalledWith(
expect.objectContaining(supplierMock.transformedResponse),
);
});
it('should reply with 401 error, if not authenticated', async () => {
const req = getMockReq({
headers: {
host: 'localhost',
authorization: 'no.valid.token',
},
IS_BRIDGE: 'true',
});
await suppliers(req, res);
expect(res.status).toHaveBeenCalledWith(401);
expect(res.send).toHaveBeenCalledWith('Not authenticated for this endpoint');
});
});
我们假设“Bearer this.is.valid”是有效的令牌。第二个测试是绿色的,因为被 catch 块捕获并返回 401。我也想摆脱 try catch 块,但这使得两个测试都变成红色。
我尝试模拟 verifyToken 和其他函数,但似乎仍然不起作用。