@memberjunction/testing-integration 0.0.0 → 5.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/IntegrationTestDriver.d.ts +63 -0
  2. package/dist/IntegrationTestDriver.d.ts.map +1 -0
  3. package/dist/IntegrationTestDriver.js +412 -0
  4. package/dist/IntegrationTestDriver.js.map +1 -0
  5. package/dist/ai-verify.d.ts +27 -0
  6. package/dist/ai-verify.d.ts.map +1 -0
  7. package/dist/ai-verify.js +120 -0
  8. package/dist/ai-verify.js.map +1 -0
  9. package/dist/bootstrap-client.d.ts +11 -0
  10. package/dist/bootstrap-client.d.ts.map +1 -0
  11. package/dist/bootstrap-client.js +68 -0
  12. package/dist/bootstrap-client.js.map +1 -0
  13. package/dist/bootstrap-shared.d.ts +94 -0
  14. package/dist/bootstrap-shared.d.ts.map +1 -0
  15. package/dist/bootstrap-shared.js +94 -0
  16. package/dist/bootstrap-shared.js.map +1 -0
  17. package/dist/bootstrap.d.ts +14 -0
  18. package/dist/bootstrap.d.ts.map +1 -0
  19. package/dist/bootstrap.js +133 -0
  20. package/dist/bootstrap.js.map +1 -0
  21. package/dist/check-registry.d.ts +39 -0
  22. package/dist/check-registry.d.ts.map +1 -0
  23. package/dist/check-registry.js +61 -0
  24. package/dist/check-registry.js.map +1 -0
  25. package/dist/check.d.ts +531 -0
  26. package/dist/check.d.ts.map +1 -0
  27. package/dist/check.js +2 -0
  28. package/dist/check.js.map +1 -0
  29. package/dist/checks/self-test.check.d.ts +2 -0
  30. package/dist/checks/self-test.check.d.ts.map +1 -0
  31. package/dist/checks/self-test.check.js +35 -0
  32. package/dist/checks/self-test.check.js.map +1 -0
  33. package/dist/config.d.ts +35 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +81 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/index.d.ts +25 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +37 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/instrumented-cache.d.ts +47 -0
  42. package/dist/instrumented-cache.d.ts.map +1 -0
  43. package/dist/instrumented-cache.js +81 -0
  44. package/dist/instrumented-cache.js.map +1 -0
  45. package/dist/registry.d.ts +33 -0
  46. package/dist/registry.d.ts.map +1 -0
  47. package/dist/registry.js +37 -0
  48. package/dist/registry.js.map +1 -0
  49. package/dist/rls-fixture.d.ts +37 -0
  50. package/dist/rls-fixture.d.ts.map +1 -0
  51. package/dist/rls-fixture.js +91 -0
  52. package/dist/rls-fixture.js.map +1 -0
  53. package/dist/test-runner.d.ts +55 -0
  54. package/dist/test-runner.d.ts.map +1 -0
  55. package/dist/test-runner.js +128 -0
  56. package/dist/test-runner.js.map +1 -0
  57. package/dist/tiers.d.ts +28 -0
  58. package/dist/tiers.d.ts.map +1 -0
  59. package/dist/tiers.js +41 -0
  60. package/dist/tiers.js.map +1 -0
  61. package/dist/types.d.ts +51 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +2 -0
  64. package/dist/types.js.map +1 -0
  65. package/package.json +59 -8
  66. package/README.md +0 -45
