feat: upload integration tests (#759)
This commit is contained in:
@@ -22,6 +22,7 @@ type CreateArgs<T = any> = {
|
||||
slug?: string
|
||||
data: T
|
||||
auth?: boolean
|
||||
file?: boolean
|
||||
}
|
||||
|
||||
type FindArgs = {
|
||||
@@ -34,8 +35,14 @@ type UpdateArgs<T = any> = {
|
||||
slug?: string
|
||||
id: string
|
||||
data: Partial<T>
|
||||
auth?: boolean
|
||||
query?: any
|
||||
}
|
||||
type DeleteArgs = {
|
||||
slug?: string
|
||||
id: string
|
||||
auth?: boolean
|
||||
}
|
||||
|
||||
type DocResponse<T> = {
|
||||
status: number
|
||||
@@ -57,10 +64,10 @@ export class RESTClient {
|
||||
|
||||
private token: string;
|
||||
|
||||
private serverURL: string;
|
||||
|
||||
private defaultSlug: string;
|
||||
|
||||
serverURL: string;
|
||||
|
||||
constructor(config: Config, args: Args) {
|
||||
this.config = config;
|
||||
this.serverURL = args.serverURL;
|
||||
@@ -92,9 +99,9 @@ export class RESTClient {
|
||||
|
||||
async create<T = any>(args: CreateArgs): Promise<DocResponse<T>> {
|
||||
const options = {
|
||||
body: JSON.stringify(args.data),
|
||||
body: args.file ? args.data : JSON.stringify(args.data),
|
||||
headers: {
|
||||
...headers,
|
||||
...(args.file ? [] : headers),
|
||||
Authorization: '',
|
||||
},
|
||||
method: 'post',
|
||||
@@ -138,6 +145,9 @@ export class RESTClient {
|
||||
async update<T = any>(args: UpdateArgs<T>): Promise<DocResponse<T>> {
|
||||
const { slug, id, data, query } = args;
|
||||
const formattedQs = qs.stringify(query);
|
||||
if (args?.auth) {
|
||||
headers.Authorization = `JWT ${this.token}`;
|
||||
}
|
||||
const response = await fetch(
|
||||
`${this.serverURL}/api/${slug || this.defaultSlug}/${id}${formattedQs}`,
|
||||
{
|
||||
@@ -161,11 +171,20 @@ export class RESTClient {
|
||||
return { status, doc };
|
||||
}
|
||||
|
||||
async delete<T = any>(id: string, args?: { slug?: string }): Promise<DocResponse<T>> {
|
||||
const response = await fetch(`${this.serverURL}/api/${args?.slug || this.defaultSlug}/${id}`, {
|
||||
headers,
|
||||
async delete<T = any>(id: string, args?: DeleteArgs): Promise<DocResponse<T>> {
|
||||
const options = {
|
||||
headers: {
|
||||
...headers,
|
||||
Authorization: '',
|
||||
},
|
||||
method: 'delete',
|
||||
});
|
||||
};
|
||||
|
||||
if (args?.auth) {
|
||||
options.headers.Authorization = `JWT ${this.token}`;
|
||||
}
|
||||
|
||||
const response = await fetch(`${this.serverURL}/api/${args?.slug || this.defaultSlug}/${id}`, options);
|
||||
const { status } = response;
|
||||
const doc = await response.json();
|
||||
return { status, doc };
|
||||
|
||||
@@ -23,7 +23,6 @@ export default buildConfig({
|
||||
},
|
||||
}),
|
||||
},
|
||||
// upload: {},
|
||||
collections: [
|
||||
{
|
||||
slug: relationSlug,
|
||||
@@ -69,6 +68,14 @@ export default buildConfig({
|
||||
fields: [
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'unstored-media',
|
||||
upload: {
|
||||
staticURL: '/media',
|
||||
disableLocalStorage: true,
|
||||
},
|
||||
fields: [],
|
||||
},
|
||||
],
|
||||
onInit: async (payload) => {
|
||||
// delete files in /media
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import FormData from 'form-data';
|
||||
import { promisify } from 'util';
|
||||
import { initPayloadTest } from '../helpers/configHelpers';
|
||||
import { RESTClient } from '../helpers/rest';
|
||||
import config, { mediaSlug } from './config';
|
||||
import payload from '../../src';
|
||||
import getFileByPath from '../../src/uploads/getFileByPath';
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
|
||||
require('isomorphic-fetch');
|
||||
|
||||
let client;
|
||||
|
||||
describe('Collections - Uploads', () => {
|
||||
beforeAll(async (done) => {
|
||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||
client = new RESTClient(config, { serverURL, defaultSlug: mediaSlug });
|
||||
await client.login();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
describe('REST', () => {
|
||||
describe('create', () => {
|
||||
it('creates from form data', async () => {
|
||||
const formData = new FormData();
|
||||
formData.append(
|
||||
'file',
|
||||
fs.createReadStream(path.join(__dirname, './image.png')),
|
||||
);
|
||||
|
||||
const { status, doc } = await client.create({
|
||||
file: true,
|
||||
data: formData,
|
||||
auth: true,
|
||||
headers: {},
|
||||
});
|
||||
|
||||
expect(status).toBe(201);
|
||||
|
||||
// Check for files
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.sizes.maintainedAspectRatio.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.sizes.tablet.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.sizes.mobile.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.sizes.icon.filename))).toBe(true);
|
||||
|
||||
// Check api response
|
||||
expect(doc.mimeType).toEqual('image/png');
|
||||
expect(doc.sizes.maintainedAspectRatio.url).toContain('/media/image');
|
||||
expect(doc.sizes.maintainedAspectRatio.url).toContain('.png');
|
||||
expect(doc.sizes.maintainedAspectRatio.width).toEqual(1024);
|
||||
expect(doc.sizes.maintainedAspectRatio.height).toEqual(1024);
|
||||
expect(doc.sizes).toHaveProperty('tablet');
|
||||
expect(doc.sizes).toHaveProperty('mobile');
|
||||
expect(doc.sizes).toHaveProperty('icon');
|
||||
});
|
||||
});
|
||||
|
||||
it('creates images that do not require all sizes', async () => {
|
||||
const formData = new FormData();
|
||||
formData.append(
|
||||
'file',
|
||||
fs.createReadStream(path.join(__dirname, './small.png')),
|
||||
);
|
||||
|
||||
const { status, doc } = await client.create({
|
||||
file: true,
|
||||
data: formData,
|
||||
auth: true,
|
||||
headers: {},
|
||||
});
|
||||
|
||||
expect(status).toBe(201);
|
||||
|
||||
// Check for files
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', 'small-640x480.png'))).toBe(false);
|
||||
expect(await fileExists(path.join(__dirname, './media', doc.sizes.icon.filename))).toBe(true);
|
||||
|
||||
// Check api response
|
||||
expect(doc.sizes.tablet.filename).toBeUndefined();
|
||||
expect(doc.sizes.icon.filename).toBeDefined();
|
||||
});
|
||||
|
||||
it('creates media without storing a file', async () => {
|
||||
const formData = new FormData();
|
||||
formData.append(
|
||||
'file',
|
||||
fs.createReadStream(path.join(__dirname, './small.png')),
|
||||
);
|
||||
|
||||
// unstored media
|
||||
const { status, doc } = await client.create({
|
||||
slug: 'unstored-media',
|
||||
file: true,
|
||||
data: formData,
|
||||
auth: true,
|
||||
headers: {},
|
||||
});
|
||||
|
||||
expect(status).toBe(201);
|
||||
|
||||
// Check for files
|
||||
expect(await !fileExists(path.join(__dirname, './media', doc.filename))).toBe(false);
|
||||
|
||||
// Check api response
|
||||
expect(doc.filename).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('update', async () => {
|
||||
// Create image
|
||||
const filePath = path.resolve(__dirname, './image.png');
|
||||
const file = getFileByPath(filePath);
|
||||
file.name = 'renamed.png';
|
||||
|
||||
const mediaDoc = await payload.create({
|
||||
collection: mediaSlug,
|
||||
data: {},
|
||||
file,
|
||||
});
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append(
|
||||
'file',
|
||||
fs.createReadStream(path.join(__dirname, './small.png')),
|
||||
);
|
||||
|
||||
const { status, doc } = await client.update({
|
||||
id: mediaDoc.id,
|
||||
file: true,
|
||||
data: formData,
|
||||
auth: true,
|
||||
headers: {},
|
||||
});
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
// Check that previously existing files weren't affected
|
||||
expect(await fileExists(path.join(__dirname, './media', mediaDoc.filename))).toBe(true);
|
||||
expect(await fileExists(path.join(__dirname, './media', mediaDoc.sizes.icon.filename))).toBe(true);
|
||||
});
|
||||
|
||||
it('delete', async () => {
|
||||
const formData = new FormData();
|
||||
formData.append(
|
||||
'file',
|
||||
fs.createReadStream(path.join(__dirname, './image.png')),
|
||||
);
|
||||
|
||||
const { doc } = await client.create({
|
||||
file: true,
|
||||
data: formData,
|
||||
auth: true,
|
||||
headers: {},
|
||||
});
|
||||
|
||||
const { status } = await client.delete(doc.id, {
|
||||
auth: true,
|
||||
});
|
||||
|
||||
expect(status).toBe(200);
|
||||
|
||||
expect(await fileExists(path.join(__dirname, doc.filename))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
async function fileExists(fileName: string): Promise<boolean> {
|
||||
try {
|
||||
await stat(fileName);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user