Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-24 21:09:14 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-24 21:09:14 +0300
commit72875e4a370cf2014e7bb35633d63ccb938e4edb (patch)
tree927761bf7c89a3cedeab6b2c28f04cbffda7a587 /spec
parent94c1ea61908ce610ba40786e2d80d5701acd8cbf (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/markdown/mermaid_spec.rb8
-rw-r--r--spec/fixtures/whats_new/20201225_01_01.yml3
-rw-r--r--spec/fixtures/whats_new/20201225_01_02.yml3
-rw-r--r--spec/fixtures/whats_new/20201225_01_05.yml7
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js402
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb2
-rw-r--r--spec/helpers/whats_new_helper_spec.rb31
-rw-r--r--spec/models/release_highlight_spec.rb135
-rw-r--r--spec/presenters/gitlab/whats_new/item_presenter_spec.rb29
-rw-r--r--spec/requests/api/projects_spec.rb4
-rw-r--r--spec/requests/whats_new_controller_spec.rb26
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