Files
gridpilot.gg/adapters/media/MediaResolverAdapter.test.ts
2026-01-16 21:40:26 +01:00

229 lines
8.0 KiB
TypeScript

/**
* TDD Tests for MediaResolverAdapter and its components
*
* Tests the complete resolution flow for all media reference types
*/
import { MediaReference } from '@core/domain/media/MediaReference';
import { describe, expect, it } from 'vitest';
import { DefaultResolvers, MediaResolverAdapter } from './MediaResolverAdapter';
import { DefaultMediaResolverAdapter } from './resolvers/DefaultMediaResolverAdapter';
import { GeneratedMediaResolverAdapter } from './resolvers/GeneratedMediaResolverAdapter';
import { UploadedMediaResolverAdapter } from './resolvers/UploadedMediaResolverAdapter';
describe('DefaultMediaResolverAdapter', () => {
const adapter = new DefaultMediaResolverAdapter();
describe('System Default URLs', () => {
it('should resolve avatar default without variant', async () => {
const ref = MediaReference.createSystemDefault('avatar');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/neutral-default-avatar');
});
it('should resolve male avatar default', async () => {
const ref = MediaReference.createSystemDefault('avatar', 'male');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/male-default-avatar');
});
it('should resolve female avatar default', async () => {
const ref = MediaReference.createSystemDefault('avatar', 'female');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/female-default-avatar');
});
it('should resolve neutral avatar default', async () => {
const ref = MediaReference.createSystemDefault('avatar', 'neutral');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/neutral-default-avatar');
});
it('should resolve team logo default', async () => {
const ref = MediaReference.createSystemDefault('logo');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/logo.png');
});
it('should resolve league logo default', async () => {
const ref = MediaReference.createSystemDefault('logo');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/default/logo.png');
});
it('should return null for non-system-default references', async () => {
const ref = MediaReference.createGenerated('team-123');
const url = await adapter.resolve(ref);
expect(url).toBeNull();
});
});
});
describe('GeneratedMediaResolverAdapter', () => {
const adapter = new GeneratedMediaResolverAdapter();
describe('Generated URLs', () => {
it('should resolve team logo generated', async () => {
const ref = MediaReference.createGenerated('team-123');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/teams/123/logo');
});
it('should resolve league logo generated', async () => {
const ref = MediaReference.createGenerated('league-456');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/leagues/456/logo');
});
it('should resolve driver avatar generated', async () => {
const ref = MediaReference.createGenerated('driver-789');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/avatar/789');
});
it('should handle complex type names with hyphens', async () => {
const ref = MediaReference.createGenerated('team-league-123');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/teams/league-123/logo');
});
it('should return null for invalid format (no hyphen)', async () => {
const ref = MediaReference.createGenerated('invalid');
const url = await adapter.resolve(ref);
expect(url).toBeNull();
});
it('should return null for non-generated references', async () => {
const ref = MediaReference.createSystemDefault('avatar');
const url = await adapter.resolve(ref);
expect(url).toBeNull();
});
});
});
describe('UploadedMediaResolverAdapter', () => {
const adapter = new UploadedMediaResolverAdapter();
describe('Uploaded URLs', () => {
it('should resolve uploaded media', async () => {
const ref = MediaReference.createUploaded('media-123');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/uploaded/media-123');
});
it('should handle different media IDs', async () => {
const ref = MediaReference.createUploaded('media-456');
const url = await adapter.resolve(ref);
expect(url).toBe('/media/uploaded/media-456');
});
it('should return null for non-uploaded references', async () => {
const ref = MediaReference.createSystemDefault('avatar');
const url = await adapter.resolve(ref);
expect(url).toBeNull();
});
});
});
describe('MediaResolverAdapter (Composite)', () => {
const resolver = new MediaResolverAdapter();
describe('Composite Resolution', () => {
it('should resolve system-default references', async () => {
const ref = MediaReference.createSystemDefault('avatar', 'male');
const url = await resolver.resolve(ref);
expect(url).toBe('/media/default/male-default-avatar');
});
it('should resolve generated references', async () => {
const ref = MediaReference.createGenerated('team-123');
const url = await resolver.resolve(ref);
expect(url).toBe('/media/teams/123/logo');
});
it('should resolve uploaded references', async () => {
const ref = MediaReference.createUploaded('media-456');
const url = await resolver.resolve(ref);
expect(url).toBe('/media/uploaded/media-456');
});
it('should return null for none references', async () => {
const ref = MediaReference.createNone();
const url = await resolver.resolve(ref);
expect(url).toBeNull();
});
it('should return null for null/undefined input', async () => {
expect(await resolver.resolve(null as unknown as MediaReference)).toBeNull();
expect(await resolver.resolve(undefined as unknown as MediaReference)).toBeNull();
});
});
describe('Factory Functions', () => {
it('should create local resolver', () => {
const local = DefaultResolvers.local();
// Local resolver should work without baseUrl (path-only)
expect(local).toBeInstanceOf(MediaResolverAdapter);
});
it('should create production resolver', () => {
const prod = DefaultResolvers.production();
// Production resolver should work without baseUrl (path-only)
expect(prod).toBeInstanceOf(MediaResolverAdapter);
});
});
});
describe('Integration: End-to-End Resolution', () => {
const resolver = new MediaResolverAdapter();
it('should resolve all reference types consistently', async () => {
const testCases = [
{
ref: MediaReference.createSystemDefault('avatar', 'male'),
expected: '/media/default/male-default-avatar'
},
{
ref: MediaReference.createSystemDefault('avatar', 'female'),
expected: '/media/default/female-default-avatar'
},
{
ref: MediaReference.createSystemDefault('logo'),
expected: '/media/default/logo.png'
},
{
ref: MediaReference.createGenerated('team-abc123'),
expected: '/media/teams/abc123/logo'
},
{
ref: MediaReference.createGenerated('league-def456'),
expected: '/media/leagues/def456/logo'
},
{
ref: MediaReference.createUploaded('media-ghi789'),
expected: '/media/uploaded/media-ghi789'
},
{
ref: MediaReference.createNone(),
expected: null
}
];
for (const testCase of testCases) {
const result = await resolver.resolve(testCase.ref);
expect(result).toBe(testCase.expected);
}
});
it('should maintain URL consistency across multiple resolutions', async () => {
const ref = MediaReference.createGenerated('team-123');
const url1 = await resolver.resolve(ref);
const url2 = await resolver.resolve(ref);
const url3 = await resolver.resolve(ref);
expect(url1).toBe(url2);
expect(url2).toBe(url3);
expect(url1).toBe('/media/teams/123/logo');
});
});