Commit c0ba5ba5 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 101e7e04 ab695c19
/* eslint-disable class-methods-use-this */
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import { localTimeAgo } from './lib/utils/datetime_utility';
......@@ -55,7 +55,7 @@ export default class Activities {
const filter = $sender.attr('id').split('_')[0];
$('.event-filter .active').removeClass('active');
Cookies.set('event_filter', filter);
setCookie('event_filter', filter);
$sender.closest('li').toggleClass('active');
}
......
......@@ -2,10 +2,10 @@
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Cookies from 'js-cookie';
import { uniq } from 'lodash';
import { getCookie, setCookie, scrollToElement } from '~/lib/utils/common_utils';
import * as Emoji from '~/emoji';
import { scrollToElement } from '~/lib/utils/common_utils';
import { dispose, fixTitle } from '~/tooltips';
import createFlash from './flash';
import axios from './lib/utils/axios_utils';
......@@ -506,7 +506,7 @@ export class AwardsHandler {
addEmojiToFrequentlyUsedList(emoji) {
if (this.emoji.isEmojiNameValid(emoji)) {
this.frequentlyUsedEmojis = uniq(this.getFrequentlyUsedEmojis().concat(emoji));
Cookies.set('frequently_used_emojis', this.frequentlyUsedEmojis.join(','), { expires: 365 });
setCookie('frequently_used_emojis', this.frequentlyUsedEmojis.join(','));
}
}
......@@ -514,7 +514,7 @@ export class AwardsHandler {
return (
this.frequentlyUsedEmojis ||
(() => {
const frequentlyUsedEmojis = uniq((Cookies.get('frequently_used_emojis') || '').split(','));
const frequentlyUsedEmojis = uniq((getCookie('frequently_used_emojis') || '').split(','));
this.frequentlyUsedEmojis = frequentlyUsedEmojis.filter((inputName) =>
this.emoji.isEmojiNameValid(inputName),
);
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import { flatten } from 'lodash';
import Mousetrap from 'mousetrap';
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import findAndFollowLink from '~/lib/utils/navigation_utility';
import { refreshCurrentPage, visitUrl } from '~/lib/utils/url_utility';
import {
......@@ -161,10 +161,10 @@ export default class Shortcuts {
static onTogglePerfBar(e) {
e.preventDefault();
const performanceBarCookieName = 'perf_bar_enabled';
if (parseBoolean(Cookies.get(performanceBarCookieName))) {
Cookies.set(performanceBarCookieName, 'false', { expires: 365, path: '/' });
if (parseBoolean(getCookie(performanceBarCookieName))) {
setCookie(performanceBarCookieName, 'false', { path: '/' });
} else {
Cookies.set(performanceBarCookieName, 'true', { expires: 365, path: '/' });
setCookie(performanceBarCookieName, 'true', { path: '/' });
}
refreshCurrentPage();
}
......@@ -172,8 +172,8 @@ export default class Shortcuts {
static onToggleCanary(e) {
e.preventDefault();
const canaryCookieName = 'gitlab_canary';
const currentValue = parseBoolean(Cookies.get(canaryCookieName));
Cookies.set(canaryCookieName, (!currentValue).toString(), {
const currentValue = parseBoolean(getCookie(canaryCookieName));
setCookie(canaryCookieName, (!currentValue).toString(), {
expires: 365,
path: '/',
// next.gitlab.com uses a leading period. See https://gitlab.com/gitlab-org/gitlab/-/issues/350186
......
<script>
import { GlModal, GlSprintf, GlLink, GlButton } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { getCookie, removeCookie } from '~/lib/utils/common_utils';
import { __, s__ } from '~/locale';
import Tracking from '~/tracking';
......@@ -62,7 +62,7 @@ export default {
return this.commitCookiePath || this.projectMergeRequestsPath;
},
commitCookiePath() {
const cookieVal = Cookies.get(this.commitCookie);
const cookieVal = getCookie(this.commitCookie);
if (cookieVal !== 'true') return cookieVal;
return '';
......@@ -85,7 +85,7 @@ export default {
},
methods: {
disableModalFromRenderingAgain() {
Cookies.remove(this.commitCookie);
removeCookie(this.commitCookie);
},
},
};
......
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
const handleOnDismiss = ({ currentTarget }) => {
currentTarget.removeEventListener('click', handleOnDismiss);
......@@ -6,7 +6,7 @@ const handleOnDismiss = ({ currentTarget }) => {
dataset: { id, expireDate },
} = currentTarget;
Cookies.set(`hide_broadcast_message_${id}`, true, { expires: new Date(expireDate) });
setCookie(`hide_broadcast_message_${id}`, true, { expires: new Date(expireDate) });
const notification = document.querySelector(`.js-broadcast-notification-${id}`);
notification.parentNode.removeChild(notification);
......
......@@ -14,8 +14,8 @@ import {
GlModal,
GlSprintf,
} from '@gitlab/ui';
import Cookies from 'js-cookie';
import { mapActions, mapState } from 'vuex';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import Tracking from '~/tracking';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
......@@ -59,7 +59,7 @@ export default {
mixins: [glFeatureFlagsMixin(), trackingMixin],
data() {
return {
isTipDismissed: Cookies.get(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
validationErrorEventProperty: '',
};
},
......@@ -176,7 +176,7 @@ export default {
'setVariableProtected',
]),
dismissTip() {
Cookies.set(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 });
setCookie(AWS_TIP_DISMISSED_COOKIE_NAME, 'true', { expires: 90 });
this.isTipDismissed = true;
},
deleteVarAndClose() {
......
import { GlBreakpointInstance as bp, breakpoints } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Cookies from 'js-cookie';
import { debounce } from 'lodash';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { parseBoolean } from '~/lib/utils/common_utils';
export const SIDEBAR_COLLAPSED_CLASS = 'js-sidebar-collapsed';
......@@ -59,7 +58,7 @@ export default class ContextualSidebar {
if (!ContextualSidebar.isDesktopBreakpoint()) {
return;
}
Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 });
setCookie('sidebar_collapsed', value, { expires: 365 * 10 });
}
toggleSidebarNav(show) {
......@@ -111,7 +110,7 @@ export default class ContextualSidebar {
if (!ContextualSidebar.isDesktopBreakpoint()) {
this.toggleSidebarNav(false);
} else {
const collapse = parseBoolean(Cookies.get('sidebar_collapsed'));
const collapse = parseBoolean(getCookie('sidebar_collapsed'));
this.toggleCollapsedSidebar(collapse, true);
}
......
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { mapActions, mapState, mapGetters } from 'vuex';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import { toYmd } from '~/analytics/shared/utils';
import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import StageTable from '~/cycle_analytics/components/stage_table.vue';
......@@ -35,7 +35,7 @@ export default {
},
data() {
return {
isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE),
isOverviewDialogDismissed: getCookie(OVERVIEW_DIALOG_COOKIE),
};
},
computed: {
......@@ -134,7 +134,7 @@ export default {
},
dismissOverviewDialog() {
this.isOverviewDialogDismissed = true;
Cookies.set(OVERVIEW_DIALOG_COOKIE, '1', { expires: 365 });
setCookie(OVERVIEW_DIALOG_COOKIE, '1');
},
isUserAllowed(id) {
const { permissions } = this;
......
......@@ -13,7 +13,6 @@ deprecated_notes_spec.js is the spec for the legacy, jQuery notes application. I
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import Autosize from 'autosize';
import $ from 'jquery';
import Cookies from 'js-cookie';
import { escape, uniqueId } from 'lodash';
import Vue from 'vue';
import '~/lib/utils/jquery_at_who';
......@@ -28,6 +27,7 @@ import { defaultAutocompleteConfig } from './gfm_auto_complete';
import GLForm from './gl_form';
import axios from './lib/utils/axios_utils';
import {
getCookie,
isInViewport,
getPagePath,
scrollToElement,
......@@ -121,7 +121,7 @@ export default class Notes {
}
setViewType(view) {
this.view = Cookies.get('diff_view') || view;
this.view = getCookie('diff_view') || view;
}
addBinding() {
......@@ -473,7 +473,7 @@ export default class Notes {
}
isParallelView() {
return Cookies.get('diff_view') === 'parallel';
return getCookie('diff_view') === 'parallel';
}
/**
......
<script>
import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { parseBoolean, isLoggedIn } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean, isLoggedIn } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import Participants from '~/sidebar/components/participants/participants.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
......@@ -53,7 +53,7 @@ export default {
},
data() {
return {
isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)),
isResolvedCommentsPopoverHidden: parseBoolean(getCookie(this.$options.cookieKey)),
discussionWithOpenForm: '',
isLoggedIn: isLoggedIn(),
};
......@@ -96,7 +96,7 @@ export default {
methods: {
handleSidebarClick() {
this.isResolvedCommentsPopoverHidden = true;
Cookies.set(this.$options.cookieKey, 'true', { expires: 365 * 10 });
setCookie(this.$options.cookieKey, 'true', { expires: 365 * 10 });
this.updateActiveDiscussion();
},
updateActiveDiscussion(id) {
......
import Cookies from 'js-cookie';
import Vue from 'vue';
import { mapActions, mapState, mapGetters } from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean, removeCookie } from '~/lib/utils/common_utils';
import { getParameterValues } from '~/lib/utils/url_utility';
import eventHub from '../notes/event_hub';
import diffsApp from './components/app.vue';
......@@ -58,14 +58,14 @@ export default function initDiffsApp(store) {
// Check for cookie and save that setting for future use.
// Then delete the cookie as we are phasing it out and using the database as SSOT.
// NOTE: This can/should be removed later
if (Cookies.get(DIFF_WHITESPACE_COOKIE_NAME)) {
const hideWhitespace = Cookies.get(DIFF_WHITESPACE_COOKIE_NAME);
if (getCookie(DIFF_WHITESPACE_COOKIE_NAME)) {
const hideWhitespace = getCookie(DIFF_WHITESPACE_COOKIE_NAME);
this.setShowWhitespace({
url: this.endpointUpdateUser,
showWhitespace: hideWhitespace !== '1',
trackClick: false,
});
Cookies.remove(DIFF_WHITESPACE_COOKIE_NAME);
removeCookie(DIFF_WHITESPACE_COOKIE_NAME);
} else {
// This is only to set the the user preference in Vuex for use later
this.setShowWhitespace({
......@@ -77,7 +77,7 @@ export default function initDiffsApp(store) {
const vScrollingParam = getParameterValues('virtual_scrolling')[0];
if (vScrollingParam === 'false' || vScrollingParam === 'true') {
Cookies.set('diffs_virtual_scrolling', vScrollingParam);
setCookie('diffs_virtual_scrolling', vScrollingParam);
}
},
methods: {
......
import Cookies from 'js-cookie';
import Vue from 'vue';
import {
setCookie,
handleLocationHash,
historyPushState,
scrollToElement,
} from '~/lib/utils/common_utils';
import createFlash from '~/flash';
import { diffViewerModes } from '~/ide/constants';
import axios from '~/lib/utils/axios_utils';
import { handleLocationHash, historyPushState, scrollToElement } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import Poll from '~/lib/utils/poll';
import { mergeUrlParams, getLocationHash } from '~/lib/utils/url_utility';
......@@ -369,7 +374,7 @@ export const setRenderIt = ({ commit }, file) => commit(types.RENDER_FILE, file)
export const setInlineDiffViewType = ({ commit }) => {
commit(types.SET_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE);
Cookies.set(DIFF_VIEW_COOKIE_NAME, INLINE_DIFF_VIEW_TYPE);
setCookie(DIFF_VIEW_COOKIE_NAME, INLINE_DIFF_VIEW_TYPE);
const url = mergeUrlParams({ view: INLINE_DIFF_VIEW_TYPE }, window.location.href);
historyPushState(url);
......@@ -381,7 +386,7 @@ export const setInlineDiffViewType = ({ commit }) => {
export const setParallelDiffViewType = ({ commit }) => {
commit(types.SET_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE);
Cookies.set(DIFF_VIEW_COOKIE_NAME, PARALLEL_DIFF_VIEW_TYPE);
setCookie(DIFF_VIEW_COOKIE_NAME, PARALLEL_DIFF_VIEW_TYPE);
const url = mergeUrlParams({ view: PARALLEL_DIFF_VIEW_TYPE }, window.location.href);
historyPushState(url);
......
import Cookies from 'js-cookie';
import { getCookie } from '~/lib/utils/common_utils';
import { getParameterValues } from '~/lib/utils/url_utility';
import { __, n__ } from '~/locale';
import {
......@@ -175,7 +175,7 @@ export function suggestionCommitMessage(state, _, rootState) {
}
export const isVirtualScrollingEnabled = (state) => {
const vSrollerCookie = Cookies.get('diffs_virtual_scrolling');
const vSrollerCookie = getCookie('diffs_virtual_scrolling');
if (state.disableVirtualScroller) {
return false;
......
import Cookies from 'js-cookie';
import { getCookie } from '~/lib/utils/common_utils';
import { getParameterValues } from '~/lib/utils/url_utility';
import { INLINE_DIFF_VIEW_TYPE, DIFF_VIEW_COOKIE_NAME } from '../../constants';
const getViewTypeFromQueryString = () => getParameterValues('view')[0];
const viewTypeFromCookie = Cookies.get(DIFF_VIEW_COOKIE_NAME);
const viewTypeFromCookie = getCookie(DIFF_VIEW_COOKIE_NAME);
const defaultViewType = INLINE_DIFF_VIEW_TYPE;
export default () => ({
......
import Cookies from 'js-cookie';
import { chunk, memoize, uniq } from 'lodash';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import { initEmojiMap, getEmojiCategoryMap } from '~/emoji';
import {
EMOJIS_PER_ROW,
......@@ -13,7 +13,7 @@ export const generateCategoryHeight = (emojisLength) =>
emojisLength * EMOJI_ROW_HEIGHT + CATEGORY_ROW_HEIGHT;
export const getFrequentlyUsedEmojis = () => {
const savedEmojis = Cookies.get(FREQUENTLY_USED_COOKIE_KEY);
const savedEmojis = getCookie(FREQUENTLY_USED_COOKIE_KEY);
if (!savedEmojis) return null;
......@@ -30,13 +30,13 @@ export const getFrequentlyUsedEmojis = () => {
export const addToFrequentlyUsed = (emoji) => {
const frequentlyUsedEmojis = uniq(
(Cookies.get(FREQUENTLY_USED_COOKIE_KEY) || '')
(getCookie(FREQUENTLY_USED_COOKIE_KEY) || '')
.split(',')
.filter((e) => e)
.concat(emoji),
);
Cookies.set(FREQUENTLY_USED_COOKIE_KEY, frequentlyUsedEmojis.join(','), { expires: 365 });
setCookie(FREQUENTLY_USED_COOKIE_KEY, frequentlyUsedEmojis.join(','));
};
export const hasFrequentlyUsedEmojis = () => getFrequentlyUsedEmojis() !== null;
......
......@@ -4,7 +4,7 @@
* causes reflows, visit https://gist.github.com/paulirish/5d52fb081b3570c81e3a
*/
import Cookies from 'js-cookie';
import { getCookie } from '~/lib/utils/common_utils';
const LINE_NUMBER_CLASS = 'diff-line-num';
const UNFOLDABLE_LINE_CLASS = 'js-unfold';
......@@ -29,7 +29,7 @@ export default {
$diffFile.closest(DIFF_CONTAINER_SELECTOR).data('canCreateNote') === '';
}
this.isParallelView = Cookies.get('diff_view') === 'parallel';
this.isParallelView = getCookie('diff_view') === 'parallel';
if (this.userCanCreateNote) {
$diffFile
......
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
class Landing {
constructor(landingElement, dismissButton, cookieName) {
......@@ -27,11 +26,11 @@ class Landing {
dismissLanding() {
this.landingElement.classList.add('hidden');
Cookies.set(this.cookieName, 'true', { expires: 365 });
setCookie(this.cookieName, 'true');
}
isDismissed() {
return parseBoolean(Cookies.get(this.cookieName));
return parseBoolean(getCookie(this.cookieName));
}
}
......
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import { loadCSSFile } from '~/lib/utils/css_utils';
import UsersSelect from '~/users_select';
......@@ -62,7 +62,7 @@ export default class IssuableContext {
const supportedSizes = ['xs', 'sm', 'md'];
if (supportedSizes.includes(bpBreakpoint)) {
Cookies.set('collapsed_gutter', true);
setCookie('collapsed_gutter', true);
}
});
}
......
......@@ -705,7 +705,10 @@ export const scopedLabelKey = ({ title = '' }) => {
};
// Methods to set and get Cookie
export const setCookie = (name, value) => Cookies.set(name, value, { expires: 365 });
export const setCookie = (name, value, attributes) => {
const defaults = { expires: 365, secure: Boolean(window.gon?.secure) };
Cookies.set(name, value, { ...defaults, ...attributes });
};
export const getCookie = (name) => Cookies.get(name);
......
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
......@@ -51,7 +51,7 @@ export const setFailedRequest = ({ commit }, message) => {
export const setViewType = ({ commit }, viewType) => {
commit(types.SET_VIEW_TYPE, viewType);
Cookies.set('diff_view', viewType);
setCookie('diff_view', viewType);
};
export const setSubmitState = ({ commit }, isSubmitting) => {
......
import Cookies from 'js-cookie';
import { getCookie } from '~/lib/utils/common_utils';
import { VIEW_TYPES } from '../constants';
const diffViewType = Cookies.get('diff_view');
const diffViewType = getCookie('diff_view');
export default () => ({
isLoading: true,
......
/* eslint-disable no-new, class-methods-use-this */
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Cookies from 'js-cookie';
import Vue from 'vue';
import {
getCookie,
parseUrlPathname,
isMetaClick,
parseBoolean,
scrollToElement,
} from '~/lib/utils/common_utils';
import createEventHub from '~/helpers/event_hub_factory';
import BlobForkSuggestion from './blob/blob_fork_suggestion';
import Diff from './diff';
import createFlash from './flash';
import { initDiffStatsDropdown } from './init_diff_stats_dropdown';
import axios from './lib/utils/axios_utils';
import {
parseUrlPathname,
isMetaClick,
parseBoolean,
scrollToElement,
} from './lib/utils/common_utils';
import { localTimeAgo } from './lib/utils/datetime_utility';
import { isInVueNoteablePage } from './lib/utils/dom_utils';
import { __ } from './locale';
......@@ -514,7 +515,7 @@ export default class MergeRequestTabs {
// Expand the issuable sidebar unless the user explicitly collapsed it
expandView() {
if (parseBoolean(Cookies.get('collapsed_gutter'))) {
if (parseBoolean(getCookie('collapsed_gutter'))) {
return;
}
const $gutterBtn = $('.js-sidebar-toggle');
......
<script>
import { GlButton } from '@gitlab/ui';
import Cookies from 'js-cookie';
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import Translate from '../../../../../vue_shared/translate';
Vue.use(Translate);
......@@ -17,13 +17,13 @@ export default {
inject: ['docsUrl', 'illustrationUrl'],
data() {
return {
calloutDismissed: parseBoolean(Cookies.get(cookieKey)),
calloutDismissed: parseBoolean(getCookie(cookieKey)),
};
},
methods: {
dismissCallout() {
this.calloutDismissed = true;
Cookies.set(cookieKey, this.calloutDismissed, { expires: 365 });
setCookie(cookieKey, this.calloutDismissed);
},
},
};
......
/* eslint-disable func-names, no-return-assign */
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import initClonePanel from '~/clone_panel';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import createFlash from '~/flash';
......@@ -24,19 +24,19 @@ export default class Project {
}
$('.js-hide-no-ssh-message').on('click', function (e) {
Cookies.set('hide_no_ssh_message', 'false');
setCookie('hide_no_ssh_message', 'false');
$(this).parents('.js-no-ssh-key-message').remove();
return e.preventDefault();
});
$('.js-hide-no-password-message').on('click', function (e) {
Cookies.set('hide_no_password_message', 'false');
setCookie('hide_no_password_message', 'false');
$(this).parents('.js-no-password-message').remove();
return e.preventDefault();
});
$('.hide-auto-devops-implicitly-enabled-banner').on('click', function (e) {
const projectId = $(this).data('project-id');
const cookieKey = `hide_auto_devops_implicitly_enabled_banner_${projectId}`;
Cookies.set(cookieKey, 'false');
setCookie(cookieKey, 'false');
$(this).parents('.auto-devops-implicitly-enabled-banner').remove();
return e.preventDefault();
});
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import UserCallout from '~/user_callout';
import UserTabs from './user_tabs';
......@@ -10,7 +10,7 @@ function initUserProfile(action) {
// hide project limit message
$('.hide-project-limit-message').on('click', (e) => {
e.preventDefault();
Cookies.set('hide_project_limit_message', 'false');
setCookie('hide_project_limit_message', 'false');
$(this).parents('.project-limit-message').remove();
});
}
......
/* eslint-disable func-names, consistent-return, no-param-reassign */
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
import { hide, fixTitle } from '~/tooltips';
import createFlash from './flash';
import axios from './lib/utils/axios_utils';
......@@ -80,7 +80,7 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) {
hide($this);
if (!triggered) {
Cookies.set('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed'));
setCookie('collapsed_gutter', $('.right-sidebar').hasClass('right-sidebar-collapsed'));
}
};
......
<script>
import { GlBanner } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
export default {
components: {
......@@ -19,13 +18,13 @@ export default {
};
},
created() {
if (parseBoolean(Cookies.get('hide_serverless_survey'))) {
if (parseBoolean(getCookie('hide_serverless_survey'))) {
this.visible = false;
}
},
methods: {
handleClose() {
Cookies.set('hide_serverless_survey', 'true', { expires: 365 * 10 });
setCookie('hide_serverless_survey', 'true', { expires: 365 * 10 });
this.visible = false;
},
},
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
export default class UserCallout {
constructor(options = {}) {
......@@ -9,7 +9,7 @@ export default class UserCallout {
this.userCalloutBody = $(`.${className}`);
this.cookieName = this.userCalloutBody.data('uid');
this.isCalloutDismissed = Cookies.get(this.cookieName);
this.isCalloutDismissed = getCookie(this.cookieName);
this.init();
}
......@@ -30,7 +30,7 @@ export default class UserCallout {
cookieOptions.path = this.userCalloutBody.data('projectPath');
}
Cookies.set(this.cookieName, 'true', cookieOptions);
setCookie(this.cookieName, 'true', cookieOptions);
if ($currentTarget.hasClass('close') || $currentTarget.hasClass('js-close')) {
this.userCalloutBody.remove();
......
import Vue from 'vue';
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { setCookie, parseBoolean } from '~/lib/utils/common_utils';
import DismissibleAlert from '~/vue_shared/components/dismissible_alert.vue';
const getCookieExpirationPeriod = (expirationPeriod) => {
......@@ -33,7 +33,7 @@ const mountVueAlert = (el) => {
if (!dismissCookieName) {
return;
}
Cookies.set(dismissCookieName, true, {
setCookie(dismissCookieName, true, {
expires: getCookieExpirationPeriod(dismissCookieExpire),
});
},
......
<script>
import { GlIcon } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import { USER_COLLAPSED_GUTTER_COOKIE } from '../constants';
export default {
......@@ -10,7 +10,7 @@ export default {
GlIcon,
},
data() {
const userExpanded = !parseBoolean(Cookies.get(USER_COLLAPSED_GUTTER_COOKIE));
const userExpanded = !parseBoolean(getCookie(USER_COLLAPSED_GUTTER_COOKIE));
// We're deliberately keeping two different props for sidebar status;
// 1. userExpanded reflects value based on cookie `collapsed_gutter`.
......@@ -46,7 +46,7 @@ export default {
this.isExpanded = !this.isExpanded;
this.userExpanded = this.isExpanded;
Cookies.set(USER_COLLAPSED_GUTTER_COOKIE, !this.userExpanded);
setCookie(USER_COLLAPSED_GUTTER_COOKIE, !this.userExpanded);
this.updatePageContainerClass();
},
},
......
......@@ -259,10 +259,9 @@ $tabs-holder-z-index: 250;
> span {
display: inline-block;
max-width: 12.5em;
margin-bottom: -3px;
margin-bottom: -6px;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 14px;
overflow: hidden;
}
}
......
......@@ -1548,6 +1548,46 @@ To fix this you can do one of two things:
We use a concrete example to illustrate how to
diagnose a problem with the S3 setup.
#### Investigate a cleanup policy
If you're unsure why your cleanup policy did or didn't delete a tag, execute the policy line by line
by running the below script from the [Rails console](../../administration/operations/rails_console.md).
This can help diagnose problems with the policy.
```ruby
repo = ContainerRepository.find(<project_id>)
policy = repo.project.container_expiration_policy
tags = repo.tags
tags.map(&:name)
tags.reject!(&:latest?)
tags.map(&:name)
regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex}\\z")
regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex_keep}\\z")
tags.select! { |tag| regex_delete.match?(tag.name) && !regex_retain.match?(tag.name) }
tags.map(&:name)
now = DateTime.current
tags.sort_by! { |tag| tag.created_at || now }.reverse! # Lengthy operation
tags = tags.drop(policy.keep_n)
tags.map(&:name)
older_than_timestamp = ChronicDuration.parse(policy.older_than).seconds.ago
tags.select! { |tag| tag.created_at && tag.created_at < older_than_timestamp }
tags.map(&:name)
```
- The script builds the list of tags to delete (`tags`).
- `tags.map(&:name)` prints a list of tags to remove. This may be a lengthy operation.
- After each filter, check the list of `tags` to see if it contains the intended tags to destroy.
#### Unexpected 403 error during push
A user attempted to enable an S3-backed Registry. The `docker login` step went
......
......@@ -332,10 +332,6 @@ try to preserve worktrees and try to re-use them by default.
This has limitations when using the [Docker Machine executor](https://docs.gitlab.com/runner/executors/docker_machine.html).
It does not work for [the `kubernetes` executor](https://docs.gitlab.com/runner/executors/kubernetes.html),
but a [feature proposal](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3847) exists.
The `kubernetes` executor always clones into an temporary directory.
A Git strategy of `none` also re-uses the local working copy, but skips all Git
operations normally done by GitLab. GitLab Runner pre-clone scripts are also skipped,
if present. This strategy could mean you need to add `fetch` and `checkout` commands
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { setCookie } from '~/lib/utils/common_utils';
import createDefaultClient from '~/lib/graphql';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import BurnCharts from './components/burn_charts.vue';
......@@ -17,7 +17,7 @@ export default () => {
const hint = $('.burndown-hint');
hint.on('click', '.dismiss-icon', () => {
hint.hide();
Cookies.set('hide_burndown_message', 'true');
setCookie('hide_burndown_message', 'true');
});
// generate burndown chart (if data available)
......
<script>
import { GlTabs, GlTab } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { getCookie } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { COMPLIANCE_TAB_COOKIE_KEY } from '../constants';
......@@ -60,7 +60,7 @@ export default {
},
methods: {
showTabs() {
return Cookies.get(COMPLIANCE_TAB_COOKIE_KEY) === 'true';
return getCookie(COMPLIANCE_TAB_COOKIE_KEY) === 'true';
},
toggleDrawer(mergeRequest) {
if (this.showDrawer && mergeRequest.id === this.drawerMergeRequest.id) {
......
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
export default class EETrialBanner {
constructor($trialBanner) {
......@@ -55,23 +54,23 @@ export default class EETrialBanner {
const today = new Date();
// Check if Cookie is defined
if (!Cookies.get(this.COOKIE_KEY)) {
if (!getCookie(this.COOKIE_KEY)) {
// Cookie was not defined, let's define with default value
// Check if License is yet to expire
if (today < this.licenseExpiresOn) {
// License has not expired yet, we show initial banner of 7 days
// with cookie set to validity same as license expiry
Cookies.set(this.COOKIE_KEY, 'true', { expires: this.licenseExpiresOn });
setCookie(this.COOKIE_KEY, 'true', { expires: this.licenseExpiresOn });
} else {
// License is already expired so we show final Banner with cookie set to 20 years validity.
Cookies.set(this.COOKIE_KEY, 'true', { expires: 7300 });
setCookie(this.COOKIE_KEY, 'true', { expires: 7300 });
}
this.toggleBanner(true);
} else {
// Cookie was defined, let's read value and show/hide banner
this.toggleBanner(parseBoolean(Cookies.get(this.COOKIE_KEY)));
this.toggleBanner(parseBoolean(getCookie(this.COOKIE_KEY)));
}
}
......@@ -103,8 +102,8 @@ export default class EETrialBanner {
this.toggleBanner(false);
this.toggleMainNavbarMargin(false);
this.toggleSecondaryNavbarMargin(false);
if (Cookies.get(this.COOKIE_KEY)) {
Cookies.set(this.COOKIE_KEY, 'false');
if (getCookie(this.COOKIE_KEY)) {
setCookie(this.COOKIE_KEY, 'false');
}
}
}
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import Cookies from 'js-cookie';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { mapActions } from 'vuex';
import { setCookie, convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
import { parseIssuableData } from '~/issues/show/utils/parse_data';
import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
import { defaultClient } from '~/sidebar/graphql';
import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_vue/store';
......@@ -35,7 +35,7 @@ export default () => {
// Collapse the sidebar on mobile screens by default
const bpBreakpoint = bp.getBreakpointSize();
if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm' || bpBreakpoint === 'md') {
Cookies.set('collapsed_gutter', true);
setCookie('collapsed_gutter', true);
}
return new Vue({
......
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
export default class SidebarContext {
constructor() {
......@@ -35,7 +35,7 @@ export default class SidebarContext {
// collapsed_gutter cookie hides the sidebar
const bpBreakpoint = bp.getBreakpointSize();
if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm' || bpBreakpoint === 'md') {
Cookies.set('collapsed_gutter', true);
setCookie('collapsed_gutter', true);
}
});
}
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import { sanitize } from '~/lib/dompurify';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import { dateInWords, parsePikadayDate } from '~/lib/utils/datetime_utility';
import { __, s__, sprintf } from '~/locale';
......@@ -33,9 +32,9 @@ const toggleContainerClass = (className) => {
}
};
const getCollapsedGutter = () => parseBoolean(Cookies.get('collapsed_gutter'));
const getCollapsedGutter = () => parseBoolean(getCookie('collapsed_gutter'));
const setCollapsedGutter = (value) => Cookies.set('collapsed_gutter', value);
const setCollapsedGutter = (value) => setCookie('collapsed_gutter', value);
const getDateValidity = (startDateTime, dueDateTime) => {
// If both dates are defined
......
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
const handleOnDismiss = ({ currentTarget }) => {
const {
dataset: { id, level },
} = currentTarget;
Cookies.set(`hide_storage_limit_alert_${id}_${level}`, true, { expires: 30 });
setCookie(`hide_storage_limit_alert_${id}_${level}`, true, { expires: 30 });
const notification = document.querySelector('.js-namespace-storage-alert');
notification.parentNode.removeChild(notification);
......
import Cookies from 'js-cookie';
import { setCookie } from '~/lib/utils/common_utils';
const handleOnDismiss = ({ currentTarget }) => {
const {
dataset: { cookieId },
} = currentTarget;
Cookies.set(cookieId, true, { expires: 30 });
setCookie(cookieId, true, { expires: 30 });
};
export default () => {
......
<script>
import Cookies from 'js-cookie';
import { difference } from 'lodash';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import { translateScannerNames } from '~/security_configuration/utils';
import SecurityTrainingPromo from 'ee/security_dashboard/components/shared/security_training_promo.vue';
import ReportNotConfiguredProject from '../shared/empty_states/report_not_configured_project.vue';
......@@ -31,7 +31,7 @@ export default {
scannerAlertDismissed: false,
securityScanners: {},
shouldShowAutoFixUserCallout:
this.glFeatures.securityAutoFix && !Cookies.get(this.$options.autoFixUserCalloutCookieName),
this.glFeatures.securityAutoFix && !getCookie(this.$options.autoFixUserCalloutCookieName),
};
},
apollo: {
......@@ -73,7 +73,7 @@ export default {
},
methods: {
closeAutoFixUserCallout() {
Cookies.set(this.$options.autoFixUserCalloutCookieName, 'true');
setCookie(this.$options.autoFixUserCalloutCookieName, 'true');
this.shouldShowAutoFixUserCallout = false;
},
setScannerAlertDismissed(value) {
......
<script>
import Cookies from 'js-cookie';
import { PortalTarget } from 'portal-vue';
import { GlLink, GlSprintf } from '@gitlab/ui';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
import { s__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
......@@ -58,7 +58,7 @@ export default {
const shouldShowAutoFixUserCallout =
this.dashboardType === DASHBOARD_TYPES.PROJECT &&
this.glFeatures.securityAutoFix &&
!Cookies.get(this.$options.autoFixUserCalloutCookieName);
!getCookie(this.$options.autoFixUserCalloutCookieName);
return {
filters: null,
......@@ -103,7 +103,7 @@ export default {
this.filters = filters;
},
handleAutoFixUserCalloutClose() {
Cookies.set(this.$options.autoFixUserCalloutCookieName, 'true');
setCookie(this.$options.autoFixUserCalloutCookieName, 'true');
this.shouldShowAutoFixUserCallout = false;
},
},
......
......@@ -32,7 +32,7 @@ export default {
directives: {
autofocusonshow,
},
inject: ['user', 'submitPath'],
inject: ['user', 'submitPath', 'onboarding'],
data() {
return this.user;
},
......@@ -68,6 +68,7 @@ export default {
<template>
<gl-form :action="submitPath" method="post" @submit="onSubmit">
<input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
<input :value="onboarding" type="hidden" name="onboarding" />
<div class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-mt-5">
<gl-form-group
:label="$options.i18n.firstNameLabel"
......
......@@ -14,6 +14,7 @@ export const initTrialCreateLeadForm = () => {
country,
state,
phoneNumber,
onboarding,
} = el.dataset;
return new Vue({
......@@ -29,6 +30,7 @@ export const initTrialCreateLeadForm = () => {
state: state || '',
phoneNumber,
},
onboarding,
submitPath,
},
render(createElement) {
......
<script>
import { GlAlert } from '@gitlab/ui';
import Cookies from 'js-cookie';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import { __, sprintf } from '~/locale';
export const COOKIE_NAME = 'dismissed_resolution_alerts';
......@@ -35,7 +35,7 @@ export default {
methods: {
alreadyDismissedVulnerabilities() {
try {
return JSON.parse(Cookies.get(COOKIE_NAME));
return JSON.parse(getCookie(COOKIE_NAME));
} catch (e) {
return [];
}
......@@ -45,7 +45,7 @@ export default {
},
dismiss() {
const dismissed = this.alreadyDismissedVulnerabilities().concat(this.vulnerabilityId);
Cookies.set(COOKIE_NAME, JSON.stringify(dismissed), { expires: 90 });
setCookie(COOKIE_NAME, JSON.stringify(dismissed), { expires: 90 });
this.isVisible = false;
},
},
......
# frozen_string_literal: true
module Registrations::ApplyTrial
extend ActiveSupport::Concern
included do
private
def apply_trial
apply_trial_params = {
uid: current_user.id,
trial_user: params.permit(:glm_source, :glm_content).merge({
namespace_id: @group.id,
gitlab_com_trial: true,
sync_to_gl: true
})
}
result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params)
flash.now[:alert] = result&.dig(:errors) unless result&.dig(:success)
result&.dig(:success)
end
end
end
......@@ -25,7 +25,7 @@ module Registrations::CreateProject
end
def learn_gitlab_project_name
helpers.in_trial_onboarding_flow? ? s_('Learn GitLab - Ultimate trial') : s_('Learn GitLab')
helpers.in_trial_onboarding_flow? ? LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL : LearnGitlab::Project::PROJECT_NAME
end
def project_params
......
......@@ -3,6 +3,7 @@
module Registrations
class GroupsController < ApplicationController
include Registrations::CreateGroup
include Registrations::ApplyTrial
include ::Gitlab::Utils::StrongMemoize
include OneTrustCSP
......@@ -95,21 +96,5 @@ module Registrations
result&.dig(:success)
end
def apply_trial
apply_trial_params = {
uid: current_user.id,
trial_user: params.permit(:glm_source, :glm_content).merge({
namespace_id: @group.id,
gitlab_com_trial: true,
sync_to_gl: true
})
}
result = GitlabSubscriptions::ApplyTrialService.new.execute(apply_trial_params)
flash[:alert] = result&.dig(:errors) unless result&.dig(:success)
result&.dig(:success)
end
end
end
......@@ -4,6 +4,7 @@ module Registrations
class GroupsProjectsController < ApplicationController
include Registrations::CreateProject
include Registrations::CreateGroup
include Registrations::ApplyTrial
include OneTrustCSP
skip_before_action :require_verification, only: :new
......@@ -35,30 +36,30 @@ module Registrations
if @group.persisted?
if @group.previously_new_record?
combined_registration_experiment.track(:create_group, namespace: @group)
helpers.require_verification_experiment.record_conversion(@group)
unless apply_trial_when_in_trial_flow
@project = Project.new(project_params) # #new requires a Project
return render :new
end
end
@project = ::Projects::CreateService.new(current_user, project_params).execute
if @project.saved?
combined_registration_experiment.track(:create_project, namespace: @project.namespace)
@learn_gitlab_project = create_learn_gitlab_project
create_learn_gitlab_project
store_location
redirect_path = continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: @project.id)
if helpers.registration_verification_enabled?
redirect_to new_users_sign_up_verification_path(url_params.merge(combined: true))
elsif helpers.in_trial_onboarding_flow?
redirect_to trial_getting_started_users_sign_up_welcome_path(url_params)
store_location_for(:user, redirect_path)
redirect_to new_users_sign_up_verification_path(project_id: @project.id, offer_trial: offer_trial?)
elsif offer_trial?
store_location_for(:user, redirect_path)
redirect_to new_trial_path
else
success_url = continuous_onboarding_getting_started_users_sign_up_welcome_path(url_params)
if current_user.setup_for_company
success_url = new_trial_path
end
helpers.require_verification_experiment.record_conversion(@group)
redirect_to success_url
redirect_to redirect_path
end
else
render :new
......@@ -71,7 +72,7 @@ module Registrations
def import
@group = Groups::CreateService.new(current_user, modified_group_params).execute
if @group.persisted?
if @group.persisted? && apply_trial_when_in_trial_flow
combined_registration_experiment.track(:create_group, namespace: @group)
helpers.require_verification_experiment.record_conversion(@group)
......@@ -103,19 +104,12 @@ module Registrations
modifed_group_params
end
def store_location
if current_user.setup_for_company && !helpers.in_trial_onboarding_flow?
success_url = continuous_onboarding_getting_started_users_sign_up_welcome_path(url_params)
store_location_for(:user, success_url)
end
def offer_trial?
current_user.setup_for_company && !helpers.in_trial_onboarding_flow? && !params[:skip_trial].present?
end
def url_params
if helpers.in_trial_onboarding_flow?
{ learn_gitlab_project_id: @learn_gitlab_project.id }
else
{ project_id: @project.id }
end
def apply_trial_when_in_trial_flow
!helpers.in_trial_onboarding_flow? || apply_trial
end
end
end
......@@ -11,6 +11,7 @@ class TrialRegistrationsController < RegistrationsController
before_action :check_if_gl_com_or_dev
before_action :set_redirect_url, only: [:new]
before_action :add_onboarding_parameter_to_redirect_url, only: :create
before_action only: [:new] do
push_frontend_feature_flag(:gitlab_gtm_datalayer, type: :ops)
end
......@@ -42,6 +43,16 @@ class TrialRegistrationsController < RegistrationsController
end
end
def add_onboarding_parameter_to_redirect_url
stored_url = stored_location_for(:user)
return unless stored_url.present?
redirect_uri = URI.parse(stored_url)
new_query = URI.decode_www_form(String(redirect_uri.query)) << ['onboarding', true]
redirect_uri.query = URI.encode_www_form(new_query)
store_location_for(:user, redirect_uri.to_s)
end
def sign_up_params
if params[:user]
params.require(:user).permit(:first_name, :last_name, :username, :email, :password, :skip_confirmation, :email_opted_in)
......
......@@ -36,8 +36,8 @@ class TrialsController < ApplicationController
render(:new) && return unless @result[:success]
if EE::TrialHelper::TRIAL_ONBOARDING_SOURCE_URLS.include?(params[:glm_source])
redirect_to(new_users_sign_up_group_path(url_params.merge(trial_onboarding_flow: true)))
if params[:onboarding] == 'true'
redirect_to(new_users_sign_up_groups_project_path(url_params.merge(trial_onboarding_flow: true)))
elsif @namespace = helpers.only_trialable_group_namespace
params[:namespace_id] = @namespace.id
apply_trial_and_redirect
......@@ -73,7 +73,11 @@ class TrialsController < ApplicationController
end
def skip
redirect_to stored_location_or_provided_path(dashboard_projects_path)
if params[:onboarding] == 'true'
redirect_to new_users_sign_up_groups_project_path(skip_trial: true)
else
redirect_to stored_location_or_provided_path(dashboard_projects_path)
end
end
protected
......
......@@ -21,7 +21,7 @@ module EE
def registration_verification_data
url = if params[:learn_gitlab_project_id].present?
trial_getting_started_users_sign_up_welcome_path(params.slice(:learn_gitlab_project_id).permit!)
elsif params[:combined].present? && current_user.setup_for_company
elsif params[:offer_trial] == 'true'
new_trial_path
elsif params[:project_id].present?
continuous_onboarding_getting_started_users_sign_up_welcome_path(params.slice(:project_id).permit!)
......
......@@ -20,7 +20,8 @@ module EE
submit_path: create_lead_trials_path(glm_params),
first_name: current_user.first_name,
last_name: current_user.last_name,
company_name: current_user.organization
company_name: current_user.organization,
onboarding: params[:onboarding]
}.merge(params.slice(:first_name, :last_name, :company_name, :company_size, :phone_number, :country, :state).to_unsafe_h.symbolize_keys)
end
......
- @html_class = "subscriptions-layout-html"
- @hide_flash = true
- page_title _('Your GitLab group')
- form_params = { trial_onboarding_flow: params[:trial_onboarding_flow], glm_source: params[:glm_source], glm_content: params[:glm_content] }
- form_params = { trial_onboarding_flow: params[:trial_onboarding_flow], glm_source: params[:glm_source], glm_content: params[:glm_content], skip_trial: params[:skip_trial] }
- content_for :page_specific_javascripts do
= render "layouts/one_trust"
- if in_trial_onboarding_flow?
.row
.gl-display-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-mt-3
= render 'registrations/trial_is_activated_banner'
.row.gl-flex-grow-1
.gl-display-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5
.new-project.gl-display-flex.gl-flex-direction-column.gl-align-items-center.gl-xs-w-full
- unless in_trial_onboarding_flow?
#progress-bar
%h2.gl-text-center= _('Create or import your first project')
%p.gl-text-center= _('Projects help you organize your work. They contain your file repository, issues, merge requests, and so much more.')
......
......@@ -4,6 +4,6 @@
.gl-font-sm.gl-text-gray-700
= s_("Trials|You can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'")
- else
= link_to s_('Trials|Skip Trial'), skip_trials_path, class: 'block py-2 js-skip-trial'
= link_to s_('Trials|Skip Trial'), skip_trials_path(params.permit(:onboarding)), class: 'block py-2 js-skip-trial'
.gl-font-sm.gl-text-gray-700
= s_("Trials|You won't get a free trial right now but you can always resume this process by selecting your avatar and choosing 'Start an Ultimate trial'")
......@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Registrations::GroupsProjectsController, :experiment do
include AfterNextHelpers
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
......@@ -141,6 +143,12 @@ RSpec.describe Registrations::GroupsProjectsController, :experiment do
it { is_expected.to render_template(:new) }
end
context 'with signup onboarding not enabled' do
let(:dev_env_or_com) { false }
it { is_expected.to have_gitlab_http_status(:not_found) }
end
context "when group can be created but the project can't" do
let(:project_params) { { name: '', path: '', visibility_level: Gitlab::VisibilityLevel::PRIVATE } }
......@@ -187,55 +195,130 @@ RSpec.describe Registrations::GroupsProjectsController, :experiment do
post_create
end
end
context 'it redirects' do
let_it_be(:project) { create(:project) }
context 'it redirects' do
let_it_be(:project) { create(:project) }
let(:success_path) { continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: project.id) }
before do
allow_next_instance_of(::Projects::CreateService) do |service|
allow(service).to receive(:execute).and_return(project)
end
end
it { is_expected.to redirect_to(success_path) }
context 'when the `registration_verification` experiment is enabled' do
before do
allow_next_instance_of(::Projects::CreateService) do |service|
allow(service).to receive(:execute).and_return(project)
end
stub_experiments(registration_verification: :candidate)
end
it { is_expected.to redirect_to(continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: project.id)) }
it 'is expected to store the success path and redirect to the verification page' do
expect(subject).to redirect_to(new_users_sign_up_verification_path(project_id: project.id))
expect(controller.stored_location_for(:user)).to eq(success_path)
end
end
context 'when setup_for_company is true' do
let_it_be(:user) { create(:user, setup_for_company: true) }
it 'is expected to store the success path and redirect to the new trial page' do
expect(subject).to redirect_to(new_trial_path)
expect(controller.stored_location_for(:user)).to eq(success_path)
end
context 'when the skip_trial param is set' do
let(:extra_params) { { skip_trial: true } }
it { is_expected.to redirect_to(success_path) }
end
context 'when the trial_onboarding_flow param is set' do
let(:extra_params) { { trial_onboarding_flow: true } }
before do
allow_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service|
allow(service).to receive(:execute).and_return({ success: true })
end
end
it { is_expected.to redirect_to(success_path) }
end
end
end
end
shared_context 'groups_projects projects concern' do
let_it_be(:project) { create(:project) }
let_it_be(:namespace) { create(:group) }
context 'when in the trial onboarding flow' do
let(:success) { true }
let(:extra_params) do
{ trial_onboarding_flow: true, glm_source: 'about.gitlab.com', glm_content: 'content' }
end
let(:group_params) { { name: 'Group name', path: 'group-path', visibility_level: "#{Gitlab::VisibilityLevel::PRIVATE}", setup_for_company: setup_for_company } }
let(:extra_params) { { group: group_params } }
let(:params) { { name: 'New project', path: 'project-path', visibility_level: Gitlab::VisibilityLevel::PRIVATE } }
let(:create_service) { double(:create_service) }
let(:apply_trial_params) do
{
uid: user.id,
trial_user: ActionController::Parameters.new(
{
glm_source: 'about.gitlab.com',
glm_content: 'content',
namespace_id: group.id,
gitlab_com_trial: true,
sync_to_gl: true
}
).permit!
}
end
before do
allow(controller).to receive(:record_experiment_user).and_call_original
allow(controller).to receive(:record_experiment_conversion_event).and_call_original
before do
allow_next_instance_of(::Groups::CreateService) do |service|
allow(service).to receive(:execute).and_return(group)
end
expect_next_instance_of(GitlabSubscriptions::ApplyTrialService) do |service|
expect(service).to receive(:execute).with(apply_trial_params).and_return({ success: success })
end
end
allow(Groups::CreateService).to receive(:new).and_call_original
allow(Groups::CreateService).to receive(:new).with(user, ActionController::Parameters.new(group_params.merge(create_event: true)).permit!).and_return(create_service)
allow(create_service).to receive(:execute).and_return(namespace)
it 'applies a trial' do
post_create
end
context 'when failing to apply trial' do
let(:success) { false }
it { is_expected.to render_template(:new) }
end
end
end
it_behaves_like "Registrations::ProjectsController POST #create" do
include_context 'groups_projects projects concern'
end
context 'learn gitlab project' do
using RSpec::Parameterized::TableSyntax
context 'when the user is setup_for_company: true it redirects to the new_trial_path' do
let(:setup_for_company) { true }
where(:trial, :project_name, :template) do
false | 'Learn GitLab' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE
true | 'Learn GitLab - Ultimate trial' | described_class::LEARN_GITLAB_ULTIMATE_TEMPLATE
end
with_them do
let(:path) { Rails.root.join('vendor', 'project_templates', template) }
let(:expected_arguments) { { namespace_id: group.id, file: handle, name: project_name } }
let(:handle) { double }
let(:group_params) { { id: group.id } }
let(:extra_params) { { trial_onboarding_flow: trial } }
it_behaves_like "Registrations::ProjectsController POST #create" do
let_it_be(:first_project) { create(:project) }
before do
group.add_owner(user)
allow(File).to receive(:open).and_call_original
expect(File).to receive(:open).with(path).and_yield(handle)
end
let(:user) { create(:user, setup_for_company: setup_for_company) }
let(:success_path) { new_trial_path }
let(:stored_location_for) { continuous_onboarding_getting_started_users_sign_up_welcome_path(project_id: first_project.id) }
specify do
expect_next(::Projects::GitlabProjectsImportService, user, expected_arguments)
.to receive(:execute)
include_context 'groups_projects projects concern'
subject
end
end
end
end
end
......
......@@ -103,5 +103,14 @@ RSpec.describe TrialRegistrationsController do
expect(User.last.name).to eq("#{user_params[:first_name]} #{user_params[:last_name]}")
end
end
context 'applying the onboarding=true parameter' do
it 'adds the parameter' do
redirect_path = new_trial_path(glm_source: 'about.gitlab.com', glm_content: 'default-saas-trial')
controller.store_location_for(:user, redirect_path)
post_create
expect(controller.stored_location_for(:user)).to eq(redirect_path + '&onboarding=true')
end
end
end
end
......@@ -94,27 +94,11 @@ RSpec.describe TrialsController, :saas do
it { is_expected.to redirect_to(select_trials_url) }
context 'coming from about.gitlab.com' do
let(:post_params) { { glm_source: 'about.gitlab.com' } }
context 'when the onboarding=true parameter is set' do
let(:post_params) { { glm_source: 'about.gitlab.com', onboarding: true } }
it 'redirects to trial onboarding' do
is_expected.to redirect_to(new_users_sign_up_group_path(glm_source: 'about.gitlab.com', trial_onboarding_flow: true))
end
end
context 'coming from docs.gitlab.com' do
let(:post_params) { { glm_source: 'docs.gitlab.com' } }
it 'redirects to trial onboarding' do
is_expected.to redirect_to(new_users_sign_up_group_path(glm_source: 'docs.gitlab.com', trial_onboarding_flow: true))
end
end
context 'coming from learn.gitlab.com' do
let(:post_params) { { glm_source: 'learn.gitlab.com' } }
it 'redirects to trial onboarding' do
is_expected.to redirect_to(new_users_sign_up_group_path(glm_source: 'learn.gitlab.com', trial_onboarding_flow: true))
it 'redirects to the combined registration path' do
is_expected.to redirect_to(new_users_sign_up_groups_project_path(glm_source: 'about.gitlab.com', trial_onboarding_flow: true))
end
end
......@@ -611,7 +595,15 @@ RSpec.describe TrialsController, :saas do
end
describe '#skip' do
subject(:get_skip) { get :skip }
subject(:get_skip) { get :skip, params: params }
let(:params) { {} }
context 'when the onboarding=true parameter is set' do
let(:params) { { onboarding: true } }
it { is_expected.to redirect_to(new_users_sign_up_groups_project_path(skip_trial: true)) }
end
context 'when the user is `setup_for_company: true`' do
let(:user) { create(:user, setup_for_company: true) }
......
......@@ -55,7 +55,10 @@ describe('EE gitlab license banner dismiss', () => {
jest.spyOn(Cookies, 'set');
dismiss();
expect(Cookies.set).toHaveBeenCalledWith('show_ee_trial_banner', 'false');
expect(Cookies.set).toHaveBeenCalledWith('show_ee_trial_banner', 'false', {
expires: 365,
secure: false,
});
});
it('should not call Cookies.set for `show_ee_trial_banner` when a non close button is clicked', () => {
......
......@@ -31,6 +31,7 @@ describe('broadcast message on dismiss', () => {
expect(Cookies.set).toHaveBeenCalledWith('hide_storage_limit_alert_1_info', true, {
expires: 30,
secure: false,
});
});
});
......@@ -22,6 +22,9 @@ describe('dismissing the alert', () => {
clickDismissButton();
expect(Cookies.set).toHaveBeenCalledWith('hide_user_cap_alert_1', true, { expires: 30 });
expect(Cookies.set).toHaveBeenCalledWith('hide_user_cap_alert_1', true, {
expires: 30,
secure: false,
});
});
});
......@@ -189,6 +189,10 @@ describe('Project vulnerability report app component', () => {
expect(Cookies.set).toHaveBeenCalledWith(
wrapper.vm.$options.autoFixUserCalloutCookieName,
'true',
{
expires: 365,
secure: false,
},
);
});
......
......@@ -189,6 +189,10 @@ describe('Vulnerability Report', () => {
expect(Cookies.set).toHaveBeenCalledWith(
wrapper.vm.$options.autoFixUserCalloutCookieName,
'true',
{
expires: 365,
secure: false,
},
);
});
......
......@@ -23,6 +23,7 @@ describe('TrialCreateLeadForm', () => {
provide: {
submitPath: SUBMIT_PATH,
user: FORM_DATA,
onboarding: false,
},
});
};
......
......@@ -63,11 +63,9 @@ RSpec.describe EE::RegistrationsHelper do
describe '#registration_verification_data' do
before do
allow(helper).to receive(:params).and_return(ActionController::Parameters.new(params))
allow(helper).to receive(:current_user).and_return(build(:user, setup_for_company: setup_for_company))
allow(helper).to receive(:current_user).and_return(build(:user))
end
let(:setup_for_company) { false }
context 'with `learn_gitlab_project_id` parameter present' do
let(:params) { { learn_gitlab_project_id: 1 } }
......@@ -86,23 +84,12 @@ RSpec.describe EE::RegistrationsHelper do
end
end
context 'with `combined` parameter present' do
let(:params) { { combined: true } }
context 'with `offer_trial` parameter present' do
let(:params) { { offer_trial: 'true' } }
context 'when user is setting up for a company' do
let(:setup_for_company) { true }
it 'return expected data' do
expect(helper.registration_verification_data)
.to eq(next_step_url: helper.new_trial_path)
end
end
context 'when user is not setting up for a company' do
it 'return expected data' do
expect(helper.registration_verification_data)
.to eq(next_step_url: helper.root_path)
end
it 'return expected data' do
expect(helper.registration_verification_data)
.to eq(next_step_url: helper.new_trial_path)
end
end
......
......@@ -32,7 +32,7 @@ RSpec.describe EE::TrialHelper do
end
it 'provides expected form data' do
keys = extra_params.keys + [:submit_path]
keys = extra_params.keys + [:submit_path, :onboarding]
expect(helper.create_lead_form_data.keys.map(&:to_sym)).to match_array(keys)
end
......
......@@ -27,6 +27,7 @@ module Gitlab
gon.revision = Gitlab.revision
gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence
gon.gitlab_logo = ActionController::Base.helpers.asset_path('gitlab_logo.png')
gon.secure = Gitlab.config.gitlab.https
gon.sprite_icons = IconsHelper.sprite_icon_path
gon.sprite_file_icons = IconsHelper.sprite_file_icons_path
gon.emoji_sprites_css_path = ActionController::Base.helpers.stylesheet_path('emoji_sprites')
......
......@@ -3,6 +3,7 @@
module LearnGitlab
class Project
PROJECT_NAME = 'Learn GitLab'
PROJECT_NAME_ULTIMATE_TRIAL = 'Learn GitLab - Ultimate trial'
BOARD_NAME = 'GitLab onboarding'
LABEL_NAME = 'Novice'
......@@ -15,7 +16,7 @@ module LearnGitlab
end
def project
@project ||= current_user.projects.find_by_name(PROJECT_NAME)
@project ||= current_user.projects.find_by_name([PROJECT_NAME, PROJECT_NAME_ULTIMATE_TRIAL])
end
def board
......
......@@ -58,7 +58,7 @@ module QA
{
title: "Reliable e2e test report",
description: report_issue_body,
labels: "Quality,test,type::maintenance,reliable test report"
labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
},
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
)
......
......@@ -167,7 +167,7 @@ describe QA::Tools::ReliableReport do
payload: {
title: "Reliable e2e test report",
description: issue_body,
labels: "Quality,test,type::maintenance,reliable test report"
labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
}
)
expect(slack_notifier).to have_received(:post).with(
......
......@@ -30,6 +30,7 @@ describe('broadcast message on dismiss', () => {
expect(Cookies.set).toHaveBeenCalledWith('hide_broadcast_message_1', true, {
expires: new Date(endsAt),
secure: false,
});
});
});
......@@ -118,7 +118,7 @@ describe('When the code_quality_walkthrough URL parameter is present', () => {
expect(Cookies.set).toHaveBeenCalledWith(
EXPERIMENT_NAME,
{ commit_ci_file: true, data: dummyContext },
{ expires: 365 },
{ expires: 365, secure: false },
);
});
......
......@@ -254,7 +254,10 @@ describe('Design management design sidebar component', () => {
it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
jest.spyOn(Cookies, 'set');
wrapper.trigger('click');
expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 });
expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', {
expires: 365 * 10,
secure: false,
});
});
});
......
......@@ -31,6 +31,7 @@ describe('addToFrequentlyUsed', () => {
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
expires: 365,
secure: false,
});
});
......@@ -41,6 +42,7 @@ describe('addToFrequentlyUsed', () => {
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsdown,thumbsup', {
expires: 365,
secure: false,
});
});
......@@ -51,6 +53,7 @@ describe('addToFrequentlyUsed', () => {
expect(Cookies.set).toHaveBeenCalledWith('frequently_used_emojis', 'thumbsup', {
expires: 365,
secure: false,
});
});
});
......@@ -159,7 +159,10 @@ describe('Landing', () => {
});
it('should call Cookies.set', () => {
expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', { expires: 365 });
expect(Cookies.set).toHaveBeenCalledWith(test.cookieName, 'true', {
expires: 365,
secure: false,
});
});
});
......
......@@ -207,7 +207,10 @@ describe('merge conflicts actions', () => {
],
[],
() => {
expect(Cookies.set).toHaveBeenCalledWith('diff_view', payload);
expect(Cookies.set).toHaveBeenCalledWith('diff_view', payload, {
expires: 365,
secure: false,
});
done();
},
);
......
......@@ -84,6 +84,7 @@ describe('Pipeline Schedule Callout', () => {
expect(setCookiesSpy).toHaveBeenCalledWith('pipeline_schedules_callout_dismissed', true, {
expires: 365,
secure: false,
});
});
});
......
......@@ -37,7 +37,10 @@ describe('Knative survey banner', () => {
wrapper.find(GlBanner).vm.$emit('close');
await nextTick();
expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', {
expires: 3650,
secure: false,
});
expect(wrapper.find(GlBanner).exists()).toBe(false);
});
......
......@@ -70,7 +70,10 @@ describe('IssuableSidebarRoot', () => {
it('updates "collapsed_gutter" cookie value and layout classes', async () => {
await findToggleSidebarButton().trigger('click');
expect(Cookies.set).toHaveBeenCalledWith(USER_COLLAPSED_GUTTER_COOKIE, true);
expect(Cookies.set).toHaveBeenCalledWith(USER_COLLAPSED_GUTTER_COOKIE, true, {
expires: 365,
secure: false,
});
assertPageLayoutClasses({ isExpanded: false });
});
});
......
......@@ -6,9 +6,41 @@ RSpec.describe Gitlab::GonHelper do
let(:helper) do
Class.new do
include Gitlab::GonHelper
def current_user
nil
end
end.new
end
describe '#add_gon_variables' do
let(:gon) { double('gon').as_null_object }
let(:https) { true }
before do
allow(helper).to receive(:gon).and_return(gon)
stub_config_setting(https: https)
end
context 'when HTTPS is enabled' do
it 'sets the secure flag to true' do
expect(gon).to receive(:secure=).with(true)
helper.add_gon_variables
end
end
context 'when HTTP is enabled' do
let(:https) { false }
it 'sets the secure flag to false' do
expect(gon).to receive(:secure=).with(false)
helper.add_gon_variables
end
end
end
describe '#push_frontend_feature_flag' do
before do
skip_feature_flags_yaml_validation
......
......@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe LearnGitlab::Project do
let_it_be(:current_user) { create(:user) }
let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME) }
let_it_be(:learn_gitlab_ultimate_trial_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL) }
let_it_be(:learn_gitlab_board) { create(:board, project: learn_gitlab_project, name: LearnGitlab::Project::BOARD_NAME) }
let_it_be(:learn_gitlab_label) { create(:label, project: learn_gitlab_project, name: LearnGitlab::Project::LABEL_NAME) }
......@@ -45,6 +46,12 @@ RSpec.describe LearnGitlab::Project do
subject { described_class.new(current_user).project }
it { is_expected.to eq learn_gitlab_project }
context 'when it is created during trial signup' do
let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL) }
it { is_expected.to eq learn_gitlab_project }
end
end
describe '.board' do
......
......@@ -3,11 +3,11 @@
RSpec.shared_examples 'group and project packages query' do
include GraphqlHelpers
let_it_be(:versionaless_package) { create(:maven_package, project: project1, version: nil) }
let_it_be(:maven_package) { create(:maven_package, project: project1, name: 'tab', version: '4.0.0', created_at: 5.days.ago) }
let_it_be(:package) { create(:npm_package, project: project1, name: 'uab', version: '5.0.0', created_at: 4.days.ago) }
let_it_be(:composer_package) { create(:composer_package, project: project2, name: 'vab', version: '6.0.0', created_at: 3.days.ago) }
let_it_be(:debian_package) { create(:debian_package, project: project2, name: 'zab', version: '7.0.0', created_at: 2.days.ago) }
let_it_be(:versionless_package) { create(:maven_package, project: project1, version: nil) }
let_it_be(:maven_package) { create(:maven_package, project: project1, name: 'bab', version: '6.0.0', created_at: 1.day.ago) }
let_it_be(:npm_package) { create(:npm_package, project: project1, name: 'cab', version: '7.0.0', created_at: 4.days.ago) }
let_it_be(:composer_package) { create(:composer_package, project: project2, name: 'dab', version: '4.0.0', created_at: 3.days.ago) }
let_it_be(:debian_package) { create(:debian_package, project: project2, name: 'aab', version: '5.0.0', created_at: 2.days.ago) }
let_it_be(:composer_metadatum) do
create(:composer_metadatum, package: composer_package,
target_sha: 'afdeh',
......@@ -21,11 +21,11 @@ RSpec.shared_examples 'group and project packages query' do
let(:fields) do
<<~QUERY
count
nodes {
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
metadata { #{query_graphql_fragment('ComposerMetadata')} }
}
count
nodes {
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
metadata { #{query_graphql_fragment('ComposerMetadata')} }
}
QUERY
end
......@@ -47,7 +47,7 @@ RSpec.shared_examples 'group and project packages query' do
it 'returns packages successfully' do
expect(package_names).to contain_exactly(
package.name,
npm_package.name,
maven_package.name,
debian_package.name,
composer_package.name
......@@ -88,7 +88,23 @@ RSpec.shared_examples 'group and project packages query' do
end
describe 'sorting and pagination' do
let_it_be(:ascending_packages) { [maven_package, package, composer_package, debian_package].map { |package| global_id_of(package)} }
let_it_be(:packages_order_map) do
{
TYPE_ASC: [maven_package, npm_package, composer_package, debian_package],
TYPE_DESC: [debian_package, composer_package, npm_package, maven_package],
NAME_ASC: [debian_package, maven_package, npm_package, composer_package],
NAME_DESC: [composer_package, npm_package, maven_package, debian_package],
VERSION_ASC: [composer_package, debian_package, maven_package, npm_package],
VERSION_DESC: [npm_package, maven_package, debian_package, composer_package],
CREATED_ASC: [npm_package, composer_package, debian_package, maven_package],
CREATED_DESC: [maven_package, debian_package, composer_package, npm_package]
}
end
let(:expected_packages) { sorted_packages.map { |package| global_id_of(package) } }
let(:data_path) { [resource_type, :packages] }
......@@ -96,22 +112,14 @@ RSpec.shared_examples 'group and project packages query' do
resource.add_reporter(current_user)
end
[:CREATED_ASC, :NAME_ASC, :VERSION_ASC, :TYPE_ASC].each do |order|
[:CREATED_ASC, :NAME_ASC, :VERSION_ASC, :TYPE_ASC, :CREATED_DESC, :NAME_DESC, :VERSION_DESC, :TYPE_DESC].each do |order|
context "#{order}" do
it_behaves_like 'sorted paginated query' do
let(:sort_param) { order }
let(:first_param) { 4 }
let(:all_records) { ascending_packages }
end
end
end
let(:sorted_packages) { packages_order_map.fetch(order) }
[:CREATED_DESC, :NAME_DESC, :VERSION_DESC, :TYPE_DESC].each do |order|
context "#{order}" do
it_behaves_like 'sorted paginated query' do
let(:sort_param) { order }
let(:first_param) { 4 }
let(:all_records) { ascending_packages.reverse }
let(:all_records) { expected_packages }
end
end
end
......@@ -180,7 +188,7 @@ RSpec.shared_examples 'group and project packages query' do
context 'include_versionless' do
let(:params) { { include_versionless: true } }
it { is_expected.to include({ "name" => versionaless_package.name }) }
it { is_expected.to include({ "name" => versionless_package.name }) }
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