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
15 changes: 13 additions & 2 deletions packages/core/src/security/platform-admin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ import {
setPlatformAdminConfigSink,
type PlatformAdminConfigSink,
} from './platform-admin.js';
// The security entry is loaded HERE, at module top, and not by a dynamic import
// inside the case that probes it below. That import loads the entry's whole
// re-export graph (signatures, sandbox, permission enforcement), and inside a
// case the load is charged to vitest's per-case budget (5000ms by default), so
// the pin's verdict would turn on how loaded the machine is. At module top the
// same load is charged to the COLLECT phase, where no per-case budget applies.
// The case loses nothing: it asserts export presence and absence only, and the
// entry only re-exports, so loading it earlier observes no env this file's
// hooks set or clear. Same reasoning as the core precedent
// `packages/core/src/service-resolution-discriminator.contract.test.ts`.
import * as securityEntry from './index.js';

const ENV = 'OS_PLATFORM_OWNER_EMAIL';

Expand Down Expand Up @@ -275,8 +286,8 @@ describe('[#11663 L5] the legacy-grant deprecation pointer is retired', () => {
expect('resolvePlatformAdminEmails' in mod).toBe(true);
});

it("⛔ nor by `@objectstack/core`'s security entry — the published surface lost them", async () => {
const entry: Record<string, unknown> = await import('./index.js');
it("⛔ nor by `@objectstack/core`'s security entry — the published surface lost them", () => {
const entry: Record<string, unknown> = securityEntry;
expect('reportLegacyPlatformAdminGrant' in entry).toBe(false);
expect('resetLegacyPlatformAdminGrantReport' in entry).toBe(false);
// Positive control on the same entry: its sibling config exports are still
Expand Down
1 change: 1 addition & 0 deletions packages/lint/src/lazy-deps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ describe('lazy dependency loading (kernel boot-path contract)', () => {

it('loads each dep lazily in-process and the gates still work', async () => {
const req = createRequire(import.meta.url);
// Kept in-case on purpose: loading the barrel IS this case's subject, budgeted by COLD_LOAD_TIMEOUT_MS.
const {
validateReactPages,
validateReactPageProps,
Expand Down
14 changes: 12 additions & 2 deletions packages/lint/src/validate-predicate-path-refs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ import {
PREDICATE_RHS_PATH_SHAPED,
} from './validate-predicate-path-refs.js';
import { AUTHORING_RULES } from './authoring-rules.js';
// The published barrel is loaded HERE, at module top, and not by a dynamic
// import inside the case that reads the id off it. That import loads the whole
// `@objectstack/lint` index graph, and inside a case the load is charged to
// vitest's per-case budget (5000ms by default), so the case's verdict would
// turn on how loaded the machine is. At module top the same load is charged to
// the COLLECT phase, where no per-case budget applies. The case loses nothing:
// it asserts an id's value and identity only. `lazy-deps.test.ts` is the one
// file here that keeps its barrel load inside a case, because that load is its
// subject. Same reasoning as the core precedent
// `packages/core/src/service-resolution-discriminator.contract.test.ts`.
import * as barrel from './index.js';

// ── A miniature target schema, so the traversal is pinned against a shape the
// test fully controls rather than against whatever `FieldSchema` happens to
Expand Down Expand Up @@ -372,8 +383,7 @@ describe('validatePredicatePathRefs — path-shaped right-hand side (#7659)', ()
expect(rhs('data.name == $b')).toEqual([]);
});

it('emits the id the published barrel exports', async () => {
const barrel = await import('./index.js');
it('emits the id the published barrel exports', () => {
expect(barrel.PREDICATE_RHS_PATH_SHAPED).toBe('predicate-rhs-path-shaped');
expect(rhs('data.name == data.type')[0].rule).toBe(barrel.PREDICATE_RHS_PATH_SHAPED);
});
Expand Down
15 changes: 13 additions & 2 deletions packages/objectql/src/system-write-organization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ import {
SystemWriteOrganizationRequiredError,
SYSTEM_WRITE_ORGANIZATION_REQUIRED_CODE,
} from './tenancy/system-write-organization.js';
// The package barrel is loaded HERE, at module top, and not by a dynamic import
// inside the barrel case at the foot of this file. That import loads the whole
// `@objectstack/objectql` index graph, and inside a case the load is charged to
// vitest's per-case budget (5000ms by default): the case was measured timing
// out on a loaded box while its assertions held, so its verdict was a function
// of the machine rather than of the code. At module top the same load is
// charged to the COLLECT phase, where no per-case budget applies. The case
// loses nothing: it asserts symbol identity only, and the barrel itself only
// re-exports. Same reasoning, and the same shape, as the core precedent
// `packages/core/src/service-resolution-discriminator.contract.test.ts`.
import * as barrel from './index.js';

const ORG_ID = 'org_msokm9oaz0cal87q';
const SECOND_ORG_ID = 'org_second';
Expand Down Expand Up @@ -499,11 +510,11 @@ describe('#14936 the published recognizer for the org-less system-write refusal'
expect(pinned).toBe(SYSTEM_WRITE_ORGANIZATION_REQUIRED_CODE);
});

it('publishes both names from the package BARREL, not only from the module', async () => {
it('publishes both names from the package BARREL, not only from the module', () => {
// The card's landing surface is "the module plus that package's index.ts
// export" - a consumer reaches these by bare specifier, so an export that
// exists only on the deep module is not the affordance that was asked for.
const barrel = await import('./index.js');
// `barrel` is the module-top import (see the imports for why it is there).
expect(barrel.SYSTEM_WRITE_ORGANIZATION_REQUIRED_CODE).toBe(SYSTEM_WRITE_ORGANIZATION_REQUIRED_CODE);
expect(barrel.isSystemWriteOrganizationRequiredError).toBe(isSystemWriteOrganizationRequiredError);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@
// the seam is wired. The source has to be MOVED for the two to differ, which is
// what the mock below does.

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import { withSourceFallback, findStaleFills } from '@objectstack/platform-objects/apps';
import { enObjects } from './en.objects.generated.js';
import { esESObjects } from './es-ES.objects.generated.js';
import { esESGeneratedSourceHashes } from './es-ES.source-hashes.generated.js';
// The barrel as committed, loaded HERE, at module top. Both of this file's
// barrel loads happen at module top and neither inside a case: a fresh load of
// the barrel and its bundles inside a case is charged to vitest's per-case
// budget (5000ms by default), so the verdict would turn on how loaded the
// machine is, while at module top the same load is charged to the COLLECT
// phase, where no per-case budget applies. The second load, against a moved
// source, is below `revisedSource`. Same reasoning as the core precedent
// `packages/core/src/service-resolution-discriminator.contract.test.ts`.
import { SharingTranslations } from './index.js';

/** The leaf the gap was measured on: recorded in es-ES only. */
const PATH = ['objects', 'sys_share_link', 'fields', 'token', 'label'] as const;
Expand All @@ -64,12 +73,18 @@ function revisedObjects() {
/** The same thing as a `TranslationData` — what the barrel passes as `source`. */
const revisedSource = () => ({ objects: revisedObjects() });

describe('SharingTranslations — the provenance companion is read at serving time', () => {
beforeEach(() => {
vi.resetModules();
vi.doUnmock('./en.objects.generated.js');
});
// The SAME barrel, evaluated a second time with the source string behind the
// recorded leaf revised. This setup has to run before the load it shapes, which
// is why it sits here at module top rather than in a hook: `resetModules` drops
// the copy the static import above cached, so the import below evaluates the
// barrel afresh against the mock, and `doUnmock` takes the mock straight back
// out, so the static bindings and every case see the committed bundles.
vi.resetModules();
vi.doMock('./en.objects.generated.js', () => ({ enObjects: revisedObjects() }));
const { SharingTranslations: servedAfterSourceMoved } = await import('./index.js');
vi.doUnmock('./en.objects.generated.js');

describe('SharingTranslations — the provenance companion is read at serving time', () => {
it('the leaf under test is recorded in es-ES and is a byte copy of the current source', () => {
const path = PATH.join('.');
expect(esESGeneratedSourceHashes[path]).toBeTypeOf('string');
Expand All @@ -81,23 +96,20 @@ describe('SharingTranslations — the provenance companion is read at serving ti
expect(stale.map((s) => s.path)).toEqual([PATH.join('.')]);
});

it('SERVES the current source when the source moves under the recorded leaf', async () => {
vi.doMock('./en.objects.generated.js', () => ({ enObjects: revisedObjects() }));
const { SharingTranslations } = await import('./index.js');
expect(read(SharingTranslations['es-ES'])).toBe(REVISED);
it('SERVES the current source when the source moves under the recorded leaf', () => {
expect(read(servedAfterSourceMoved['es-ES'])).toBe(REVISED);
// The locales with no record for this path are legacy-trusted and untouched —
// recovery is per-locale, which is the half of ruling #8765 Option B that a
// blanket "fall back to source" would have destroyed.
expect(read(SharingTranslations['zh-CN'])).toBe('令牌');
expect(read(servedAfterSourceMoved['zh-CN'])).toBe('令牌');
});

it('NEGATIVE CONTROL: the same bundle with no companion serves the superseded draft', () => {
const unserved = withSourceFallback({ objects: esESObjects }, revisedSource(), undefined, undefined);
expect(read(unserved)).toBe('Token');
});

it('substitutes nothing while the source has not moved', async () => {
const { SharingTranslations } = await import('./index.js');
it('substitutes nothing while the source has not moved', () => {
expect(read(SharingTranslations['es-ES'])).toBe(read({ objects: enObjects }));
});
});
Loading