Update dependencies / Add tests

This commit is contained in:
yumauri
2020-04-01 17:50:10 +03:00
parent a037fcebfa
commit 8a37d7aa9a
8 changed files with 1307 additions and 1027 deletions
+9 -8
View File
@@ -12,7 +12,7 @@
], ],
"scripts": { "scripts": {
"dev": "ts-node src/index.ts", "dev": "ts-node src/index.ts",
"test": "jest --config jestconfig.json", "test": "jest",
"build": "rm -rf pkg/ && pika build", "build": "rm -rf pkg/ && pika build",
"format": "prettier --write \"src/**/*.ts\" --write \"test/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\" --write \"test/**/*.ts\"",
"lint": "tslint -p tsconfig.json && yarn spell", "lint": "tslint -p tsconfig.json && yarn spell",
@@ -69,23 +69,24 @@
"@pika/pack": "^0.5.0", "@pika/pack": "^0.5.0",
"@pika/plugin-build-node": "^0.9.2", "@pika/plugin-build-node": "^0.9.2",
"@pika/plugin-ts-standard-pkg": "^0.9.2", "@pika/plugin-ts-standard-pkg": "^0.9.2",
"@size-limit/preset-small-lib": "^4.3.1", "@size-limit/preset-small-lib": "^4.4.2",
"@types/jest": "^25.1.4", "@types/jest": "^25.1.4",
"@types/node": "^13.9.1", "@types/node": "^13.9.8",
"flowgen": "^1.10.0", "flowgen": "^1.10.0",
"jest": "^25.1.0", "jest": "^25.2.4",
"nock": "^12.0.3",
"pika-plugin-package.json": "^1.0.2", "pika-plugin-package.json": "^1.0.2",
"pika-plugin-typedefs-to-flow": "^0.0.2", "pika-plugin-typedefs-to-flow": "^0.0.2",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"size-limit": "^4.3.1", "size-limit": "^4.4.2",
"ts-jest": "^25.2.1", "ts-jest": "^25.3.0",
"ts-node": "^8.6.2", "ts-node": "^8.8.1",
"tslint": "^6.1.0", "tslint": "^6.1.0",
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"tslint-config-security": "^1.16.0", "tslint-config-security": "^1.16.0",
"tslint-config-standard-plus": "^2.3.0", "tslint-config-standard-plus": "^2.3.0",
"typescript": "^3.8.3", "typescript": "^3.8.3",
"yaspeller": "^6.0.3" "yaspeller": "^6.1.0"
}, },
"engines": { "engines": {
"node": ">=10.9.0" "node": ">=10.9.0"
+1
View File
@@ -69,6 +69,7 @@ export const toTuples = (source: Source, recursive = false): TupleSource[] => {
// if we get there inside of recursion -> this is bad // if we get there inside of recursion -> this is bad
if (recursive) { if (recursive) {
// by tests looks like this is impossible case -> should remove it?
throw new Error('Bad source, possible recursive iterables?') throw new Error('Bad source, possible recursive iterables?')
} }
+80
View File
@@ -0,0 +1,80 @@
import nock from 'nock'
import FormData from 'form-data'
import { client } from '../../src/client/node'
// Helper function to get response JOSN body
async function toJSON(response: any) {
const chunks: any[] = []
const text = await new Promise<string>((resolve, reject) => {
response.on('data', (chunk: any) => chunks.push(chunk))
response.on('error', reject)
response.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
})
return JSON.parse(text)
}
test('`client` should return functional client', () => {
const clnt = client()
expect(typeof clnt.get).toBe('function')
expect(typeof clnt.post).toBe('function')
})
test('Should do GET request', async () => {
nock('https://127.0.0.1:3000')
.get('/ping')
.reply(200, { status: 'OK' })
const clnt = client()
const response = await clnt.get!('https://127.0.0.1:3000/ping')
expect(await toJSON(response)).toEqual({ status: 'OK' })
})
test('Should throw on bad GET request', async () => {
nock('https://127.0.0.1:3000')
.get('/ping')
.reply(500)
const clnt = client()
let error: any
try {
await clnt.get!('https://127.0.0.1:3000/ping')
} catch (e) {
error = e
}
expect(error).toEqual(new Error('500 null'))
})
test('Should do POST request', async () => {
nock('https://127.0.0.1:3000')
.post('/convert/html')
.reply(200, { status: 'OK' })
const clnt = client()
const response = await clnt.post('https://127.0.0.1:3000/convert/html', new FormData())
expect(await toJSON(response)).toEqual({ status: 'OK' })
})
test('Should throw on bad POST request', async () => {
nock('https://127.0.0.1:3000')
.post('/convert/html')
.reply(500, { status: 'ERROR' })
const clnt = client()
let error: any
try {
await clnt.post('https://127.0.0.1:3000/convert/html', new FormData())
} catch (e) {
error = e
}
expect(error).toEqual(new Error('500 null (undefined)')) // hm???
})
test('Should handle http', async () => {
nock('http://127.0.0.1:3000')
.get('/ping')
.reply(200, { status: 'OK' })
const clnt = client()
const response = await clnt.get!('http://127.0.0.1:3000/ping')
expect(await toJSON(response)).toEqual({ status: 'OK' })
})
+74
View File
@@ -0,0 +1,74 @@
import { RequestType } from '../src'
import { gotenberg } from '../src/gotenberg'
test('Test `gotenberg` function without client', () => {
const fn = gotenberg('http://120.0.0.1:3000')
expect(typeof fn).toBe('function')
expect(fn('test')).toMatchObject({
type: RequestType.Undefined,
url: 'http://120.0.0.1:3000',
source: 'test',
fields: {},
})
})
test('Test `gotenberg` function with custom client', () => {
const client = {
get() {}, // tslint:disable-line: no-empty
post() {}, // tslint:disable-line: no-empty
}
const fn = gotenberg('http://120.0.0.1:3000', client)
expect(typeof fn).toBe('function')
expect(fn('test')).toEqual({
type: RequestType.Undefined,
client,
url: 'http://120.0.0.1:3000',
source: 'test',
fields: {},
})
})
test('Test `gotenberg` function with custom functional client', () => {
const mock = jest.fn()
const clientImpl = {
get() {}, // tslint:disable-line: no-empty
post() {}, // tslint:disable-line: no-empty
}
const client = function(arg: any) {
mock(arg)
return clientImpl
}
const fn = gotenberg('http://120.0.0.1:3000', client, { base: 'test' })
expect(typeof fn).toBe('function')
expect(fn('test')).toEqual({
type: RequestType.Undefined,
client: clientImpl,
url: 'http://120.0.0.1:3000',
source: 'test',
fields: {},
})
expect(mock.mock.calls.length).toBe(1)
expect(mock.mock.calls[0][0]).toEqual({ base: 'test' })
})
test('Test `gotenberg` function with custom class client', () => {
const mock = jest.fn()
class Client {
constructor(arg: any) {
mock(arg)
}
get() {} // tslint:disable-line: no-empty
post() {} // tslint:disable-line: no-empty
}
const fn = gotenberg('http://120.0.0.1:3000', Client, { base: 'test' })
expect(typeof fn).toBe('function')
expect(fn('test')).toEqual({
type: RequestType.Undefined,
client: expect.any(Client),
url: 'http://120.0.0.1:3000',
source: 'test',
fields: {},
})
expect(mock.mock.calls.length).toBe(1)
expect(mock.mock.calls[0][0]).toEqual({ base: 'test' })
})
+71
View File
@@ -0,0 +1,71 @@
import { Readable } from 'stream'
import { basename } from 'path'
import { createReadStream, ReadStream } from 'fs'
import {
DEFAULT_FILENAME,
fromFile,
toStream,
toStreams,
toTuples,
} from '../../src/internal/source-converters'
// tslint:disable no-any
test('Test `toTuples` function', () => {
expect(() => toTuples(undefined as any)).toThrow()
expect(toTuples(new URL('http://1'))).toEqual([])
expect(toTuples('file://test.html')).toEqual([[DEFAULT_FILENAME, 'file://test.html']])
expect(toTuples('file://test.doc')).toEqual([['test.doc', 'file://test.doc']])
expect(toTuples('test')).toEqual([[DEFAULT_FILENAME, 'test']])
const buffer = Buffer.from('test')
expect(toTuples(buffer)).toEqual([[DEFAULT_FILENAME, buffer]])
const stream = new Readable()
expect(toTuples(stream)).toEqual([[DEFAULT_FILENAME, stream]])
const file = createReadStream(__filename)
expect(toTuples(file)).toEqual([[basename(__filename), file]])
expect(toTuples(['index.html', 'test'])).toEqual([['index.html', 'test']])
expect(toTuples({ 'index.html': 'test' })).toEqual([['index.html', 'test']])
const map = new Map<string, any>()
map.set('index.html', 'test')
expect(toTuples(map)).toEqual([['index.html', 'test']])
const set = new Set<any>()
set.add(new Set<any>())
expect(() => toTuples(set)).toThrow('Bad source, don\'t know what to do with "[object Set]"')
})
test('Test `fromFile` function', () => {
expect(fromFile('file:' + __filename) instanceof ReadStream).toBe(true)
expect(fromFile('file://' + __filename) instanceof ReadStream).toBe(true)
})
test('Test `toStream` function', async () => {
const stream0 = new Readable()
expect(toStream(stream0)).toEqual(stream0)
expect(toStream('file:' + __filename) instanceof ReadStream).toBe(true)
expect(toStream('test') instanceof Readable).toBe(true)
const chunks: any[] = []
const stream = toStream('test')
const result = await new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk))
stream.on('error', reject)
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
})
expect(result).toEqual('test')
})
test('Test `toStreams` function', () => {
expect(toStreams()).toEqual([])
const result1 = toStreams(Buffer.from('test'))
expect(result1 instanceof Array).toBe(true)
expect(result1[0] instanceof Array).toBe(true)
expect(result1[0][0]).toEqual(DEFAULT_FILENAME)
expect(result1[0][1] instanceof Readable).toBe(true)
})
+120
View File
@@ -0,0 +1,120 @@
import FormData from 'form-data'
import { createReadStream } from 'fs'
import { HtmlRequest, MarkdownRequest, OfficeRequest, PingRequest, RequestType } from '../src'
import { please } from '../src/please'
test('Should make client POST call with request', async () => {
const get = jest.fn()
const post = jest.fn()
const request: HtmlRequest = {
type: RequestType.Html,
client: { get, post },
url: 'http://120.0.0.1:3000/convert/html',
source: 'test',
fields: {},
}
await please(request)
expect(post.mock.calls.length).toBe(1)
expect(post.mock.calls[0][0]).toEqual('http://120.0.0.1:3000/convert/html')
expect(post.mock.calls[0][1]).toEqual(expect.any(FormData))
})
test('Should make client GET call with ping request', async () => {
const get = jest.fn()
const post = jest.fn()
const request: PingRequest = {
type: RequestType.Ping,
client: {
get: async url => {
get(url)
return createReadStream(__filename)
},
post,
},
url: 'http://120.0.0.1:3000/ping',
fields: {},
}
await please(request)
expect(get.mock.calls.length).toBe(1)
expect(get.mock.calls[0][0]).toEqual('http://120.0.0.1:3000/ping')
})
test('Should throw on ping request if there is no get method', () => {
const post = jest.fn()
const request: PingRequest = {
type: RequestType.Ping,
client: { post },
url: 'http://120.0.0.1:3000/ping',
fields: {},
}
expect(() => please(request)).toThrow(`Gotenberg client doesn't implements "get" method`)
})
test('Should make client POST call with request', async () => {
const get = jest.fn()
const post = jest.fn()
const fields = Object.create({ test: 'test' }) // this is to test 'hasOwnProperty'
fields.landscape = true
fields.resultFilename = 'index.pdf'
fields.waitDelay = undefined
const request: HtmlRequest = {
type: RequestType.Html,
client: { get, post },
url: 'http://120.0.0.1:3000/convert/html',
source: 'test',
fields,
headers: { 'Gotenberg-Remoteurl-Test': 'Foo' },
}
await please(request)
expect(post.mock.calls.length).toBe(1)
expect(post.mock.calls[0][0]).toEqual('http://120.0.0.1:3000/convert/html')
expect(post.mock.calls[0][1]).toEqual(expect.any(FormData))
expect(post.mock.calls[0][2]).toEqual({ 'Gotenberg-Remoteurl-Test': 'Foo' })
})
test('Should throw on duplicates', () => {
const request: HtmlRequest = {
type: RequestType.Html,
source: [
['index.html', 'test'],
['index.html', 'test'],
],
} as any
expect(() => please(request)).toThrow(`There are duplicates in file names: index.html`)
})
test('Should throw on wrong source filenames', () => {
const request1: HtmlRequest = {
type: RequestType.Html,
source: { 'test.doc': 'test' },
} as any
expect(() => please(request1)).toThrow(`File "index.html" is required for HTML conversion`)
const request2: MarkdownRequest = {
type: RequestType.Markdown,
source: { 'test.doc': 'test' },
} as any
expect(() => please(request2)).toThrow(`File "index.html" is required for Markdown conversion`)
const request3: OfficeRequest = {
type: RequestType.Office,
source: { 'index.html': 'test' },
} as any
expect(() => please(request3)).toThrow(
`Default filename "index.html" is not allowed for Office conversion, ` +
`looks like you didn't set filename for document`
)
})
+952 -1019
View File
File diff suppressed because it is too large Load Diff