Skip to main content
Glama
coverage-boost.test.js9.72 kB
const axios = require('axios'); const MockAdapter = require('axios-mock-adapter'); const PlexMCPServer = require('../../index.js'); describe('Coverage Boost Tests', () => { let server; let mock; beforeEach(() => { const mockAxios = axios.create(); mock = new MockAdapter(mockAxios); server = new PlexMCPServer({ axios: mockAxios }); process.env.PLEX_TOKEN = 'test-token'; process.env.PLEX_URL = 'http://localhost:32400'; }); afterEach(() => { mock.restore(); delete process.env.PLEX_TOKEN; delete process.env.PLEX_URL; }); // Test utility methods directly to increase coverage describe('Utility Methods Direct Testing', () => { it('should test parseSearchResults edge cases', () => { // Test with empty object (will hit the early return) let result = server.parseSearchResults({}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); // Test with MediaContainer but no Metadata result = server.parseSearchResults({ MediaContainer: {} }); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); // Test with empty Metadata array result = server.parseSearchResults({ MediaContainer: { Metadata: [] } }); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test parseLibraries edge cases', () => { let result = server.parseLibraries({}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); result = server.parseLibraries({ MediaContainer: {} }); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test parsePlaylists edge cases', () => { let result = server.parsePlaylists({}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); result = server.parsePlaylists({ MediaContainer: {} }); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test parseWatchHistory edge cases', () => { let result = server.parseWatchHistory({}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test parseOnDeck edge cases', () => { let result = server.parseOnDeck({}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test parseWatchedStatus edge cases', () => { let result = server.parseWatchedStatus({}); expect(typeof result).toBe('object'); expect(result.ratingKey).toBeUndefined(); expect(result.viewCount).toBe(0); result = server.parseWatchedStatus({ ratingKey: '123', title: 'Test' }); expect(typeof result).toBe('object'); expect(result.ratingKey).toBe('123'); expect(result.title).toBe('Test'); }); it('should test getPlexTypeNumber with all types', () => { expect(server.getPlexTypeNumber('movie')).toBe(1); expect(server.getPlexTypeNumber('show')).toBe(2); expect(server.getPlexTypeNumber('episode')).toBe(4); expect(server.getPlexTypeNumber('artist')).toBe(8); expect(server.getPlexTypeNumber('album')).toBe(9); expect(server.getPlexTypeNumber('track')).toBe(10); expect(server.getPlexTypeNumber('unknown')).toBeNull(); }); }); describe('Advanced Filter Coverage', () => { it('should test applyAdvancedFilters with empty arrays', () => { let result = server.applyAdvancedFilters([], {}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test applyAdvancedFilters with items without Media', () => { const items = [{ title: 'Test', ratingKey: '1' }]; const result = server.applyAdvancedFilters(items, { resolution: '1080p' }); expect(Array.isArray(result)).toBe(true); }); it('should test applyAdvancedFilters with various audio formats', () => { const items = [{ title: 'Test', Media: [{ Part: [{ audioCodec: 'dts', size: 1000000000 }] }] }]; let result = server.applyAdvancedFilters(items, { audio_format: 'lossless' }); expect(result.length).toBe(1); result = server.applyAdvancedFilters(items, { audio_format: 'lossy' }); expect(result.length).toBe(0); }); }); describe('Activity Filter Coverage', () => { it('should test applyActivityFilters with empty arrays', () => { let result = server.applyActivityFilters([], {}); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(0); }); it('should test applyActivityFilters with items without viewCount', () => { const items = [{ title: 'Test', ratingKey: '1' }]; let result = server.applyActivityFilters(items, { play_count_min: 1 }); expect(result.length).toBe(0); result = server.applyActivityFilters(items, { never_played: true }); expect(result.length).toBe(1); }); it('should test applyActivityFilters with date filters', () => { const recentTime = Math.floor(Date.now() / 1000) - (12 * 60 * 60); // 12 hours ago (within 1 day) const veryOldTime = Math.floor(Date.now() / 1000) - (48 * 60 * 60); // 2 days ago const items = [{ title: 'Test', viewCount: 1, lastViewedAt: recentTime.toString() }]; let result = server.applyActivityFilters(items, { played_in_last_days: 1 }); expect(result.length).toBe(1); // Test with an item that's definitely too old for 0 days const oldItems = [{ title: 'Old Test', viewCount: 1, lastViewedAt: veryOldTime.toString() }]; // Note: played_in_last_days: 0 is falsy, so the filter might not apply at all // Let's test with a very small positive number instead result = server.applyActivityFilters(oldItems, { played_in_last_days: 0.001 }); expect(result.length).toBe(0); }); }); describe('Format Methods Coverage', () => { it('should test formatResults with various item types', () => { const movieItem = { title: 'Test Movie', type: 'movie', year: '2023', summary: 'A'.repeat(500), // Long summary to test truncation duration: 7200000 }; const result = server.formatResults([movieItem]); expect(typeof result).toBe('string'); expect(result).toContain('Test Movie'); }); it('should test formatLibraries with various inputs', () => { const libraries = [{ title: 'Movies', type: 'movie', key: '1', updatedAt: '1640995200' }]; const result = server.formatLibraries(libraries); expect(typeof result).toBe('string'); expect(result).toContain('Movies'); }); it('should test formatPlaylists with various inputs', () => { const playlists = [{ title: 'Test Playlist', playlistType: 'video', smart: '1', leafCount: 10, duration: 3600000 }]; const result = server.formatPlaylists(playlists); expect(typeof result).toBe('string'); expect(result).toContain('Test Playlist'); }); it('should test formatWatchHistory with various inputs', () => { const history = [{ title: 'Watched Movie', type: 'movie', viewedAt: '1640995200' }]; const result = server.formatWatchHistory(history); expect(typeof result).toBe('string'); expect(result).toContain('Watched Movie'); }); it('should test formatOnDeck with various inputs', () => { const onDeck = [{ title: 'Continue Show', type: 'episode', viewOffset: 600000, duration: 1800000 }]; const result = server.formatOnDeck(onDeck); expect(typeof result).toBe('string'); expect(result).toContain('Continue Show'); }); it('should test formatWatchedStatus with various inputs', () => { const statuses = [{ item_key: '123', title: 'Test Movie', status: 'watched', progress: '100%' }]; const result = server.formatWatchedStatus(statuses); expect(typeof result).toBe('string'); expect(result).toContain('Test Movie'); }); it('should test formatRecentlyAdded with various inputs', () => { const recent = [{ title: 'New Movie', type: 'movie', addedAt: '1640995200', Genre: [{ tag: 'Action' }, { tag: 'Drama' }, { tag: 'Comedy' }, { tag: 'Thriller' }] }]; const result = server.formatRecentlyAdded(recent); expect(typeof result).toBe('string'); expect(result).toContain('New Movie'); }); }); describe('Error Path Coverage', () => { it('should handle missing environment variables', async() => { delete process.env.PLEX_TOKEN; const result = await server.handleBrowseLibrary({ library_id: '1' }); expect(result.isError).toBe(true); }); it('should handle network errors gracefully', async() => { mock.onGet().networkError(); const result = await server.handleBrowseLibraries({}); expect(result.isError).toBe(true); }); it('should handle timeout errors', async() => { mock.onGet().timeout(); const result = await server.handleListPlaylists({}); expect(result.isError).toBe(true); }); it('should handle malformed responses', async() => { mock.onGet().reply(200, 'invalid json'); const result = await server.handleOnDeck({}); // This may or may not be an error depending on how the XML parser handles it expect(typeof result).toBe('object'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vyb1ng/plex-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server