diff --git a/frontend/app/components/Spots/SpotPlayer/spotPlayerStore.ts b/frontend/app/components/Spots/SpotPlayer/spotPlayerStore.ts index c8675e95d..45e7ac7c2 100644 --- a/frontend/app/components/Spots/SpotPlayer/spotPlayerStore.ts +++ b/frontend/app/components/Spots/SpotPlayer/spotPlayerStore.ts @@ -1,7 +1,7 @@ import { makeAutoObservable } from 'mobx'; import { getResourceFromNetworkRequest } from 'App/player'; -import { Log as PLog, ILog } from "App/player"; +import { Log as PLog } from "App/player"; import { PlayingState } from 'App/player-ui' interface Event { diff --git a/frontend/app/player/web/types/resource.ts b/frontend/app/player/web/types/resource.ts index 2ccf8156f..d4520d8aa 100644 --- a/frontend/app/player/web/types/resource.ts +++ b/frontend/app/player/web/types/resource.ts @@ -1,4 +1,4 @@ -import type {ResourceTiming, NetworkRequest, Fetch, IosNetworkCall} from '../messages' +import type {ResourceTiming, NetworkRequest, Fetch, MobileNetworkCall} from '../messages' export const enum ResourceType { XHR = 'xhr', @@ -60,11 +60,6 @@ export function getResourceName(url: string) { .pop(); } - -const YELLOW_BOUND = 10; -const RED_BOUND = 80; - - interface IResource { //index: number, time: number, @@ -129,7 +124,7 @@ export function getResourceFromResourceTiming(msg: ResourceTiming, sessStart: nu }) } -export function getResourceFromNetworkRequest(msg: NetworkRequest | Fetch | IosNetworkCall, sessStart: number) { +export function getResourceFromNetworkRequest(msg: NetworkRequest | Fetch | MobileNetworkCall, sessStart: number) { return Resource({ ...msg, // @ts-ignore diff --git a/frontend/.babelrc b/frontend/babel.config.js similarity index 97% rename from frontend/.babelrc rename to frontend/babel.config.js index 4ec9226ab..4fdf68799 100644 --- a/frontend/.babelrc +++ b/frontend/babel.config.js @@ -1,4 +1,4 @@ -{ +module.exports = { "presets": [ "@babel/preset-env", "@babel/preset-react", diff --git a/frontend/jest.config.js b/frontend/jest.config.mjs similarity index 78% rename from frontend/jest.config.js rename to frontend/jest.config.mjs index 033463ec2..d3dbab8f4 100644 --- a/frontend/jest.config.js +++ b/frontend/jest.config.mjs @@ -1,26 +1,26 @@ -console.log(__dirname) -const dir = __dirname -module.exports = { +export default { preset: 'ts-jest', testEnvironment: 'jsdom', moduleNameMapper: { '^Types/session/(.+)$': '/app/types/session/$1', '^App/(.+)$': '/app/$1', + "\\.(css|less)$": "/tests/mocks/style.mock.js", }, collectCoverage: true, verbose: true, collectCoverageFrom: [ - // '/app/**/*.{ts,tsx,js,jsx}', '/app/player/**/*.{ts,tsx,js,jsx}', '/app/mstore/**/*.{ts,tsx,js,jsx}', '/app/utils/**/*.{ts,tsx,js,jsx}', - '!/app/**/*.d.ts', - '!/node_modules' + '!/node_modules', ], transform: { '^.+\\.(ts|tsx)?$': ['ts-jest', { isolatedModules: true, diagnostics: { warnOnly: true } }], '^.+\\.(js|jsx)$': 'babel-jest', }, moduleDirectories: ['node_modules'], + transformIgnorePatterns: [ + '/node_modules/(?!syncod)', + ], }; diff --git a/frontend/tests/mocks/style.mock.js b/frontend/tests/mocks/style.mock.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/frontend/tests/mocks/style.mock.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/frontend/tests/spotPlayerStore.test.ts b/frontend/tests/spotPlayerStore.test.ts new file mode 100644 index 000000000..043b4eff6 --- /dev/null +++ b/frontend/tests/spotPlayerStore.test.ts @@ -0,0 +1,169 @@ +import { jest, beforeEach, describe, expect, it } from '@jest/globals'; + +import spotPlayerStore, { + PANELS, +} from '../app/components/Spots/SpotPlayer/spotPlayerStore'; + +jest.mock('App/player', () => ({ + getResourceFromNetworkRequest: jest.fn(), + Log: jest.fn((log: Record) => ({ + isRed: log.level === 'exception' || log.level === 'error', + isYellow: log.level === 'warn', + ...log, + })), +})); + +jest.mock('App/player-ui', () => ({ + PlayingState: { + Playing: 0, + Paused: 1, + Completed: 2, + }, +})); + +enum PlayingState { + Playing, + Paused, + Completed, +} + +const createSampleEvents = () => { + return { + logs: [{ time: 1000, level: 'info', msg: 'Test log message' }], + locations: [{ time: 2000, location: 'Test location', navTiming: {} }], + clicks: [{ time: 3000, label: 'Test click' }], + network: [ + { + time: 4000, + type: 'fetch', + statusCode: 200, + url: 'https://example.com', + fromCache: false, + body: 'Response body', + encodedBodySize: 100, + responseBodySize: 100, + duration: 50, + method: 'GET', + }, + ], + }; +}; + +describe('SpotPlayerStore', () => { + beforeEach(() => { + spotPlayerStore.clearData(); + }); + + it('should initialize with default values', () => { + expect(spotPlayerStore.time).toBe(0); + expect(spotPlayerStore.isPlaying).toBe(true); + expect(spotPlayerStore.state).toBe(PlayingState.Playing); + expect(spotPlayerStore.volume).toBe(1); + expect(spotPlayerStore.logs).toEqual([]); + expect(spotPlayerStore.network).toEqual([]); + }); + + it('should clear all data on clearData()', () => { + spotPlayerStore.setDeviceData('Chrome', '1920x1080', 'Windows'); + spotPlayerStore.setIsPlaying(false); + + spotPlayerStore.clearData(); + + expect(spotPlayerStore.time).toBe(0); + expect(spotPlayerStore.isPlaying).toBe(true); + expect(spotPlayerStore.state).toBe(PlayingState.Playing); + expect(spotPlayerStore.browserVersion).toBeNull(); + }); + + it('should set device data correctly', () => { + spotPlayerStore.setDeviceData('Firefox', '1366x768', 'Linux'); + + expect(spotPlayerStore.browserVersion).toBe('Firefox'); + expect(spotPlayerStore.resolution).toBe('1366x768'); + expect(spotPlayerStore.platform).toBe('Linux'); + }); + + it('should set skip interval correctly', () => { + spotPlayerStore.setSkipInterval(15); + expect(spotPlayerStore.skipInterval).toBe(15); + }); + + it('should set active panel correctly', () => { + spotPlayerStore.setActivePanel(PANELS.CONSOLE); + expect(spotPlayerStore.activePanel).toBe(PANELS.CONSOLE); + + spotPlayerStore.setActivePanel(null); + expect(spotPlayerStore.activePanel).toBeNull(); + }); + + it('should set duration correctly', () => { + spotPlayerStore.setDuration('02:30'); + expect(spotPlayerStore.duration).toBe(150); + expect(spotPlayerStore.durationString).toBe('02:30'); + }); + + it('should update logs, locations, clicks, and network events correctly', () => { + const { logs, locations, clicks, network } = createSampleEvents(); + + // @ts-ignore + spotPlayerStore.setEvents(logs, locations, clicks, network); + + expect(spotPlayerStore.logs.length).toBe(1); + expect(spotPlayerStore.locations.length).toBe(1); + expect(spotPlayerStore.clicks.length).toBe(1); + expect(spotPlayerStore.network.length).toBe(1); + }); + + it('should correctly compute the current log index', () => { + spotPlayerStore.logs = [{ time: 1000 }, { time: 2000 }, { time: 3000 }]; + spotPlayerStore.time = 1.5; + + const currentIndex = spotPlayerStore.currentLogIndex; + + expect(currentIndex).toBe(0); + }); + + it('should correctly highlight the closest event', () => { + const eventTime = 2; + // @ts-ignore + spotPlayerStore.locations = [{ time: 1000 }, { time: 3000 }]; + + const closestLocation = spotPlayerStore.getClosestLocation(eventTime); + + expect(closestLocation.time).toBe(1000); + }); + + it('should correctly set the playing state', () => { + spotPlayerStore.setIsPlaying(false); + expect(spotPlayerStore.isPlaying).toBe(false); + expect(spotPlayerStore.state).toBe(PlayingState.Paused); + + spotPlayerStore.setIsPlaying(true); + expect(spotPlayerStore.isPlaying).toBe(true); + expect(spotPlayerStore.state).toBe(PlayingState.Playing); + }); + + it('should correctly mute and unmute', () => { + spotPlayerStore.setIsMuted(true); + expect(spotPlayerStore.isMuted).toBe(true); + + spotPlayerStore.setIsMuted(false); + expect(spotPlayerStore.isMuted).toBe(false); + }); + + it('should correctly set volume', () => { + spotPlayerStore.setVolume(0.5); + expect(spotPlayerStore.volume).toBe(0.5); + + spotPlayerStore.setVolume(1); + expect(spotPlayerStore.volume).toBe(1); + }); + + it('should correctly handle fullscreen toggle', () => { + spotPlayerStore.setIsFullScreen(true); + expect(spotPlayerStore.isFullScreen).toBe(true); + + spotPlayerStore.setIsFullScreen(false); + expect(spotPlayerStore.isFullScreen).toBe(false); + }); +}); diff --git a/frontend/tests/types.resource.test.ts b/frontend/tests/types.resource.test.ts index 8e623d46a..c90631a42 100644 --- a/frontend/tests/types.resource.test.ts +++ b/frontend/tests/types.resource.test.ts @@ -55,7 +55,6 @@ describe('Resource', () => { const expectedResult = { ...testResource, name: 'script.js', - isRed: false, isYellow: false, }; expect(Resource(testResource)).toEqual(expectedResult);