diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 5452da6..c3d8aaf 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -59,9 +59,18 @@ describe('index', () => { expect(result5).toBeUndefined(); expect(requestLoginLink).toBeCalledWith(storedOptions, { loginLinkTo: 'settings' }); - mocked(exchangeToken).mockResolvedValueOnce('test'); + const token = { + access_token: 'access_token', + refresh_token: 'refresh_token', + expires_in: 3600, + token_type: 'bearer', + scope: 'guest_read', + created_at: Date.now(), + resource_server: 'jp-api' + }; + mocked(exchangeToken).mockResolvedValueOnce(token); const result6 = await instance.exchangeToken({ code: 'code' }); - expect(result6).toBe('test'); + expect(result6).toEqual(token); expect(exchangeToken).toBeCalledWith(storedOptions, { code: 'code' }); // @ts-ignore: set tokenInfo with invalid type value diff --git a/src/api/__tests__/exchange-token.test.ts b/src/api/__tests__/exchange-token.test.ts index 212795d..f9d26d2 100644 --- a/src/api/__tests__/exchange-token.test.ts +++ b/src/api/__tests__/exchange-token.test.ts @@ -11,7 +11,15 @@ describe('api', () => { const clientId = 'clientId'; const code = 'code'; const redirectUri = 'redirectUri'; - const token = 'token'; + const token = { + access_token: 'access_token', + refresh_token: 'refresh_token', + expires_in: 3600, + token_type: 'bearer', + scope: 'guest_read', + created_at: Date.now(), + resource_server: 'jp-api' + }; const state = 'state'; const mtLinkSdk = new MtLinkSdk(); @@ -48,8 +56,7 @@ describe('api', () => { test('make request', async () => { fetch.mockClear(); - - fetch.mockResponseOnce(JSON.stringify({ access_token: token })); + fetch.mockResponseOnce(JSON.stringify(token)); await exchangeToken(mtLinkSdk.storedOptions, { code, codeVerifier: '' }); @@ -94,14 +101,12 @@ describe('api', () => { test('auto extract code from url query if no code was passed', async () => { fetch.mockClear(); + fetch.mockResponseOnce(JSON.stringify(token)); - const code1 = 'code1'; - const code2 = 'code2'; - - fetch.mockResponseOnce(JSON.stringify({ access_token: token })); + const code = 'realCode'; jest.spyOn(window, 'location', 'get').mockReturnValueOnce({ - search: `?code=${code1}&code=${code2}` + search: `?code=otherCode&code=${code}` } as typeof window.location); await exchangeToken(mtLinkSdk.storedOptions, { state }); @@ -109,21 +114,20 @@ describe('api', () => { const result = fetch.mock.calls[0][1] || {}; const data = JSON.parse(result.body as string); - expect(data.code).toBe(code2); + expect(data.code).toBe(code); }); test('auto extract state from url query if no state was passed or set during init', async () => { fetch.mockClear(); - - const state1 = 'state1'; - - fetch.mockResponseOnce(JSON.stringify({ access_token: token })); + fetch.mockResponseOnce(JSON.stringify(token)); jest.spyOn(window, 'location', 'get').mockReturnValueOnce({ - search: `?state=${state1}&state=${state}` + search: `?state=otherState&state=${state}` } as typeof window.location); - await expect(exchangeToken(mtLinkSdk.storedOptions, { code, redirectUri })).resolves.toBe(token); + const actual = await exchangeToken(mtLinkSdk.storedOptions, { code, redirectUri }); + + expect(actual).toEqual(token); }); test('non browser environment will not auto extract code from url', async () => { diff --git a/src/api/exchange-token.ts b/src/api/exchange-token.ts index 19013dd..1d6852e 100644 --- a/src/api/exchange-token.ts +++ b/src/api/exchange-token.ts @@ -2,7 +2,7 @@ import qs from 'qs'; import { generateSdkHeaderInfo } from '../helper'; import { MY_ACCOUNT_DOMAINS } from '../server-paths'; -import { StoredOptions, ExchangeTokenOptions } from '../typings'; +import { StoredOptions, ExchangeTokenOptions, Token } from '../typings'; import storage from '../storage'; function getCode(): string | undefined { @@ -21,7 +21,7 @@ function getCode(): string | undefined { export default async function exchangeToken( storedOptions: StoredOptions, options: ExchangeTokenOptions = {} -): Promise { +): Promise { const { clientId, redirectUri: defaultRedirectUri, mode } = storedOptions; if (!clientId) { @@ -64,7 +64,7 @@ export default async function exchangeToken( throw new Error(result.error_description); } - return result.access_token; + return result as Token; } catch (error) { throw new Error(`[mt-link-sdk] \`exchangeToken\` execution failed. ${error}`); } diff --git a/src/index.ts b/src/index.ts index 8259366..6c9d27a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ import requestLoginLink from './api/request-login-link'; import exchangeToken from './api/exchange-token'; import tokenInfo from './api/token-info'; import { + Token, StoredOptions, ServiceId, LogoutOptions, @@ -141,7 +142,7 @@ export class MtLinkSdk { return requestLoginLink(this.storedOptions, options); } - public exchangeToken(options?: ExchangeTokenOptions): Promise { + public exchangeToken(options?: ExchangeTokenOptions): Promise { return exchangeToken(this.storedOptions, options); } diff --git a/src/typings.ts b/src/typings.ts index dcd23bc..3cda954 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -170,3 +170,13 @@ export interface TokenInfo { lang: string; }; } + +export interface Token { + access_token: string; + refresh_token: string; + token_type: string; + created_at: number; + expires_in: number; + scope: string; + resource_server: string; +}