Skip to content

Commit

Permalink
Resolve requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Machi3mfl committed Dec 26, 2024
1 parent 5fa2c4a commit 0b38816
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 246 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import { createMockLogger } from '../../../test/mocks/logger-mocked';
import { IConfigurationProvider } from './configuration-provider';
import { ConfigurationStore } from './configuration-store';

const noop = () => {};

function createMockLogger() {
const logger = {
info: noop,
error: noop,
debug: noop,
warn: noop,
trace: noop,
fatal: noop,
log: noop,
get: () => logger,
};

return logger;
}

const mockedProvider = jest.mocked<IConfigurationProvider>({
const mockedProvider: IConfigurationProvider = {
getAll: jest.fn(),
get: jest.fn(),
set: jest.fn(),
setName: jest.fn(),
getName: jest.fn(),
});
};

beforeEach(() => {
jest.clearAllMocks();
Expand Down Expand Up @@ -55,8 +39,8 @@ describe(`[service] ConfigurationStore`, () => {
const logger = createMockLogger();
const configurationStore = new ConfigurationStore(logger);

// @ts-expect-error Testing error case
expect(() =>
// @ts-expect-error Testing error case
configurationStore.registerProvider('test', null),
).toThrowError('Provider is required');
});
Expand All @@ -66,7 +50,7 @@ describe(`[service] ConfigurationStore`, () => {
const configurationStore = new ConfigurationStore(logger);

configurationStore.registerProvider('test', mockedProvider);
(mockedProvider.getAll as jest.Mock).mockResolvedValue({ test: 'test' });
mockedProvider.getAll.mockResolvedValue({ test: 'test' });
expect(
configurationStore.getProviderConfiguration('test'),
).resolves.toEqual({ test: 'test' });
Expand Down Expand Up @@ -102,8 +86,8 @@ describe(`[service] ConfigurationStore`, () => {
const logger = createMockLogger();
const configurationStore = new ConfigurationStore(logger);

(mockedProvider.getAll as jest.Mock).mockResolvedValue({ test: 'test' });
(mockedProvider.get as jest.Mock).mockResolvedValue('test');
mockedProvider.getAll.mockResolvedValue({ test: 'test' });
mockedProvider.get.mockResolvedValue('test');
configurationStore.registerProvider('test', mockedProvider);
expect(await configurationStore.get('test')).toEqual('test');
});
Expand All @@ -112,11 +96,9 @@ describe(`[service] ConfigurationStore`, () => {
const logger = createMockLogger();
const configurationStore = new ConfigurationStore(logger);

(mockedProvider.getAll as jest.Mock).mockResolvedValue({ test: 'test' });
mockedProvider.getAll.mockResolvedValue({ test: 'test' });
configurationStore.registerProvider('test', mockedProvider);
(mockedProvider.get as jest.Mock).mockRejectedValue(
new Error('test error'),
);
mockedProvider.get.mockRejectedValue(new Error('test error'));

try {
await configurationStore.get('test');
Expand All @@ -130,7 +112,7 @@ describe(`[service] ConfigurationStore`, () => {
const configurationStore = new ConfigurationStore(logger);

configurationStore.registerProvider('test', mockedProvider);
(mockedProvider.getAll as jest.Mock).mockResolvedValue({ test: 'test' });
mockedProvider.getAll.mockResolvedValue({ test: 'test' });
expect(configurationStore.getAll()).resolves.toEqual({ test: 'test' });
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger } from 'opensearch-dashboards/server';
import { IConfigurationStore } from './configuration';
import { IConfigurationStore } from './types';
import { IConfigurationProvider } from './configuration-provider';

export class ConfigurationStore implements IConfigurationStore {
Expand All @@ -11,6 +11,7 @@ export class ConfigurationStore implements IConfigurationStore {

registerProvider(name: string, provider: IConfigurationProvider) {
if (!provider) {
// ToDo: Create custom error and implement error handling
throw new Error('Provider is required');
}

Expand All @@ -22,6 +23,7 @@ export class ConfigurationStore implements IConfigurationStore {
const provider = this.providers.get(name);

if (!provider) {
// ToDo: Create custom error and implement error handling
throw new Error(`Provider ${name} not found`);
}

Expand All @@ -33,6 +35,7 @@ export class ConfigurationStore implements IConfigurationStore {
const provider = this.providers.get(key);

if (!provider) {
// ToDo: Create custom error and implement error handling
throw new Error(`Provider ${key} not found`);
}

Expand All @@ -41,6 +44,7 @@ export class ConfigurationStore implements IConfigurationStore {
return configuration;
} catch (error) {
const errorCasted = error as Error;
// ToDo: Create custom error and implement error handling
const enhancedError = new Error(
`Error getting configuration: ${errorCasted?.message}`,
);
Expand Down Expand Up @@ -77,6 +81,7 @@ export class ConfigurationStore implements IConfigurationStore {
return configuration[configName];
}

// ToDo: Create custom error and implement error handling
throw new Error(`Configuration ${configName} not found`);
}

Expand Down Expand Up @@ -109,12 +114,4 @@ export class ConfigurationStore implements IConfigurationStore {

return result;
}

async set(_settings: Record<string, any>): Promise<any> {
throw new Error('Method not implemented yet.');
}

async clear(_settings: string[]): Promise<any> {
throw new Error('Method not implemented yet.');
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
import { Configuration, IConfigurationStore } from './configuration';
import { ConfigurationStore } from './configuration-store';

const noop = () => {};

function createMockLogger() {
const logger = {
info: noop,
error: noop,
debug: noop,
warn: noop,
trace: noop,
fatal: noop,
log: noop,
get: () => logger,
};

return logger;
}
import { createMockLogger } from '../../../test/mocks/logger-mocked';
import { Configuration } from './configuration';
import { IConfigurationStore } from './types';

const mockConfigurationStore: IConfigurationStore = {
setup: jest.fn(),
Expand Down Expand Up @@ -74,7 +58,7 @@ describe('Configuration service', () => {
const logger = createMockLogger();
const configuration = new Configuration(logger, mockConfigurationStore);

(mockConfigurationStore.get as jest.Mock).mockRejectedValue(
mockConfigurationStore.get.mockRejectedValue(
new Error('Configuration setting not found'),
);

Expand All @@ -98,7 +82,7 @@ describe('Configuration service', () => {
const logger = createMockLogger();
const configuration = new Configuration(logger, mockConfigurationStore);

(mockConfigurationStore.getAll as jest.Mock).mockRejectedValue(
mockConfigurationStore.getAll.mockRejectedValue(
new Error('Configuration settings not found'),
);

Expand Down
167 changes: 1 addition & 166 deletions plugins/wazuh-core/common/services/configuration/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,169 +1,4 @@
import { IConfigurationProvider } from './configuration-provider';

export interface ILogger {
debug: (message: string) => void;
info: (message: string) => void;
warn: (message: string) => void;
error: (message: string) => void;
}

interface TConfigurationSettingOptionsPassword {
password: {
dual?: 'text' | 'password' | 'dual';
};
}

interface TConfigurationSettingOptionsTextArea {
maxRows?: number;
minRows?: number;
maxLength?: number;
}

interface TConfigurationSettingOptionsSelect {
select: { text: string; value: any }[];
}

interface TConfigurationSettingOptionsEditor {
editor: {
language: string;
};
}

interface TConfigurationSettingOptionsFile {
file: {
type: 'image';
extensions?: string[];
size?: {
maxBytes?: number;
minBytes?: number;
};
recommended?: {
dimensions?: {
width: number;
height: number;
unit: string;
};
};
store?: {
relativePathFileSystem: string;
filename: string;
resolveStaticURL: (filename: string) => string;
};
};
}

interface TConfigurationSettingOptionsNumber {
number: {
min?: number;
max?: number;
integer?: boolean;
};
}

interface TConfigurationSettingOptionsSwitch {
switch: {
values: {
disabled: { label?: string; value: any };
enabled: { label?: string; value: any };
};
};
}

export enum E_PLUGIN_SETTING_TYPE {
TEXT = 'text',
PASSWORD = 'password',
TEXTAREA = 'textarea',
SWITCH = 'switch',
NUMBER = 'number',
EDITOR = 'editor',
SELECT = 'select',
FILEPICKER = 'filepicker',
}

export interface TConfigurationSetting {
// Define the text displayed in the UI.
title: string;
// Description.
description: string;
// Category.
category: number;
// Type.
type: EpluginSettingType;
// Default value.
defaultValue: any;
/* Special: This is used for the settings of customization to get the hidden default value, because the default value is empty to not to be displayed on the App Settings. */
defaultValueIfNotSet?: any;
// Configurable from the configuration file.
isConfigurableFromSettings: boolean;
// Modify the setting requires running the plugin health check (frontend).
requiresRunningHealthCheck?: boolean;
// Modify the setting requires reloading the browser tab (frontend).
requiresReloadingBrowserTab?: boolean;
// Modify the setting requires restarting the plugin platform to take effect.
requiresRestartingPluginPlatform?: boolean;
// Define options related to the `type`.
options?:
| TConfigurationSettingOptionsEditor
| TConfigurationSettingOptionsFile
| TConfigurationSettingOptionsNumber
| TConfigurationSettingOptionsPassword
| TConfigurationSettingOptionsSelect
| TConfigurationSettingOptionsSwitch
| TConfigurationSettingOptionsTextArea;
store?: {
file: {
// Define if the setting is managed by the ConfigurationStore service
configurableManaged?: boolean;
// Define a text to print as the default in the configuration block
defaultBlock?: string;
/* Transform the value defined in the configuration file to be consumed by the Configuration
service */
transformFrom?: (value: any) => any;
};
};
// Transform the input value. The result is saved in the form global state of Settings/Configuration
uiFormTransformChangedInputValue?: (value: any) => any;
// Transform the configuration value or default as initial value for the input in Settings/Configuration
uiFormTransformConfigurationValueToInputValue?: (value: any) => any;
// Transform the input value changed in the form of Settings/Configuration and returned in the `changed` property of the hook useForm
uiFormTransformInputValueToConfigurationValue?: (value: any) => any;
// Validate the value in the form of App Settings. It returns a string if there is some validation error.
validateUIForm?: (value: any) => string | undefined;
// Validate function creator to validate the setting in the backend.
validate?: (schema: any) => (value: unknown) => string | undefined;
}

export type TConfigurationSettingWithKey = TConfigurationSetting & {
key: string;
};
export interface TConfigurationSettingCategory {
title: string;
description?: string;
documentationLink?: string;
renderOrder?: number;
}

type TConfigurationSettings = Record<string, any>;
export interface IConfigurationStore {
setup: () => Promise<any>;
start: () => Promise<any>;
stop: () => Promise<any>;
get: (...settings: string[]) => Promise<TConfigurationSettings>;
getAll: () => Promise<Record<string, any>>;
set: (settings: TConfigurationSettings) => Promise<any>;
getProviderConfiguration: (key: string) => Promise<Record<string, any>>;
registerProvider: (name: string, provider: IConfigurationProvider) => void;
getProvider: (name: string) => IConfigurationProvider;
}

export interface IConfiguration {
setStore: (store: IConfigurationStore) => void;
setup: () => Promise<any>;
start: () => Promise<any>;
stop: () => Promise<any>;
get: (settingsKey: string) => Promise<any>;
getAll: () => Promise<Record<string, any>>;
}
import { IConfiguration, IConfigurationStore, ILogger } from './types';

export class Configuration implements IConfiguration {
store: IConfigurationStore | null = null;
Expand Down
Loading

0 comments on commit 0b38816

Please sign in to comment.