Skip to content

Commit 7451b58

Browse files
authored
fix(message-parser): Fix payload generation for custom protocols (#799)
1 parent f471cc9 commit 7451b58

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

packages/message-parser/src/utils.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,19 @@ export const plain = generate('PLAIN_TEXT');
6767
export const strike = generate('STRIKE');
6868

6969
export const codeLine = generate('CODE_LINE');
70+
71+
const isValidLink = (link: string) => {
72+
try {
73+
return Boolean(new URL(link));
74+
} catch (error) {
75+
return false;
76+
}
77+
};
7078
export const link = (() => {
7179
const fn = generate('LINK');
7280

7381
return (src: string, label?: Markup) => {
74-
const href =
75-
src !== '' && !src.startsWith('http') && !src.startsWith('//')
76-
? `//${src}`
77-
: src;
82+
const href = isValidLink(src) || src.startsWith('//') ? src : `//${src}`;
7883

7984
return fn({ src: plain(href), label: label || plain(src) });
8085
};

packages/message-parser/tests/link.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ test.each([
235235
'http:/ google.com',
236236
[paragraph([plain('http:/ '), link('//google.com', plain('google.com'))])],
237237
],
238+
[
239+
'[custom](custom://google.com)',
240+
[paragraph([link('custom://google.com', plain('custom'))])],
241+
],
238242
])('parses %p', (input, output) => {
239243
expect(parser(input)).toMatchObject(output);
240244
});

packages/message-parser/tests/url.test.ts

+50
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,56 @@ test.each([
5858
[paragraph([link('ftp://user:pass@localhost:21/etc/hosts')])],
5959
],
6060
['ssh://test@test.test', [paragraph([link('ssh://test@test.test')])]],
61+
['custom://test@test.test', [paragraph([link('custom://test@test.test')])]],
62+
['ftp://test.com', [paragraph([link('ftp://test.com')])]],
6163
])('parses %p', (input, output) => {
6264
expect(parser(input)).toMatchObject(output);
6365
});
66+
67+
describe('link helper function', () => {
68+
it('should preserve the original protocol if the protocol is http or https', () => {
69+
expect(link('https://rocket.chat/test')).toMatchObject({
70+
type: 'LINK',
71+
value: {
72+
src: plain('https://rocket.chat/test'),
73+
label: plain('https://rocket.chat/test'),
74+
},
75+
});
76+
expect(link('http://rocket.chat/test')).toMatchObject({
77+
type: 'LINK',
78+
value: {
79+
src: plain('http://rocket.chat/test'),
80+
label: plain('http://rocket.chat/test'),
81+
},
82+
});
83+
});
84+
85+
it('should preserve the original protocol even if for custom protocols', () => {
86+
expect(link('custom://rocket.chat/test')).toMatchObject({
87+
type: 'LINK',
88+
value: {
89+
src: plain('custom://rocket.chat/test'),
90+
label: plain('custom://rocket.chat/test'),
91+
},
92+
});
93+
});
94+
95+
it('should return // as the protocol if // is the protocol specified', () => {
96+
expect(link('//rocket.chat/test')).toMatchObject({
97+
type: 'LINK',
98+
value: {
99+
src: plain('//rocket.chat/test'),
100+
label: plain('//rocket.chat/test'),
101+
},
102+
});
103+
});
104+
it("should return an url concatenated '//' if the url has no protocol", () => {
105+
expect(link('rocket.chat/test')).toMatchObject({
106+
type: 'LINK',
107+
value: {
108+
src: plain('//rocket.chat/test'),
109+
label: plain('rocket.chat/test'),
110+
},
111+
});
112+
});
113+
});

0 commit comments

Comments
 (0)