diff --git a/webapp/src/components/link_tooltip/index.jsx b/webapp/src/components/link_tooltip/index.jsx
index 00bd19fa4..7f1448e18 100644
--- a/webapp/src/components/link_tooltip/index.jsx
+++ b/webapp/src/components/link_tooltip/index.jsx
@@ -8,7 +8,10 @@ import manifest from '@/manifest';
import {LinkTooltip} from './link_tooltip';
const mapStateToProps = (state) => {
- return {connected: state[`plugins-${manifest.id}`].connected};
+ return {
+ connected: state[`plugins-${manifest.id}`].connected,
+ enterpriseURL: state[`plugins-${manifest.id}`].enterpriseURL,
+ };
};
export default connect(mapStateToProps, null)(LinkTooltip);
diff --git a/webapp/src/components/link_tooltip/link_tooltip.jsx b/webapp/src/components/link_tooltip/link_tooltip.jsx
index feff6df51..88de4b63f 100644
--- a/webapp/src/components/link_tooltip/link_tooltip.jsx
+++ b/webapp/src/components/link_tooltip/link_tooltip.jsx
@@ -13,32 +13,43 @@ import {getLabelFontColor, hexToRGB} from '../../utils/styles';
const maxTicketDescriptionLength = 160;
-export const LinkTooltip = ({href, connected, show, theme}) => {
+export const LinkTooltip = ({href, connected, show, theme, enterpriseURL}) => {
const [data, setData] = useState(null);
useEffect(() => {
const initData = async () => {
- if (href.includes('github.com/')) {
- const [owner, repo, type, number] = href.split('github.com/')[1].split('/');
- if (!owner | !repo | !type | !number) {
- return;
+ let owner;
+ let repo;
+ let type;
+ let number;
+
+ if (enterpriseURL) {
+ const entURL = enterpriseURL.endsWith('/') ? enterpriseURL : enterpriseURL + '/';
+ if (href.startsWith(entURL)) {
+ [owner, repo, type, number] = href.substring(entURL.length).split('/');
}
+ } else if (href.includes('github.com/')) {
+ [owner, repo, type, number] = href.split('github.com/')[1].split('/');
+ }
- let res;
- switch (type) {
- case 'issues':
- res = await Client.getIssue(owner, repo, number);
- break;
- case 'pull':
- res = await Client.getPullRequest(owner, repo, number);
- break;
- }
- if (res) {
- res.owner = owner;
- res.repo = repo;
- res.type = type;
- }
- setData(res);
+ if (!owner || !repo || !type || !number) {
+ return;
+ }
+
+ let res;
+ switch (type) {
+ case 'issues':
+ res = await Client.getIssue(owner, repo, number);
+ break;
+ case 'pull':
+ res = await Client.getPullRequest(owner, repo, number);
+ break;
+ }
+ if (res) {
+ res.owner = owner;
+ res.repo = repo;
+ res.type = type;
}
+ setData(res);
};
// show is not provided for Mattermost Server < 5.28
@@ -47,7 +58,7 @@ export const LinkTooltip = ({href, connected, show, theme}) => {
}
initData();
- }, [connected, data, href, show]);
+ }, [connected, data, href, show, enterpriseURL]);
const getIconElement = () => {
const iconProps = {
@@ -117,7 +128,7 @@ export const LinkTooltip = ({href, connected, show, theme}) => {
- { getIconElement() }
+ {getIconElement()}
{/* info */}
@@ -135,7 +146,7 @@ export const LinkTooltip = ({href, connected, show, theme}) => {
{'Opened by '}
@@ -193,4 +204,5 @@ LinkTooltip.propTypes = {
connected: PropTypes.bool.isRequired,
theme: PropTypes.object.isRequired,
show: PropTypes.bool,
+ enterpriseURL: PropTypes.string,
};
diff --git a/webapp/src/components/link_tooltip/link_tooltip.test.jsx b/webapp/src/components/link_tooltip/link_tooltip.test.jsx
new file mode 100644
index 000000000..a6ad64282
--- /dev/null
+++ b/webapp/src/components/link_tooltip/link_tooltip.test.jsx
@@ -0,0 +1,96 @@
+import React from 'react';
+import {mount} from 'enzyme';
+
+import Client from '@/client';
+
+import {LinkTooltip} from './link_tooltip';
+
+jest.mock('@/client', () => ({
+ getIssue: jest.fn(),
+ getPullRequest: jest.fn(),
+}));
+
+jest.mock('react-markdown', () => () => );
+
+describe('LinkTooltip', () => {
+ const baseProps = {
+ href: 'https://github.com/mattermost/mattermost-plugin-github/issues/1',
+ connected: true,
+ show: true,
+ theme: {
+ centerChannelBg: '#ffffff',
+ centerChannelColor: '#333333',
+ },
+ enterpriseURL: '',
+ };
+
+ let wrapper;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ afterEach(() => {
+ if (wrapper && wrapper.length) {
+ wrapper.unmount();
+ }
+ });
+
+ test('should fetch issue for github.com link', () => {
+ // We need to use mount or wait for useEffect?
+ // shallow renders the component, useEffect is a hook.
+ // Enzyme shallow supports hooks in newer versions, but let's check if we need to manually trigger logic.
+ // The component uses useEffect to call initData.
+ wrapper = mount();
+ expect(Client.getIssue).toHaveBeenCalledWith('mattermost', 'mattermost-plugin-github', '1');
+ });
+
+ test('should fetch pull request for github.com link', () => {
+ const props = {
+ ...baseProps,
+ href: 'https://github.com/mattermost/mattermost-plugin-github/pull/2',
+ };
+ wrapper = mount();
+ expect(Client.getPullRequest).toHaveBeenCalledWith('mattermost', 'mattermost-plugin-github', '2');
+ });
+
+ test('should fetch issue for enterprise link', () => {
+ const props = {
+ ...baseProps,
+ href: 'https://github.example.com/mattermost/mattermost-plugin-github/issues/3',
+ enterpriseURL: 'https://github.example.com',
+ };
+ wrapper = mount();
+ expect(Client.getIssue).toHaveBeenCalledWith('mattermost', 'mattermost-plugin-github', '3');
+ });
+
+ test('should fetch pull request for enterprise link', () => {
+ const props = {
+ ...baseProps,
+ href: 'https://github.example.com/mattermost/mattermost-plugin-github/pull/4',
+ enterpriseURL: 'https://github.example.com',
+ };
+ wrapper = mount();
+ expect(Client.getPullRequest).toHaveBeenCalledWith('mattermost', 'mattermost-plugin-github', '4');
+ });
+
+ test('should handle enterprise URL with trailing slash', () => {
+ const props = {
+ ...baseProps,
+ href: 'https://github.example.com/mattermost/mattermost-plugin-github/issues/5',
+ enterpriseURL: 'https://github.example.com/',
+ };
+ wrapper = mount();
+ expect(Client.getIssue).toHaveBeenCalledWith('mattermost', 'mattermost-plugin-github', '5');
+ });
+
+ test('should not fetch if enterprise URL does not match', () => {
+ const props = {
+ ...baseProps,
+ href: 'https://other-github.com/mattermost/mattermost-plugin-github/issues/6',
+ enterpriseURL: 'https://github.example.com',
+ };
+ wrapper = mount();
+ expect(Client.getIssue).not.toHaveBeenCalled();
+ });
+});