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>2021-08-16 09:09:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-16 09:09:08 +0300
commit80f5d0d15f8d7ced767651978fb016072003f376 (patch)
tree8ddbe65b30cf5f2d2b6543bac7f7508ba259b9ec /spec
parent2a3313dc5ec97ba732681fe034de900215807ac3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb32
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js24
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js12
-rw-r--r--spec/graphql/resolvers/merge_requests_resolver_spec.rb23
-rw-r--r--spec/models/merge_request_spec.rb38
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb40
7 files changed, 139 insertions, 34 deletions
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index ab6242784fe..f96717970bf 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
milestone: create(:milestone, project: project, due_date: '2013-12-11'),
created_at: 1.minute.ago,
updated_at: 1.minute.ago)
- @fix.metrics.update_column(:merged_at, 10.seconds.ago)
+ @fix.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.seconds.ago)
@markdown = create(:merge_request,
title: 'markdown',
@@ -34,7 +34,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
milestone: create(:milestone, project: project, due_date: '2013-12-12'),
created_at: 2.minutes.ago,
updated_at: 2.minutes.ago)
- @markdown.metrics.update_column(:merged_at, 50.seconds.ago)
+ @markdown.metrics.update!(merged_at: 10.minutes.ago, latest_closed_at: 10.seconds.ago)
@merge_test = create(:merge_request,
title: 'merge-test',
@@ -42,7 +42,15 @@ RSpec.describe 'Merge requests > User lists merge requests' do
source_branch: 'merge-test',
created_at: 3.minutes.ago,
updated_at: 10.seconds.ago)
- @merge_test.metrics.update_column(:merged_at, 10.seconds.ago)
+ @merge_test.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.seconds.ago)
+
+ @feature = create(:merge_request,
+ title: 'feature',
+ source_project: project,
+ source_branch: 'feautre',
+ created_at: 2.minutes.ago,
+ updated_at: 1.minute.ago)
+ @feature.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.minutes.ago)
end
context 'merge request reviewers' do
@@ -71,9 +79,10 @@ RSpec.describe 'Merge requests > User lists merge requests' do
expect(current_path).to eq(project_merge_requests_path(project))
expect(page).to have_content 'merge-test'
+ expect(page).to have_content 'feature'
expect(page).not_to have_content 'fix'
expect(page).not_to have_content 'markdown'
- expect(count_merge_requests).to eq(1)
+ expect(count_merge_requests).to eq(2)
end
it 'filters on a specific assignee' do
@@ -90,28 +99,35 @@ RSpec.describe 'Merge requests > User lists merge requests' do
expect(first_merge_request).to include('fix')
expect(last_merge_request).to include('merge-test')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by last updated' do
visit_merge_requests(project, sort: sort_value_recently_updated)
expect(first_merge_request).to include('merge-test')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by milestone' do
visit_merge_requests(project, sort: sort_value_milestone)
expect(first_merge_request).to include('fix')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by merged at' do
visit_merge_requests(project, sort: sort_value_merged_date)
expect(first_merge_request).to include('markdown')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
+ end
+
+ it 'sorts by closed at' do
+ visit_merge_requests(project, sort: sort_value_closed_date)
+
+ expect(first_merge_request).to include('feature')
+ expect(count_merge_requests).to eq(4)
end
it 'filters on one label and sorts by due date' do
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
index 74f579e77ed..d3e1bfef561 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/author_token_spec.js
@@ -86,7 +86,7 @@ describe('AuthorToken', () => {
});
describe('methods', () => {
- describe('fetchAuthorBySearchTerm', () => {
+ describe('fetchAuthors', () => {
beforeEach(() => {
wrapper = createComponent();
});
@@ -155,7 +155,7 @@ describe('AuthorToken', () => {
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
suggestions: mockAuthors,
- fnActiveTokenValue: wrapper.vm.getActiveAuthor,
+ getActiveTokenValue: wrapper.vm.getActiveAuthor,
});
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
index cd6ffd679d0..c746cb7749a 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
@@ -53,7 +53,6 @@ const mockProps = {
suggestionsLoading: false,
defaultSuggestions: DEFAULT_LABELS,
recentSuggestionsStorageKey: mockStorageKey,
- fnCurrentTokenValue: jest.fn(),
};
function createComponent({
@@ -99,31 +98,20 @@ describe('BaseToken', () => {
});
describe('computed', () => {
- describe('currentTokenValue', () => {
- it('calls `fnCurrentTokenValue` when it is provided', () => {
- // We're disabling lint to trigger computed prop execution for this test.
- // eslint-disable-next-line no-unused-vars
- const { currentTokenValue } = wrapper.vm;
-
- expect(wrapper.vm.fnCurrentTokenValue).toHaveBeenCalledWith(`"${mockRegularLabel.title}"`);
- });
- });
-
describe('activeTokenValue', () => {
- it('calls `fnActiveTokenValue` when it is provided', async () => {
- const mockFnActiveTokenValue = jest.fn();
+ it('calls `getActiveTokenValue` when it is provided', async () => {
+ const mockGetActiveTokenValue = jest.fn();
wrapper.setProps({
- fnActiveTokenValue: mockFnActiveTokenValue,
- fnCurrentTokenValue: undefined,
+ getActiveTokenValue: mockGetActiveTokenValue,
});
await wrapper.vm.$nextTick();
- expect(mockFnActiveTokenValue).toHaveBeenCalledTimes(1);
- expect(mockFnActiveTokenValue).toHaveBeenCalledWith(
+ expect(mockGetActiveTokenValue).toHaveBeenCalledTimes(1);
+ expect(mockGetActiveTokenValue).toHaveBeenCalledWith(
mockLabels,
- `"${mockRegularLabel.title.toLowerCase()}"`,
+ `"${mockRegularLabel.title}"`,
);
});
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
index ec9458f64d2..e5ffbd41afa 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js
@@ -98,11 +98,11 @@ describe('LabelToken', () => {
});
});
- describe('fetchLabelBySearchTerm', () => {
+ describe('fetchLabels', () => {
it('calls `config.fetchLabels` with provided searchTerm param', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels');
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
expect(wrapper.vm.config.fetchLabels).toHaveBeenCalledWith('foo');
});
@@ -110,7 +110,7 @@ describe('LabelToken', () => {
it('sets response to `labels` when request is succesful', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockResolvedValue(mockLabels);
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.labels).toEqual(mockLabels);
@@ -120,7 +120,7 @@ describe('LabelToken', () => {
it('calls `createFlash` with flash error message when request fails', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockRejectedValue({});
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(createFlash).toHaveBeenCalledWith({
@@ -132,7 +132,7 @@ describe('LabelToken', () => {
it('sets `loading` to false when request completes', () => {
jest.spyOn(wrapper.vm.config, 'fetchLabels').mockRejectedValue({});
- wrapper.vm.fetchLabelBySearchTerm('foo');
+ wrapper.vm.fetchLabels('foo');
return waitForPromises().then(() => {
expect(wrapper.vm.loading).toBe(false);
@@ -160,7 +160,7 @@ describe('LabelToken', () => {
expect(baseTokenEl.exists()).toBe(true);
expect(baseTokenEl.props()).toMatchObject({
suggestions: mockLabels,
- fnActiveTokenValue: wrapper.vm.getActiveLabel,
+ getActiveTokenValue: wrapper.vm.getActiveLabel,
});
});
diff --git a/spec/graphql/resolvers/merge_requests_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
index aec6c6c6708..64ee0d4f9cc 100644
--- a/spec/graphql/resolvers/merge_requests_resolver_spec.rb
+++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb
@@ -303,6 +303,29 @@ RSpec.describe Resolvers::MergeRequestsResolver do
expect { resolve_mr(project, sort: :merged_at_desc, labels: %w[a b]) }.not_to raise_error
end
end
+
+ context 'when sorting by closed at' do
+ before do
+ merge_request_1.metrics.update!(latest_closed_at: 10.days.ago)
+ merge_request_3.metrics.update!(latest_closed_at: 5.days.ago)
+ end
+
+ it 'sorts merge requests ascending' do
+ expect(resolve_mr(project, sort: :closed_at_asc))
+ .to match_array(mrs)
+ .and be_sorted(->(mr) { [closed_at(mr), -mr.id] })
+ end
+
+ it 'sorts merge requests descending' do
+ expect(resolve_mr(project, sort: :closed_at_desc))
+ .to match_array(mrs)
+ .and be_sorted(->(mr) { [-closed_at(mr), -mr.id] })
+ end
+
+ def closed_at(mr)
+ nils_last(mr.metrics.latest_closed_at)
+ end
+ end
end
end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index edd543854cb..4a8a2909891 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -80,6 +80,24 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
+ describe '.order_closed_at_asc' do
+ let_it_be(:older_mr) { create(:merge_request, :closed_last_month) }
+ let_it_be(:newer_mr) { create(:merge_request, :closed_last_month) }
+
+ it 'returns MRs ordered by closed_at ascending' do
+ expect(described_class.order_closed_at_asc).to eq([older_mr, newer_mr])
+ end
+ end
+
+ describe '.order_closed_at_desc' do
+ let_it_be(:older_mr) { create(:merge_request, :closed_last_month) }
+ let_it_be(:newer_mr) { create(:merge_request, :closed_last_month) }
+
+ it 'returns MRs ordered by closed_at descending' do
+ expect(described_class.order_closed_at_desc).to eq([newer_mr, older_mr])
+ end
+ end
+
describe '.with_jira_issue_keys' do
let_it_be(:mr_with_jira_title) { create(:merge_request, :unique_branches, title: 'Fix TEST-123') }
let_it_be(:mr_with_jira_description) { create(:merge_request, :unique_branches, description: 'this closes TEST-321') }
@@ -577,6 +595,26 @@ RSpec.describe MergeRequest, factory_default: :keep do
expect(merge_requests).to eq([newer_mr, older_mr])
end
end
+
+ context 'closed_at' do
+ let_it_be(:older_mr) { create(:merge_request, :closed_last_month) }
+ let_it_be(:newer_mr) { create(:merge_request, :closed_last_month) }
+
+ it 'sorts asc' do
+ merge_requests = described_class.sort_by_attribute(:closed_at_asc)
+ expect(merge_requests).to eq([older_mr, newer_mr])
+ end
+
+ it 'sorts desc' do
+ merge_requests = described_class.sort_by_attribute(:closed_at_desc)
+ expect(merge_requests).to eq([newer_mr, older_mr])
+ end
+
+ it 'sorts asc when its closed_at' do
+ merge_requests = described_class.sort_by_attribute(:closed_at)
+ expect(merge_requests).to eq([older_mr, newer_mr])
+ end
+ end
end
describe 'time to merge calculations' do
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
index 7fc1ef05fa7..1b0405be09c 100644
--- a/spec/requests/api/graphql/project/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -422,6 +422,46 @@ RSpec.describe 'getting merge request listings nested in a project' do
end
end
end
+
+ context 'when sorting by closed_at DESC' do
+ let(:sort_param) { :CLOSED_AT_DESC }
+ let(:expected_results) do
+ [
+ merge_request_b,
+ merge_request_d,
+ merge_request_c,
+ merge_request_e,
+ merge_request_a
+ ].map { |mr| global_id_of(mr) }
+ end
+
+ before do
+ five_days_ago = 5.days.ago
+
+ merge_request_d.metrics.update!(latest_closed_at: five_days_ago)
+
+ # same merged_at, the second order column will decide (merge_request.id)
+ merge_request_c.metrics.update!(latest_closed_at: five_days_ago)
+
+ merge_request_b.metrics.update!(latest_closed_at: 1.day.ago)
+ end
+
+ it_behaves_like 'sorted paginated query' do
+ let(:first_param) { 2 }
+ end
+
+ context 'when last parameter is given' do
+ let(:params) { graphql_args(sort: sort_param, last: 2) }
+ let(:page_info) { nil }
+
+ it 'takes the last 2 records' do
+ query = pagination_query(params)
+ post_graphql(query, current_user: current_user)
+
+ expect(results.map { |item| item["id"] }).to eq(expected_results.last(2))
+ end
+ end
+ end
end
context 'when only the count is requested' do