Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-12-12 18:07:34 +00:00
parent 7530cf5ad8
commit 90859e80ca
35 changed files with 266 additions and 115 deletions

View File

@ -1,4 +1,4 @@
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.22-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33"
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33"
stages:
- sync

View File

@ -13,7 +13,7 @@
- .default-before_script
- .assets-compile-cache
- .only:changes-code-backstage-qa
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-git-2.22-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-graphicsmagick-1.3.33-docker-19.03.1
image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-graphicsmagick-1.3.33-docker-19.03.1
stage: test
dependencies: ["setup-test-env"]
needs: ["setup-test-env"]

View File

@ -202,7 +202,7 @@
- name: redis:alpine
.use-pg10:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.22-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
services:
- name: postgres:10.9
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@ -216,7 +216,7 @@
- name: docker.elastic.co/elasticsearch/elasticsearch:5.6.12
.use-pg10-ee:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.22-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-10-graphicsmagick-1.3.33"
services:
- name: postgres:10.9
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]

View File

@ -232,9 +232,3 @@ dast:
- gl-dast-report.json
reports:
dast: gl-dast-report.json
only:
variables:
- $GITLAB_FEATURES =~ /\bdast\b/
except:
variables:
- $DAST_DISABLED

View File

@ -828,6 +828,13 @@ Please view this file on the master branch, on stable branches it's out of date.
- Don't send CI usage email notifications for self-hosted instances. !14809
## 12.0.10
### Fixed (1 change)
- Backport the new reliable fetcher to 12.0.9. !20532
## 12.0.7
### Security (3 changes)

View File

@ -8,6 +8,7 @@ entry.
- Update maven_file_name_regex for full string match.
## 12.5.3
### Fixed (4 changes)
@ -768,6 +769,7 @@ entry.
- Update maven_file_name_regex for full string match.
## 12.3.7
### Security (12 changes)
@ -1091,10 +1093,6 @@ entry.
- Updates tooltip of 'detached' label/state.
## 12.2.10
- No changes.
## 12.2.8
### Security (1 change)

View File

@ -242,7 +242,7 @@ gem 'slack-notifier', '~> 1.5.1'
gem 'hangouts-chat', '~> 0.0.5'
# Asana integration
gem 'asana', '~> 0.8.1'
gem 'asana', '~> 0.9'
# FogBugz integration
gem 'ruby-fogbugz', '~> 0.2.1'

View File

@ -63,11 +63,11 @@ GEM
graphql (>= 1.8)
rails (>= 4.2)
arel (9.0.0)
asana (0.8.1)
asana (0.9.3)
faraday (~> 0.9)
faraday_middleware (~> 0.9)
faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0)
oauth2 (~> 1.4)
asciidoctor (2.0.10)
asciidoctor-include-ext (0.3.1)
asciidoctor (>= 1.5.6, < 3.0.0)
@ -1119,7 +1119,7 @@ DEPENDENCIES
addressable (~> 2.5.2)
akismet (~> 2.0)
apollo_upload_server (~> 2.0.0.beta3)
asana (~> 0.8.1)
asana (~> 0.9)
asciidoctor (~> 2.0.10)
asciidoctor-include-ext (~> 0.3.1)
asciidoctor-plantuml (= 0.0.9)

View File

@ -43,7 +43,7 @@ const Api = {
releasesPath: '/api/:version/projects/:id/releases',
releasePath: '/api/:version/projects/:id/releases/:tag_name',
mergeRequestsPipeline: '/api/:version/projects/:id/merge_requests/:merge_request_iid/pipelines',
adminStatisticsPath: 'api/:version/application/statistics',
adminStatisticsPath: '/api/:version/application/statistics',
group(groupId, callback) {
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);

View File

@ -44,12 +44,14 @@ export default {
'Serverless|Your repository does not have a corresponding %{startTag}serverless.yml%{endTag} file.',
),
{ startTag: '<code>', endTag: '</code>' },
false,
);
},
noGitlabYamlConfigured() {
return sprintf(
s__('Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured.'),
{ startTag: '<code>', endTag: '</code>' },
false,
);
},
mismatchedServerlessFunctions() {
@ -58,6 +60,7 @@ export default {
"Serverless|The functions listed in the %{startTag}serverless.yml%{endTag} file don't match the namespace of your cluster.",
),
{ startTag: '<code>', endTag: '</code>' },
false,
);
},
},
@ -111,15 +114,9 @@ export default {
}}
</p>
<ul>
<li>
{{ noServerlessConfigFile }}
</li>
<li>
{{ noGitlabYamlConfigured }}
</li>
<li>
{{ mismatchedServerlessFunctions }}
</li>
<li v-html="noServerlessConfigFile"></li>
<li v-html="noGitlabYamlConfigured"></li>
<li v-html="mismatchedServerlessFunctions"></li>
<li>{{ s__('Serverless|The deploy job has not finished.') }}</li>
</ul>

View File

@ -32,14 +32,13 @@ export default {
};
</script>
<template>
<div class="title hide-collapsed" data-qa-selector="assignee_title">
<div class="title hide-collapsed">
{{ assigneeTitle }}
<i v-if="loading" aria-hidden="true" class="fa fa-spinner fa-spin block-loading"></i>
<a
v-if="editable"
class="js-sidebar-dropdown-toggle edit-link float-right"
href="#"
data-qa-selector="assignee_edit_link"
data-track-event="click_edit_button"
data-track-label="right_sidebar"
data-track-property="assignee"

View File

@ -81,12 +81,12 @@ http://app.asana.com/-/account_api'
def check_commit(message, push_msg)
# matches either:
# - #1234
# - https://app.asana.com/0/0/1234
# - https://app.asana.com/0/{project_gid}/{task_gid}
# optionally preceded with:
# - fix/ed/es/ing
# - close/s/d
# - closing
issue_finder = %r{(fix\w*|clos[ei]\w*+)?\W*(?:https://app\.asana\.com/\d+/\d+/(\d+)|#(\d+))}i
issue_finder = %r{(fix\w*|clos[ei]\w*+)?\W*(?:https://app\.asana\.com/\d+/\w+/(\w+)|#(\w+))}i
message.scan(issue_finder).each do |tuple|
# tuple will be
@ -94,7 +94,7 @@ http://app.asana.com/-/account_api'
taskid = tuple[2] || tuple[1]
begin
task = Asana::Task.find_by_id(client, taskid)
task = Asana::Resources::Task.find_by_id(client, taskid)
task.add_comment(text: "#{push_msg} #{message}")
if tuple[0]

View File

@ -13,30 +13,29 @@ module Issues
if can_add_link? && (link = parse_link(link))
begin
add_zoom_meeting(link)
success(_('Zoom meeting added'))
rescue ActiveRecord::RecordNotUnique
error(_('Failed to add a Zoom meeting'))
error(message: _('Failed to add a Zoom meeting'))
end
else
error(_('Failed to add a Zoom meeting'))
error(message: _('Failed to add a Zoom meeting'))
end
end
def remove_link
if can_remove_link?
remove_zoom_meeting
success(_('Zoom meeting removed'))
success(message: _('Zoom meeting removed'))
else
error(_('Failed to remove a Zoom meeting'))
error(message: _('Failed to remove a Zoom meeting'))
end
end
def can_add_link?
can_update_issue? && !@added_meeting
can_change_link? && !@added_meeting
end
def can_remove_link?
can_update_issue? && !!@added_meeting
can_change_link? && @issue.persisted? && !!@added_meeting
end
def parse_link(link)
@ -56,14 +55,29 @@ module Issues
end
def add_zoom_meeting(link)
ZoomMeeting.create(
zoom_meeting = new_zoom_meeting(link)
response =
if @issue.persisted?
# Save the meeting directly since we only want to update one meeting, not all
zoom_meeting.save
success(message: _('Zoom meeting added'))
else
success(message: _('Zoom meeting added'), payload: { zoom_meetings: [zoom_meeting] })
end
track_meeting_added_event
SystemNoteService.zoom_link_added(@issue, @project, current_user)
response
end
def new_zoom_meeting(link)
ZoomMeeting.new(
issue: @issue,
project: @issue.project,
project: @project,
issue_status: :added,
url: link
)
track_meeting_added_event
SystemNoteService.zoom_link_added(@issue, @project, current_user)
end
def remove_zoom_meeting
@ -72,16 +86,20 @@ module Issues
SystemNoteService.zoom_link_removed(@issue, @project, current_user)
end
def success(message)
ServiceResponse.success(message: message)
def success(message:, payload: nil)
ServiceResponse.success(message: message, payload: payload)
end
def error(message)
def error(message:)
ServiceResponse.error(message: message)
end
def can_update_issue?
can?(current_user, :update_issue, project)
def can_change_link?
if @issue.persisted?
can?(current_user, :update_issue, @project)
else
can?(current_user, :create_issue, @project)
end
end
end
end

View File

@ -0,0 +1,5 @@
---
title: Collect the date a SaaS trial starts on
merge_request: 20384
author:
type: added

View File

@ -0,0 +1,5 @@
---
title: Fix Zoom Quick Action server error when creating a GitLab Issue
merge_request: 21262
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Change Puma log format to JSON
merge_request: 21101
author:
type: other

View File

@ -0,0 +1,5 @@
---
title: Fix Asana integration
merge_request: 21501
author:
type: fixed

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
# Gitlab.com uses Snowplow for identifying users and events.
# https://gitlab.com/gitlab-org/gitlab/issues/6329
#
# SnowplowTracker write log into STDERR
# https://github.com/snowplow/snowplow-ruby-tracker/blob/39fcfa2be793f2e25e73087a9700abc93f43b5e8/lib/snowplow-tracker/emitters.rb#L23
# `LOGGER = Logger.new(STDERR)`
#
# In puma.rb, if `stdout_redirect` specify stderr, Puma will overwrite STDERR in:
# https://github.com/puma/puma/blob/b41205f5cacbc2ad0060472bdce68ba636f42175/lib/puma/runner.rb#L134
# `STDERR.reopen stderr, (append ? "a" : "w")`
# As a result, SnowplowTracker will log into Puma stderr, when Puma enabled.
#
# By default, SnowplowTracker uses default log formatter.
# When enable Puma, SnowplowTracker log is expected to be JSON format, as part of puma_stderr.log.
# Hence overwrite ::SnowplowTracker::LOGGER.formatter to JSON formatter
if defined?(::Puma) && defined?(::SnowplowTracker::LOGGER)
::SnowplowTracker::LOGGER.formatter = proc do |severity, datetime, progname, msg|
{ severity: severity, timestamp: datetime.utc.iso8601(3), pid: $$, progname: progname, message: msg }.to_json << "\n"
end
end

View File

@ -78,3 +78,11 @@ tag 'gitlab-puma-worker'
# value is 60 seconds.
#
worker_timeout 60
# Use json formatter
require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"
json_formatter = Gitlab::PumaLogging::JSONFormatter.new
log_formatter do |str|
json_formatter.call(str)
end

View File

@ -68,3 +68,11 @@ tag 'gitlab-puma-worker'
# value is 60 seconds.
#
worker_timeout 60
# Use json formatter
require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"
json_formatter = Gitlab::PumaLogging::JSONFormatter.new
log_formatter do |str|
json_formatter.call(str)
end

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddTrialStartsOnToGitlabSubscriptions < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_column :gitlab_subscriptions, :trial_starts_on, :date, null: true
add_column :gitlab_subscription_histories, :trial_starts_on, :date, null: true
end
end

View File

@ -1882,6 +1882,7 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do
t.integer "change_type", limit: 2
t.bigint "gitlab_subscription_id", null: false
t.datetime_with_timezone "created_at"
t.date "trial_starts_on"
t.index ["gitlab_subscription_id"], name: "index_gitlab_subscription_histories_on_gitlab_subscription_id"
end
@ -1896,6 +1897,7 @@ ActiveRecord::Schema.define(version: 2019_12_08_071112) do
t.integer "max_seats_used", default: 0
t.integer "seats", default: 0
t.boolean "trial", default: false
t.date "trial_starts_on"
t.index ["hosted_plan_id"], name: "index_gitlab_subscriptions_on_hosted_plan_id"
t.index ["namespace_id"], name: "index_gitlab_subscriptions_on_namespace_id", unique: true
end

View File

@ -393,6 +393,23 @@ It is stored at:
- `/var/log/gitlab/gitlab-rails/database_load_balancing.log` for Omnibus GitLab packages.
- `/home/git/gitlab/log/database_load_balancing.log` for installations from source.
## `elasticsearch.log`
Introduced in GitLab 12.6. This file lives in
`/var/log/gitlab/gitlab-rails/elasticsearch.log` for Omnibus GitLab
packages or in `/home/git/gitlab/log/elasticsearch.log` for installations
from source.
It logs information related to the Elasticsearch Integration including
errors during indexing or searching Elasticsearch.
Each line contains a JSON line that can be ingested by Elasticsearch, Splunk,
etc. For example:
```json
{"severity":"DEBUG","time":"2019-10-17T06:23:13.227Z","correlation_id":null,"message":"redacted_search_result","class_name":"Milestone","id":2,"ability":"read_milestone","current_user_id":2,"query":"project"}
```
[repocheck]: repository_checks.md
[Rack Attack]: ../security/rack_attack.md
[Rate Limit]: ../user/admin_area/settings/rate_limits_on_raw_endpoints.md

View File

@ -42,9 +42,9 @@ The current stages are:
## Default image
The default image is currently
`registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33`.
`registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33`.
It includes Ruby 2.6.3, Go 1.12, Git 2.22, Chrome 73, Node 12, Yarn 1.16,
It includes Ruby 2.6.3, Go 1.12, Git 2.24, Git LFS 2.9, Chrome 73, Node 12, Yarn 1.16,
PostgreSQL 9.6, and Graphics Magick 1.3.33.
The images used in our pipelines are configured in the

View File

@ -134,7 +134,7 @@ Make sure you have the right version of Git installed:
# Install Git
sudo apt-get install -y git-core
# Make sure Git is version 2.22.0 or higher
# Make sure Git is version 2.24.1 or higher (minimal supported version is 2.22.0)
git --version
```
@ -171,9 +171,9 @@ sudo make install
# Download and compile from source
cd /tmp
curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.22.0.tar.gz
echo 'a4b7e4365bee43caa12a38d646d2c93743d755d1cea5eab448ffb40906c9da0b git-2.22.0.tar.gz' | shasum -a256 -c - && tar -xzf git-2.22.0.tar.gz
cd git-2.22.0/
curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.24.1.tar.gz
echo 'ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02 git-2.24.1.tar.gz' | shasum -a256 -c - && tar -xzf git-2.24.1.tar.gz
cd git-2.24.1/
./configure --with-libpcre
make prefix=/usr/local all

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
module Gitlab
module Elasticsearch
class Logger < ::Gitlab::JsonLogger
def self.file_name_noext
'elasticsearch'
end
end
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
require 'json'
module Gitlab
module PumaLogging
class JSONFormatter
def call(str)
{ timestamp: Time.now.utc.iso8601(3), pid: $$, message: str }.to_json
end
end
end
end

View File

@ -183,6 +183,7 @@ module Gitlab
command :zoom do |link|
result = @zoom_service.add_link(link)
@execution_message[:zoom] = result.message
@updates.merge!(result.payload) if result.payload
end
desc _('Remove Zoom meeting')

View File

@ -26,11 +26,6 @@ module QA
element :avatar_image
end
view 'app/assets/javascripts/sidebar/components/assignees/assignee_title.vue' do
element :assignee_edit_link
element :assignee_title
end
view 'app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue' do
element :more_assignees_link
end
@ -61,16 +56,6 @@ module QA
element :new_note_form, 'attr: :note' # rubocop:disable QA/ElementWithPattern
end
def assign(user)
click_element(:assignee_edit_link)
select_user(user.username)
click_body
end
def assignee_title
find_element(:assignee_title)
end
def avatar_image_count
wait_assignees_block_finish_loading do
all_elements(:avatar_image).count
@ -168,19 +153,6 @@ module QA
end
end
def select_user(username)
find("#{element_selector_css(:assignee_block)} input").set(username)
dropdown_menu_user_link_selector = '.dropdown-menu-user-link'
at_username = "@#{username}"
ten_seconds = 10
wait(reload: false, max: ten_seconds, interval: 1) do
has_css?(dropdown_menu_user_link_selector, wait: ten_seconds, text: at_username)
end
find(dropdown_menu_user_link_selector, text: at_username).click
end
def wait_assignees_block_finish_loading
within_element(:assignee_block) do
wait(reload: false, max: 10, interval: 1) do

View File

@ -34,7 +34,7 @@ export const utilsMockData = [
content: [
{
text:
'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.11-git-2.22-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33',
'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33',
},
],
section: 'prepare-executor',

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::PumaLogging::JSONFormatter do
it "generate json format with timestamp and pid" do
Timecop.freeze( Time.utc(2019, 12, 04, 9, 10, 11, 123456)) do
expect(subject.call('log message')).to eq "{\"timestamp\":\"2019-12-04T09:10:11.123Z\",\"pid\":#{Process.pid},\"message\":\"log message\"}"
end
end
end

View File

@ -21,6 +21,7 @@ describe AsanaService do
describe 'Execute' do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:gid) { "123456789ABCD" }
def create_data_for_commits(*messages)
{
@ -48,32 +49,32 @@ describe AsanaService do
end
it 'calls Asana service to create a story' do
data = create_data_for_commits('Message from commit. related to #123456')
data = create_data_for_commits("Message from commit. related to ##{gid}")
expected_message = "#{data[:user_name]} pushed to branch #{data[:ref]} of #{project.full_name} ( #{data[:commits][0][:url]} ): #{data[:commits][0][:message]}"
d1 = double('Asana::Task')
d1 = double('Asana::Resources::Task')
expect(d1).to receive(:add_comment).with(text: expected_message)
expect(Asana::Task).to receive(:find_by_id).with(anything, '123456').once.and_return(d1)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, gid).once.and_return(d1)
@asana.execute(data)
end
it 'calls Asana service to create a story and close a task' do
data = create_data_for_commits('fix #456789')
d1 = double('Asana::Task')
d1 = double('Asana::Resources::Task')
expect(d1).to receive(:add_comment)
expect(d1).to receive(:update).with(completed: true)
expect(Asana::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(d1)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(d1)
@asana.execute(data)
end
it 'is able to close via url' do
data = create_data_for_commits('closes https://app.asana.com/19292/956299/42')
d1 = double('Asana::Task')
d1 = double('Asana::Resources::Task')
expect(d1).to receive(:add_comment)
expect(d1).to receive(:update).with(completed: true)
expect(Asana::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d1)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d1)
@asana.execute(data)
end
@ -84,28 +85,28 @@ describe AsanaService do
ref https://app.asana.com/19292/956299/42 and closing https://app.asana.com/19292/956299/12
EOF
data = create_data_for_commits(message)
d1 = double('Asana::Task')
d1 = double('Asana::Resources::Task')
expect(d1).to receive(:add_comment)
expect(d1).to receive(:update).with(completed: true)
expect(Asana::Task).to receive(:find_by_id).with(anything, '123').once.and_return(d1)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '123').once.and_return(d1)
d2 = double('Asana::Task')
d2 = double('Asana::Resources::Task')
expect(d2).to receive(:add_comment)
expect(d2).to receive(:update).with(completed: true)
expect(Asana::Task).to receive(:find_by_id).with(anything, '456').once.and_return(d2)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '456').once.and_return(d2)
d3 = double('Asana::Task')
d3 = double('Asana::Resources::Task')
expect(d3).to receive(:add_comment)
expect(Asana::Task).to receive(:find_by_id).with(anything, '789').once.and_return(d3)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '789').once.and_return(d3)
d4 = double('Asana::Task')
d4 = double('Asana::Resources::Task')
expect(d4).to receive(:add_comment)
expect(Asana::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d4)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d4)
d5 = double('Asana::Task')
d5 = double('Asana::Resources::Task')
expect(d5).to receive(:add_comment)
expect(d5).to receive(:update).with(completed: true)
expect(Asana::Task).to receive(:find_by_id).with(anything, '12').once.and_return(d5)
expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '12').once.and_return(d5)
@asana.execute(data)
end

View File

@ -27,12 +27,18 @@ describe Issues::ZoomLinkService do
end
end
shared_context 'insufficient permissions' do
shared_context 'insufficient issue update permissions' do
before do
project.add_guest(user)
end
end
shared_context 'insufficient issue create permissions' do
before do
expect(service).to receive(:can?).with(user, :create_issue, project).and_return(false)
end
end
describe '#add_link' do
shared_examples 'can add meeting' do
it 'appends the new meeting to zoom_meetings' do
@ -69,18 +75,40 @@ describe Issues::ZoomLinkService do
subject(:result) { service.add_link(zoom_link) }
context 'without existing Zoom meeting' do
include_examples 'can add meeting'
context 'when updating an issue' do
before do
allow(issue).to receive(:persisted?).and_return(true)
end
include_examples 'can add meeting'
context 'with insufficient issue update permissions' do
include_context 'insufficient issue update permissions'
include_examples 'cannot add meeting'
end
end
context 'when creating an issue' do
before do
allow(issue).to receive(:persisted?).and_return(false)
end
it 'creates a new zoom meeting' do
expect(result).to be_success
expect(result.payload[:zoom_meetings][0].url).to eq(zoom_link)
end
context 'with insufficient issue create permissions' do
include_context 'insufficient issue create permissions'
include_examples 'cannot add meeting'
end
end
context 'with invalid Zoom url' do
let(:zoom_link) { 'https://not-zoom.link' }
include_examples 'cannot add meeting'
end
context 'with insufficient permissions' do
include_context 'insufficient permissions'
include_examples 'cannot add meeting'
end
end
context 'with "added" Zoom meeting' do
@ -92,6 +120,7 @@ describe Issues::ZoomLinkService do
include_context '"added" Zoom meeting'
before do
allow(service).to receive(:can_add_link?).and_return(true)
allow(issue).to receive(:persisted?).and_return(true)
end
include_examples 'cannot add meeting'
@ -104,8 +133,8 @@ describe Issues::ZoomLinkService do
context 'without "added" zoom meeting' do
it { is_expected.to eq(true) }
context 'with insufficient permissions' do
include_context 'insufficient permissions'
context 'with insufficient issue update permissions' do
include_context 'insufficient issue update permissions'
it { is_expected.to eq(false) }
end
@ -156,12 +185,24 @@ describe Issues::ZoomLinkService do
context 'with Zoom meeting' do
include_context '"added" Zoom meeting'
context 'removes the link' do
context 'with existing issue' do
before do
allow(issue).to receive(:persisted?).and_return(true)
end
include_examples 'can remove meeting'
end
context 'with insufficient permissions' do
include_context 'insufficient permissions'
context 'without existing issue' do
before do
allow(issue).to receive(:persisted?).and_return(false)
end
include_examples 'cannot remove meeting'
end
context 'with insufficient issue update permissions' do
include_context 'insufficient issue update permissions'
include_examples 'cannot remove meeting'
end
end
@ -193,8 +234,8 @@ describe Issues::ZoomLinkService do
it { is_expected.to eq(true) }
end
context 'with insufficient permissions' do
include_context 'insufficient permissions'
context 'with insufficient issue update permissions' do
include_context 'insufficient issue update permissions'
it { is_expected.to eq(false) }
end
end

0
vendor/gitignore/C++.gitignore vendored Normal file → Executable file
View File

0
vendor/gitignore/Java.gitignore vendored Normal file → Executable file
View File