Commit 511f5570 authored by Nick Thomas's avatar Nick Thomas

Merge remote-tracking branch 'upstream/master' into ce-to-ee

parents 806371bf 131e1db5
......@@ -117,19 +117,34 @@ module IssuableCollections
key = 'issuable_sort'
cookies[key] = params[:sort] if params[:sort].present?
# id_desc and id_asc are old values for these two.
cookies[key] = sort_value_recently_created if cookies[key] == 'id_desc'
cookies[key] = sort_value_oldest_created if cookies[key] == 'id_asc'
cookies[key] = update_cookie_value(cookies[key])
params[:sort] = cookies[key]
end
def default_sort_order
case params[:state]
when 'opened', 'all' then sort_value_recently_created
when 'opened', 'all' then sort_value_created_date
when 'merged', 'closed' then sort_value_recently_updated
else sort_value_recently_created
else sort_value_created_date
end
end
# Update old values to the actual ones.
def update_cookie_value(value)
case value
when 'id_asc' then sort_value_oldest_created
when 'id_desc' then sort_value_recently_created
when 'created_asc' then sort_value_created_date
when 'created_desc' then sort_value_created_date
when 'due_date_asc' then sort_value_due_date
when 'due_date_desc' then sort_value_due_date
when 'milestone_due_asc' then sort_value_milestone
when 'milestone_due_desc' then sort_value_milestone
when 'downvotes_asc' then sort_value_popularity
when 'downvotes_desc' then sort_value_popularity
when 'weight_asc' then sort_value_weight
when 'weight_desc' then sort_value_weight
else value
end
end
end
This diff is collapsed.
......@@ -142,15 +142,17 @@ module Issuable
end
def sort(method, excluded_labels: [])
sorted = case method.to_s
when 'milestone_due_asc' then order_milestone_due_asc
when 'milestone_due_desc' then order_milestone_due_desc
sorted =
case method.to_s
when 'downvotes_desc' then order_downvotes_desc
when 'upvotes_desc' then order_upvotes_desc
when 'label_priority' then order_labels_priority(excluded_labels: excluded_labels)
when 'milestone' then order_milestone_due_asc
when 'milestone_due_asc' then order_milestone_due_asc
when 'milestone_due_desc' then order_milestone_due_desc
when 'popularity' then order_upvotes_desc
when 'priority' then order_due_date_and_labels_priority(excluded_labels: excluded_labels)
else
order_by(method)
when 'upvotes_desc' then order_upvotes_desc
else order_by(method)
end
# Break ties with the ID column for pagination
......@@ -224,7 +226,7 @@ module Issuable
def grouping_columns(sort)
grouping_columns = [arel_table[:id]]
if %w(milestone_due_desc milestone_due_asc).include?(sort)
if %w(milestone_due_desc milestone_due_asc milestone).include?(sort)
milestone_table = Milestone.arel_table
grouping_columns << milestone_table[:id]
grouping_columns << milestone_table[:due_date]
......
......@@ -19,14 +19,15 @@ module Sortable
module ClassMethods
def order_by(method)
case method.to_s
when 'created_asc' then order_created_asc
when 'created_date' then order_created_desc
when 'created_desc' then order_created_desc
when 'id_asc' then order_id_asc
when 'id_desc' then order_id_desc
when 'name_asc' then order_name_asc
when 'name_desc' then order_name_desc
when 'updated_asc' then order_updated_asc
when 'updated_desc' then order_updated_desc
when 'created_asc' then order_created_asc
when 'created_desc' then order_created_desc
when 'id_desc' then order_id_desc
when 'id_asc' then order_id_asc
else
all
end
......
......@@ -128,10 +128,12 @@ class Issue < ActiveRecord::Base
def self.sort(method, excluded_labels: [])
case method.to_s
when 'due_date' then order_due_date_asc
when 'due_date_asc' then order_due_date_asc
when 'due_date_desc' then order_due_date_desc
when 'weight_desc' then order_weight_desc
when 'weight' then order_weight_asc
when 'weight_asc' then order_weight_asc
when 'weight_desc' then order_weight_desc
else
super
end
......
......@@ -41,7 +41,7 @@ module Geo
end
rescue OpenSSL::Cipher::CipherError
['Error decrypting the Geo secret from the database. Check that the primary uses the correct db_key_base.']
rescue HTTParty::Error, Timeout::Error, SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED => e
rescue HTTParty::Error, Timeout::Error, SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
[e.message]
end
......
- sorted_by = sort_options_hash[@sort]
- viewing_issues = controller.controller_name == 'issues' || controller.action_name == 'issues'
.dropdown.inline.prepend-left-10
%button.dropdown-toggle{ type: 'button', data: {toggle: 'dropdown' } }
- if @sort.present?
= sort_options_hash[@sort]
- else
= sort_title_recently_created
%button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown' } }
= sorted_by
= icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort
%ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-selectable.dropdown-menu-sort
%li
= link_to page_filter_path(sort: sort_value_priority, label: true) do
= sort_title_priority
= link_to page_filter_path(sort: sort_value_label_priority, label: true) do
= sort_title_label_priority
= link_to page_filter_path(sort: sort_value_recently_created, label: true) do
= sort_title_recently_created
= link_to page_filter_path(sort: sort_value_oldest_created, label: true) do
= sort_title_oldest_created
= link_to page_filter_path(sort: sort_value_recently_updated, label: true) do
= sort_title_recently_updated
= link_to page_filter_path(sort: sort_value_oldest_updated, label: true) do
= sort_title_oldest_updated
= sortable_item(sort_title_priority, page_filter_path(sort: sort_value_priority, label: true), sorted_by)
= sortable_item(sort_title_created_date, page_filter_path(sort: sort_value_created_date, label: true), sorted_by)
= sortable_item(sort_title_recently_updated, page_filter_path(sort: sort_value_recently_updated, label: true), sorted_by)
- if viewing_issues && (@project || @group)&.feature_available?(:issue_weights)
= link_to page_filter_path(sort: sort_value_more_weight, label: true) do
= sort_title_more_weight
= link_to page_filter_path(sort: sort_value_less_weight, label: true) do
= sort_title_less_weight
= sortable_item(sort_title_weight, page_filter_path(sort: sort_value_weight, label: true), sorted_by)
= link_to page_filter_path(sort: sort_value_milestone_soon, label: true) do
= sort_title_milestone_soon
= link_to page_filter_path(sort: sort_value_milestone_later, label: true) do
= sort_title_milestone_later
- if viewing_issues
= link_to page_filter_path(sort: sort_value_due_date_soon, label: true) do
= sort_title_due_date_soon
= link_to page_filter_path(sort: sort_value_due_date_later, label: true) do
= sort_title_due_date_later
= link_to page_filter_path(sort: sort_value_upvotes, label: true) do
= sort_title_upvotes
= link_to page_filter_path(sort: sort_value_downvotes, label: true) do
= sort_title_downvotes
= sortable_item(sort_title_milestone, page_filter_path(sort: sort_value_milestone, label: true), sorted_by)
= sortable_item(sort_title_due_date, page_filter_path(sort: sort_value_due_date, label: true), sorted_by) if viewing_issues
= sortable_item(sort_title_popularity, page_filter_path(sort: sort_value_popularity, label: true), sorted_by)
= sortable_item(sort_title_label_priority, page_filter_path(sort: sort_value_label_priority, label: true), sorted_by)
---
title: Fix an error reporting some failures in the elasticsearch indexer
merge_request: 2998
author:
type: fixed
---
title: Improve list of sorting options
merge_request: 14320
author: Vitaliy @blackst0ne Klachkov
type: added
......@@ -262,7 +262,7 @@ get the cluster up and running.
Verify the nodes are all communicating:
```sh
sudo consul members
sudo /opt/gitlab/embedded/bin/consul members
```
The output should be similar to:
......
......@@ -51,36 +51,34 @@ Feature: Project Issues
@javascript
Scenario: Visiting Issues after being sorted the list
Given I visit project "Shop" issues page
And I sort the list by "Oldest updated"
And I sort the list by "Last updated"
And I visit my project's home page
And I visit project "Shop" issues page
Then The list should be sorted by "Oldest updated"
Then The list should be sorted by "Last updated"
@javascript
Scenario: Visiting Merge Requests after being sorted the list
Given project "Shop" has a "Bugfix MR" merge request open
And I visit project "Shop" issues page
And I sort the list by "Oldest updated"
And I sort the list by "Last updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
Then The list should be sorted by "Last updated"
@javascript
Scenario: Visiting Merge Requests from a differente Project after sorting
Given project "Shop" has a "Bugfix MR" merge request open
And I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I sort the list by "Last updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
Then The list should be sorted by "Last updated"
@javascript
Scenario: Sort issues by upvotes/downvotes
Given project "Shop" have "Bugfix" open issue
And issue "Release 0.4" have 2 upvotes and 1 downvote
And issue "Tweet control" have 1 upvote and 2 downvotes
And I sort the list by "Most popular"
Then The list should be sorted by "Most popular"
And I sort the list by "Least popular"
Then The list should be sorted by "Least popular"
And I sort the list by "Popularity"
Then The list should be sorted by "Popularity"
# Markdown
......
......@@ -91,28 +91,26 @@ Feature: Project Merge Requests
@javascript
Scenario: Visiting Merge Requests after being sorted the list
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I sort the list by "Last updated"
And I visit my project's home page
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
Then The list should be sorted by "Last updated"
@javascript
Scenario: Visiting Merge Requests from a different Project after sorting
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I sort the list by "Last updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
Then The list should be sorted by "Last updated"
@javascript
Scenario: Sort merge requests by upvotes/downvotes
Scenario: Sort merge requests by upvotes
Given project "Shop" have "Bug NS-05" open merge request with diffs inside
And project "Shop" have "Bug NS-06" open merge request
And merge request "Bug NS-04" have 2 upvotes and 1 downvote
And merge request "Bug NS-06" have 1 upvote and 2 downvotes
And I sort the list by "Most popular"
Then The list should be sorted by "Most popular"
And I sort the list by "Least popular"
Then The list should be sorted by "Least popular"
And I sort the list by "Popularity"
Then The list should be sorted by "Popularity"
@javascript
Scenario: I comment on a merge request diff
......
......@@ -223,7 +223,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
end
step 'The list should be sorted by "Most popular"' do
step 'The list should be sorted by "Popularity"' do
page.within '.issues-list' do
page.within 'li.issue:nth-child(1)' do
expect(page).to have_content 'Release 0.4'
......
......@@ -222,7 +222,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
end
step 'The list should be sorted by "Most popular"' do
step 'The list should be sorted by "Popularity"' do
page.within '.mr-list' do
page.within 'li.merge-request:nth-child(1)' do
expect(page).to have_content 'Bug NS-04'
......
......@@ -112,10 +112,10 @@ module SharedIssuable
edit_issuable
end
step 'I sort the list by "Oldest updated"' do
step 'I sort the list by "Last updated"' do
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link "Oldest updated"
click_link "Last updated"
end
end
......@@ -127,16 +127,16 @@ module SharedIssuable
end
end
step 'I sort the list by "Most popular"' do
step 'I sort the list by "Popularity"' do
find('button.dropdown-toggle').click
page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do
click_link 'Most popular'
click_link 'Popularity'
end
end
step 'The list should be sorted by "Oldest updated"' do
expect(find('.issues-filters')).to have_content('Oldest updated')
step 'The list should be sorted by "Last updated"' do
expect(find('.issues-filters')).to have_content('Last updated')
end
step 'I click link "Next" in the sidebar' do
......
......@@ -63,7 +63,7 @@ module Gitlab
output, status = Gitlab::Popen.popen(command, nil, vars)
raise Error, output unless status.zero?
raise Error, output unless status&.zero?
end
def update_index_status(to_sha)
......
......@@ -100,19 +100,10 @@ describe Projects::IssuesController do
end
describe '#index' do
it 'allows sorting by weight (ascending)' do
it 'allows sorting by weight' do
expected = [issue, issue2].sort_by(&:weight)
perform :get, :index, sort: 'weight_asc'
expect(response).to have_http_status(200)
expect(assigns(:issues)).to eq(expected)
end
it 'allows sorting by weight (descending)' do
expected = [issue, issue2].sort { |a, b| b.weight <=> a.weight }
perform :get, :index, sort: 'weight_desc'
perform :get, :index, sort: 'weight'
expect(response).to have_http_status(200)
expect(assigns(:issues)).to eq(expected)
......@@ -157,9 +148,6 @@ describe Projects::IssuesController do
end
describe '#index' do
it 'ignores sorting by weight (ascending)'
it 'ignores sorting by weight (descending)'
it 'ignores filtering by weight' do
expected = [issue, issue2]
......
......@@ -90,17 +90,17 @@ feature 'Dashboard Issues filtering', :js do
context 'sorting' do
it 'shows sorted issues' do
sorting_by('Oldest updated')
sorting_by('Created date')
visit_issues
expect(find('.issues-filters')).to have_content('Oldest updated')
expect(find('.issues-filters')).to have_content('Created date')
end
it 'keeps sorting issues after visiting Projects Issues page' do
sorting_by('Oldest updated')
sorting_by('Created date')
visit project_issues_path(project)
expect(find('.issues-filters')).to have_content('Oldest updated')
expect(find('.issues-filters')).to have_content('Created date')
end
end
......
......@@ -112,19 +112,19 @@ feature 'Dashboard Merge Requests' do
end
it 'shows sorted merge requests' do
sorting_by('Oldest updated')
sorting_by('Created date')
visit merge_requests_dashboard_path(assignee_id: current_user.id)
expect(find('.issues-filters')).to have_content('Oldest updated')
expect(find('.issues-filters')).to have_content('Created date')
end
it 'keeps sorting merge requests after visiting Projects MR page' do
sorting_by('Oldest updated')
sorting_by('Created date')
visit project_merge_requests_path(project)
expect(find('.issues-filters')).to have_content('Oldest updated')
expect(find('.issues-filters')).to have_content('Created date')
end
end
end
......@@ -40,10 +40,10 @@ describe 'Projects > Issuables > Default sort order' do
context 'in the "merge requests / open" tab', js: true do
let(:issuable_type) { :merge_request }
it 'is "last created"' do
it 'is "created date"' do
visit_merge_requests_with_state(project, 'open')
expect(selected_sort_order).to eq('last created')
expect(selected_sort_order).to eq('created date')
expect(first_merge_request).to include(last_created_issuable.title)
expect(last_merge_request).to include(first_created_issuable.title)
end
......@@ -76,10 +76,10 @@ describe 'Projects > Issuables > Default sort order' do
context 'in the "merge requests / all" tab', js: true do
let(:issuable_type) { :merge_request }
it 'is "last created"' do
it 'is "created date"' do
visit_merge_requests_with_state(project, 'all')
expect(find('.issues-other-filters')).to have_content('Last created')
expect(find('.issues-other-filters')).to have_content('Created date')
expect(first_merge_request).to include(last_created_issuable.title)
expect(last_merge_request).to include(first_created_issuable.title)
end
......@@ -105,10 +105,10 @@ describe 'Projects > Issuables > Default sort order' do
context 'in the "issues" tab', js: true do
let(:issuable_type) { :issue }
it 'is "last created"' do
it 'is "created date"' do
visit_issues project
expect(find('.issues-other-filters')).to have_content('Last created')
expect(find('.issues-other-filters')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
......@@ -117,10 +117,10 @@ describe 'Projects > Issuables > Default sort order' do
context 'in the "issues / open" tab', js: true do
let(:issuable_type) { :issue }
it 'is "last created"' do
it 'is "created date"' do
visit_issues_with_state(project, 'open')
expect(find('.issues-other-filters')).to have_content('Last created')
expect(find('.issues-other-filters')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
......@@ -141,10 +141,10 @@ describe 'Projects > Issuables > Default sort order' do
context 'in the "issues / all" tab', js: true do
let(:issuable_type) { :issue }
it 'is "last created"' do
it 'is "created date"' do
visit_issues_with_state(project, 'all')
expect(find('.issues-other-filters')).to have_content('Last created')
expect(find('.issues-other-filters')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
......@@ -157,26 +157,12 @@ describe 'Projects > Issuables > Default sort order' do
visit_issues(project, sort: 'id_desc')
end
it 'shows the sort order as last created' do
expect(find('.issues-other-filters')).to have_content('Last created')
it 'shows the sort order as created date' do
expect(find('.issues-other-filters')).to have_content('Created date')
expect(first_issue).to include(last_created_issuable.title)
expect(last_issue).to include(first_created_issuable.title)
end
end
context 'when the sort in the URL is id_asc' do
let(:issuable_type) { :issue }
before do
visit_issues(project, sort: 'id_asc')
end
it 'shows the sort order as oldest created' do
expect(find('.issues-other-filters')).to have_content('Oldest created')
expect(first_issue).to include(first_created_issuable.title)
expect(last_issue).to include(last_created_issuable.title)
end
end
end
def selected_sort_order
......
......@@ -422,20 +422,18 @@ describe 'Filter issues', js: true do
end
context 'sorting' do
it 'sorts by oldest updated' do
create(:issue,
it 'sorts by created date' do
new_issue = create(:issue,
title: '3 days ago',
project: project,
author: user,
created_at: 3.days.ago,
updated_at: 3.days.ago)
created_at: 3.days.ago)
old_issue = create(:issue,
create(:issue,
title: '5 days ago',
project: project,
author: user,
created_at: 5.days.ago,
updated_at: 5.days.ago)
created_at: 5.days.ago)
input_filtered_search('days ago')
......@@ -444,10 +442,10 @@ describe 'Filter issues', js: true do
sort_toggle = find('.filtered-search-wrapper .dropdown-toggle')
sort_toggle.click
find('.filtered-search-wrapper .dropdown-menu li a', text: 'Oldest updated').click
find('.filtered-search-wrapper .dropdown-menu li a', text: 'Created date').click
wait_for_requests
expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(old_issue.title)
expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(new_issue.title)
end
end
end
......
......@@ -201,19 +201,12 @@ describe 'Issues' do
let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') }
it 'sorts by newest' do
visit project_issues_path(project, sort: sort_value_recently_created)
visit project_issues_path(project, sort: sort_value_created_date)
expect(first_issue).to include('foo')
expect(last_issue).to include('baz')
end
it 'sorts by oldest' do
visit project_issues_path(project, sort: sort_value_oldest_created)
expect(first_issue).to include('baz')
expect(last_issue).to include('foo')
end
it 'sorts by most recently updated' do
baz.updated_at = Time.now + 100
baz.save
......@@ -222,36 +215,22 @@ describe 'Issues' do
expect(first_issue).to include('baz')
end
it 'sorts by least recently updated' do
baz.updated_at = Time.now - 100
baz.save
visit project_issues_path(project, sort: sort_value_oldest_updated)
expect(first_issue).to include('baz')
end
describe 'sorting by due date' do
before do
foo.update(due_date: 1.day.from_now)
bar.update(due_date: 6.days.from_now)
end
it 'sorts by recently due date' do
visit project_issues_path(project, sort: sort_value_due_date_soon)
it 'sorts by due date' do
visit project_issues_path(project, sort: sort_value_due_date)
expect(first_issue).to include('foo')
end
it 'sorts by least recently due date' do
visit project_issues_path(project, sort: sort_value_due_date_later)
expect(first_issue).to include('bar')
end
it 'sorts by least recently due date by excluding nil due dates' do
it 'sorts by due date by excluding nil due dates' do
bar.update(due_date: nil)
visit project_issues_path(project, sort: sort_value_due_date_later)
visit project_issues_path(project, sort: sort_value_due_date)
expect(first_issue).to include('foo')
end
......@@ -350,19 +329,12 @@ describe 'Issues' do
bar.save
end
it 'sorts by recently due milestone' do
visit project_issues_path(project, sort: sort_value_milestone_soon)
it 'sorts by milestone' do
visit project_issues_path(project, sort: sort_value_milestone)
expect(first_issue).to include('foo')
expect(last_issue).to include('baz')
end
it 'sorts by least recently due milestone' do
visit project_issues_path(project, sort: sort_value_milestone_later)
expect(first_issue).to include('bar')
expect(last_issue).to include('baz')
end
end
describe 'combine filter and sort' do
......@@ -376,13 +348,11 @@ describe 'Issues' do
end
it 'sorts with a filter applied' do
visit project_issues_path(project,
sort: sort_value_oldest_created,
assignee_id: user2.id)
visit project_issues_path(project, sort: sort_value_created_date, assignee_id: user2.id)
expect(first_issue).to include('bar')
expect(last_issue).to include('foo')
expect(page).not_to have_content 'baz'
expect(first_issue).to include('foo')
expect(last_issue).to include('bar')
expect(page).not_to have_content('baz')
end
end
end
......
......@@ -277,9 +277,9 @@ describe 'Filter merge requests' do
expect_mr_list_count(2)
click_button 'Last created'
click_button 'Created date'
page.within '.dropdown-menu-sort' do
click_link 'Oldest created'
click_link 'Priority'
end
wait_for_requests
......
......@@ -52,21 +52,13 @@ describe 'Projects > Merge requests > User lists merge requests' do
end
it 'sorts by newest' do
visit_merge_requests(project, sort: sort_value_recently_created)
visit_merge_requests(project, sort: sort_value_created_date)
expect(first_merge_request).to include('fix')
expect(last_merge_request).to include('merge-test')
expect(count_merge_requests).to eq(3)
end
it 'sorts by oldest' do
visit_merge_requests(project, sort: sort_value_oldest_created)
expect(first_merge_request).to include('merge-test')
expect(last_merge_request).to include('fix')
expect(count_merge_requests).to eq(3)
end
it 'sorts by last updated' do
visit_merge_requests(project, sort: sort_value_recently_updated)
......@@ -74,33 +66,19 @@ describe 'Projects > Merge requests > User lists merge requests' do
expect(count_merge_requests).to eq(3)
end
it 'sorts by oldest updated' do
visit_merge_requests(project, sort: sort_value_oldest_updated)
expect(first_merge_request).to include('markdown')
expect(count_merge_requests).to eq(3)
end
it 'sorts by milestone due soon' do
visit_merge_requests(project, sort: sort_value_milestone_soon)
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)
end
it 'sorts by milestone due later' do
visit_merge_requests(project, sort: sort_value_milestone_later)
expect(first_merge_request).to include('markdown')
expect(count_merge_requests).to eq(3)
end
it 'filters on one label and sorts by due soon' do
it 'filters on one label and sorts by due date' do
label = create(:label, project: project)
create(:label_link, label: label, target: @fix)
visit_merge_requests(project, label_name: [label.name],
sort: sort_value_due_date_soon)
sort: sort_value_due_date)
expect(first_merge_request).to include('fix')
expect(count_merge_requests).to eq(1)
......@@ -115,9 +93,9 @@ describe 'Projects > Merge requests > User lists merge requests' do
create(:label_link, label: label2, target: @fix)
end
it 'sorts by due soon' do
it 'sorts by due date' do
visit_merge_requests(project, label_name: [label.name, label2.name],
sort: sort_value_due_date_soon)
sort: sort_value_due_date)
expect(first_merge_request).to include('fix')
expect(count_merge_requests).to eq(1)
......@@ -127,7 +105,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
it 'sorts by due soon' do
visit_merge_requests(project, label_name: [label.name, label2.name],
assignee_id: user.id,
sort: sort_value_due_date_soon)
sort: sort_value_due_date)
expect(first_merge_request).to include('fix')
expect(count_merge_requests).to eq(1)
......@@ -137,7 +115,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
visit project_merge_requests_path(project,
label_name: [label.name, label2.name],
assignee_id: user.id,
sort: sort_value_milestone_soon)
sort: sort_value_milestone)
expect(first_merge_request).to include('fix')
end
......
require 'spec_helper'
describe ProjectPolicy do
let(:guest) { create(:user) }
let(:reporter) { create(:user) }
let(:dev) { create(:user) }
let(:master) { create(:user) }
let(:owner) { create(:user) }
let(:auditor) { create(:user, :auditor) }
let(:admin) { create(:admin) }
set(:guest) { create(:user) }
set(:reporter) { create(:user) }
set(:developer) { create(:user) }
set(:master) { create(:user) }
set(:owner) { create(:user) }
set(:admin) { create(:admin) }
let(:project) { create(:project, :public, namespace: owner.namespace) }
let(:guest_permissions) do
let(:base_guest_permissions) do
%i[
read_project read_board read_list read_wiki read_issue read_label
read_issue_link read_milestone read_project_snippet read_project_member
read_milestone read_project_snippet read_project_member
read_note create_project create_issue create_note
upload_file
]
end
let(:reporter_permissions) do
let(:base_reporter_permissions) do
%i[
download_code fork_project create_project_snippet update_issue
admin_issue admin_label admin_issue_link admin_list read_commit_status read_build
admin_issue admin_label admin_list read_commit_status read_build
read_container_image read_pipeline read_environment read_deployment
read_merge_request download_wiki_code
]
......@@ -42,10 +41,9 @@ describe ProjectPolicy do
]
end
let(:master_permissions) do
let(:base_master_permissions) do
%i[
push_code_to_protected_branches delete_protected_branch
update_project_snippet update_environment
delete_protected_branch update_project_snippet update_environment
update_deployment admin_project_snippet
admin_project_member admin_note admin_wiki admin_project
admin_commit_status admin_build admin_container_image
......@@ -68,21 +66,20 @@ describe ProjectPolicy do
]
end
let(:auditor_permissions) do
%i[
download_code download_wiki_code read_project read_board read_list
read_wiki read_issue read_label read_issue_link read_milestone read_project_snippet
read_project_member read_note read_cycle_analytics read_pipeline
read_build read_commit_status read_container_image read_environment
read_deployment read_merge_request read_pages
]
end
# Used in EE specs
let(:additional_guest_permissions) { [] }
let(:additional_reporter_permissions) { [] }
let(:additional_master_permissions) { [] }
let(:guest_permissions) { base_guest_permissions + additional_guest_permissions }
let(:reporter_permissions) { base_reporter_permissions + additional_reporter_permissions }
let(:master_permissions) { base_master_permissions + additional_master_permissions }
before do
project.team << [guest, :guest]
project.team << [master, :master]
project.team << [dev, :developer]
project.team << [reporter, :reporter]
project.add_guest(guest)
project.add_master(master)
project.add_developer(developer)
project.add_reporter(reporter)
end
def expect_allowed(*permissions)
......@@ -139,7 +136,9 @@ describe ProjectPolicy do
end
end
context 'when a project has pending invites, and the current user is anonymous' do
shared_examples 'project policies as anonymous' do
context 'abilities for public projects' do
context 'when a project has pending invites' do
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public, namespace: group) }
let(:user_permissions) { [:create_project, :create_issue, :create_note, :upload_file] }
......@@ -156,21 +155,22 @@ describe ProjectPolicy do
expect_disallowed(*user_permissions)
end
end
end
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
subject { described_class.new(current_user, project) }
context 'with no user' do
let(:current_user) { nil }
subject { described_class.new(nil, project) }
it { is_expected.to be_banned }
end
end
context 'guests' do
let(:current_user) { guest }
shared_examples 'project policies as guest' do
subject { described_class.new(guest, project) }
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
let(:reporter_public_build_permissions) do
reporter_permissions - [:read_build, :read_pipeline]
end
......@@ -191,7 +191,7 @@ describe ProjectPolicy do
end
end
context 'public builds disabled' do
context 'when public builds disabled' do
before do
project.update(public_builds: false)
end
......@@ -204,8 +204,7 @@ describe ProjectPolicy do
context 'when builds are disabled' do
before do
project.project_feature.update(
builds_access_level: ProjectFeature::DISABLED)
project.project_feature.update(builds_access_level: ProjectFeature::DISABLED)
end
it do
......@@ -214,9 +213,13 @@ describe ProjectPolicy do
end
end
end
end
shared_examples 'project policies as reporter' do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
context 'reporter' do
let(:current_user) { reporter }
subject { described_class.new(reporter, project) }
it do
expect_allowed(*guest_permissions)
......@@ -228,9 +231,13 @@ describe ProjectPolicy do
expect_disallowed(*owner_permissions)
end
end
end
shared_examples 'project policies as developer' do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
context 'developer' do
let(:current_user) { dev }
subject { described_class.new(developer, project) }
it do
expect_allowed(*guest_permissions)
......@@ -241,9 +248,13 @@ describe ProjectPolicy do
expect_disallowed(*owner_permissions)
end
end
end
context 'master' do
let(:current_user) { master }
shared_examples 'project policies as master' do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
subject { described_class.new(master, project) }
it do
expect_allowed(*guest_permissions)
......@@ -254,9 +265,13 @@ describe ProjectPolicy do
expect_disallowed(*owner_permissions)
end
end
end
context 'owner' do
let(:current_user) { owner }
shared_examples 'project policies as owner' do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
subject { described_class.new(owner, project) }
it do
expect_allowed(*guest_permissions)
......@@ -267,9 +282,13 @@ describe ProjectPolicy do
expect_allowed(*owner_permissions)
end
end
end
shared_examples 'project policies as admin' do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
context 'admin' do
let(:current_user) { admin }
subject { described_class.new(admin, project) }
it do
expect_allowed(*guest_permissions)
......@@ -280,11 +299,44 @@ describe ProjectPolicy do
expect_allowed(*owner_permissions)
end
end
end
it_behaves_like 'project policies as anonymous'
it_behaves_like 'project policies as guest'
it_behaves_like 'project policies as reporter'
it_behaves_like 'project policies as developer'
it_behaves_like 'project policies as master'
it_behaves_like 'project policies as owner'
it_behaves_like 'project policies as admin'
context 'EE' do
let(:additional_guest_permissions) { [:read_issue_link] }
let(:additional_reporter_permissions) { [:admin_issue_link]}
let(:additional_master_permissions) { [:push_code_to_protected_branches] }
let(:auditor_permissions) do
%i[
download_code download_wiki_code read_project read_board read_list
read_wiki read_issue read_label read_issue_link read_milestone read_project_snippet
read_project_member read_note read_cycle_analytics read_pipeline
read_build read_commit_status read_container_image read_environment
read_deployment read_merge_request read_pages
]
end
it_behaves_like 'project policies as anonymous'
it_behaves_like 'project policies as guest'
it_behaves_like 'project policies as reporter'
it_behaves_like 'project policies as developer'
it_behaves_like 'project policies as master'
it_behaves_like 'project policies as owner'
it_behaves_like 'project policies as admin'
context 'auditor' do
let(:current_user) { auditor }
let(:auditor) { create(:user, :auditor) }
subject { described_class.new(auditor, project) }
context 'not a team member' do
context 'who is not a team member' do
it do
is_expected.to be_disallowed(*developer_permissions)
is_expected.to be_disallowed(*master_permissions)
......@@ -294,9 +346,9 @@ describe ProjectPolicy do
end
end
context 'team member' do
context 'who is a team member' do
before do
project.team << [auditor, :guest]
project.add_guest(auditor)
end
it do
......
......@@ -57,6 +57,23 @@ describe Geo::NodeStatusService do
expect(status.health).to eq("Could not connect to Geo node - HTTP Status Code: 401 Unauthorized\n")
end
it 'alerts on bad SSL certficate' do
message = 'bad certificate'
allow(described_class).to receive(:get).and_raise(OpenSSL::SSL::SSLError.new(message))
status = subject.call(secondary)
expect(status.health).to eq(message)
end
it 'handles connection refused' do
allow(described_class).to receive(:get).and_raise(Errno::ECONNREFUSED.new('bad connection'))
status = subject.call(secondary)
expect(status.health).to eq('Connection refused - bad connection')
end
it 'returns meaningful error message when primary uses incorrect db key' do
secondary # create it before mocking GeoNode#secret_access_key
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment