355 lines
11 KiB
TypeScript
355 lines
11 KiB
TypeScript
import { sessionService } from '../../app/services';
|
|
import Session from '../../app/types/session';
|
|
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
|
|
import SessionStore from '../../app/mstore/sessionStore';
|
|
import { searchStore } from '../../app/mstore/index';
|
|
import { checkEventWithFilters } from '../../app/components/Session_/Player/Controls/checkEventWithFilters';
|
|
import { mockSession } from '../mocks/sessionData';
|
|
|
|
jest.mock('../../app/player', () => ({
|
|
createWebPlayer: jest.fn(),
|
|
createIOSPlayer: jest.fn(),
|
|
createClickMapPlayer: jest.fn(),
|
|
createLiveWebPlayer: jest.fn(),
|
|
createClipPlayer: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('../../app/services', () => ({
|
|
sessionService: {
|
|
getSessions: jest.fn(),
|
|
getLiveSessions: jest.fn(),
|
|
getSessionInfo: jest.fn(),
|
|
getSessionEvents: jest.fn(),
|
|
getSessionNotes: jest.fn(),
|
|
getFavoriteSessions: jest.fn(),
|
|
getSessionClickMap: jest.fn(),
|
|
toggleFavorite: jest.fn(),
|
|
getClickMap: jest.fn(),
|
|
getAutoplayList: jest.fn(),
|
|
getFirstMobUrl: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
jest.mock('App/player/web/network/loadFiles', () => ({
|
|
loadFile: jest.fn(),
|
|
}));
|
|
|
|
jest.mock(
|
|
'@/components/Session_/Player/Controls/checkEventWithFilters',
|
|
() => ({
|
|
checkEventWithFilters: jest.fn(),
|
|
}),
|
|
);
|
|
|
|
jest.mock('../../app/mstore/index', () => ({
|
|
searchStore: {
|
|
instance: {
|
|
filters: [],
|
|
events: [],
|
|
toSearch: jest.fn().mockReturnValue({}),
|
|
},
|
|
},
|
|
searchStoreLive: {
|
|
instance: {
|
|
filters: [],
|
|
events: [],
|
|
},
|
|
},
|
|
}));
|
|
|
|
describe('SessionStore', () => {
|
|
let sessionStore: SessionStore;
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
sessionStore = new SessionStore();
|
|
});
|
|
|
|
describe('resetUserFilter', () => {
|
|
it('should reset user filter', () => {
|
|
sessionStore.userFilter.update('page', 5);
|
|
expect(sessionStore.userFilter.page).toBe(5);
|
|
|
|
sessionStore.resetUserFilter();
|
|
expect(sessionStore.userFilter.page).toBe(1);
|
|
});
|
|
});
|
|
|
|
describe('fetchLiveSessions', () => {
|
|
it('should fetch and set live sessions', async () => {
|
|
const mockResponse = {
|
|
sessions: [{ sessionId: 'live-1', userId: 'user1' }],
|
|
total: 1,
|
|
};
|
|
|
|
(sessionService.getLiveSessions as jest.Mock).mockResolvedValue(
|
|
mockResponse,
|
|
);
|
|
|
|
await sessionStore.fetchLiveSessions({ sort: 'timestamp' });
|
|
|
|
expect(sessionService.getLiveSessions).toHaveBeenCalledWith({
|
|
sort: 'timestamp',
|
|
});
|
|
expect(sessionStore.liveSessions.length).toBe(1);
|
|
expect(sessionStore.liveSessions[0].sessionId).toBe('live-1');
|
|
expect(sessionStore.liveSessions[0].live).toBe(true);
|
|
expect(sessionStore.totalLiveSessions).toBe(1);
|
|
expect(sessionStore.loadingLiveSessions).toBe(false);
|
|
});
|
|
|
|
it('should handle duration sort by converting to timestamp', async () => {
|
|
(sessionService.getLiveSessions as jest.Mock).mockResolvedValue({
|
|
sessions: [],
|
|
total: 0,
|
|
});
|
|
|
|
await sessionStore.fetchLiveSessions({ sort: 'duration', order: 'asc' });
|
|
|
|
expect(sessionService.getLiveSessions).toHaveBeenCalledWith({
|
|
sort: 'timestamp',
|
|
order: 'desc',
|
|
});
|
|
});
|
|
|
|
it('should handle errors and set loading to false', async () => {
|
|
const mockError = new Error('API error');
|
|
console.error = jest.fn();
|
|
|
|
(sessionService.getLiveSessions as jest.Mock).mockRejectedValue(
|
|
mockError,
|
|
);
|
|
|
|
await sessionStore.fetchLiveSessions();
|
|
|
|
expect(console.error).toHaveBeenCalledWith(mockError);
|
|
expect(sessionStore.loadingLiveSessions).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('fetchSessions', () => {
|
|
it('should fetch and set sessions', async () => {
|
|
const mockResponse = {
|
|
sessions: [
|
|
new Session(mockSession({ sessionId: '1', favorite: true })),
|
|
new Session(mockSession({ sessionId: '2' })),
|
|
],
|
|
total: 2,
|
|
};
|
|
|
|
(sessionService.getSessions as jest.Mock).mockResolvedValue(mockResponse);
|
|
|
|
await sessionStore.fetchSessions({ page: 1, filters: [] }, true);
|
|
|
|
expect(sessionService.getSessions).toHaveBeenCalledWith({
|
|
page: 1,
|
|
filters: [],
|
|
});
|
|
expect(sessionStore.list.length).toBe(2);
|
|
expect(sessionStore.total).toBe(2);
|
|
expect(sessionStore.sessionIds).toEqual(['1', '2']);
|
|
expect(sessionStore.favoriteList.length).toBe(1);
|
|
expect(sessionStore.favoriteList[0].sessionId).toBe('1');
|
|
expect(sessionStore.loadingSessions).toBe(false);
|
|
});
|
|
|
|
it('should handle errors and set loading to false', async () => {
|
|
const mockError = new Error('API error');
|
|
console.error = jest.fn();
|
|
|
|
(sessionService.getSessions as jest.Mock).mockRejectedValue(mockError);
|
|
|
|
await sessionStore.fetchSessions({ filters: [] }, true);
|
|
|
|
expect(console.error).toHaveBeenCalledWith(mockError);
|
|
expect(sessionStore.loadingSessions).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('clearAll', () => {
|
|
it('should clear session list and current session', () => {
|
|
sessionStore.list = [new Session({ sessionId: 'test' })];
|
|
sessionStore.current = new Session({ sessionId: 'current' });
|
|
|
|
sessionStore.clearAll();
|
|
|
|
expect(sessionStore.list).toEqual([]);
|
|
expect(sessionStore.current.sessionId).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('fetchSessionData', () => {
|
|
it('should fetch and set session data with events', async () => {
|
|
const mockSessionId = 'test-session-id';
|
|
const mockSessionInfo = { sessionId: mockSessionId, userId: 'user1' };
|
|
const mockEventsData = {
|
|
events: [
|
|
{ type: 'LOCATION', url: 'https://example.com', time: 100 },
|
|
{ type: 'CLICK', value: 'button', time: 200 },
|
|
],
|
|
errors: [],
|
|
crashes: [],
|
|
issues: [],
|
|
resources: [],
|
|
stackEvents: [],
|
|
userEvents: [],
|
|
userTesting: [],
|
|
};
|
|
|
|
(sessionService.getSessionInfo as jest.Mock).mockResolvedValue(
|
|
mockSessionInfo,
|
|
);
|
|
(sessionService.getSessionEvents as jest.Mock).mockResolvedValue(
|
|
mockEventsData,
|
|
);
|
|
(checkEventWithFilters as jest.Mock).mockReturnValue(false);
|
|
|
|
await sessionStore.fetchSessionData(mockSessionId);
|
|
|
|
expect(sessionService.getSessionInfo).toHaveBeenCalledWith(
|
|
mockSessionId,
|
|
false,
|
|
);
|
|
expect(sessionService.getSessionEvents).toHaveBeenCalledWith(
|
|
mockSessionId,
|
|
);
|
|
expect(sessionStore.current.sessionId).toBe(mockSessionId);
|
|
expect(sessionStore.visitedEvents.length).toBe(1);
|
|
expect(sessionStore.visitedEvents[0].url).toBe('https://example.com');
|
|
expect(sessionStore.host).toBe('');
|
|
expect(sessionStore.prefetched).toBe(false);
|
|
});
|
|
|
|
it('should handle event filtering based on search filters', async () => {
|
|
const mockSessionId = 'test-session-id';
|
|
const mockSessionInfo = { sessionId: mockSessionId, userId: 'user1' };
|
|
const mockEventsData = {
|
|
events: [
|
|
{ type: 'LOCATION', url: 'https://example.com', time: 100 },
|
|
{ type: 'CLICK', value: 'button', time: 200 },
|
|
],
|
|
};
|
|
|
|
// Setup search filters
|
|
(searchStore.instance.events as any) = [
|
|
{ key: 'LOCATION', operator: 'is', value: 'https://example.com' },
|
|
];
|
|
|
|
(sessionService.getSessionInfo as jest.Mock).mockResolvedValue(
|
|
mockSessionInfo,
|
|
);
|
|
(sessionService.getSessionEvents as jest.Mock).mockResolvedValue(
|
|
mockEventsData,
|
|
);
|
|
(checkEventWithFilters as jest.Mock).mockReturnValue(true);
|
|
|
|
await sessionStore.fetchSessionData(mockSessionId);
|
|
|
|
expect(sessionStore.eventsIndex).toEqual([0]);
|
|
});
|
|
|
|
it('should handle different filter operators', async () => {
|
|
const mockSessionId = 'test-session-id';
|
|
const mockSessionInfo = { sessionId: mockSessionId, userId: 'user1' };
|
|
const mockEventsData = {
|
|
events: [
|
|
{ type: 'LOCATION', url: 'https://example.com', time: 100 },
|
|
{ type: 'CLICK', value: 'test-button', time: 200 },
|
|
],
|
|
};
|
|
|
|
(searchStore.instance.events as any) = [
|
|
{ key: 'CLICK', operator: 'contains', value: 'test' },
|
|
];
|
|
|
|
(sessionService.getSessionInfo as jest.Mock).mockResolvedValue(
|
|
mockSessionInfo,
|
|
);
|
|
(sessionService.getSessionEvents as jest.Mock).mockResolvedValue(
|
|
mockEventsData,
|
|
);
|
|
(checkEventWithFilters as jest.Mock).mockReturnValue(true);
|
|
|
|
await sessionStore.fetchSessionData(mockSessionId);
|
|
|
|
expect(sessionStore.eventsIndex).toEqual([1]);
|
|
});
|
|
|
|
it('should handle errors when fetching events', async () => {
|
|
const mockSessionId = 'test-session-id';
|
|
const mockSessionInfo = { sessionId: mockSessionId, userId: 'user1' };
|
|
const mockError = new Error('API error');
|
|
console.error = jest.fn();
|
|
|
|
(sessionService.getSessionInfo as jest.Mock).mockResolvedValue(
|
|
mockSessionInfo,
|
|
);
|
|
(sessionService.getSessionEvents as jest.Mock).mockRejectedValue(
|
|
mockError,
|
|
);
|
|
|
|
await sessionStore.fetchSessionData(mockSessionId);
|
|
|
|
expect(console.error).toHaveBeenCalledWith(
|
|
'Failed to fetch events',
|
|
mockError,
|
|
);
|
|
expect(sessionStore.current.sessionId).toBe(mockSessionId);
|
|
expect(sessionStore.current.events).toEqual([]);
|
|
});
|
|
|
|
it('should handle errors when fetching session info', async () => {
|
|
const mockSessionId = 'test-session-id';
|
|
const mockError = new Error('API error');
|
|
console.error = jest.fn();
|
|
|
|
(sessionService.getSessionInfo as jest.Mock).mockRejectedValue(mockError);
|
|
|
|
await sessionStore.fetchSessionData(mockSessionId);
|
|
|
|
expect(console.error).toHaveBeenCalledWith(mockError);
|
|
expect(sessionStore.fetchFailed).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('sortSessions', () => {
|
|
it('should sort sessions by the specified key in ascending order', () => {
|
|
sessionStore.list = [
|
|
new Session(mockSession({ duration: 3000, sessionId: '1' })),
|
|
new Session(mockSession({ duration: 1000, sessionId: '2' })),
|
|
new Session(mockSession({ duration: 2000, sessionId: '3' })),
|
|
];
|
|
sessionStore.favoriteList = [
|
|
new Session(mockSession({ duration: 3000, sessionId: '1' })),
|
|
new Session(mockSession({ duration: 2000, sessionId: '3' })),
|
|
];
|
|
|
|
sessionStore.sortSessions('duration', 1);
|
|
|
|
expect(sessionStore.list.map((s) => s.sessionId)).toEqual([
|
|
'2',
|
|
'3',
|
|
'1',
|
|
]);
|
|
expect(sessionStore.favoriteList.map((s) => s.sessionId)).toEqual([
|
|
'3',
|
|
'1',
|
|
]);
|
|
});
|
|
|
|
it('should sort sessions by the specified key in descending order', () => {
|
|
sessionStore.list = [
|
|
new Session(mockSession({ duration: 3000, sessionId: '1' })),
|
|
new Session(mockSession({ duration: 1000, sessionId: '2' })),
|
|
new Session(mockSession({ duration: 2000, sessionId: '3' })),
|
|
];
|
|
|
|
sessionStore.sortSessions('duration', -1);
|
|
expect(sessionStore.list.map((s) => s.sessionId)).toEqual([
|
|
'1',
|
|
'3',
|
|
'2',
|
|
]);
|
|
});
|
|
});
|
|
});
|