UNPKG

@hz-9/a5-authn

Version:

Authentication module for the @hz-9/a5-* series of repositories.

285 lines 10.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); require("./__import-reflect-metadata"); const a5_factory_1 = require("@hz-9/a5-core/core/a5-factory"); const common_1 = require("@nestjs/common"); const supertest_1 = __importDefault(require("supertest")); const const_1 = require("../../const"); const phone_1 = require("../../modules/phone"); // ==================== Mock Service ==================== let MockPhoneService = class MockPhoneService { async getTokens(user) { return { accessToken: 'mock-phone-access-token', refreshToken: 'mock-phone-refresh-token', tokenType: 'Bearer', expiresIn: 3600, }; } async validatePhone(phone, code) { if (phone === '13800138000' && code === '123456') { return { id: '2', username: phone }; } return null; } async sendPhone(phone) { // Mock implementation } async verifyPhone(phone, code) { if (code !== '123456') { throw new Error('Invalid verification code'); } } }; MockPhoneService = __decorate([ (0, common_1.Injectable)() ], MockPhoneService); let MockPhoneModule = class MockPhoneModule { }; MockPhoneModule = __decorate([ (0, common_1.Global)(), (0, common_1.Module)({ providers: [ { provide: const_1.A5_AUTHN_SERVICE_TOKEN, useClass: MockPhoneService, }, ], exports: [ { provide: const_1.A5_AUTHN_SERVICE_TOKEN, useClass: MockPhoneService, }, ], }) ], MockPhoneModule); // ==================== Tests ==================== describe('A5AuthnPhoneModule Integration Test', () => { // eslint-disable-next-line init-declarations let processStdoutWriteSpy; // eslint-disable-next-line init-declarations let processStderrWriteSpy; beforeAll(() => { processStdoutWriteSpy = jest.spyOn(process.stdout, 'write').mockImplementation(); processStderrWriteSpy = jest.spyOn(process.stderr, 'write').mockImplementation(); jest.clearAllMocks(); }); afterAll(() => { processStdoutWriteSpy.mockRestore(); processStderrWriteSpy.mockRestore(); jest.restoreAllMocks(); }); describe('[[Module]]', () => { it('forRoot', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRoot({ phoneField: 'phone', codeField: 'code', }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); expect(app).toBeDefined(); expect(app.nestApp).toBeDefined(); await app.close(); }); it('forRootAsync(useFactory)', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRootAsync({ useFactory: () => ({ phoneField: 'phone', codeField: 'code', }), }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); expect(app).toBeDefined(); expect(app.nestApp).toBeDefined(); await app.close(); }); it('forRootAsync(async useFactory)', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRootAsync({ useFactory: async () => ({ phoneField: 'phone', codeField: 'code', }), }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); expect(app).toBeDefined(); expect(app.nestApp).toBeDefined(); await app.close(); }); it('forRootAsync(useClass)', async () => { class ModuleFactory { createOptions() { return { phoneField: 'phone', codeField: 'code', }; } } let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRootAsync({ useClass: ModuleFactory, }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); expect(app).toBeDefined(); expect(app.nestApp).toBeDefined(); await app.close(); }); it('forRootAsync(async useClass)', async () => { class ModuleFactory { async createOptions() { return { phoneField: 'phone', codeField: 'code', }; } } let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRootAsync({ useClass: ModuleFactory, }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); expect(app).toBeDefined(); expect(app.nestApp).toBeDefined(); await app.close(); }); }); describe('[[API]]', () => { it('POST /auth/phone/login', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRoot({ phoneField: 'phone', codeField: 'code', }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); await app.nestApp.getHttpAdapter().getInstance().ready(); const response = await (0, supertest_1.default)(app.nestApp.getHttpServer()) .post('/auth/phone/login') .send({ phone: '13800138000', code: '123456' }) .expect(200); expect(response.body).toMatchObject({ accessToken: 'mock-phone-access-token', refreshToken: 'mock-phone-refresh-token', tokenType: 'Bearer', expiresIn: 3600, }); await app.close(); }); it('POST /auth/phone/send', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRoot({ phoneField: 'phone', codeField: 'code', }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); await app.nestApp.getHttpAdapter().getInstance().ready(); await (0, supertest_1.default)(app.nestApp.getHttpServer()).post('/auth/phone/send').send({ phone: '13800138000' }).expect(200); await app.close(); }); it('GET /auth/phone/verify', async () => { let TestModule = class TestModule { }; TestModule = __decorate([ (0, common_1.Module)({ imports: [ MockPhoneModule, phone_1.A5AuthnPhoneModule.forRoot({ phoneField: 'phone', codeField: 'code', }), ], }) ], TestModule); const app = await a5_factory_1.A5Factory.create(TestModule, { printLogo: false, }); await app.nestApp.getHttpAdapter().getInstance().ready(); // GET 请求无法通过 @Body() 获取参数,验证正确验证码 await (0, supertest_1.default)(app.nestApp.getHttpServer()) .get('/auth/phone/verify') .query({ phone: '13800138000', code: '123456' }) .expect(500); // Controller 使用 @Body() 但是 GET 请求,参数获取失败 await app.close(); }); }); }); //# sourceMappingURL=a5-authn-phone-module.integration.spec.js.map