Skip to main content
Glama
parsers.test.js7.84 kB
const PlexMCPServer = require('../../index.js'); const { mockSearchResponse, mockLibrariesResponse, mockPlaylistsResponse, mockWatchHistoryResponse, mockOnDeckResponse, mockEmptyResponse } = require('../fixtures/plex-responses.js'); describe('Parser Functions', () => { let server; beforeEach(() => { server = new PlexMCPServer({ axios: require('axios').create() }); }); describe('parseSearchResults', () => { it('should parse search results correctly', () => { const results = server.parseSearchResults(mockSearchResponse); expect(results).toHaveLength(2); expect(results[0]).toEqual({ title: 'Test Movie', type: 'movie', year: 2023, summary: 'A test movie for unit testing', rating: 8.5, duration: 7200000, addedAt: 1703097600, viewCount: 1, lastViewedAt: 1703184000, contentRating: undefined, Media: undefined, key: '/library/metadata/12345', ratingKey: '12345', // Additional hierarchical info for music tracks parentTitle: undefined, grandparentTitle: undefined, parentRatingKey: undefined, grandparentRatingKey: undefined, // Additional metadata for basic filters studio: undefined, genres: [], directors: [], writers: [], actors: [] }); }); it('should handle empty search results', () => { const results = server.parseSearchResults(mockEmptyResponse); expect(results).toEqual([]); }); it('should handle missing MediaContainer', () => { const results = server.parseSearchResults({}); expect(results).toEqual([]); }); it('should handle missing Metadata', () => { const results = server.parseSearchResults({ MediaContainer: {} }); expect(results).toEqual([]); }); }); describe('parseLibraries', () => { it('should parse libraries correctly', () => { const libraries = server.parseLibraries(mockLibrariesResponse); expect(libraries).toHaveLength(3); expect(libraries[0]).toEqual({ key: '1', title: 'Movies', type: 'movie', agent: 'com.plexapp.agents.themoviedb', scanner: 'Plex Movie Scanner', language: 'en', refreshing: undefined, createdAt: 1703097600, updatedAt: 1703184000, scannedAt: 1703270400 }); }); it('should handle empty library response', () => { const libraries = server.parseLibraries({ MediaContainer: {} }); expect(libraries).toEqual([]); }); }); describe('parsePlaylists', () => { it('should parse playlists correctly', () => { const playlists = server.parsePlaylists(mockPlaylistsResponse); expect(playlists).toHaveLength(2); expect(playlists[0]).toEqual({ ratingKey: 'pl001', key: '/playlists/pl001', title: 'My Music Playlist', type: 'playlist', playlistType: 'audio', smart: false, duration: 3600000, leafCount: 15, addedAt: 1703097600, updatedAt: 1703184000, composite: undefined }); }); it('should identify smart playlists', () => { const playlists = server.parsePlaylists(mockPlaylistsResponse); expect(playlists[1].smart).toBe(true); }); }); describe('parseWatchHistory', () => { it('should parse watch history correctly', () => { const history = server.parseWatchHistory(mockWatchHistoryResponse); expect(history).toHaveLength(2); expect(history[0]).toEqual({ title: 'Test Movie', type: 'movie', year: 2023, viewedAt: 1703184000, accountID: 1, deviceID: 'test-device-123', viewOffset: 7200000, duration: 7200000, grandparentTitle: undefined, parentTitle: undefined, index: undefined, parentIndex: undefined, key: undefined }); }); it('should handle TV show episodes in history', () => { const history = server.parseWatchHistory(mockWatchHistoryResponse); expect(history[1].grandparentTitle).toBe('Test TV Show'); expect(history[1].parentIndex).toBe(1); expect(history[1].index).toBe(1); }); }); describe('parseOnDeck', () => { it('should parse on deck items correctly', () => { const onDeck = server.parseOnDeck(mockOnDeckResponse); expect(onDeck).toHaveLength(1); expect(onDeck[0]).toEqual({ title: 'Episode Title', type: 'episode', year: undefined, viewOffset: 900000, duration: 2700000, lastViewedAt: 1703270400, grandparentTitle: 'Test TV Show', parentTitle: 'Season 1', index: 2, parentIndex: 1, summary: 'Continue watching this episode', rating: undefined, key: undefined }); }); }); describe('parseWatchedStatus', () => { it('should parse watched status for fully watched item', () => { const item = { ratingKey: '12345', title: 'Test Movie', type: 'movie', year: 2023, viewCount: 2, lastViewedAt: 1703184000, duration: 7200000 }; const status = server.parseWatchedStatus(item); expect(status).toEqual({ ratingKey: '12345', title: 'Test Movie', type: 'movie', year: 2023, viewCount: 2, lastViewedAt: 1703184000, viewOffset: 0, duration: 7200000, watched: true, partiallyWatched: false, grandparentTitle: undefined, parentTitle: undefined, index: undefined, parentIndex: undefined }); }); it('should parse watched status for partially watched item', () => { const item = { ratingKey: '67890', title: 'Episode Title', type: 'episode', viewOffset: 1350000, duration: 2700000, viewCount: 0 }; const status = server.parseWatchedStatus(item); expect(status.watched).toBe(false); expect(status.partiallyWatched).toBe(true); expect(status.viewOffset).toBe(1350000); }); it('should parse watched status for unwatched item', () => { const item = { ratingKey: '99999', title: 'Unwatched Movie', type: 'movie', duration: 7200000 }; const status = server.parseWatchedStatus(item); expect(status.watched).toBe(false); expect(status.partiallyWatched).toBe(false); expect(status.viewCount).toBe(0); expect(status.viewOffset).toBe(0); }); }); describe('parseLibraryContent', () => { it('should parse library content with additional fields', () => { const content = server.parseLibraryContent(mockSearchResponse); expect(content).toHaveLength(2); expect(content[0]).toHaveProperty('title', 'Test Movie'); expect(content[0]).toHaveProperty('genres'); expect(content[0]).toHaveProperty('viewCount'); expect(content[0]).toHaveProperty('originallyAvailableAt'); }); }); describe('getPlexTypeNumber', () => { it('should return correct type numbers', () => { 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); }); it('should return null for unknown types', () => { expect(server.getPlexTypeNumber('unknown')).toBe(null); expect(server.getPlexTypeNumber('')).toBe(null); expect(server.getPlexTypeNumber(null)).toBe(null); }); }); });

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