feat: access token generic para permitir customização

This commit is contained in:
Leandro Costa 2023-06-16 19:06:50 -03:00
parent 477d9fc6a7
commit 71e18bc997

View file

@ -1,9 +1,9 @@
import axios from 'axios'; import axios from "axios";
import { LhispOauthClient } from "../src/lhisp-oauth-client"; import { LhispOauthClient } from "../src/lhisp-oauth-client";
import { ContentType, LhispOauthClientConstructorParams } from '../src/lhisp-oauth-client.t'; import { ContentType, LhispOauthClientConstructorParams } from "../src/lhisp-oauth-client.t";
// Mock jest and set the type // Mock jest and set the type
jest.mock('axios'); jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>; const mockedAxios = axios as jest.Mocked<typeof axios>;
const apiUrl = "https://myapi.com"; const apiUrl = "https://myapi.com";
@ -11,206 +11,226 @@ const authUrl = "https://auth.myapi.com/oauth/token";
const clientId = "testClientdId"; const clientId = "testClientdId";
const clientSecret = "testClientSecret"; const clientSecret = "testClientSecret";
const baseClientParams = { apiUrl, authUrl, clientId, clientSecret }; const baseClientParams = { apiUrl, authUrl, clientId, clientSecret };
const basicAuth = `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`; const basicAuth = `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`;
const contentTypeApplicationJson = "application/json"; const contentTypeApplicationJson = "application/json";
const contentTypeApplicationXFormUrlEncoded = "application/x-www-form-urlencoded"; const contentTypeApplicationXFormUrlEncoded = "application/x-www-form-urlencoded";
const defaultGrantValue='client_credentials'; const defaultGrantValue = "client_credentials";
const defaultGrantType=`{"grant_type":"${defaultGrantValue}"}`; const defaultGrantType = `{"grant_type":"${defaultGrantValue}"}`;
describe("Get Access Token", ()=>{ describe("Get Access Token", () => {
beforeEach(() => { beforeEach(() => {
mockedAxios.request.mockReset(); mockedAxios.request.mockReset();
mockedAxios.request.mockResolvedValueOnce({ data: mockedAccessToken }); mockedAxios.request.mockResolvedValueOnce({ data: mockedAccessToken });
}); });
it("Shoud Get with Standard Config", async ()=>{ it("Shoud Get with Standard Config", async () => {
const cli = getOauthClient(); const cli = getOauthClient();
await accessTokenValidator(cli); await accessTokenValidator(cli);
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
}); });
it("Shoud Get with Custom Auth Header", async ()=>{ it("Shoud Get with Custom Auth Header", async () => {
const cli = getOauthClient({ const cli = getOauthClient({
...baseClientParams, ...baseClientParams,
authHeaderName: 'CustomAuthorizationHeader', authHeaderName: "CustomAuthorizationHeader",
}); });
await accessTokenValidator(cli); await accessTokenValidator(cli);
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: authUrl, url: authUrl,
method: "POST", method: "POST",
headers: { headers: {
CustomAuthorizationHeader: basicAuth, CustomAuthorizationHeader: basicAuth,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: defaultGrantType, data: defaultGrantType,
})); })
);
}); });
it("Shoud Get with Custom Grant Type", async ()=>{ it("Shoud Get with Custom Grant Type", async () => {
const cli = getOauthClient({ const cli = getOauthClient({
...baseClientParams, ...baseClientParams,
grantType: 'PermissaoCustom', grantType: "PermissaoCustom",
}); });
await accessTokenValidator(cli); await accessTokenValidator(cli);
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: authUrl, url: authUrl,
method: "POST", method: "POST",
headers: { headers: {
Authorization: basicAuth, Authorization: basicAuth,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: '{"grant_type":"PermissaoCustom"}', data: '{"grant_type":"PermissaoCustom"}',
})); })
);
}); });
it("Shoud Get with Custom Auth Scope", async ()=>{ it("Shoud Get with Custom Auth Scope", async () => {
const cli = getOauthClient({ const cli = getOauthClient({
...baseClientParams, ...baseClientParams,
authScope: 'EscopoCustom', authScope: "EscopoCustom",
}); });
await accessTokenValidator(cli); await accessTokenValidator(cli);
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: authUrl, url: authUrl,
method: "POST", method: "POST",
headers: { headers: {
Authorization: basicAuth, Authorization: basicAuth,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: `{"grant_type":"${defaultGrantValue}","scope":"EscopoCustom"}`, data: `{"grant_type":"${defaultGrantValue}","scope":"EscopoCustom"}`,
})); })
);
}); });
it("Shoud Get with Credentials on Request body", async ()=>{ it("Shoud Get with Credentials on Request body", async () => {
const cli = getOauthClient({ const cli = getOauthClient({
...baseClientParams, ...baseClientParams,
sendAuthCredentialsOnRequestBody: true, sendAuthCredentialsOnRequestBody: true,
}); });
await accessTokenValidator(cli); await accessTokenValidator(cli);
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: authUrl, url: authUrl,
method: "POST", method: "POST",
headers: { headers: {
Authorization: basicAuth, Authorization: basicAuth,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: `{"grant_type":"${defaultGrantValue}","client_id":"${clientId}","client_secret":"${clientSecret}"}`, data: `{"grant_type":"${defaultGrantValue}","client_id":"${clientId}","client_secret":"${clientSecret}"}`,
})); })
);
}); });
}); });
describe("Request", ()=>{ describe("Request", () => {
beforeEach(() => { beforeEach(() => {
mockedAxios.request.mockReset(); mockedAxios.request.mockReset();
mockedAxios.request.mockResolvedValueOnce({ data: mockedAccessToken }); mockedAxios.request.mockResolvedValueOnce({ data: mockedAccessToken });
mockedAxios.request.mockResolvedValueOnce({ data: {"status": "ok"} }); mockedAxios.request.mockResolvedValueOnce({ data: { status: "ok" } });
}); });
it("Get without Params", async ()=>{ it("Get without Params", async () => {
const cli = getOauthClient(); const cli = getOauthClient();
const resp = await cli.get({ path: '/my-test-url' }); const resp = await cli.get({ path: "/my-test-url" });
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: `${apiUrl}/my-test-url`, url: `${apiUrl}/my-test-url`,
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer SomeAccessToken`, Authorization: `Bearer SomeAccessToken`,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: undefined data: undefined,
})); })
expect(resp).toStrictEqual({"status": "ok"}); );
expect(resp).toStrictEqual({ status: "ok" });
}); });
it("Get with Params", async ()=>{ it("Get with Params", async () => {
const cli = getOauthClient(); const cli = getOauthClient();
const resp = await cli.get({ path: '/my-test-url', params: { id: 1 } }); const resp = await cli.get({ path: "/my-test-url", params: { id: 1 } });
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: `${apiUrl}/my-test-url`, url: `${apiUrl}/my-test-url`,
method: "GET", method: "GET",
headers: { headers: {
Authorization: `Bearer SomeAccessToken`, Authorization: `Bearer SomeAccessToken`,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
params: { id: 1 }, params: { id: 1 },
data: undefined data: undefined,
})); })
expect(resp).toStrictEqual({"status": "ok"}); );
expect(resp).toStrictEqual({ status: "ok" });
}); });
it("Post", async ()=>{ it("Post", async () => {
const cli = getOauthClient(); const cli = getOauthClient();
const resp = await cli.post({ path: '/my-test-url-post', data: { id: 1, user: 'test' } }); const resp = await cli.post({ path: "/my-test-url-post", data: { id: 1, user: "test" } });
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: `${apiUrl}/my-test-url-post`, url: `${apiUrl}/my-test-url-post`,
method: "POST", method: "POST",
headers: { headers: {
Authorization: `Bearer SomeAccessToken`, Authorization: `Bearer SomeAccessToken`,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: { id: 1, user: 'test' } data: { id: 1, user: "test" },
})); })
expect(resp).toStrictEqual({"status": "ok"}); );
expect(resp).toStrictEqual({ status: "ok" });
}); });
it("Post with different contentType", async ()=>{ it("Post with different contentType", async () => {
const cli = getOauthClient(); const cli = getOauthClient();
const resp = await cli.post({ const resp = await cli.post({
path: '/my-test-url-post', path: "/my-test-url-post",
data: { id: 1, user: 'test' }, data: { id: 1, user: "test" },
contentType: ContentType.APPLICATION_X_WWW_FORM_URLENCODED contentType: ContentType.APPLICATION_X_WWW_FORM_URLENCODED,
}); });
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: `${apiUrl}/my-test-url-post`, url: `${apiUrl}/my-test-url-post`,
method: "POST", method: "POST",
headers: { headers: {
Authorization: `Bearer SomeAccessToken`, Authorization: `Bearer SomeAccessToken`,
'Content-Type': contentTypeApplicationXFormUrlEncoded, "Content-Type": contentTypeApplicationXFormUrlEncoded,
}, },
data: { id: 1, user: 'test' } data: { id: 1, user: "test" },
})); })
expect(resp).toStrictEqual({"status": "ok"}); );
expect(resp).toStrictEqual({ status: "ok" });
}); });
it("Post with Different Token Header Name", async ()=>{ it("Post with Different Token Header Name", async () => {
const cli = getOauthClient({ const cli = getOauthClient({
...baseClientParams, ...baseClientParams,
tokenHeaderName: "x-token", tokenHeaderName: "x-token",
}); });
const resp = await cli.post({ const resp = await cli.post({
path: '/my-test-url-post', path: "/my-test-url-post",
data: { id: 1, user: 'test' }, data: { id: 1, user: "test" },
contentType: ContentType.APPLICATION_X_WWW_FORM_URLENCODED contentType: ContentType.APPLICATION_X_WWW_FORM_URLENCODED,
}); });
validateDefaultGetAccessToken(); validateDefaultGetAccessToken();
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: `${apiUrl}/my-test-url-post`, url: `${apiUrl}/my-test-url-post`,
method: "POST", method: "POST",
headers: { headers: {
'x-token': `Bearer SomeAccessToken`, "x-token": `Bearer SomeAccessToken`,
'Content-Type': contentTypeApplicationXFormUrlEncoded, "Content-Type": contentTypeApplicationXFormUrlEncoded,
}, },
data: { id: 1, user: 'test' } data: { id: 1, user: "test" },
})); })
expect(resp).toStrictEqual({"status": "ok"}); );
expect(resp).toStrictEqual({ status: "ok" });
}); });
}); });
function validateDefaultGetAccessToken(){ function validateDefaultGetAccessToken() {
expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({ expect(mockedAxios.request).toBeCalledWith(
expect.objectContaining({
url: authUrl, url: authUrl,
method: "POST", method: "POST",
headers: { headers: {
Authorization: basicAuth, Authorization: basicAuth,
'Content-Type': contentTypeApplicationJson, "Content-Type": contentTypeApplicationJson,
}, },
data: defaultGrantType, data: defaultGrantType,
})); })
);
} }
async function accessTokenValidator(cli: LhispOauthClient){ async function accessTokenValidator(cli: LhispOauthClient) {
const now = Date.now(); const now = Date.now();
const accessToken = await cli.getAccessToken(); const accessToken = await cli.getAccessToken();
expect(accessToken).toBeDefined(); expect(accessToken).toBeDefined();
@ -218,10 +238,9 @@ async function accessTokenValidator(cli: LhispOauthClient){
expect(accessToken.access_token).toBe(mockedAccessToken.access_token); expect(accessToken.access_token).toBe(mockedAccessToken.access_token);
expect(accessToken.expires_in).toBe(mockedAccessToken.expires_in); expect(accessToken.expires_in).toBe(mockedAccessToken.expires_in);
expect(accessToken.scope).toBe(mockedAccessToken.scope); expect(accessToken.scope).toBe(mockedAccessToken.scope);
expect(accessToken.created_at).toBeGreaterThanOrEqual(now);
} }
function getOauthClient(opt:LhispOauthClientConstructorParams=baseClientParams){ function getOauthClient(opt: LhispOauthClientConstructorParams = baseClientParams) {
return new LhispOauthClient(opt); return new LhispOauthClient(opt);
} }
@ -230,4 +249,4 @@ const mockedAccessToken = {
access_token: "SomeAccessToken", access_token: "SomeAccessToken",
expires_in: 600, expires_in: 600,
scope: "cobrancas.boletos-requisicao cobrancas.boletos-info", scope: "cobrancas.boletos-requisicao cobrancas.boletos-info",
} };