Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3846,6 +3846,19 @@ jobs:
- name: Declared REST fault-log level
run: node scripts/check-rest-log-declared.mjs --self-test && node scripts/check-rest-log-declared.mjs

# The pairing half of the one above (#17865, ruling batch #128 item 4).
# The `packages/rest` harness now runs at `OS_REST_LOG: 'silent'`, which
# takes those 2,095 frame lines to ZERO — and that is safe only while
# every test file that OBSERVES the fault log declares its own loud level.
# Half of that population announces itself when it breaks: 15 files / 28
# test cases go RED the moment the suite is silenced. The other half does
# not. Eight files assert that an expected 4xx logs NOTHING, and a
# silenced shim makes those pass with every 4xx logged loudly — a phantom
# check reached by a legitimate-looking config line. This gate names an
# undeclared observer instead. Self-test first.
- name: Declared REST fault-log level — observers
run: node scripts/check-rest-log-spy-declared.mjs --self-test && node scripts/check-rest-log-spy-declared.mjs

# Live-server database isolation (#10382). CI provisions ONE Postgres and
# ONE MySQL for the whole temporal-conformance job and points every live
# leg at them, and every live suite in the repo issues a `drop` when it
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"check:test-source-alias": "node scripts/check-test-source-alias.mjs --self-test && node scripts/check-test-source-alias.mjs",
"check:registry-log-declared": "node scripts/check-registry-log-declared.mjs --self-test && node scripts/check-registry-log-declared.mjs",
"check:rest-log-declared": "node scripts/check-rest-log-declared.mjs --self-test && node scripts/check-rest-log-declared.mjs",
"check:rest-log-spy-declared": "node scripts/check-rest-log-spy-declared.mjs --self-test && node scripts/check-rest-log-spy-declared.mjs",
"check:refd-timer-probe": "node scripts/check-refd-timer-probe.mjs --self-test && node scripts/check-refd-timer-probe.mjs",
"check:type-source-resolution": "node scripts/check-type-source-resolution.mjs --self-test && node scripts/check-type-source-resolution.mjs",
"check:undeclared-dep-imports": "node scripts/check-undeclared-dep-imports.mjs --self-test && node scripts/check-undeclared-dep-imports.mjs",
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-16019-driver-declared-fault.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,21 @@
* case stays GREEN, which is precisely why it could not stand in for this one.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import type { Logger } from '@objectstack/spec/contracts';
import { AnalyticsService } from '@objectstack/service-analytics';
import { SqlDriver } from '@objectstack/driver-sql';
import { INTERNAL_ERROR_MESSAGE, declaresServerFault, looksLikeInternalErrorLeak } from '@objectstack/types';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness (the shape `analytics-dataset-dimension-gate.test.ts` uses) ──────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-dataset-dimension-gate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,20 @@
* sources: mutating the service without rebuilding it proves nothing here.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import type { Logger } from '@objectstack/spec/contracts';
import { AnalyticsService } from '@objectstack/service-analytics';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness (the shape `analytics-filter-refusal-envelope.test.ts` uses) ──────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-dataset-where-gate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@
* must be falsifiable on its own.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import type { Logger } from '@objectstack/spec/contracts';
import { AnalyticsService } from '@objectstack/service-analytics';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness (the shape the two sibling analytics rest tests use) ─────────────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-fault-user-message.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,19 @@
* or strategy.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { RestServer } from './rest-server';
import { handleRouteError } from './error-response.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness (the shape the sibling analytics envelope tests use) ──────────────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-filter-refusal-envelope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,20 @@
* be re-labelled with a code of its own choosing.
*/

import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import type { Logger } from '@objectstack/spec/contracts';
import { AnalyticsService } from '@objectstack/service-analytics';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness ──────────────────────────────────────────────────────────────────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/analytics-read-scope-refusal-envelope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,20 @@
* threw.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import type { Logger } from '@objectstack/spec/contracts';
import { AnalyticsService } from '@objectstack/service-analytics';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ── harness (the shape the sibling analytics envelope tests use) ──────────────

function mockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/execctx-authz-input-seam-reachability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
* outside vitest (it needs git history) and is recorded on the card.
*/

import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
Expand All @@ -103,6 +103,14 @@ import type { RouteHandler } from '@objectstack/spec/contracts';
import { registerPackageRoutes } from './package-routes.js';
import { RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const PKGS = '/api/v1/packages';
const HERE = dirname(fileURLToPath(import.meta.url));
const SOURCE = readFileSync(resolve(HERE, 'rest-server.ts'), 'utf8');
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/external-write-forbidden-envelope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@
// had this test lie about what it measures.
// ---------------------------------------------------------------------------

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { ObjectQL } from '@objectstack/objectql';
import type { IDataDriver } from '@objectstack/spec/contracts';
import { RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const DATA_COLLECTION = '/api/v1/data/:object';
const DATA_ITEM = '/api/v1/data/:object/:id';

Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/meta-app-nav-servability-gate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@
* and must fail here.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
// Explicit `.js` extension: this package's tsconfig resolves NodeNext, so the
// extensionless spelling its older test files use is a TS2835 — 67 of them are
// frozen in the TEST_DEBT ledger, which only ever shrinks. A new file must not
// add the 68th.
import { RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const ANON_API = { api: { requireAuth: false } };

function createMockServer() {
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-5xx-message-sanitization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,20 @@
// keep the status the producer declared, keep the machine-readable `code`, drop
// the prose. The status-preservation assertions below are what pin that.

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { ObjectQL } from '@objectstack/objectql';
import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const META_ITEM = '/api/v1/meta/:type/:name';
const OBJ_BATCH = '/api/v1/data/:object/batch';
const BATCH_OBJECT = 'showcase_account';
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-5xx-status-passthrough.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,18 @@
// above the passthrough are untouched.
// ---------------------------------------------------------------------------

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { mapDataError, RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const DATA_LIST = '/api/v1/data/:object';

// ---------------------------------------------------------------------------
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-data-door-code-prefix.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,19 @@
* anchored strip answers the well-formed idiom byte-identically.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
// `.js` extension deliberately: this package resolves `nodenext`, so an
// extensionless relative import is a `tsc` error (TS2835).
import { RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const ITEM = '/api/v1/data/:object/:id';
const COLLECTION = '/api/v1/data/:object';
const SHARES = '/api/v1/data/:object/:id/shares';
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-declared-refusal-relay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,20 @@
* pass by the two strings coinciding.
*/

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { assertEngineFindOnePredicate } from '@objectstack/metadata-core';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
import { ObjectStackProtocolImplementation } from '@objectstack/metadata-protocol';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const META = '/api/v1/meta';

/** Prose a producer authored FOR the caller. Names nothing tenant-sensitive. */
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-endpoint-surfaces-served-only.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,19 @@
// guard that changed colour with the fix would be pinning the fix rather than
// the invariant. Both predictions were confirmed by running it (see the PR).

import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import { MetadataManager } from '@objectstack/metadata';
import { MemoryLoader } from '@objectstack/metadata';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

// ---------------------------------------------------------------------------
// The three declarations, each standing for one way a route can exist
// ---------------------------------------------------------------------------
Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-expected-error-logging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@
// bug is never silent — is the same one, and is now carried by the status band
// rather than by the absence of a `code`.

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { RestServer } from './rest-server';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const META_ITEM = '/api/v1/meta/:type/:name';
const DATA_LIST = '/api/v1/data/:object';

Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-hook-refusal-code-parity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,20 @@
// prediction is reported rather than fitted to the measurement.
// ---------------------------------------------------------------------------

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
// `.js` extension deliberately: this package resolves `nodenext`, so an
// extensionless relative import is a `tsc` error (TS2835).
import { mapDataError, RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const DATA_COLLECTION = '/api/v1/data/:object';
const DATA_ITEM = '/api/v1/data/:object/:id';

Expand Down
10 changes: 9 additions & 1 deletion packages/rest/src/rest-hook-refusal-message-parity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,21 @@
// re-reading both files from the repository root rather than trusting the trap.
// ---------------------------------------------------------------------------

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
import { INTERNAL_ERROR_MESSAGE } from '@objectstack/types';
// `.js` extension deliberately: this package resolves `nodenext`, so an
// extensionless relative import is a `tsc` error (TS2835).
import { mapDataError, handleRouteError } from './error-response.js';
import { RestServer } from './rest-server.js';

// [#17865] This file observes the REST fault log, so it declares the level it
// asserts against instead of inheriting the suite's quiet one. 'info' is the
// SHIPPED default — what a real caller gets. Paired by
// scripts/check-rest-log-spy-declared.mjs: an observer that declares nothing
// is a finding by name.
beforeAll(() => { vi.stubEnv('OS_REST_LOG', 'info'); });
afterAll(() => { vi.unstubAllEnvs(); });

const DATA_COLLECTION = '/api/v1/data/:object';
const DATA_ITEM = '/api/v1/data/:object/:id';

Expand Down
Loading
Loading