mirror of
https://github.com/logto-io/logto.git
synced 2025-01-06 20:40:08 -05:00
156 lines
5 KiB
TypeScript
156 lines
5 KiB
TypeScript
|
import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit';
|
||
|
import nock from 'nock';
|
||
|
|
||
|
import { accessTokenEndpoint, authorizationEndpoint, userInfoEndpoint } from './constant.js';
|
||
|
import createConnector, { getAccessToken } from './index.js';
|
||
|
import { mockedConfig } from './mock.js';
|
||
|
|
||
|
const { jest } = import.meta;
|
||
|
|
||
|
const getConfig = jest.fn().mockResolvedValue(mockedConfig);
|
||
|
|
||
|
describe('kakao connector', () => {
|
||
|
describe('getAuthorizationUri', () => {
|
||
|
afterEach(() => {
|
||
|
jest.clearAllMocks();
|
||
|
});
|
||
|
|
||
|
it('should get a valid authorizationUri with redirectUri and state', async () => {
|
||
|
const connector = await createConnector({ getConfig });
|
||
|
const authorizationUri = await connector.getAuthorizationUri(
|
||
|
{
|
||
|
state: 'some_state',
|
||
|
redirectUri: 'http://localhost:3000/callback',
|
||
|
connectorId: 'some_connector_id',
|
||
|
connectorFactoryId: 'some_connector_factory_id',
|
||
|
jti: 'some_jti',
|
||
|
headers: {},
|
||
|
},
|
||
|
jest.fn()
|
||
|
);
|
||
|
expect(authorizationUri).toEqual(
|
||
|
`${authorizationEndpoint}?client_id=%3Cclient-id%3E&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&response_type=code&state=some_state`
|
||
|
);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('getAccessToken', () => {
|
||
|
afterEach(() => {
|
||
|
nock.cleanAll();
|
||
|
jest.clearAllMocks();
|
||
|
});
|
||
|
|
||
|
it('should get an accessToken by exchanging with code', async () => {
|
||
|
nock(accessTokenEndpoint).post('').reply(200, {
|
||
|
access_token: 'access_token',
|
||
|
scope: 'scope',
|
||
|
token_type: 'token_type',
|
||
|
});
|
||
|
const { accessToken } = await getAccessToken(mockedConfig, {
|
||
|
code: 'code',
|
||
|
redirectUri: 'dummyRedirectUri',
|
||
|
});
|
||
|
expect(accessToken).toEqual('access_token');
|
||
|
});
|
||
|
|
||
|
it('throws SocialAuthCodeInvalid error if accessToken not found in response', async () => {
|
||
|
nock(accessTokenEndpoint)
|
||
|
.post('')
|
||
|
.reply(200, { access_token: '', scope: 'scope', token_type: 'token_type' });
|
||
|
await expect(
|
||
|
getAccessToken(mockedConfig, { code: 'code', redirectUri: 'dummyRedirectUri' })
|
||
|
).rejects.toMatchError(new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid));
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('getUserInfo', () => {
|
||
|
beforeEach(() => {
|
||
|
nock(accessTokenEndpoint).post('').reply(200, {
|
||
|
access_token: 'access_token',
|
||
|
scope: 'scope',
|
||
|
token_type: 'token_type',
|
||
|
});
|
||
|
});
|
||
|
|
||
|
afterEach(() => {
|
||
|
nock.cleanAll();
|
||
|
jest.clearAllMocks();
|
||
|
});
|
||
|
|
||
|
it('should get valid SocialUserInfo', async () => {
|
||
|
nock(userInfoEndpoint)
|
||
|
.post('')
|
||
|
.reply(200, {
|
||
|
id: 1_234_567_890,
|
||
|
kakao_account: {
|
||
|
is_email_valid: true,
|
||
|
email: 'ruddbs5302@gmail.com',
|
||
|
profile: {
|
||
|
nickname: 'pemassi',
|
||
|
profile_image_url: 'https://github.com/images/error/octocat_happy.gif',
|
||
|
is_default_image: false,
|
||
|
},
|
||
|
},
|
||
|
});
|
||
|
const connector = await createConnector({ getConfig });
|
||
|
const socialUserInfo = await connector.getUserInfo(
|
||
|
{
|
||
|
code: 'code',
|
||
|
redirectUri: 'redirectUri',
|
||
|
},
|
||
|
jest.fn()
|
||
|
);
|
||
|
expect(socialUserInfo).toMatchObject({
|
||
|
id: '1234567890',
|
||
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||
|
name: 'pemassi',
|
||
|
email: 'ruddbs5302@gmail.com',
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('throws SocialAccessTokenInvalid error if remote response code is 401', async () => {
|
||
|
nock(userInfoEndpoint).post('').reply(401);
|
||
|
const connector = await createConnector({ getConfig });
|
||
|
await expect(
|
||
|
connector.getUserInfo({ code: 'code', redirectUri: '' }, jest.fn())
|
||
|
).rejects.toMatchError(new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid));
|
||
|
});
|
||
|
|
||
|
it('throws General error', async () => {
|
||
|
nock(userInfoEndpoint).post('').reply(200, {
|
||
|
sub: '1234567890',
|
||
|
name: 'monalisa octocat',
|
||
|
given_name: 'monalisa',
|
||
|
family_name: 'octocat',
|
||
|
picture: 'https://github.com/images/error/octocat_happy.gif',
|
||
|
email: 'octocat@google.com',
|
||
|
email_verified: true,
|
||
|
locale: 'en',
|
||
|
});
|
||
|
const connector = await createConnector({ getConfig });
|
||
|
await expect(
|
||
|
connector.getUserInfo(
|
||
|
{
|
||
|
error: 'general_error',
|
||
|
error_description: 'General error encountered.',
|
||
|
},
|
||
|
jest.fn()
|
||
|
)
|
||
|
).rejects.toMatchError(
|
||
|
new ConnectorError(
|
||
|
ConnectorErrorCodes.General,
|
||
|
'{"error":"general_error","error_description":"General error encountered."}'
|
||
|
)
|
||
|
);
|
||
|
});
|
||
|
|
||
|
it('throws unrecognized error', async () => {
|
||
|
nock(userInfoEndpoint).post('').reply(500);
|
||
|
const connector = await createConnector({ getConfig });
|
||
|
await expect(
|
||
|
connector.getUserInfo({ code: 'code', redirectUri: '' }, jest.fn())
|
||
|
).rejects.toThrow();
|
||
|
});
|
||
|
});
|
||
|
});
|