Skip to content

Feature Request: Support MockAppSheetClient injection in SchemaManager #6

@wagnert

Description

@wagnert

Problem

SchemaManager cannot be used with MockAppSheetClient for testing because:

  1. SchemaManager constructor only accepts SchemaConfig, not a pre-configured ConnectionManager
  2. ConnectionManager.register() only accepts ConnectionConfig and always creates a new AppSheetClient internally

This makes it impossible to inject a MockAppSheetClient for unit/integration testing while using the SchemaManager API with its automatic validation features.

Current API (v2.1.0)

// SchemaManager creates its own ConnectionManager internally
const schemaManager = new SchemaManager(schema);

// ConnectionManager only accepts config, not a ready client
connectionManager.register(config: ConnectionConfig);  // Always creates new AppSheetClient

Proposed API

Option 1: SchemaManager accepts optional ConnectionManager

export class SchemaManager {
  constructor(schema: SchemaConfig, connectionManager?: ConnectionManager) {
    this.schema = schema;
    this.connectionManager = connectionManager || new ConnectionManager();
    if (!connectionManager) {
      this.initialize(); // Only auto-initialize if no ConnectionManager provided
    }
  }
}

Option 2: ConnectionManager.registerClient() method

export class ConnectionManager {
  // Existing method - creates new client from config
  register(config: ConnectionConfig): void;
  
  // NEW method - accepts pre-created client
  registerClient(name: string, client: AppSheetClientInterface): void {
    if (this.connections.has(name)) {
      throw new Error(`Connection "${name}" is already registered`);
    }
    this.connections.set(name, client);
  }
}

Use Case: TSyringe DI with Mock Support

// container.base.ts
export function registerSchemaManager(c: DependencyContainer): void {
  c.register(TOKENS.SchemaManager, {
    useFactory: (container) => {
      const client = container.resolve(TOKENS.AppSheetClient); // Real or Mock
      const schema = SchemaLoader.fromJson('config/appsheet-schema.json');
      const connectionManager = new ConnectionManager();
      connectionManager.registerClient('default', client); // ← NEW API
      return new SchemaManager(schema, connectionManager); // ← NEW API
    }
  });
}

// container.development.ts - Uses MockAppSheetClient
registerMockAppSheetClient(container);
registerSchemaManager(container); // SchemaManager uses MockAppSheetClient

// container.production.ts - Uses real AppSheetClient
registerRealAppSheetClient(container);
registerSchemaManager(container); // SchemaManager uses real AppSheetClient

Benefits

  • Testability: Unit/integration tests can use MockAppSheetClient with full SchemaManager features
  • DI Support: Works with TSyringe, InversifyJS, and other DI containers
  • Validation: DynamicTable runtime validation still works (the core value of SchemaManager)
  • Backward Compatible: Existing code using new SchemaManager(schema) continues to work

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions