diff options
author | Clement Ho <408677-ClemMakesApps@users.noreply.gitlab.com> | 2019-07-17 06:41:27 +0000 |
---|---|---|
committer | Clement Ho <408677-ClemMakesApps@users.noreply.gitlab.com> | 2019-07-17 06:41:27 +0000 |
commit | c1202131f47f8bcd5b3bc36119b99a3d5256343b (patch) | |
tree | 53284acc02a0a98976d5e483344e24eef44e934c | |
parent | c1d370c904b0f6a0b6ebb27ebc3a5df7b693c4bb (diff) | |
parent | f8afb3805cf8cd12085c0e93bc6dad111afbd9c2 (diff) | |
download | gitlab-ce-c1202131f47f8bcd5b3bc36119b99a3d5256343b.tar.gz |
Merge branch 'issue-zoom-url' into 'master'
Use backend to determine if issue desc contains zoom link
Closes #63282
See merge request gitlab-org/gitlab-ce!29910
-rw-r--r-- | app/assets/javascripts/issue_show/components/app.vue | 7 | ||||
-rw-r--r-- | app/assets/javascripts/issue_show/components/pinned_links.vue | 31 | ||||
-rw-r--r-- | app/helpers/issuables_helper.rb | 4 | ||||
-rw-r--r-- | changelogs/unreleased/issue-zoom-url.yml | 5 | ||||
-rw-r--r-- | lib/gitlab/zoom_link_extractor.rb | 21 | ||||
-rw-r--r-- | spec/frontend/issue_show/components/pinned_links_spec.js | 52 | ||||
-rw-r--r-- | spec/helpers/issuables_helper_spec.rb | 41 | ||||
-rw-r--r-- | spec/lib/gitlab/zoom_link_extractor_spec.rb | 24 |
8 files changed, 110 insertions, 75 deletions
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index de2a9664cde..9ca38d6bbfa 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -55,6 +55,11 @@ export default { required: false, default: true, }, + zoomMeetingUrl: { + type: String, + required: false, + default: null, + }, issuableRef: { type: String, required: true, @@ -342,7 +347,7 @@ export default { :title-text="state.titleText" :show-inline-edit-button="showInlineEditButton" /> - <pinned-links :description-html="state.descriptionHtml" /> + <pinned-links :zoom-meeting-url="zoomMeetingUrl" /> <description-component v-if="state.descriptionHtml" :can-update="canUpdate" diff --git a/app/assets/javascripts/issue_show/components/pinned_links.vue b/app/assets/javascripts/issue_show/components/pinned_links.vue index 7a54b26bc2b..965e8a3d751 100644 --- a/app/assets/javascripts/issue_show/components/pinned_links.vue +++ b/app/assets/javascripts/issue_show/components/pinned_links.vue @@ -8,40 +8,19 @@ export default { GlLink, }, props: { - descriptionHtml: { + zoomMeetingUrl: { type: String, - required: true, - }, - }, - 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; - }, ''); + required: false, + default: null, }, }, }; </script> <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 - :href="zoomHref" + :href="zoomMeetingUrl" target="_blank" class="btn btn-inverted btn-secondary btn-sm text-dark mb-3" > diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 67685ba4e1d..e2e007eee50 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -282,6 +282,10 @@ module IssuablesHelper 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) data[:groupPath] = parent.path else diff --git a/changelogs/unreleased/issue-zoom-url.yml b/changelogs/unreleased/issue-zoom-url.yml new file mode 100644 index 00000000000..e0bd5478192 --- /dev/null +++ b/changelogs/unreleased/issue-zoom-url.yml @@ -0,0 +1,5 @@ +--- +title: Extract zoom link from issue and pass to frontend +merge_request: 29910 +author: raju249 +type: added diff --git a/lib/gitlab/zoom_link_extractor.rb b/lib/gitlab/zoom_link_extractor.rb new file mode 100644 index 00000000000..d9994898a08 --- /dev/null +++ b/lib/gitlab/zoom_link_extractor.rb @@ -0,0 +1,21 @@ +# 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 diff --git a/spec/frontend/issue_show/components/pinned_links_spec.js b/spec/frontend/issue_show/components/pinned_links_spec.js index 50041667a61..77da3390918 100644 --- a/spec/frontend/issue_show/components/pinned_links_spec.js +++ b/spec/frontend/issue_show/components/pinned_links_spec.js @@ -5,10 +5,6 @@ import PinnedLinks from '~/issue_show/components/pinned_links.vue'; const localVue = createLocalVue(); 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', () => { let wrapper; @@ -27,7 +23,7 @@ describe('PinnedLinks', () => { localVue, sync: false, propsData: { - descriptionHtml: '', + zoomMeetingUrl: null, ...props, }, }); @@ -35,55 +31,15 @@ describe('PinnedLinks', () => { it('displays Zoom link', () => { createComponent({ - descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`, + zoomMeetingUrl: `<a href="${plainZoomUrl}">Zoom</a>`, }); expect(link.text).toBe('Join Zoom meeting'); }); - it('detects plain Zoom link', () => { + it('does not render if there are no links', () => { createComponent({ - descriptionHtml: `<a href="${plainZoomUrl}">Zoom</a>`, - }); - - 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>`, + zoomMeetingUrl: null, }); expect(wrapper.find(GlLink).exists()).toBe(false); diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 1d1446eaa30..3c8179460ac 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -202,5 +202,46 @@ describe IssuablesHelper do } expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data)) 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 diff --git a/spec/lib/gitlab/zoom_link_extractor_spec.rb b/spec/lib/gitlab/zoom_link_extractor_spec.rb new file mode 100644 index 00000000000..52387fc3688 --- /dev/null +++ b/spec/lib/gitlab/zoom_link_extractor_spec.rb @@ -0,0 +1,24 @@ +# 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 |