Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  status-helpers.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { describe, expect, it } from "vitest";
import {
  createAsyncComputedAccountStatusAdapter,
  buildBaseAccountStatusSnapshot,
  buildBaseChannelStatusSummary,
  buildComputedAccountStatusSnapshot,
  buildRuntimeAccountStatusSnapshot,
  createComputedAccountStatusAdapter,
  buildWebhookChannelStatusSummary,
  buildTokenChannelStatusSummary,
  collectStatusIssuesFromLastError,
  createDependentCredentialStatusIssueCollector,
  createDefaultChannelRuntimeState,
} from "./status-helpers.js";

const defaultRuntimeState = {
  running: false,
  lastStartAt: null,
  lastStopAt: null,
  lastError: null,
};

type ExpectedAccountSnapshot = {
  accountId: string;
  name?: string;
  enabled?: boolean;
  configured?: boolean;
  running: boolean;
  lastStartAt: number | null;
  lastStopAt: number | null;
  lastError: string | null;
  probe?: unknown;
  lastInboundAt: number | null;
  lastOutboundAt: number | null;
} & Record<string, unknown>;

const defaultChannelSummary = {
  configured: false,
  ...defaultRuntimeState,
};

const defaultTokenChannelSummary = {
  ...defaultChannelSummary,
  tokenSource: "none",
  mode: null,
  probe: undefined,
  lastProbeAt: null,
};

const defaultAccountSnapshot: ExpectedAccountSnapshot = {
  accountId: "default",
  name: undefined,
  enabled: undefined,
  configured: false,
  ...defaultRuntimeState,
  probe: undefined,
  lastInboundAt: null,
  lastOutboundAt: null,
};

function expectedAccountSnapshot(
  overrides: Partial<ExpectedAccountSnapshot> = {},
): ExpectedAccountSnapshot {
  return {
    ...defaultAccountSnapshot,
    ...overrides,
  };
}

const adapterAccount = {
  accountId: "default",
  enabled: true,
  profileUrl: "https://example.test",
};

const adapterRuntime = {
  accountId: "default",
  running: true,
};

const adapterProbe = { ok: true };

function expectedAdapterAccountSnapshot() {
  return {
    ...expectedAccountSnapshot({
      enabled: true,
      configured: true,
      running: true,
      probe: adapterProbe,
    }),
    profileUrl: adapterAccount.profileUrl,
    connected: true,
  };
}

function createComputedStatusAdapter() {
  return createComputedAccountStatusAdapter<
    { accountId: string; enabled: boolean; profileUrl: string },
    { ok: boolean }
  >({
    defaultRuntime: createDefaultChannelRuntimeState("default"),
    resolveAccountSnapshot: ({ account, runtime, probe }) => ({
      accountId: account.accountId,
      enabled: account.enabled,
      configured: true,
      extra: {
        profileUrl: account.profileUrl,
        connected: runtime?.running ?? false,
        probe,
      },
    }),
  });
}

function createAsyncStatusAdapter() {
  return createAsyncComputedAccountStatusAdapter<
    { accountId: string; enabled: boolean; profileUrl: string },
    { ok: boolean }
  >({
    defaultRuntime: createDefaultChannelRuntimeState("default"),
    resolveAccountSnapshot: async ({ account, runtime, probe }) => ({
      accountId: account.accountId,
      enabled: account.enabled,
      configured: true,
      extra: {
        profileUrl: account.profileUrl,
        connected: runtime?.running ?? false,
        probe,
      },
    }),
  });
}

describe("createDefaultChannelRuntimeState", () => {
  it.each([
    {
      name: "builds default runtime state without extra fields",
      accountId: "default",
      extra: undefined,
      expected: {
        accountId: "default",
        ...defaultRuntimeState,
      },
    },
    {
      name: "merges extra fields into the default runtime state",
      accountId: "alerts",
      extra: {
        probeAt: 123,
        healthy: true,
      },
      expected: {
        accountId: "alerts",
        ...defaultRuntimeState,
        probeAt: 123,
        healthy: true,
      },
    },
  ])("$name", ({ accountId, extra, expected }) => {
    expect(createDefaultChannelRuntimeState(accountId, extra)).toEqual(expected);
  });
});

