refactor: serverless module

This commit is contained in:
Innei
2022-03-11 11:12:09 +08:00
parent 5d88d6333f
commit 0fc0b6f84b
19 changed files with 528 additions and 360 deletions

View File

@@ -0,0 +1,136 @@
import { Test } from '@nestjs/testing'
import { getModelForClass } from '@typegoose/typegoose'
import { getModelToken } from 'nestjs-typegoose'
import { dbHelper } from 'test/helper/db-mock.helper'
import { createMockedContextResponse } from '~/modules/serverless/mock-response.util'
import { ServerlessService } from '~/modules/serverless/serverless.service'
import { SnippetModel, SnippetType } from '~/modules/snippet/snippet.model'
import { CacheService } from '~/processors/cache/cache.service'
import { AssetService } from '~/processors/helper/helper.asset.service'
import { HttpService } from '~/processors/helper/helper.http.service'
describe('test serverless function service', () => {
let service: ServerlessService
beforeAll(async () => {
await dbHelper.connect()
const moduleRef = Test.createTestingModule({
providers: [
ServerlessService,
HttpService,
AssetService,
{
provide: CacheService,
useValue: {},
},
{
provide: getModelToken('SnippetModel'),
useValue: getModelForClass(SnippetModel),
},
],
})
const app = await moduleRef.compile()
await app.init()
service = app.get(ServerlessService)
})
describe('run serverless function', () => {
test('case-1', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return 1 + 1
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBe(2)
})
test('case-2: require built-in module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return (await require('path')).join('1', '1')
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBe('1/1')
})
test('case-3: require extend module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return (await require('axios')).get.toString()
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBeDefined()
})
test('case-4: require ban module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return await require('os')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: {} as any,
}),
).rejects.toThrow()
})
test('case-5: require ban extend module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return await require('@nestjs/core')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: {} as any,
}),
).rejects.toThrow()
})
test('case-6: throws', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return context.throws(404, 'not found')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: createMockedContextResponse(),
}),
).rejects.toThrow()
})
})
})

View File

@@ -4,12 +4,10 @@ import { getModelForClass } from '@typegoose/typegoose'
import { getModelToken } from 'nestjs-typegoose'
import { dbHelper } from 'test/helper/db-mock.helper'
import { setupE2EApp } from 'test/helper/register-app.helper'
import { ServerlessService } from '~/modules/serverless/serverless.service'
import { SnippetController } from '~/modules/snippet/snippet.controller'
import { SnippetModel, SnippetType } from '~/modules/snippet/snippet.model'
import { SnippetService } from '~/modules/snippet/snippet.service'
import { CacheService } from '~/processors/cache/cache.service'
import { AssetService } from '~/processors/helper/helper.asset.service'
import { HttpService } from '~/processors/helper/helper.http.service'
describe('test /snippets', () => {
let app: NestFastifyApplication
@@ -36,9 +34,15 @@ describe('test /snippets', () => {
controllers: [SnippetController],
providers: [
SnippetService,
AssetService,
HttpService,
{ provide: CacheService, useValue: {} },
{
provide: ServerlessService,
useValue: {
isValidServerlessFunction() {
return true
},
},
},
{
provide: getModelToken(SnippetModel.name),
useValue: model,
@@ -55,7 +59,7 @@ describe('test /snippets', () => {
method: 'POST',
url: '/snippets',
payload: {
name: 'Snippet-1',
name: 'Snippet*1',
private: false,
raw: JSON.stringify({ foo: 'bar' }),
type: SnippetType.JSON,
@@ -124,4 +128,39 @@ describe('test /snippets', () => {
expect(json).toStrictEqual(JSON.parse(mockPayload1.raw))
})
})
const snippetFuncType = {
type: SnippetType.Function,
raw: async function handler(context, require) {
return 1 + 1
}.toString(),
name: 'func-1',
private: false,
reference: 'root',
}
test('POST /snippets, should create function successfully', async () => {
await app
.inject({
method: 'POST',
url: '/snippets',
payload: {
...snippetFuncType,
},
})
.then((res) => {
expect(res.statusCode).toBe(201)
})
})
test('GET /snippets/root/func-1', async () => {
await app
.inject({
method: 'GET',
url: '/snippets/root/func-1',
})
.then((res) => {
expect(res.statusCode).toBe(400)
})
})
})

View File

@@ -3,12 +3,10 @@ import { Test } from '@nestjs/testing'
import { getModelForClass } from '@typegoose/typegoose'
import { getModelToken } from 'nestjs-typegoose'
import { dbHelper } from 'test/helper/db-mock.helper'
import { createMockedContextResponse } from '~/modules/snippet/mock-response.util'
import { ServerlessService } from '~/modules/serverless/serverless.service'
import { SnippetModel, SnippetType } from '~/modules/snippet/snippet.model'
import { SnippetService } from '~/modules/snippet/snippet.service'
import { CacheService } from '~/processors/cache/cache.service'
import { AssetService } from '~/processors/helper/helper.asset.service'
import { HttpService } from '~/processors/helper/helper.http.service'
describe('test Snippet Service', () => {
let service: SnippetService
@@ -18,11 +16,11 @@ describe('test Snippet Service', () => {
const moduleRef = Test.createTestingModule({
providers: [
SnippetService,
AssetService,
HttpService,
{ provide: CacheService, useValue: {} },
{ provide: ServerlessService, useValue: {} },
{
provide: getModelToken('SnippetModel'),
provide: getModelToken(SnippetModel.name),
useValue: getModelForClass(SnippetModel),
},
],
@@ -44,6 +42,7 @@ describe('test Snippet Service', () => {
private: false,
reference: 'root',
}
let id = ''
it('should create one', async () => {
const res = await service.create(snippet)
@@ -68,104 +67,6 @@ describe('test Snippet Service', () => {
expect(res.name).toBe(snippet.name)
})
describe('run serverless function', () => {
test('case-1', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return 1 + 1
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBe(2)
})
test('case-2: require built-in module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return (await require('path')).join('1', '1')
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBe('1/1')
})
test('case-3: require extend module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return (await require('axios')).get.toString()
}.toString(),
})
const data = await service.injectContextIntoServerlessFunctionAndCall(
model,
{ req: {} as any, res: {} as any },
)
expect(data).toBeDefined()
})
test('case-4: require ban module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return await require('os')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: {} as any,
}),
).rejects.toThrow()
})
test('case-5: require ban extend module', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return await require('@nestjs/core')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: {} as any,
}),
).rejects.toThrow()
})
test('case-6: throws', async () => {
const model = new SnippetModel()
Object.assign<SnippetModel, Partial<SnippetModel>>(model, {
type: SnippetType.Function,
raw: async function handler(context, require) {
return context.throws(404, 'not found')
}.toString(),
})
expect(
service.injectContextIntoServerlessFunctionAndCall(model, {
req: {} as any,
res: createMockedContextResponse(),
}),
).rejects.toThrow()
})
})
test('modify', async () => {
const newSnippet = {
name: 'test',