/** * Tests for URL Utilities * FE-TEST-004: Test all URL utility functions */ import { describe, it, expect } from 'vitest'; import { buildUrl, parseQueryString, buildQueryString, getUrlPathname, getUrlHostname, isAbsoluteUrl, isRelativeUrl, normalizeUrl, addQueryParam, removeQueryParam, getQueryParam, hasQueryParam, extractDomain, extractProtocol, extractPort, isValidUrl, isSecureUrl, getUrlWithoutQuery, getUrlWithoutHash, getHashFromUrl, setHashInUrl, removeHashFromUrl, getBaseUrl, getRelativePath, isSameOrigin, getUrlSegments, getLastUrlSegment, getParentUrl, } from './url'; describe('url utilities', () => { describe('buildUrl', () => { it('should build URL with base and path', () => { const result = buildUrl('https://example.com', '/api/users'); expect(result).toBe('https://example.com/api/users'); }); it('should add query parameters', () => { const result = buildUrl('https://example.com', '/api/users', { page: 1, limit: 10 }); expect(result).toContain('page=1'); expect(result).toContain('limit=10'); }); it('should ignore null and undefined params', () => { const result = buildUrl('https://example.com', '/api/users', { page: 1, limit: null }); expect(result).toContain('page=1'); expect(result).not.toContain('limit'); }); }); describe('parseQueryString', () => { it('should parse query string', () => { const result = parseQueryString('?page=1&limit=10'); expect(result.page).toBe('1'); expect(result.limit).toBe('10'); }); it('should return empty object for empty string', () => { const result = parseQueryString(''); expect(result).toEqual({}); }); }); describe('buildQueryString', () => { it('should build query string from params', () => { const result = buildQueryString({ page: 1, limit: 10 }); expect(result).toContain('page=1'); expect(result).toContain('limit=10'); }); it('should ignore null and undefined', () => { const result = buildQueryString({ page: 1, limit: null }); expect(result).toContain('page=1'); expect(result).not.toContain('limit'); }); }); describe('getUrlPathname', () => { it('should extract pathname', () => { expect(getUrlPathname('https://example.com/api/users')).toBe('/api/users'); }); it('should return original string if invalid URL', () => { expect(getUrlPathname('invalid-url')).toBe('invalid-url'); }); }); describe('getUrlHostname', () => { it('should extract hostname', () => { expect(getUrlHostname('https://example.com/api/users')).toBe('example.com'); }); it('should return empty string for invalid URL', () => { expect(getUrlHostname('invalid-url')).toBe(''); }); }); describe('isAbsoluteUrl', () => { it('should return true for absolute URLs', () => { expect(isAbsoluteUrl('https://example.com')).toBe(true); expect(isAbsoluteUrl('http://example.com')).toBe(true); }); it('should return false for relative URLs', () => { expect(isAbsoluteUrl('/api/users')).toBe(false); }); it('should return false for invalid URLs', () => { expect(isAbsoluteUrl('not-a-url')).toBe(false); }); }); describe('isRelativeUrl', () => { it('should return true for relative URLs', () => { expect(isRelativeUrl('/api/users')).toBe(true); }); it('should return false for absolute URLs', () => { expect(isRelativeUrl('https://example.com')).toBe(false); }); }); describe('normalizeUrl', () => { it('should normalize valid URL', () => { const result = normalizeUrl('https://example.com/api'); expect(result).toBe('https://example.com/api'); }); it('should return original string if invalid', () => { expect(normalizeUrl('invalid-url')).toBe('invalid-url'); }); }); describe('addQueryParam', () => { it('should add query parameter', () => { const result = addQueryParam('https://example.com', 'page', '1'); expect(result).toContain('page=1'); }); it('should return original URL if invalid', () => { expect(addQueryParam('invalid-url', 'page', '1')).toBe('invalid-url'); }); }); describe('removeQueryParam', () => { it('should remove query parameter', () => { const result = removeQueryParam('https://example.com?page=1&limit=10', 'page'); expect(result).not.toContain('page=1'); expect(result).toContain('limit=10'); }); }); describe('getQueryParam', () => { it('should get query parameter', () => { const result = getQueryParam('https://example.com?page=1', 'page'); expect(result).toBe('1'); }); it('should return null if param not found', () => { const result = getQueryParam('https://example.com?page=1', 'limit'); expect(result).toBeNull(); }); }); describe('hasQueryParam', () => { it('should return true if param exists', () => { expect(hasQueryParam('https://example.com?page=1', 'page')).toBe(true); }); it('should return false if param does not exist', () => { expect(hasQueryParam('https://example.com?page=1', 'limit')).toBe(false); }); }); describe('extractDomain', () => { it('should extract domain', () => { expect(extractDomain('https://example.com/api')).toBe('example.com'); }); it('should return empty string for invalid URL', () => { expect(extractDomain('invalid-url')).toBe(''); }); }); describe('extractProtocol', () => { it('should extract protocol', () => { expect(extractProtocol('https://example.com')).toBe('https:'); }); }); describe('extractPort', () => { it('should extract port', () => { expect(extractPort('https://example.com:8080')).toBe('8080'); }); }); describe('isValidUrl', () => { it('should return true for valid URLs', () => { expect(isValidUrl('https://example.com')).toBe(true); expect(isValidUrl('http://example.com')).toBe(true); }); it('should return false for invalid URLs', () => { expect(isValidUrl('not-a-url')).toBe(false); }); }); describe('isSecureUrl', () => { it('should return true for HTTPS', () => { expect(isSecureUrl('https://example.com')).toBe(true); }); it('should return false for HTTP', () => { expect(isSecureUrl('http://example.com')).toBe(false); }); }); describe('getUrlWithoutQuery', () => { it('should remove query string', () => { expect(getUrlWithoutQuery('https://example.com?page=1')).toBe('https://example.com/'); }); }); describe('getUrlWithoutHash', () => { it('should remove hash', () => { expect(getUrlWithoutHash('https://example.com#section')).toBe('https://example.com/'); }); }); describe('getHashFromUrl', () => { it('should extract hash', () => { expect(getHashFromUrl('https://example.com#section')).toBe('#section'); }); }); describe('setHashInUrl', () => { it('should set hash', () => { const result = setHashInUrl('https://example.com', 'section'); expect(result).toContain('#section'); }); }); describe('removeHashFromUrl', () => { it('should remove hash', () => { const result = removeHashFromUrl('https://example.com#section'); expect(result).not.toContain('#section'); }); }); describe('getBaseUrl', () => { it('should get base URL', () => { expect(getBaseUrl('https://example.com/api/users')).toBe('https://example.com'); }); }); describe('getRelativePath', () => { it('should get relative path', () => { expect(getRelativePath('https://example.com/api/users')).toBe('/api/users'); }); }); describe('isSameOrigin', () => { it('should return true for same origin', () => { expect(isSameOrigin('https://example.com/api', 'https://example.com/users')).toBe(true); }); it('should return false for different origins', () => { expect(isSameOrigin('https://example.com', 'https://other.com')).toBe(false); }); }); describe('getUrlSegments', () => { it('should get URL segments', () => { expect(getUrlSegments('https://example.com/api/users/123')).toEqual(['api', 'users', '123']); }); }); describe('getLastUrlSegment', () => { it('should get last segment', () => { expect(getLastUrlSegment('https://example.com/api/users/123')).toBe('123'); }); }); describe('getParentUrl', () => { it('should get parent URL', () => { const result = getParentUrl('https://example.com/api/users/123'); expect(result).toContain('/api/users'); expect(result).not.toContain('/123'); }); }); });