Commit f8afb380 authored by Rajendra kadam's avatar Rajendra kadam Committed by Clement Ho

Fetch latest link in the description for zoom link, add more tests and remove...

Fetch latest link in the description for zoom link, add more tests and remove frontend spec unnecessary tests
parent c1d370c9
...@@ -55,6 +55,11 @@ export default { ...@@ -55,6 +55,11 @@ export default {
required: false, required: false,
default: true, default: true,
}, },
zoomMeetingUrl: {
type: String,
required: false,
default: null,
},
issuableRef: { issuableRef: {
type: String, type: String,
required: true, required: true,
...@@ -342,7 +347,7 @@ export default { ...@@ -342,7 +347,7 @@ export default {
:title-text="state.titleText" :title-text="state.titleText"
:show-inline-edit-button="showInlineEditButton" :show-inline-edit-button="showInlineEditButton"
/> />
<pinned-links :description-html="state.descriptionHtml" /> <pinned-links :zoom-meeting-url="zoomMeetingUrl" />
<description-component <description-component
v-if="state.descriptionHtml" v-if="state.descriptionHtml"
:can-update="canUpdate" :can-update="canUpdate"
......
...@@ -8,40 +8,19 @@ export default { ...@@ -8,40 +8,19 @@ export default {
GlLink, GlLink,
}, },
props: { props: {
descriptionHtml: { zoomMeetingUrl: {
type: String, type: String,
required: true, required: false,
}, default: null,
},
computed: {
linksInDescription() {
const el = document.createElement('div');
el.innerHTML = this.descriptionHtml;
return [...el.querySelectorAll('a')].map(a => a.href);
},
// Detect links matching the following formats:
// Zoom Start links: https://zoom.us/s/<meeting-id>
// Zoom Join links: https://zoom.us/j/<meeting-id>
// Personal Zoom links: https://zoom.us/my/<meeting-id>
// Vanity Zoom links: https://gitlab.zoom.us/j/<meeting-id> (also /s and /my)
zoomHref() {
const zoomRegex = /^https:\/\/([\w\d-]+\.)?zoom\.us\/(s|j|my)\/.+/;
return this.linksInDescription.reduce((acc, currentLink) => {
let lastLink = acc;
if (zoomRegex.test(currentLink)) {
lastLink = currentLink;
}
return lastLink;
}, '');
}, },
}, },
}; };
</script> </script>
<template> <template>
<div v-if="zoomHref" class="border-bottom mb-3 mt-n2"> <div v-if="zoomMeetingUrl" class="border-bottom mb-3 mt-n2">
<gl-link <gl-link
:href="zoomHref" :href="zoomMeetingUrl"
target="_blank" target="_blank"
class="btn btn-inverted btn-secondary btn-sm text-dark mb-3" class="btn btn-inverted btn-secondary btn-sm text-dark mb-3"
> >
......
...@@ -282,6 +282,10 @@ module IssuablesHelper ...@@ -282,6 +282,10 @@ module IssuablesHelper
data[:hasClosingMergeRequest] = issuable.merge_requests_count(current_user) != 0 if issuable.is_a?(Issue) data[:hasClosingMergeRequest] = issuable.merge_requests_count(current_user) != 0 if issuable.is_a?(Issue)
zoom_links = Gitlab::ZoomLinkExtractor.new(issuable.description).links
data[:zoomMeetingUrl] = zoom_links.last if zoom_links.any?
if parent.is_a?(Group) if parent.is_a?(Group)
data[:groupPath] = parent.path data[:groupPath] = parent.path
else else
......
---
title: Extract zoom link from issue and pass to frontend
merge_request: 29910
author: raju249
type: added
# frozen_string_literal: true
# Detect links matching the following formats:
# Zoom Start links: https://zoom.us/s/<meeting-id>
# Zoom Join links: https://zoom.us/j/<meeting-id>
# Personal Zoom links: https://zoom.us/my/<meeting-id>
# Vanity Zoom links: https://gitlab.zoom.us/j/<meeting-id> (also /s and /my)
module Gitlab
class ZoomLinkExtractor
ZOOM_REGEXP = %r{https://(?:[\w-]+\.)?zoom\.us/(?:s|j|my)/\S+}.freeze
def initialize(text)
@text = text.to_s
end
def links
@text.scan(ZOOM_REGEXP)
end
end
end
...@@ -5,10 +5,6 @@ import PinnedLinks from '~/issue_show/components/pinned_links.vue'; ...@@ -5,10 +5,6 @@ import PinnedLinks from '~/issue_show/components/pinned_links.vue';
const localVue = createLocalVue(); const localVue = createLocalVue();
const plainZoomUrl = 'https://zoom.us/j/123456789'; const plainZoomUrl = 'https://zoom.us/j/123456789';
const vanityZoomUrl = 'https://gitlab.zoom.us/j/123456789';
const startZoomUrl = 'https://zoom.us/s/123456789';
const personalZoomUrl = 'https://zoom.us/my/hunter-zoloman';
const randomUrl = 'https://zoom.us.com';
describe('PinnedLinks', () => { describe('PinnedLinks', () => {
let wrapper; let wrapper;
...@@ -27,7 +23,7 @@ describe('PinnedLinks', () => { ...@@ -27,7 +23,7 @@ describe('PinnedLinks', () => {
localVue, localVue,
sync: false, sync: false,
propsData: { propsData: {
descriptionHtml: '', zoomMeetingUrl: null,
...props, ...props,
}, },
}); });
...@@ -35,55 +31,15 @@ describe('PinnedLinks', () => { ...@@ -35,55 +31,15 @@ describe('PinnedLinks', () => {
it('displays Zoom link', () => { it('displays Zoom link', () => {
createComponent({ createComponent({
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`, zoomMeetingUrl: `<a href="${plainZoomUrl}">Zoom</a>`,
}); });
expect(link.text).toBe('Join Zoom meeting'); expect(link.text).toBe('Join Zoom meeting');
}); });
it('detects plain Zoom link', () => { it('does not render if there are no links', () => {
createComponent({ createComponent({
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`, zoomMeetingUrl: null,
});
expect(link.href).toBe(plainZoomUrl);
});
it('detects vanity Zoom link', () => {
createComponent({
descriptionHtml: `<a href="${vanityZoomUrl}">Zoom</a>`,
});
expect(link.href).toBe(vanityZoomUrl);
});
it('detects Zoom start meeting link', () => {
createComponent({
descriptionHtml: `<a href="${startZoomUrl}">Zoom</a>`,
});
expect(link.href).toBe(startZoomUrl);
});
it('detects personal Zoom room link', () => {
createComponent({
descriptionHtml: `<a href="${personalZoomUrl}">Zoom</a>`,
});
expect(link.href).toBe(personalZoomUrl);
});
it('only renders final Zoom link in description', () => {
createComponent({
descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a><a href="${vanityZoomUrl}">Zoom</a>`,
});
expect(link.href).toBe(vanityZoomUrl);
});
it('does not render for other links', () => {
createComponent({
descriptionHtml: `<a href="${randomUrl}">Some other link</a>`,
}); });
expect(wrapper.find(GlLink).exists()).toBe(false); expect(wrapper.find(GlLink).exists()).toBe(false);
......
...@@ -202,5 +202,46 @@ describe IssuablesHelper do ...@@ -202,5 +202,46 @@ describe IssuablesHelper do
} }
expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data)) expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data))
end end
describe '#zoomMeetingUrl in issue' do
let(:issue) { create(:issue, author: user, description: description) }
before do
assign(:project, issue.project)
end
context 'no zoom links in the issue description' do
let(:description) { 'issue text' }
it 'does not set zoomMeetingUrl' do
expect(helper.issuable_initial_data(issue))
.not_to include(:zoomMeetingUrl)
end
end
context 'no zoom links in the issue description if it has link but not a zoom link' do
let(:description) { 'issue text https://stackoverflow.com/questions/22' }
it 'does not set zoomMeetingUrl' do
expect(helper.issuable_initial_data(issue))
.not_to include(:zoomMeetingUrl)
end
end
context 'with two zoom links in description' do
let(:description) do
<<~TEXT
issue text and
zoom call on https://zoom.us/j/123456789 this url
and new zoom url https://zoom.us/s/lastone and some more text
TEXT
end
it 'sets zoomMeetingUrl value to the last url' do
expect(helper.issuable_initial_data(issue))
.to include(zoomMeetingUrl: 'https://zoom.us/s/lastone')
end
end
end
end end
end end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::ZoomLinkExtractor do
describe "#links" do
using RSpec::Parameterized::TableSyntax
where(:text, :links) do
'issue text https://zoom.us/j/123 and https://zoom.us/s/1123433' | %w[https://zoom.us/j/123 https://zoom.us/s/1123433]
'https://zoom.us/j/1123433 issue text' | %w[https://zoom.us/j/1123433]
'issue https://zoom.us/my/1123433 text' | %w[https://zoom.us/my/1123433]
'issue https://gitlab.com and https://gitlab.zoom.us/s/1123433' | %w[https://gitlab.zoom.us/s/1123433]
'https://gitlab.zoom.us/j/1123433' | %w[https://gitlab.zoom.us/j/1123433]
'https://gitlab.zoom.us/my/1123433' | %w[https://gitlab.zoom.us/my/1123433]
end
with_them do
subject { described_class.new(text).links }
it { is_expected.to eq(links) }
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment