diff options
Diffstat (limited to 'spec')
11 files changed, 195 insertions, 24 deletions
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js index 74441e147cf..7c8996be0b8 100644 --- a/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js +++ b/spec/frontend/boards/components/sidebar/board_sidebar_time_tracker_spec.js @@ -26,6 +26,7 @@ describe('BoardSidebarTimeTracker', () => { store = createStore(); store.state.boardItems = { 1: { + id: 1, iid: 1, timeEstimate: 3600, totalTimeSpent: 1800, @@ -49,6 +50,7 @@ describe('BoardSidebarTimeTracker', () => { expect(wrapper.find(IssuableTimeTracker).props()).toEqual({ limitToHours: timeTrackingLimitToHours, showCollapsed: false, + issuableId: '1', issuableIid: '1', fullPath: '', initialTimeTracking: { diff --git a/spec/frontend/frequent_items/utils_spec.js b/spec/frontend/frequent_items/utils_spec.js index a7ab18b0d10..8c3841558f4 100644 --- a/spec/frontend/frequent_items/utils_spec.js +++ b/spec/frontend/frequent_items/utils_spec.js @@ -66,35 +66,36 @@ describe('Frequent Items utils spec', () => { }); describe('updateExistingFrequentItem', () => { - let mockedProject; - - beforeEach(() => { - mockedProject = { - ...mockProject, - frequency: 1, - lastAccessedOn: 1497979281815, - }; + const LAST_ACCESSED = 1497979281815; + const WITHIN_AN_HOUR = LAST_ACCESSED + HOUR_IN_MS; + const OVER_AN_HOUR = WITHIN_AN_HOUR + 1; + const EXISTING_ITEM = Object.freeze({ + ...mockProject, + frequency: 1, + lastAccessedOn: 1497979281815, }); - it('updates item if accessed over an hour ago', () => { - const newTimestamp = Date.now() + HOUR_IN_MS + 1; + it.each` + desc | existingProps | newProps | expected + ${'updates item if accessed over an hour ago'} | ${{}} | ${{ lastAccessedOn: OVER_AN_HOUR }} | ${{ lastAccessedOn: Date.now(), frequency: 2 }} + ${'does not update is accessed with an hour'} | ${{}} | ${{ lastAccessedOn: WITHIN_AN_HOUR }} | ${{ lastAccessedOn: EXISTING_ITEM.lastAccessedOn, frequency: 1 }} + ${'updates if lastAccessedOn not found'} | ${{ lastAccessedOn: undefined }} | ${{ lastAccessedOn: WITHIN_AN_HOUR }} | ${{ lastAccessedOn: Date.now(), frequency: 2 }} + `('$desc', ({ existingProps, newProps, expected }) => { const newItem = { - ...mockedProject, - lastAccessedOn: newTimestamp, + ...EXISTING_ITEM, + ...newProps, }; - const result = updateExistingFrequentItem(mockedProject, newItem); - - expect(result.frequency).toBe(mockedProject.frequency + 1); - }); - - it('does not update item if accessed within the hour', () => { - const newItem = { - ...mockedProject, - lastAccessedOn: mockedProject.lastAccessedOn + HOUR_IN_MS, + const existingItem = { + ...EXISTING_ITEM, + ...existingProps, }; - const result = updateExistingFrequentItem(mockedProject, newItem); - expect(result.frequency).toBe(mockedProject.frequency); + const result = updateExistingFrequentItem(existingItem, newItem); + + expect(result).toEqual({ + ...newItem, + ...expected, + }); }); }); diff --git a/spec/frontend/nav/components/responsive_app_spec.js b/spec/frontend/nav/components/responsive_app_spec.js index 7221ea2c5cd..e1b443745e3 100644 --- a/spec/frontend/nav/components/responsive_app_spec.js +++ b/spec/frontend/nav/components/responsive_app_spec.js @@ -111,6 +111,7 @@ describe('~/nav/components/responsive_app.vue', () => { containerClass: 'gl-px-3', frequentItemsDropdownType: ResponsiveApp.FREQUENT_ITEMS_PROJECTS.namespace, frequentItemsVuexModule: ResponsiveApp.FREQUENT_ITEMS_PROJECTS.vuexModule, + currentItem: {}, linksPrimary: TEST_NAV_DATA.views.projects.linksPrimary, linksSecondary: TEST_NAV_DATA.views.projects.linksSecondary, }; @@ -118,6 +119,7 @@ describe('~/nav/components/responsive_app.vue', () => { containerClass: 'gl-px-3', frequentItemsDropdownType: ResponsiveApp.FREQUENT_ITEMS_GROUPS.namespace, frequentItemsVuexModule: ResponsiveApp.FREQUENT_ITEMS_GROUPS.vuexModule, + currentItem: {}, linksPrimary: TEST_NAV_DATA.views.groups.linksPrimary, linksSecondary: TEST_NAV_DATA.views.groups.linksSecondary, }; diff --git a/spec/frontend/nav/components/top_nav_container_view_spec.js b/spec/frontend/nav/components/top_nav_container_view_spec.js index 06d2179b859..0218f09af0a 100644 --- a/spec/frontend/nav/components/top_nav_container_view_spec.js +++ b/spec/frontend/nav/components/top_nav_container_view_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { merge } from 'lodash'; import { nextTick } from 'vue'; import FrequentItemsApp from '~/frequent_items/components/app.vue'; import { FREQUENT_ITEMS_PROJECTS } from '~/frequent_items/constants'; @@ -82,7 +83,9 @@ describe('~/nav/components/top_nav_container_view.vue', () => { it('renders frequent items app', () => { expect(findFrequentItemsApp()).toEqual({ vuexModule: DEFAULT_PROPS.frequentItemsVuexModule, - props: expect.objectContaining(TEST_OTHER_PROPS), + props: expect.objectContaining( + merge({ currentItem: { lastAccessedOn: Date.now() } }, TEST_OTHER_PROPS), + ), attributes: expect.objectContaining(EXTRA_ATTRS), }); }); diff --git a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js index e08bd80b18e..eb202a8cfcc 100644 --- a/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js @@ -19,6 +19,7 @@ describe('Issuable Time Tracker', () => { const defaultProps = { limitToHours: false, fullPath: 'gitlab-org/gitlab-test', + issuableId: '1', issuableIid: '1', initialTimeTracking: { ...issuableTimeTrackingResponse.data.workspace.issuable, diff --git a/spec/lib/gitlab/local_and_remote_storage_migration/artifact_migrater_spec.rb b/spec/lib/gitlab/local_and_remote_storage_migration/artifact_migrater_spec.rb new file mode 100644 index 00000000000..b3f2003c207 --- /dev/null +++ b/spec/lib/gitlab/local_and_remote_storage_migration/artifact_migrater_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'support/shared_examples/lib/gitlab/local_and_remote_storage_migration_shared_examples' + +RSpec.describe Gitlab::LocalAndRemoteStorageMigration::ArtifactMigrater do + before do + stub_artifacts_object_storage(enabled: true) + end + + let!(:item) { create(:ci_job_artifact, :archive, file_store: start_store) } + + it_behaves_like 'local and remote storage migration' +end diff --git a/spec/lib/gitlab/local_and_remote_storage_migration/pages_deployment_migrater_spec.rb b/spec/lib/gitlab/local_and_remote_storage_migration/pages_deployment_migrater_spec.rb new file mode 100644 index 00000000000..2cc48b445f1 --- /dev/null +++ b/spec/lib/gitlab/local_and_remote_storage_migration/pages_deployment_migrater_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'support/shared_examples/lib/gitlab/local_and_remote_storage_migration_shared_examples' + +RSpec.describe Gitlab::LocalAndRemoteStorageMigration::PagesDeploymentMigrater do + before do + stub_pages_object_storage(::Pages::DeploymentUploader, enabled: true) + end + + let!(:item) { create(:pages_deployment, file_store: start_store) } + + it_behaves_like 'local and remote storage migration' +end diff --git a/spec/models/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb index d4ccaa6a10e..fa78527e366 100644 --- a/spec/models/deploy_key_spec.rb +++ b/spec/models/deploy_key_spec.rb @@ -93,4 +93,46 @@ RSpec.describe DeployKey, :mailer do end end end + + describe 'PolicyActor methods' do + let_it_be(:user) { create(:user) } + let_it_be(:deploy_key) { create(:deploy_key, user: user) } + let_it_be(:project) { create(:project, creator: user, namespace: user.namespace) } + + let(:methods) { PolicyActor.instance_methods } + + subject { deploy_key } + + it 'responds to all PolicyActor methods' do + methods.each do |method| + expect(subject.respond_to?(method)).to be true + end + end + + describe '#can?' do + it { expect(user.can?(:read_project, project)).to be true } + + context 'when a read deploy key is enabled in the project' do + let!(:deploy_keys_project) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) } + + it { expect(subject.can?(:read_project, project)).to be false } + it { expect(subject.can?(:download_code, project)).to be true } + it { expect(subject.can?(:push_code, project)).to be false } + end + + context 'when a write deploy key is enabled in the project' do + let!(:deploy_keys_project) { create(:deploy_keys_project, :write_access, project: project, deploy_key: deploy_key) } + + it { expect(subject.can?(:read_project, project)).to be false } + it { expect(subject.can?(:download_code, project)).to be true } + it { expect(subject.can?(:push_code, project)).to be true } + end + + context 'when the deploy key is not enabled in the project' do + it { expect(subject.can?(:read_project, project)).to be false } + it { expect(subject.can?(:download_code, project)).to be false } + it { expect(subject.can?(:push_code, project)).to be false } + end + end + end end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 2c514593de8..373f3a89e14 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1044,6 +1044,14 @@ RSpec.describe Namespace do end describe '#all_projects' do + context 'when recursive approach is disabled' do + before do + stub_feature_flags(recursive_approach_for_all_projects: false) + end + + include_examples '#all_projects' + end + context 'with use_traversal_ids feature flag enabled' do before do stub_feature_flags(use_traversal_ids: true) diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index d0fe0cca8a1..f3c92751d06 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -795,6 +795,37 @@ RSpec.describe ProjectPolicy do end end + context 'deploy key access' do + context 'private project' do + let(:project) { private_project } + let!(:deploy_key) { create(:deploy_key, user: owner) } + + subject { described_class.new(deploy_key, project) } + + context 'when a read deploy key is enabled in the project' do + let!(:deploy_keys_project) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) } + + it { is_expected.to be_allowed(:download_code) } + it { is_expected.to be_disallowed(:push_code) } + it { is_expected.to be_disallowed(:read_project) } + end + + context 'when a write deploy key is enabled in the project' do + let!(:deploy_keys_project) { create(:deploy_keys_project, :write_access, project: project, deploy_key: deploy_key) } + + it { is_expected.to be_allowed(:download_code) } + it { is_expected.to be_allowed(:push_code) } + it { is_expected.to be_disallowed(:read_project) } + end + + context 'when the deploy key is not enabled in the project' do + it { is_expected.to be_disallowed(:download_code) } + it { is_expected.to be_disallowed(:push_code) } + it { is_expected.to be_disallowed(:read_project) } + end + end + end + context 'deploy token access' do let!(:project_deploy_token) do create(:project_deploy_token, project: project, deploy_token: deploy_token) diff --git a/spec/support/shared_examples/lib/gitlab/local_and_remote_storage_migration_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/local_and_remote_storage_migration_shared_examples.rb new file mode 100644 index 00000000000..27ca27a9035 --- /dev/null +++ b/spec/support/shared_examples/lib/gitlab/local_and_remote_storage_migration_shared_examples.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'local and remote storage migration' do + let(:logger) { Logger.new("/dev/null") } + let(:migrater) { described_class.new(logger) } + + using RSpec::Parameterized::TableSyntax + + where(:start_store, :end_store, :method) do + ObjectStorage::Store::LOCAL | ObjectStorage::Store::REMOTE | :migrate_to_remote_storage + ObjectStorage::Store::REMOTE | ObjectStorage::Store::REMOTE | :migrate_to_remote_storage # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + ObjectStorage::Store::REMOTE | ObjectStorage::Store::LOCAL | :migrate_to_local_storage + ObjectStorage::Store::LOCAL | ObjectStorage::Store::LOCAL | :migrate_to_local_storage # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + end + + with_them do + let(:storage_name) { end_store == ObjectStorage::Store::REMOTE ? 'object' : 'local' } + + it 'successfully migrates' do + expect(logger).to receive(:info).with("Starting transfer to #{storage_name} storage") + + if start_store != end_store + expect(logger).to receive(:info).with("Transferred #{item.class.name} ID #{item.id} with size #{item.size} to #{storage_name} storage") + end + + expect(item.file_store).to eq(start_store) + + migrater.send(method) + + expect(item.reload.file_store).to eq(end_store) + end + end + + context 'when migration fails' do + let(:start_store) { ObjectStorage::Store::LOCAL } + + it 'prints error' do + expect_next_instance_of(item.file.class) do |file| + expect(file).to receive(:migrate!).and_raise("error message") + end + + expect(logger).to receive(:info).with("Starting transfer to object storage") + + expect(logger).to receive(:warn).with("Failed to transfer #{item.class.name} ID #{item.id} with error: error message") + + expect(item.file_store).to eq(start_store) + + migrater.migrate_to_remote_storage + + expect(item.reload.file_store).to eq(start_store) + end + end +end |