veza/apps/web/src/features/streaming/services/bitrateService.test.ts
2025-12-12 21:34:34 -05:00

270 lines
6.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import {
adaptBitrate,
AdaptBitrateRequest,
AdaptBitrateResponse,
} from './bitrateService';
import { apiClient } from '@/services/api/client';
// Mock du client API
vi.mock('@/services/api/client', () => ({
apiClient: {
post: vi.fn(),
},
}));
describe('bitrateService', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('adaptBitrate', () => {
it('should successfully adapt bitrate and return recommended bitrate', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760, // 10 Mbps
buffer_level: 0.5,
};
const mockResponse: AdaptBitrateResponse = {
recommended_bitrate: 320,
};
(apiClient.post as any).mockResolvedValue({
data: mockResponse,
});
const result = await adaptBitrate(trackId, request);
expect(apiClient.post).toHaveBeenCalledWith(
`/tracks/${trackId}/bitrate/adapt`,
request,
);
expect(result).toEqual(mockResponse);
expect(result.recommended_bitrate).toBe(320);
});
it('should handle bitrate decrease', async () => {
const trackId = 456;
const request: AdaptBitrateRequest = {
current_bitrate: 320,
bandwidth: 307200, // 300 kbps
buffer_level: 0.5,
};
const mockResponse: AdaptBitrateResponse = {
recommended_bitrate: 192,
};
(apiClient.post as any).mockResolvedValue({
data: mockResponse,
});
const result = await adaptBitrate(trackId, request);
expect(result.recommended_bitrate).toBe(192);
});
it('should handle no bitrate change', async () => {
const trackId = 789;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.15, // Low buffer prevents increase
};
const mockResponse: AdaptBitrateResponse = {
recommended_bitrate: 128,
};
(apiClient.post as any).mockResolvedValue({
data: mockResponse,
});
const result = await adaptBitrate(trackId, request);
expect(result.recommended_bitrate).toBe(128);
});
it('should throw error on 401 Unauthorized', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
response: {
status: 401,
data: { error: 'unauthorized' },
},
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Unauthorized: Please log in to adapt bitrate',
);
});
it('should throw error on 400 Bad Request', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 1.5, // Invalid buffer level
};
const error = {
response: {
status: 400,
data: {
error: 'invalid buffer level: 1.5 (must be between 0.0 and 1.0)',
},
},
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Invalid request: invalid buffer level: 1.5 (must be between 0.0 and 1.0)',
);
});
it('should throw error on 404 Not Found', async () => {
const trackId = 999;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
response: {
status: 404,
data: { error: 'track not found' },
},
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Track not found: 999',
);
});
it('should throw error on 500 Server Error', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
response: {
status: 500,
data: { error: 'internal server error' },
},
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Server error: internal server error',
);
});
it('should throw error on network error', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
request: {},
message: 'Network Error',
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Network error: Unable to reach the server',
);
});
it('should throw error on unknown error', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
message: 'Unknown error occurred',
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Error: Unknown error occurred',
);
});
it('should handle error without response data', async () => {
const trackId = 123;
const request: AdaptBitrateRequest = {
current_bitrate: 128,
bandwidth: 10485760,
buffer_level: 0.5,
};
const error = {
response: {
status: 400,
data: {},
},
message: 'Bad Request',
};
(apiClient.post as any).mockRejectedValue(error);
await expect(adaptBitrate(trackId, request)).rejects.toThrow(
'Invalid request: Bad Request',
);
});
it('should handle different bitrate values', async () => {
const testCases = [
{ current: 128, recommended: 192 },
{ current: 192, recommended: 320 },
{ current: 320, recommended: 192 },
{ current: 128, recommended: 128 },
];
for (const testCase of testCases) {
const request: AdaptBitrateRequest = {
current_bitrate: testCase.current,
bandwidth: 10485760,
buffer_level: 0.5,
};
const mockResponse: AdaptBitrateResponse = {
recommended_bitrate: testCase.recommended,
};
(apiClient.post as any).mockResolvedValue({
data: mockResponse,
});
const result = await adaptBitrate(123, request);
expect(result.recommended_bitrate).toBe(testCase.recommended);
}
});
});
});