test/mocks: expand cockpit mocks

Use the data from the regular fixtures, but through cockpit APIs.

There are a few hacks to get around the fact that there are no composes
without blueprints, and the lack of paging support in the cockpit api.
This commit is contained in:
Sanne Raymaekers 2025-01-29 16:31:03 +01:00 committed by Klara Simickova
parent b2f56e26f2
commit dc98ca032f
4 changed files with 145 additions and 41 deletions

View file

@ -0,0 +1,48 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import path from 'path';
import { mockGetBlueprints } from '../../fixtures/blueprints';
import { mockComposes } from '../../fixtures/composes';
const readBlueprint = (id: string): Promise<string> => {
for (const bp of mockGetBlueprints.data) {
if (bp.id === id) {
return new Promise((resolve) => {
resolve(JSON.stringify(bp));
});
}
}
return new Promise((resolve) => {
resolve('{}');
});
};
const readCompose = (id: string): Promise<string> => {
for (const compose of mockComposes) {
if (compose.id === id) {
return new Promise((resolve) => {
resolve(JSON.stringify(compose.request));
});
}
}
return new Promise((resolve) => {
resolve('{}');
});
};
export const cockpitFile = (filepath: string) => {
return {
read: (): Promise<string> => {
const file = path.parse(filepath);
const dir = path.parse(file.dir);
// if the directory matches the file it's a blueprint
if (file.name === dir.name) {
return readBlueprint(file.name);
}
return readCompose(file.name);
},
close: () => {},
replace: (contents: string) => {},
};
};

View file

@ -0,0 +1,28 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import path from 'path';
import type { Method, Headers, Params } from '../../../store/cockpit/types';
import { mockStatus } from '../../fixtures/composes';
type requestOptions = {
path: string;
method: Method;
body: unknown;
headers: Headers | undefined;
params: Params | undefined;
};
export const cockpitHTTP = (address: string, attr: object) => {
return {
request: (request: requestOptions): Promise<string> => {
if (request.path.startsWith('/api/image-builder-composer/v2/composes/')) {
return new Promise((resolve) => {
resolve(JSON.stringify(mockStatus(path.parse(request.path).name)));
});
}
return new Promise((resolve) => {
resolve('');
});
},
};
};

View file

@ -1,15 +1,75 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import path from 'path';
import { mockBlueprintIds } from '../../fixtures/blueprints';
import { mockComposes } from '../../fixtures/composes';
const bpDir = '/default/.cache/cockpit-image-builder/';
type fileinfo = {
entries?: Record<string, fileinfo>;
mtime: number;
};
interface FSInfoMap {
[id: string]: fileinfo;
}
export const listBlueprints = (): Promise<fileinfo> => {
const result: FSInfoMap = {};
for (const e of Object.values(mockBlueprintIds)) {
result[e] = {
mtime: 1,
};
}
return new Promise((resolve) => {
resolve({
entries: result,
mtime: 1,
});
});
};
export const listComposes = (): Promise<fileinfo> => {
const result: FSInfoMap = {};
let count = 0;
for (const e of mockComposes) {
// hack
if (count === 10) {
break;
}
count += 1;
result[e.id] = {
mtime: new Date(e.created_at).getTime() / 1000,
};
}
return new Promise((resolve) => {
resolve({
entries: result,
mtime: 1,
});
});
};
export const fsinfo = (
path: string,
filepath: string,
attributes: (keyof fileinfo)[],
options: object
): Promise<fileinfo> => {
if (filepath === bpDir) {
return listBlueprints();
}
// HACK: the composes in fixture don't have blueprints attached, so
// abuse one blueprint to return all composes.
if (
filepath ===
'/default/.cache/cockpit-image-builder/b3ff8307-18bd-418a-9a91-836ce039b035'
) {
return listComposes();
}
return new Promise((resolve) => {
resolve({
entries: {},

View file

@ -1,18 +1,14 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { Method, Headers, Params } from '../../../store/cockpit/types';
import path from 'path';
import { cockpitFile } from './cockpitFile';
import { cockpitHTTP } from './cockpitHTTP';
type userinfo = {
home: string;
};
type requestOptions = {
path: string;
method: Method;
body: unknown;
headers: Headers | undefined;
params: Params | undefined;
};
export default {
transport: {
host: '',
@ -21,43 +17,15 @@ export default {
user: (): Promise<userinfo> => {
return new Promise((resolve) => {
resolve({
home: '',
home: '/default',
});
});
},
file: (path: string) => {
return {
read: (): Promise<string> => {
return new Promise((resolve) => {
resolve('');
});
},
close: () => {},
replace: (contents: string): Promise<void> => {
return new Promise((resolve) => {
resolve();
});
},
};
},
file: cockpitFile,
spawn: (args: string[], attributes: object): Promise<string | Uint8Array> => {
return new Promise((resolve) => {
resolve('');
});
},
http: (address: string, options: object) => {
return {
get: (path?: string, headers?: object): string => {
return '';
},
post: (path: string, data: object, headers?: object): string => {
return '';
},
request: (request: requestOptions): Promise<string> => {
return new Promise((resolve) => {
resolve('');
});
},
};
},
http: cockpitHTTP,
};