mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-11 17:23:48 +08:00
- 基于 TypeScript AST 精确识别 readFileSync 派生变量及其断言,仅删除不改写保留代码 - 断言全为源码文本的 it() 块整块移除,混合块中只剔除单条源码断言 - 清理随之失效的变量声明、空 it()/describe() 与无用 import,6 个文件因无用例残留而删除 - 累计移除 1283 处代码区间、8270 行,守卫基线由 130 条收敛至 12 条 - 全量测试失败集合无新增,TabManager 悬浮信息用例的 CRLF 误报一并消除 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
278 lines
9.5 KiB
TypeScript
278 lines
9.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
buildMessagePublishCommand,
|
|
createDefaultMessagePublishDraft,
|
|
getMessagePublishPresentation,
|
|
} from './messagePublish';
|
|
|
|
describe('messagePublish', () => {
|
|
it('localizes presentation copy through the supplied translator while keeping transport names raw', () => {
|
|
const t = (key: string) => key;
|
|
|
|
expect(getMessagePublishPresentation({ type: 'rabbitmq' }, t)).toMatchObject({
|
|
transportLabel: 'RabbitMQ Queue',
|
|
destinationLabel: 'Queue',
|
|
destinationPlaceholder: 'message_publish.presentation.rabbitmq.destination_placeholder',
|
|
destinationRequiredMessage: 'message_publish.presentation.rabbitmq.destination_required',
|
|
alertMessage: 'message_publish.presentation.rabbitmq.alert',
|
|
successHint: 'message_publish.presentation.rabbitmq.success_hint',
|
|
keyLabel: 'message_publish.presentation.key_label',
|
|
});
|
|
|
|
expect(getMessagePublishPresentation({ type: 'rocketmq' }, t)).toMatchObject({
|
|
transportLabel: 'RocketMQ Topic',
|
|
destinationLabel: 'Topic',
|
|
destinationPlaceholder: 'message_publish.presentation.rocketmq.destination_placeholder',
|
|
destinationRequiredMessage: 'message_publish.presentation.topic_required',
|
|
alertMessage: 'message_publish.presentation.rocketmq.alert',
|
|
successHint: 'message_publish.presentation.rocketmq.success_hint',
|
|
keyLabel: 'message_publish.presentation.keys_label',
|
|
keyPlaceholder: 'message_publish.presentation.rocketmq.key_placeholder',
|
|
tagPlaceholder: 'message_publish.presentation.rocketmq.tag_placeholder',
|
|
});
|
|
|
|
expect(getMessagePublishPresentation({ type: 'mqtt' }, t)).toMatchObject({
|
|
transportLabel: 'MQTT Topic',
|
|
destinationLabel: 'Topic',
|
|
destinationPlaceholder: 'message_publish.presentation.mqtt.destination_placeholder',
|
|
destinationRequiredMessage: 'message_publish.presentation.topic_required',
|
|
alertMessage: 'message_publish.presentation.mqtt.alert',
|
|
successHint: 'message_publish.presentation.mqtt.success_hint',
|
|
keyLabel: 'message_publish.presentation.key_label',
|
|
});
|
|
|
|
expect(getMessagePublishPresentation({ type: 'kafka' }, t)).toMatchObject({
|
|
transportLabel: 'Kafka Topic',
|
|
destinationLabel: 'Topic',
|
|
destinationPlaceholder: 'message_publish.presentation.kafka.destination_placeholder',
|
|
destinationRequiredMessage: 'message_publish.presentation.topic_required',
|
|
alertMessage: 'message_publish.presentation.kafka.alert',
|
|
successHint: 'message_publish.presentation.kafka.success_hint',
|
|
keyLabel: 'message_publish.presentation.key_label',
|
|
keyPlaceholder: 'message_publish.presentation.kafka.key_placeholder',
|
|
});
|
|
});
|
|
|
|
it('localizes command validation errors while preserving raw protocol details', () => {
|
|
const t = (key: string, params?: Record<string, unknown>) => (
|
|
params ? `${key} ${JSON.stringify(params)}` : key
|
|
);
|
|
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: '',
|
|
bodyMode: 'json',
|
|
body: '{"ok":true}',
|
|
},
|
|
t,
|
|
)).toThrow('message_publish.error.destination_required');
|
|
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: 'orders.events',
|
|
bodyMode: 'json',
|
|
body: '{bad',
|
|
},
|
|
t,
|
|
)).toThrow(/message_publish\.error\.invalid_json_detail .*message_publish\.field\.body/);
|
|
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: 'orders.events',
|
|
bodyMode: 'json',
|
|
body: '{"ok":true}',
|
|
headers: '["bad"]',
|
|
},
|
|
t,
|
|
)).toThrow(/message_publish\.error\.json_object_required .*"field":"Headers"/);
|
|
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'mqtt' },
|
|
{
|
|
destination: 'devices/+/telemetry',
|
|
bodyMode: 'json',
|
|
body: '{"ok":true}',
|
|
},
|
|
t,
|
|
)).toThrow('message_publish.error.mqtt_wildcard_topic');
|
|
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'not-a-message-bus' },
|
|
{
|
|
destination: 'orders.events',
|
|
bodyMode: 'json',
|
|
body: '{"ok":true}',
|
|
},
|
|
t,
|
|
)).toThrow(/message_publish\.error\.unsupported_type .*not-a-message-bus/);
|
|
});
|
|
|
|
it('builds a Kafka publish JSON command from JSON payload inputs', () => {
|
|
const result = buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: 'orders.events',
|
|
keyMode: 'json',
|
|
key: '{"tenant":"a"}',
|
|
bodyMode: 'json',
|
|
body: '{"id":1,"event":"created"}',
|
|
headers: '{"x-env":"dev"}',
|
|
},
|
|
);
|
|
|
|
expect(result.transportLabel).toBe('Kafka Topic');
|
|
expect(result.destinationLabel).toBe('orders.events');
|
|
expect(result.commandText).toContain('"publish": "orders.events"');
|
|
expect(result.commandText).toContain('"tenant": "a"');
|
|
expect(result.commandText).toContain('"id": 1');
|
|
expect(result.commandText).toContain('"x-env": "dev"');
|
|
});
|
|
|
|
it('keeps Kafka text payloads as plain strings', () => {
|
|
const result = buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: 'logs.app',
|
|
keyMode: 'text',
|
|
key: 'tenant-a',
|
|
bodyMode: 'text',
|
|
body: 'hello gonavi',
|
|
headers: '',
|
|
},
|
|
);
|
|
|
|
expect(result.commandText).toContain('"key": "tenant-a"');
|
|
expect(result.commandText).toContain('"value": "hello gonavi"');
|
|
});
|
|
|
|
it('rejects non-object Kafka headers', () => {
|
|
expect(() => buildMessagePublishCommand(
|
|
{ type: 'kafka' },
|
|
{
|
|
destination: 'logs.app',
|
|
bodyMode: 'json',
|
|
body: '{"ok":true}',
|
|
headers: '["bad"]',
|
|
},
|
|
)).toThrow(/Headers.*JSON object/);
|
|
});
|
|
|
|
it('seeds Kafka default publish draft with a JSON body example', () => {
|
|
expect(createDefaultMessagePublishDraft({ type: 'kafka' }, 'orders.events')).toMatchObject({
|
|
destination: 'orders.events',
|
|
keyMode: 'text',
|
|
bodyMode: 'json',
|
|
});
|
|
});
|
|
|
|
it('builds an MQTT publish JSON command with qos and retain flags', () => {
|
|
const result = buildMessagePublishCommand(
|
|
{ type: 'mqtt' },
|
|
{
|
|
destination: 'devices/device-001/telemetry',
|
|
qos: 1,
|
|
retain: true,
|
|
bodyMode: 'json',
|
|
body: '{"id":1,"event":"created"}',
|
|
},
|
|
);
|
|
|
|
expect(result.transportLabel).toBe('MQTT Topic');
|
|
expect(result.destinationLabel).toBe('devices/device-001/telemetry');
|
|
expect(result.commandText).toContain('"publish": "devices/device-001/telemetry"');
|
|
expect(result.commandText).toContain('"qos": 1');
|
|
expect(result.commandText).toContain('"retain": true');
|
|
});
|
|
|
|
it('seeds MQTT default publish draft with connection qos and retain defaults', () => {
|
|
expect(createDefaultMessagePublishDraft(
|
|
{ type: 'mqtt', database: 'devices/+/telemetry', connectionParams: 'qos=1&retain=true' },
|
|
'',
|
|
)).toMatchObject({
|
|
destination: 'devices/+/telemetry',
|
|
qos: 1,
|
|
retain: true,
|
|
bodyMode: 'json',
|
|
});
|
|
});
|
|
|
|
it('builds a RabbitMQ publish JSON command with routing and properties', () => {
|
|
const result = buildMessagePublishCommand(
|
|
{ type: 'rabbitmq', connectionParams: 'defaultQueue=orders.queue&exchange=events.topic' },
|
|
{
|
|
destination: 'orders.queue',
|
|
exchange: '',
|
|
routingKey: '',
|
|
bodyMode: 'json',
|
|
body: '{"id":1,"event":"created"}',
|
|
headers: '{"x-env":"dev"}',
|
|
properties: '{"content_type":"application/json"}',
|
|
},
|
|
);
|
|
|
|
expect(result.transportLabel).toBe('RabbitMQ Queue');
|
|
expect(result.destinationLabel).toBe('orders.queue');
|
|
expect(result.commandText).toContain('"publish": "orders.queue"');
|
|
expect(result.commandText).toContain('"exchange": "events.topic"');
|
|
expect(result.commandText).toContain('"routing_key": "orders.queue"');
|
|
expect(result.commandText).toContain('"content_type": "application/json"');
|
|
});
|
|
|
|
it('seeds RabbitMQ default publish draft with defaultQueue and exchange', () => {
|
|
expect(createDefaultMessagePublishDraft(
|
|
{ type: 'rabbitmq', connectionParams: 'defaultQueue=orders.queue&exchange=events.topic' },
|
|
'',
|
|
)).toMatchObject({
|
|
destination: 'orders.queue',
|
|
exchange: 'events.topic',
|
|
routingKey: 'orders.queue',
|
|
bodyMode: 'json',
|
|
});
|
|
});
|
|
|
|
it('builds a RocketMQ publish JSON command with tag, keys and delay level', () => {
|
|
const result = buildMessagePublishCommand(
|
|
{ type: 'rocketmq' },
|
|
{
|
|
destination: 'orders.events',
|
|
key: 'key-a,key-b',
|
|
tag: 'TagA',
|
|
delayLevel: 3,
|
|
bodyMode: 'json',
|
|
body: '{"id":1,"event":"created"}',
|
|
properties: '{"trace":"trace-1"}',
|
|
},
|
|
);
|
|
|
|
const command = JSON.parse(result.commandText);
|
|
expect(result.transportLabel).toBe('RocketMQ Topic');
|
|
expect(result.destinationLabel).toBe('orders.events');
|
|
expect(command).toMatchObject({
|
|
publish: 'orders.events',
|
|
tag: 'TagA',
|
|
delayLevel: 3,
|
|
properties: {
|
|
trace: 'trace-1',
|
|
},
|
|
});
|
|
expect(command.keys).toEqual(['key-a', 'key-b']);
|
|
expect(command.payload).toMatchObject({ id: 1, event: 'created' });
|
|
});
|
|
|
|
it('seeds RocketMQ default publish draft with connection tag and delay level defaults', () => {
|
|
expect(createDefaultMessagePublishDraft(
|
|
{ type: 'rocketmq', database: 'orders.events', connectionParams: 'tag=TagA&delayLevel=5' },
|
|
'',
|
|
)).toMatchObject({
|
|
destination: 'orders.events',
|
|
tag: 'TagA',
|
|
delayLevel: 5,
|
|
bodyMode: 'json',
|
|
});
|
|
});
|
|
});
|