@amityco/ts-sdk-react-native
Version:
Amity Social Cloud Typescript SDK
165 lines (124 loc) • 5.47 kB
text/typescript
import { ASCApiError } from '~/core/errors';
import { user11, disconnectClient } from '~/utils/tests';
import { resumeSession, createClient } from '..';
import { setActiveClient } from '../activeClient';
let client: Amity.Client;
const sessionHandler: Amity.SessionHandler = {
sessionWillRenewAccessToken(_) {
// do nothing
},
};
const mockToken = {
accessToken: 'mock-access-token',
issuedAt: '2023-01-01T00:00:00Z',
expiresAt: '2025-01-01T00:00:00Z',
};
const mockUserResponse = {
data: {
users: [user11],
},
};
const onConnect = () =>
describe('resumeSession', () => {
beforeEach(() => {
client = createClient('key', 'sg');
client.mqtt?.connect && (client.mqtt.connect = jest.fn());
client.mqtt?.subscribe && (client.mqtt.subscribe = jest.fn());
client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
setActiveClient(client);
});
afterEach(async () => {
if (client.sessionState === Amity.SessionStates.ESTABLISHED) await disconnectClient();
});
test('it should connect client with access token', async () => {
onConnect().unref();
const received = await resumeSession(
{ userId: user11.userId, token: mockToken },
sessionHandler,
);
expect(received).toBe(true);
});
test('it should establish connection', async () => {
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
const { sessionState } = client;
expect(sessionState).toBe(Amity.SessionStates.ESTABLISHED);
});
test('it should have session state establishing while connecting client', () => {
resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHING);
});
test('it should have session state notLoggedIn on failure', async () => {
client.http.get = jest
.fn()
.mockRejectedValue(
new ASCApiError('unauthorized', Amity.ServerError.UNAUTHORIZED, Amity.ErrorLevel.FATAL),
);
await expect(
resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler),
).rejects.toThrow('unauthorized');
expect(client.sessionState).toBe(Amity.SessionStates.NOT_LOGGED_IN);
});
test('it should set authorization header with token', async () => {
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
expect(client.http.defaults.headers.common.Authorization).toBe(
`Bearer ${mockToken.accessToken}`,
);
expect(client.upload.defaults.headers.common.Authorization).toBe(
`Bearer ${mockToken.accessToken}`,
);
});
test('it should set token metadata', async () => {
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
expect(client.token).toEqual(mockToken);
expect(client.http.defaults.metadata).toEqual({
tokenExpiry: mockToken.expiresAt,
isGlobalBanned: false,
isUserDeleted: false,
});
});
test('it should call user endpoint to validate token', async () => {
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
expect(client.http.get).toHaveBeenCalledWith(`/api/v3/users/${user11.userId}`);
});
test('it should terminate session on ban', async () => {
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
// ban user
client.emitter.emit('user.didGlobalBan', {} as Amity.UserPayload);
expect(client.sessionState).toBe(Amity.SessionStates.TERMINATED);
});
test('it should reset client state when user is already connected with same userId', async () => {
onConnect().unref();
// First connection
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
expect(client.userId).toBe(user11.userId);
// Mock the HTTP call for second connection
client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
// Second connection with same userId should treat as token expiry (preserve cache)
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
// Verify that the client is properly reset and reconnected
expect(client.sessionState).toBe(Amity.SessionStates.ESTABLISHED);
expect(client.userId).toBe(user11.userId);
});
test('it should preserve cache when resuming session with same userId', async () => {
onConnect().unref();
// First connection - set some cache data
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
if (client.cache) {
client.cache.data = { test: 'data' };
}
// Mock the HTTP call for second connection
client.http.get = jest.fn().mockResolvedValueOnce(mockUserResponse);
// Second connection with same userId
onConnect().unref();
await resumeSession({ userId: user11.userId, token: mockToken }, sessionHandler);
// Cache should be preserved when same userId is used
expect(client.cache?.data).toEqual({ test: 'data' });
});
});