@wepublish/api-media-karma
Version:
We.publish media service
232 lines (195 loc) • 7.48 kB
text/typescript
import {KarmaMediaAdapter, MediaServerError} from '../../src'
import {URL} from 'url'
import * as fs from 'fs'
import {
ArrayBufferUpload,
ImageWithFocalPoint,
ImageOutput,
ImageRotation,
ImageTransformation
} from '@wepublish/api'
import {FileUpload} from 'graphql-upload'
import fetch from 'node-fetch'
import FormData = require('form-data')
jest.mock('node-fetch')
const {Response} = jest.requireActual('node-fetch')
const mockedFetch = fetch as jest.MockedFunction<typeof fetch>
const TEST_URL = 'http://fake.localhost.com/'
const TEST_INTERNAL_URL = 'http://internal.url.com/'
const TEST_TOKEN = 'fakeToken1234'
const TEST_IMAGE_PATH = './__tests__/specs/test.jpg'
const TEST_UPLOAD_IMAGE: ImageWithFocalPoint = {
createdAt: new Date(),
modifiedAt: new Date(),
tags: [],
id: 'testId',
filename: 'test.jpg',
fileSize: 1024,
extension: '.jpg',
mimeType: 'image/jpeg',
format: 'testFormat',
width: 1024,
height: 1024,
focalPoint: {
x: null,
y: null,
imageId: ''
},
description: null,
license: null,
link: null,
source: null,
title: null
}
const TEST_TRANSFORMATION: ImageTransformation = {
height: '1024px',
width: '1024px',
rotation: ImageRotation.Rotate0,
output: ImageOutput.JPEG,
quality: 100
}
let karmaMediaAdapter: KarmaMediaAdapter
let image: ArrayBuffer
let arrayBufferPromise: Promise<ArrayBufferUpload>
let imageStream: fs.ReadStream
let fileUploadPromise: Promise<FileUpload>
describe('Karma Media Adapter', () => {
beforeEach(() => {
karmaMediaAdapter = new KarmaMediaAdapter(new URL(TEST_URL), TEST_TOKEN)
})
test('Karma Media Adapter exists', () => {
expect(karmaMediaAdapter).toBeDefined()
})
describe('UploadImage', () => {
beforeEach(() => {
imageStream = fs.createReadStream(TEST_IMAGE_PATH)
fileUploadPromise = new Promise<FileUpload>(resolve => {
resolve({
filename: 'test.jpg',
mimetype: 'image/jpeg',
encoding: 'fakeEncoding',
createReadStream: () => imageStream
})
})
})
test('should throw an error if mediaServer responds with error', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify({}), {status: 404}))
await expect(karmaMediaAdapter.uploadImage(fileUploadPromise)).rejects.toThrowError(
MediaServerError
)
})
test('should accept UploadImage', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify(TEST_UPLOAD_IMAGE)))
const uploadedImage = await karmaMediaAdapter.uploadImage(fileUploadPromise)
expect(fetch).toHaveBeenCalledWith(
new URL(TEST_URL),
expect.objectContaining({method: 'POST', body: expect.any(FormData)})
)
expect(uploadedImage.filename).toBe('test.jpg')
})
afterEach(() => {
imageStream.close()
})
})
describe('UploadImageFromArrayBuffer', () => {
beforeEach(() => {
image = fs.readFileSync(TEST_IMAGE_PATH)
arrayBufferPromise = new Promise<ArrayBufferUpload>(resolve => {
resolve({
filename: 'test.jpg',
mimetype: 'image/jpeg',
arrayBuffer: image
})
})
})
test('should throw an error if mediaServer responds with error', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify({}), {status: 404}))
await expect(
karmaMediaAdapter.uploadImageFromArrayBuffer(arrayBufferPromise)
).rejects.toThrowError(MediaServerError)
})
test('should accept ArrayBuffer', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify(TEST_UPLOAD_IMAGE)))
const uploadedImage = await karmaMediaAdapter.uploadImageFromArrayBuffer(arrayBufferPromise)
expect(fetch).toHaveBeenCalledWith(
new URL(TEST_URL),
expect.objectContaining({method: 'POST', body: expect.any(FormData)})
)
expect(uploadedImage.filename).toBe('test.jpg')
})
})
describe('KarmaMediaAdapter', () => {
test('DeleteImage should return boolean', async () => {
mockedFetch.mockResolvedValue(new Response(null, {status: 204}))
const result = await karmaMediaAdapter.deleteImage('fakeId')
expect(fetch).toHaveBeenCalledWith(
`${new URL(TEST_URL)}${'fakeId'}`,
expect.objectContaining({method: 'DELETE'})
)
expect(result).toBeTruthy()
})
test('DeleteImage should throw error if mediaServer responds with error', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify({}), {status: 404}))
await expect(karmaMediaAdapter.deleteImage('fakeId')).rejects.toThrowError(MediaServerError)
})
test('GetImageURL should return a string without transformation', async () => {
const imageURL = await karmaMediaAdapter.getImageURL(TEST_UPLOAD_IMAGE)
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.id)
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.filename)
})
test('GetImageURL should return a string with empty transformation', async () => {
const imageURL = await karmaMediaAdapter.getImageURL(TEST_UPLOAD_IMAGE, {})
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.id)
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.filename)
expect(imageURL).not.toContain('/t/')
})
test('GetImageURL should return a string with transformation', async () => {
const testImageWithFocal: ImageWithFocalPoint = {
...TEST_UPLOAD_IMAGE,
focalPoint: {
x: 50,
y: 50,
imageId: ''
}
}
const imageURL = await karmaMediaAdapter.getImageURL(testImageWithFocal, TEST_TRANSFORMATION)
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.id)
expect(imageURL).toContain(TEST_UPLOAD_IMAGE.filename)
expect(imageURL).toContain('/t/')
expect(imageURL).toContain(`w_${TEST_TRANSFORMATION.width}`)
expect(imageURL).toContain(`h_${TEST_TRANSFORMATION.height}`)
expect(imageURL).toContain(`q_${TEST_TRANSFORMATION.quality}`)
expect(imageURL).toContain(`f_50.000:50.000`)
})
})
})
describe('Karma Media Adapter with Internal URL', () => {
const karmaMediaAdapterInternalURL = new KarmaMediaAdapter(
new URL(TEST_URL),
TEST_TOKEN,
new URL(TEST_INTERNAL_URL)
)
test('UploadImage should be called with internal URL', async () => {
mockedFetch.mockResolvedValue(new Response(JSON.stringify(TEST_UPLOAD_IMAGE)))
const uploadedImage = await karmaMediaAdapterInternalURL.uploadImage(fileUploadPromise)
expect(fetch).toHaveBeenCalledWith(
new URL(TEST_INTERNAL_URL),
expect.objectContaining({method: 'POST', body: expect.any(FormData)})
)
expect(uploadedImage.filename).toBe('test.jpg')
})
test('DeleteImage should be called with internal URL', async () => {
mockedFetch.mockResolvedValue(new Response(null, {status: 204}))
const result = await karmaMediaAdapterInternalURL.deleteImage('fakeId')
expect(fetch).toHaveBeenCalledWith(
`${new URL(TEST_INTERNAL_URL)}${'fakeId'}`,
expect.objectContaining({method: 'DELETE'})
)
expect(result).toBeTruthy()
})
test('GetImageURL should use public URL ', async () => {
const imageURL = new URL(await karmaMediaAdapterInternalURL.getImageURL(TEST_UPLOAD_IMAGE))
expect(imageURL.hostname).toEqual(new URL(TEST_URL).hostname)
expect(imageURL.hostname).not.toEqual(new URL(TEST_INTERNAL_URL).hostname)
})
})