feat(integrations): add mock integration (#3505)
This commit is contained in:
74
packages/integrations/src/mock/data/calendar.ts
Normal file
74
packages/integrations/src/mock/data/calendar.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import type { ICalendarIntegration } from "../../interfaces/calendar/calendar-integration";
|
||||
import type { CalendarEvent } from "../../interfaces/calendar/calendar-types";
|
||||
|
||||
export class CalendarMockService implements ICalendarIntegration {
|
||||
public async getCalendarEventsAsync(start: Date, end: Date, _includeUnmonitored: boolean): Promise<CalendarEvent[]> {
|
||||
const result = [homarrMeetup(start, end), titanicRelease(start, end), seriesRelease(start, end)];
|
||||
return await Promise.resolve(result);
|
||||
}
|
||||
}
|
||||
|
||||
const homarrMeetup = (start: Date, end: Date): CalendarEvent => ({
|
||||
name: "Homarr Meetup",
|
||||
subName: "",
|
||||
description: "Yearly meetup of the Homarr community",
|
||||
date: randomDateBetween(start, end),
|
||||
links: [
|
||||
{
|
||||
href: "https://homarr.dev",
|
||||
name: "Homarr",
|
||||
logo: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/homarr.svg",
|
||||
color: "#000000",
|
||||
notificationColor: "#fa5252",
|
||||
isDark: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const titanicRelease = (start: Date, end: Date): CalendarEvent => ({
|
||||
name: "Titanic",
|
||||
subName: "A classic movie",
|
||||
description: "A tragic love story set on the ill-fated RMS Titanic.",
|
||||
date: randomDateBetween(start, end),
|
||||
thumbnail: "https://image.tmdb.org/t/p/original/5bTWA20cL9LCIGNpde4Epc2Ijzn.jpg",
|
||||
mediaInformation: {
|
||||
type: "movie",
|
||||
},
|
||||
links: [
|
||||
{
|
||||
href: "https://www.imdb.com/title/tt0120338/",
|
||||
name: "IMDb",
|
||||
color: "#f5c518",
|
||||
isDark: false,
|
||||
logo: "/images/apps/imdb.svg",
|
||||
notificationColor: "cyan",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const seriesRelease = (start: Date, end: Date): CalendarEvent => ({
|
||||
name: "The Mandalorian",
|
||||
subName: "A Star Wars Series",
|
||||
description: "A lone bounty hunter in the outer reaches of the galaxy.",
|
||||
date: randomDateBetween(start, end),
|
||||
thumbnail: "https://image.tmdb.org/t/p/original/ztvm7C7hiUpS3CZRXFmJxljICzK.jpg",
|
||||
mediaInformation: {
|
||||
type: "tv",
|
||||
seasonNumber: 1,
|
||||
episodeNumber: 1,
|
||||
},
|
||||
links: [
|
||||
{
|
||||
href: "https://www.imdb.com/title/tt8111088/",
|
||||
name: "IMDb",
|
||||
color: "#f5c518",
|
||||
isDark: false,
|
||||
logo: "/images/apps/imdb.svg",
|
||||
notificationColor: "blue",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
function randomDateBetween(start: Date, end: Date): Date {
|
||||
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
|
||||
}
|
||||
100
packages/integrations/src/mock/data/cluster-health-monitoring.ts
Normal file
100
packages/integrations/src/mock/data/cluster-health-monitoring.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import type { IClusterHealthMonitoringIntegration } from "../../interfaces/health-monitoring/health-monitoring-integration";
|
||||
import type { ClusterHealthMonitoring } from "../../types";
|
||||
|
||||
export class ClusterHealthMonitoringMockService implements IClusterHealthMonitoringIntegration {
|
||||
public async getClusterInfoAsync(): Promise<ClusterHealthMonitoring> {
|
||||
return Promise.resolve({
|
||||
nodes: Array.from({ length: 5 }, (_, index) => ClusterHealthMonitoringMockService.createNode(index)),
|
||||
lxcs: Array.from({ length: 3 }, (_, index) => ClusterHealthMonitoringMockService.createLxc(index)),
|
||||
vms: Array.from({ length: 7 }, (_, index) => ClusterHealthMonitoringMockService.createVm(index)),
|
||||
storages: Array.from({ length: 9 }, (_, index) => ClusterHealthMonitoringMockService.createStorage(index)),
|
||||
});
|
||||
}
|
||||
|
||||
private static createNode(index: number): ClusterHealthMonitoring["nodes"][number] {
|
||||
return {
|
||||
id: index.toString(),
|
||||
name: `Node ${index}`,
|
||||
isRunning: Math.random() > 0.1, // 90% chance of being running
|
||||
node: `Node ${index}`,
|
||||
status: Math.random() > 0.5 ? "online" : "offline",
|
||||
type: "node",
|
||||
uptime: Math.floor(Math.random() * 1000000), // Randomly generate uptime in seconds
|
||||
haState: null,
|
||||
...this.createResourceUsage(),
|
||||
};
|
||||
}
|
||||
|
||||
private static createResourceUsage() {
|
||||
const totalMemory = Math.pow(2, Math.floor(Math.random() * 6) + 1) * 1024 * 1024 * 1024; // Randomly generate between 2GB and 64GB
|
||||
const totalStorage = Math.pow(2, Math.floor(Math.random() * 6) + 1) * 1024 * 1024 * 1024; // Randomly generate between 2GB and 64GB
|
||||
|
||||
return {
|
||||
cpu: {
|
||||
cores: Math.pow(2, Math.floor(Math.random() * 5) + 1), // Randomly generate between 2 and 32 cores,
|
||||
utilization: Math.random(),
|
||||
},
|
||||
memory: {
|
||||
total: totalMemory,
|
||||
used: Math.floor(Math.random() * totalMemory), // Randomly generate used memory
|
||||
},
|
||||
network: {
|
||||
in: Math.floor(Math.random() * 1000), // Randomly generate network in
|
||||
out: Math.floor(Math.random() * 1000), // Randomly generate network out
|
||||
},
|
||||
storage: {
|
||||
total: totalStorage,
|
||||
used: Math.floor(Math.random() * totalStorage), // Randomly generate used storage
|
||||
read: Math.floor(Math.random() * 1000), // Randomly generate read
|
||||
write: Math.floor(Math.random() * 1000), // Randomly generate write
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private static createVm(index: number): ClusterHealthMonitoring["vms"][number] {
|
||||
return {
|
||||
id: index.toString(),
|
||||
name: `VM ${index}`,
|
||||
vmId: index + 1000, // VM IDs start from 1000
|
||||
...this.createResourceUsage(),
|
||||
haState: null,
|
||||
isRunning: Math.random() > 0.1, // 90% chance of being running
|
||||
node: `Node ${Math.floor(index / 2)}`, // Assign to a node
|
||||
status: Math.random() > 0.5 ? "online" : "offline",
|
||||
type: "qemu",
|
||||
uptime: Math.floor(Math.random() * 1000000), // Randomly generate uptime in seconds
|
||||
};
|
||||
}
|
||||
|
||||
private static createLxc(index: number): ClusterHealthMonitoring["lxcs"][number] {
|
||||
return {
|
||||
id: index.toString(),
|
||||
name: `LXC ${index}`,
|
||||
vmId: index + 2000, // LXC IDs start from 2000
|
||||
...this.createResourceUsage(),
|
||||
haState: null,
|
||||
isRunning: Math.random() > 0.1, // 90% chance of being running
|
||||
node: `Node ${Math.floor(index / 2)}`, // Assign to a node
|
||||
status: Math.random() > 0.5 ? "online" : "offline",
|
||||
type: "lxc",
|
||||
uptime: Math.floor(Math.random() * 1000000), // Randomly generate uptime in seconds
|
||||
};
|
||||
}
|
||||
|
||||
private static createStorage(index: number): ClusterHealthMonitoring["storages"][number] {
|
||||
const total = Math.pow(2, Math.floor(Math.random() * 6) + 1) * 1024 * 1024 * 1024; // Randomly generate between 2GB and 64GB
|
||||
|
||||
return {
|
||||
id: index.toString(),
|
||||
name: `Storage ${index}`,
|
||||
isRunning: Math.random() > 0.1, // 90% chance of being running
|
||||
node: `Node ${Math.floor(index / 2)}`, // Assign to a node
|
||||
status: Math.random() > 0.5 ? "online" : "offline",
|
||||
isShared: Math.random() > 0.5, // 50% chance of being shared
|
||||
storagePlugin: `Plugin ${index}`,
|
||||
total,
|
||||
used: Math.floor(Math.random() * total), // Randomly generate used storage
|
||||
type: "storage",
|
||||
};
|
||||
}
|
||||
}
|
||||
26
packages/integrations/src/mock/data/dns-hole.ts
Normal file
26
packages/integrations/src/mock/data/dns-hole.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { DnsHoleSummaryIntegration } from "../../interfaces/dns-hole-summary/dns-hole-summary-integration";
|
||||
import type { DnsHoleSummary } from "../../types";
|
||||
|
||||
export class DnsHoleMockService implements DnsHoleSummaryIntegration {
|
||||
private static isEnabled = true;
|
||||
|
||||
public async getSummaryAsync(): Promise<DnsHoleSummary> {
|
||||
const blocked = Math.floor(Math.random() * Math.pow(10, 4)) + 1; // Ensure we never devide by zero
|
||||
const queries = Math.max(Math.floor(Math.random() * Math.pow(10, 5)), blocked);
|
||||
return await Promise.resolve({
|
||||
status: DnsHoleMockService.isEnabled ? "enabled" : "disabled",
|
||||
domainsBeingBlocked: Math.floor(Math.random() * Math.pow(10, 6)),
|
||||
adsBlockedToday: blocked,
|
||||
adsBlockedTodayPercentage: blocked / queries,
|
||||
dnsQueriesToday: queries,
|
||||
});
|
||||
}
|
||||
public async enableAsync(): Promise<void> {
|
||||
DnsHoleMockService.isEnabled = true;
|
||||
return await Promise.resolve();
|
||||
}
|
||||
public async disableAsync(_duration?: number): Promise<void> {
|
||||
DnsHoleMockService.isEnabled = false;
|
||||
return await Promise.resolve();
|
||||
}
|
||||
}
|
||||
58
packages/integrations/src/mock/data/download.ts
Normal file
58
packages/integrations/src/mock/data/download.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import type { DownloadClientJobsAndStatus } from "../../interfaces/downloads/download-client-data";
|
||||
import type { IDownloadClientIntegration } from "../../interfaces/downloads/download-client-integration";
|
||||
import type { DownloadClientItem } from "../../interfaces/downloads/download-client-items";
|
||||
|
||||
export class DownloadClientMockService implements IDownloadClientIntegration {
|
||||
public async getClientJobsAndStatusAsync(input: { limit: number }): Promise<DownloadClientJobsAndStatus> {
|
||||
return await Promise.resolve({
|
||||
status: {
|
||||
paused: Math.random() < 0.5,
|
||||
rates: {
|
||||
down: Math.floor(Math.random() * 5000),
|
||||
up: Math.floor(Math.random() * 5000),
|
||||
},
|
||||
types: ["torrent", "usenet"],
|
||||
},
|
||||
items: Array.from({ length: 20 }, (_, index) => DownloadClientMockService.createItem(index)).slice(
|
||||
0,
|
||||
input.limit,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
public async pauseQueueAsync(): Promise<void> {
|
||||
return await Promise.resolve();
|
||||
}
|
||||
|
||||
public async pauseItemAsync(_item: DownloadClientItem): Promise<void> {
|
||||
return await Promise.resolve();
|
||||
}
|
||||
|
||||
public async resumeQueueAsync(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public async resumeItemAsync(_item: DownloadClientItem): Promise<void> {
|
||||
return await Promise.resolve();
|
||||
}
|
||||
|
||||
public async deleteItemAsync(_item: DownloadClientItem, _fromDisk: boolean): Promise<void> {
|
||||
return await Promise.resolve();
|
||||
}
|
||||
|
||||
private static createItem(index: number): DownloadClientItem {
|
||||
const progress = Math.random() < 0.5 ? Math.random() : 1;
|
||||
return {
|
||||
id: `item-${index}`,
|
||||
index,
|
||||
name: `Item ${index}`,
|
||||
type: Math.random() > 0.5 ? "torrent" : "usenet",
|
||||
progress,
|
||||
size: Math.floor(Math.random() * 10000) + 1,
|
||||
downSpeed: Math.floor(Math.random() * 5000),
|
||||
upSpeed: Math.floor(Math.random() * 5000),
|
||||
state: progress >= 1 ? "completed" : "downloading",
|
||||
time: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
23
packages/integrations/src/mock/data/indexer-manager.ts
Normal file
23
packages/integrations/src/mock/data/indexer-manager.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { IIndexerManagerIntegration } from "../../interfaces/indexer-manager/indexer-manager-integration";
|
||||
import type { Indexer } from "../../types";
|
||||
|
||||
export class IndexerManagerMockService implements IIndexerManagerIntegration {
|
||||
public async getIndexersAsync(): Promise<Indexer[]> {
|
||||
return await Promise.resolve(
|
||||
Array.from({ length: 10 }, (_, index) => IndexerManagerMockService.createIndexer(index + 1)),
|
||||
);
|
||||
}
|
||||
public async testAllAsync(): Promise<void> {
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
private static createIndexer(index: number): Indexer {
|
||||
return {
|
||||
id: index,
|
||||
name: `Mock Indexer ${index}`,
|
||||
url: `https://mock-indexer-${index}.com`,
|
||||
enabled: Math.random() > 0.2, // 80% chance of being enabled
|
||||
status: Math.random() > 0.2, // 80% chance of being active
|
||||
};
|
||||
}
|
||||
}
|
||||
97
packages/integrations/src/mock/data/media-request.ts
Normal file
97
packages/integrations/src/mock/data/media-request.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { objectEntries } from "@homarr/common";
|
||||
|
||||
import type { IMediaRequestIntegration } from "../../interfaces/media-requests/media-request-integration";
|
||||
import type { MediaInformation, MediaRequest, RequestStats, RequestUser } from "../../types";
|
||||
import { MediaAvailability, MediaRequestStatus } from "../../types";
|
||||
|
||||
export class MediaRequestMockService implements IMediaRequestIntegration {
|
||||
public async getSeriesInformationAsync(mediaType: "movie" | "tv", id: number): Promise<MediaInformation> {
|
||||
return await Promise.resolve({
|
||||
id,
|
||||
overview: `Overview of media ${id}`,
|
||||
posterPath: "https://image.tmdb.org/t/p/original/ztvm7C7hiUpS3CZRXFmJxljICzK.jpg",
|
||||
seasons:
|
||||
mediaType === "tv"
|
||||
? Array.from({ length: 3 }, (_, seasonIndex) => ({
|
||||
id: seasonIndex + 1,
|
||||
name: `Season ${seasonIndex + 1}`,
|
||||
episodeCount: Math.floor(Math.random() * 10) + 1,
|
||||
overview: `Overview of season ${seasonIndex + 1} of media ${id}`,
|
||||
}))
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
public async requestMediaAsync(_mediaType: "movie" | "tv", _id: number, _seasons?: number[]): Promise<void> {
|
||||
await Promise.resolve();
|
||||
}
|
||||
public async getRequestsAsync(): Promise<MediaRequest[]> {
|
||||
const result = await Promise.resolve(
|
||||
Array.from({ length: 10 }, (_, index) => MediaRequestMockService.createRequest(index)),
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
public async getStatsAsync(): Promise<RequestStats> {
|
||||
return await Promise.resolve({
|
||||
approved: Math.floor(Math.random() * 100),
|
||||
available: Math.floor(Math.random() * 100),
|
||||
declined: Math.floor(Math.random() * 100),
|
||||
movie: Math.floor(Math.random() * 100),
|
||||
pending: Math.floor(Math.random() * 100),
|
||||
processing: Math.floor(Math.random() * 100),
|
||||
total: Math.floor(Math.random() * 1000),
|
||||
tv: Math.floor(Math.random() * 100),
|
||||
});
|
||||
}
|
||||
public async getUsersAsync(): Promise<RequestUser[]> {
|
||||
return await Promise.resolve(Array.from({ length: 5 }, (_, index) => MediaRequestMockService.createUser(index)));
|
||||
}
|
||||
|
||||
public async approveRequestAsync(_requestId: number): Promise<void> {
|
||||
await Promise.resolve();
|
||||
}
|
||||
public async declineRequestAsync(_requestId: number): Promise<void> {
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
private static createUser(index: number): RequestUser {
|
||||
return {
|
||||
id: index,
|
||||
displayName: `User ${index}`,
|
||||
avatar: "/images/mock/avatar.jpg",
|
||||
requestCount: Math.floor(Math.random() * 100),
|
||||
link: `https://example.com/user/${index}`,
|
||||
};
|
||||
}
|
||||
|
||||
private static createRequest(index: number): MediaRequest {
|
||||
return {
|
||||
id: index,
|
||||
name: `Media Request ${index}`,
|
||||
availability: this.randomAvailability(),
|
||||
backdropImageUrl: "https://image.tmdb.org/t/p/original/ztvm7C7hiUpS3CZRXFmJxljICzK.jpg",
|
||||
posterImagePath: "https://image.tmdb.org/t/p/original/ztvm7C7hiUpS3CZRXFmJxljICzK.jpg",
|
||||
createdAt: new Date(),
|
||||
airDate: new Date(Date.now() + (Math.random() - 0.5) * 1000 * 60 * 60 * 24 * 365 * 4),
|
||||
status: this.randomStatus(),
|
||||
href: `https://example.com/media/${index}`,
|
||||
type: Math.random() > 0.5 ? "movie" : "tv",
|
||||
requestedBy: {
|
||||
avatar: "/images/mock/avatar.jpg",
|
||||
displayName: `User ${index}`,
|
||||
id: index,
|
||||
link: `https://example.com/user/${index}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private static randomAvailability(): MediaAvailability {
|
||||
const values = objectEntries(MediaAvailability).filter(([key]) => typeof key === "number");
|
||||
return values[Math.floor(Math.random() * values.length)]?.[1] ?? MediaAvailability.Available;
|
||||
}
|
||||
|
||||
private static randomStatus(): MediaRequestStatus {
|
||||
const values = objectEntries(MediaRequestStatus).filter(([key]) => typeof key === "number");
|
||||
return values[Math.floor(Math.random() * values.length)]?.[1] ?? MediaRequestStatus.PendingApproval;
|
||||
}
|
||||
}
|
||||
35
packages/integrations/src/mock/data/media-server.ts
Normal file
35
packages/integrations/src/mock/data/media-server.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { IMediaServerIntegration } from "../../interfaces/media-server/media-server-integration";
|
||||
import type { CurrentSessionsInput, StreamSession } from "../../interfaces/media-server/media-server-types";
|
||||
|
||||
export class MediaServerMockService implements IMediaServerIntegration {
|
||||
public async getCurrentSessionsAsync(options: CurrentSessionsInput): Promise<StreamSession[]> {
|
||||
return await Promise.resolve(
|
||||
Array.from({ length: 10 }, (_, index) => MediaServerMockService.createSession(index)).filter(
|
||||
(session) => !options.showOnlyPlaying || session.currentlyPlaying !== null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private static createSession(index: number): StreamSession {
|
||||
return {
|
||||
sessionId: `session-${index}`,
|
||||
sessionName: `Session ${index}`,
|
||||
user: {
|
||||
userId: `user-${index}`,
|
||||
username: `User${index}`,
|
||||
profilePictureUrl: "/images/mock/avatar.jpg",
|
||||
},
|
||||
currentlyPlaying:
|
||||
Math.random() > 0.9 // 10% chance of being null (not currently playing)
|
||||
? {
|
||||
type: "movie",
|
||||
name: `Movie ${index}`,
|
||||
seasonName: undefined,
|
||||
episodeName: null,
|
||||
albumName: null,
|
||||
episodeCount: null,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
68
packages/integrations/src/mock/data/media-transcoding.ts
Normal file
68
packages/integrations/src/mock/data/media-transcoding.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import type { IMediaTranscodingIntegration } from "../../interfaces/media-transcoding/media-transcoding-integration";
|
||||
import type {
|
||||
TdarrQueue,
|
||||
TdarrStatistics,
|
||||
TdarrWorker,
|
||||
} from "../../interfaces/media-transcoding/media-transcoding-types";
|
||||
|
||||
export class MediaTranscodingMockService implements IMediaTranscodingIntegration {
|
||||
public async getStatisticsAsync(): Promise<TdarrStatistics> {
|
||||
return await Promise.resolve({
|
||||
libraryName: "Mock Library",
|
||||
totalFileCount: 1000,
|
||||
totalTranscodeCount: 200,
|
||||
totalHealthCheckCount: 150,
|
||||
failedTranscodeCount: 10,
|
||||
failedHealthCheckCount: 5,
|
||||
stagedTranscodeCount: 20,
|
||||
stagedHealthCheckCount: 15,
|
||||
totalSavedSpace: 5000000,
|
||||
audioCodecs: [{ name: "AAC", value: 300 }],
|
||||
audioContainers: [{ name: "MP4", value: 200 }],
|
||||
videoCodecs: [{ name: "H.264", value: 400 }],
|
||||
videoContainers: [{ name: "MKV", value: 250 }],
|
||||
videoResolutions: [{ name: "1080p", value: 600 }],
|
||||
healthCheckStatus: [{ name: "Healthy", value: 100 }],
|
||||
transcodeStatus: [{ name: "Transcode success", value: 180 }],
|
||||
});
|
||||
}
|
||||
public async getWorkersAsync(): Promise<TdarrWorker[]> {
|
||||
return await Promise.resolve(
|
||||
Array.from({ length: 5 }, (_, index) => MediaTranscodingMockService.createWorker(index)),
|
||||
);
|
||||
}
|
||||
public async getQueueAsync(firstItemIndex: number, pageSize: number): Promise<TdarrQueue> {
|
||||
return await Promise.resolve({
|
||||
array: Array.from({ length: pageSize }, (_, index) => ({
|
||||
id: `item-${firstItemIndex + index}`,
|
||||
healthCheck: "Pending",
|
||||
transcode: "Pending",
|
||||
filePath: `/path/to/file-${firstItemIndex + index}.mkv`,
|
||||
fileSize: 1000000000 + (firstItemIndex + index) * 100000000, // in bytes
|
||||
container: "MKV",
|
||||
codec: "H.264",
|
||||
resolution: "1080p",
|
||||
type: "transcode",
|
||||
})),
|
||||
totalCount: 50,
|
||||
startIndex: firstItemIndex,
|
||||
endIndex: firstItemIndex + pageSize - 1,
|
||||
});
|
||||
}
|
||||
|
||||
private static createWorker(index: number): TdarrWorker {
|
||||
return {
|
||||
id: `worker-${index}`,
|
||||
filePath: `/path/to/file-${index}.mkv`,
|
||||
fps: 24 + index,
|
||||
percentage: index * 20,
|
||||
ETA: `${30 - index * 5} minutes`,
|
||||
jobType: "Transcode",
|
||||
status: "In Progress",
|
||||
step: `Step ${index + 1}`,
|
||||
originalSize: 1000000000 + index * 100000000, // in bytes
|
||||
estimatedSize: 800000000 + index * 50000000, // in bytes
|
||||
outputSize: 750000000 + index * 40000000, // in bytes
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { NetworkControllerSummaryIntegration } from "../../interfaces/network-controller-summary/network-controller-summary-integration";
|
||||
import type { NetworkControllerSummary } from "../../types";
|
||||
|
||||
export class NetworkControllerSummaryMockService implements NetworkControllerSummaryIntegration {
|
||||
public async getNetworkSummaryAsync(): Promise<NetworkControllerSummary> {
|
||||
return await Promise.resolve({
|
||||
lan: {
|
||||
guests: 5,
|
||||
users: 10,
|
||||
status: "enabled",
|
||||
},
|
||||
vpn: {
|
||||
users: 3,
|
||||
status: "enabled",
|
||||
},
|
||||
wanStatus: "disabled",
|
||||
wifi: {
|
||||
status: "disabled",
|
||||
guests: 0,
|
||||
users: 0,
|
||||
},
|
||||
www: {
|
||||
latency: 22,
|
||||
status: "enabled",
|
||||
ping: 32,
|
||||
uptime: 3600,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
19
packages/integrations/src/mock/data/notifications.ts
Normal file
19
packages/integrations/src/mock/data/notifications.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { Notification } from "../../interfaces/notifications/notification-types";
|
||||
import type { INotificationsIntegration } from "../../interfaces/notifications/notifications-integration";
|
||||
|
||||
export class NotificationsMockService implements INotificationsIntegration {
|
||||
public async getNotificationsAsync(): Promise<Notification[]> {
|
||||
return await Promise.resolve(
|
||||
Array.from({ length: 10 }, (_, index) => NotificationsMockService.createNotification(index)),
|
||||
);
|
||||
}
|
||||
|
||||
private static createNotification(index: number): Notification {
|
||||
return {
|
||||
id: index.toString(),
|
||||
time: new Date(Date.now() - Math.random() * 1000000), // Random time within the next 11 days
|
||||
title: `Notification ${index}`,
|
||||
body: `This is the body of notification ${index}.`,
|
||||
};
|
||||
}
|
||||
}
|
||||
27
packages/integrations/src/mock/data/smart-home.ts
Normal file
27
packages/integrations/src/mock/data/smart-home.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { ISmartHomeIntegration } from "../../interfaces/smart-home/smart-home-integration";
|
||||
import type { EntityStateResult } from "../../interfaces/smart-home/smart-home-types";
|
||||
|
||||
export class SmartHomeMockService implements ISmartHomeIntegration {
|
||||
public async getEntityStateAsync(entityId: string): Promise<EntityStateResult> {
|
||||
return await Promise.resolve({
|
||||
success: true as const,
|
||||
data: {
|
||||
entity_id: entityId,
|
||||
state: "on",
|
||||
attributes: {
|
||||
friendly_name: `Mock Entity ${entityId}`,
|
||||
device_class: "light",
|
||||
supported_features: 1,
|
||||
},
|
||||
last_changed: new Date(),
|
||||
last_updated: new Date(),
|
||||
},
|
||||
});
|
||||
}
|
||||
public async triggerAutomationAsync(_entityId: string): Promise<boolean> {
|
||||
return await Promise.resolve(true);
|
||||
}
|
||||
public async triggerToggleAsync(_entityId: string): Promise<boolean> {
|
||||
return await Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { SystemHealthMonitoring } from "../..";
|
||||
import type { ISystemHealthMonitoringIntegration } from "../../interfaces/health-monitoring/health-monitoring-integration";
|
||||
|
||||
export class SystemHealthMonitoringMockService implements ISystemHealthMonitoringIntegration {
|
||||
public async getSystemInfoAsync(): Promise<SystemHealthMonitoring> {
|
||||
return await Promise.resolve({
|
||||
version: "1.0.0",
|
||||
cpuModelName: "Mock CPU",
|
||||
cpuUtilization: Math.random(),
|
||||
memUsed: (4 * 1024 * 1024 * 1024).toString(), // 4 GB in bytes
|
||||
memAvailable: (8 * 1024 * 1024 * 1024).toString(), // 8 GB in bytes
|
||||
availablePkgUpdates: 0,
|
||||
rebootRequired: false,
|
||||
cpuTemp: Math.floor(Math.random() * 100), // Random temperature between 0 and 99
|
||||
uptime: Math.floor(Math.random() * 1000000), // Random uptime in seconds
|
||||
fileSystem: Array.from({ length: 3 }, (_, index) => ({
|
||||
deviceName: `sha${index + 1}`,
|
||||
used: "1 GB",
|
||||
available: "500 MB",
|
||||
percentage: Math.floor(Math.random() * 100), // Random percentage between 0 and 99
|
||||
})),
|
||||
loadAverage: {
|
||||
"1min": Math.random() * 10,
|
||||
"5min": Math.random() * 10,
|
||||
"15min": Math.random() * 10,
|
||||
},
|
||||
smart: [
|
||||
{
|
||||
deviceName: "Mock Device",
|
||||
temperature: Math.floor(Math.random() * 100), // Random temperature between 0 and 99
|
||||
overallStatus: "OK",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
119
packages/integrations/src/mock/mock-integration.ts
Normal file
119
packages/integrations/src/mock/mock-integration.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import type { IntegrationTestingInput } from "../base/integration";
|
||||
import { Integration } from "../base/integration";
|
||||
import type { TestingResult } from "../base/test-connection/test-connection-service";
|
||||
import type { ICalendarIntegration } from "../interfaces/calendar/calendar-integration";
|
||||
import type { DnsHoleSummaryIntegration } from "../interfaces/dns-hole-summary/dns-hole-summary-integration";
|
||||
import type { IDownloadClientIntegration } from "../interfaces/downloads/download-client-integration";
|
||||
import type {
|
||||
IClusterHealthMonitoringIntegration,
|
||||
ISystemHealthMonitoringIntegration,
|
||||
} from "../interfaces/health-monitoring/health-monitoring-integration";
|
||||
import type { IIndexerManagerIntegration } from "../interfaces/indexer-manager/indexer-manager-integration";
|
||||
import type { IMediaRequestIntegration } from "../interfaces/media-requests/media-request-integration";
|
||||
import type { IMediaServerIntegration } from "../interfaces/media-server/media-server-integration";
|
||||
import type { IMediaTranscodingIntegration } from "../interfaces/media-transcoding/media-transcoding-integration";
|
||||
import type { NetworkControllerSummaryIntegration } from "../interfaces/network-controller-summary/network-controller-summary-integration";
|
||||
import type { ISmartHomeIntegration } from "../interfaces/smart-home/smart-home-integration";
|
||||
import { CalendarMockService } from "./data/calendar";
|
||||
import { ClusterHealthMonitoringMockService } from "./data/cluster-health-monitoring";
|
||||
import { DnsHoleMockService } from "./data/dns-hole";
|
||||
import { DownloadClientMockService } from "./data/download";
|
||||
import { IndexerManagerMockService } from "./data/indexer-manager";
|
||||
import { MediaRequestMockService } from "./data/media-request";
|
||||
import { MediaServerMockService } from "./data/media-server";
|
||||
import { MediaTranscodingMockService } from "./data/media-transcoding";
|
||||
import { NetworkControllerSummaryMockService } from "./data/network-controller-summary";
|
||||
import { NotificationsMockService } from "./data/notifications";
|
||||
import { SmartHomeMockService } from "./data/smart-home";
|
||||
import { SystemHealthMonitoringMockService } from "./data/system-health-monitoring";
|
||||
|
||||
export class MockIntegration
|
||||
extends Integration
|
||||
implements
|
||||
DnsHoleSummaryIntegration,
|
||||
ICalendarIntegration,
|
||||
IDownloadClientIntegration,
|
||||
IClusterHealthMonitoringIntegration,
|
||||
ISystemHealthMonitoringIntegration,
|
||||
IIndexerManagerIntegration,
|
||||
IMediaRequestIntegration,
|
||||
IMediaServerIntegration,
|
||||
IMediaTranscodingIntegration,
|
||||
NetworkControllerSummaryIntegration,
|
||||
ISmartHomeIntegration
|
||||
{
|
||||
private static readonly dnsHole = new DnsHoleMockService();
|
||||
private static readonly calendar = new CalendarMockService();
|
||||
private static readonly downloadClient = new DownloadClientMockService();
|
||||
private static readonly clusterMonitoring = new ClusterHealthMonitoringMockService();
|
||||
private static readonly systemMonitoring = new SystemHealthMonitoringMockService();
|
||||
private static readonly indexerManager = new IndexerManagerMockService();
|
||||
private static readonly mediaRequest = new MediaRequestMockService();
|
||||
private static readonly mediaServer = new MediaServerMockService();
|
||||
private static readonly mediaTranscoding = new MediaTranscodingMockService();
|
||||
private static readonly networkController = new NetworkControllerSummaryMockService();
|
||||
private static readonly notifications = new NotificationsMockService();
|
||||
private static readonly smartHome = new SmartHomeMockService();
|
||||
|
||||
protected async testingAsync(_: IntegrationTestingInput): Promise<TestingResult> {
|
||||
return await Promise.resolve({
|
||||
success: true,
|
||||
});
|
||||
}
|
||||
|
||||
// CalendarIntegration
|
||||
getCalendarEventsAsync = MockIntegration.calendar.getCalendarEventsAsync.bind(MockIntegration.calendar);
|
||||
|
||||
// DnsHoleSummaryIntegration
|
||||
getSummaryAsync = MockIntegration.dnsHole.getSummaryAsync.bind(MockIntegration.dnsHole);
|
||||
enableAsync = MockIntegration.dnsHole.enableAsync.bind(MockIntegration.dnsHole);
|
||||
disableAsync = MockIntegration.dnsHole.disableAsync.bind(MockIntegration.dnsHole);
|
||||
|
||||
// IDownloadClientIntegration
|
||||
getClientJobsAndStatusAsync = MockIntegration.downloadClient.getClientJobsAndStatusAsync.bind(
|
||||
MockIntegration.downloadClient,
|
||||
);
|
||||
pauseQueueAsync = MockIntegration.downloadClient.pauseQueueAsync.bind(MockIntegration.downloadClient);
|
||||
pauseItemAsync = MockIntegration.downloadClient.pauseItemAsync.bind(MockIntegration.downloadClient);
|
||||
resumeQueueAsync = MockIntegration.downloadClient.resumeQueueAsync.bind(MockIntegration.downloadClient);
|
||||
resumeItemAsync = MockIntegration.downloadClient.resumeItemAsync.bind(MockIntegration.downloadClient);
|
||||
deleteItemAsync = MockIntegration.downloadClient.deleteItemAsync.bind(MockIntegration.downloadClient);
|
||||
|
||||
// Health Monitoring Integrations
|
||||
getSystemInfoAsync = MockIntegration.systemMonitoring.getSystemInfoAsync.bind(MockIntegration.systemMonitoring);
|
||||
getClusterInfoAsync = MockIntegration.clusterMonitoring.getClusterInfoAsync.bind(MockIntegration.downloadClient);
|
||||
|
||||
// IndexerManagerIntegration
|
||||
getIndexersAsync = MockIntegration.indexerManager.getIndexersAsync.bind(MockIntegration.indexerManager);
|
||||
testAllAsync = MockIntegration.indexerManager.testAllAsync.bind(MockIntegration.indexerManager);
|
||||
|
||||
// MediaRequestIntegration
|
||||
getSeriesInformationAsync = MockIntegration.mediaRequest.getSeriesInformationAsync.bind(MockIntegration.mediaRequest);
|
||||
requestMediaAsync = MockIntegration.mediaRequest.requestMediaAsync.bind(MockIntegration.mediaRequest);
|
||||
getRequestsAsync = MockIntegration.mediaRequest.getRequestsAsync.bind(MockIntegration.mediaRequest);
|
||||
getStatsAsync = MockIntegration.mediaRequest.getStatsAsync.bind(MockIntegration.mediaRequest);
|
||||
getUsersAsync = MockIntegration.mediaRequest.getUsersAsync.bind(MockIntegration.mediaRequest);
|
||||
approveRequestAsync = MockIntegration.mediaRequest.approveRequestAsync.bind(MockIntegration.mediaRequest);
|
||||
declineRequestAsync = MockIntegration.mediaRequest.declineRequestAsync.bind(MockIntegration.mediaRequest);
|
||||
|
||||
// MediaServerIntegration
|
||||
getCurrentSessionsAsync = MockIntegration.mediaServer.getCurrentSessionsAsync.bind(MockIntegration.mediaRequest);
|
||||
|
||||
// MediaTranscodingIntegration
|
||||
getStatisticsAsync = MockIntegration.mediaTranscoding.getStatisticsAsync.bind(MockIntegration.mediaTranscoding);
|
||||
getWorkersAsync = MockIntegration.mediaTranscoding.getWorkersAsync.bind(MockIntegration.mediaTranscoding);
|
||||
getQueueAsync = MockIntegration.mediaTranscoding.getQueueAsync.bind(MockIntegration.mediaTranscoding);
|
||||
|
||||
// NetworkControllerSummaryIntegration
|
||||
getNetworkSummaryAsync = MockIntegration.networkController.getNetworkSummaryAsync.bind(
|
||||
MockIntegration.networkController,
|
||||
);
|
||||
|
||||
// NotificationsIntegration
|
||||
getNotificationsAsync = MockIntegration.notifications.getNotificationsAsync.bind(MockIntegration.notifications);
|
||||
|
||||
// SmartHomeIntegration
|
||||
getEntityStateAsync = MockIntegration.smartHome.getEntityStateAsync.bind(MockIntegration.smartHome);
|
||||
triggerAutomationAsync = MockIntegration.smartHome.triggerAutomationAsync.bind(MockIntegration.smartHome);
|
||||
triggerToggleAsync = MockIntegration.smartHome.triggerToggleAsync.bind(MockIntegration.smartHome);
|
||||
}
|
||||
Reference in New Issue
Block a user