diff options
22 files changed, 286 insertions, 83 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 9785e7626f9..f661a29d9d1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -563,7 +563,7 @@ Style/Proc: # branches, and conditions. Metrics/AbcSize: Enabled: true - Max: 57.08 + Max: 56.96 # This cop checks if the length of a block exceeds some maximum value. Metrics/BlockLength: @@ -164,7 +164,7 @@ gem 'rainbow', '~> 2.2' gem 'settingslogic', '~> 2.0.9' # Linear-time regex library for untrusted regular expressions -gem 're2', '~> 1.0.0' +gem 're2', '~> 1.1.0' # Misc diff --git a/Gemfile.lock b/Gemfile.lock index b295cf8cdf4..6ffff0d8735 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -656,7 +656,7 @@ GEM debugger-ruby_core_source (~> 1.3) rdoc (4.2.2) json (~> 1.4) - re2 (1.0.0) + re2 (1.1.0) recaptcha (3.0.0) json recursive-open-struct (1.0.0) @@ -1055,7 +1055,7 @@ DEPENDENCIES raindrops (~> 0.18) rblineprof (~> 0.3.6) rdoc (~> 4.2) - re2 (~> 1.0.0) + re2 (~> 1.1.0) recaptcha (~> 3.0) redcarpet (~> 3.4) redis (~> 3.2) diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 984d5398708..0b6cd71e651 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -3,18 +3,9 @@ class Admin::ProjectsController < Admin::ApplicationController before_action :group, only: [:show, :transfer] def index - params[:sort] ||= 'latest_activity_desc' - @projects = Project.with_statistics - @projects = @projects.in_namespace(params[:namespace_id]) if params[:namespace_id].present? - @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present? - @projects = @projects.with_push if params[:with_push].present? - @projects = @projects.abandoned if params[:abandoned].present? - @projects = @projects.where(last_repository_check_failed: true) if params[:last_repository_check_failed].present? - @projects = @projects.non_archived unless params[:archived].present? - @projects = @projects.personal(current_user) if params[:personal].present? - @projects = @projects.search(params[:name]) if params[:name].present? - @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]) + finder = Admin::ProjectsFinder.new(params: params, current_user: current_user) + @projects = finder.execute + @sort = finder.sort respond_to do |format| format.html diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb new file mode 100644 index 00000000000..a5ba791a513 --- /dev/null +++ b/app/finders/admin/projects_finder.rb @@ -0,0 +1,33 @@ +class Admin::ProjectsFinder + attr_reader :sort, :namespace_id, :visibility_level, :with_push, + :abandoned, :last_repository_check_failed, :archived, + :personal, :name, :page, :current_user + + def initialize(params:, current_user:) + @current_user = current_user + @sort = params.fetch(:sort) { 'latest_activity_desc' } + @namespace_id = params[:namespace_id] + @visibility_level = params[:visibility_level] + @with_push = params[:with_push] + @abandoned = params[:abandoned] + @last_repository_check_failed = params[:last_repository_check_failed] + @archived = params[:archived] + @personal = params[:personal] + @name = params[:name] + @page = params[:page] + end + + def execute + items = Project.with_statistics + items = items.in_namespace(namespace_id) if namespace_id.present? + items = items.where(visibility_level: visibility_level) if visibility_level.present? + items = items.with_push if with_push.present? + items = items.abandoned if abandoned.present? + items = items.where(last_repository_check_failed: true) if last_repository_check_failed.present? + items = items.non_archived unless archived.present? + items = items.personal(current_user) if personal.present? + items = items.search(name) if name.present? + items = items.sort(sort) + items.includes(:namespace).order("namespaces.path, projects.name ASC").page(page) + end +end diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index 30ca95eef7a..d81035e4eba 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -5,7 +5,7 @@ module Projects return error('New visibility level not allowed!') end - if project.has_container_registry_tags? + if renaming_project_with_container_registry_tags? return error('Cannot rename project because it contains container registry tags!') end @@ -44,6 +44,13 @@ module Projects true end + def renaming_project_with_container_registry_tags? + new_path = params[:path] + + new_path && new_path != project.path && + project.has_container_registry_tags? + end + def changing_default_branch? new_branch = params[:default_branch] diff --git a/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml b/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml new file mode 100644 index 00000000000..b8f30b52b18 --- /dev/null +++ b/changelogs/unreleased/28202_decrease_abc_threshold_step2.yml @@ -0,0 +1,4 @@ +--- +title: Decrease ABC threshold to 56.96 +merge_request: 11227 +author: Maxim Rydkin diff --git a/changelogs/unreleased/bvl-fix-invalid-po-files.yml b/changelogs/unreleased/bvl-fix-invalid-po-files.yml new file mode 100644 index 00000000000..b8a22a9e6df --- /dev/null +++ b/changelogs/unreleased/bvl-fix-invalid-po-files.yml @@ -0,0 +1,4 @@ +--- +title: Fix some invalid entries in PO files +merge_request: 13032 +author: diff --git a/changelogs/unreleased/fix-gb-project-update-with-registry-images.yml b/changelogs/unreleased/fix-gb-project-update-with-registry-images.yml new file mode 100644 index 00000000000..a54a34c71d4 --- /dev/null +++ b/changelogs/unreleased/fix-gb-project-update-with-registry-images.yml @@ -0,0 +1,4 @@ +--- +title: Fix editing project with container images present +merge_request: 13028 +author: diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb index 187a9e1145f..7ce2e9d636e 100644 --- a/lib/gitlab/untrusted_regexp.rb +++ b/lib/gitlab/untrusted_regexp.rb @@ -22,33 +22,9 @@ module Gitlab end def scan(text) - text = text.dup # modified in-place - results = [] - - loop do - match = scan_regexp.match(text) - break unless match - - # Ruby scan returns empty strings, not nil - groups = match.to_a.map(&:to_s) - - results << - if regexp.number_of_capturing_groups.zero? - groups[0] - else - groups[1..-1] - end - - matchsize = match.end(0) - - # No further matches - break unless matchsize.present? - - text.slice!(0, matchsize) - break unless text.present? - end - - results + matches = scan_regexp.scan(text).to_a + matches.map!(&:first) if regexp.number_of_capturing_groups.zero? + matches end def replace(text, rewrite) diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po index cf74abf81bc..04c61906c73 100644 --- a/locale/ja/gitlab.po +++ b/locale/ja/gitlab.po @@ -33,7 +33,8 @@ msgstr "%{commit_author_link}は%{commit_timeago}前、コミットしました msgid "1 pipeline" msgid_plural "%d pipelines" -msgstr[0] "%d 個のパイプライン" +msgstr[0] "1 個のパイプライン" +msgstr[1] "%d 個のパイプライン" msgid "A collection of graphs regarding Continuous Integration" msgstr "CIについてのグラフ" @@ -1135,8 +1136,7 @@ msgstr "" msgid "" "You are going to remove the fork relationship to source project " "%{forked_from_project}. Are you ABSOLUTELY sure?" -msgstr "元のプロジェクト (%{forked_from_project}) とのリレーションを削除しようとしています。\n" -"本当によろしいですか?" +msgstr "元のプロジェクト (%{forked_from_project}) とのリレーションを削除しようとしています。本当によろしいですか?" msgid "" "You are going to transfer %{project_name_with_namespace} to another owner. " @@ -1201,4 +1201,3 @@ msgstr "メール通知" msgid "parent" msgid_plural "parents" msgstr[0] "親" - diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po index c4918a4c920..78cf6d2dacc 100644 --- a/locale/pt_BR/gitlab.po +++ b/locale/pt_BR/gitlab.po @@ -6,13 +6,13 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-28 13:32+0200\n" +"POT-Creation-Date: 2017-07-05 08:50-0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-07-12 09:05-0400\n" -"Last-Translator: Leandro Nunes dos Santos <leandronunes@gmail.com>\n" "Language-Team: Portuguese (Brazil) (https://translate.zanata.org/project/view/GitLab)\n" +"PO-Revision-Date: 2017-07-14 01:17-0400\n" +"Last-Translator: Huang Tao <htve@outlook.com>\n" "Language: pt-BR\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" @@ -644,6 +644,12 @@ msgstr "Todos" msgid "PipelineSchedules|Inactive" msgstr "Inativo" +msgid "PipelineSchedules|Input variable key" +msgstr "PipelineSchedules|Chave da variável de entrada" + +msgid "PipelineSchedules|Input variable value" +msgstr "PipelineSchedules|Valor da variável de entrada" + msgid "PipelineSchedules|Next Run" msgstr "Próxima Execução" @@ -653,12 +659,18 @@ msgstr "Nenhum" msgid "PipelineSchedules|Provide a short description for this pipeline" msgstr "Digite uma descrição curta para esta pipeline" +msgid "PipelineSchedules|Remove variable row" +msgstr "PipelineSchedules|Remova a linha da variável" + msgid "PipelineSchedules|Take ownership" msgstr "Tornar-se proprietário" msgid "PipelineSchedules|Target" msgstr "Destino" +msgid "PipelineSchedules|Variables" +msgstr "PipelineSchedules|Variáveis" + msgid "PipelineSheduleIntervalPattern|Custom" msgstr "Personalizado" @@ -1151,6 +1163,15 @@ msgid "Withdraw Access Request" msgstr "Remover Requisição de Acesso" msgid "" +"You are going to remove %{group_name}.\n" +"Removed groups CANNOT be restored!\n" +"Are you ABSOLUTELY sure?" +msgstr "" +"Você vai remover %{group_name}.\n" +"Grupos removidos NÃO PODEM ser restaurados!\n" +"Você está ABSOLUTAMENTE certo?" + +msgid "" "You are going to remove %{project_name_with_namespace}.\n" "Removed project CANNOT be restored!\n" "Are you ABSOLUTELY sure?" diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po index 59a7eb6e1b3..f198fff8dce 100644 --- a/locale/uk/gitlab.po +++ b/locale/uk/gitlab.po @@ -379,7 +379,7 @@ msgid "Edit" msgstr "Редагувати" msgid "Edit Pipeline Schedule %{id}" -msgstr "Редагувати Розклад Конвеєра % {id}" +msgstr "Редагувати Розклад Конвеєра %{id}" msgid "Every day (at 4:00am)" msgstr "Кожен день (в 4:00 ранку)" @@ -1231,4 +1231,3 @@ msgid_plural "parents" msgstr[0] "джерело" msgstr[1] "джерела" msgstr[2] "джерел" - diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po index 47b72d7be1a..f471e7def25 100644 --- a/locale/zh_CN/gitlab.po +++ b/locale/zh_CN/gitlab.po @@ -29,7 +29,8 @@ msgstr "由 %{commit_author_link} 提交于 %{commit_timeago}" msgid "1 pipeline" msgid_plural "%d pipelines" -msgstr[0] "%d 条流水线" +msgstr[0] "1 条流水线" +msgstr[1] "%d 条流水线" msgid "A collection of graphs regarding Continuous Integration" msgstr "持续集成数据图" @@ -236,7 +237,7 @@ msgstr "创建新目录" msgid "" "Create a personal access token on your account to pull or push via " "%{protocol}." -msgstr "在帐户上创建个人访问令牌,以通过%{protocol}来拉取或推送。" +msgstr "在帐户上创建个人访问令牌,以通过 %{protocol} 来拉取或推送。" msgid "Create directory" msgstr "创建目录" @@ -1109,9 +1110,7 @@ msgid "" "You are going to remove %{project_name_with_namespace}.\n" "Removed project CANNOT be restored!\n" "Are you ABSOLUTELY sure?" -msgstr "即将要删除 %{project_name_with_namespace}。\n" -"已删除的项目无法恢复!\n" -"确定继续吗?" +msgstr "即将要删除 %{project_name_with_namespace}。已删除的项目无法恢复!确定继续吗?" msgid "" "You are going to remove the fork relationship to source project " @@ -1179,4 +1178,3 @@ msgstr "通知邮件" msgid "parent" msgid_plural "parents" msgstr[0] "父级" - diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po index 8a4e6da4ea9..1b7c39f8f62 100644 --- a/locale/zh_HK/gitlab.po +++ b/locale/zh_HK/gitlab.po @@ -28,7 +28,8 @@ msgstr "由 %{commit_author_link} 提交於 %{commit_timeago}" msgid "1 pipeline" msgid_plural "%d pipelines" -msgstr[0] "%d 條流水線" +msgstr[0] "1 條流水線" +msgstr[1] "%d 條流水線" msgid "A collection of graphs regarding Continuous Integration" msgstr "相關持續集成的圖像集合" @@ -1108,9 +1109,7 @@ msgid "" "You are going to remove %{project_name_with_namespace}.\n" "Removed project CANNOT be restored!\n" "Are you ABSOLUTELY sure?" -msgstr "即將要刪除 %{project_name_with_namespace}。\n" -"已刪除的項目無法恢複!\n" -"確定繼續嗎?" +msgstr "即將要刪除 %{project_name_with_namespace}。已刪除的項目無法恢複!確定繼續嗎?" msgid "" "You are going to remove the fork relationship to source project " @@ -1178,4 +1177,3 @@ msgstr "通知郵件" msgid "parent" msgid_plural "parents" msgstr[0] "父級" - diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po index 05173ed12c0..8d30a78145d 100644 --- a/locale/zh_TW/gitlab.po +++ b/locale/zh_TW/gitlab.po @@ -32,7 +32,8 @@ msgstr "%{commit_author_link} 在 %{commit_timeago} 送交" msgid "1 pipeline" msgid_plural "%d pipelines" -msgstr[0] "%d 條流水線" +msgstr[0] "1 條流水線" +msgstr[1] "%d 條流水線" msgid "A collection of graphs regarding Continuous Integration" msgstr "持續整合 (CI) 相關的圖表" @@ -1193,4 +1194,3 @@ msgstr "通知信" msgid "parent" msgid_plural "parents" msgstr[0] "上層" - diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb index 7dd69f550ac..e51d527bdf9 100644 --- a/spec/features/explore/new_menu_spec.rb +++ b/spec/features/explore/new_menu_spec.rb @@ -1,17 +1,13 @@ require 'spec_helper' feature 'Top Plus Menu', feature: true, js: true do - let(:user) { create :user } - let(:guest_user) { create :user} + let(:user) { create(:user) } let(:group) { create(:group) } let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) } let(:public_project) { create(:project, :public) } before do group.add_owner(user) - group.add_guest(guest_user) - - project.add_guest(guest_user) end context 'used by full user' do @@ -39,7 +35,7 @@ feature 'Top Plus Menu', feature: true, js: true do scenario 'click on New snippet shows new snippet page' do visit root_dashboard_path - + click_topmenuitem("New snippet") expect(page).to have_content('New Snippet') @@ -102,7 +98,12 @@ feature 'Top Plus Menu', feature: true, js: true do end context 'used by guest user' do + let(:guest_user) { create(:user) } + before do + group.add_guest(guest_user) + project.add_guest(guest_user) + sign_in(guest_user) end @@ -153,7 +154,7 @@ feature 'Top Plus Menu', feature: true, js: true do scenario 'has no New project for group menu item' do visit group_path(group) - + expect(find('.header-new.dropdown')).not_to have_selector('.header-new-group-project') end end @@ -168,5 +169,5 @@ feature 'Top Plus Menu', feature: true, js: true do def hasnot_topmenuitem(item_name) expect(find('.header-new.dropdown')).not_to have_content(item_name) - end + end end diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb new file mode 100644 index 00000000000..73038a4c8d6 --- /dev/null +++ b/spec/finders/admin/projects_finder_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +describe Admin::ProjectsFinder do + describe '#execute' do + let(:user) { create(:user) } + let(:group) { create(:group, :public) } + + let!(:private_project) do + create(:empty_project, :private, name: 'A', path: 'A') + end + + let!(:internal_project) do + create(:empty_project, :internal, group: group, name: 'B', path: 'B') + end + + let!(:public_project) do + create(:empty_project, :public, group: group, name: 'C', path: 'C') + end + + let!(:shared_project) do + create(:empty_project, :private, name: 'D', path: 'D') + end + + let(:params) { {} } + let(:current_user) { user } + let(:project_ids_relation) { nil } + let(:finder) { described_class.new(params: params, current_user: current_user) } + + subject { finder.execute.to_a } + + context 'without a user' do + let(:current_user) { nil } + + it { is_expected.to eq([shared_project, public_project, internal_project, private_project]) } + end + + context 'with a user' do + it { is_expected.to eq([shared_project, public_project, internal_project, private_project]) } + end + + context 'filter by namespace_id' do + let(:namespace) { create(:namespace) } + let!(:project_in_namespace) { create(:empty_project, namespace: namespace) } + let(:params) { { namespace_id: namespace.id } } + + it { is_expected.to eq([project_in_namespace]) } + end + + context 'filter by visibility_level' do + before do + private_project.add_master(user) + end + + context 'private' do + let(:params) { { visibility_level: Gitlab::VisibilityLevel::PRIVATE } } + + it { is_expected.to eq([shared_project, private_project]) } + end + + context 'internal' do + let(:params) { { visibility_level: Gitlab::VisibilityLevel::INTERNAL } } + + it { is_expected.to eq([internal_project]) } + end + + context 'public' do + let(:params) { { visibility_level: Gitlab::VisibilityLevel::PUBLIC } } + + it { is_expected.to eq([public_project]) } + end + end + + context 'filter by push' do + let(:pushed_event) { create(:event, :pushed) } + let!(:project_with_push) { pushed_event.project } + let(:params) { { with_push: true } } + + it { is_expected.to eq([project_with_push]) } + end + + context 'filter by abandoned' do + before do + private_project.update(last_activity_at: Time.zone.now - 6.months - 1.minute) + end + + let(:params) { { abandoned: true } } + + it { is_expected.to eq([private_project]) } + end + + context 'filter by last_repository_check_failed' do + before do + private_project.update(last_repository_check_failed: true) + end + + let(:params) { { last_repository_check_failed: true } } + + it { is_expected.to eq([private_project]) } + end + + context 'filter by archived' do + let!(:archived_project) { create(:empty_project, :public, :archived, name: 'E', path: 'E') } + + context 'archived=false' do + let(:params) { { archived: false } } + + it { is_expected.to match_array([shared_project, public_project, internal_project, private_project]) } + end + + context 'archived=true' do + let(:params) { { archived: true } } + + it { is_expected.to match_array([archived_project, shared_project, public_project, internal_project, private_project]) } + end + end + + context 'filter by personal' do + let!(:personal_project) { create(:empty_project, namespace: user.namespace) } + let(:params) { { personal: true } } + + it { is_expected.to eq([personal_project]) } + end + + context 'filter by name' do + let(:params) { { name: 'C' } } + + it { is_expected.to eq([shared_project, public_project, private_project]) } + end + + context 'sorting' do + let(:params) { { sort: 'name_asc' } } + + it { is_expected.to eq([private_project, internal_project, public_project, shared_project]) } + end + end +end diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index 8b925fd4e22..ebe5af56160 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -308,6 +308,20 @@ describe Gitlab::Ci::Trace::Stream do it { is_expected.to eq('65') } end + context 'long line' do + let(:data) { 'a' * 80000 + '100%' + 'a' * 80000 } + let(:regex) { '\d+\%' } + + it { is_expected.to eq('100') } + end + + context 'many lines' do + let(:data) { "foo\n" * 80000 + "100%\n" + "foo\n" * 80000 } + let(:regex) { '\d+\%' } + + it { is_expected.to eq('100') } + end + context 'empty regex' do let(:data) { 'foo' } let(:regex) { '' } diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb index 21d47b7897a..bed58d407ef 100644 --- a/spec/lib/gitlab/untrusted_regexp_spec.rb +++ b/spec/lib/gitlab/untrusted_regexp_spec.rb @@ -54,8 +54,8 @@ describe Gitlab::UntrustedRegexp do let(:regexp) { '' } let(:text) { 'foo' } - it 'returns an array of empty matches' do - is_expected.to eq(['']) + it 'returns an array of nil matches' do + is_expected.to eq([nil, nil, nil, nil]) end end @@ -63,8 +63,8 @@ describe Gitlab::UntrustedRegexp do let(:regexp) { '()' } let(:text) { 'foo' } - it 'returns an array of empty matches in an array' do - is_expected.to eq([['']]) + it 'returns an array of nil matches in an array' do + is_expected.to eq([[nil], [nil], [nil], [nil]]) end end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index fd4011ad606..3ee834748df 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -103,7 +103,7 @@ describe Projects::UpdateService, '#execute', :services do end end - context 'when renaming project that contains container images' do + context 'when updating a project that contains container images' do before do stub_container_registry_config(enabled: true) stub_container_registry_tags(repository: /image/, tags: %w[rc1]) @@ -116,6 +116,13 @@ describe Projects::UpdateService, '#execute', :services do expect(result).to include(status: :error) expect(result[:message]).to match(/contains container registry tags/) end + + it 'allows to update other settings' do + result = update_project(project, admin, public_builds: true) + + expect(result[:status]).to eq :success + expect(project.reload.public_builds).to be true + end end context 'when passing invalid parameters' do diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb index 033e338fe61..035428a7d9b 100644 --- a/spec/support/features/issuable_slash_commands_shared_examples.rb +++ b/spec/support/features/issuable_slash_commands_shared_examples.rb @@ -5,8 +5,6 @@ shared_examples 'issuable record that supports quick actions in its description include QuickActionsHelpers let(:master) { create(:user) } - let(:assignee) { create(:user, username: 'bob') } - let(:guest) { create(:user) } let(:project) { create(:project, :public) } let!(:milestone) { create(:milestone, project: project, title: 'ASAP') } let!(:label_bug) { create(:label, project: project, title: 'bug') } @@ -15,8 +13,6 @@ shared_examples 'issuable record that supports quick actions in its description before do project.team << [master, :master] - project.team << [assignee, :developer] - project.team << [guest, :guest] sign_in(master) end @@ -57,6 +53,7 @@ shared_examples 'issuable record that supports quick actions in its description context 'with a note containing commands' do it 'creates a note without the commands and interpret the commands accordingly' do + assignee = create(:user, username: 'bob') write_note("Awesome!\n/assign @bob\n/label ~bug\n/milestone %\"ASAP\"") expect(page).to have_content 'Awesome!' @@ -77,6 +74,7 @@ shared_examples 'issuable record that supports quick actions in its description context 'with a note containing only commands' do it 'does not create a note but interpret the commands accordingly' do + assignee = create(:user, username: 'bob') write_note("/assign @bob\n/label ~bug\n/milestone %\"ASAP\"") expect(page).not_to have_content '/assign @bob' @@ -111,8 +109,12 @@ shared_examples 'issuable record that supports quick actions in its description context "when current user cannot close #{issuable_type}" do before do + guest = create(:user) + project.add_guest(guest) + sign_out(:user) sign_in(guest) + visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) end @@ -146,8 +148,12 @@ shared_examples 'issuable record that supports quick actions in its description context "when current user cannot reopen #{issuable_type}" do before do + guest = create(:user) + project.add_guest(guest) + sign_out(:user) sign_in(guest) + visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) end @@ -176,6 +182,9 @@ shared_examples 'issuable record that supports quick actions in its description context "when current user cannot change title of #{issuable_type}" do before do + guest = create(:user) + project.add_guest(guest) + sign_out(:user) sign_in(guest) visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) @@ -267,6 +276,8 @@ shared_examples 'issuable record that supports quick actions in its description describe "preview of note on #{issuable_type}" do it 'removes quick actions from note and explains them' do + create(:user, username: 'bob') + visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) page.within('.js-main-target-form') do |