feat: add changelog highlights to auto-update notifications (#1286)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Ralph Khreish
2025-10-10 18:49:59 +02:00
committed by GitHub
parent aaf903ff2f
commit f12a16d096
5 changed files with 214 additions and 14 deletions

View File

@@ -279,12 +279,14 @@ describe('Version comparison utility', () => {
describe('Update check functionality', () => {
let displayUpgradeNotification;
let parseChangelogHighlights;
let consoleLogSpy;
beforeAll(async () => {
// Import from @tm/cli instead of commands.js
const cliModule = await import('../../apps/cli/src/utils/auto-update.js');
displayUpgradeNotification = cliModule.displayUpgradeNotification;
parseChangelogHighlights = cliModule.parseChangelogHighlights;
});
beforeEach(() => {
@@ -302,6 +304,61 @@ describe('Update check functionality', () => {
expect(consoleLogSpy.mock.calls[0][0]).toContain('1.0.0');
expect(consoleLogSpy.mock.calls[0][0]).toContain('1.1.0');
});
test('displays upgrade notification with highlights when provided', () => {
const highlights = [
'Add Codex CLI provider with OAuth authentication',
'Cursor IDE custom slash command support',
'Move to AI SDK v5'
];
displayUpgradeNotification('1.0.0', '1.1.0', highlights);
expect(consoleLogSpy).toHaveBeenCalled();
const output = consoleLogSpy.mock.calls[0][0];
expect(output).toContain('Update Available!');
expect(output).toContain('1.0.0');
expect(output).toContain('1.1.0');
expect(output).toContain("What's New:");
expect(output).toContain(
'Add Codex CLI provider with OAuth authentication'
);
expect(output).toContain('Cursor IDE custom slash command support');
expect(output).toContain('Move to AI SDK v5');
});
test('displays upgrade notification without highlights section when empty array', () => {
displayUpgradeNotification('1.0.0', '1.1.0', []);
expect(consoleLogSpy).toHaveBeenCalled();
const output = consoleLogSpy.mock.calls[0][0];
expect(output).toContain('Update Available!');
expect(output).not.toContain("What's New:");
expect(output).toContain(
'Auto-updating to the latest version with new features and bug fixes'
);
});
test('parseChangelogHighlights validates version format to prevent ReDoS', () => {
const mockChangelog = `
## 1.0.0
### Minor Changes
- [#123](https://example.com) Thanks [@user](https://example.com)! - Test feature
`;
// Valid versions should work
expect(parseChangelogHighlights(mockChangelog, '1.0.0')).toEqual([
'Test feature'
]);
expect(parseChangelogHighlights(mockChangelog, '1.0.0-rc.1')).toEqual([]);
// Invalid versions should return empty array (ReDoS protection)
expect(parseChangelogHighlights(mockChangelog, 'invalid')).toEqual([]);
expect(parseChangelogHighlights(mockChangelog, '1.0')).toEqual([]);
expect(parseChangelogHighlights(mockChangelog, 'a.b.c')).toEqual([]);
expect(
parseChangelogHighlights(mockChangelog, '((((((((((((((((((((((((((((((a')
).toEqual([]);
});
});
// -----------------------------------------------------------------------------