@@ -0,0 +1,55 @@
1
+ export interface TestOutcome {
2
+ Name: string;
3
+ Passed: boolean;
4
+ DurationMs: number;
5
+ Error?: string;
6
+ }
7
+ /** The serialized per-check shape both execution paths emit for the golden diff. */
8
+ export interface EmittedOutcome {
9
+ name: string;
10
+ passed: boolean;
11
+ durationMs: number;
12
+ error?: string;
13
+ }
14
+ /**
15
+ * Minimal sequential test runner. Tests run in registration order (several tests
16
+ * intentionally depend on cache state built up by earlier ones — order matters and
17
+ * is part of what's being tested). Returns the number of failures from Run().
18
+ */
19
+ export declare class TestRunner {
20
+ readonly SuiteName: string;
21
+ private tests;
22
+ private lastOutcomes;
23
+ constructor(SuiteName: string);
24
+ Test(name: string, fn: () => Promise<void>): void;
25
+ Run(): Promise<number>;
26
+ /** Per-test results from the most recent Run(); empty until Run() completes. */
27
+ get LastOutcomes(): readonly TestOutcome[];
28
+ }
29
+ /**
30
+ * Write per-check outcomes to a JSON file as `{name, passed, durationMs, error?}[]`
31
+ * — the shape the golden-equivalence diff (scripts/integration-golden-diff.mjs)
32
+ * compares. Both the tsx scripts (via EmitOutcomes) and the IntegrationTestDriver
33
+ * call this so the two execution paths produce identical files.
34
+ */
35
+ export declare function writeOutcomesFile(path: string, outcomes: readonly TestOutcome[]): Promise<void>;
36
+ /** Dump a finished TestRunner's outcomes for the golden diff (no-op semantics on Run() preserved). */
37
+ export declare function EmitOutcomes(runner: TestRunner, path: string): Promise<void>;
38
+ export declare function Assert(condition: boolean, message: string): void;
39
+ /**
40
+ * Sleep for `ms` — lets fire-and-forget run/step/detail saves (BaseEntitySaveQueue) land before a
41
+ * check reads them back. Lifted from the tsx harness so graduated bundles read it from the package.
42
+ */
43
+ export declare const settle: (ms: number) => Promise<void>;
44
+ export declare function AssertEqual<T>(actual: T, expected: T, message: string): void;
45
+ /** Sorted, lowercased key list of a result row — the canonical "shape" of a row. */
46
+ export declare function RowKeys(row: Record<string, unknown>): string[];
47
+ /**
48
+ * Asserts a row has EXACTLY the expected keys (case-insensitive, order-insensitive).
49
+ * This is the core assertion of the cache suites: cache hit and cache miss must
50
+ * produce identical shapes for identical requests.
51
+ */
52
+ export declare function AssertRowShape(row: Record<string, unknown>, expectedKeys: string[], message: string): void;
53
+ export declare function AssertKeysInclude(row: Record<string, unknown>, keys: string[], message: string): void;
54
+ export declare function AssertKeysExclude(row: Record<string, unknown>, keys: string[], message: string): void;
55
+ //# sourceMappingURL=test-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../src/test-runner.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,UAAU;aAIS,SAAS,EAAE,MAAM;IAH7C,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,YAAY,CAAqB;gBAEb,SAAS,EAAE,MAAM;IAEtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI3C,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IA4BnC,gFAAgF;IAChF,IAAW,YAAY,IAAI,SAAS,WAAW,EAAE,CAEhD;CACJ;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrG;AAED,sGAAsG;AACtG,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAMD,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIhE;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,KAAG,OAAO,CAAC,IAAI,CAAoD,CAAC;AAErG,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAI5E;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAM1G;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMrG;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMrG"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * test-runner.ts — the minimal sequential TestRunner and the result-shape
3
+ * assertion helpers, lifted verbatim from the original live harness. The
4
+ * additive pieces (the `LastOutcomes` getter and the `EmitOutcomes` /
5
+ * `writeOutcomesFile` helpers) exist so per-test outcomes can be dumped for the
6
+ * golden-equivalence diff; the `Run()` return value (failure count) and ordering
7
+ * semantics are unchanged.
8
+ */
9
+ import { writeFile, mkdir } from 'node:fs/promises';
10
+ import { dirname } from 'node:path';
11
+ /**
12
+ * Minimal sequential test runner. Tests run in registration order (several tests
13
+ * intentionally depend on cache state built up by earlier ones — order matters and
14
+ * is part of what's being tested). Returns the number of failures from Run().
15
+ */
16
+ export class TestRunner {
17
+ constructor(SuiteName) {
18
+ this.SuiteName = SuiteName;
19
+ this.tests = [];
20
+ this.lastOutcomes = [];
21
+ }
22
+ Test(name, fn) {
23
+ this.tests.push({ Name: name, Fn: fn });
24
+ }
25
+ async Run() {
26
+ console.log(`\n══════ ${this.SuiteName} — ${this.tests.length} tests ══════\n`);
27
+ const outcomes = [];
28
+ for (const test of this.tests) {
29
+ const start = Date.now();
30
+ try {
31
+ await test.Fn();
32
+ outcomes.push({ Name: test.Name, Passed: true, DurationMs: Date.now() - start });
33
+ console.log(` ✓ ${test.Name} (${Date.now() - start}ms)`);
34
+ }
35
+ catch (error) {
36
+ const message = error instanceof Error ? error.message : String(error);
37
+ outcomes.push({ Name: test.Name, Passed: false, DurationMs: Date.now() - start, Error: message });
38
+ console.log(` ✗ ${test.Name} (${Date.now() - start}ms)`);
39
+ console.log(` ${message}`);
40
+ }
41
+ }
42
+ this.lastOutcomes = outcomes;
43
+ const failed = outcomes.filter(o => !o.Passed);
44
+ console.log(`\n────── ${this.SuiteName}: ${outcomes.length - failed.length}/${outcomes.length} passed ──────`);
45
+ if (failed.length > 0) {
46
+ console.log('\nFailures:');
47
+ for (const f of failed) {
48
+ console.log(` ✗ ${f.Name}\n ${f.Error}`);
49
+ }
50
+ }
51
+ return failed.length;
52
+ }
53
+ /** Per-test results from the most recent Run(); empty until Run() completes. */
54
+ get LastOutcomes() {
55
+ return this.lastOutcomes;
56
+ }
57
+ }
58
+ /**
59
+ * Write per-check outcomes to a JSON file as `{name, passed, durationMs, error?}[]`
60
+ * — the shape the golden-equivalence diff (scripts/integration-golden-diff.mjs)
61
+ * compares. Both the tsx scripts (via EmitOutcomes) and the IntegrationTestDriver
62
+ * call this so the two execution paths produce identical files.
63
+ */
64
+ export async function writeOutcomesFile(path, outcomes) {
65
+ const serialized = outcomes.map(o => ({
66
+ name: o.Name,
67
+ passed: o.Passed,
68
+ durationMs: o.DurationMs,
69
+ ...(o.Error ? { error: o.Error } : {})
70
+ }));
71
+ // Create the parent directory if needed so an EMIT_OUTCOMES path like /tmp/golden/x.json
72
+ // "just works" without a prior mkdir (writeFile alone throws ENOENT on a missing dir).
73
+ await mkdir(dirname(path), { recursive: true });
74
+ await writeFile(path, JSON.stringify(serialized, null, 2));
75
+ }
76
+ /** Dump a finished TestRunner's outcomes for the golden diff (no-op semantics on Run() preserved). */
77
+ export async function EmitOutcomes(runner, path) {
78
+ await writeOutcomesFile(path, runner.LastOutcomes);
79
+ }
80
+ // ────────────────────────────────────────────────────────────────────────────
81
+ // Assertions
82
+ // ────────────────────────────────────────────────────────────────────────────
83
+ export function Assert(condition, message) {
84
+ if (!condition) {
85
+ throw new Error(message);
86
+ }
87
+ }
88
+ /**
89
+ * Sleep for `ms` — lets fire-and-forget run/step/detail saves (BaseEntitySaveQueue) land before a
90
+ * check reads them back. Lifted from the tsx harness so graduated bundles read it from the package.
91
+ */
92
+ export const settle = (ms) => new Promise(resolve => setTimeout(resolve, ms));
93
+ export function AssertEqual(actual, expected, message) {
94
+ if (actual !== expected) {
95
+ throw new Error(`${message} — expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
96
+ }
97
+ }
98
+ /** Sorted, lowercased key list of a result row — the canonical "shape" of a row. */
99
+ export function RowKeys(row) {
100
+ return Object.keys(row).map(k => k.toLowerCase()).sort();
101
+ }
102
+ /**
103
+ * Asserts a row has EXACTLY the expected keys (case-insensitive, order-insensitive).
104
+ * This is the core assertion of the cache suites: cache hit and cache miss must
105
+ * produce identical shapes for identical requests.
106
+ */
107
+ export function AssertRowShape(row, expectedKeys, message) {
108
+ const actual = RowKeys(row);
109
+ const expected = [...expectedKeys.map(k => k.toLowerCase())].sort();
110
+ if (actual.length !== expected.length || actual.some((k, i) => k !== expected[i])) {
111
+ throw new Error(`${message} — expected keys [${expected.join(', ')}], got [${actual.join(', ')}]`);
112
+ }
113
+ }
114
+ export function AssertKeysInclude(row, keys, message) {
115
+ const actual = new Set(RowKeys(row));
116
+ const missing = keys.filter(k => !actual.has(k.toLowerCase()));
117
+ if (missing.length > 0) {
118
+ throw new Error(`${message} — missing keys [${missing.join(', ')}]; present: [${[...actual].join(', ')}]`);
119
+ }
120
+ }
121
+ export function AssertKeysExclude(row, keys, message) {
122
+ const actual = new Set(RowKeys(row));
123
+ const present = keys.filter(k => actual.has(k.toLowerCase()));
124
+ if (present.length > 0) {
125
+ throw new Error(`${message} — keys [${present.join(', ')}] should NOT be present`);
126
+ }
127
+ }
128
+ //# sourceMappingURL=test-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../src/test-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * tiers.ts — the single source of truth for integration-test tier gating.
3
+ *
4
+ * An integration check belongs to a tier that decides whether it runs by default:
5
+ * - 'deterministic' — credential-free, read-only-or-self-cleaning; the blocking CI gate. Ungated.
6
+ * - 'mutation' — writes to the DB and cleans up unconditionally; gated by RUN_MUTATION_TESTS.
7
+ * - 'live-model' — incurs LLM token cost; ON BY DEFAULT (opt out with RUN_AGENT_TESTS=0).
8
+ * The live-model ITs live in their OWN suite ("Integration Tests — Live
9
+ * Model"), so invoking them is already an explicit act; a second env gate
10
+ * on top of suite selection was a confusing double-opt-in (Amith,
11
+ * 2026-07-20). CI pins RUN_AGENT_TESTS=0 (no credentials, no flake budget).
12
+ *
13
+ * Both the standalone tsx scripts and the IntegrationTestDriver call IsTierEnabled(),
14
+ * so a gate is honored identically in both execution paths (no drift). This is a
15
+ * verbatim port of the harness's gate semantics (RUN_MUTATION_TESTS === '1' /
16
+ * RUN_AGENT_TESTS === '1').
17
+ */
18
+ /** The three execution tiers an integration check (or Test) can belong to. */
19
+ export type IntegrationTier = 'deterministic' | 'mutation' | 'live-model';
20
+ /** Maps a tier to the env var that must equal '1' for it to run. Deterministic is ungated. */
21
+ export declare const TIER_ENV_GATE: Readonly<Record<IntegrationTier, string | null>>;
22
+ /**
23
+ * Returns true if the given tier is enabled in the current process environment.
24
+ * Deterministic is always enabled; mutation/live-model require their env gate === '1'.
25
+ * Single source of truth honored by both the tsx scripts and IntegrationTestDriver.
26
+ */
27
+ export declare function IsTierEnabled(tier: IntegrationTier, env?: NodeJS.ProcessEnv): boolean;
28
+ //# sourceMappingURL=tiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.d.ts","sourceRoot":"","sources":["../src/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;AAE1E,8FAA8F;AAC9F,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC,CAI1E,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAWlG"}
package/dist/tiers.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * tiers.ts — the single source of truth for integration-test tier gating.
3
+ *
4
+ * An integration check belongs to a tier that decides whether it runs by default:
5
+ * - 'deterministic' — credential-free, read-only-or-self-cleaning; the blocking CI gate. Ungated.
6
+ * - 'mutation' — writes to the DB and cleans up unconditionally; gated by RUN_MUTATION_TESTS.
7
+ * - 'live-model' — incurs LLM token cost; ON BY DEFAULT (opt out with RUN_AGENT_TESTS=0).
8
+ * The live-model ITs live in their OWN suite ("Integration Tests — Live
9
+ * Model"), so invoking them is already an explicit act; a second env gate
10
+ * on top of suite selection was a confusing double-opt-in (Amith,
11
+ * 2026-07-20). CI pins RUN_AGENT_TESTS=0 (no credentials, no flake budget).
12
+ *
13
+ * Both the standalone tsx scripts and the IntegrationTestDriver call IsTierEnabled(),
14
+ * so a gate is honored identically in both execution paths (no drift). This is a
15
+ * verbatim port of the harness's gate semantics (RUN_MUTATION_TESTS === '1' /
16
+ * RUN_AGENT_TESTS === '1').
17
+ */
18
+ /** Maps a tier to the env var that must equal '1' for it to run. Deterministic is ungated. */
19
+ export const TIER_ENV_GATE = {
20
+ 'deterministic': null,
21
+ 'mutation': 'RUN_MUTATION_TESTS',
22
+ 'live-model': 'RUN_AGENT_TESTS'
23
+ };
24
+ /**
25
+ * Returns true if the given tier is enabled in the current process environment.
26
+ * Deterministic is always enabled; mutation/live-model require their env gate === '1'.
27
+ * Single source of truth honored by both the tsx scripts and IntegrationTestDriver.
28
+ */
29
+ export function IsTierEnabled(tier, env = process.env) {
30
+ const gate = TIER_ENV_GATE[tier];
31
+ if (gate === null) {
32
+ return true;
33
+ }
34
+ if (tier === 'live-model') {
35
+ // Default-ON, explicit opt-out. '1' still means on (backward compat with every
36
+ // existing RUN_AGENT_TESTS=1 invocation); only an explicit '0' disables.
37
+ return env[gate] !== '0';
38
+ }
39
+ return env[gate] === '1';
40
+ }
41
+ //# sourceMappingURL=tiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.js","sourceRoot":"","sources":["../src/tiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,aAAa,GAAqD;IAC3E,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,oBAAoB;IAChC,YAAY,EAAE,iBAAiB;CAClC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAqB,EAAE,MAAyB,OAAO,CAAC,GAAG;IACrF,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QACxB,+EAA+E;QAC/E,yEAAyE;QACzE,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * types.ts — the shape the IntegrationTestDriver parses off MJTestEntity.Configuration.
3
+ * The metadata layer is intentionally thin: a Test's Configuration selects an ordered
4
+ * list of registered checks (by Id) plus optional gating.
5
+ */
6
+ import type { IntegrationTier } from './tiers.js';
7
+ /** Per-selector knobs the driver reads off a check-bundle selection. */
8
+ export interface IntegrationCheckSelectionConfig {
9
+ /** Include the bundle's RequiresMutation checks (the original RUN_MUTATION_TESTS gate). */
10
+ runMutationTests?: boolean;
11
+ /** `dataset-cache` bundle: the dataset name to exercise (default 'MJ_Metadata'). */
12
+ datasetName?: string;
13
+ /** `aggregates-cache` bundle: the entity to aggregate over (default 'MJ: User Settings'). */
14
+ entityName?: string;
15
+ /** `rls-isolation` bundle: require two distinct non-exempt users (else degrade to skip). */
16
+ requireTwoDistinctUsers?: boolean;
17
+ }
18
+ /** One check-BUNDLE selection inside an integration Test's Configuration. */
19
+ export interface IntegrationCheckSelection {
20
+ /** Bundle name resolved at runtime via IntegrationCheckRegistry.GetBundle, e.g.
21
+ * "server-cache" / "runquery-cache" / "client-cache". Free-text, like the
22
+ * existing Configuration.oracles[].type pattern; the driver expands it to the
23
+ * bundle's ordered NamedCheck[]. */
24
+ type: string;
25
+ /** Optional per-bundle gating knobs. */
26
+ config?: IntegrationCheckSelectionConfig;
27
+ }
28
+ /** Shape parsed off MJTestEntity.Configuration for the Integration Test type. */
29
+ export interface IntegrationTestConfig {
30
+ /** Ordered list of check BUNDLES to run in ONE Execute() against one bootstrapped
31
+ * context. Order is load-bearing both across bundles and WITHIN each bundle: the
32
+ * driver runs each bundle's checks in array order so stateful pairs like S1 (warm)
33
+ * → S2 (assert hit) behave like the standalone harness. */
34
+ checks: IntegrationCheckSelection[];
35
+ /** Which tier this Test belongs to. Decides the whole-test env gate via TIER_ENV_GATE:
36
+ * 'deterministic' (default) runs unconditionally; 'mutation' requires RUN_MUTATION_TESTS;
37
+ * 'live-model' requires RUN_AGENT_TESTS. When the tier is gated and its env var is unset,
38
+ * Execute() skip-passes with a gate note. Per-check RequiresMutation/RequiresLiveModel
39
+ * flags are gated independently (a deterministic Test can still carry mutation checks
40
+ * that only fire under RUN_MUTATION_TESTS). */
41
+ tier?: IntegrationTier;
42
+ /** Explicit env-gate override. When set, takes precedence over the tier-derived gate:
43
+ * Execute() reads process.env[requiresEnv] and skip-passes if !== '1'. Normally omitted
44
+ * in favor of `tier` (local-dev / gated-tier safety net). */
45
+ requiresEnv?: string;
46
+ /** Which transport the checks need. 'server' = SQLServerDataProvider only;
47
+ * 'client' = also needs a running MJAPI + MJ_API_KEY. When omitted, inferred
48
+ * from the selected bundles (client-cache ⇒ client; everything else ⇒ server). */
49
+ transport?: 'server' | 'client';
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wEAAwE;AACxE,MAAM,WAAW,+BAA+B;IAC5C,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACtC;;;yCAGqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,MAAM,CAAC,EAAE,+BAA+B,CAAC;CAC5C;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IAClC;;;gEAG4D;IAC5D,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACpC;;;;;oDAKgD;IAChD,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB;;kEAE8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;uFAEmF;IACnF,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACnC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,10 +1,61 @@
1
1
  {
2
2
  "name": "@memberjunction/testing-integration",
3
- "version": "0.0.0",
4
- "description": "OIDC trusted publishing setup package for @memberjunction/testing-integration",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
3
+ "type": "module",
4
+ "version": "5.49.0",
5
+ "description": "MemberJunction Integration Test bootstrap library, IntegrationCheck registry, and IntegrationTestDriver. Installs an instrumented LocalCacheManager as the first caller and owns its process.",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "/dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc && tsc-alias -f",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "test:coverage": "vitest run --coverage"
16
+ },
17
+ "author": "MemberJunction.com",
18
+ "license": "ISC",
19
+ "dependencies": {
20
+ "@memberjunction/core": "5.49.0",
21
+ "@memberjunction/core-entities": "5.49.0",
22
+ "@memberjunction/global": "5.49.0",
23
+ "@memberjunction/testing-engine": "5.49.0",
24
+ "@memberjunction/testing-engine-base": "5.49.0",
25
+ "@memberjunction/sqlserver-dataprovider": "5.49.0",
26
+ "@memberjunction/graphql-dataprovider": "5.49.0",
27
+ "@memberjunction/server-bootstrap-lite": "5.49.0",
28
+ "cosmiconfig": "9.0.0",
29
+ "dotenv": "17.2.4",
30
+ "mssql": "^12.2.0"
31
+ },
32
+ "optionalDependencies": {
33
+ "@memberjunction/postgresql-dataprovider": "5.49.0"
34
+ },
35
+ "devDependencies": {
36
+ "typescript": "^5.9.3",
37
+ "vitest": "^4.0.18"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/MemberJunction/MJ"
42
+ },
43
+ "exports": {
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "default": "./dist/index.js"
47
+ },
48
+ "./client": {
49
+ "types": "./dist/bootstrap-client.d.ts",
50
+ "default": "./dist/bootstrap-client.js"
51
+ },
52
+ "./registry": {
53
+ "types": "./dist/registry.d.ts",
54
+ "default": "./dist/registry.js"
55
+ },
56
+ "./checks/*": {
57
+ "types": "./dist/checks/*.d.ts",
58
+ "default": "./dist/checks/*.js"
59
+ }
60
+ }
61
+ }
package/README.md DELETED
@@ -1,45 +0,0 @@
1
- # @memberjunction/testing-integration
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/testing-integration`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**