From d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 20 Oct 2021 08:43:02 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-4-stable-ee --- spec/features/groups/board_spec.rb | 2 +- spec/features/groups/container_registry_spec.rb | 12 +++ .../groups/dependency_proxy_for_containers_spec.rb | 108 +++++++++++++++++++++ spec/features/groups/dependency_proxy_spec.rb | 50 +++++----- .../groups/import_export/connect_instance_spec.rb | 34 ++----- .../groups/import_export/migration_history_spec.rb | 30 ++++++ spec/features/groups/members/manage_groups_spec.rb | 11 ++- ...master_adds_member_with_expiration_date_spec.rb | 15 +-- spec/features/groups/milestone_spec.rb | 8 +- spec/features/groups/packages_spec.rb | 4 + 10 files changed, 207 insertions(+), 67 deletions(-) create mode 100644 spec/features/groups/dependency_proxy_for_containers_spec.rb create mode 100644 spec/features/groups/import_export/migration_history_spec.rb (limited to 'spec/features/groups') diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb index afe36dabcb5..aece6d790b5 100644 --- a/spec/features/groups/board_spec.rb +++ b/spec/features/groups/board_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Group Boards' do it 'adds an issue to the backlog' do page.within(find('.board', match: :first)) do issue_title = 'New Issue' - find(:css, '.issue-count-badge-add-button').click + click_button 'New issue' wait_for_requests diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb index 65374263f45..098559dc3f8 100644 --- a/spec/features/groups/container_registry_spec.rb +++ b/spec/features/groups/container_registry_spec.rb @@ -16,6 +16,7 @@ RSpec.describe 'Container Registry', :js do sign_in(user) stub_container_registry_config(enabled: true) stub_container_registry_tags(repository: :any, tags: []) + stub_container_registry_info end it 'has a page title set' do @@ -57,6 +58,16 @@ RSpec.describe 'Container Registry', :js do expect(page).to have_content 'latest' end + [ContainerRegistry::Path::InvalidRegistryPathError, Faraday::Error].each do |error_class| + context "when there is a #{error_class}" do + before do + expect(::ContainerRegistry::Client).to receive(:registry_info).and_raise(error_class, nil, nil) + end + + it_behaves_like 'handling feature network errors with the container registry' + end + end + describe 'image repo details' do before do visit_container_registry_details 'my/image' @@ -81,6 +92,7 @@ RSpec.describe 'Container Registry', :js do expect(service).to receive(:execute).with(container_repository) { { status: :success } } expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['latest']) { service } + first('[data-testid="additional-actions"]').click first('[data-testid="single-delete-button"]').click expect(find('.modal .modal-title')).to have_content _('Remove tag') find('.modal .modal-footer .btn-danger').click diff --git a/spec/features/groups/dependency_proxy_for_containers_spec.rb b/spec/features/groups/dependency_proxy_for_containers_spec.rb new file mode 100644 index 00000000000..a4cd6d0f503 --- /dev/null +++ b/spec/features/groups/dependency_proxy_for_containers_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Group Dependency Proxy for containers', :js do + include DependencyProxyHelpers + + include_context 'file upload requests helpers' + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:sha) { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4' } + let_it_be(:content) { fixture_file_upload("spec/fixtures/dependency_proxy/#{sha}.gz").read } + + let(:image) { 'alpine' } + let(:url) { capybara_url("/v2/#{group.full_path}/dependency_proxy/containers/#{image}/blobs/sha256:#{sha}") } + let(:token) { 'token' } + let(:headers) { { 'Authorization' => "Bearer #{build_jwt(user).encoded}" } } + + subject do + HTTParty.get(url, headers: headers) + end + + def run_server(handler) + default_server = Capybara.server + + Capybara.server = Capybara.servers[:puma] + server = Capybara::Server.new(handler) + server.boot + server + ensure + Capybara.server = default_server + end + + let_it_be(:external_server) do + handler = lambda do |env| + if env['REQUEST_PATH'] == '/token' + [200, {}, [{ token: 'token' }.to_json]] + else + [200, {}, [content]] + end + end + + run_server(handler) + end + + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + stub_config(dependency_proxy: { enabled: true }) + group.add_developer(user) + + stub_const("DependencyProxy::Registry::AUTH_URL", external_server.base_url) + stub_const("DependencyProxy::Registry::LIBRARY_URL", external_server.base_url) + end + + shared_examples 'responds with the file' do + it 'sends file' do + expect(subject.code).to eq(200) + expect(subject.body).to eq(content) + expect(subject.headers.to_h).to include( + "content-type" => ["application/gzip"], + "content-disposition" => ["attachment; filename=\"#{sha}.gz\"; filename*=UTF-8''#{sha}.gz"], + "content-length" => ["32"] + ) + end + end + + shared_examples 'caches the file' do + it 'caches the file' do + expect { subject }.to change { + group.dependency_proxy_blobs.count + }.from(0).to(1) + + expect(subject.code).to eq(200) + expect(group.dependency_proxy_blobs.first.file.read).to eq(content) + end + end + + context 'fetching a blob' do + context 'when the blob is cached for the group' do + let!(:dependency_proxy_blob) { create(:dependency_proxy_blob, group: group) } + + it_behaves_like 'responds with the file' + + context 'dependency_proxy_workhorse feature flag disabled' do + before do + stub_feature_flags({ dependency_proxy_workhorse: false }) + end + + it_behaves_like 'responds with the file' + end + end + end + + context 'when the blob must be downloaded' do + it_behaves_like 'responds with the file' + it_behaves_like 'caches the file' + + context 'dependency_proxy_workhorse feature flag disabled' do + before do + stub_feature_flags({ dependency_proxy_workhorse: false }) + end + + it_behaves_like 'responds with the file' + it_behaves_like 'caches the file' + end + end +end diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb index 51371ddc532..d6b0bdc8ea4 100644 --- a/spec/features/groups/dependency_proxy_spec.rb +++ b/spec/features/groups/dependency_proxy_spec.rb @@ -3,13 +3,14 @@ require 'spec_helper' RSpec.describe 'Group Dependency Proxy' do - let(:developer) { create(:user) } + let(:owner) { create(:user) } let(:reporter) { create(:user) } let(:group) { create(:group) } let(:path) { group_dependency_proxy_path(group) } + let(:settings_path) { group_settings_packages_and_registries_path(group) } before do - group.add_developer(developer) + group.add_owner(owner) group.add_reporter(reporter) enable_feature @@ -22,42 +23,46 @@ RSpec.describe 'Group Dependency Proxy' do visit path - expect(page).not_to have_css('.js-dependency-proxy-toggle-area') - expect(page).not_to have_css('.js-dependency-proxy-url') + expect(page).not_to have_css('[data-testid="proxy-url"]') end end context 'feature is available', :js do - context 'when logged in as group developer' do + context 'when logged in as group owner' do before do - sign_in(developer) - visit path + sign_in(owner) end it 'sidebar menu is open' do + visit path + sidebar = find('.nav-sidebar') expect(sidebar).to have_link _('Dependency Proxy') end it 'toggles defaults to enabled' do - page.within('.js-dependency-proxy-toggle-area') do - expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('true') - end + visit path + + expect(page).to have_css('[data-testid="proxy-url"]') end it 'shows the proxy URL' do - page.within('.edit_dependency_proxy_group_setting') do - expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers') - end + visit path + + expect(find('input[data-testid="proxy-url"]').value).to have_content('/dependency_proxy/containers') end it 'hides the proxy URL when feature is disabled' do - page.within('.edit_dependency_proxy_group_setting') do - find('.js-project-feature-toggle').click - end + visit settings_path + wait_for_requests + + click_button 'Enable Proxy' + + expect(page).to have_button 'Enable Proxy', class: '!is-checked' + + visit path - expect(page).not_to have_css('.js-dependency-proxy-url') - expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('false') + expect(page).not_to have_css('input[data-testid="proxy-url"]') end end @@ -68,18 +73,17 @@ RSpec.describe 'Group Dependency Proxy' do end it 'does not show the feature toggle but shows the proxy URL' do - expect(page).not_to have_css('.js-dependency-proxy-toggle-area') - expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers') + expect(find('input[data-testid="proxy-url"]').value).to have_content('/dependency_proxy/containers') end end end context 'feature is not avaible' do before do - sign_in(developer) + sign_in(owner) end - context 'feature flag is disabled' do + context 'feature flag is disabled', :js do before do stub_feature_flags(dependency_proxy_for_private_groups: false) end @@ -90,7 +94,7 @@ RSpec.describe 'Group Dependency Proxy' do it 'informs user that feature is only available for public groups' do visit path - expect(page).to have_content('Dependency proxy feature is limited to public groups for now.') + expect(page).to have_content('Dependency Proxy feature is limited to public groups for now.') end end end diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb index cf893e444c4..552b599a3f3 100644 --- a/spec/features/groups/import_export/connect_instance_spec.rb +++ b/spec/features/groups/import_export/connect_instance_spec.rb @@ -19,34 +19,12 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do end context 'when the user provides valid credentials' do + source_url = 'https://gitlab.com' + + include_context 'bulk imports requests context', source_url + it 'successfully connects to remote instance' do - source_url = 'https://gitlab.com' pat = 'demo-pat' - stub_path = 'stub-group' - total = 37 - - stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: source_url }).to_return( - body: [{ - id: 2595438, - web_url: 'https://gitlab.com/groups/auto-breakfast', - name: 'Stub', - path: stub_path, - full_name: 'Stub', - full_path: stub_path - }].to_json, - headers: { - 'Content-Type' => 'application/json', - 'X-Next-Page' => 2, - 'X-Page' => 1, - 'X-Per-Page' => 20, - 'X-Total' => total, - 'X-Total-Pages' => 2 - } - ) - - allow_next_instance_of(BulkImports::Clients::HTTP) do |client| - allow(client).to receive(:validate_instance_version!).and_return(true) - end expect(page).to have_content 'Import groups from another instance of GitLab' expect(page).to have_content 'Not all related objects are migrated' @@ -56,8 +34,8 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do click_on 'Connect instance' - expect(page).to have_content 'Showing 1-1 of %{total} groups from %{url}' % { url: source_url, total: total } - expect(page).to have_content stub_path + expect(page).to have_content 'Showing 1-1 of 42 groups from %{url}' % { url: source_url } + expect(page).to have_content 'stub-group' visit '/' diff --git a/spec/features/groups/import_export/migration_history_spec.rb b/spec/features/groups/import_export/migration_history_spec.rb new file mode 100644 index 00000000000..243bdcc13a9 --- /dev/null +++ b/spec/features/groups/import_export/migration_history_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Import/Export - GitLab migration history', :js do + let_it_be(:user) { create(:user) } + + let_it_be(:user_import_1) { create(:bulk_import, user: user) } + let_it_be(:finished_entity_1) { create(:bulk_import_entity, :finished, bulk_import: user_import_1) } + + let_it_be(:user_import_2) { create(:bulk_import, user: user) } + let_it_be(:failed_entity_2) { create(:bulk_import_entity, :failed, bulk_import: user_import_2) } + + before do + gitlab_sign_in(user) + + visit new_group_path + + click_link 'Import group' + end + + it 'successfully displays import history' do + click_link 'History' + + wait_for_requests + + expect(page).to have_content 'Group import history' + expect(page.find('tbody')).to have_css('tr', count: 2) + end +end diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb index 2dfcd941b4f..d822a5ea871 100644 --- a/spec/features/groups/members/manage_groups_spec.rb +++ b/spec/features/groups/members/manage_groups_spec.rb @@ -63,6 +63,7 @@ RSpec.describe 'Groups > Members > Manage groups', :js do context 'when group link exists' do let_it_be(:shared_with_group) { create(:group) } let_it_be(:shared_group) { create(:group) } + let_it_be(:expiration_date) { 5.days.from_now.to_date } let(:additional_link_attrs) { {} } @@ -115,29 +116,29 @@ RSpec.describe 'Groups > Members > Manage groups', :js do click_groups_tab page.within first_row do - fill_in 'Expiration date', with: 5.days.from_now.to_date + fill_in 'Expiration date', with: expiration_date find_field('Expiration date').native.send_keys :enter wait_for_requests - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) end end context 'when expiry date is set' do - let(:additional_link_attrs) { { expires_at: 5.days.from_now.to_date } } + let(:additional_link_attrs) { { expires_at: expiration_date } } it 'clears expiry date' do click_groups_tab page.within first_row do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) find('[data-testid="clear-button"]').click wait_for_requests - expect(page).to have_content('No expiration set') + expect(page).to have_field('Expiration date', with: '') end end end diff --git a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb index ddf3c6d8f9b..86185b8dd32 100644 --- a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js let_it_be(:user1) { create(:user, name: 'John Doe') } let_it_be(:group) { create(:group) } + let_it_be(:expiration_date) { 5.days.from_now.to_date } let(:new_member) { create(:user, name: 'Mary Jane') } @@ -19,10 +20,10 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js it 'expiration date is displayed in the members list' do visit group_group_members_path(group) - invite_member(new_member.name, role: 'Guest', expires_at: 5.days.from_now.to_date) + invite_member(new_member.name, role: 'Guest', expires_at: expiration_date) page.within second_row do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) end end @@ -31,27 +32,27 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js visit group_group_members_path(group) page.within second_row do - fill_in 'Expiration date', with: 5.days.from_now.to_date + fill_in 'Expiration date', with: expiration_date find_field('Expiration date').native.send_keys :enter wait_for_requests - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) end end it 'clears expiration date' do - create(:group_member, :developer, user: new_member, group: group, expires_at: 5.days.from_now.to_date) + create(:group_member, :developer, user: new_member, group: group, expires_at: expiration_date) visit group_group_members_path(group) page.within second_row do - expect(page).to have_content(/in \d days/) + expect(page).to have_field('Expiration date', with: expiration_date) find('[data-testid="clear-button"]').click wait_for_requests - expect(page).to have_content('No expiration set') + expect(page).to have_field('Expiration date', with: '') end end end diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb index c51ee250331..4edf27e8fa4 100644 --- a/spec/features/groups/milestone_spec.rb +++ b/spec/features/groups/milestone_spec.rb @@ -98,9 +98,11 @@ RSpec.describe 'Group milestones' do end it 'counts milestones correctly' do - expect(find('.top-area .active .badge').text).to eq("3") - expect(find('.top-area .closed .badge').text).to eq("3") - expect(find('.top-area .all .badge').text).to eq("6") + page.within '[data-testid="milestones-filter"]' do + expect(page).to have_content('Open 3') + expect(page).to have_content('Closed 3') + expect(page).to have_content('All 6') + end end it 'lists group and project milestones' do diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb index 3c2ade6b274..0dfc7180187 100644 --- a/spec/features/groups/packages_spec.rb +++ b/spec/features/groups/packages_spec.rb @@ -28,6 +28,10 @@ RSpec.describe 'Group Packages' do context 'when feature is available', :js do before do + # we are simply setting the featrure flag to false because the new UI has nothing to test yet + # when the refactor is complete or almost complete we will turn on the feature tests + # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work + stub_feature_flags(package_list_apollo: false) visit_group_packages end -- cgit v1.2.1