summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-02 06:09:04 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-02 06:09:04 +0000
commit9ecca14b2b3f05673a15399a2d1cc439206f3e0f (patch)
tree750343fab3388130b3485eee3cb4b539c1903e71
parent7f119dc26391dc953126b4fc902ade7b44a10ce2 (diff)
downloadgitlab-ce-9ecca14b2b3f05673a15399a2d1cc439206f3e0f.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/boards/components/board_card_inner.vue19
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue15
-rw-r--r--lib/api/internal/kubernetes.rb10
-rw-r--r--qa/qa/resource/project_imported_from_github.rb2
-rw-r--r--qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb2
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js88
7 files changed, 103 insertions, 35 deletions
diff --git a/app/assets/javascripts/boards/components/board_card_inner.vue b/app/assets/javascripts/boards/components/board_card_inner.vue
index 814ff16efec..af1d0bf0807 100644
--- a/app/assets/javascripts/boards/components/board_card_inner.vue
+++ b/app/assets/javascripts/boards/components/board_card_inner.vue
@@ -11,10 +11,12 @@ import { sortBy } from 'lodash';
import { mapActions, mapGetters, mapState } from 'vuex';
import boardCardInner from 'ee_else_ce/boards/mixins/board_card_inner';
import { isScopedLabel } from '~/lib/utils/common_utils';
+import { updateHistory } from '~/lib/utils/url_utility';
import { sprintf, __, n__ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { ListType } from '../constants';
+import eventHub from '../eventhub';
import BoardBlockedIcon from './board_blocked_icon.vue';
import IssueDueDate from './issue_due_date.vue';
import IssueTimeEstimate from './issue_time_estimate.vue';
@@ -174,10 +176,19 @@ export default {
)
);
},
- labelTarget(label) {
+ filterByLabel(label) {
+ if (!this.updateFilters) return;
+
const filterPath = window.location.search ? `${window.location.search}&` : '?';
- const value = encodeURIComponent(label.title);
- return `${filterPath}label_name[]=${value}`;
+ const filter = `label_name[]=${encodeURIComponent(label.title)}`;
+
+ if (!filterPath.includes(filter)) {
+ updateHistory({
+ url: `${filterPath}${filter}`,
+ });
+ this.performSearch();
+ eventHub.$emit('updateTokens');
+ }
},
showScopedLabel(label) {
return this.scopedLabelsAvailable && isScopedLabel(label);
@@ -232,7 +243,7 @@ export default {
:description="label.description"
size="sm"
:scoped="showScopedLabel(label)"
- :target="labelTarget(label)"
+ @click="filterByLabel(label)"
/>
</template>
</div>
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index aeb2cee590d..fa0c798ca9d 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -2,7 +2,8 @@
import { pickBy, isEmpty, mapValues } from 'lodash';
import { mapActions } from 'vuex';
import { getIdFromGraphQLId, isGid } from '~/graphql_shared/utils';
-import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import {
FILTERED_SEARCH_TERM,
@@ -10,6 +11,7 @@ import {
} from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import { AssigneeFilterType } from '~/boards/constants';
+import eventHub from '../eventhub';
export default {
i18n: {
@@ -33,6 +35,7 @@ export default {
data() {
return {
filterParams: this.initialFilterParams,
+ filteredSearchKey: 0,
};
},
computed: {
@@ -306,12 +309,21 @@ export default {
},
},
created() {
+ eventHub.$on('updateTokens', this.updateTokens);
if (!isEmpty(this.eeFilters)) {
this.filterParams = this.eeFilters;
}
},
+ beforeDestroy() {
+ eventHub.$off('updateTokens', this.updateTokens);
+ },
methods: {
...mapActions(['performSearch']),
+ updateTokens() {
+ const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
+ this.filterParams = convertObjectPropsToCamelCase(rawFilterParams, {});
+ this.filteredSearchKey += 1;
+ },
handleFilter(filters) {
this.filterParams = this.getFilterParams(filters);
@@ -399,6 +411,7 @@ export default {
<template>
<filtered-search
+ :key="filteredSearchKey"
class="gl-w-full"
namespace=""
:tokens="tokens"
diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb
index 50573dbd3ba..90e378cb3c8 100644
--- a/lib/api/internal/kubernetes.rb
+++ b/lib/api/internal/kubernetes.rb
@@ -5,12 +5,6 @@ module API
module Internal
class Kubernetes < ::API::Base
feature_category :kubernetes_management
- urgency :low, [
- '/api/:version/internal/kubernetes/agent_configuration',
- '/api/:version/internal/kubernetes/agent_info',
- '/api/:version/internal/kubernetes/project_info'
- ]
-
before do
check_feature_enabled
authenticate_gitlab_kas_request!
@@ -73,7 +67,7 @@ module API
detail 'Retrieves agent info for the given token'
end
route_setting :authentication, cluster_agent_token_allowed: true
- get '/agent_info' do
+ get '/agent_info', urgency: :low do
project = agent.project
status 200
@@ -87,7 +81,7 @@ module API
end
end
- namespace 'kubernetes/agent_configuration' do
+ namespace 'kubernetes/agent_configuration', urgency: :low do
desc 'POST agent configuration' do
detail 'Store configuration for an agent'
end
diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb
index 28a0f12b3e3..b9dbd2a6131 100644
--- a/qa/qa/resource/project_imported_from_github.rb
+++ b/qa/qa/resource/project_imported_from_github.rb
@@ -17,7 +17,7 @@ module QA
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(github_personal_access_token)
import_page.import!(github_repository_path, group.full_path, name)
- import_page.wait_for_success(github_repository_path)
+ import_page.wait_for_success(github_repository_path, wait: 240)
end
reload!
diff --git a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
index 79bba484bea..79509bdbe01 100644
--- a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
@@ -36,7 +36,7 @@ module QA
imported_project.reload! # import the project
expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
- .within(max_duration: 90, sleep_interval: 1)
+ .within(max_duration: 240, sleep_interval: 1)
aggregate_failures do
verify_status_data
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
index 3bf5a11b074..0477a9b8a1f 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
@@ -46,7 +46,7 @@ module QA
import_page.import!(github_repo, group.full_path, imported_project.name)
aggregate_failures do
- expect(import_page).to have_imported_project(github_repo)
+ expect(import_page).to have_imported_project(github_repo, wait: 240)
# validate button is present instead of navigating to avoid dealing with multiple tabs
# which makes the test more complicated
expect(import_page).to have_go_to_project_button(github_repo)
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 677978d31ca..c6de3ee69f3 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -2,12 +2,15 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vuex from 'vuex';
import { nextTick } from 'vue';
+import setWindowLocation from 'helpers/set_window_location_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardBlockedIcon from '~/boards/components/board_blocked_icon.vue';
import BoardCardInner from '~/boards/components/board_card_inner.vue';
import { issuableTypes } from '~/boards/constants';
+import eventHub from '~/boards/eventhub';
import defaultStore from '~/boards/stores';
+import { updateHistory } from '~/lib/utils/url_utility';
import { mockLabelList, mockIssue, mockIssueFullPath } from './mock_data';
jest.mock('~/lib/utils/url_utility');
@@ -34,7 +37,7 @@ describe('Board card component', () => {
let list;
let store;
- const findBoardBlockedIcon = () => wrapper.find(BoardBlockedIcon);
+ const findBoardBlockedIcon = () => wrapper.findComponent(BoardBlockedIcon);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findEpicCountablesTotalTooltip = () => wrapper.findComponent(GlTooltip);
const findEpicCountables = () => wrapper.findByTestId('epic-countables');
@@ -45,9 +48,14 @@ describe('Board card component', () => {
const findEpicProgressTooltip = () => wrapper.findByTestId('epic-progress-tooltip-content');
const findHiddenIssueIcon = () => wrapper.findByTestId('hidden-icon');
+ const performSearchMock = jest.fn();
+
const createStore = ({ isEpicBoard = false, isProjectBoard = false } = {}) => {
store = new Vuex.Store({
...defaultStore,
+ actions: {
+ performSearch: performSearchMock,
+ },
state: {
...defaultStore.state,
issuableType: issuableTypes.issue,
@@ -70,7 +78,6 @@ describe('Board card component', () => {
...props,
},
stubs: {
- GlLabel: true,
GlLoadingIcon: true,
},
directives: {
@@ -179,7 +186,7 @@ describe('Board card component', () => {
describe('confidential issue', () => {
beforeEach(() => {
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
confidential: true,
@@ -194,7 +201,7 @@ describe('Board card component', () => {
describe('hidden issue', () => {
beforeEach(() => {
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
hidden: true,
@@ -219,7 +226,7 @@ describe('Board card component', () => {
describe('with assignee', () => {
describe('with avatar', () => {
beforeEach(() => {
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
assignees: [user],
@@ -272,7 +279,7 @@ describe('Board card component', () => {
beforeEach(() => {
global.gon.default_avatar_url = 'default_avatar';
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
assignees: [
@@ -301,7 +308,7 @@ describe('Board card component', () => {
describe('multiple assignees', () => {
beforeEach(() => {
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
assignees: [
@@ -342,7 +349,7 @@ describe('Board card component', () => {
avatarUrl: 'test_image',
});
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
assignees,
@@ -368,7 +375,7 @@ describe('Board card component', () => {
avatarUrl: 'test_image',
})),
];
- wrapper.setProps({
+ createWrapper({
item: {
...wrapper.props('item'),
assignees,
@@ -384,31 +391,74 @@ describe('Board card component', () => {
describe('labels', () => {
beforeEach(() => {
- wrapper.setProps({ item: { ...issue, labels: [list.label, label1] } });
+ createWrapper({ item: { ...issue, labels: [list.label, label1] } });
});
it('does not render list label but renders all other labels', () => {
- expect(wrapper.findAll(GlLabel).length).toBe(1);
- const label = wrapper.find(GlLabel);
+ expect(wrapper.findAllComponents(GlLabel).length).toBe(1);
+ const label = wrapper.findComponent(GlLabel);
expect(label.props('title')).toEqual(label1.title);
expect(label.props('description')).toEqual(label1.description);
expect(label.props('backgroundColor')).toEqual(label1.color);
});
it('does not render label if label does not have an ID', async () => {
- wrapper.setProps({ item: { ...issue, labels: [label1, { title: 'closed' }] } });
+ createWrapper({ item: { ...issue, labels: [label1, { title: 'closed' }] } });
await nextTick();
- expect(wrapper.findAll(GlLabel).length).toBe(1);
+ expect(wrapper.findAllComponents(GlLabel).length).toBe(1);
expect(wrapper.text()).not.toContain('closed');
});
+ });
- describe('when label params arent set', () => {
- it('passes the right target to GlLabel', () => {
- expect(wrapper.findAll(GlLabel).at(0).props('target')).toEqual(
- '?label_name[]=testing%20123',
- );
+ describe('filterByLabel method', () => {
+ beforeEach(() => {
+ createWrapper({
+ item: {
+ ...issue,
+ labels: [label1],
+ },
+ updateFilters: true,
+ });
+ });
+
+ describe('when selected label is not in the filter', () => {
+ beforeEach(() => {
+ setWindowLocation('?');
+ wrapper.findComponent(GlLabel).vm.$emit('click', label1);
+ });
+
+ it('calls updateHistory', () => {
+ expect(updateHistory).toHaveBeenCalledTimes(1);
+ });
+
+ it('dispatches performSearch vuex action', () => {
+ expect(performSearchMock).toHaveBeenCalledTimes(1);
+ });
+
+ it('emits updateTokens event', () => {
+ expect(eventHub.$emit).toHaveBeenCalledTimes(1);
+ expect(eventHub.$emit).toHaveBeenCalledWith('updateTokens');
+ });
+ });
+
+ describe('when selected label is already in the filter', () => {
+ beforeEach(() => {
+ setWindowLocation('?label_name[]=testing%20123');
+ wrapper.findComponent(GlLabel).vm.$emit('click', label1);
+ });
+
+ it('does not call updateHistory', () => {
+ expect(updateHistory).not.toHaveBeenCalled();
+ });
+
+ it('does not dispatch performSearch vuex action', () => {
+ expect(performSearchMock).not.toHaveBeenCalled();
+ });
+
+ it('does not emit updateTokens event', () => {
+ expect(eventHub.$emit).not.toHaveBeenCalled();
});
});
});