made unit testing xml compatible

This commit is contained in:
JasonLandbridge
2025-02-05 12:53:53 +01:00
parent aea7a4bf90
commit 401efaf340
4 changed files with 48 additions and 9 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -38,7 +38,8 @@
"swagger-cli": "^4.0.4",
"typescript": "^5.5.4",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.0.5"
"vitest": "^2.0.5",
"xml-js": "^1.6.11"
},
"dependencies": {
"ajv": "^8.17.1",

View File

@@ -97,8 +97,8 @@ get:
description: "User's email address."
example: "zgfuc7krcqfimrmb9lsl5j@protonmail.com"
recommendationsPlaylistId:
type: string
description: "ID of the user's recommendation playlist."
type: ["null", string]
example: ""
thumb:
type: string
@@ -133,19 +133,19 @@ get:
- description: "Indicates if the user can manage subtitles."
- $ref: "../../models/common/PlexBoolean.yaml"
filterAll:
type: string
type: ["null", string]
description: "Filters applied for all content."
example: ""
filterMovies:
type: string
type: ["null", string]
description: "Filters applied for movies."
example: ""
filterMusic:
type: string
type: ["null", string]
description: "Filters applied for music."
example: ""
filterPhotos:
type: string
type: ["null", string]
description: "Filters applied for photos."
example: ""
filterTelevision:

View File

@@ -3,6 +3,7 @@ import Ajv from "ajv"
import addFormats from "ajv-formats"
import { expect } from "vitest"
import { merge } from "lodash-es"
import { xml2json } from "xml-js"
/**
* Validate a response against the OpenAPI spec
* NOTE: It accounts for the following scenarios:
@@ -13,12 +14,14 @@ import { merge } from "lodash-es"
* @param type
* @param statusCode
* @param response
* @param responseType
*/
export function validateResponseSpec(
path: string,
type: "get" | "post" | "delete",
statusCode: number,
response: any
response: any,
responseType: "json" | "xml" = "json"
): void {
const ajv = new Ajv({ allErrors: true, strict: false })
@@ -30,9 +33,28 @@ export function validateResponseSpec(
addFormats(ajv)
// Convert JSONPath to JSON Pointer
const pathPointer = `/paths/${path.replace(/\//g, `~1`)}/${type}/responses/${statusCode}/content/application~1json/schema`
const pathPointer = `/paths/${path.replace(/\//g, `~1`)}/${type}/responses/${statusCode}/content/application~1${responseType}/schema`
const validate = ajv.validate({ $ref: "API.yaml#" + pathPointer }, response)
let jsonResponse = response
if (responseType === "xml") {
const x = response.replace(/=""/g, '="a"')
jsonResponse = flattenAttributes(
JSON.parse(
xml2json(x, {
compact: true,
ignoreDeclaration: true,
nativeType: true,
// @ts-ignore
nativeTypeAttributes: true
})
)
)
}
const validate = ajv.validate(
{ $ref: "API.yaml#" + pathPointer },
jsonResponse
)
if (!validate) {
console.error(ajv.errors)
@@ -78,3 +100,19 @@ function addAdditionalProperties(schema) {
}
}
}
function flattenAttributes(obj: any): any {
if (Array.isArray(obj)) {
return obj.map(flattenAttributes)
} else if (typeof obj === "object" && obj !== null) {
if ("_attributes" in obj) {
Object.assign(obj, obj._attributes)
delete obj._attributes
}
// Recursively process all properties
for (const key in obj) {
obj[key] = flattenAttributes(obj[key])
}
}
return obj
}