diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/markdown/mermaid_spec.rb | 8 | ||||
-rw-r--r-- | spec/fixtures/whats_new/20201225_01_01.yml | 3 | ||||
-rw-r--r-- | spec/fixtures/whats_new/20201225_01_02.yml | 3 | ||||
-rw-r--r-- | spec/fixtures/whats_new/20201225_01_05.yml | 7 | ||||
-rw-r--r-- | spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js | 402 | ||||
-rw-r--r-- | spec/graphql/types/merge_request_type_spec.rb | 2 | ||||
-rw-r--r-- | spec/helpers/whats_new_helper_spec.rb | 31 | ||||
-rw-r--r-- | spec/models/release_highlight_spec.rb | 135 | ||||
-rw-r--r-- | spec/presenters/gitlab/whats_new/item_presenter_spec.rb | 29 | ||||
-rw-r--r-- | spec/requests/api/projects_spec.rb | 4 | ||||
-rw-r--r-- | spec/requests/whats_new_controller_spec.rb | 26 |
11 files changed, 423 insertions, 227 deletions
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb index bdb549326fa..9875fda17a9 100644 --- a/spec/features/markdown/mermaid_spec.rb +++ b/spec/features/markdown/mermaid_spec.rb @@ -44,7 +44,7 @@ RSpec.describe 'Mermaid rendering', :js do expect(page.html.scan(expected).count).to be(4) end - it 'renders only 2 Mermaid blocks and ', :js, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' } do + it 'renders only 2 Mermaid blocks and ', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' do description = <<~MERMAID ```mermaid graph LR @@ -71,7 +71,7 @@ RSpec.describe 'Mermaid rendering', :js do end end - it 'correctly sizes mermaid diagram inside <details> block', :js do + it 'correctly sizes mermaid diagram inside <details> block' do description = <<~MERMAID <details> <summary>Click to show diagram</summary> @@ -102,7 +102,7 @@ RSpec.describe 'Mermaid rendering', :js do end end - it 'correctly sizes mermaid diagram block', :js do + it 'correctly sizes mermaid diagram block' do description = <<~MERMAID ```mermaid graph TD; @@ -121,7 +121,7 @@ RSpec.describe 'Mermaid rendering', :js do expect(page).to have_css('svg.mermaid[style*="max-width"][width="100%"]') end - it 'display button when diagram exceeds length', :js do + it 'display button when diagram exceeds length', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/287806' do graph_edges = "A-->B;B-->A;" * 420 description = <<~MERMAID diff --git a/spec/fixtures/whats_new/20201225_01_01.yml b/spec/fixtures/whats_new/20201225_01_01.yml index 06db95be44f..48248757b9a 100644 --- a/spec/fixtures/whats_new/20201225_01_01.yml +++ b/spec/fixtures/whats_new/20201225_01_01.yml @@ -1,2 +1,5 @@ --- - title: It's gonna be a bright + self-managed: true + gitlab-com: false + packages: ["Premium", "Ultimate"] diff --git a/spec/fixtures/whats_new/20201225_01_02.yml b/spec/fixtures/whats_new/20201225_01_02.yml index 91b0bd7036e..f0fbc036698 100644 --- a/spec/fixtures/whats_new/20201225_01_02.yml +++ b/spec/fixtures/whats_new/20201225_01_02.yml @@ -1,2 +1,5 @@ --- - title: bright + self-managed: true + gitlab-com: false + packages: ["Premium", "Ultimate"] diff --git a/spec/fixtures/whats_new/20201225_01_05.yml b/spec/fixtures/whats_new/20201225_01_05.yml index 7c95e386f00..152609296c9 100644 --- a/spec/fixtures/whats_new/20201225_01_05.yml +++ b/spec/fixtures/whats_new/20201225_01_05.yml @@ -1,3 +1,10 @@ --- - title: bright and sunshinin' day + self-managed: true + gitlab-com: false + packages: ["Premium", "Ultimate"] release: '01.05' +- title: I think I can make it now the pain is gone + self-managed: false + gitlab-com: true + packages: ["Premium", "Ultimate"] diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index b8cd1469179..ad21e6e6f4f 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -6,6 +6,7 @@ import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_ describe('MRWidgetConflicts', () => { let vm; + let mergeRequestWidgetGraphql = null; const path = '/conflicts'; function createComponent(propsData = {}) { @@ -13,7 +14,35 @@ describe('MRWidgetConflicts', () => { vm = shallowMount(localVue.extend(ConflictsComponent), { propsData, + provide: { + glFeatures: { + mergeRequestWidgetGraphql, + }, + }, + mocks: { + $apollo: { + queries: { + userPermissions: { loading: false }, + stateData: { loading: false }, + }, + }, + }, }); + + if (mergeRequestWidgetGraphql) { + vm.setData({ + userPermissions: { + canMerge: propsData.mr.canMerge, + pushToSourceBranch: propsData.mr.canPushToSourceBranch, + }, + stateData: { + shouldBeRebased: propsData.mr.shouldBeRebased, + sourceBranchProtected: propsData.mr.sourceBranchProtected, + }, + }); + } + + return vm.vm.$nextTick(); } beforeEach(() => { @@ -21,206 +50,215 @@ describe('MRWidgetConflicts', () => { }); afterEach(() => { + mergeRequestWidgetGraphql = null; vm.destroy(); }); - // There are two permissions we need to consider: - // - // 1. Is the user allowed to merge to the target branch? - // 2. Is the user allowed to push to the source branch? - // - // This yields 4 possible permutations that we need to test, and - // we test them below. A user who can push to the source - // branch should be allowed to resolve conflicts. This is - // consistent with what the backend does. - describe('when allowed to merge but not allowed to push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: false, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, + [false, true].forEach(featureEnabled => { + describe(`with GraphQL feature flag ${featureEnabled ? 'enabled' : 'disabled'}`, () => { + beforeEach(() => { + mergeRequestWidgetGraphql = featureEnabled; }); - }); - - it('should tell you about conflicts without bothering other people', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).not.toContain('ask someone with write access'); - }); - - it('should not allow you to resolve the conflicts', () => { - expect(vm.text()).not.toContain('Resolve conflicts'); - }); - - it('should have merge buttons', () => { - const mergeLocallyButton = vm.find('.js-merge-locally-button'); - - expect(mergeLocallyButton.text()).toContain('Merge locally'); - }); - }); - describe('when not allowed to merge but allowed to push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: true, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, - }); - }); - - it('should tell you about conflicts', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).toContain('ask someone with write access'); - }); - - it('should allow you to resolve the conflicts', () => { - const resolveButton = vm.find('.js-resolve-conflicts-button'); - - expect(resolveButton.text()).toContain('Resolve conflicts'); - expect(resolveButton.attributes('href')).toEqual(path); - }); - - it('should not have merge buttons', () => { - expect(vm.text()).not.toContain('Merge locally'); - }); - }); - - describe('when allowed to merge and push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, + // There are two permissions we need to consider: + // + // 1. Is the user allowed to merge to the target branch? + // 2. Is the user allowed to push to the source branch? + // + // This yields 4 possible permutations that we need to test, and + // we test them below. A user who can push to the source + // branch should be allowed to resolve conflicts. This is + // consistent with what the backend does. + describe('when allowed to merge but not allowed to push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: false, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts without bothering other people', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).not.toContain('ask someone with write access'); + }); + + it('should not allow you to resolve the conflicts', () => { + expect(vm.text()).not.toContain('Resolve conflicts'); + }); + + it('should have merge buttons', () => { + const mergeLocallyButton = vm.find('.js-merge-locally-button'); + + expect(mergeLocallyButton.text()).toContain('Merge locally'); + }); }); - }); - - it('should tell you about conflicts without bothering other people', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).not.toContain('ask someone with write access'); - }); - it('should allow you to resolve the conflicts', () => { - const resolveButton = vm.find('.js-resolve-conflicts-button'); - - expect(resolveButton.text()).toContain('Resolve conflicts'); - expect(resolveButton.attributes('href')).toEqual(path); - }); - - it('should have merge buttons', () => { - const mergeLocallyButton = vm.find('.js-merge-locally-button'); - - expect(mergeLocallyButton.text()).toContain('Merge locally'); - }); - }); - - describe('when user does not have permission to push to source branch', () => { - it('should show proper message', () => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: false, - conflictsDocsPath: '', - }, + describe('when not allowed to merge but allowed to push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: true, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).toContain('ask someone with write access'); + }); + + it('should allow you to resolve the conflicts', () => { + const resolveButton = vm.find('.js-resolve-conflicts-button'); + + expect(resolveButton.text()).toContain('Resolve conflicts'); + expect(resolveButton.attributes('href')).toEqual(path); + }); + + it('should not have merge buttons', () => { + expect(vm.text()).not.toContain('Merge locally'); + }); }); - expect( - vm - .text() - .trim() - .replace(/\s\s+/g, ' '), - ).toContain('ask someone with write access'); - }); - - it('should not have action buttons', () => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: false, - conflictsDocsPath: '', - }, + describe('when allowed to merge and push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts without bothering other people', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).not.toContain('ask someone with write access'); + }); + + it('should allow you to resolve the conflicts', () => { + const resolveButton = vm.find('.js-resolve-conflicts-button'); + + expect(resolveButton.text()).toContain('Resolve conflicts'); + expect(resolveButton.attributes('href')).toEqual(path); + }); + + it('should have merge buttons', () => { + const mergeLocallyButton = vm.find('.js-merge-locally-button'); + + expect(mergeLocallyButton.text()).toContain('Merge locally'); + }); }); - expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); - expect(vm.find('.js-merge-locally-button').exists()).toBe(false); - }); - - it('should not have resolve button when no conflict resolution path', () => { - createComponent({ - mr: { - canMerge: true, - conflictResolutionPath: null, - conflictsDocsPath: '', - }, + describe('when user does not have permission to push to source branch', () => { + it('should show proper message', async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: false, + conflictsDocsPath: '', + }, + }); + + expect( + vm + .text() + .trim() + .replace(/\s\s+/g, ' '), + ).toContain('ask someone with write access'); + }); + + it('should not have action buttons', async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: false, + conflictsDocsPath: '', + }, + }); + + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); + expect(vm.find('.js-merge-locally-button').exists()).toBe(false); + }); + + it('should not have resolve button when no conflict resolution path', async () => { + await createComponent({ + mr: { + canMerge: true, + conflictResolutionPath: null, + conflictsDocsPath: '', + }, + }); + + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); + }); }); - expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); - }); - }); - - describe('when fast-forward or semi-linear merge enabled', () => { - it('should tell you to rebase locally', () => { - createComponent({ - mr: { - shouldBeRebased: true, - conflictsDocsPath: '', - }, + describe('when fast-forward or semi-linear merge enabled', () => { + it('should tell you to rebase locally', async () => { + await createComponent({ + mr: { + shouldBeRebased: true, + conflictsDocsPath: '', + }, + }); + + expect(removeBreakLine(vm.text()).trim()).toContain( + 'Fast-forward merge is not possible. To merge this request, first rebase locally.', + ); + }); }); - expect(removeBreakLine(vm.text()).trim()).toContain( - 'Fast-forward merge is not possible. To merge this request, first rebase locally.', - ); - }); - }); - - describe('when source branch protected', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: TEST_HOST, - sourceBranchProtected: true, - conflictsDocsPath: '', - }, + describe('when source branch protected', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: TEST_HOST, + sourceBranchProtected: true, + conflictsDocsPath: '', + }, + }); + }); + + it('sets resolve button as disabled', () => { + expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('true'); + }); + + it('renders popover', () => { + expect($.fn.popover).toHaveBeenCalled(); + }); }); - }); - - it('sets resolve button as disabled', () => { - expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('true'); - }); - it('renders popover', () => { - expect($.fn.popover).toHaveBeenCalled(); - }); - }); - - describe('when source branch not protected', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: TEST_HOST, - sourceBranchProtected: false, - conflictsDocsPath: '', - }, + describe('when source branch not protected', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: TEST_HOST, + sourceBranchProtected: false, + conflictsDocsPath: '', + }, + }); + }); + + it('sets resolve button as disabled', () => { + expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined); + }); + + it('renders popover', () => { + expect($.fn.popover).not.toHaveBeenCalled(); + }); }); }); - - it('sets resolve button as disabled', () => { - expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined); - }); - - it('renders popover', () => { - expect($.fn.popover).not.toHaveBeenCalled(); - }); }); }); diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb index 8800250b103..c929a93a9eb 100644 --- a/spec/graphql/types/merge_request_type_spec.rb +++ b/spec/graphql/types/merge_request_type_spec.rb @@ -27,7 +27,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do upvotes downvotes head_pipeline pipelines task_completion_status milestone assignees participants subscribed labels discussion_locked time_estimate total_time_spent reference author merged_at commit_count current_user_todos - conflicts auto_merge_enabled approved_by + conflicts auto_merge_enabled approved_by source_branch_protected ] if Gitlab.ee? diff --git a/spec/helpers/whats_new_helper_spec.rb b/spec/helpers/whats_new_helper_spec.rb index 1c8684de75c..cdb4fc60629 100644 --- a/spec/helpers/whats_new_helper_spec.rb +++ b/spec/helpers/whats_new_helper_spec.rb @@ -3,22 +3,22 @@ require 'spec_helper' RSpec.describe WhatsNewHelper do - let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) } - describe '#whats_new_storage_key' do subject { helper.whats_new_storage_key } context 'when version exist' do + let(:release_item) { double(:item) } + before do - allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + allow(ReleaseHighlight).to receive(:most_recent_version).and_return(84.0) end - it { is_expected.to eq('display-whats-new-notification-01.05') } + it { is_expected.to eq('display-whats-new-notification-84.0') } end - context 'when recent release items do NOT exist' do + context 'when most recent release highlights do NOT exist' do before do - allow(helper).to receive(:whats_new_release_items).and_return(nil) + allow(ReleaseHighlight).to receive(:most_recent_version).and_return(nil) end it { is_expected.to be_nil } @@ -30,31 +30,18 @@ RSpec.describe WhatsNewHelper do context 'when recent release items exist' do it 'returns the count from the most recent file' do - expect(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + allow(ReleaseHighlight).to receive(:most_recent_item_count).and_return(1) expect(subject).to eq(1) end end context 'when recent release items do NOT exist' do - before do - allow(YAML).to receive(:safe_load).and_raise - - expect(Gitlab::ErrorTracking).to receive(:track_exception) - end + it 'returns nil' do + allow(ReleaseHighlight).to receive(:most_recent_item_count).and_return(nil) - it 'fails gracefully and logs an error' do expect(subject).to be_nil end end end - - # Testing this important private method here because the request spec required multiple confusing mocks and felt wrong and overcomplicated - describe '#whats_new_items_cache_key' do - it 'returns a key containing the most recent file name and page parameter' do - allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) - - expect(helper.send(:whats_new_items_cache_key, 2)).to eq('whats_new:release_items:file-20201225_01_05:page-2') - end - end end diff --git a/spec/models/release_highlight_spec.rb b/spec/models/release_highlight_spec.rb new file mode 100644 index 00000000000..b7817a04134 --- /dev/null +++ b/spec/models/release_highlight_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ReleaseHighlight do + describe '#paginated' do + let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) } + let(:cache_mock) { double(:cache_mock) } + let(:dot_com) { false } + + before do + allow(Gitlab).to receive(:com?).and_return(dot_com) + allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + + expect(Rails).to receive(:cache).twice.and_return(cache_mock) + expect(cache_mock).to receive(:fetch).with('release_highlight:file_paths', expires_in: 1.hour).and_yield + end + + after do + ReleaseHighlight.instance_variable_set(:@file_paths, nil) + end + + context 'with page param' do + subject { ReleaseHighlight.paginated(page: page) } + + before do + allow(cache_mock).to receive(:fetch).and_yield + end + + context 'when there is another page of results' do + let(:page) { 2 } + + it 'responds with paginated results' do + expect(subject[:items].first['title']).to eq('bright') + expect(subject[:next_page]).to eq(3) + end + end + + context 'when there is NOT another page of results' do + let(:page) { 3 } + + it 'responds with paginated results and no next_page' do + expect(subject[:items].first['title']).to eq("It's gonna be a bright") + expect(subject[:next_page]).to eq(nil) + end + end + + context 'when that specific page does not exist' do + let(:page) { 84 } + + it 'returns nil' do + expect(subject).to be_nil + end + end + end + + context 'with no page param' do + subject { ReleaseHighlight.paginated } + + before do + expect(cache_mock).to receive(:fetch).with('release_highlight:items:file-20201225_01_05:page-1', expires_in: 1.hour).and_yield + end + + it 'returns platform specific items and uses a cache key' do + expect(subject[:items].count).to eq(1) + expect(subject[:items].first['title']).to eq("bright and sunshinin' day") + expect(subject[:next_page]).to eq(2) + end + + context 'when Gitlab.com' do + let(:dot_com) { true } + + it 'responds with a different set of data' do + expect(subject[:items].count).to eq(1) + expect(subject[:items].first['title']).to eq("I think I can make it now the pain is gone") + end + end + + context 'when recent release items do NOT exist' do + before do + allow(YAML).to receive(:safe_load).and_raise(Psych::Exception) + + expect(Gitlab::ErrorTracking).to receive(:track_exception) + end + + it 'fails gracefully and logs an error' do + expect(subject).to be_nil + end + end + end + end + + describe '.most_recent_version' do + subject { ReleaseHighlight.most_recent_version } + + context 'when version exist' do + let(:release_item) { double(:item) } + + before do + allow(ReleaseHighlight).to receive(:paginated).and_return({ items: [release_item] }) + allow(release_item).to receive(:[]).with('release').and_return(84.0) + end + + it { is_expected.to eq(84.0) } + end + + context 'when most recent release highlights do NOT exist' do + before do + allow(ReleaseHighlight).to receive(:paginated).and_return(nil) + end + + it { is_expected.to be_nil } + end + end + + describe '#most_recent_item_count' do + subject { ReleaseHighlight.most_recent_item_count } + + context 'when recent release items exist' do + it 'returns the count from the most recent file' do + allow(ReleaseHighlight).to receive(:paginated).and_return({ items: [double(:item)] }) + + expect(subject).to eq(1) + end + end + + context 'when recent release items do NOT exist' do + it 'returns nil' do + allow(ReleaseHighlight).to receive(:paginated).and_return(nil) + + expect(subject).to be_nil + end + end + end +end diff --git a/spec/presenters/gitlab/whats_new/item_presenter_spec.rb b/spec/presenters/gitlab/whats_new/item_presenter_spec.rb new file mode 100644 index 00000000000..b7b711e04c7 --- /dev/null +++ b/spec/presenters/gitlab/whats_new/item_presenter_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::WhatsNew::ItemPresenter do + let(:present) { Gitlab::WhatsNew::ItemPresenter.present(item) } + let(:item) { { "packages" => %w(Premium Ultimate) } } + let(:gitlab_com) { true } + + before do + allow(Gitlab).to receive(:com?).and_return(gitlab_com) + end + + describe '.present' do + context 'when on Gitlab.com' do + it 'transforms package names to gitlab.com friendly package names' do + expect(present).to eq({ "packages" => %w(Silver Gold) }) + end + end + + context 'when not on Gitlab.com' do + let(:gitlab_com) { false } + + it 'does not transform package names' do + expect(present).to eq({ "packages" => %w(Premium Ultimate) }) + end + end + end +end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 4a792fc218d..eb3e610934d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -254,7 +254,7 @@ RSpec.describe API::Projects do statistics = json_response.find { |p| p['id'] == project.id }['statistics'] expect(statistics).to be_present - expect(statistics).to include('commit_count', 'storage_size', 'repository_size', 'wiki_size', 'lfs_objects_size', 'job_artifacts_size', 'snippets_size') + expect(statistics).to include('commit_count', 'storage_size', 'repository_size', 'wiki_size', 'lfs_objects_size', 'job_artifacts_size', 'snippets_size', 'packages_size') end it "does not include license by default" do @@ -619,7 +619,7 @@ RSpec.describe API::Projects do end context 'sorting by project statistics' do - %w(repository_size storage_size wiki_size).each do |order_by| + %w(repository_size storage_size wiki_size packages_size).each do |order_by| context "sorting by #{order_by}" do before do ProjectStatistics.update_all(order_by => 100) diff --git a/spec/requests/whats_new_controller_spec.rb b/spec/requests/whats_new_controller_spec.rb index c04a6b00a93..30d741ee0f0 100644 --- a/spec/requests/whats_new_controller_spec.rb +++ b/spec/requests/whats_new_controller_spec.rb @@ -5,28 +5,30 @@ require 'spec_helper' RSpec.describe WhatsNewController do describe 'whats_new_path' do context 'with whats_new_drawer feature enabled' do - let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) } - before do stub_feature_flags(whats_new_drawer: true) - allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) end context 'with no page param' do + let(:most_recent) { { items: [item], next_page: 2 } } + let(:item) { double(:item) } + it 'responds with paginated data and headers' do + allow(ReleaseHighlight).to receive(:paginated).with(page: 1).and_return(most_recent) + allow(Gitlab::WhatsNew::ItemPresenter).to receive(:present).with(item).and_return(item) + get whats_new_path, xhr: true - expect(response.body).to eq([{ title: "bright and sunshinin' day", release: "01.05" }].to_json) + expect(response.body).to eq(most_recent[:items].to_json) expect(response.headers['X-Next-Page']).to eq(2) end end context 'with page param' do - it 'responds with paginated data and headers' do - get whats_new_path(page: 2), xhr: true + it 'passes the page parameter' do + expect(ReleaseHighlight).to receive(:paginated).with(page: 2).and_call_original - expect(response.body).to eq([{ title: 'bright' }].to_json) - expect(response.headers['X-Next-Page']).to eq(3) + get whats_new_path(page: 2), xhr: true end it 'returns a 404 if page param is negative' do @@ -34,14 +36,6 @@ RSpec.describe WhatsNewController do expect(response).to have_gitlab_http_status(:not_found) end - - context 'when there are no more paginated results' do - it 'responds with nil X-Next-Page header' do - get whats_new_path(page: 3), xhr: true - expect(response.body).to eq([{ title: "It's gonna be a bright" }].to_json) - expect(response.headers['X-Next-Page']).to be nil - end - end end end |