Skip to content

Commit 76b1da0

Browse files
committed
test(service-mailbox): the three objects publish clean through the object write door
Claude-Session: https://claude.ai/code/session_013tMiyVNzCwaUhgfUe6gg8y Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4777cb3 commit 76b1da0

4 files changed

Lines changed: 36 additions & 0 deletions

File tree

‎packages/services/service-mailbox/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"@objectstack/spec": "workspace:*"
3030
},
3131
"devDependencies": {
32+
"@objectstack/lint": "workspace:*",
3233
"@types/node": "^26.6.3",
3334
"typescript": "^6.0.3",
3435
"vitest": "^4.1.11"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { describe, expect, it } from 'vitest';
4+
import { runRuntimeAuthoringRules } from '@objectstack/lint';
5+
import { SysMailAssociation, SysMailbox, SysMailMessage } from './index.js';
6+
7+
/**
8+
* The three inbound-mail objects publish clean through the object write door:
9+
* every field reference they carry (`highlightFields`, `nameField`,
10+
* `titleFormat`, index columns) resolves. Driven through the real authoring
11+
* gate rather than by comparing keys, because the gate resolves injected system
12+
* columns and semantic aliases a key comparison does not. The control proves the
13+
* door ran: one dangling entry is refused at its path.
14+
*/
15+
describe('the inbound-mail objects — field references resolve at the object write door', () => {
16+
const objects = [SysMailbox, SysMailMessage, SysMailAssociation];
17+
const gate = (item: unknown) =>
18+
runRuntimeAuthoringRules({ type: 'object', item, context: { objects } });
19+
20+
it.each(objects.map((o) => [o.name, o] as const))('%s publishes clean', (_name, object) => {
21+
const result = gate(object);
22+
expect(result.errors, JSON.stringify(result.errors, null, 2)).toEqual([]);
23+
});
24+
25+
it('control: a dangling highlight field is refused at its path, so the cases above are not vacuous', () => {
26+
const result = gate({ ...SysMailMessage, highlightFields: ['subject', 'from'] });
27+
expect(result.errors.map((e) => `${e.rule} ${e.path}`)).toEqual([
28+
'object-field-ref-unknown objects.sys_mail_message.highlightFields[1]',
29+
]);
30+
});
31+
});

‎packages/services/service-mailbox/vitest.config.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default defineConfig({
2020
},
2121
resolve: {
2222
alias: [
23+
{ find: /^@objectstack\/lint$/, replacement: path.resolve(__dirname, '../../lint/src/index.ts') },
2324
{ find: /^@objectstack\/core$/, replacement: path.resolve(__dirname, '../../core/src/index.ts') },
2425
{ find: /^@objectstack\/platform-objects\/apps$/, replacement: path.resolve(__dirname, '../../platform-objects/src/apps/index.ts') },
2526
{ find: /^@objectstack\/spec$/, replacement: path.resolve(__dirname, '../../spec/src/index.ts') },

‎pnpm-lock.yaml‎

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)