Usecase puncipal + test
This commit is contained in:
@@ -1,18 +1,18 @@
|
|||||||
import { httpclient } from "config/httpclient.config.js";
|
import { httpclient } from "config/httpclient.config.js";
|
||||||
import { pgClient } from "config/pgclient.config.js";
|
import { pgClient } from "config/pgclient.config.js";
|
||||||
import type { ServerContext } from "domain/ServerContext.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 { NfcUsecases } from "./Nfc.usecases.js";
|
||||||
|
import type { NfcRepository } from "infrastructure/Nfc.repository.js";
|
||||||
import assert from "node:assert";
|
import assert from "node:assert";
|
||||||
|
|
||||||
|
describe("NFC activation code (Private methods)", () => {
|
||||||
describe("NFC activation code", () => {
|
|
||||||
const serverContext: ServerContext = {
|
const serverContext: ServerContext = {
|
||||||
PostgresClient: pgClient,
|
PostgresClient: pgClient,
|
||||||
HttpClient: httpclient
|
HttpClient: httpclient
|
||||||
}
|
}
|
||||||
|
|
||||||
const nfcUsecases = new NfcUsecases(serverContext)
|
const nfcUsecases = new NfcUsecases(serverContext, {} as NfcRepository)
|
||||||
|
|
||||||
test("Should generate 8 digit codes", () => {
|
test("Should generate 8 digit codes", () => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@@ -43,3 +43,89 @@ describe("NFC activation code", () => {
|
|||||||
assert(validation == false)
|
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 type { ServerContext } from "domain/ServerContext.js";
|
||||||
import { labelTemplate } from "./labelTemplate.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 {
|
export class NfcUsecases {
|
||||||
private ctx: ServerContext;
|
private ctx: ServerContext;
|
||||||
|
private nfcRepository: NfcRepository;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
serverContext: ServerContext
|
serverContext: ServerContext,
|
||||||
|
nfcRepository: NfcRepository
|
||||||
) {
|
) {
|
||||||
this.ctx = serverContext
|
this.ctx = serverContext
|
||||||
|
this.nfcRepository = nfcRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRandomDayOffset() {
|
private getRandomDayOffset() {
|
||||||
@@ -69,16 +77,58 @@ export class NfcUsecases {
|
|||||||
return validationChar == testValidationChar
|
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() {
|
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 codigo = this.generateActivationCode()
|
||||||
const label = labelTemplate(codigo)
|
const label = labelTemplate(codigo)
|
||||||
|
|
||||||
// Introducir en la bdd
|
// Introducir en la bdd
|
||||||
|
|
||||||
|
// Caso base: codigo limpio generado
|
||||||
return {
|
return {
|
||||||
code: codigo,
|
data: {
|
||||||
label: label
|
code: codigo,
|
||||||
|
label: label,
|
||||||
|
overriden: args.override ?? false,
|
||||||
|
reused: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,12 @@ export type ActivationLogDTO = {
|
|||||||
geo_location: string,
|
geo_location: string,
|
||||||
created_at: Date,
|
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 { Result } from "domain/Result.js";
|
||||||
import type { ServerContext } from "domain/ServerContext.js";
|
import type { ServerContext } from "domain/ServerContext.js";
|
||||||
import { constrainedMemory } from "node:process";
|
import { constrainedMemory } from "node:process";
|
||||||
|
|||||||
Reference in New Issue
Block a user