mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-04 04:57:51 +00:00 
			
		
		
		
	# Pull Request Template
## Description
**Issue**
This PR fixes template variables in messages (e.g., {{customer.name}})
that were being incorrectly converted to clickable links by the
`MessageFormatter's linkify` functionality. This caused formatting
issues and broken links.
**Solution**
Added a `linkify` parameter to `MessageFormatter` to optionally disable
link conversion
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Screenshots**
**Before**
<img width="1012" alt="image"
src="https://github.com/user-attachments/assets/70abb238-b4d9-439d-9e51-c7513cf482fb"
/>
**After**
<img width="1012" alt="image"
src="https://github.com/user-attachments/assets/387acb74-674e-4b26-85cc-2d7190d256b1"
/>
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
		
	
		
			
				
	
	
		
			133 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import MessageFormatter from '../MessageFormatter';
 | 
						|
 | 
						|
describe('#MessageFormatter', () => {
 | 
						|
  describe('content with links', () => {
 | 
						|
    it('should format correctly', () => {
 | 
						|
      const message =
 | 
						|
        'Chatwoot is an opensource tool. [Chatwoot](https://www.chatwoot.com)';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        '<p>Chatwoot is an opensource tool. <a href="https://www.chatwoot.com" class="link" rel="noreferrer noopener nofollow" target="_blank">Chatwoot</a></p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
    it('should format correctly', () => {
 | 
						|
      const message =
 | 
						|
        'Chatwoot is an opensource tool. https://www.chatwoot.com';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        '<p>Chatwoot is an opensource tool. <a href="https://www.chatwoot.com" class="link" rel="noreferrer noopener nofollow" target="_blank">https://www.chatwoot.com</a></p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
    it('should not convert template variables to links when linkify is disabled', () => {
 | 
						|
      const message = 'Hey {{customer.name}}, check https://chatwoot.com';
 | 
						|
      const formatter = new MessageFormatter(message, false, false, false);
 | 
						|
      expect(formatter.formattedMessage).toMatch(
 | 
						|
        '<p>Hey {{customer.name}}, check https://chatwoot.com</p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('parses heading to strong', () => {
 | 
						|
    it('should format correctly', () => {
 | 
						|
      const message = '### opensource \n ## tool';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        `<h3>opensource</h3>
 | 
						|
<h2>tool</h2>`
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('content with image and has "cw_image_height" query at the end of URL', () => {
 | 
						|
    it('should set image height correctly', () => {
 | 
						|
      const message =
 | 
						|
        'Chatwoot is an opensource tool. ';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        '<p>Chatwoot is an opensource tool. <img src="http://chatwoot.com/chatwoot.png?cw_image_height=24px" alt="" style="height: 24px;" /></p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('should set image height correctly if its original size', () => {
 | 
						|
      const message =
 | 
						|
        'Chatwoot is an opensource tool. ';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        '<p>Chatwoot is an opensource tool. <img src="http://chatwoot.com/chatwoot.png?cw_image_height=auto" alt="" style="height: auto;" /></p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('should not set height', () => {
 | 
						|
      const message =
 | 
						|
        'Chatwoot is an opensource tool. ';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        '<p>Chatwoot is an opensource tool. <img src="http://chatwoot.com/chatwoot.png" alt="" /></p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('tweets', () => {
 | 
						|
    it('should return the same string if not tags or @mentions', () => {
 | 
						|
      const message = 'Chatwoot is an opensource tool';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(message);
 | 
						|
    });
 | 
						|
 | 
						|
    it('should add links to @mentions', () => {
 | 
						|
      const message =
 | 
						|
        '@chatwootapp is an opensource tool thanks @longnonexistenttwitterusername';
 | 
						|
      expect(
 | 
						|
        new MessageFormatter(message, true, false).formattedMessage
 | 
						|
      ).toMatch(
 | 
						|
        '<p><a href="http://twitter.com/chatwootapp" class="link" rel="noreferrer noopener nofollow" target="_blank">@chatwootapp</a> is an opensource tool thanks @longnonexistenttwitterusername</p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('should add links to #tags', () => {
 | 
						|
      const message = '#chatwootapp is an opensource tool';
 | 
						|
      expect(
 | 
						|
        new MessageFormatter(message, true, false).formattedMessage
 | 
						|
      ).toMatch(
 | 
						|
        '<p><a href="https://twitter.com/hashtag/chatwootapp" class="link" rel="noreferrer noopener nofollow" target="_blank">#chatwootapp</a> is an opensource tool</p>'
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('private notes', () => {
 | 
						|
    it('should return the same string if not tags or @mentions', () => {
 | 
						|
      const message = 'Chatwoot is an opensource tool';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(message);
 | 
						|
    });
 | 
						|
 | 
						|
    it('should add links to @mentions', () => {
 | 
						|
      const message =
 | 
						|
        '@chatwootapp is an opensource tool thanks @longnonexistenttwitterusername';
 | 
						|
      expect(
 | 
						|
        new MessageFormatter(message, false, true).formattedMessage
 | 
						|
      ).toMatch(message);
 | 
						|
    });
 | 
						|
 | 
						|
    it('should add links to #tags', () => {
 | 
						|
      const message = '#chatwootapp is an opensource tool';
 | 
						|
      expect(
 | 
						|
        new MessageFormatter(message, false, true).formattedMessage
 | 
						|
      ).toMatch(message);
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('plain text content', () => {
 | 
						|
    it('returns the plain text without HTML', () => {
 | 
						|
      const message =
 | 
						|
        '<b>Chatwoot is an opensource tool. https://www.chatwoot.com</b>';
 | 
						|
      expect(new MessageFormatter(message).plainText).toMatch(
 | 
						|
        'Chatwoot is an opensource tool. https://www.chatwoot.com'
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('#sanitize', () => {
 | 
						|
    it('sanitizes markup and removes all unnecessary elements', () => {
 | 
						|
      const message =
 | 
						|
        '[xssLink](javascript:alert(document.cookie))\n[normalLink](https://google.com)**I am a bold text paragraph**';
 | 
						|
      expect(new MessageFormatter(message).formattedMessage).toMatch(
 | 
						|
        `<p>[xssLink](javascript:alert(document.cookie))<br />
 | 
						|
<a href="https://google.com" class="link" rel="noreferrer noopener nofollow" target="_blank">normalLink</a><strong>I am a bold text paragraph</strong></p>`
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |