Skip to content

Add test infrastructure with in-memory CRUD data store, OIDC bypass, skip remote calls switch, and merchant name editing#510

Merged
StuartFerguson merged 13 commits intomainfrom
copilot/enhance-test-infrastructure
Jan 7, 2026
Merged

Add test infrastructure with in-memory CRUD data store, OIDC bypass, skip remote calls switch, and merchant name editing#510
StuartFerguson merged 13 commits intomainfrom
copilot/enhance-test-infrastructure

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 6, 2026

Integration tests currently require full Docker orchestration including OIDC containers, making tests slow (~30-60s startup) and complex. This adds a test mode that bypasses OIDC and provides an editable in-memory data store while maintaining the mediator pattern. Additionally, adds a skip remote calls switch to enable UI-only testing without backend service dependencies, and enables merchant name editing on the update merchant screen.

Changes

Test Mode Infrastructure

  • TestMode configuration flag - Conditionally swaps authentication and mediator services in Program.cs
  • TestAuthenticationHandler - Bypasses OIDC flow, provides test user claims automatically
  • appsettings.Test.json - Test-specific configuration preset

In-Memory Data Store

  • ITestDataStore / TestDataStore - Thread-safe CRUD operations for Estates, Merchants, Operators, Contracts
  • Reset() method - Restores default state for test isolation
  • ConcurrentDictionary backing - Safe for parallel test execution

Test Mediator Service

  • TestMediatorService - Implements IMediator using TestDataStore
  • All queries read from in-memory store
  • All commands mutate in-memory store
  • Dashboard/file queries return mock data (unchanged from StubbedMediatorService)

Skip Remote Calls Switch

  • TestConfiguration - Reads from appsettings.json (primary) or environment variables (fallback) to enable UI-only testing
  • appsettings.json - Test project configuration file with TestSettings:SkipRemoteCalls and TestSettings:EnableTestMode settings
  • SharedSteps updates - Modified test step definitions to conditionally skip remote API calls to SecurityService, TransactionProcessor, and other backend services
  • UI-only test mode - When enabled, tests only interact with the UI via Playwright without requiring backend Docker containers
  • Configuration packages - Added Microsoft.Extensions.Configuration and Microsoft.Extensions.Configuration.Json for appsettings support

Test Helpers

  • TestDataHelper - Simplified API for common test operations
  • TestDataManagementSteps - Example Reqnroll step definitions showing CRUD usage

UI Enhancements

  • Merchant name editing - Enabled merchant name field to be editable on the merchant edit screen
  • Validation - Added required field validation for merchant name
  • UpdateMerchantCommand integration - Merchant name changes are now saved via the existing UpdateMerchantCommand

Usage

Enable Test Mode

Enable test mode via config or environment:

{
  "AppSettings": { "TestMode": true }
}

Manipulate test data during execution:

// Add merchant mid-test
var merchant = new MerchantModel { ... };
testDataStore.AddMerchant(estateId, merchant);

// Verify via UI, then update
merchant.Balance = 10000m;
testDataStore.UpdateMerchant(estateId, merchant);

// Reset for next scenario
testDataStore.Reset();

Skip Remote Calls

Option 1: appsettings.json (Recommended)

{
  "TestSettings": {
    "SkipRemoteCalls": true,
    "EnableTestMode": true
  }
}

Option 2: Environment Variables (Backward Compatible)

# Skip remote API calls to backend services
export SKIP_REMOTE_CALLS=true

# Enable test mode in Blazor app
export APP_TEST_MODE=true

# Run UI-only tests (only UI container needed)
dotnet test

When skip remote calls is enabled, test steps skip all backend API calls and only interact with the UI via Playwright. Configuration values in appsettings.json take precedence over environment variables.

Default Test Data

Initializes with:

  • 1 Estate (ID: 11111111-1111-1111-1111-111111111111)
  • 3 Merchants (MERCH001-003) with varying balances and settlement schedules
  • 2 Operators (Safaricom with custom numbers, Voucher without)
  • 2 Contracts with products and transaction fees

Impact

  • No Docker containers needed for authentication
  • UI-only testing - Skip backend containers entirely with configuration flag
  • Configuration via appsettings.json for easier management
  • Backward compatible with environment variables
  • Immediate test startup vs 30-60s
  • Test data state maintainable between steps
  • Merchant name can now be updated - Removed restriction preventing merchant name changes after creation
  • Existing tests work unchanged (default TestMode=false, SkipRemoteCalls=false)
Original prompt

This section details on the original issue you should resolve

<issue_title>Enhance test infrastructure with editable test data and OIDC bypass</issue_title>
<issue_description>Currently, the Blazor integration tests require spinning up all docker containers including OIDC authentication services. This makes the test setup complex and slow.

Proposed Enhancements:

