🧪 Add test for Plex

This commit is contained in:
Manuel
2023-03-20 23:17:17 +01:00
parent 0b237f27f7
commit 6633d21788
8 changed files with 192 additions and 11 deletions

View File

@@ -37,5 +37,6 @@ module.exports = {
max: 3,
},
],
'testing-library/no-node-access': ['error', { allowContainerFirstChild: true }],
},
};

View File

@@ -99,7 +99,8 @@
"turbo": "^1.7.4",
"typescript": "^4.7.4",
"video.js": "^8.0.3",
"vitest": "^0.29.3"
"vitest": "^0.29.3",
"vitest-fetch-mock": "^0.2.2"
},
"resolutions": {
"@types/react": "17.0.2",

8
setupVitest.ts Normal file
View File

@@ -0,0 +1,8 @@
//setupVitest.js or similar file
import createFetchMock from 'vitest-fetch-mock';
import { vi } from 'vitest';
const fetchMocker = createFetchMock(vi);
// sets globalThis.fetch and globalThis.fetchMock to our mocked version
fetchMocker.enableMocks();

View File

@@ -2,15 +2,51 @@ import { render } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { AppAvatar } from './AppAvatar';
describe(AppAvatar.name, () => {
it.concurrent('display placeholder when no url', () => {
describe('AppAvatar', () => {
it('display placeholder when no url', () => {
const { container } = render(<AppAvatar iconUrl="" color="blue" />);
expect(container.firstElementChild).not.toBeNull();
expect(container.firstElementChild!.className).contain('mantine-Avatar-root');
expect(container.firstChild).toMatchInlineSnapshot(`
<div
class="mantine-Avatar-root mantine-1rb4n7x"
>
<div
class="mantine-lgdaxf mantine-Avatar-placeholder"
>
<svg
class="mantine-rsrrdl mantine-Avatar-placeholderIcon"
fill="none"
height="15"
viewBox="0 0 15 15"
width="15"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M0.877014 7.49988C0.877014 3.84219 3.84216 0.877045 7.49985 0.877045C11.1575 0.877045 14.1227 3.84219 14.1227 7.49988C14.1227 11.1575 11.1575 14.1227 7.49985 14.1227C3.84216 14.1227 0.877014 11.1575 0.877014 7.49988ZM7.49985 1.82704C4.36683 1.82704 1.82701 4.36686 1.82701 7.49988C1.82701 8.97196 2.38774 10.3131 3.30727 11.3213C4.19074 9.94119 5.73818 9.02499 7.50023 9.02499C9.26206 9.02499 10.8093 9.94097 11.6929 11.3208C12.6121 10.3127 13.1727 8.97172 13.1727 7.49988C13.1727 4.36686 10.6328 1.82704 7.49985 1.82704ZM10.9818 11.9787C10.2839 10.7795 8.9857 9.97499 7.50023 9.97499C6.01458 9.97499 4.71624 10.7797 4.01845 11.9791C4.97952 12.7272 6.18765 13.1727 7.49985 13.1727C8.81227 13.1727 10.0206 12.727 10.9818 11.9787ZM5.14999 6.50487C5.14999 5.207 6.20212 4.15487 7.49999 4.15487C8.79786 4.15487 9.84999 5.207 9.84999 6.50487C9.84999 7.80274 8.79786 8.85487 7.49999 8.85487C6.20212 8.85487 5.14999 7.80274 5.14999 6.50487ZM7.49999 5.10487C6.72679 5.10487 6.09999 5.73167 6.09999 6.50487C6.09999 7.27807 6.72679 7.90487 7.49999 7.90487C8.27319 7.90487 8.89999 7.27807 8.89999 6.50487C8.89999 5.73167 8.27319 5.10487 7.49999 5.10487Z"
fill="currentColor"
fill-rule="evenodd"
/>
</svg>
</div>
</div>
`);
});
const svgElement = container.querySelector('svg');
expect(svgElement).not.toBeNull();
expect(svgElement?.getAttribute('fill')).not.toBeNull();
it('display placeholder when valid url', () => {
const { container } = render(
<AppAvatar iconUrl="https://homarr.dev/img/logo.svg" color="red" />
);
expect(container.firstChild).toMatchInlineSnapshot(`
<div
class="mantine-Avatar-root mantine-11ss4u9"
>
<img
class="mantine-1trwvlz mantine-Avatar-image"
src="https://homarr.dev/img/logo.svg"
/>
</div>
`);
});
});

View File

@@ -9,7 +9,7 @@ export const getServerSideTranslations = async (
res?: ServerResponse,
) => {
if (!req || !res) {
return await serverSideTranslations(
return serverSideTranslations(
requestLocale ?? 'en',
namespaces
);
@@ -17,7 +17,7 @@ export const getServerSideTranslations = async (
const configLocale = getCookie('config-locale', { req, res });
return await serverSideTranslations(
return serverSideTranslations(
(configLocale ?? requestLocale ?? 'en') as string,
namespaces
);

View File

@@ -0,0 +1,73 @@
import { describe, expect, it } from 'vitest';
import 'vitest-fetch-mock';
import { PlexClient } from './plexClient';
const mockResponse = `<MediaContainer size="1">
<Video addedAt="0000000" art="/library/metadata/2/art/00000000" audienceRating="0.0" audienceRatingImage="niceImage" chapterSource="media" contentRating="TV-PG" duration="6262249" guid="plex://movie/0000000000000000" key="/library/metadata/2" lastViewedAt="0000000" librarySectionID="1" librarySectionKey="/library/sections/1" librarySectionTitle="Movies" originalTitle="00000000000000" originallyAvailableAt="0000-00-00" rating="0.0" ratingImage="ratingimage" ratingKey="2" sessionKey="1" studio="Example Studio" summary="Lorem Ispum dolor sit amet" tagline="Yep" thumb="/library/metadata/2/thumb/0000000" title="A long title" titleSort="A short title" type="movie" updatedAt="000000" viewOffset="0" year="0000">
<Media audioProfile="ma" id="2" videoProfile="high" audioChannels="2" audioCodec="aac" bitrate="20231" container="mp4" duration="6262249" height="1080" optimizedForStreaming="1" protocol="dash" videoCodec="h264" videoFrameRate="24p" videoResolution="1080p" width="1920" selected="1">
<Part audioProfile="ma" hasThumbnail="1" id="2" videoProfile="high" bitrate="20231" container="mp4" duration="6262249" height="1080" optimizedForStreaming="1" protocol="dash" width="1920" decision="transcode" selected="1">
<Stream bitDepth="8" bitrate="19975" chromaLocation="left" chromaSubsampling="4:2:0" codec="h264" codedHeight="1088" codedWidth="1920" default="1" displayTitle="XXXX" extendedDisplayTitle="Yes" frameRate="23.975999832153320" hasScalingMatrix="0" height="1080" id="4" level="41" profile="high" refFrames="4" scanType="progressive" streamType="1" title="Example" width="1920" decision="copy" location="segments-video"/>
<Stream bitrate="256" bitrateMode="cbr" channels="2" codec="aac" default="1" displayTitle="Not Existing" extendedDisplayTitle="Yes, really" id="5" language="Yep" languageCode="jpn" languageTag="ch" selected="1" streamType="2" decision="transcode" location="segments-audio"/>
</Part>
</Media>
<Genre count="13" filter="genre=48" id="48" tag="Drama"/>
<Genre count="8" filter="genre=104" id="104" tag="Adventure"/>
<User id="1" thumb="https://google.com" title="example_usr"/>
<Player address="0.0.0.0" device="Windows" machineIdentifier="72483785378573857385" model="bundled" platform="Chrome" platformVersion="111.0" product="Plex Web" profile="Web" state="paused" title="Chrome" version="0.000.0" local="1" relayed="0" secure="1" userID="1"/>
<Session id="2894294r2jf2038fj3098jgf3gt" bandwidth="21560" location="lan"/>
<TranscodeSession key="/transcode/sessions/example-session" throttled="0" complete="0" progress="0" size="-22" speed="18.600000381469727" error="0" duration="100" remaining="70" context="streaming" sourceVideoCodec="h264" sourceAudioCodec="dca" videoDecision="copy" audioDecision="transcode" protocol="dash" container="mp4" videoCodec="h264" audioCodec="aac" audioChannels="2" width="1920" height="1080" transcodeHwRequested="0" transcodeHwFullPipeline="0" timeStamp="1679349635.2791338" maxOffsetAvailable="104.27" minOffsetAvailable="84.166999816894531"/>
</Video>
</MediaContainer>`;
describe('Plex SDK', () => {
it('abc', async () => {
// arrange
const client = new PlexClient('https://plex', 'MY_TOKEN');
fetchMock.mockResponseOnce(mockResponse);
// act
const response = await client.getSessions();
// assert
expect(fetchMock.requests().length).toBe(1);
expect(fetchMock.requests()[0].url).toBe('https://plex/status/sessions?X-Plex-Token=MY_TOKEN');
expect(response).not.toBeNull();
expect(response.length).toBe(1);
expect(response[0].id).toBe('2894294r2jf2038fj3098jgf3gt');
expect(response[0].username).toBe('example_usr');
expect(response[0].userProfilePicture).toBe('https://google.com');
expect(response[0].sessionName).toBe('Plex Web (Chrome)');
expect(response[0].currentlyPlaying).toMatchObject({
name: 'A long title',
type: 'movie',
metadata: {
video: {
bitrate: '20231',
height: '1080',
videoCodec: 'h264',
videoFrameRate: '24p',
width: '1920',
},
audio: { audioChannels: '2', audioCodec: 'aac' },
transcoding: {
audioChannels: '2',
audioCodec: 'aac',
audioDecision: 'transcode',
container: 'mp4',
context: 'streaming',
duration: '100',
error: false,
height: '1080',
sourceAudioCodec: 'dca',
sourceVideoCodec: 'h264',
timeStamp: '1679349635.2791338',
transcodeHwRequested: false,
videoCodec: 'h264',
videoDecision: 'copy',
width: '1920',
},
},
});
});
});

View File

@@ -12,6 +12,9 @@ export default defineConfig({
reporter: ['html'],
all: true,
exclude: ['.next/', '.yarn/', 'data/']
}
},
setupFiles: [
"./setupVitest.ts"
]
},
});

View File

@@ -3145,6 +3145,15 @@ __metadata:
languageName: node
linkType: hard
"cross-fetch@npm:^3.0.6":
version: 3.1.5
resolution: "cross-fetch@npm:3.1.5"
dependencies:
node-fetch: 2.6.7
checksum: f6b8c6ee3ef993ace6277fd789c71b6acf1b504fd5f5c7128df4ef2f125a429e29cd62dc8c127523f04a5f2fa4771ed80e3f3d9695617f441425045f505cf3bb
languageName: node
linkType: hard
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@@ -4932,6 +4941,7 @@ __metadata:
uuid: ^8.3.2
video.js: ^8.0.3
vitest: ^0.29.3
vitest-fetch-mock: ^0.2.2
xml-js: ^1.6.11
yarn: ^1.22.19
zustand: ^4.1.4
@@ -6273,6 +6283,20 @@ __metadata:
languageName: node
linkType: hard
"node-fetch@npm:2.6.7":
version: 2.6.7
resolution: "node-fetch@npm:2.6.7"
dependencies:
whatwg-url: ^5.0.0
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b
languageName: node
linkType: hard
"node-gyp@npm:latest":
version: 9.3.1
resolution: "node-gyp@npm:9.3.1"
@@ -7868,6 +7892,13 @@ __metadata:
languageName: node
linkType: hard
"tr46@npm:~0.0.3":
version: 0.0.3
resolution: "tr46@npm:0.0.3"
checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3
languageName: node
linkType: hard
"tsconfig-paths@npm:^3.14.1":
version: 3.14.1
resolution: "tsconfig-paths@npm:3.14.1"
@@ -8304,6 +8335,17 @@ __metadata:
languageName: node
linkType: hard
"vitest-fetch-mock@npm:^0.2.2":
version: 0.2.2
resolution: "vitest-fetch-mock@npm:0.2.2"
dependencies:
cross-fetch: ^3.0.6
peerDependencies:
vitest: ">=0.16.0"
checksum: fa160f301171cd45dbf7d782880b6b6063fc74b9dd1965ef9206545e812ca8696e6be76662afbac822c6bf850fbb66cf8fb066af646e0e159f5a87ab25c97a02
languageName: node
linkType: hard
"vitest@npm:^0.29.3":
version: 0.29.3
resolution: "vitest@npm:0.29.3"
@@ -8378,6 +8420,13 @@ __metadata:
languageName: node
linkType: hard
"webidl-conversions@npm:^3.0.0":
version: 3.0.1
resolution: "webidl-conversions@npm:3.0.1"
checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c
languageName: node
linkType: hard
"webidl-conversions@npm:^7.0.0":
version: 7.0.0
resolution: "webidl-conversions@npm:7.0.0"
@@ -8430,6 +8479,16 @@ __metadata:
languageName: node
linkType: hard
"whatwg-url@npm:^5.0.0":
version: 5.0.0
resolution: "whatwg-url@npm:5.0.0"
dependencies:
tr46: ~0.0.3
webidl-conversions: ^3.0.0
checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c
languageName: node
linkType: hard
"which-boxed-primitive@npm:^1.0.2":
version: 1.0.2
resolution: "which-boxed-primitive@npm:1.0.2"