From 104f52fb1ec7b5031f5fc7d5f3156d06f6f0ef95 Mon Sep 17 00:00:00 2001 From: Sion Ramos de los Santos Date: Wed, 5 Apr 2023 02:28:14 -0300 Subject: [PATCH] feat: implement control-plane service and testing --- .../drivens/for-authenticador-stub-adapter.ts | 53 +++++++++++ .../control-plane/adapters/drivens/index.ts | 1 + .../drivers/control-authenticating-proxy.ts | 16 ++++ .../control-plane/adapters/drivers/index.ts | 1 + .../control-plane/app/composition-root.ts | 16 ++++ .../control-plane/app/control-plane.test.ts | 90 +++++++++++++++++++ .../control-plane/app/control-plane.ts | 14 +++ .../control-plane/app/shemas/authDetails.ts | 4 + .../control-plane/app/shemas/index.ts | 2 + .../control-plane/app/shemas/permissions.ts | 4 + .../control-plane/ports/drivens/for-auth.ts | 6 ++ .../control-plane/ports/drivens/index.ts | 1 + .../ports/drivers/for-authenticating-user.ts | 6 ++ .../control-plane/ports/drivers/index.ts | 1 + 14 files changed, 215 insertions(+) create mode 100644 src/services/control-plane/adapters/drivens/for-authenticador-stub-adapter.ts create mode 100644 src/services/control-plane/adapters/drivens/index.ts create mode 100644 src/services/control-plane/adapters/drivers/control-authenticating-proxy.ts create mode 100644 src/services/control-plane/adapters/drivers/index.ts create mode 100644 src/services/control-plane/app/composition-root.ts create mode 100644 src/services/control-plane/app/control-plane.test.ts create mode 100644 src/services/control-plane/app/control-plane.ts create mode 100644 src/services/control-plane/app/shemas/authDetails.ts create mode 100644 src/services/control-plane/app/shemas/index.ts create mode 100644 src/services/control-plane/app/shemas/permissions.ts create mode 100644 src/services/control-plane/ports/drivens/for-auth.ts create mode 100644 src/services/control-plane/ports/drivens/index.ts create mode 100644 src/services/control-plane/ports/drivers/for-authenticating-user.ts create mode 100644 src/services/control-plane/ports/drivers/index.ts diff --git a/src/services/control-plane/adapters/drivens/for-authenticador-stub-adapter.ts b/src/services/control-plane/adapters/drivens/for-authenticador-stub-adapter.ts new file mode 100644 index 0000000..0528b14 --- /dev/null +++ b/src/services/control-plane/adapters/drivens/for-authenticador-stub-adapter.ts @@ -0,0 +1,53 @@ +import { AuthDetails, Permissions } from "../../app/shemas"; +import { ForAuthenticating } from "../../ports/drivens"; + +const authDetailsMock: AuthDetails = { + token: "it's a token", + refreshToken: "it's a cool token", +}; + +interface userMock extends Permissions { + email: string; + password: string; +} + +const users: userMock[] = [ + { + user: true, + admin: true, + email: "JohnC@gmail.com", + password: "It's John Cena", + }, + { + user: true, + admin: false, + email: "Mesirve@gmail.com", + password: "123456", + }, +]; + +export class ControlAuthenticatorStub implements ForAuthenticating { + async getAuthDetails(email: string, password: string): Promise { + const user = users.find( + (curUser) => curUser.email == email && curUser.password == password + ); + + if (!user) { + throw new Error("user does not authenticated"); + } + + return Promise.resolve(authDetailsMock); + } + + async getPermissions(email: string, password: string): Promise { + const user = users.find( + (curUser) => curUser.email == email && curUser.password == password + ); + + if (!user) { + throw new Error("user does not have permissions"); + } + + return Promise.resolve({ admin: user.admin, user: user.user }); + } +} diff --git a/src/services/control-plane/adapters/drivens/index.ts b/src/services/control-plane/adapters/drivens/index.ts new file mode 100644 index 0000000..cf83011 --- /dev/null +++ b/src/services/control-plane/adapters/drivens/index.ts @@ -0,0 +1 @@ +export * from "./for-authenticador-stub-adapter"; diff --git a/src/services/control-plane/adapters/drivers/control-authenticating-proxy.ts b/src/services/control-plane/adapters/drivers/control-authenticating-proxy.ts new file mode 100644 index 0000000..a7a55cb --- /dev/null +++ b/src/services/control-plane/adapters/drivers/control-authenticating-proxy.ts @@ -0,0 +1,16 @@ +import { ControlPlane } from "../../app/control-plane"; +import { AuthDetails, Permissions } from "../../app/shemas"; +import { ForAuthenticatingUser } from "../../ports/drivers"; + +export class ControlAuthenticatingProxyAdapter + implements ForAuthenticatingUser +{ + constructor(private readonly controlPlane: ControlPlane) {} + + async getAuthDetails(email: string, password: string): Promise { + return this.controlPlane.getAuthDetails(email, password); + } + async getPermissions(email: string, password: string): Promise { + return this.controlPlane.getPermissions(email, password); + } +} diff --git a/src/services/control-plane/adapters/drivers/index.ts b/src/services/control-plane/adapters/drivers/index.ts new file mode 100644 index 0000000..6f0a535 --- /dev/null +++ b/src/services/control-plane/adapters/drivers/index.ts @@ -0,0 +1 @@ +export * from "./control-authenticating-proxy"; diff --git a/src/services/control-plane/app/composition-root.ts b/src/services/control-plane/app/composition-root.ts new file mode 100644 index 0000000..4ae39a7 --- /dev/null +++ b/src/services/control-plane/app/composition-root.ts @@ -0,0 +1,16 @@ +import { ControlPlane } from "./control-plane"; +import { ControlAuthenticatorStub } from "../adapters/drivens"; +import { ControlAuthenticatingProxyAdapter } from "../adapters/drivers"; + +export const compositionMock = () => { + const authenticatorStub = new ControlAuthenticatorStub(); + const controlPlane = new ControlPlane(authenticatorStub); + const controlAuthenticatingProxyAdapter = + new ControlAuthenticatingProxyAdapter(controlPlane); + + return { + controlAuthenticatingProxyAdapter, + }; +}; + +export const { controlAuthenticatingProxyAdapter } = compositionMock(); diff --git a/src/services/control-plane/app/control-plane.test.ts b/src/services/control-plane/app/control-plane.test.ts new file mode 100644 index 0000000..a937885 --- /dev/null +++ b/src/services/control-plane/app/control-plane.test.ts @@ -0,0 +1,90 @@ +import { describe, expect, it } from "vitest"; +import { ControlPlane } from "./control-plane"; +import { ControlAuthenticatorStub } from "../adapters/drivens"; +import { ControlAuthenticatingProxyAdapter } from "../adapters/drivers"; +import { AuthDetails, Permissions } from "./shemas"; + +describe("Control Plane", () => { + const authenticatorStub = new ControlAuthenticatorStub(); + const controlPlane = new ControlPlane(authenticatorStub); + const controlAuthenticatingProxyAdapter = + new ControlAuthenticatingProxyAdapter(controlPlane); + + it.concurrent("should return a token an refreshToken", async () => { + const mockedUser = { + email: "JohnC@gmail.com", + password: "It's John Cena", + }; + + const expectResult: AuthDetails = { + token: "it's a token", + refreshToken: "it's a cool token", + }; + + const result = await controlAuthenticatingProxyAdapter.getAuthDetails( + mockedUser.email, + mockedUser.password + ); + + expect(result).toEqual(expectResult); + }); + + it.concurrent("should throw error ", async () => { + const mockedUser = { + email: "Simon@gmail.com", + password: "Simon si soy", + }; + + const expectResult: AuthDetails = { + token: "it's a token", + refreshToken: "it's a cool token", + }; + let result; + + try { + result = await controlAuthenticatingProxyAdapter.getAuthDetails( + mockedUser.email, + mockedUser.password + ); + } catch (e) {} + expect(result).not.toEqual(expectResult); + }); + + it.concurrent("should be return user permission only", async () => { + const mockedUser = { + email: "Mesirve@gmail.com", + password: "123456", + }; + + const expectResult: Permissions = { + admin: false, + user: true, + }; + + const result = await controlAuthenticatingProxyAdapter.getPermissions( + mockedUser.email, + mockedUser.password + ); + + expect(result).toEqual(expectResult); + }); + + it.concurrent("should be return both permissions", async () => { + const mockedUser = { + email: "JohnC@gmail.com", + password: "It's John Cena", + }; + + const expectResult: Permissions = { + admin: true, + user: true, + }; + + const result = await controlAuthenticatingProxyAdapter.getPermissions( + mockedUser.email, + mockedUser.password + ); + + expect(result).toEqual(expectResult); + }); +}); diff --git a/src/services/control-plane/app/control-plane.ts b/src/services/control-plane/app/control-plane.ts new file mode 100644 index 0000000..ed57cfe --- /dev/null +++ b/src/services/control-plane/app/control-plane.ts @@ -0,0 +1,14 @@ +import { ForAuthenticatingUser } from "../ports/drivers"; +import { AuthDetails, Permissions } from "./shemas"; +import { ForAuthenticating } from "../ports/drivens"; + +export class ControlPlane implements ForAuthenticatingUser { + constructor(private readonly handlerAuthorization: ForAuthenticating) {} + + async getAuthDetails(email: string, password: string): Promise { + return this.handlerAuthorization.getAuthDetails(email, password); + } + async getPermissions(email: string, password: string): Promise { + return this.handlerAuthorization.getPermissions(email, password); + } +} diff --git a/src/services/control-plane/app/shemas/authDetails.ts b/src/services/control-plane/app/shemas/authDetails.ts new file mode 100644 index 0000000..bb5cdfe --- /dev/null +++ b/src/services/control-plane/app/shemas/authDetails.ts @@ -0,0 +1,4 @@ +export interface AuthDetails { + token: string; + refreshToken: string; +} diff --git a/src/services/control-plane/app/shemas/index.ts b/src/services/control-plane/app/shemas/index.ts new file mode 100644 index 0000000..f142d8d --- /dev/null +++ b/src/services/control-plane/app/shemas/index.ts @@ -0,0 +1,2 @@ +export * from "./authDetails"; +export * from "./permissions"; diff --git a/src/services/control-plane/app/shemas/permissions.ts b/src/services/control-plane/app/shemas/permissions.ts new file mode 100644 index 0000000..adce1ad --- /dev/null +++ b/src/services/control-plane/app/shemas/permissions.ts @@ -0,0 +1,4 @@ +export interface Permissions { + admin: boolean; + user: boolean; +} diff --git a/src/services/control-plane/ports/drivens/for-auth.ts b/src/services/control-plane/ports/drivens/for-auth.ts new file mode 100644 index 0000000..8c8aa17 --- /dev/null +++ b/src/services/control-plane/ports/drivens/for-auth.ts @@ -0,0 +1,6 @@ +import { AuthDetails, Permissions } from "../../app/shemas"; + +export interface ForAuthenticating { + getAuthDetails(email: string, password: string): Promise; + getPermissions(email: string, password: string): Promise; +} diff --git a/src/services/control-plane/ports/drivens/index.ts b/src/services/control-plane/ports/drivens/index.ts new file mode 100644 index 0000000..757c339 --- /dev/null +++ b/src/services/control-plane/ports/drivens/index.ts @@ -0,0 +1 @@ +export * from "./for-auth"; diff --git a/src/services/control-plane/ports/drivers/for-authenticating-user.ts b/src/services/control-plane/ports/drivers/for-authenticating-user.ts new file mode 100644 index 0000000..ba3e1b6 --- /dev/null +++ b/src/services/control-plane/ports/drivers/for-authenticating-user.ts @@ -0,0 +1,6 @@ +import { AuthDetails, Permissions } from "../../app/shemas"; + +export interface ForAuthenticatingUser { + getAuthDetails(email: string, password: string): Promise; + getPermissions(email: string, password: string): Promise; +} diff --git a/src/services/control-plane/ports/drivers/index.ts b/src/services/control-plane/ports/drivers/index.ts new file mode 100644 index 0000000..de07d6b --- /dev/null +++ b/src/services/control-plane/ports/drivers/index.ts @@ -0,0 +1 @@ +export * from "./for-authenticating-user";