Files
bDS/tests/renderer/navigation/blogmarkTransformOutput.test.ts

166 lines
5.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
buildBlogmarkTransformOutputEntries,
buildBlogmarkTransformToastNotifications,
parseBlogmarkCreatedEventPayload,
shouldAutoOpenPanelForOutputEntries,
} from '../../../src/renderer/navigation/blogmarkTransformOutput';
describe('parseBlogmarkCreatedEventPayload', () => {
it('parses legacy payload shape where event value is the post itself', () => {
const payload = parseBlogmarkCreatedEventPayload({ id: 'post-1', title: 'Legacy post' });
expect(payload).toEqual({
post: { id: 'post-1', title: 'Legacy post' },
transform: undefined,
});
});
it('parses new payload shape with post and transform metadata', () => {
const payload = parseBlogmarkCreatedEventPayload({
post: { id: 'post-2', title: 'With transforms' },
transform: {
appliedScriptIds: ['a', 'b'],
errors: [{ scriptId: 'c', scriptSlug: 'c', message: 'boom' }],
toasts: ['done'],
},
});
expect(payload).toEqual({
post: { id: 'post-2', title: 'With transforms' },
transform: {
appliedScriptIds: ['a', 'b'],
errors: [{ scriptId: 'c', scriptSlug: 'c', message: 'boom' }],
toasts: ['done'],
},
});
});
});
describe('buildBlogmarkTransformOutputEntries', () => {
const t = (key: string, values?: Record<string, string | number>) => {
if (key === 'app.blogmark.transforms.summary') {
return `summary:${values?.applied}:${values?.failed}`;
}
if (key === 'app.blogmark.transforms.appliedList') {
return `applied:${values?.scripts}`;
}
if (key === 'app.blogmark.transforms.failed') {
return `failed:${values?.script}:${values?.message}`;
}
if (key === 'app.blogmark.transforms.toast') {
return `toast:${values?.message}`;
}
if (key === 'app.blogmark.transforms.errorToast') {
return `error-toast:${values?.count}`;
}
return key;
};
it('returns empty list when no transform info is provided', () => {
expect(buildBlogmarkTransformOutputEntries(undefined, t)).toEqual([]);
});
it('returns summary and applied list entries for successful transforms', () => {
const entries = buildBlogmarkTransformOutputEntries(
{
appliedScriptIds: ['alpha', 'beta'],
errors: [],
toasts: [],
},
t,
);
expect(entries).toHaveLength(2);
expect(entries[0]?.kind).toBe('result');
expect(entries[0]?.message).toBe('summary:2:0');
expect(entries[1]?.kind).toBe('result');
expect(entries[1]?.message).toBe('applied:alpha, beta');
});
it('returns one error entry per failed transform', () => {
const entries = buildBlogmarkTransformOutputEntries(
{
appliedScriptIds: ['alpha'],
errors: [
{ scriptId: 'broken', scriptSlug: 'broken_slug', message: 'boom' },
{ scriptId: 'bad', scriptSlug: 'bad_slug', message: 'invalid output' },
],
toasts: ['Step finished'],
},
t,
);
expect(entries).toHaveLength(5);
expect(entries[0]?.message).toBe('summary:1:2');
expect(entries[1]?.message).toBe('applied:alpha');
expect(entries[2]?.kind).toBe('result');
expect(entries[2]?.message).toBe('toast:Step finished');
expect(entries[3]?.kind).toBe('error');
expect(entries[3]?.message).toBe('failed:broken_slug:boom');
expect(entries[4]?.kind).toBe('error');
expect(entries[4]?.message).toBe('failed:bad_slug:invalid output');
});
});
describe('buildBlogmarkTransformToastNotifications', () => {
const t = (key: string, values?: Record<string, string | number>) => {
if (key === 'app.blogmark.transforms.errorToast') {
return `error-toast:${values?.count}`;
}
return key;
};
it('returns toast notifications for script toasts and aggregated errors', () => {
const notifications = buildBlogmarkTransformToastNotifications({
appliedScriptIds: ['alpha'],
toasts: ['Saved one item'],
errors: [{ scriptId: 'broken', scriptSlug: 'broken_slug', message: 'boom' }],
}, t);
expect(notifications).toEqual([
{ kind: 'success', message: 'Saved one item' },
{ kind: 'error', message: 'error-toast:1' },
]);
});
});
describe('shouldAutoOpenPanelForOutputEntries', () => {
it('returns false for empty entries', () => {
expect(shouldAutoOpenPanelForOutputEntries([])).toBe(false);
});
it('returns false when all entries are result kind', () => {
expect(shouldAutoOpenPanelForOutputEntries([
{ kind: 'result', message: 'summary:2:0' },
{ kind: 'result', message: 'applied:alpha, beta' },
])).toBe(false);
});
it('returns true when entries contain an error', () => {
expect(shouldAutoOpenPanelForOutputEntries([
{ kind: 'result', message: 'summary:1:1' },
{ kind: 'error', message: 'failed:broken:boom' },
])).toBe(true);
});
it('returns true when entries contain stdout', () => {
expect(shouldAutoOpenPanelForOutputEntries([
{ kind: 'result', message: 'summary:1:0' },
{ kind: 'stdout', message: 'hello from python' },
])).toBe(true);
});
it('returns true when entries contain only errors', () => {
expect(shouldAutoOpenPanelForOutputEntries([
{ kind: 'error', message: 'uncaught exception' },
])).toBe(true);
});
it('returns true when entries contain only stdout', () => {
expect(shouldAutoOpenPanelForOutputEntries([
{ kind: 'stdout', message: 'debug output' },
])).toBe(true);
});
});