import { checkTokenExpired } from "../handler" const mockApiGetToken = async () => { return Promise.resolve({ data: { data: { access_token: "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzo4ZDA1NjJmNS0zMjI0LTQ1OGYtODBkZS01YjczNTdkMWUwMjIiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOltdLCJjbGllbnRfaWQiOiI4MzE5ZGQ4NS03YjU3LTQ0NTUtYThkYy01ZmIxZDE0MmE0MDAiLCJleHAiOjE2NjIzNTk5NDEsImV4dCI6eyJlY29zeXN0ZW1faWQiOiI2MmZjNTcyNC0zNzUxLTQ3OTctYmU3OS02MDU2MzVmYTZjOTMifSwiaWF0IjoxNjYxNzU1MTQxLCJpc3MiOiJodHRwczovL2Rldi1vaWRjLWNvcmUuY3JlZGlmeS5uaW5qYS8iLCJqdGkiOiJkZDI2MDA0My04NjQ4LTQ0YTUtOTZkMC0xMzQ0Y2YzNDhiOWYiLCJuYmYiOjE2NjE3NTUxNDEsInNjcCI6WyJvcmdhbml6YXRpb24iLCJjbGFpbV9wcm92aWRlciIsImlkcGFzc19wcm92aWRlciJdLCJzdWIiOiI4MzE5ZGQ4NS03YjU3LTQ0NTUtYThkYy01ZmIxZDE0MmE0MDAifQ.Tm3qtltNVWi-TVwEbX8i5T_ZQ2qTsVcAOOCEc0JD2PdJd0VwhIPwYs4tZQV62pfRUvqe7Jq-Tui89zj-ms6H8qVfV0CJ1iN8PAhh6JPOwWmcxJcCa_29AgNfW1SO3D-xE7Wq5Nn47pp1vtpe1JiaYWNnfbKT0wuLHCtuR3KNIYXrIIqwoZ4fxniSyb3FxRZlzSixjpJjgbu7VURk4yCof9uzUpM884vH8AxpNUy-JLynp9S9X5-pUyw2unVCW1iBAtlmIlCX3p9fAhAELiCABIZC7tL992x38RhhPEhFuonfZfRp0e0zGRZehQSicscV1mkRmHDbK_pcs4dg2Q78lPB4qQ8P1eh8zSoOmA3rUAWmKWT7Fm38EuABVH682UwhO156WpI9OGmICE0LuAP3NceuL0jTz8R3IFTbwo1puQZ-MHVBzKblJIXpX4mE1YshGBJkKasqMv8UwjO00jLLNdyQGE6RgvcgsAaD6JO3IOBMvow6psX2GO1wwcsGEpg1m6dfqbkYsfsP4CjCybL49hZjUZFcaT7mxlDjhccMXwGWv2Ky0Ggo6ab2clcrUX6u-jiP1Js75NDjppf44_LY-_YMXJXBJ6MrDxYpjK9b_yOwXl75O5QLEJcLLFJgZ2RGB8Tc6p1G4wuHhLBug8xkw07vPUnA4yqkhhMVWNizv6w", }, }, }) } class Credify { private static _instance: { [apiKey: string]: Credify } = {} accessToken: string static countCall = 0 /** * Instantiates Credify object * @param accessToken * */ constructor(accessToken: string) { this.accessToken = accessToken } static async getInstance(apiKey: string) { if ( Object.prototype.hasOwnProperty.call(this._instance, apiKey) && !checkTokenExpired(this._instance[apiKey].accessToken) ) { return this._instance[apiKey] } this.countCall++ const res = await mockApiGetToken() const accessToken = res?.data?.data?.access_token || "" this._instance[apiKey] = new Credify(accessToken) return this._instance[apiKey] } static reset() { this.countCall = 0 this._instance = {} } } // Integration test here to make sure no thing goes wrong with our SDK in a real integrated system and just need to test some happy cases only cause other cases is well tested with our unit tests const mockApiKey = "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzo4ZDA1NjJmNS0zMjI0LTQ1OGYtODBkZS01YjczNTdkMWUwMjIiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOltdLCJjbGllbnRfaWQiOiI4MzE5ZGQ4NS03YjU3LTQ0NTUtYThkYy01ZmIxZDE0MmE0MDAiLCJleHAiOjE2NjIzNTk5NDEsImV4dCI6eyJlY29zeXN0ZW1faWQiOiI2MmZjNTcyNC0zNzUxLTQ3OTctYmU3OS02MDU2MzVmYTZjOTMifSwiaWF0IjoxNjYxNzU1MTQxLCJpc3MiOiJodHRwczovL2Rldi1vaWRjLWNvcmUuY3JlZGlmeS5uaW5qYS8iLCJqdGkiOiJkZDI2MDA0My04NjQ4LTQ0YTUtOTZkMC0xMzQ0Y2YzNDhiOWYiLCJuYmYiOjE2NjE3NTUxNDEsInNjcCI6WyJvcmdhbml6YXRpb24iLCJjbGFpbV9wcm92aWRlciIsImlkcGFzc19wcm92aWRlciJdLCJzdWIiOiI4MzE5ZGQ4NS03YjU3LTQ0NTUtYThkYy01ZmIxZDE0MmE0MDAifQ.Tm3qtltNVWi-TVwEbX8i5T_ZQ2qTsVcAOOCEc0JD2PdJd0VwhIPwYs4tZQV62pfRUvqe7Jq-Tui89zj-ms6H8qVfV0CJ1iN8PAhh6JPOwWmcxJcCa_29AgNfW1SO3D-xE7Wq5Nn47pp1vtpe1JiaYWNnfbKT0wuLHCtuR3KNIYXrIIqwoZ4fxniSyb3FxRZlzSixjpJjgbu7VURk4yCof9uzUpM884vH8AxpNUy-JLynp9S9X5-pUyw2unVCW1iBAtlmIlCX3p9fAhAELiCABIZC7tL992x38RhhPEhFuonfZfRp0e0zGRZehQSicscV1mkRmHDbK_pcs4dg2Q78lPB4qQ8P1eh8zSoOmA3rUAWmKWT7Fm38EuABVH682UwhO156WpI9OGmICE0LuAP3NceuL0jTz8R3IFTbwo1puQZ-MHVBzKblJIXpX4mE1YshGBJkKasqMv8UwjO00jLLNdyQGE6RgvcgsAaD6JO3IOBMvow6psX2GO1wwcsGEpg1m6dfqbkYsfsP4CjCybL49hZjUZFcaT7mxlDjhccMXwGWv2Ky0Ggo6ab2clcrUX6u-jiP1Js75NDjppf44_LY-_YMXJXBJ6MrDxYpjK9b_yOwXl75O5QLEJcLLFJgZ2RGB8Tc6p1G4wuHhLBug8xkw07vPUnA4yqkhhMVWNizv6w" describe("Credify", () => { const expireTimeFromToken = 1662359941 beforeEach(() => { Credify.reset() }) test("Create new instance", async () => { const credifyInstance = await Credify.getInstance(mockApiKey) expect(Credify.countCall).toEqual(1) expect(credifyInstance).toBeTruthy() }) test("Create instance 2 times, same api key, token is not expired", async () => { const credifyInstance = await Credify.getInstance(mockApiKey) // Mock current time = expireTimeFromToken -> is not expired jest.useFakeTimers("modern") // tell Jest to use a different timer implementation. const currentTime = new Date(expireTimeFromToken * 1000) jest.setSystemTime(currentTime.getTime()) const credifyInstance1 = await Credify.getInstance(mockApiKey) expect(Credify.countCall).toEqual(1) expect(credifyInstance).toBeTruthy() expect(credifyInstance1).toBeTruthy() expect(credifyInstance === credifyInstance1).toEqual(true) }) test("Create instance 2 times, different api key, token is not expired", async () => { const credifyInstance = await Credify.getInstance(mockApiKey) // Mock current time = expireTimeFromToken -> is not expired jest.useFakeTimers("modern") // tell Jest to use a different timer implementation. const currentTime = new Date(expireTimeFromToken * 1000) jest.setSystemTime(currentTime.getTime()) const credifyInstance1 = await Credify.getInstance(`${mockApiKey}z`) expect(Credify.countCall).toEqual(2) expect(credifyInstance).toBeTruthy() expect(credifyInstance1).toBeTruthy() expect(credifyInstance !== credifyInstance1).toEqual(true) }) test("Create instance 2 times, same api key, token is expired", async () => { const credifyInstance = await Credify.getInstance(mockApiKey) // Mock current time = expireTimeFromToken - 59 seconds -> is expired jest.useFakeTimers("modern") // tell Jest to use a different timer implementation. const currentTime = new Date((expireTimeFromToken - 59) * 1000) jest.setSystemTime(currentTime.getTime()) const credifyInstance1 = await Credify.getInstance(mockApiKey) expect(Credify.countCall).toEqual(2) expect(credifyInstance).toBeTruthy() expect(credifyInstance1).toBeTruthy() expect(credifyInstance !== credifyInstance1).toEqual(true) }) })