describe("buildBaseChannelStatusSummary", () => {
  it.each([
    {
      name: "defaults missing values",
      input: {},
      expected: defaultChannelSummary,
    },
    {
      name: "keeps explicit values",
      input: {
        configured: true,
        running: true,
        lastStartAt: 1,
        lastStopAt: 2,
        lastError: "boom",
      },
      expected: {
        ...defaultChannelSummary,
        configured: true,
        running: true,
        lastStartAt: 1,
        lastStopAt: 2,
        lastError: "boom",
      },
    },
  ])("$name", ({ input, expected }) => {
    expect(buildBaseChannelStatusSummary(input)).toEqual(expected);
  });

  it("merges extra fields into the normalized channel summary", () => {
    expect(
      buildBaseChannelStatusSummary(
        {
          configured: true,
        },
        {
          mode: "webhook",
          secretSource: "env",
        },
      ),
    ).toEqual({
      ...defaultChannelSummary,
      configured: true,
      mode: "webhook",
      secretSource: "env",
    });
  });
});

describe("buildBaseAccountStatusSnapshot", () => {
  it.each([
    {
      name: "builds account status with runtime defaults",
      input: {
        account: { accountId: "default", enabled: true, configured: true },
      },
      extra: undefined,
      expected: expectedAccountSnapshot({ enabled: true, configured: true }),
    },
    {
      name: "merges extra snapshot fields after the shared account shape",
      input: {
        account: { accountId: "default", configured: true },
      },
      extra: {
        connected: true,
        mode: "polling",
      },
      expected: {
        ...expectedAccountSnapshot({ configured: true }),
        connected: true,
        mode: "polling",
      },
    },
  ])("$name", ({ input, extra, expected }) => {
    expect(buildBaseAccountStatusSnapshot(input, extra)).toEqual(expected);
  });
});

describe("buildComputedAccountStatusSnapshot", () => {
  it("builds account status when configured is computed outside resolver", () => {
    expect(
      buildComputedAccountStatusSnapshot({
        accountId: "default",
        enabled: true,
        configured: false,
      }),
    ).toEqual(expectedAccountSnapshot({ enabled: true }));
  });

  it("merges computed extras after the shared fields", () => {
    expect(
      buildComputedAccountStatusSnapshot(
        {
          accountId: "default",
          configured: true,
        },
        {
          connected: true,
        },
      ),
    ).toEqual({
      ...expectedAccountSnapshot({ configured: true }),
      connected: true,
    });
  });
});

describe("computed account status adapters", () => {
  it.each([
    {
      name: "sync",
      createStatus: createComputedStatusAdapter,
    },
    {
      name: "async",
      createStatus: createAsyncStatusAdapter,
    },
  ])(
    "builds account snapshots from $name computed account metadata and extras",
    async ({ createStatus }) => {
      const status = createStatus();
      await expect(
        Promise.resolve(
          status.buildAccountSnapshot?.({
            account: adapterAccount,
            cfg: {} as never,
            runtime: adapterRuntime,
            probe: adapterProbe,
          }),
        ),
      ).resolves.toEqual(expectedAdapterAccountSnapshot());
    },
  );
});

