import { Fixtures } from '~test/fixtures.ts'; import { logger } from '~test/util.ts'; import { smartTruncate } from './pr-body.ts'; const prBody = Fixtures.get('pr-body.txt'); describe('modules/platform/utils/pr-body', () => { describe('.smartTruncate', () => { it('truncates to 1000', () => { const body = smartTruncate(prBody, 1000); expect(body).toHaveLength(1000); expect(body.length < prBody.length).toBe(true); expect(body).toStartWith( '> ℹ️ **Note**\n> \n> This PR body was truncated due to platform limits.\n\n', ); // the release notes are the part that gets cut expect(body).toContain('### Release Notes'); expect(body).not.toContain('AWS ECR authentication support'); expect(body).toContain( '\n\n> ❗ **Important**\n> \n> ✂ PR body was truncated to here.\n', ); // smart truncation keeps the tail after the release notes expect(body).toContain('### Configuration'); expect(body).toEndWith( 'This PR has been generated by [Mend Renovate CLI](https://togithub.com/marketplace/renovate). View repository job log [here](https://renovatebot.com/dashboard#VisualOn/docker-images).\n', ); expect(logger.logger.debug).toHaveBeenCalledWith( 'Truncating PR body due to platform limitation of 1000 characters', ); }); it('truncates to 300 not smart', () => { const body = smartTruncate(prBody, 300); expect(body).toHaveLength(300); expect(body).toStartWith( '> ℹ️ **Note**\n> \n> This PR body was truncated due to platform limits.\n\n', ); // plain cut: the input is chopped mid-table and nothing after it is kept expect(body).toContain( '| [renovate/renovate](https://togithub.com/renovatebot/renovate) | final |', ); expect(body).not.toContain('### Release Notes'); expect(body).not.toContain('### Configuration'); expect(body).toEndWith( '\n\n> ❗ **Important**\n> \n> ✂ PR body was truncated to here.\n', ); expect(logger.logger.debug).toHaveBeenCalledWith( 'Truncating PR body due to platform limitation of 300 characters', ); }); it('includes truncation notice at end of truncated content (when "not smart")', () => { const body = smartTruncate(prBody, 300); expect(body).toContain('PR body was truncated to here'); expect(body).toHaveLength(300); }); it('includes truncation notice before Configuration section (when "smart")', () => { const body = smartTruncate(prBody, 3000); expect(body.length).toBeLessThanOrEqual(3000); expect(body).toContain('PR body was truncated to here'); expect(body).toContain('### Configuration'); expect(body.indexOf('PR body was truncated to here')).toBeLessThan( body.indexOf('### Configuration'), ); }); it('truncates content without release notes structure when notice fits', () => { const body = smartTruncate('x'.repeat(500), 200); expect(body).toHaveLength(200); expect(body).toContain('PR body was truncated to here'); }); it('truncates to below notice length with release notes structure', () => { const body = smartTruncate(prBody, 50); expect(body).toHaveLength(50); expect(body).not.toContain('PR body was truncated to here'); }); it('truncates to 10', () => { const body = smartTruncate('Lorem ipsum dolor sit amet', 10); expect(body).toBe('> ℹ️ **Not'); expect(logger.logger.debug).toHaveBeenCalledWith( 'Truncating PR body due to platform limitation of 10 characters', ); }); it('does not truncate', () => { expect(smartTruncate(prBody, 60000)).toEqual(prBody); }); }); });