From eec910aabb29959b9138a636cab160db14342f18 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 3 Oct 2026 22:32:45 +0200 Subject: [PATCH] fix: classify Plex music releases correctly (#6977) * fix: classify Plex music releases correctly * test(plex): cover music release classification --- apps/docs/docs/integrations/plex/index.mdx | 2 ++ .../integrations/src/plex/plex-integration.ts | 6 +++- .../src/plex/test/plex-integration.spec.ts | 28 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/docs/docs/integrations/plex/index.mdx b/apps/docs/docs/integrations/plex/index.mdx index b6e35a6e3..eaf9bf1d6 100644 --- a/apps/docs/docs/integrations/plex/index.mdx +++ b/apps/docs/docs/integrations/plex/index.mdx @@ -19,6 +19,8 @@ import { mediaReleasesWidget } from "@site/docs/widgets/media-releases"; +The Media releases widget classifies Plex albums, artists, and tracks as Music. + ### Adding the integration diff --git a/packages/integrations/src/plex/plex-integration.ts b/packages/integrations/src/plex/plex-integration.ts index 90f8e1357..deaf12bca 100644 --- a/packages/integrations/src/plex/plex-integration.ts +++ b/packages/integrations/src/plex/plex-integration.ts @@ -606,7 +606,7 @@ const identitySchema = z.object({ }), }); -const mapType = (type: string): "movie" | "tv" | "unknown" => { +const mapType = (type: string): "movie" | "tv" | "music" | "unknown" => { switch (type) { case "movie": return "movie"; @@ -614,6 +614,10 @@ const mapType = (type: string): "movie" | "tv" | "unknown" => { case "season": case "episode": return "tv"; + case "album": + case "artist": + case "track": + return "music"; default: return "unknown"; } diff --git a/packages/integrations/src/plex/test/plex-integration.spec.ts b/packages/integrations/src/plex/test/plex-integration.spec.ts index 9b66148e9..82f500095 100644 --- a/packages/integrations/src/plex/test/plex-integration.spec.ts +++ b/packages/integrations/src/plex/test/plex-integration.spec.ts @@ -71,6 +71,34 @@ beforeEach(() => { }); describe("PlexIntegration.getMediaReleasesAsync", () => { + test.each([ + ["album", "music"], + ["artist", "music"], + ["track", "music"], + ["movie", "movie"], + ["show", "tv"], + ["unsupported", "unknown"], + ])("classifies %s releases as %s", async (type, expectedType) => { + mockFetch.mockImplementation((url) => { + const urlString = String(url); + if (urlString.endsWith("/identity")) { + return respond({ MediaContainer: { machineIdentifier: "server-id" } }); + } + if (urlString.endsWith("/library/recentlyAdded")) { + return respond({ MediaContainer: { Metadata: [createMetadataItem(type, { type })] } }); + } + if (urlString.endsWith("/library/sections")) { + return respond({ MediaContainer: { Directory: [] } }); + } + throw new Error(`Unexpected Plex request: ${urlString}`); + }); + + const releases = await createIntegration().getMediaReleasesAsync(); + + expect(releases).toHaveLength(1); + expect(releases[0]).toMatchObject({ title: "Movie", type: expectedType }); + }); + test("uses the series title for TV seasons and episodes", async () => { mockFetch.mockImplementation((url) => { const urlString = String(url);