test: fix all ts errors, eslint overrides

This commit is contained in:
Elliot DeNolf
2022-04-03 00:55:49 -04:00
committed by Elliot DeNolf
parent 9c6af860d4
commit 839e3f9dae
9 changed files with 190 additions and 132 deletions

View File

@@ -40,6 +40,12 @@ module.exports = {
], ],
}, },
}, },
{
files: ['*.spec.ts'],
rules: {
'@typescript-eslint/no-use-before-define': 'off',
},
},
], ],
rules: { rules: {
'no-sparse-arrays': 'off', 'no-sparse-arrays': 'off',
@@ -63,6 +69,5 @@ module.exports = {
tsx: 'never', tsx: 'never',
}, },
], ],
'operator-linbreak': 'off',
}, },
}; };

View File

@@ -166,7 +166,9 @@ export default buildConfig({
// indexSortableFields: true, // indexSortableFields: true,
hooks: { hooks: {
afterError: (err) => { afterError: (err) => {
console.error('global error config handler', err); if (process.env.DISABLE_LOGGING !== 'true') {
console.error('global error config handler', err);
}
}, },
}, },
upload: { upload: {

View File

@@ -14,10 +14,13 @@ describe('Collections - Local', () => {
describe('Create', () => { describe('Create', () => {
it('should allow an upload-enabled file to be created and uploaded', async () => { it('should allow an upload-enabled file to be created and uploaded', async () => {
const alt = 'Alt Text Here'; const alt = 'Alt Text Here';
const filePath = path.resolve(__dirname, '../../../admin/assets/images/generic-block-image.svg'); const filePath = path.resolve(
__dirname,
'../../../admin/assets/images/generic-block-image.svg',
);
const { size } = fs.statSync(filePath); const { size } = fs.statSync(filePath);
const result = await payload.create({ const result: Media = await payload.create({
collection: 'media', collection: 'media',
data: { data: {
alt, alt,
@@ -37,7 +40,7 @@ describe('Collections - Local', () => {
it('should allow an upload-enabled file to be re-uploaded and alt-text to be changed.', async () => { it('should allow an upload-enabled file to be re-uploaded and alt-text to be changed.', async () => {
const newAltText = 'New Alt Text Here'; const newAltText = 'New Alt Text Here';
const result = await payload.update({ const result: Media = await payload.update({
collection: 'media', collection: 'media',
id: createdMediaID, id: createdMediaID,
data: { data: {
@@ -115,7 +118,9 @@ describe('Collections - Local', () => {
showHiddenFields: true, showHiddenFields: true,
}); });
expect(relationshipBWithHiddenNestedField.post[0].demoHiddenField).toStrictEqual(demoHiddenField); expect(relationshipBWithHiddenNestedField.post[0].demoHiddenField).toStrictEqual(
demoHiddenField,
);
}); });
describe('Find', () => { describe('Find', () => {
const title = 'local-find'; const title = 'local-find';
@@ -139,9 +144,11 @@ describe('Collections - Local', () => {
{ {
blockType: 'richTextBlock', blockType: 'richTextBlock',
blockName: 'Test Block Name', blockName: 'Test Block Name',
content: [{ content: [
children: [{ text: 'english' }], {
}], children: [{ text: 'english' }],
},
],
}, },
], ],
}; };
@@ -185,3 +192,27 @@ describe('Collections - Local', () => {
}); });
}); });
}); });
interface ImageSize {
url?: string;
width?: number;
height?: number;
mimeType?: string;
filesize?: number;
filename?: string;
}
interface Media {
id?: string;
filename?: string;
filesize?: number;
width?: number;
height?: number;
sizes?: {
maintainedAspectRatio?: ImageSize;
tablet?: ImageSize;
mobile?: ImageSize;
icon?: ImageSize;
};
alt: string;
}

View File

@@ -2,10 +2,12 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import FormData from 'form-data'; import FormData from 'form-data';
import { GraphQLClient } from 'graphql-request'; import { GraphQLClient } from 'graphql-request';
import { promisify } from 'util';
import getConfig from '../../config/load'; import getConfig from '../../config/load';
import fileExists from '../../../tests/api/utils/fileExists';
import { email, password } from '../../mongoose/testCredentials'; import { email, password } from '../../mongoose/testCredentials';
const stat = promisify(fs.stat);
require('isomorphic-fetch'); require('isomorphic-fetch');
const config = getConfig(); const config = getConfig();
@@ -59,11 +61,14 @@ describe('Collections - Uploads', () => {
describe('create', () => { describe('create', () => {
it('creates', async () => { it('creates', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png')),
);
formData.append('alt', 'test media'); formData.append('alt', 'test media');
formData.append('locale', 'en'); formData.append('locale', 'en');
const response = await fetch(`${api}/media`, { const response = await fetch(`${api}/media`, {
body: formData, body: formData as unknown as BodyInit,
headers, headers,
method: 'post', method: 'post',
}); });
@@ -113,12 +118,15 @@ describe('Collections - Uploads', () => {
it('creates media without storing a file', async () => { it('creates media without storing a file', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png')),
);
formData.append('alt', 'test media'); formData.append('alt', 'test media');
formData.append('locale', 'en'); formData.append('locale', 'en');
const response = await fetch(`${api}/unstored-media`, { const response = await fetch(`${api}/unstored-media`, {
body: formData, body: formData as unknown as BodyInit,
headers, headers,
method: 'post', method: 'post',
}); });
@@ -150,12 +158,15 @@ describe('Collections - Uploads', () => {
it('creates with same name', async () => { it('creates with same name', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/samename.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/samename.png')),
);
formData.append('alt', 'test media'); formData.append('alt', 'test media');
formData.append('locale', 'en'); formData.append('locale', 'en');
const firstResponse = await fetch(`${api}/media`, { const firstResponse = await fetch(`${api}/media`, {
body: formData, body: formData as unknown as BodyInit,
headers, headers,
method: 'post', method: 'post',
}); });
@@ -163,12 +174,15 @@ describe('Collections - Uploads', () => {
expect(firstResponse.status).toBe(201); expect(firstResponse.status).toBe(201);
const sameForm = new FormData(); const sameForm = new FormData();
sameForm.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/samename.png'))); sameForm.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/samename.png')),
);
sameForm.append('alt', 'test media'); sameForm.append('alt', 'test media');
sameForm.append('locale', 'en'); sameForm.append('locale', 'en');
const response = await fetch(`${api}/media`, { const response = await fetch(`${api}/media`, {
body: sameForm, body: sameForm as unknown as BodyInit,
headers, headers,
method: 'post', method: 'post',
}); });
@@ -211,15 +225,16 @@ describe('Collections - Uploads', () => {
it('update', async () => { it('update', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/update.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/update.png')),
);
formData.append('alt', 'test media'); formData.append('alt', 'test media');
formData.append('locale', 'en'); formData.append('locale', 'en');
const response = await fetch(`${api}/media`, { const response = await fetch(`${api}/media`, {
body: formData, body: formData as unknown as BodyInit,
headers: { headers,
Authorization: `JWT ${token}`,
},
method: 'post', method: 'post',
}); });
@@ -233,10 +248,8 @@ describe('Collections - Uploads', () => {
updateFormData.append('filename', data.doc.filename); updateFormData.append('filename', data.doc.filename);
updateFormData.append('alt', newAlt); updateFormData.append('alt', newAlt);
const updateResponse = await fetch(`${api}/media/${data.doc.id}`, { const updateResponse = await fetch(`${api}/media/${data.doc.id}`, {
body: updateFormData, body: updateFormData as unknown as BodyInit,
headers: { headers,
Authorization: `JWT ${token}`,
},
method: 'put', method: 'put',
}); });
@@ -280,15 +293,16 @@ describe('Collections - Uploads', () => {
it('delete', async () => { it('delete', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/delete.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/delete.png')),
);
formData.append('alt', 'test media'); formData.append('alt', 'test media');
formData.append('locale', 'en'); formData.append('locale', 'en');
const createResponse = await fetch(`${api}/media`, { const createResponse = await fetch(`${api}/media`, {
body: formData, body: formData as unknown as BodyInit,
headers: { headers,
Authorization: `JWT ${token}`,
},
method: 'post', method: 'post',
}); });
@@ -297,9 +311,7 @@ describe('Collections - Uploads', () => {
const docId = createData.doc.id; const docId = createData.doc.id;
const response = await fetch(`${api}/media/${docId}`, { const response = await fetch(`${api}/media/${docId}`, {
headers: { headers,
Authorization: `JWT ${token}`,
},
method: 'delete', method: 'delete',
}); });
@@ -318,15 +330,20 @@ describe('Collections - Uploads', () => {
let image; let image;
const alt = 'alt text'; const alt = 'alt text';
beforeAll(async (done) => { beforeAll(async (done) => {
client = new GraphQLClient(`${api}${config.routes.graphQL}`, { headers: { Authorization: `JWT ${token}` } }); client = new GraphQLClient(`${api}${config.routes.graphQL}`, {
headers: { Authorization: `JWT ${token}` },
});
// create media using REST // create media using REST
const formData = new FormData(); const formData = new FormData();
formData.append('file', fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png'))); formData.append(
'file',
fs.createReadStream(path.join(__dirname, '../../..', 'tests/api/assets/image.png')),
);
formData.append('alt', alt); formData.append('alt', alt);
formData.append('locale', 'en'); formData.append('locale', 'en');
const mediaResponse = await fetch(`${api}/media`, { const mediaResponse = await fetch(`${api}/media`, {
body: formData, body: formData as unknown as BodyInit,
headers, headers,
method: 'post', method: 'post',
}); });
@@ -364,3 +381,12 @@ describe('Collections - Uploads', () => {
}); });
}); });
}); });
async function fileExists(fileName: string): Promise<boolean> {
try {
await stat(fileName);
return true;
} catch (err) {
return false;
}
}

View File

@@ -1,120 +1,112 @@
import { Response } from 'express';
import Logger from '../../utilities/logger'; import Logger from '../../utilities/logger';
import errorHandler from './errorHandler'; import errorHandler from './errorHandler';
import { APIError } from '../../errors'; import { APIError } from '../../errors';
import { PayloadRequest } from '../types';
import { SanitizedConfig } from '../../config/types';
const logger = Logger(); const logger = Logger();
const testError = new APIError('test error', 503); const testError = new APIError('test error', 503);
const mockResponse = () => {
const res = {
status: jest.fn(),
send: jest.fn(),
};
jest.spyOn(res, 'status').mockImplementation()
.mockReturnValue(res);
jest.spyOn(res, 'send').mockImplementation()
.mockReturnValue(res);
return res;
};
const mockRequest = async () => {
const req = {};
req.collection = {
config: {
hooks: {},
},
};
req.collection.config.hooks.afterError = await jest.fn();
return req;
};
describe('errorHandler', () => { describe('errorHandler', () => {
let res; const res = generateResponse();
let req; const next = jest.fn();
beforeAll(async (done) => { const req = generateRequest() as PayloadRequest;
res = mockResponse();
req = await mockRequest();
done();
});
it('should send the response with the error', async () => { it('should send the response with the error', async () => {
const handler = errorHandler({ debug: true, hooks: {} }, logger); const handler = errorHandler(generateConfig({ debug: true }), logger);
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.send) expect(res.send).toHaveBeenCalledWith(
.toHaveBeenCalledWith( expect.objectContaining({ errors: [{ message: 'test error' }] }),
expect.objectContaining({ errors: [{ message: 'test error' }] }), );
);
}); });
it('should include stack trace when config debug is on', async () => { it('should include stack trace when config debug is on', async () => {
const handler = errorHandler({ debug: true, hooks: {} }, logger); const handler = errorHandler(generateConfig({ debug: true }), logger);
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.send) expect(res.send).toHaveBeenCalledWith(expect.objectContaining({ stack: expect.any(String) }));
.toHaveBeenCalledWith(
expect.objectContaining({ stack: expect.any(String) }),
);
}); });
it('should not include stack trace when config debug is not set', async () => { it('should not include stack trace when config debug is not set', async () => {
const handler = errorHandler({ hooks: {} }, logger); const handler = errorHandler(generateConfig({ debug: undefined }), logger);
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.send) expect(res.send).toHaveBeenCalledWith(
.toHaveBeenCalledWith( expect.not.objectContaining({ stack: expect.any(String) }),
expect.not.objectContaining({ stack: expect.any(String) }), );
);
}); });
it('should not include stack trace when config debug is false', async () => { it('should not include stack trace when config debug is false', async () => {
const handler = errorHandler({ debug: false, hooks: {} }, logger); const handler = errorHandler(generateConfig({ debug: false }), logger);
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.send) expect(res.send).toHaveBeenCalledWith(
.toHaveBeenCalledWith( expect.not.objectContaining({ stack: expect.any(String) }),
expect.not.objectContaining({ stack: expect.any(String) }), );
);
}); });
it('should show the status code when given an error with a code', async () => { it('should show the status code when given an error with a code', async () => {
const handler = errorHandler({ debug: false, hooks: {} }, logger); const handler = errorHandler(generateConfig(), logger);
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.status) expect(res.status).toHaveBeenCalledWith(503);
.toHaveBeenCalledWith(
503,
);
}); });
it('should default to 500 when an error does not have a status code', async () => { it('should default to 500 when an error does not have a status code', async () => {
const handler = errorHandler({ debug: false, hooks: {} }, logger); const handler = errorHandler(generateConfig(), logger);
testError.status = undefined; testError.status = undefined;
await handler(testError, req, res); await handler(testError, req, res, next);
expect(res.status) expect(res.status).toHaveBeenCalledWith(500);
.toHaveBeenCalledWith(
500,
);
}); });
it('should call payload config afterError hook', async () => { it('should call payload config afterError hook', async () => {
const afterError = jest.fn(); const afterError = jest.fn();
const handler = errorHandler({ const handler = errorHandler(
debug: false, generateConfig({
hooks: { afterError }, hooks: { afterError },
}, logger); }),
await handler(testError, req, res); logger,
);
await handler(testError, req, res, next);
expect(afterError) expect(afterError)
// eslint-disable-next-line jest/prefer-called-with // eslint-disable-next-line jest/prefer-called-with
.toHaveBeenCalled(); .toHaveBeenCalled();
}); });
it('should call collection config afterError hook', async () => { it('should call collection config afterError hook', async () => {
const handler = errorHandler({ const handler = errorHandler(generateConfig(), logger);
debug: false, await handler(testError, req, res, next);
hooks: {},
}, logger);
await handler(testError, req, res);
expect(req.collection.config.hooks.afterError) expect(req.collection.config.hooks.afterError)
// eslint-disable-next-line jest/prefer-called-with // eslint-disable-next-line jest/prefer-called-with
.toHaveBeenCalled(); .toHaveBeenCalled();
}); });
}); });
function generateResponse() {
const res = {
status: jest.fn(),
send: jest.fn(),
};
jest.spyOn(res, 'status').mockImplementation().mockReturnValue(res);
jest.spyOn(res, 'send').mockImplementation().mockReturnValue(res);
return res as unknown as Response;
}
function generateRequest(): PayloadRequest {
return {
collection: {
config: {
hooks: {
afterError: jest.fn(),
},
},
},
} as unknown as PayloadRequest;
}
function generateConfig(overrides?: Partial<SanitizedConfig>): SanitizedConfig {
return {
debug: false,
hooks: { afterError: jest.fn() },
...overrides,
} as unknown as SanitizedConfig;
}

View File

@@ -1,9 +1,12 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import { email, password } from '../../src/mongoose/testCredentials'; import { email, password } from '../../src/mongoose/testCredentials';
import fileExists from './utils/fileExists'; import { fileExists } from './utils/fileExists';
import loadConfig from '../../src/config/load'; import loadConfig from '../../src/config/load';
process.env.PAYLOAD_CONFIG_PATH = 'demo/payload.config.ts';
process.env.DISABLE_LOGGING = 'true';
require('isomorphic-fetch'); require('isomorphic-fetch');
require('../../demo/server'); require('../../demo/server');

View File

@@ -1,15 +0,0 @@
const fs = require('fs');
const { promisify } = require('util');
const stat = promisify(fs.stat);
const fileExists = async (fileName) => {
try {
await stat(fileName);
return true;
} catch (err) {
return false;
}
};
module.exports = fileExists;

View File

@@ -0,0 +1,13 @@
import fs from 'fs';
import { promisify } from 'util';
const stat = promisify(fs.stat);
export const fileExists = async (fileName: string): Promise<boolean> => {
try {
await stat(fileName);
return true;
} catch (err) {
return false;
}
};

View File

@@ -37,6 +37,7 @@
"build", "build",
"tests", "tests",
"**/*.spec.js", "**/*.spec.js",
"**/*.spec.ts",
"node_modules", "node_modules",
".eslintrc.js" ".eslintrc.js"
] ]