studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
168 lines (167 loc) • 6.16 kB
JavaScript
class StudioCMSPluginTester {
plugin;
injectedLogger;
constructor(plugin, logger) {
this.plugin = plugin;
this.injectedLogger = logger;
}
/**
* Creates a mock logger object for testing purposes.
*
* The returned logger implements the `AstroIntegrationLogger` interface and provides
* stubbed logging methods (`info`, `warn`, `error`, `debug`) that delegate to the corresponding
* `console` methods. It also includes a `fork` method, which returns a new mock logger
* instance with an attached label for testing logger forking behavior.
*
* @returns {AstroIntegrationLogger} A mock logger instance suitable for use in tests.
*/
createMockLogger() {
if (this.injectedLogger) return this.injectedLogger;
const logger = {
info: console.log,
warn: console.warn,
error: console.error,
debug: console.debug,
fork: (label) => {
const forked = this.createMockLogger();
forked.label = label;
return forked;
}
};
return logger;
}
/**
* Executes the 'studiocms:astro:config' hook if it exists on the plugin,
* providing a mock logger and a method to collect Astro integrations.
*
* @returns A promise that resolves to an object containing the collected integrations.
*
* @remarks
* This method checks if the plugin defines a 'studiocms:astro:config' hook as a function.
* If so, it invokes the hook with a mock logger and an `addIntegrations` callback,
* which accumulates integrations into an array. The collected integrations are then
* returned in an object.
*/
async runAstroConfigHook() {
const integrations = [];
if (this.plugin.hooks["studiocms:astro:config"] && typeof this.plugin.hooks["studiocms:astro:config"] === "function") {
await this.plugin.hooks["studiocms:astro:config"]({
logger: this.createMockLogger(),
addIntegrations: (newIntegrations) => {
const toAdd = Array.isArray(newIntegrations) ? newIntegrations : [newIntegrations];
integrations.push(...toAdd);
}
});
}
return { integrations };
}
/**
* Executes the `studiocms:config:setup` hook on the current plugin, if available,
* and collects configuration options set by the hook into partial option objects.
*
* This method mocks the hook's context by providing setter functions for various
* StudioCMS configuration aspects, such as authentication, dashboard, frontend,
* image service, rendering, and sitemap. Each setter captures the values provided
* by the hook and stores them in corresponding partial option objects.
*
* @returns A promise that resolves to an object containing the collected configuration
* options for authentication service, dashboard, frontend, image service,
* rendering, and sitemap.
*
* @remarks
* This utility is primarily intended for testing purposes, allowing inspection of
* configuration values set by a plugin's `studiocms:config:setup` hook.
*/
async runStudioCMSConfigHook() {
const authService = {};
const dashboard = {};
const frontend = {};
const imageService = {};
const rendering = {};
const sitemap = {};
if (this.plugin.hooks["studiocms:config:setup"] && typeof this.plugin.hooks["studiocms:config:setup"] === "function") {
await this.plugin.hooks["studiocms:config:setup"]({
logger: this.createMockLogger(),
setAuthService: ({ oAuthProvider }) => {
if (oAuthProvider !== void 0) {
authService.oAuthProvider = oAuthProvider;
}
},
setDashboard: ({ dashboardGridItems, dashboardPages }) => {
if (dashboardGridItems !== void 0) {
dashboard.dashboardGridItems = dashboardGridItems;
}
if (dashboardPages !== void 0) {
dashboard.dashboardPages = dashboardPages;
}
},
setFrontend: ({ frontendNavigationLinks }) => {
if (frontendNavigationLinks !== void 0) {
frontend.frontendNavigationLinks = frontendNavigationLinks;
}
},
setImageService: ({ imageService: imgService }) => {
if (imgService !== void 0) {
imageService.imageService = imgService;
}
},
setRendering: ({ pageTypes }) => {
if (pageTypes !== void 0) {
rendering.pageTypes = pageTypes;
}
},
setSitemap: ({ sitemaps, triggerSitemap }) => {
if (sitemaps !== void 0) {
sitemap.sitemaps = sitemaps;
}
if (triggerSitemap !== void 0) {
sitemap.triggerSitemap = triggerSitemap;
}
}
});
}
return {
authService,
dashboard,
frontend,
imageService,
rendering,
sitemap
};
}
/**
* Retrieves information about the current plugin.
*
* @returns An object containing the plugin's identifier, name, minimum required StudioCMS version, and dependencies.
*/
getPluginInfo() {
return {
identifier: this.plugin.identifier,
name: this.plugin.name,
studiocmsMinimumVersion: this.plugin.studiocmsMinimumVersion,
requires: this.plugin.requires
};
}
/**
* Asynchronously retrieves the results of configured plugin hooks.
*
* @returns An object containing the presence and results of the 'studiocms:astro:config' and 'studiocms:config:setup' hooks.
* - `astroConfig`: Indicates if the 'studiocms:astro:config' hook exists and provides its execution results.
* - `studiocmsConfig`: Indicates if the 'studiocms:config:setup' hook exists and provides its execution results.
*/
async getHookResults() {
return {
astroConfig: {
hasHook: typeof this.plugin.hooks["studiocms:astro:config"] === "function",
hookResults: await this.runAstroConfigHook()
},
studiocmsConfig: {
hasHook: typeof this.plugin.hooks["studiocms:config:setup"] === "function",
hookResults: await this.runStudioCMSConfigHook()
}
};
}
}
export {
StudioCMSPluginTester
};