-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement control-plane service and testing #1
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: "[email protected]", | ||
password: "It's John Cena", | ||
}, | ||
{ | ||
user: true, | ||
admin: false, | ||
email: "[email protected]", | ||
password: "123456", | ||
}, | ||
]; | ||
|
||
export class ControlAuthenticatorStub implements ForAuthenticating { | ||
async getAuthDetails(email: string, password: string): Promise<AuthDetails> { | ||
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<Permissions> { | ||
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 }); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./for-authenticador-stub-adapter"; |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -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<AuthDetails> { | ||||||||
return this.controlPlane.getAuthDetails(email, password); | ||||||||
} | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agregar espacio entre métodos y secciones lógicas
Suggested change
|
||||||||
async getPermissions(email: string, password: string): Promise<Permissions> { | ||||||||
return this.controlPlane.getPermissions(email, password); | ||||||||
} | ||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./control-authenticating-proxy"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. llamarlo controlPlaneMock, ya que justamente es un mock del control plane |
||
const controlAuthenticatingProxyAdapter = | ||
new ControlAuthenticatingProxyAdapter(controlPlane); | ||
|
||
return { | ||
controlAuthenticatingProxyAdapter, | ||
}; | ||
}; | ||
|
||
export const { controlAuthenticatingProxyAdapter } = compositionMock(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. faltan los |
||
const mockedUser = { | ||
email: "[email protected]", | ||
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: "[email protected]", | ||
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: "[email protected]", | ||
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: "[email protected]", | ||
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); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<AuthDetails> { | ||
return this.handlerAuthorization.getAuthDetails(email, password); | ||
} | ||
async getPermissions(email: string, password: string): Promise<Permissions> { | ||
return this.handlerAuthorization.getPermissions(email, password); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface AuthDetails { | ||
token: string; | ||
refreshToken: string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./authDetails"; | ||
export * from "./permissions"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface Permissions { | ||
admin: boolean; | ||
user: boolean; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { AuthDetails, Permissions } from "../../app/shemas"; | ||
|
||
export interface ForAuthenticating { | ||
getAuthDetails(email: string, password: string): Promise<AuthDetails>; | ||
getPermissions(email: string, password: string): Promise<Permissions>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./for-auth"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { AuthDetails, Permissions } from "../../app/shemas"; | ||
|
||
export interface ForAuthenticatingUser { | ||
getAuthDetails(email: string, password: string): Promise<AuthDetails>; | ||
getPermissions(email: string, password: string): Promise<Permissions>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./for-authenticating-user"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Esto está muy bien, si quieres puedes poner que siempre devuelva un mock sin necesidad de agregar lógica de búsqueda ya que justamente es eso, es para controlar la lógica principal en un ambiente controlado
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
La lógica en sí deberías de hacerla en el control plane ya que es parte del domain