describe("buildRuntimeAccountStatusSnapshot", () => {
  it.each([
    {
      name: "builds runtime lifecycle fields with defaults",
      input: {},
      extra: undefined,
      expected: {
        ...defaultRuntimeState,
        probe: undefined,
      },
    },
    {
      name: "merges extra fields into runtime snapshots",
      input: {},
      extra: { port: 3978 },
      expected: {
        ...defaultRuntimeState,
        probe: undefined,
        port: 3978,
      },
    },
    {
      name: "preserves runtime connectivity metadata",
      input: {
        runtime: {
          connected: true,
          restartPending: true,
          reconnectAttempts: 3,
          lastConnectedAt: 11,
          lastDisconnect: { at: 12, error: "boom" },
          lastEventAt: 13,
          lastTransportActivityAt: 14,
          healthState: "healthy",
          running: true,
        },
      },
      extra: undefined,
      expected: {
        ...defaultRuntimeState,
        running: true,
        connected: true,
        restartPending: true,
        reconnectAttempts: 3,
        lastConnectedAt: 11,
        lastDisconnect: { at: 12, error: "boom" },
        lastEventAt: 13,
        lastTransportActivityAt: 14,
        healthState: "healthy",
        probe: undefined,
      },
    },
  ])("$name", ({ input, extra, expected }) => {
    expect(buildRuntimeAccountStatusSnapshot(input, extra)).toEqual(expected);
  });
});

describe("buildTokenChannelStatusSummary", () => {
  it.each([
    {
      name: "includes token/probe fields with mode by default",
      input: {},
      options: undefined,
      expected: defaultTokenChannelSummary,
    },
    {
      name: "can omit mode for channels without a mode state",
      input: {
        configured: true,
        tokenSource: "env",
        running: true,
        lastStartAt: 1,
        lastStopAt: 2,
        lastError: "boom",
        probe: { ok: true },
        lastProbeAt: 3,
      },
      options: { includeMode: false },
      expected: {
        configured: true,
        tokenSource: "env",
        running: true,
        lastStartAt: 1,
        lastStopAt: 2,
        lastError: "boom",
        probe: { ok: true },
        lastProbeAt: 3,
      },
    },
  ])("$name", ({ input, options, expected }) => {
    expect(buildTokenChannelStatusSummary(input, options)).toEqual(expected);
  });
});

describe("buildWebhookChannelStatusSummary", () => {
  it("defaults mode to webhook and keeps supplied extras", () => {
    expect(
      buildWebhookChannelStatusSummary(
        {
          configured: true,
          running: true,
        },
        {
          secretSource: "env",
        },
      ),
    ).toEqual({
      configured: true,
      running: true,
      lastStartAt: null,
      lastStopAt: null,
      lastError: null,
      mode: "webhook",
      secretSource: "env",
    });
  });
});

describe("createDependentCredentialStatusIssueCollector", () => {
  it("uses source metadata from sanitized snapshots to pick the missing field", () => {
    const collect = createDependentCredentialStatusIssueCollector({
      channel: "line",
      dependencySourceKey: "tokenSource",
      missingPrimaryMessage: "LINE channel access token not configured",
      missingDependentMessage: "LINE channel secret not configured",
    });

    expect(
      collect([
        { accountId: "default", configured: false, tokenSource: "none" },
        { accountId: "work", configured: false, tokenSource: "env" },
        { accountId: "ok", configured: true, tokenSource: "env" },
      ]),
    ).toEqual([
      {
        channel: "line",
        accountId: "default",
        kind: "config",
        message: "LINE channel access token not configured",
      },
      {
        channel: "line",
        accountId: "work",
        kind: "config",
        message: "LINE channel secret not configured",
      },
    ]);
  });
});

describe("collectStatusIssuesFromLastError", () => {
  it("returns runtime issues only for non-empty string lastError values", () => {
    expect(
      collectStatusIssuesFromLastError("demo-channel", [
        { accountId: "default", lastError: " timeout " },
        { accountId: "silent", lastError: "   " },
        { accountId: "typed", lastError: { message: "boom" } },
      ]),
    ).toEqual([
      {
        channel: "demo-channel",
        accountId: "default",
        kind: "runtime",
        message: "Channel error: timeout",
      },
    ]);
  });
});

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge