import type { IDataObject, INodeProperties } from 'n8n-workflow'; import { ExternalSecretsProviders } from '@/modules/external-secrets.ee/external-secrets-providers.ee'; import { SecretsProvider } from '@/modules/external-secrets.ee/types'; import type { SecretsProviderSettings } from '@/modules/external-secrets.ee/types'; export class MockProviders extends ExternalSecretsProviders { override providers: Record = { dummy: DummyProvider, }; setProviders(providers: Record) { this.providers = providers; } } export class DummyProvider extends SecretsProvider { properties: INodeProperties[] = [ { name: 'username', displayName: 'Username', type: 'string', default: '', required: true, }, { name: 'other', displayName: 'Other', type: 'string', default: '', }, { name: 'password', displayName: 'Password', type: 'string', default: '', typeOptions: { password: true, }, }, ]; secrets: Record = {}; displayName = 'Dummy Provider'; name = 'dummy'; _updateSecrets: Record = { test1: 'value1', test2: 'value2', }; async init(_settings: SecretsProviderSettings): Promise {} protected async doConnect(): Promise { // Connected successfully - base class will set state } async disconnect(): Promise {} async update(): Promise { this.secrets = this._updateSecrets; } async test(): Promise<[boolean] | [boolean, string]> { return [true]; } getSecret(name: string): IDataObject | undefined { return this.secrets[name] as unknown as IDataObject | undefined; } hasSecret(name: string): boolean { return name in this.secrets; } getSecretNames(): string[] { return Object.keys(this.secrets); } } export class AnotherDummyProvider extends SecretsProvider { properties: INodeProperties[] = [ { name: 'username', displayName: 'Username', type: 'string', default: '', required: true, }, ]; secrets: Record = {}; displayName = 'Another Dummy Provider'; name = 'another_dummy'; _updateSecrets: Record = { test1: 'value1', test2: 'value2', }; async init(_settings: SecretsProviderSettings): Promise {} protected async doConnect(): Promise { // Connected successfully - base class will set state } async disconnect(): Promise {} async update(): Promise { this.secrets = this._updateSecrets; } async test(): Promise<[boolean] | [boolean, string]> { return [true]; } getSecret(name: string): IDataObject | undefined { return this.secrets[name] as unknown as IDataObject | undefined; } hasSecret(name: string): boolean { return name in this.secrets; } getSecretNames(): string[] { return Object.keys(this.secrets); } } export class ErrorProvider extends SecretsProvider { secrets: Record = {}; displayName = 'Error Provider'; name = 'dummy'; properties = []; async init(_settings: SecretsProviderSettings): Promise { throw new Error(); } protected async doConnect(): Promise { throw new Error('Connection failed'); } async disconnect(): Promise { // no-op } async update(): Promise { throw new Error(); } async test(): Promise<[boolean] | [boolean, string]> { throw new Error(); } getSecret(_name: string): IDataObject | undefined { throw new Error(); } hasSecret(_name: string): boolean { throw new Error(); } getSecretNames(): string[] { throw new Error(); } } export class FailedProvider extends SecretsProvider { secrets: Record = {}; displayName = 'Failed Provider'; name = 'dummy'; properties = []; async init(_settings: SecretsProviderSettings): Promise {} protected async doConnect(): Promise { throw new Error('Failed to connect'); } async disconnect(): Promise {} async update(): Promise {} async test(): Promise<[boolean] | [boolean, string]> { return [true]; } getSecret(name: string): IDataObject | undefined { return this.secrets[name] as unknown as IDataObject | undefined; } hasSecret(name: string): boolean { return name in this.secrets; } getSecretNames(): string[] { return Object.keys(this.secrets); } } export class TestFailProvider extends SecretsProvider { secrets: Record = {}; displayName = 'Test Failed Provider'; name = 'dummy'; properties = []; _updateSecrets: Record = { test1: 'value1', test2: 'value2', }; async init(_settings: SecretsProviderSettings): Promise {} protected async doConnect(): Promise { // Connected successfully - base class will set state } async disconnect(): Promise {} async update(): Promise { this.secrets = this._updateSecrets; } async test(): Promise<[boolean] | [boolean, string]> { return [false]; } getSecret(name: string): IDataObject | undefined { return this.secrets[name] as unknown as IDataObject | undefined; } hasSecret(name: string): boolean { return name in this.secrets; } getSecretNames(): string[] { return Object.keys(this.secrets); } } export function createDummyProvider({ name, secrets, displayName, properties, }: { name: string; displayName?: string; secrets?: Record; properties?: INodeProperties[]; }): { new (): SecretsProvider } { const defaultSecrets = secrets ?? { test1: 'value1', test2: 'value2', }; class FreshProvider extends SecretsProvider { name = name; displayName = displayName ?? name; properties: INodeProperties[] = properties ?? [ { name: 'username', displayName: 'Username', type: 'string', default: '', required: true, }, { name: 'other', displayName: 'Other', type: 'string', default: '', }, { name: 'password', displayName: 'Password', type: 'string', default: '', typeOptions: { password: true, }, }, ]; secrets: Record = { ...defaultSecrets }; _updateSecrets: Record = { ...defaultSecrets }; async init(_settings: SecretsProviderSettings): Promise {} protected async doConnect(): Promise { // Connected successfully - base class will set state } async disconnect(): Promise {} async update(): Promise { this.secrets = this._updateSecrets; } async test(): Promise<[boolean] | [boolean, string]> { return [true]; } getSecret(name: string): IDataObject | undefined { return this.secrets[name] as unknown as IDataObject | undefined; } hasSecret(name: string): boolean { return name in this.secrets; } getSecretNames(): string[] { return Object.keys(this.secrets); } } return FreshProvider; }