Usecase puncipal + test
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
import { httpclient } from "config/httpclient.config.js";
|
||||
import { pgClient } from "config/pgclient.config.js";
|
||||
import type { ServerContext } from "domain/ServerContext.js";
|
||||
import test, { describe } from "node:test";
|
||||
import test, { describe, beforeEach } from "node:test";
|
||||
import { NfcUsecases } from "./Nfc.usecases.js";
|
||||
import type { NfcRepository } from "infrastructure/Nfc.repository.js";
|
||||
import assert from "node:assert";
|
||||
|
||||
|
||||
describe("NFC activation code", () => {
|
||||
describe("NFC activation code (Private methods)", () => {
|
||||
const serverContext: ServerContext = {
|
||||
PostgresClient: pgClient,
|
||||
HttpClient: httpclient
|
||||
}
|
||||
|
||||
const nfcUsecases = new NfcUsecases(serverContext)
|
||||
const nfcUsecases = new NfcUsecases(serverContext, {} as NfcRepository)
|
||||
|
||||
test("Should generate 8 digit codes", () => {
|
||||
// @ts-expect-error
|
||||
@@ -43,3 +43,89 @@ describe("NFC activation code", () => {
|
||||
assert(validation == false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("NfcUsecases Unit Tests (Public methods with Mocks)", () => {
|
||||
let mockNfcRepository: any;
|
||||
let mockServerContext: ServerContext;
|
||||
let nfcUsecases: NfcUsecases;
|
||||
|
||||
beforeEach(() => {
|
||||
mockNfcRepository = {
|
||||
findActivationCodes: test.mock.fn(),
|
||||
createActivationCode: test.mock.fn(),
|
||||
};
|
||||
|
||||
mockServerContext = {
|
||||
PostgresClient: {} as any,
|
||||
HttpClient: {} as any,
|
||||
};
|
||||
|
||||
nfcUsecases = new NfcUsecases(mockServerContext, mockNfcRepository as unknown as NfcRepository);
|
||||
});
|
||||
|
||||
describe("generateActivationLabel", () => {
|
||||
const card_id = "test-card-id";
|
||||
|
||||
test("should return error if repository.findActivationCodes fails", async () => {
|
||||
const expectedError = "Repository error";
|
||||
mockNfcRepository.findActivationCodes.mock.mockImplementation(async () => ({
|
||||
error: expectedError
|
||||
}));
|
||||
|
||||
const usecase = nfcUsecases.generateActivationLabel();
|
||||
const result = await usecase({ card_id });
|
||||
|
||||
assert.strictEqual(result.error, expectedError);
|
||||
assert.strictEqual(mockNfcRepository.findActivationCodes.mock.callCount(), 1);
|
||||
});
|
||||
|
||||
test("should reuse existing code if found and override is false", async () => {
|
||||
const existingCode = "v1234567";
|
||||
mockNfcRepository.findActivationCodes.mock.mockImplementation(async () => ({
|
||||
data: [{ code_plain: existingCode }]
|
||||
}));
|
||||
mockNfcRepository.createActivationCode.mock.mockImplementation(async () => ({
|
||||
data: { card_id, code_plain: existingCode }
|
||||
}));
|
||||
|
||||
const usecase = nfcUsecases.generateActivationLabel();
|
||||
const result = await usecase({ card_id, override: false });
|
||||
|
||||
assert.ok(result.data);
|
||||
assert.strictEqual(result.data.code, existingCode);
|
||||
assert.strictEqual(result.data.reused, true);
|
||||
assert.strictEqual(result.data.overriden, false);
|
||||
|
||||
assert.strictEqual(mockNfcRepository.createActivationCode.mock.callCount(), 1);
|
||||
});
|
||||
|
||||
test("should generate new code if no existing codes found", async () => {
|
||||
mockNfcRepository.findActivationCodes.mock.mockImplementation(async () => ({
|
||||
data: []
|
||||
}));
|
||||
|
||||
const usecase = nfcUsecases.generateActivationLabel();
|
||||
const result = await usecase({ card_id });
|
||||
|
||||
assert.ok(result.data);
|
||||
assert.ok(result.data.code);
|
||||
assert.strictEqual(result.data.reused, false);
|
||||
assert.strictEqual(result.data.overriden, false);
|
||||
});
|
||||
|
||||
test("should generate new code if override is true even if existing codes exist", async () => {
|
||||
const existingCode = "v1234567";
|
||||
mockNfcRepository.findActivationCodes.mock.mockImplementation(async () => ({
|
||||
data: [{ code_plain: existingCode }]
|
||||
}));
|
||||
|
||||
const usecase = nfcUsecases.generateActivationLabel();
|
||||
const result = await usecase({ card_id, override: true });
|
||||
|
||||
assert.ok(result.data);
|
||||
assert.notStrictEqual(result.data.code, existingCode);
|
||||
assert.strictEqual(result.data.reused, false);
|
||||
assert.strictEqual(result.data.overriden, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import type { ServerContext } from "domain/ServerContext.js";
|
||||
import { labelTemplate } from "./labelTemplate.js";
|
||||
import type { NfcRepository } from "infrastructure/Nfc.repository.js";
|
||||
import assert from "node:assert";
|
||||
import type { CodeGenerationResultDTO } from "domain/NfcDTOs.js";
|
||||
import type { Result } from "domain/Result.js";
|
||||
|
||||
export class NfcUsecases {
|
||||
private ctx: ServerContext;
|
||||
private nfcRepository: NfcRepository;
|
||||
|
||||
constructor(
|
||||
serverContext: ServerContext
|
||||
serverContext: ServerContext,
|
||||
nfcRepository: NfcRepository
|
||||
) {
|
||||
this.ctx = serverContext
|
||||
this.nfcRepository = nfcRepository
|
||||
}
|
||||
|
||||
private getRandomDayOffset() {
|
||||
@@ -69,16 +77,58 @@ export class NfcUsecases {
|
||||
return validationChar == testValidationChar
|
||||
}
|
||||
|
||||
/**
|
||||
* Caso de uso principal, genera una etiqueta con un codigo de activación,
|
||||
* si ya se ha generado uno para esa tarjeta se avisará.
|
||||
* Se puede forzar generar uno nuevo.
|
||||
*/
|
||||
public generateActivationLabel() {
|
||||
return () => {
|
||||
return async (args: {
|
||||
card_id: string,
|
||||
override?: boolean,
|
||||
}): Promise<Result<string, CodeGenerationResultDTO>> => {
|
||||
const generatedCodes = await this.nfcRepository.findActivationCodes(args.card_id)
|
||||
|
||||
if (generatedCodes.error != undefined) {
|
||||
console.error(generatedCodes.error)
|
||||
return generatedCodes // Caso de error
|
||||
}
|
||||
|
||||
if (generatedCodes.data.length > 0 && !args.override) {
|
||||
// Ya se habia generado un codigo
|
||||
assert(generatedCodes.data[0] != undefined)
|
||||
const code = generatedCodes.data[0].code_plain
|
||||
assert(code != undefined)
|
||||
|
||||
const label = labelTemplate(code)
|
||||
this.nfcRepository.createActivationCode({
|
||||
cardId: args.card_id,
|
||||
code: code
|
||||
})
|
||||
|
||||
return {
|
||||
data: {
|
||||
code: code,
|
||||
label: label,
|
||||
overriden: false,
|
||||
reused: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const codigo = this.generateActivationCode()
|
||||
const label = labelTemplate(codigo)
|
||||
|
||||
// Introducir en la bdd
|
||||
|
||||
// Caso base: codigo limpio generado
|
||||
return {
|
||||
code: codigo,
|
||||
label: label
|
||||
data: {
|
||||
code: codigo,
|
||||
label: label,
|
||||
overriden: args.override ?? false,
|
||||
reused: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,3 +26,12 @@ export type ActivationLogDTO = {
|
||||
geo_location: string,
|
||||
created_at: Date,
|
||||
}
|
||||
|
||||
export type CodeGenerationResultDTO = {
|
||||
code: string,
|
||||
label: string,
|
||||
/** Si ya existia un codigo anterior pero se ha creado uno nuevo*/
|
||||
overriden: boolean,
|
||||
/** Si ya existia un código anterior y se ha reusado */
|
||||
reused: boolean
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ActivationCodeDTO } from "domain/NfcRegistry.js";
|
||||
import type { ActivationCodeDTO } from "domain/NfcDTOs.js";
|
||||
import type { Result } from "domain/Result.js";
|
||||
import type { ServerContext } from "domain/ServerContext.js";
|
||||
import { constrainedMemory } from "node:process";
|
||||
|
||||
Reference in New Issue
Block a user