chore: partial passing upload int tests
This commit is contained in:
@@ -66,6 +66,16 @@ export const RouteError = async ({
|
|||||||
err: APIError
|
err: APIError
|
||||||
collection?: Collection
|
collection?: Collection
|
||||||
}) => {
|
}) => {
|
||||||
|
if (!req?.payload) {
|
||||||
|
return Response.json(
|
||||||
|
{
|
||||||
|
message: err.message,
|
||||||
|
stack: err.stack,
|
||||||
|
},
|
||||||
|
{ status: httpStatus.INTERNAL_SERVER_ERROR },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const { config, logger } = req.payload
|
const { config, logger } = req.payload
|
||||||
let response = formatErrors(err)
|
let response = formatErrors(err)
|
||||||
let status = err.status || httpStatus.INTERNAL_SERVER_ERROR
|
let status = err.status || httpStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ export const deleteAssociatedFiles: (args: Args) => Promise<void> = async ({
|
|||||||
}) => {
|
}) => {
|
||||||
if (!collectionConfig.upload) return
|
if (!collectionConfig.upload) return
|
||||||
if (overrideDelete || files.length > 0) {
|
if (overrideDelete || files.length > 0) {
|
||||||
const staticPath = path.resolve(collectionConfig.upload.staticDir)
|
const staticPath = path.resolve(config.paths.configDir, collectionConfig.upload.staticDir)
|
||||||
// const staticPath = path.resolve(config.paths.configDir, collectionConfig.upload.staticDir)
|
|
||||||
|
|
||||||
const fileToDelete = `${staticPath}/${doc.filename}`
|
const fileToDelete = `${staticPath}/${doc.filename}`
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ export const generateFileData = async <T>({
|
|||||||
|
|
||||||
let staticPath = staticDir
|
let staticPath = staticDir
|
||||||
if (staticDir.indexOf('/') !== 0) {
|
if (staticDir.indexOf('/') !== 0) {
|
||||||
staticPath = path.resolve(staticDir)
|
staticPath = path.resolve(config.paths.configDir, staticDir)
|
||||||
// staticPath = path.resolve(config.paths.configDir, staticDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file && uploadEdits && data) {
|
if (!file && uploadEdits && data) {
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ import {
|
|||||||
import { devUser } from '../credentials'
|
import { devUser } from '../credentials'
|
||||||
|
|
||||||
type ValidPath = `/${string}`
|
type ValidPath = `/${string}`
|
||||||
type RequestQuery = {
|
type RequestOptions = {
|
||||||
|
auth?: boolean
|
||||||
|
file?: boolean
|
||||||
query?: {
|
query?: {
|
||||||
depth?: number
|
depth?: number
|
||||||
fallbackLocale?: string
|
fallbackLocale?: string
|
||||||
@@ -27,7 +29,7 @@ type RequestQuery = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateQueryString(query: RequestQuery['query'], params: ParsedQs): string {
|
function generateQueryString(query: RequestOptions['query'], params: ParsedQs): string {
|
||||||
return QueryString.stringify(
|
return QueryString.stringify(
|
||||||
{
|
{
|
||||||
...(params || {}),
|
...(params || {}),
|
||||||
@@ -52,6 +54,8 @@ export class NextRESTClient {
|
|||||||
|
|
||||||
private readonly config: SanitizedConfig
|
private readonly config: SanitizedConfig
|
||||||
|
|
||||||
|
private token: string
|
||||||
|
|
||||||
serverURL: string = 'http://localhost:3000'
|
serverURL: string = 'http://localhost:3000'
|
||||||
|
|
||||||
constructor(config: SanitizedConfig) {
|
constructor(config: SanitizedConfig) {
|
||||||
@@ -64,6 +68,22 @@ export class NextRESTClient {
|
|||||||
this._GRAPHQL_POST = createGraphqlPOST(config)
|
this._GRAPHQL_POST = createGraphqlPOST(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildHeaders(options: RequestInit & RequestOptions): Headers {
|
||||||
|
const defaultHeaders = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
const headers = new Headers({
|
||||||
|
...(options?.file ? {} : defaultHeaders),
|
||||||
|
...(options?.headers || {}),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (options.auth !== false && this.token) {
|
||||||
|
headers.set('Authorization', `JWT ${this.token}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers
|
||||||
|
}
|
||||||
|
|
||||||
private generateRequestParts(path: ValidPath): {
|
private generateRequestParts(path: ValidPath): {
|
||||||
params?: ParsedQs
|
params?: ParsedQs
|
||||||
slug: string[]
|
slug: string[]
|
||||||
@@ -79,7 +99,7 @@ export class NextRESTClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async DELETE(path: ValidPath, options: RequestInit & RequestQuery = {}): Promise<Response> {
|
async DELETE(path: ValidPath, options: RequestInit & RequestOptions = {}): Promise<Response> {
|
||||||
const { url, slug, params } = this.generateRequestParts(path)
|
const { url, slug, params } = this.generateRequestParts(path)
|
||||||
const { query, ...rest } = options || {}
|
const { query, ...rest } = options || {}
|
||||||
const queryParams = generateQueryString(query, params)
|
const queryParams = generateQueryString(query, params)
|
||||||
@@ -87,17 +107,14 @@ export class NextRESTClient {
|
|||||||
const request = new Request(`${url}${queryParams}`, {
|
const request = new Request(`${url}${queryParams}`, {
|
||||||
...rest,
|
...rest,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: this.buildHeaders(options),
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(options?.headers || {}),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
return this._DELETE(request, { params: { slug } })
|
return this._DELETE(request, { params: { slug } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async GET(
|
async GET(
|
||||||
path: ValidPath,
|
path: ValidPath,
|
||||||
options: Omit<RequestInit, 'body'> & RequestQuery = {},
|
options: Omit<RequestInit, 'body'> & RequestOptions = {},
|
||||||
): Promise<Response> {
|
): Promise<Response> {
|
||||||
const { url, slug, params } = this.generateRequestParts(path)
|
const { url, slug, params } = this.generateRequestParts(path)
|
||||||
const { query, ...rest } = options || {}
|
const { query, ...rest } = options || {}
|
||||||
@@ -106,15 +123,12 @@ export class NextRESTClient {
|
|||||||
const request = new Request(`${url}${queryParams}`, {
|
const request = new Request(`${url}${queryParams}`, {
|
||||||
...rest,
|
...rest,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: new Headers({
|
headers: this.buildHeaders(options),
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(options?.headers || {}),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
return this._GET(request, { params: { slug } })
|
return this._GET(request, { params: { slug } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async GRAPHQL_POST(options: RequestInit & RequestQuery): Promise<Response> {
|
async GRAPHQL_POST(options: RequestInit & RequestOptions): Promise<Response> {
|
||||||
const { query, ...rest } = options
|
const { query, ...rest } = options
|
||||||
const queryParams = generateQueryString(query, {})
|
const queryParams = generateQueryString(query, {})
|
||||||
const request = new Request(
|
const request = new Request(
|
||||||
@@ -122,16 +136,13 @@ export class NextRESTClient {
|
|||||||
{
|
{
|
||||||
...rest,
|
...rest,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: new Headers({
|
headers: this.buildHeaders(options),
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(options?.headers || {}),
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return this._GRAPHQL_POST(request)
|
return this._GRAPHQL_POST(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
async PATCH(path: ValidPath, options: RequestInit & RequestQuery): Promise<Response> {
|
async PATCH(path: ValidPath, options: RequestInit & RequestOptions): Promise<Response> {
|
||||||
const { url, slug, params } = this.generateRequestParts(path)
|
const { url, slug, params } = this.generateRequestParts(path)
|
||||||
const { query, ...rest } = options
|
const { query, ...rest } = options
|
||||||
const queryParams = generateQueryString(query, params)
|
const queryParams = generateQueryString(query, params)
|
||||||
@@ -139,25 +150,19 @@ export class NextRESTClient {
|
|||||||
const request = new Request(`${url}${queryParams}`, {
|
const request = new Request(`${url}${queryParams}`, {
|
||||||
...rest,
|
...rest,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: new Headers({
|
headers: this.buildHeaders(options),
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(options?.headers || {}),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
return this._PATCH(request, { params: { slug } })
|
return this._PATCH(request, { params: { slug } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async POST(path: ValidPath, options: RequestInit = {}): Promise<Response> {
|
async POST(path: ValidPath, options: RequestInit & { file?: boolean } = {}): Promise<Response> {
|
||||||
const { url, slug, params } = this.generateRequestParts(path)
|
const { url, slug, params } = this.generateRequestParts(path)
|
||||||
const queryParams = generateQueryString({}, params)
|
const queryParams = generateQueryString({}, params)
|
||||||
|
|
||||||
const request = new Request(`${url}${queryParams}`, {
|
const request = new Request(`${url}${queryParams}`, {
|
||||||
...options,
|
...options,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: new Headers({
|
headers: this.buildHeaders(options),
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(options?.headers || {}),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
return this._POST(request, { params: { slug } })
|
return this._POST(request, { params: { slug } })
|
||||||
}
|
}
|
||||||
@@ -171,11 +176,15 @@ export class NextRESTClient {
|
|||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
slug: string
|
slug: string
|
||||||
}): Promise<Response> {
|
}): Promise<string> {
|
||||||
return this.POST(`/${slug}/login`, {
|
this.token = await this.POST(`/${slug}/login`, {
|
||||||
body: JSON.stringify(
|
body: JSON.stringify(
|
||||||
credentials ? { ...credentials } : { email: devUser.email, password: devUser.password },
|
credentials ? { ...credentials } : { email: devUser.email, password: devUser.password },
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => data.token)
|
||||||
|
|
||||||
|
return this.token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import {
|
|||||||
|
|
||||||
let restClient: NextRESTClient
|
let restClient: NextRESTClient
|
||||||
let payload: Payload
|
let payload: Payload
|
||||||
let token: string
|
|
||||||
|
|
||||||
type EasierChained = { id: string; relation: EasierChained }
|
type EasierChained = { id: string; relation: EasierChained }
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ describe('Relationships', () => {
|
|||||||
const config = await startMemoryDB(configPromise)
|
const config = await startMemoryDB(configPromise)
|
||||||
payload = await getPayload({ config })
|
payload = await getPayload({ config })
|
||||||
restClient = new NextRESTClient(payload.config)
|
restClient = new NextRESTClient(payload.config)
|
||||||
;({ token } = await restClient.login({ slug: usersSlug }).then((res) => res.json()))
|
await restClient.login({ slug: usersSlug })
|
||||||
})
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@@ -153,18 +152,14 @@ describe('Relationships', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should prevent an unauthorized population of strict access', async () => {
|
it('should prevent an unauthorized population of strict access', async () => {
|
||||||
const doc = await restClient.GET(`/${slug}/${post.id}`).then((res) => res.json())
|
const doc = await restClient
|
||||||
|
.GET(`/${slug}/${post.id}`, { auth: false })
|
||||||
|
.then((res) => res.json())
|
||||||
expect(doc.defaultAccessRelation).toEqual(defaultAccessRelation.id)
|
expect(doc.defaultAccessRelation).toEqual(defaultAccessRelation.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should populate strict access when authorized', async () => {
|
it('should populate strict access when authorized', async () => {
|
||||||
const doc = await restClient
|
const doc = await restClient.GET(`/${slug}/${post.id}`).then((res) => res.json())
|
||||||
.GET(`/${slug}/${post.id}`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `JWT ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
|
||||||
expect(doc.defaultAccessRelation).toEqual(defaultAccessRelation)
|
expect(doc.defaultAccessRelation).toEqual(defaultAccessRelation)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -270,22 +265,14 @@ describe('Relationships', () => {
|
|||||||
describe('Custom ID', () => {
|
describe('Custom ID', () => {
|
||||||
it('should query a custom id relation', async () => {
|
it('should query a custom id relation', async () => {
|
||||||
const { customIdRelation } = await restClient
|
const { customIdRelation } = await restClient
|
||||||
.GET(`/${slug}/${post.id}`, {
|
.GET(`/${slug}/${post.id}`)
|
||||||
headers: {
|
|
||||||
Authorization: `JWT ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
expect(customIdRelation).toMatchObject({ id: generatedCustomId })
|
expect(customIdRelation).toMatchObject({ id: generatedCustomId })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should query a custom id number relation', async () => {
|
it('should query a custom id number relation', async () => {
|
||||||
const { customIdNumberRelation } = await restClient
|
const { customIdNumberRelation } = await restClient
|
||||||
.GET(`/${slug}/${post.id}`, {
|
.GET(`/${slug}/${post.id}`)
|
||||||
headers: {
|
|
||||||
Authorization: `JWT ${token}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
expect(customIdNumberRelation).toMatchObject({ id: generatedCustomIdNumber })
|
expect(customIdNumberRelation).toMatchObject({ id: generatedCustomIdNumber })
|
||||||
})
|
})
|
||||||
@@ -312,9 +299,6 @@ describe('Relationships', () => {
|
|||||||
|
|
||||||
it('should allow update removing a relationship', async () => {
|
it('should allow update removing a relationship', async () => {
|
||||||
const response = await restClient.PATCH(`/${slug}/${post.id}`, {
|
const response = await restClient.PATCH(`/${slug}/${post.id}`, {
|
||||||
headers: {
|
|
||||||
Authorization: `JWT ${token}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
customIdRelation: null,
|
customIdRelation: null,
|
||||||
}),
|
}),
|
||||||
@@ -647,9 +631,6 @@ describe('Relationships', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
headers: {
|
|
||||||
Authorization: `JWT ${token}`,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
|
|
||||||
|
|||||||
@@ -9,21 +9,10 @@ import Uploads2 from './collections/Upload2'
|
|||||||
import AdminThumbnailCol from './collections/admin-thumbnail'
|
import AdminThumbnailCol from './collections/admin-thumbnail'
|
||||||
import { audioSlug, enlargeSlug, mediaSlug, reduceSlug, relationSlug } from './shared'
|
import { audioSlug, enlargeSlug, mediaSlug, reduceSlug, relationSlug } from './shared'
|
||||||
|
|
||||||
const mockModulePath = path.resolve(__dirname, './mocks/mockFSModule.js')
|
|
||||||
|
|
||||||
export default buildConfigWithDefaults({
|
export default buildConfigWithDefaults({
|
||||||
serverURL: undefined,
|
serverURL: undefined,
|
||||||
admin: {
|
paths: {
|
||||||
webpack: (config) => ({
|
configDir: __dirname,
|
||||||
...config,
|
|
||||||
resolve: {
|
|
||||||
...config.resolve,
|
|
||||||
alias: {
|
|
||||||
...config?.resolve?.alias,
|
|
||||||
fs: mockModulePath,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
collections: [
|
collections: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,43 +1,94 @@
|
|||||||
import FormData from 'form-data'
|
import { File as FileBuffer } from 'buffer'
|
||||||
|
import NodeFormData from 'form-data'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { promisify } from 'util'
|
import { promisify } from 'util'
|
||||||
|
|
||||||
|
import type { Payload } from '../../packages/payload/src'
|
||||||
import type { Enlarge, Media } from './payload-types'
|
import type { Enlarge, Media } from './payload-types'
|
||||||
|
|
||||||
import payload from '../../packages/payload/src'
|
import { getPayload } from '../../packages/payload/src'
|
||||||
import getFileByPath from '../../packages/payload/src/uploads/getFileByPath'
|
import getFileByPath from '../../packages/payload/src/uploads/getFileByPath'
|
||||||
import { initPayloadTest } from '../helpers/configHelpers'
|
import { NextRESTClient } from '../helpers/NextRESTClient'
|
||||||
import { RESTClient } from '../helpers/rest'
|
import { startMemoryDB } from '../startMemoryDB'
|
||||||
import configPromise from './config'
|
import configPromise from './config'
|
||||||
import { enlargeSlug, mediaSlug, reduceSlug, relationSlug } from './shared'
|
import { enlargeSlug, mediaSlug, reduceSlug, relationSlug, usersSlug } from './shared'
|
||||||
|
|
||||||
|
const getMimeType = (
|
||||||
|
filePath: string,
|
||||||
|
): {
|
||||||
|
filename: string
|
||||||
|
type: string
|
||||||
|
} => {
|
||||||
|
const ext = path.extname(filePath).slice(1)
|
||||||
|
let type: string
|
||||||
|
switch (ext) {
|
||||||
|
case 'png':
|
||||||
|
type = 'image/png'
|
||||||
|
break
|
||||||
|
case 'jpg':
|
||||||
|
type = 'image/jpeg'
|
||||||
|
break
|
||||||
|
case 'jpeg':
|
||||||
|
type = 'image/jpeg'
|
||||||
|
break
|
||||||
|
case 'svg':
|
||||||
|
type = 'image/svg+xml'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
type = 'image/png'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
filename: path.basename(filePath),
|
||||||
|
type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bufferToFileBlob = async (filePath: string): Promise<File> =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(filePath, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(`Error reading file at ${filePath}:`, err)
|
||||||
|
reject(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { filename, type } = getMimeType(filePath)
|
||||||
|
|
||||||
|
// Convert type FileBuffer > unknown > File
|
||||||
|
// The File type expects webkitRelativePath, we don't have that
|
||||||
|
resolve(new FileBuffer([data], filename, { type: type }) as unknown as File)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const stat = promisify(fs.stat)
|
const stat = promisify(fs.stat)
|
||||||
|
|
||||||
require('isomorphic-fetch')
|
let restClient: NextRESTClient
|
||||||
|
let payload: Payload
|
||||||
|
|
||||||
describe('Collections - Uploads', () => {
|
describe('Collections - Uploads', () => {
|
||||||
let client: RESTClient
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } })
|
const config = await startMemoryDB(configPromise)
|
||||||
const config = await configPromise
|
payload = await getPayload({ config })
|
||||||
client = new RESTClient(config, { serverURL, defaultSlug: mediaSlug })
|
restClient = new NextRESTClient(payload.config)
|
||||||
await client.login()
|
await restClient.login({ slug: usersSlug })
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('REST', () => {
|
describe('REST', () => {
|
||||||
describe('create', () => {
|
describe('create', () => {
|
||||||
it('creates from form data given a png', async () => {
|
it('creates from form data given a png', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './image.png')))
|
const filePath = path.join(__dirname, './image.png')
|
||||||
|
|
||||||
const { status, doc } = await client.create({
|
formData.append('file', await bufferToFileBlob(filePath))
|
||||||
|
|
||||||
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
|
|
||||||
const { sizes } = doc
|
const { sizes } = doc
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
@@ -64,14 +115,16 @@ describe('Collections - Uploads', () => {
|
|||||||
|
|
||||||
it('creates from form data given an svg', async () => {
|
it('creates from form data given an svg', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './image.svg')))
|
const filePath = path.join(__dirname, './image.svg')
|
||||||
|
formData.append('file', await bufferToFileBlob(filePath))
|
||||||
|
|
||||||
const { status, doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
|
|
||||||
// Check for files
|
// Check for files
|
||||||
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(true)
|
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(true)
|
||||||
@@ -86,14 +139,16 @@ describe('Collections - Uploads', () => {
|
|||||||
|
|
||||||
it('should have valid image url', async () => {
|
it('should have valid image url', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './image.png')))
|
const fileBlob = await bufferToFileBlob(path.join(__dirname, './image.svg'))
|
||||||
|
formData.append('file', fileBlob)
|
||||||
|
|
||||||
const { status, doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true)
|
expect(await fileExists(path.join(expectedPath, doc.filename))).toBe(true)
|
||||||
|
|
||||||
@@ -102,14 +157,16 @@ describe('Collections - Uploads', () => {
|
|||||||
|
|
||||||
it('creates images that do not require all sizes', async () => {
|
it('creates images that do not require all sizes', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './small.png')))
|
const fileBlob = await bufferToFileBlob(path.join(__dirname, './small.png'))
|
||||||
|
formData.append('file', fileBlob)
|
||||||
|
|
||||||
const { status, doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
|
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
|
|
||||||
@@ -125,14 +182,16 @@ describe('Collections - Uploads', () => {
|
|||||||
|
|
||||||
it('creates images from a different format', async () => {
|
it('creates images from a different format', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './image.jpg')))
|
const fileBlob = await bufferToFileBlob(path.join(__dirname, './image.jpg'))
|
||||||
|
formData.append('file', fileBlob)
|
||||||
|
|
||||||
const { status, doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
|
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
|
|
||||||
@@ -151,16 +210,17 @@ 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, './unstored.png')))
|
const fileBlob = await bufferToFileBlob(path.join(__dirname, './unstored.png'))
|
||||||
|
formData.append('file', fileBlob)
|
||||||
|
|
||||||
// unstored media
|
// unstored media
|
||||||
const { status, doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
slug: 'unstored-media',
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
expect(status).toBe(201)
|
expect(response.status).toBe(201)
|
||||||
|
|
||||||
// Check for files
|
// Check for files
|
||||||
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(false)
|
expect(await fileExists(path.join(__dirname, './media', doc.filename))).toBe(false)
|
||||||
@@ -242,7 +302,7 @@ describe('Collections - Uploads', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should not reduce images if resize options `withoutReduction` is set to true', async () => {
|
it('should not reduce images if resize options `withoutReduction` is set to true', async () => {
|
||||||
const formData = new FormData()
|
const formData = new NodeFormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './small.png')))
|
formData.append('file', fs.createReadStream(path.join(__dirname, './small.png')))
|
||||||
const small = await getFileByPath(path.resolve(__dirname, './small.png'))
|
const small = await getFileByPath(path.resolve(__dirname, './small.png'))
|
||||||
|
|
||||||
@@ -296,14 +356,14 @@ describe('Collections - Uploads', () => {
|
|||||||
})) as unknown as Media
|
})) as unknown as Media
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './small.png')))
|
formData.append('file', await bufferToFileBlob(path.join(__dirname, './small.png')))
|
||||||
|
|
||||||
const { status } = await client.update({
|
const response = await restClient.PATCH(`/${mediaSlug}/${mediaDoc.id}`, {
|
||||||
id: mediaDoc.id,
|
body: formData,
|
||||||
data: formData,
|
file: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(status).toBe(200)
|
expect(response.status).toBe(200)
|
||||||
|
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
|
|
||||||
@@ -325,17 +385,21 @@ describe('Collections - Uploads', () => {
|
|||||||
})) as unknown as Media
|
})) as unknown as Media
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './small.png')))
|
formData.append('file', await bufferToFileBlob(path.join(__dirname, './small.png')))
|
||||||
|
|
||||||
const { status } = await client.updateMany({
|
const response = await restClient.PATCH(`/${mediaSlug}`, {
|
||||||
// id: mediaDoc.id,
|
body: formData,
|
||||||
where: {
|
file: true,
|
||||||
id: { equals: mediaDoc.id },
|
query: {
|
||||||
|
where: {
|
||||||
|
id: {
|
||||||
|
equals: mediaDoc.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(status).toBe(200)
|
expect(response.status).toBe(200)
|
||||||
|
|
||||||
const expectedPath = path.join(__dirname, './media')
|
const expectedPath = path.join(__dirname, './media')
|
||||||
|
|
||||||
@@ -522,37 +586,43 @@ 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, './image.png')))
|
formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png')))
|
||||||
|
|
||||||
const { doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
expect(response.status).toBe(200)
|
||||||
|
|
||||||
const { status } = await client.delete(doc.id, {
|
const { doc } = await response.json()
|
||||||
id: doc.id,
|
const response2 = await restClient.DELETE(`/${mediaSlug}/${doc.id}`)
|
||||||
})
|
expect(response2.status).toBe(200)
|
||||||
|
|
||||||
expect(status).toBe(200)
|
|
||||||
|
|
||||||
expect(await fileExists(path.join(__dirname, doc.filename))).toBe(false)
|
expect(await fileExists(path.join(__dirname, doc.filename))).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('delete - update many', async () => {
|
it('delete - update many', async () => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', fs.createReadStream(path.join(__dirname, './image.png')))
|
formData.append('file', await bufferToFileBlob(path.join(__dirname, './image.png')))
|
||||||
|
|
||||||
const { doc } = await client.create({
|
const response = await restClient.POST(`/${mediaSlug}`, {
|
||||||
|
body: formData,
|
||||||
file: true,
|
file: true,
|
||||||
data: formData,
|
|
||||||
})
|
})
|
||||||
|
expect(response.status).toBe(200)
|
||||||
|
const { doc } = await response.json()
|
||||||
|
|
||||||
const { errors } = await client.deleteMany({
|
const { errors } = await restClient
|
||||||
slug: mediaSlug,
|
.DELETE(`/${mediaSlug}`, {
|
||||||
where: {
|
query: {
|
||||||
id: { equals: doc.id },
|
where: {
|
||||||
},
|
id: {
|
||||||
})
|
equals: doc.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
|
||||||
expect(errors).toHaveLength(0)
|
expect(errors).toHaveLength(0)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
export const usersSlug = 'users'
|
||||||
|
|
||||||
export const mediaSlug = 'media'
|
export const mediaSlug = 'media'
|
||||||
|
|
||||||
export const relationSlug = 'relation'
|
export const relationSlug = 'relation'
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
"@payloadcms/translations/api": ["./packages/translations/src/all"],
|
"@payloadcms/translations/api": ["./packages/translations/src/all"],
|
||||||
"@payloadcms/next/*": ["./packages/next/src/*"],
|
"@payloadcms/next/*": ["./packages/next/src/*"],
|
||||||
"@payloadcms/graphql": ["./packages/graphql/src"],
|
"@payloadcms/graphql": ["./packages/graphql/src"],
|
||||||
"payload-config": ["./test/auth/config.ts"]
|
"payload-config": ["./test/uploads/config.ts"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["dist", "build", "temp", "node_modules"],
|
"exclude": ["dist", "build", "temp", "node_modules"],
|
||||||
|
|||||||
Reference in New Issue
Block a user