Commit 16ecb913 authored by GitLab Bot's avatar GitLab Bot

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

# Conflicts:
#	app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js
#	app/assets/javascripts/filtered_search/filtered_search_manager.js
#	app/assets/javascripts/pages/groups/issues/index.js
#	app/assets/javascripts/pages/groups/merge_requests/index.js
#	app/assets/javascripts/pages/projects/issues/index/index.js
#	app/assets/javascripts/pages/projects/merge_requests/index/index.js
#	app/controllers/admin/runners_controller.rb
#	app/helpers/sorting_helper.rb
#	app/models/ci/runner.rb
#	app/views/admin/runners/index.html.haml
#	lib/api/runners.rb
#	locale/gitlab.pot
#	spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js
#	spec/javascripts/filtered_search/dropdown_user_spec.js
#	spec/javascripts/filtered_search/dropdown_utils_spec.js
#	spec/javascripts/filtered_search/filtered_search_manager_spec.js
#	spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js

[ci skip]
parents 1e650461 4d029537
...@@ -11,8 +11,10 @@ export default () => ({ ...@@ -11,8 +11,10 @@ export default () => ({
endpoint: '', endpoint: '',
basePath: '', basePath: '',
commit: null, commit: null,
startVersion: null,
diffFiles: [], diffFiles: [],
mergeRequestDiffs: [], mergeRequestDiffs: [],
mergeRequestDiff: null,
diffLineCommentForms: {}, diffLineCommentForms: {},
diffViewType: viewTypeFromQueryString || viewTypeFromCookie || defaultViewType, diffViewType: viewTypeFromQueryString || viewTypeFromCookie || defaultViewType,
}); });
...@@ -3,10 +3,10 @@ import * as getters from '../getters'; ...@@ -3,10 +3,10 @@ import * as getters from '../getters';
import mutations from '../mutations'; import mutations from '../mutations';
import createState from './diff_state'; import createState from './diff_state';
export default { export default () => ({
namespaced: true, namespaced: true,
state: createState(), state: createState(),
getters, getters,
actions, actions,
mutations, mutations,
}; });
...@@ -97,12 +97,15 @@ export default class FilteredSearchDropdownManager { ...@@ -97,12 +97,15 @@ export default class FilteredSearchDropdownManager {
gl: NullDropdown, gl: NullDropdown,
element: this.container.querySelector('#js-dropdown-admin-runner-status'), element: this.container.querySelector('#js-dropdown-admin-runner-status'),
}, },
<<<<<<< HEAD
weight: { weight: {
reference: null, reference: null,
gl: DropdownWeight, gl: DropdownWeight,
element: this.container.querySelector('#js-dropdown-weight'), element: this.container.querySelector('#js-dropdown-weight'),
}, },
=======
>>>>>>> upstream/master
}; };
supportedTokens.forEach(type => { supportedTokens.forEach(type => {
......
...@@ -3,7 +3,11 @@ import { ...@@ -3,7 +3,11 @@ import {
getParameterByName, getParameterByName,
getUrlParamsArray, getUrlParamsArray,
} from '~/lib/utils/common_utils'; } from '~/lib/utils/common_utils';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
import { visitUrl } from '../lib/utils/url_utility'; import { visitUrl } from '../lib/utils/url_utility';
import Flash from '../flash'; import Flash from '../flash';
import FilteredSearchContainer from './container'; import FilteredSearchContainer from './container';
...@@ -23,7 +27,11 @@ export default class FilteredSearchManager { ...@@ -23,7 +27,11 @@ export default class FilteredSearchManager {
isGroup = false, isGroup = false,
isGroupAncestor = true, isGroupAncestor = true,
isGroupDecendent = false, isGroupDecendent = false,
<<<<<<< HEAD
filteredSearchTokenKeys = IssuesFilteredSearchTokenKeys, filteredSearchTokenKeys = IssuesFilteredSearchTokenKeys,
=======
filteredSearchTokenKeys = IssuableFilteredSearchTokenKeys,
>>>>>>> upstream/master
stateFiltersSelector = '.issues-state-filters', stateFiltersSelector = '.issues-state-filters',
}) { }) {
this.isGroup = isGroup; this.isGroup = isGroup;
......
import FilteredSearchTokenKeys from './filtered_search_token_keys';
const tokenKeys = [{
key: 'author',
type: 'string',
param: 'username',
symbol: '@',
icon: 'pencil',
tag: '@author',
}, {
key: 'assignee',
type: 'string',
param: 'username',
symbol: '@',
icon: 'user',
tag: '@assignee',
}, {
key: 'milestone',
type: 'string',
param: 'title',
symbol: '%',
icon: 'clock-o',
tag: '%milestone',
}, {
key: 'label',
type: 'array',
param: 'name[]',
symbol: '~',
icon: 'tag',
tag: '~label',
}];
if (gon.current_user_id) {
// Appending tokenkeys only logged-in
tokenKeys.push({
key: 'my-reaction',
type: 'string',
param: 'emoji',
symbol: '',
icon: 'thumbs-up',
tag: 'emoji',
});
}
const alternativeTokenKeys = [{
key: 'label',
type: 'string',
param: 'name',
symbol: '~',
}];
const conditions = [{
url: 'assignee_id=0',
tokenKey: 'assignee',
value: 'none',
}, {
url: 'milestone_title=No+Milestone',
tokenKey: 'milestone',
value: 'none',
}, {
url: 'milestone_title=%23upcoming',
tokenKey: 'milestone',
value: 'upcoming',
}, {
url: 'milestone_title=%23started',
tokenKey: 'milestone',
value: 'started',
}, {
url: 'label_name[]=No+Label',
tokenKey: 'label',
value: 'none',
}];
const IssuableFilteredSearchTokenKeys =
new FilteredSearchTokenKeys(tokenKeys, alternativeTokenKeys, conditions);
export default IssuableFilteredSearchTokenKeys;
...@@ -9,7 +9,7 @@ Vue.use(Vuex); ...@@ -9,7 +9,7 @@ Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
modules: { modules: {
page: mrPageModule, page: mrPageModule,
notes: notesModule, notes: notesModule(),
diffs: diffsModule, diffs: diffsModule(),
}, },
}); });
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import * as actions from './actions'; import notesModule from './modules';
import * as getters from './getters';
import mutations from './mutations';
import module from './modules';
Vue.use(Vuex); Vue.use(Vuex);
export default () => export default () =>
new Vuex.Store({ new Vuex.Store(notesModule());
state: module.state,
actions,
getters,
mutations,
});
...@@ -2,7 +2,7 @@ import * as actions from '../actions'; ...@@ -2,7 +2,7 @@ import * as actions from '../actions';
import * as getters from '../getters'; import * as getters from '../getters';
import mutations from '../mutations'; import mutations from '../mutations';
export default { export default () => ({
state: { state: {
discussions: [], discussions: [],
targetNoteHash: null, targetNoteHash: null,
...@@ -24,4 +24,4 @@ export default { ...@@ -24,4 +24,4 @@ export default {
actions, actions,
getters, getters,
mutations, mutations,
}; });
import projectSelect from '~/project_select'; import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search'; import initFilteredSearch from '~/pages/search/init_filtered_search';
import { FILTERED_SEARCH } from '~/pages/constants'; import { FILTERED_SEARCH } from '~/pages/constants';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({ initFilteredSearch({
page: FILTERED_SEARCH.ISSUES, page: FILTERED_SEARCH.ISSUES,
isGroupDecendent: true, isGroupDecendent: true,
<<<<<<< HEAD
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeysEE, filteredSearchTokenKeys: IssuesFilteredSearchTokenKeysEE,
=======
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
>>>>>>> upstream/master
}); });
projectSelect(); projectSelect();
}); });
import projectSelect from '~/project_select'; import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search'; import initFilteredSearch from '~/pages/search/init_filtered_search';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
import { FILTERED_SEARCH } from '~/pages/constants'; import { FILTERED_SEARCH } from '~/pages/constants';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({ initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS, page: FILTERED_SEARCH.MERGE_REQUESTS,
isGroupDecendent: true, isGroupDecendent: true,
<<<<<<< HEAD
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys, filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
=======
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
>>>>>>> upstream/master
}); });
projectSelect(); projectSelect();
}); });
...@@ -4,6 +4,7 @@ import IssuableIndex from '~/issuable_index'; ...@@ -4,6 +4,7 @@ import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/shortcuts_navigation'; import ShortcutsNavigation from '~/shortcuts_navigation';
import UsersSelect from '~/users_select'; import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search'; import initFilteredSearch from '~/pages/search/init_filtered_search';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants'; import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_search_token_keys';
...@@ -11,7 +12,11 @@ import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_ ...@@ -11,7 +12,11 @@ import IssuesFilteredSearchTokenKeysEE from 'ee/filtered_search/issues_filtered_
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({ initFilteredSearch({
page: FILTERED_SEARCH.ISSUES, page: FILTERED_SEARCH.ISSUES,
<<<<<<< HEAD
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeysEE, filteredSearchTokenKeys: IssuesFilteredSearchTokenKeysEE,
=======
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
>>>>>>> upstream/master
}); });
new IssuableIndex(ISSUABLE_INDEX.ISSUE); new IssuableIndex(ISSUABLE_INDEX.ISSUE);
......
...@@ -2,14 +2,22 @@ import IssuableIndex from '~/issuable_index'; ...@@ -2,14 +2,22 @@ import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/shortcuts_navigation'; import ShortcutsNavigation from '~/shortcuts_navigation';
import UsersSelect from '~/users_select'; import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search'; import initFilteredSearch from '~/pages/search/init_filtered_search';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
import { FILTERED_SEARCH } from '~/pages/constants'; import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants'; import { ISSUABLE_INDEX } from '~/pages/projects/constants';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initFilteredSearch({ initFilteredSearch({
page: FILTERED_SEARCH.MERGE_REQUESTS, page: FILTERED_SEARCH.MERGE_REQUESTS,
<<<<<<< HEAD
filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys, filteredSearchTokenKeys: IssuesFilteredSearchTokenKeys,
=======
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
>>>>>>> upstream/master
}); });
new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new
......
...@@ -5,7 +5,11 @@ class Admin::RunnersController < Admin::ApplicationController ...@@ -5,7 +5,11 @@ class Admin::RunnersController < Admin::ApplicationController
def index def index
finder = Admin::RunnersFinder.new(params: params) finder = Admin::RunnersFinder.new(params: params)
@runners = finder.execute @runners = finder.execute
<<<<<<< HEAD
@active_runners_cnt = Ci::Runner.online.count @active_runners_cnt = Ci::Runner.online.count
=======
@active_runners_count = Ci::Runner.online.count
>>>>>>> upstream/master
@sort = finder.sort_key @sort = finder.sort_key
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -22,7 +22,7 @@ class Dashboard::MilestonesController < Dashboard::ApplicationController ...@@ -22,7 +22,7 @@ class Dashboard::MilestonesController < Dashboard::ApplicationController
private private
def group_milestones def group_milestones
groups = GroupsFinder.new(current_user, all_available: true).execute groups = GroupsFinder.new(current_user, all_available: false).execute
DashboardGroupMilestone.build_collection(groups) DashboardGroupMilestone.build_collection(groups)
end end
......
...@@ -29,8 +29,12 @@ module SortingHelper ...@@ -29,8 +29,12 @@ module SortingHelper
sort_value_popularity => sort_title_popularity, sort_value_popularity => sort_title_popularity,
sort_value_priority => sort_title_priority, sort_value_priority => sort_title_priority,
sort_value_upvotes => sort_title_upvotes, sort_value_upvotes => sort_title_upvotes,
<<<<<<< HEAD
sort_value_contacted_date => sort_title_contacted_date, sort_value_contacted_date => sort_title_contacted_date,
sort_value_weight => sort_title_weight sort_value_weight => sort_title_weight
=======
sort_value_contacted_date => sort_title_contacted_date
>>>>>>> upstream/master
} }
end end
...@@ -395,8 +399,11 @@ module SortingHelper ...@@ -395,8 +399,11 @@ module SortingHelper
def sort_value_contacted_date def sort_value_contacted_date
'contacted_asc' 'contacted_asc'
end end
<<<<<<< HEAD
def sort_value_weight def sort_value_weight
'weight' 'weight'
end end
=======
>>>>>>> upstream/master
end end
...@@ -32,6 +32,15 @@ module Ci ...@@ -32,6 +32,15 @@ module Ci
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }
scope :paused, -> { where(active: false) } scope :paused, -> { where(active: false) }
scope :online, -> { where('contacted_at > ?', contact_time_deadline) } scope :online, -> { where('contacted_at > ?', contact_time_deadline) }
<<<<<<< HEAD
=======
# The following query using negation is cheaper than using `contacted_at <= ?`
# because there are less runners online than have been created. The
# resulting query is quickly finding online ones and then uses the regular
# indexed search and rejects the ones that are in the previous set. If we
# did `contacted_at <= ?` the query would effectively have to do a seq
# scan.
>>>>>>> upstream/master
scope :offline, -> { where.not(id: online) } scope :offline, -> { where.not(id: online) }
scope :ordered, -> { order(id: :desc) } scope :ordered, -> { order(id: :desc) }
......
...@@ -73,19 +73,10 @@ module Clusters ...@@ -73,19 +73,10 @@ module Clusters
"clientSecret" => oauth_application.secret, "clientSecret" => oauth_application.secret,
"callbackUrl" => callback_url "callbackUrl" => callback_url
} }
},
"singleuser" => {
"extraEnv" => {
"GITLAB_PROJECT_ID" => project_id
}
} }
} }
end end
def project_id
cluster&.project&.id
end
def gitlab_url def gitlab_url
Gitlab.config.gitlab.url Gitlab.config.gitlab.url
end end
......
...@@ -13,7 +13,7 @@ class DashboardGroupMilestone < GlobalMilestone ...@@ -13,7 +13,7 @@ class DashboardGroupMilestone < GlobalMilestone
end end
def self.build_collection(groups) def self.build_collection(groups)
MilestonesFinder.new(group_ids: groups.pluck(:id)).execute.map { |m| new(m) } # rubocop: disable CodeReuse/Finder MilestonesFinder.new(group_ids: groups.select(:id)).execute.map { |m| new(m) } # rubocop: disable CodeReuse/Finder
end end
override :group_milestone? override :group_milestone?
......
...@@ -47,7 +47,11 @@ ...@@ -47,7 +47,11 @@
.bs-callout .bs-callout
%p %p
<<<<<<< HEAD
= _('Runners currently online: %{active_runners_cnt}') % { active_runners_cnt: @active_runners_cnt } = _('Runners currently online: %{active_runners_cnt}') % { active_runners_cnt: @active_runners_cnt }
=======
= _('Runners currently online: %{active_runners_count}') % { active_runners_count: @active_runners_count }
>>>>>>> upstream/master
.row-content-block.second-block .row-content-block.second-block
= form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do = form_tag admin_runners_path, id: 'runners-search', method: :get, class: 'filter-form js-filter-form' do
...@@ -68,13 +72,21 @@ ...@@ -68,13 +72,21 @@
#js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul{ data: { dropdown: true } } %ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { action: 'submit' } } %li.filter-dropdown-item{ data: { action: 'submit' } }
<<<<<<< HEAD
%button.btn.btn-link %button.btn.btn-link
=======
= button_tag class: %w[btn btn-link] do
>>>>>>> upstream/master
= icon('search') = icon('search')
%span %span
= _('Press Enter or click to search') = _('Press Enter or click to search')
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item %li.filter-dropdown-item
<<<<<<< HEAD
%button.btn.btn-link %button.btn.btn-link
=======
= button_tag class: %w[btn btn-link] do
>>>>>>> upstream/master
-# Encapsulate static class name `{{icon}}` inside #{} to bypass -# Encapsulate static class name `{{icon}}` inside #{} to bypass
-# haml lint's ClassAttributeWithStaticValue -# haml lint's ClassAttributeWithStaticValue
%i.fa{ class: "#{'{{icon}}'}" } %i.fa{ class: "#{'{{icon}}'}" }
...@@ -86,9 +98,15 @@ ...@@ -86,9 +98,15 @@
%ul{ data: { dropdown: true } } %ul{ data: { dropdown: true } }
- Ci::Runner::AVAILABLE_STATUSES.each do |status| - Ci::Runner::AVAILABLE_STATUSES.each do |status|
%li.filter-dropdown-item{ data: { value: status } } %li.filter-dropdown-item{ data: { value: status } }
<<<<<<< HEAD
%button.btn.btn-link %button.btn.btn-link
= status.titleize = status.titleize
%button.clear-search.hidden{ type: 'button' } %button.clear-search.hidden{ type: 'button' }
=======
= button_tag class: %w[btn btn-link] do
= status.titleize
= button_tag class: %w[clear-search hidden] do
>>>>>>> upstream/master
= icon('times') = icon('times')
.filter-dropdown-container .filter-dropdown-container
= render 'sort_dropdown' = render 'sort_dropdown'
......
---
title: Filter group milestones based on user membership.
merge_request: 21660
author:
type: fixed
...@@ -14,7 +14,11 @@ module API ...@@ -14,7 +14,11 @@ module API
use :pagination use :pagination
end end
get do get do
<<<<<<< HEAD
runners = filter_runners(current_user.ci_owned_runners, params[:scope], only: Ci::Runner::AVAILABLE_STATUSES) runners = filter_runners(current_user.ci_owned_runners, params[:scope], only: Ci::Runner::AVAILABLE_STATUSES)
=======
runners = filter_runners(current_user.ci_owned_runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
>>>>>>> upstream/master
present paginate(runners), with: Entities::Runner present paginate(runners), with: Entities::Runner
end end
...@@ -160,12 +164,19 @@ module API ...@@ -160,12 +164,19 @@ module API
end end
helpers do helpers do
<<<<<<< HEAD
def filter_runners(runners, scope, only: nil) def filter_runners(runners, scope, only: nil)
return runners unless scope.present? return runners unless scope.present?
available_scopes = only || ::Ci::Runner::AVAILABLE_SCOPES available_scopes = only || ::Ci::Runner::AVAILABLE_SCOPES
unless available_scopes.include?(scope) unless available_scopes.include?(scope)
=======
def filter_runners(runners, scope, allowed_scopes: ::Ci::Runner::AVAILABLE_SCOPES)
return runners unless scope.present?
unless allowed_scopes.include?(scope)
>>>>>>> upstream/master
render_api_error!('Scope contains invalid value', 400) render_api_error!('Scope contains invalid value', 400)
end end
......
...@@ -6480,7 +6480,11 @@ msgstr "" ...@@ -6480,7 +6480,11 @@ msgstr ""
msgid "Runners can be placed on separate users, servers, even on your local machine." msgid "Runners can be placed on separate users, servers, even on your local machine."
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Runners currently online: %{active_runners_cnt}" msgid "Runners currently online: %{active_runners_cnt}"
=======
msgid "Runners currently online: %{active_runners_count}"
>>>>>>> upstream/master
msgstr "" msgstr ""
msgid "Runners page" msgid "Runners page"
...@@ -8125,9 +8129,12 @@ msgstr "" ...@@ -8125,9 +8129,12 @@ msgstr ""
msgid "Version" msgid "Version"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "View epics list" msgid "View epics list"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "View file @ " msgid "View file @ "
msgstr "" msgstr ""
......
...@@ -3,9 +3,11 @@ require 'spec_helper' ...@@ -3,9 +3,11 @@ require 'spec_helper'
describe Dashboard::MilestonesController do describe Dashboard::MilestonesController do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:public_group) { create(:group, :public) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project_milestone) { create(:milestone, project: project) } let(:project_milestone) { create(:milestone, project: project) }
let(:group_milestone) { create(:milestone, group: group) } let(:group_milestone) { create(:milestone, group: group) }
let!(:public_milestone) { create(:milestone, group: public_group) }
let(:milestone) do let(:milestone) do
DashboardMilestone.build( DashboardMilestone.build(
[project], [project],
...@@ -43,13 +45,13 @@ describe Dashboard::MilestonesController do ...@@ -43,13 +45,13 @@ describe Dashboard::MilestonesController do
end end
describe "#index" do describe "#index" do
it 'should contain group and project milestones' do it 'returns group and project milestones to which the user belongs' do
get :index, format: :json get :index, format: :json
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2) expect(json_response.size).to eq(2)
expect(json_response.map { |i| i["first_milestone"]["id"] }).to include(group_milestone.id, project_milestone.id) expect(json_response.map { |i| i["first_milestone"]["id"] }).to match_array([group_milestone.id, project_milestone.id])
expect(json_response.map { |i| i["group_name"] }).to include(group.name) expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
end end
end end
end end
...@@ -17,8 +17,9 @@ describe 'Dashboard > Milestones' do ...@@ -17,8 +17,9 @@ describe 'Dashboard > Milestones' do
let(:project) { create(:project, namespace: user.namespace) } let(:project) { create(:project, namespace: user.namespace) }
let!(:milestone) { create(:milestone, project: project) } let!(:milestone) { create(:milestone, project: project) }
let!(:milestone2) { create(:milestone, group: group) } let!(:milestone2) { create(:milestone, group: group) }
before do before do
project.add_maintainer(user) group.add_developer(user)
sign_in(user) sign_in(user)
visit dashboard_milestones_path visit dashboard_milestones_path
end end
......
// TODO: https://gitlab.com/gitlab-org/gitlab-ce/issues/48034 import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants';
import App from '~/diffs/components/app.vue';
import createDiffsStore from '../create_diffs_store';
describe('diffs/components/app', () => {
const oldMrTabs = window.mrTabs;
const Component = Vue.extend(App);
let vm;
beforeEach(() => {
// setup globals (needed for component to mount :/)
window.mrTabs = jasmine.createSpyObj('mrTabs', ['resetViewContainer']);
// setup component
const store = createDiffsStore();
store.state.diffs.isLoading = false;
vm = mountComponentWithStore(Component, {
store,
props: {
endpoint: `${TEST_HOST}/diff/endpoint`,
projectPath: 'namespace/project',
currentUser: {},
},
});
});
afterEach(() => {
// reset globals
window.mrTabs = oldMrTabs;
// reset component
vm.$destroy();
});
it('shows comments message, with commit', done => {
vm.$store.state.diffs.commit = {};
vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText('Only comments from the following commit are shown below');
})
.then(done)
.catch(done.fail);
});
it('shows comments message, with old mergeRequestDiff', done => {
vm.$store.state.diffs.mergeRequestDiff = { latest: false };
vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText("Not all comments are displayed because you're viewing an old version of the diff.");
})
.then(done)
.catch(done.fail);
});
it('shows comments message, with startVersion', done => {
vm.$store.state.diffs.startVersion = 'test';
vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText("Not all comments are displayed because you're comparing two versions of the diff.");
})
.then(done)
.catch(done.fail);
});
});
...@@ -8,7 +8,7 @@ describe('ChangedFiles', () => { ...@@ -8,7 +8,7 @@ describe('ChangedFiles', () => {
const Component = Vue.extend(changedFiles); const Component = Vue.extend(changedFiles);
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { modules: {
diffs: diffsModule, diffs: diffsModule(),
}, },
}); });
......
...@@ -16,8 +16,8 @@ describe('diff_file_header', () => { ...@@ -16,8 +16,8 @@ describe('diff_file_header', () => {
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { modules: {
diffs: diffsModule, diffs: diffsModule(),
notes: notesModule, notes: notesModule(),
}, },
}); });
...@@ -450,13 +450,14 @@ describe('diff_file_header', () => { ...@@ -450,13 +450,14 @@ describe('diff_file_header', () => {
propsCopy.diffFile.deletedFile = true; propsCopy.diffFile.deletedFile = true;
const discussionGetter = () => [diffDiscussionMock]; const discussionGetter = () => [diffDiscussionMock];
notesModule.getters.discussions = discussionGetter; const notesModuleMock = notesModule();
notesModuleMock.getters.discussions = discussionGetter;
vm = mountComponentWithStore(Component, { vm = mountComponentWithStore(Component, {
props: propsCopy, props: propsCopy,
store: new Vuex.Store({ store: new Vuex.Store({
modules: { modules: {
diffs: diffsModule, diffs: diffsModule(),
notes: notesModule, notes: notesModuleMock,
}, },
}), }),
}); });
......
import Vue from 'vue';
import Vuex from 'vuex';
import diffsModule from '~/diffs/store/modules';
import notesModule from '~/notes/stores/modules';
Vue.use(Vuex);
export default function createDiffsStore() {
return new Vuex.Store({
modules: {
diffs: diffsModule(),
notes: notesModule(),
},
});
}
import Vue from 'vue'; import Vue from 'vue';
import eventHub from '~/filtered_search/event_hub'; import eventHub from '~/filtered_search/event_hub';
import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content.vue'; import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content.vue';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
const createComponent = (propsData) => { const createComponent = (propsData) => {
const Component = Vue.extend(RecentSearchesDropdownContent); const Component = Vue.extend(RecentSearchesDropdownContent);
...@@ -18,14 +22,22 @@ const trimMarkupWhitespace = text => text.replace(/(\n|\s)+/gm, ' ').trim(); ...@@ -18,14 +22,22 @@ const trimMarkupWhitespace = text => text.replace(/(\n|\s)+/gm, ' ').trim();
describe('RecentSearchesDropdownContent', () => { describe('RecentSearchesDropdownContent', () => {
const propsDataWithoutItems = { const propsDataWithoutItems = {
items: [], items: [],
<<<<<<< HEAD
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(), allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
=======
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
>>>>>>> upstream/master
}; };
const propsDataWithItems = { const propsDataWithItems = {
items: [ items: [
'foo', 'foo',
'author:@root label:~foo bar', 'author:@root label:~foo bar',
], ],
<<<<<<< HEAD
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(), allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
=======
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
>>>>>>> upstream/master
}; };
let vm; let vm;
......
import DropdownUtils from '~/filtered_search/dropdown_utils'; import DropdownUtils from '~/filtered_search/dropdown_utils';
import DropdownUser from '~/filtered_search/dropdown_user'; import DropdownUser from '~/filtered_search/dropdown_user';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer'; import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
describe('Dropdown User', () => { describe('Dropdown User', () => {
describe('getSearchInput', () => { describe('getSearchInput', () => {
...@@ -14,7 +18,11 @@ describe('Dropdown User', () => { ...@@ -14,7 +18,11 @@ describe('Dropdown User', () => {
spyOn(DropdownUtils, 'getSearchInput').and.callFake(() => {}); spyOn(DropdownUtils, 'getSearchInput').and.callFake(() => {});
dropdownUser = new DropdownUser({ dropdownUser = new DropdownUser({
<<<<<<< HEAD
tokenKeys: IssuesFilteredSearchTokenKeys, tokenKeys: IssuesFilteredSearchTokenKeys,
=======
tokenKeys: IssuableFilteredTokenKeys,
>>>>>>> upstream/master
}); });
}); });
......
import DropdownUtils from '~/filtered_search/dropdown_utils'; import DropdownUtils from '~/filtered_search/dropdown_utils';
import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager'; import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dropdown_manager';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
describe('Dropdown Utils', () => { describe('Dropdown Utils', () => {
...@@ -137,7 +141,11 @@ describe('Dropdown Utils', () => { ...@@ -137,7 +141,11 @@ describe('Dropdown Utils', () => {
`); `);
input = document.getElementById('test'); input = document.getElementById('test');
<<<<<<< HEAD
allowedKeys = IssuesFilteredSearchTokenKeys.getKeys(); allowedKeys = IssuesFilteredSearchTokenKeys.getKeys();
=======
allowedKeys = IssuableFilteredSearchTokenKeys.getKeys();
>>>>>>> upstream/master
}); });
function config() { function config() {
......
import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error'; import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error';
import RecentSearchesRoot from '~/filtered_search/recent_searches_root'; import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
>>>>>>> upstream/master
import '~/lib/utils/common_utils'; import '~/lib/utils/common_utils';
import DropdownUtils from '~/filtered_search/dropdown_utils'; import DropdownUtils from '~/filtered_search/dropdown_utils';
import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens'; import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens';
...@@ -86,7 +90,11 @@ describe('Filtered Search Manager', function () { ...@@ -86,7 +90,11 @@ describe('Filtered Search Manager', function () {
expect(RecentSearchesService.isAvailable).toHaveBeenCalled(); expect(RecentSearchesService.isAvailable).toHaveBeenCalled();
expect(RecentSearchesStoreSpy).toHaveBeenCalledWith({ expect(RecentSearchesStoreSpy).toHaveBeenCalledWith({
isLocalStorageAvailable, isLocalStorageAvailable,
<<<<<<< HEAD
allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(), allowedKeys: IssuesFilteredSearchTokenKeys.getKeys(),
=======
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
>>>>>>> upstream/master
}); });
}); });
}); });
......
<<<<<<< HEAD
import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys'; import IssuesFilteredSearchTokenKeys from '~/filtered_search/issues_filtered_search_token_keys';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer'; import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
describe('Filtered Search Tokenizer', () => { describe('Filtered Search Tokenizer', () => {
const allowedKeys = IssuesFilteredSearchTokenKeys.getKeys(); const allowedKeys = IssuesFilteredSearchTokenKeys.getKeys();
=======
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
describe('Filtered Search Tokenizer', () => {
const allowedKeys = IssuableFilteredSearchTokenKeys.getKeys();
>>>>>>> upstream/master
describe('processTokens', () => { describe('processTokens', () => {
it('returns for input containing only search value', () => { it('returns for input containing only search value', () => {
......
...@@ -108,17 +108,8 @@ describe Clusters::Applications::Jupyter do ...@@ -108,17 +108,8 @@ describe Clusters::Applications::Jupyter do
expect(values).to include('rbac') expect(values).to include('rbac')
expect(values).to include('proxy') expect(values).to include('proxy')
expect(values).to include('auth') expect(values).to include('auth')
expect(values).to include('singleuser')
expect(values).to match(/clientId: '?#{application.oauth_application.uid}/) expect(values).to match(/clientId: '?#{application.oauth_application.uid}/)
expect(values).to match(/callbackUrl: '?#{application.callback_url}/) expect(values).to match(/callbackUrl: '?#{application.callback_url}/)
end end
context 'when cluster belongs to a project' do
let(:project) { application.cluster.first_project }
it 'sets GitLab project id' do
expect(values).to match(/GITLAB_PROJECT_ID: '?#{project.id}/)
end
end
end end
end end
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