Exercise 6: Context-Based Isolation (Tenants)

This exercise shows tenant-specific data handling. Switch tenants using the ?sap-client= query parameter for isolated testing scenarios.

6.1 Setup Tenant-Specific Data

This exercise shows tenant-specific data handling. Switch tenants using the ?sap-client= query parameter (for example ?sap-client=tenant001 or ?sap-client=tenant002 ). This helps when testing different scenarios without changing data files.

1. Context-based isolation works automatically

The mockserver automatically supports tenant-specific data files without requiring any special configuration. Simply create tenant-specific JSON files and access them using the ?sap-client= query parameter.

Automatic Fallback Behavior: When no tenant-specific JSON file exists (e.g., Chapters-tenant001.json ), the mockserver automatically falls back to the root JSON file (e.g., Chapters.json ). This means you only need to create tenant-specific files for entities that should have different data per tenant, while other entities can use the shared root JSON files.

2. Create tenant-specific data files:

Create webapp/localService/mainService/data/Books-tenant001.json :

ex6/webapp/localService/mainService/data/Books-tenant001.json View on GitHub ↗
[
  {
    "ID": "tenant001-book-001",
    "title": "Tenant 1: Enterprise Architecture",
    "author": "Tech Corp Authors",
    "price": 89.99,
    "currency_code": "EUR",
    "stock": 50,
    "description": "Enterprise-specific technical book for Tenant 001.",
    "IsActiveEntity": true,
    "HasActiveEntity": false,
    "HasDraftEntity": false
  }
]

Create webapp/localService/mainService/data/Books-tenant002.json :

ex6/webapp/localService/mainService/data/Books-tenant002.json View on GitHub ↗
[
  {
    "ID": "tenant002-book-001",
    "title": "Tenant 2: Marketing Strategies",
    "author": "Marketing Gurus",
    "price": 45.0,
    "currency_code": "USD",
    "stock": 25,
    "description": "Marketing-focused content for Tenant 002.",
    "IsActiveEntity": true,
    "HasActiveEntity": false,
    "HasDraftEntity": false
  }
]

3. Fallback Example with Chapters

To demonstrate the automatic fallback behavior, notice that in this exercise we only have:

  • Books-tenant001.json and Books-tenant002.json (tenant-specific)
  • Chapters.json (shared/root file - no tenant-specific versions)

When you access different tenants, Books data will be tenant-specific, but Chapters data will automatically fall back to the shared Chapters.json file for all tenants. This allows you to mix tenant-specific and shared data seamlessly.

6.2 Tenant-Specific Business Logic (Optional)

Update Books.js to handle tenant-specific logic (not needed if you don't have custom logic):

ex6/webapp/localService/mainService/data/Books.js View on GitHub ↗
module.exports = {
  executeAction: async function (actionDefinition, actionData, keys, odataRequest) {
    const tenantId = odataRequest.tenantId || 'default';
    console.log(`Executing ${actionDefinition.name} for tenant: ${tenantId}`);

    switch (actionDefinition.name) {
      case 'promoteBook':
        let promoMessage = 'Book promoted!';

        // Tenant-specific promotion logic
        if (tenantId === 'tenant-tenant001') {
          promoMessage = 'Enterprise book promoted with technical review!';
        } else if (tenantId === 'tenant-tenant002') {
          promoMessage = 'Marketing book promoted with campaign boost!';
        }

        const entries = await this.base.fetchEntries(keys);

        await this.base.updateEntry(keys, {
          description: `[${tenantId.toUpperCase()}] PROMOTED: ` + entries[0].description,
        });

        return {
          message: promoMessage,
          promoted: true,
          tenant: tenantId,
        };

      default:
        return this.base.executeAction(actionDefinition, actionData, keys);
    }
  },
};

6.3 Test with Different Tenants

1. Start the application:

# from folder ex6
npm run start-mock
# or from root folder
npm run start:ex6

2. Test with different tenants:

Result: Context-based isolation enables multi-tenant testing with separate datasets per client.

6.4 Quick Debugging in VS Code

To debug tenant-specific logic:

  1. Open a JavaScript Debug Terminal in VS Code.
  2. Start the app with mockserver in the debug terminal:
    npm run start:ex6
  3. Set a breakpoint in webapp/localService/mainService/data/Books.js (for example in getInitialDataSet or executeAction ).
  4. Open the app with a tenant parameter, e.g. http://localhost:8086/index.html?sap-client=tenant001 .
  5. When the service loads or an action is triggered, VS Code pauses at your breakpoint.

6.5 Key Benefits of Tenant Isolation

  • Multi-Tenant Testing: Test different customer scenarios without data conflicts
  • Business Logic Variations: Different processing rules per tenant for SaaS applications
  • Data Segregation: Complete isolation of customer-specific data and configurations
  • URL-Based Routing: Easy switching between tenant contexts using query parameters

Next Steps

Exercise 7 will show how to implement error handling patterns with proper HTTP status codes and business rule violations for comprehensive UI testing scenarios.