Editable Static Test Data

Implement an in-memory data store or mock repository pattern
Allow CRUD operations (add/update/remove) on test data during test execution
Maintain test data state between test steps
Ensure data isolation between test scenarios
OIDC Authentication Bypass

Create a test authentication mechanism that bypasses the normal OIDC flow
Allow tests to run without spinning up non-UI docker containers
Provide a way to set test user context directly
Maintain security boundaries while simplifying test setup
Benefits:

Faster test execution
Simpler test environment setup
Reduced infrastructure requirements for local development
More flexible test data management

Note this must still maintain the mediator pattern as this in how the app will function once I am past this development phase</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 5 commits January 6, 2026 17:43
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance test infrastructure with editable test data and OIDC bypass Add test infrastructure with in-memory CRUD data store and OIDC bypass Jan 6, 2026
Copilot AI requested a review from StuartFerguson January 6, 2026 17:54
@StuartFerguson
Copy link
Copy Markdown
Member

@copilot can you add some kind of switch into the actual tests to skip remote calls other than UI based calls ?

Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 6, 2026

@copilot can you add some kind of switch into the actual tests to skip remote calls other than UI based calls ?

Added skip remote calls switch via SKIP_REMOTE_CALLS environment variable. When enabled, test steps skip all backend API calls (SecurityService, TransactionProcessor, etc.) and only interact with the UI via Playwright.

Usage:

export SKIP_REMOTE_CALLS=true
export APP_TEST_MODE=true
dotnet test

Implementation in commit f79db5a:

  • Created TestConfiguration class to check environment variable
  • Updated SharedSteps.cs to conditionally skip remote calls in ~10 Given steps
  • Added SKIP_REMOTE_CALLS.md documentation

This enables UI-only testing without any backend Docker containers - only the Blazor UI container is needed.

Copilot AI changed the title Add test infrastructure with in-memory CRUD data store and OIDC bypass Add test infrastructure with in-memory CRUD data store, OIDC bypass, and skip remote calls switch Jan 6, 2026
@StuartFerguson
Copy link
Copy Markdown
Member

@copilot can you add a flag to the appsettings of the integration tests rather than an environment variable

Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 6, 2026

@copilot can you add a flag to the appsettings of the integration tests rather than an environment variable

Configuration moved to appsettings.json in the integration test project.

Usage:

{
  "TestSettings": {
    "SkipRemoteCalls": true,
    "EnableTestMode": true
  }
}

Implementation in commit c797975:

  • Created appsettings.json in test project
  • Updated TestConfiguration to read from appsettings.json (with environment variable fallback for backward compatibility)
  • Added Microsoft.Extensions.Configuration packages
  • Updated documentation in SKIP_REMOTE_CALLS.md

appsettings.json values take precedence over environment variables when both are set.

@StuartFerguson
Copy link
Copy Markdown
Member

@copilot looking pretty good, can you tweak the update merchant screen so the merchant name can be updated please

Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 6, 2026

@copilot looking pretty good, can you tweak the update merchant screen so the merchant name can be updated please

Merchant name can now be updated on the edit screen.

Changes in commit b000af5:

  1. Made merchant name field editable - Changed from disabled input to InputText component with two-way binding
  2. Added validation - Merchant name is now a required field with validation messages
  3. Integrated save logic - UpdateMerchantCommand is called when merchant name changes
  4. Updated model - Added MerchantName property to MerchantEditModel with [Required] attribute

Before:

<input type="text" value="@merchant.MerchantName" class="input w-full" disabled />
<p class="text-sm text-gray-500 mt-1">Merchant name cannot be changed after creation</p>

After:

<label class="block text-sm font-medium text-gray-700 mb-1">
    Merchant Name <span class="text-red-500">*</span>
</label>
<InputText @bind-Value="merchantEditModel.MerchantName" class="input w-full" name="MerchantName" />
<ValidationMessage For="@(() => merchantEditModel.MerchantName)" class="text-red-600 text-sm mt-1" />

The merchant name field is now fully editable and will be saved along with other merchant details when clicking the Save button on the Details tab.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • f.feedz.io
    • Triggering command: /usr/bin/dotnet dotnet build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add test infrastructure with in-memory CRUD data store, OIDC bypass, and skip remote calls switch Add test infrastructure with in-memory CRUD data store, OIDC bypass, skip remote calls switch, and merchant name editing Jan 6, 2026
@StuartFerguson StuartFerguson marked this pull request as ready for review January 7, 2026 09:40
@StuartFerguson StuartFerguson merged commit d68d449 into main Jan 7, 2026
8 of 9 checks passed
@github-actions github-actions Bot deleted the copilot/enhance-test-infrastructure branch March 9, 2026 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhance test infrastructure with editable test data and OIDC bypass

2 participants