mirror of
https://github.com/LukeHagar/plex-api-spec.git
synced 2025-12-10 12:37:44 +00:00
cleaned up Get All Libraries endpoint
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
"@modyfi/vite-plugin-yaml": "^1.1.0",
|
||||||
|
"@ngneat/falso": "^7.3.0",
|
||||||
"@redocly/cli": "^1.28.1",
|
"@redocly/cli": "^1.28.1",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.0",
|
"@types/node": "^22.5.0",
|
||||||
|
|||||||
8
src/models/directory/agent.yaml
Normal file
8
src/models/directory/agent.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- agent
|
||||||
|
properties:
|
||||||
|
agent:
|
||||||
|
type: string
|
||||||
|
description: The Plex agent used to match and retrieve media metadata.
|
||||||
|
example: tv.plex.agents.movie
|
||||||
8
src/models/directory/composite.yaml
Normal file
8
src/models/directory/composite.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- composite
|
||||||
|
properties:
|
||||||
|
composite:
|
||||||
|
type: string
|
||||||
|
description: The relative path to the composite media item.
|
||||||
|
example: /library/sections/1/composite/1743824484
|
||||||
9
src/models/directory/content-changed-at.yaml
Normal file
9
src/models/directory/content-changed-at.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- contentChangedAt
|
||||||
|
properties:
|
||||||
|
contentChangedAt:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
description: The number of seconds since the content was last changed relative to now.
|
||||||
|
example: 9173960
|
||||||
8
src/models/directory/content.yaml
Normal file
8
src/models/directory/content.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- content
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
type: boolean
|
||||||
|
description: UNKNOWN
|
||||||
|
example: true
|
||||||
8
src/models/directory/created-at.yaml
Normal file
8
src/models/directory/created-at.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
createdAt:
|
||||||
|
allOf:
|
||||||
|
- $ref: "../../models/common/PlexDateTime.yaml"
|
||||||
|
- description: "The date and time when the library was created."
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
8
src/models/directory/directory.yaml
Normal file
8
src/models/directory/directory.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- directory
|
||||||
|
properties:
|
||||||
|
directory:
|
||||||
|
type: boolean
|
||||||
|
description: UNKNOWN
|
||||||
|
example: true
|
||||||
8
src/models/directory/filters.yaml
Normal file
8
src/models/directory/filters.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- filters
|
||||||
|
properties:
|
||||||
|
filters:
|
||||||
|
type: boolean
|
||||||
|
description: UNKNOWN
|
||||||
|
example: true
|
||||||
10
src/models/directory/hidden.yaml
Normal file
10
src/models/directory/hidden.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- hidden
|
||||||
|
properties:
|
||||||
|
hidden:
|
||||||
|
allOf:
|
||||||
|
- $ref: "../common/PlexBoolean.yaml"
|
||||||
|
- type: integer
|
||||||
|
format: int32
|
||||||
|
description: UNKNOWN
|
||||||
8
src/models/directory/key.yaml
Normal file
8
src/models/directory/key.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
description: The library key representing the unique identifier
|
||||||
|
example: "1"
|
||||||
8
src/models/directory/language.yaml
Normal file
8
src/models/directory/language.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- language
|
||||||
|
properties:
|
||||||
|
language:
|
||||||
|
type: string
|
||||||
|
description: The Plex library language that has been set
|
||||||
|
example: en-US
|
||||||
8
src/models/directory/refreshing.yaml
Normal file
8
src/models/directory/refreshing.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- refreshing
|
||||||
|
properties:
|
||||||
|
refreshing:
|
||||||
|
type: boolean
|
||||||
|
description: "Indicates whether the library is currently being refreshed or updated"
|
||||||
|
example: true
|
||||||
6
src/models/directory/scanned-at.yaml
Normal file
6
src/models/directory/scanned-at.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- scannedAt
|
||||||
|
properties:
|
||||||
|
scannedAt:
|
||||||
|
$ref: "../../models/common/PlexDateTime.yaml"
|
||||||
8
src/models/directory/scanner.yaml
Normal file
8
src/models/directory/scanner.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- scanner
|
||||||
|
properties:
|
||||||
|
scanner:
|
||||||
|
type: string
|
||||||
|
description: UNKNOWN
|
||||||
|
example: Plex Movie
|
||||||
8
src/models/directory/title.yaml
Normal file
8
src/models/directory/title.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- title
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
description: "The title of the library"
|
||||||
|
example: "Movies"
|
||||||
9
src/models/directory/type.yaml
Normal file
9
src/models/directory/type.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
allOf:
|
||||||
|
- $ref: "../common/PlexMediaTypeString.yaml"
|
||||||
|
- type: string
|
||||||
|
description: "The library type"
|
||||||
6
src/models/directory/updated-at.yaml
Normal file
6
src/models/directory/updated-at.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- updatedAt
|
||||||
|
properties:
|
||||||
|
updatedAt:
|
||||||
|
$ref: "../../models/common/PlexDateTime.yaml"
|
||||||
8
src/models/directory/uuid.yaml
Normal file
8
src/models/directory/uuid.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- uuid
|
||||||
|
properties:
|
||||||
|
uuid:
|
||||||
|
type: string
|
||||||
|
description: "The universally unique identifier for the library."
|
||||||
|
example: "e69655a2-ef48-4aba-bb19-01e7d3cc34d6"
|
||||||
@@ -10,6 +10,8 @@ get:
|
|||||||
|
|
||||||
Libraries have features beyond just being a collection of media; for starters, they include information about supported types, filters and sorts.
|
Libraries have features beyond just being a collection of media; for starters, they include information about supported types, filters and sorts.
|
||||||
This allows a client to provide a rich interface around the media (e.g. allow sorting movies by release year).
|
This allows a client to provide a rich interface around the media (e.g. allow sorting movies by release year).
|
||||||
|
parameters:
|
||||||
|
- $ref: "../../parameters/accept-application-json.yaml"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The libraries available on the Server
|
description: The libraries available on the Server
|
||||||
@@ -17,111 +19,42 @@ get:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
required:
|
|
||||||
- MediaContainer
|
|
||||||
properties:
|
properties:
|
||||||
MediaContainer:
|
MediaContainer:
|
||||||
type: object
|
allOf:
|
||||||
required:
|
- $ref: "../../models/media-container/size.yaml"
|
||||||
- size
|
- $ref: "../../models/media-container/allow-sync.yaml"
|
||||||
- allowSync
|
- $ref: "../../models/media-container/title1.yaml"
|
||||||
- title1
|
- type: object
|
||||||
- Directory
|
|
||||||
properties:
|
properties:
|
||||||
size:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
example: 5
|
|
||||||
allowSync:
|
|
||||||
type: boolean
|
|
||||||
example: false
|
|
||||||
title1:
|
|
||||||
type: string
|
|
||||||
example: Plex Library
|
|
||||||
Directory:
|
Directory:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: object
|
|
||||||
required:
|
required:
|
||||||
- allowSync
|
|
||||||
- art
|
|
||||||
- composite
|
|
||||||
- filters
|
|
||||||
- refreshing
|
|
||||||
- thumb
|
|
||||||
- key
|
|
||||||
- type
|
|
||||||
- title
|
|
||||||
- agent
|
|
||||||
- scanner
|
|
||||||
- language
|
|
||||||
- uuid
|
|
||||||
- updatedAt
|
|
||||||
- createdAt
|
|
||||||
- scannedAt
|
|
||||||
- content
|
|
||||||
- directory
|
|
||||||
- contentChangedAt
|
|
||||||
- hidden
|
|
||||||
- Location
|
- Location
|
||||||
|
allOf:
|
||||||
|
- $ref: "../../models/media-container/allow-sync.yaml"
|
||||||
|
- $ref: "../../models/media-container/art.yaml"
|
||||||
|
- $ref: "../../models/directory/composite.yaml"
|
||||||
|
- $ref: "../../models/directory/filters.yaml"
|
||||||
|
- $ref: "../../models/directory/refreshing.yaml"
|
||||||
|
- $ref: "../../models/media-container/thumb.yaml"
|
||||||
|
- $ref: "../../models/directory/key.yaml"
|
||||||
|
- $ref: "../../models/directory/type.yaml"
|
||||||
|
- $ref: "../../models/directory/title.yaml"
|
||||||
|
- $ref: "../../models/directory/agent.yaml"
|
||||||
|
- $ref: "../../models/directory/scanner.yaml"
|
||||||
|
- $ref: "../../models/directory/language.yaml"
|
||||||
|
- $ref: "../../models/directory/uuid.yaml"
|
||||||
|
- $ref: "../../models/directory/updated-at.yaml"
|
||||||
|
- $ref: "../../models/directory/created-at.yaml"
|
||||||
|
- $ref: "../../models/directory/scanned-at.yaml"
|
||||||
|
- $ref: "../../models/directory/content.yaml"
|
||||||
|
- $ref: "../../models/directory/directory.yaml"
|
||||||
|
- $ref: "../../models/directory/content-changed-at.yaml"
|
||||||
|
- $ref: "../../models/directory/hidden.yaml"
|
||||||
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
allowSync:
|
|
||||||
type: boolean
|
|
||||||
example: true
|
|
||||||
art:
|
|
||||||
type: string
|
|
||||||
example: /:/resources/movie-fanart.jpg
|
|
||||||
composite:
|
|
||||||
type: string
|
|
||||||
example: /library/sections/1/composite/1705615584
|
|
||||||
filters:
|
|
||||||
type: boolean
|
|
||||||
example: true
|
|
||||||
refreshing:
|
|
||||||
type: boolean
|
|
||||||
example: false
|
|
||||||
thumb:
|
|
||||||
type: string
|
|
||||||
example: /:/resources/movie.png
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
example: "1"
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
example: movie
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
example: Movies
|
|
||||||
agent:
|
|
||||||
type: string
|
|
||||||
example: tv.plex.agents.movie
|
|
||||||
scanner:
|
|
||||||
type: string
|
|
||||||
example: Plex Movie
|
|
||||||
language:
|
|
||||||
type: string
|
|
||||||
example: en-US
|
|
||||||
uuid:
|
|
||||||
type: string
|
|
||||||
example: 322a231a-b7f7-49f5-920f-14c61199cd30
|
|
||||||
updatedAt:
|
|
||||||
$ref: "../../models/common/PlexDateTime.yaml"
|
|
||||||
createdAt:
|
|
||||||
$ref: "../../models/common/PlexDateTime.yaml"
|
|
||||||
scannedAt:
|
|
||||||
$ref: "../../models/common/PlexDateTime.yaml"
|
|
||||||
content:
|
|
||||||
type: boolean
|
|
||||||
example: true
|
|
||||||
directory:
|
|
||||||
type: boolean
|
|
||||||
example: true
|
|
||||||
contentChangedAt:
|
|
||||||
$ref: "../../models/common/PlexDateTime.yaml"
|
|
||||||
hidden:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
example: 0
|
|
||||||
Location:
|
Location:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@@ -133,10 +66,12 @@ get:
|
|||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
|
description: The ID of the location.
|
||||||
example: 1
|
example: 1
|
||||||
path:
|
path:
|
||||||
type: string
|
type: string
|
||||||
example: /movies
|
description: The path to the media item.
|
||||||
|
example: /Movies
|
||||||
"400":
|
"400":
|
||||||
$ref: "../../responses/400.yaml"
|
$ref: "../../responses/400.yaml"
|
||||||
"401":
|
"401":
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { validateResponseSpec } from "@utils"
|
import {
|
||||||
|
randPlexUnixEpoch,
|
||||||
|
randRelativeSeconds,
|
||||||
|
randUUID,
|
||||||
|
validateResponseSpec
|
||||||
|
} from "@utils"
|
||||||
import { describe, it } from "vitest"
|
import { describe, it } from "vitest"
|
||||||
|
|
||||||
describe("GET /library/sections", () => {
|
describe("GET /library/sections", () => {
|
||||||
@@ -22,13 +27,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.movie",
|
agent: "tv.plex.agents.movie",
|
||||||
scanner: "Plex Movie",
|
scanner: "Plex Movie",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "a1b2c3d4e5f67890",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394001,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476504,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047123,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 4738921,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -50,13 +55,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.movie",
|
agent: "tv.plex.agents.movie",
|
||||||
scanner: "Plex Movie",
|
scanner: "Plex Movie",
|
||||||
language: "nl-NL",
|
language: "nl-NL",
|
||||||
uuid: "b2c3d4e5f67890a1",
|
uuid: randUUID(),
|
||||||
updatedAt: 1680007500,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1680007500,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047124,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 5283714,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -78,13 +83,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.movie",
|
agent: "tv.plex.agents.movie",
|
||||||
scanner: "Plex Movie",
|
scanner: "Plex Movie",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "c3d4e5f67890a1b2",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394005,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476200,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047130,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 6379184,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -106,13 +111,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.movie",
|
agent: "tv.plex.agents.movie",
|
||||||
scanner: "Plex Movie",
|
scanner: "Plex Movie",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "d4e5f67890a1b2c3",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394010,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476302,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047135,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 5293874,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -138,13 +143,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.movie",
|
agent: "tv.plex.agents.movie",
|
||||||
scanner: "Plex Movie",
|
scanner: "Plex Movie",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "e5f67890a1b2c3d4",
|
uuid: randUUID(),
|
||||||
updatedAt: 1689075000,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1689075000,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047145,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 5182738,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -166,13 +171,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "com.plexapp.agents.hama",
|
agent: "com.plexapp.agents.hama",
|
||||||
scanner: "Plex Series Scanner",
|
scanner: "Plex Series Scanner",
|
||||||
language: "en",
|
language: "en",
|
||||||
uuid: "f67890a1b2c3d4e5",
|
uuid: randUUID(),
|
||||||
updatedAt: 1684970001,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476000,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047110,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 8379201,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -194,13 +199,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "nl-NL",
|
language: "nl-NL",
|
||||||
uuid: "67890a1b2c3d4e5f",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394002,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1680007400,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047125,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 5948203,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -222,13 +227,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "nl-NL",
|
language: "nl-NL",
|
||||||
uuid: "890a1b2c3d4e5f67",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394007,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1601860600,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047145,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 6283720,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -250,13 +255,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "a1b2c3d4e5f67890",
|
uuid: randUUID(),
|
||||||
updatedAt: 1728394003,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476100,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047150,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 6472184,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -278,13 +283,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "b2c3d4e5f67890a1",
|
uuid: randUUID(),
|
||||||
updatedAt: 1689076000,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1689076000,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047155,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 4920835,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -306,13 +311,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "c3d4e5f67890a1b2",
|
uuid: randUUID(),
|
||||||
updatedAt: 1689077000,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1689077000,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047155,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 5309283,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -334,13 +339,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.series",
|
agent: "tv.plex.agents.series",
|
||||||
scanner: "Plex TV Series",
|
scanner: "Plex TV Series",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "d4e5f67890a1b2c3",
|
uuid: randUUID(),
|
||||||
updatedAt: 1689078000,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1626704821,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047170,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 7291885,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -362,13 +367,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "tv.plex.agents.music",
|
agent: "tv.plex.agents.music",
|
||||||
scanner: "Plex Music",
|
scanner: "Plex Music",
|
||||||
language: "en-US",
|
language: "en-US",
|
||||||
uuid: "e5f67890a1b2c3d4",
|
uuid: randUUID(),
|
||||||
updatedAt: 1684974922,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598476740,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047140,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 7204063,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -390,13 +395,13 @@ describe("GET /library/sections", () => {
|
|||||||
agent: "com.plexapp.agents.none",
|
agent: "com.plexapp.agents.none",
|
||||||
scanner: "Plex Video Files Scanner",
|
scanner: "Plex Video Files Scanner",
|
||||||
language: "xn",
|
language: "xn",
|
||||||
uuid: "f67890a1b2c3d4e5",
|
uuid: randUUID(),
|
||||||
updatedAt: 1684974733,
|
updatedAt: randPlexUnixEpoch(),
|
||||||
createdAt: 1598475949,
|
createdAt: randPlexUnixEpoch(),
|
||||||
scannedAt: 1893047123,
|
scannedAt: randPlexUnixEpoch(),
|
||||||
content: true,
|
content: true,
|
||||||
directory: true,
|
directory: true,
|
||||||
contentChangedAt: 3828909,
|
contentChangedAt: randRelativeSeconds(),
|
||||||
hidden: 0,
|
hidden: 0,
|
||||||
Location: [
|
Location: [
|
||||||
{
|
{
|
||||||
@@ -409,6 +414,138 @@ describe("GET /library/sections", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateResponseSpec("/library/sections", "get", 200, response)
|
||||||
|
})
|
||||||
|
it("should validate the 200 response when the API spec is valid", () => {
|
||||||
|
const response = {
|
||||||
|
MediaContainer: {
|
||||||
|
size: 5,
|
||||||
|
allowSync: false,
|
||||||
|
title1: "Plex Library",
|
||||||
|
Directory: [
|
||||||
|
{
|
||||||
|
allowSync: false,
|
||||||
|
art: "/:/resources/movie-fanart.jpg",
|
||||||
|
composite: "/library/sections/4/composite/1743766611",
|
||||||
|
filters: true,
|
||||||
|
refreshing: false,
|
||||||
|
thumb: "/:/resources/movie.png",
|
||||||
|
key: "4",
|
||||||
|
type: "movie",
|
||||||
|
title: "Kids Movies",
|
||||||
|
agent: "tv.plex.agents.movie",
|
||||||
|
scanner: "Plex Movie",
|
||||||
|
language: "en-US",
|
||||||
|
uuid: randUUID(),
|
||||||
|
updatedAt: randPlexUnixEpoch(),
|
||||||
|
createdAt: randPlexUnixEpoch(),
|
||||||
|
scannedAt: randPlexUnixEpoch(),
|
||||||
|
content: true,
|
||||||
|
directory: true,
|
||||||
|
contentChangedAt: randRelativeSeconds(),
|
||||||
|
hidden: 0,
|
||||||
|
Location: [{ id: 50, path: "/mnt/Media/Kids/Movies" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowSync: false,
|
||||||
|
art: "/:/resources/movie-fanart.jpg",
|
||||||
|
composite: "/library/sections/3/composite/1743769012",
|
||||||
|
filters: true,
|
||||||
|
refreshing: false,
|
||||||
|
thumb: "/:/resources/movie.png",
|
||||||
|
key: "3",
|
||||||
|
type: "movie",
|
||||||
|
title: "Movies",
|
||||||
|
agent: "tv.plex.agents.movie",
|
||||||
|
scanner: "Plex Movie",
|
||||||
|
language: "en-US",
|
||||||
|
uuid: randUUID(),
|
||||||
|
updatedAt: randPlexUnixEpoch(),
|
||||||
|
createdAt: randPlexUnixEpoch(),
|
||||||
|
scannedAt: randPlexUnixEpoch(),
|
||||||
|
content: true,
|
||||||
|
directory: true,
|
||||||
|
contentChangedAt: randRelativeSeconds(),
|
||||||
|
hidden: 0,
|
||||||
|
Location: [{ id: 31, path: "/mnt/Movies_1" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowSync: false,
|
||||||
|
art: "/:/resources/show-fanart.jpg",
|
||||||
|
composite: "/library/sections/13/composite/1743768412",
|
||||||
|
filters: true,
|
||||||
|
refreshing: false,
|
||||||
|
thumb: "/:/resources/show.png",
|
||||||
|
key: "13",
|
||||||
|
type: "show",
|
||||||
|
title: "Kids TV Shows",
|
||||||
|
agent: "tv.plex.agents.series",
|
||||||
|
scanner: "Plex TV Series",
|
||||||
|
language: "en-US",
|
||||||
|
uuid: randUUID(),
|
||||||
|
updatedAt: randPlexUnixEpoch(),
|
||||||
|
createdAt: randPlexUnixEpoch(),
|
||||||
|
scannedAt: randPlexUnixEpoch(),
|
||||||
|
content: true,
|
||||||
|
directory: true,
|
||||||
|
contentChangedAt: randRelativeSeconds(),
|
||||||
|
hidden: 0,
|
||||||
|
Location: [{ id: 51, path: "/mnt/Media/Kids/TV Shows" }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowSync: false,
|
||||||
|
art: "/:/resources/show-fanart.jpg",
|
||||||
|
composite: "/library/sections/1/composite/1743772322",
|
||||||
|
filters: true,
|
||||||
|
refreshing: false,
|
||||||
|
thumb: "/:/resources/show.png",
|
||||||
|
key: "1",
|
||||||
|
type: "show",
|
||||||
|
title: "TV Shows",
|
||||||
|
agent: "tv.plex.agents.series",
|
||||||
|
scanner: "Plex TV Series",
|
||||||
|
language: "en-US",
|
||||||
|
uuid: randUUID(),
|
||||||
|
updatedAt: randPlexUnixEpoch(),
|
||||||
|
createdAt: randPlexUnixEpoch(),
|
||||||
|
scannedAt: randPlexUnixEpoch(),
|
||||||
|
content: true,
|
||||||
|
directory: true,
|
||||||
|
contentChangedAt: randRelativeSeconds(),
|
||||||
|
hidden: 0,
|
||||||
|
Location: [
|
||||||
|
{ id: 59, path: "/mnt/TV_3" },
|
||||||
|
{ id: 19, path: "/mnt/TV_1" },
|
||||||
|
{ id: 20, path: "/mnt/TV_2" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowSync: false,
|
||||||
|
art: "/:/resources/artist-fanart.jpg",
|
||||||
|
composite: "/library/sections/5/composite/1743766611",
|
||||||
|
filters: true,
|
||||||
|
refreshing: false,
|
||||||
|
thumb: "/:/resources/artist.png",
|
||||||
|
key: "5",
|
||||||
|
type: "artist",
|
||||||
|
title: "Audiobooks",
|
||||||
|
agent: "tv.plex.agents.music",
|
||||||
|
scanner: "Plex Music",
|
||||||
|
language: "en-US",
|
||||||
|
uuid: randUUID(),
|
||||||
|
updatedAt: randPlexUnixEpoch(),
|
||||||
|
createdAt: randPlexUnixEpoch(),
|
||||||
|
scannedAt: randPlexUnixEpoch(),
|
||||||
|
content: true,
|
||||||
|
directory: true,
|
||||||
|
contentChangedAt: randRelativeSeconds(),
|
||||||
|
hidden: 1,
|
||||||
|
Location: [{ id: 49, path: "/mnt/Media/Audiobooks" }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
validateResponseSpec("/library/sections", "get", 200, response)
|
validateResponseSpec("/library/sections", "get", 200, response)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import PMSSpec from "../../output/plex-media-server-spec-dereferenced.yaml"
|
|||||||
import Ajv from "ajv"
|
import Ajv from "ajv"
|
||||||
import addFormats from "ajv-formats"
|
import addFormats from "ajv-formats"
|
||||||
import { expect } from "vitest"
|
import { expect } from "vitest"
|
||||||
import { merge } from "lodash-es"
|
import { isArray, merge } from "lodash-es"
|
||||||
import { xml2json } from "xml-js"
|
import { xml2json } from "xml-js"
|
||||||
/**
|
/**
|
||||||
* Validate a response against the OpenAPI spec
|
* Validate a response against the OpenAPI spec
|
||||||
@@ -57,7 +57,19 @@ export function validateResponseSpec(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!validate) {
|
if (!validate) {
|
||||||
|
for (const error of ajv.errors) {
|
||||||
|
if (
|
||||||
|
error.hasOwnProperty("params") &&
|
||||||
|
error.params.hasOwnProperty("allowedValues") &&
|
||||||
|
isArray(error.params.allowedValues)
|
||||||
|
) {
|
||||||
|
// Format the allowedValues to be a string to make it visible in the error message
|
||||||
|
error.params.allowedValues = error.params.allowedValues.join(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error(ajv.errors)
|
console.error(ajv.errors)
|
||||||
|
console.error(JSON.stringify(jsonResponse, null, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(ajv.errors).toBe(null)
|
expect(ajv.errors).toBe(null)
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export * from "./import.js"
|
export * from "./import.js"
|
||||||
|
export * from "./mocks.js"
|
||||||
|
|||||||
14
tests/utils/mocks.ts
Normal file
14
tests/utils/mocks.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { randNumber, randRecentDate, randUuid } from "@ngneat/falso"
|
||||||
|
|
||||||
|
export function randUUID() {
|
||||||
|
return randUuid()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function randPlexUnixEpoch() {
|
||||||
|
const date = randRecentDate()
|
||||||
|
return Math.floor(date.getTime() / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function randRelativeSeconds() {
|
||||||
|
return randNumber({ min: 1000, max: 100000 })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user