Skip to content

Testing

The SDK ships a mock context so your tests exercise the exact shape production uses.

createMockPlatformContext

Defaults model a realistic single-building operator — a mall ops manager viewing their building in English, light theme. Override only what your test cares about:

tsx
import { createMockPlatformContext } from '@tv/extension-sdk/testing';
import { PlatformProvider } from '@tv/extension-sdk/react';
import { render, screen } from '@testing-library/react';
import Shell from './Shell';

test('renders the building name', () => {
  const ctx = createMockPlatformContext({
    building: {
      id: 'b1',
      slug: 'demo-mall',
      name: 'Demo Mall',
      type: 'mall',
      timezone: 'Europe/Moscow',
    },
  });

  render(
    <PlatformProvider value={ctx}>
      <Shell />
    </PlatformProvider>,
  );

  expect(screen.getByText(/Demo Mall/)).toBeInTheDocument();
});

Overrides are shallow

createMockPlatformContext(overrides) takes a Partial<PlatformContext> — shallow, not deep. Whatever top-level key you override, you supply whole. A building override needs every field of PlatformBuilding (id, slug, name, type, timezone); a partial one is a type error.

To tweak a single field, spread the default instead of hand-writing it:

ts
const base = createMockPlatformContext();
const ctx = createMockPlatformContext({
  building: { ...base.building!, name: 'Demo Mall' },
  user: { ...base.user, roles: ['manager'] },
});

Why use the mock vs. rolling your own

If you hand-build a PlatformContext in your tests, you can drift from the real shape — and your tests pass while production breaks. createMockPlatformContext() is built from the same types the platform injects, so:

  • Type changes to the context surface break your tests at compile time (good — you find out early).
  • The api client mock has the same method signatures as the real one.

Stubbing API responses

Same rule: api is a top-level key, so an override supplies the whole client. Spread the default and replace the verbs you exercise:

ts
const base = createMockPlatformContext();
const ctx = createMockPlatformContext({
  api: {
    ...base.api,
    get: vi.fn().mockResolvedValue([{ id: 's1', name: 'Unit 3B' }]),
  },
});

The default eventBus is a no-op (subscribe returns an empty unsubscribe, publish resolves) — override it the same way when you need to assert on published events.

The self-diagnosis checklist

Before opening a support ticket, run through this — most issues resolve here:

  1. Which SDK version? cat node_modules/@tv/extension-sdk/package.json | jq .version
  2. Manifest valid? npx @tv/extension-sdk validate module-manifest.json
  3. Federation expose right? npx @tv/extension-sdk check-exposes module-manifest.json
  4. Subscriptions fit the producers? npx @tv/extension-sdk check-pact module-manifest.json
  5. Using an @experimental symbol? Grep your imports — those can change between releases.
  6. Heartbeat reporting? Check your module's dot in the Building OS sidebar.
  7. Tests use createMockPlatformContext()?

If all seven are clean and it still breaks, it's on the platform — file a ticket with the checklist output.

Built on the Tango Vision platform. Questions? developers@tango.vision