Commit aac62d39 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch '5708-add-contact-sales-option-via-banner-for-canary-deployments' into 'master'

Resolve "Add contact sales option via Banner for Canary Deployments"

Closes #5708

See merge request gitlab-org/gitlab-ee!8457
parents 267f2854 0be9d5f0
...@@ -30,6 +30,28 @@ export default { ...@@ -30,6 +30,28 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
// ee-only start
canaryDeploymentFeatureId: {
type: String,
required: true,
},
showCanaryDeploymentCallout: {
type: Boolean,
required: true,
},
userCalloutsPath: {
type: String,
required: true,
},
lockPromotionSvgPath: {
type: String,
required: true,
},
helpCanaryDeploymentsPath: {
type: String,
required: true,
},
// ee-only end
}, },
methods: { methods: {
onChangePage(page) { onChangePage(page) {
...@@ -55,6 +77,11 @@ export default { ...@@ -55,6 +77,11 @@ export default {
:environments="environments" :environments="environments"
:can-create-deployment="canCreateDeployment" :can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
:canary-deployment-feature-id="canaryDeploymentFeatureId"
:show-canary-deployment-callout="showCanaryDeploymentCallout"
:user-callouts-path="userCalloutsPath"
:lock-promotion-svg-path="lockPromotionSvgPath"
:help-canary-deployments-path="helpCanaryDeploymentsPath"
/> />
<table-pagination <table-pagination
......
...@@ -44,6 +44,28 @@ export default { ...@@ -44,6 +44,28 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
// ee-only start
canaryDeploymentFeatureId: {
type: String,
required: true,
},
showCanaryDeploymentCallout: {
type: Boolean,
required: true,
},
userCalloutsPath: {
type: String,
required: true,
},
lockPromotionSvgPath: {
type: String,
required: true,
},
helpCanaryDeploymentsPath: {
type: String,
required: true,
},
// ee-only end
}, },
created() { created() {
...@@ -118,6 +140,11 @@ export default { ...@@ -118,6 +140,11 @@ export default {
:pagination="state.paginationInformation" :pagination="state.paginationInformation"
:can-create-deployment="canCreateDeployment" :can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
:canary-deployment-feature-id="canaryDeploymentFeatureId"
:show-canary-deployment-callout="showCanaryDeploymentCallout"
:user-callouts-path="userCalloutsPath"
:lock-promotion-svg-path="lockPromotionSvgPath"
:help-canary-deployments-path="helpCanaryDeploymentsPath"
@onChangePage="onChangePage" @onChangePage="onChangePage"
> >
<empty-state <empty-state
......
...@@ -3,15 +3,21 @@ ...@@ -3,15 +3,21 @@
* Render environments table. * Render environments table.
*/ */
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import environmentItem from './environment_item.vue'; import environmentItem from './environment_item.vue'; // eslint-disable-line import/order
import deployBoard from 'ee/environments/components/deploy_board_component.vue'; // eslint-disable-line import/order // ee-only start
import deployBoard from 'ee/environments/components/deploy_board_component.vue';
import CanaryDeploymentCallout from 'ee/environments/components/canary_deployment_callout.vue';
// ee-only end
export default { export default {
components: { components: {
environmentItem, environmentItem,
deployBoard, deployBoard,
GlLoadingIcon, GlLoadingIcon,
// ee-only start
CanaryDeploymentCallout,
// ee-only end
}, },
props: { props: {
...@@ -32,6 +38,33 @@ export default { ...@@ -32,6 +38,33 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
// ee-only start
canaryDeploymentFeatureId: {
type: String,
required: true,
},
showCanaryDeploymentCallout: {
type: Boolean,
required: true,
},
userCalloutsPath: {
type: String,
required: true,
},
lockPromotionSvgPath: {
type: String,
required: true,
},
helpCanaryDeploymentsPath: {
type: String,
required: true,
},
// ee-only end
}, },
methods: { methods: {
folderUrl(model) { folderUrl(model) {
...@@ -40,6 +73,11 @@ export default { ...@@ -40,6 +73,11 @@ export default {
shouldRenderFolderContent(env) { shouldRenderFolderContent(env) {
return env.isFolder && env.isOpen && env.children && env.children.length > 0; return env.isFolder && env.isOpen && env.children && env.children.length > 0;
}, },
// ee-only start
shouldShowCanaryCallout(env) {
return env.showCanaryCallout && this.showCanaryDeploymentCallout;
},
// ee-only end
}, },
}; };
</script> </script>
...@@ -110,6 +148,17 @@ export default { ...@@ -110,6 +148,17 @@ export default {
</div> </div>
</template> </template>
</template> </template>
<template v-if="shouldShowCanaryCallout(model)">
<canary-deployment-callout
:key="`canary-promo-${i}`"
:canary-deployment-feature-id="canaryDeploymentFeatureId"
:user-callouts-path="userCalloutsPath"
:lock-promotion-svg-path="lockPromotionSvgPath"
:help-canary-deployments-path="helpCanaryDeploymentsPath"
:data-js-canary-promo-key="i"
/>
</template>
</template> </template>
</div> </div>
</template> </template>
...@@ -3,6 +3,10 @@ import environmentsFolderApp from './environments_folder_view.vue'; ...@@ -3,6 +3,10 @@ import environmentsFolderApp from './environments_folder_view.vue';
import { parseBoolean } from '../../lib/utils/common_utils'; import { parseBoolean } from '../../lib/utils/common_utils';
import Translate from '../../vue_shared/translate'; import Translate from '../../vue_shared/translate';
// ee-only start
import CanaryCalloutMixin from 'ee/environments/mixins/canary_callout_mixin'; // eslint-disable-line import/order
// ee-only end
Vue.use(Translate); Vue.use(Translate);
export default () => export default () =>
...@@ -11,6 +15,9 @@ export default () => ...@@ -11,6 +15,9 @@ export default () =>
components: { components: {
environmentsFolderApp, environmentsFolderApp,
}, },
// ee-only start
mixins: [CanaryCalloutMixin],
// ee-only end
data() { data() {
const environmentsData = document.querySelector(this.$options.el).dataset; const environmentsData = document.querySelector(this.$options.el).dataset;
...@@ -30,6 +37,13 @@ export default () => ...@@ -30,6 +37,13 @@ export default () =>
cssContainerClass: this.cssContainerClass, cssContainerClass: this.cssContainerClass,
canCreateDeployment: this.canCreateDeployment, canCreateDeployment: this.canCreateDeployment,
canReadEnvironment: this.canReadEnvironment, canReadEnvironment: this.canReadEnvironment,
// ee-only start
canaryDeploymentFeatureId: this.canaryDeploymentFeatureId,
showCanaryDeploymentCallout: this.showCanaryDeploymentCallout,
userCalloutsPath: this.userCalloutsPath,
lockPromotionSvgPath: this.lockPromotionSvgPath,
helpCanaryDeploymentsPath: this.helpCanaryDeploymentsPath,
// ee-only end
}, },
}); });
}, },
......
...@@ -31,6 +31,28 @@ export default { ...@@ -31,6 +31,28 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
// ee-only start
canaryDeploymentFeatureId: {
type: String,
required: true,
},
showCanaryDeploymentCallout: {
type: Boolean,
required: true,
},
userCalloutsPath: {
type: String,
required: true,
},
lockPromotionSvgPath: {
type: String,
required: true,
},
helpCanaryDeploymentsPath: {
type: String,
required: true,
},
// ee-only end
}, },
methods: { methods: {
successCallback(resp) { successCallback(resp) {
...@@ -57,6 +79,11 @@ export default { ...@@ -57,6 +79,11 @@ export default {
:pagination="state.paginationInformation" :pagination="state.paginationInformation"
:can-create-deployment="canCreateDeployment" :can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
:canary-deployment-feature-id="canaryDeploymentFeatureId"
:show-canary-deployment-callout="showCanaryDeploymentCallout"
:user-callouts-path="userCalloutsPath"
:lock-promotion-svg-path="lockPromotionSvgPath"
:help-canary-deployments-path="helpCanaryDeploymentsPath"
@onChangePage="onChangePage" @onChangePage="onChangePage"
/> />
</div> </div>
......
...@@ -3,6 +3,10 @@ import environmentsComponent from './components/environments_app.vue'; ...@@ -3,6 +3,10 @@ import environmentsComponent from './components/environments_app.vue';
import { parseBoolean } from '../lib/utils/common_utils'; import { parseBoolean } from '../lib/utils/common_utils';
import Translate from '../vue_shared/translate'; import Translate from '../vue_shared/translate';
// ee-only start
import CanaryCalloutMixin from 'ee/environments/mixins/canary_callout_mixin'; // eslint-disable-line import/order
// ee-only end
Vue.use(Translate); Vue.use(Translate);
export default () => export default () =>
...@@ -11,6 +15,9 @@ export default () => ...@@ -11,6 +15,9 @@ export default () =>
components: { components: {
environmentsComponent, environmentsComponent,
}, },
// ee-only start
mixins: [CanaryCalloutMixin],
// ee-only end
data() { data() {
const environmentsData = document.querySelector(this.$options.el).dataset; const environmentsData = document.querySelector(this.$options.el).dataset;
...@@ -34,6 +41,13 @@ export default () => ...@@ -34,6 +41,13 @@ export default () =>
canCreateEnvironment: this.canCreateEnvironment, canCreateEnvironment: this.canCreateEnvironment,
canCreateDeployment: this.canCreateDeployment, canCreateDeployment: this.canCreateDeployment,
canReadEnvironment: this.canReadEnvironment, canReadEnvironment: this.canReadEnvironment,
// ee-only start
canaryDeploymentFeatureId: this.canaryDeploymentFeatureId,
showCanaryDeploymentCallout: this.showCanaryDeploymentCallout,
userCalloutsPath: this.userCalloutsPath,
lockPromotionSvgPath: this.lockPromotionSvgPath,
helpCanaryDeploymentsPath: this.helpCanaryDeploymentsPath,
// ee-only end
}, },
}); });
}, },
......
...@@ -2,7 +2,6 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; ...@@ -2,7 +2,6 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
// ee-only // ee-only
import { CLUSTER_TYPE } from '~/clusters/constants'; import { CLUSTER_TYPE } from '~/clusters/constants';
/** /**
* Environments Store. * Environments Store.
* *
...@@ -96,6 +95,19 @@ export default class EnvironmentsStore { ...@@ -96,6 +95,19 @@ export default class EnvironmentsStore {
this.state.environments = filteredEnvironments; this.state.environments = filteredEnvironments;
// ee-only start
/**
* Add the canary callout banner underneath the second environment listed.
*
* If there is only one environment, then add to it underneath the first.
*/
if (this.state.environments.length >= 2) {
this.state.environments[1].showCanaryCallout = true;
} else if (this.state.environments.length === 1) {
this.state.environments[0].showCanaryCallout = true;
}
// ee-only end
return filteredEnvironments; return filteredEnvironments;
} }
...@@ -222,7 +234,9 @@ export default class EnvironmentsStore { ...@@ -222,7 +234,9 @@ export default class EnvironmentsStore {
let updated = Object.assign({}, env); let updated = Object.assign({}, env);
if (env.id === environmentID) { if (env.id === environmentID) {
updated = Object.assign({}, updated, { isDeployBoardVisible: !env.isDeployBoardVisible }); updated = Object.assign({}, updated, {
isDeployBoardVisible: !env.isDeployBoardVisible,
});
} }
return updated; return updated;
}); });
......
...@@ -721,3 +721,59 @@ ...@@ -721,3 +721,59 @@
margin-left: $gl-padding-8; margin-left: $gl-padding-8;
} }
} }
// ee-only start
.canary-deployment-callout {
border-bottom: 1px solid $border-white-normal;
display: flex;
@include media-breakpoint-down(sm) {
display: none;
}
&-lock {
height: 82px;
width: 92px;
}
&-message {
max-width: 600px;
color: $gray-700;
}
&-close {
color: $gray-700;
cursor: pointer;
}
&-button {
border-color: $blue-500;
color: $blue-500;
&:not(:disabled):not(.disabled):active {
background-color: $blue-200;
border: 2px solid $blue-600;
color: $blue-700;
height: 34px;
padding: 5px 9px;
}
&:focus {
background-color: $blue-100;
border: 2px solid $blue-500;
box-shadow: 0 0 4px 1px $blue-200;
color: $blue-600;
height: 34px;
padding: 5px 9px;
}
&:hover {
background-color: $blue-100;
border: 2px solid $blue-500;
color: $blue-600;
height: 34px;
padding: 5px 9px;
}
}
}
// ee-only end
<script>
import { GlButton, GlLink } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import PersistentUserCallout from '~/persistent_user_callout';
export default {
components: {
GlButton,
GlLink,
Icon,
},
props: {
canaryDeploymentFeatureId: {
type: String,
required: true,
},
userCalloutsPath: {
type: String,
required: true,
},
lockPromotionSvgPath: {
type: String,
required: true,
},
helpCanaryDeploymentsPath: {
type: String,
required: true,
},
},
mounted() {
const callout = this.$refs['canary-deployment-callout'];
if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new
},
};
</script>
<template>
<div
ref="canary-deployment-callout"
class="p-3 canary-deployment-callout"
:data-dismiss-endpoint="userCalloutsPath"
:data-feature-id="canaryDeploymentFeatureId"
>
<img class="canary-deployment-callout-lock pr-3" :src="lockPromotionSvgPath" />
<div class="pl-3">
<p class="font-weight-bold mb-1">
{{ __('Upgrade plan to unlock Canary Deployments feature') }}
</p>
<p class="canary-deployment-callout-message">
{{
__(
'Canary Deployments is a popular CI strategy, where a small portion of the fleet is updated to the new version of your application.',
)
}}
<gl-link :href="helpCanaryDeploymentsPath">{{ __('Read more') }}</gl-link>
</p>
<gl-button
href="https://about.gitlab.com/sales/"
variant="outline-primary"
class="canary-deployment-callout-button"
>{{ __('Contact sales to upgrade') }}</gl-button
>
</div>
<div class="ml-auto pr-2 canary-deployment-callout-close js-close"><icon name="close" /></div>
</div>
</template>
import { parseBoolean } from '~/lib/utils/common_utils';
export default {
data() {
const data = document.querySelector(this.$options.el).dataset;
return {
canaryDeploymentFeatureId: data.environmentsDataCanaryDeploymentFeatureId,
showCanaryDeploymentCallout: parseBoolean(data.environmentsDataShowCanaryDeploymentCallout),
userCalloutsPath: data.environmentsDataUserCalloutsPath,
lockPromotionSvgPath: data.environmentsDataLockPromotionSvgPath,
helpCanaryDeploymentsPath: data.environmentsDataHelpCanaryDeploymentsPath,
};
},
};
...@@ -2,6 +2,30 @@ ...@@ -2,6 +2,30 @@
module EE module EE
module EnvironmentsHelper module EnvironmentsHelper
def environments_list_data
ee_environments_list_data = {
"canary_deployment_feature_id" => UserCalloutsHelper::CANARY_DEPLOYMENT,
"show-canary-deployment-callout" => show_canary_deployment_callout?(@project).to_s,
"user-callouts-path" => user_callouts_path,
"lock-promotion-svg-path" => image_path('illustrations/lock_promotion.svg'),
"help-canary-deployments-path" => help_page_path('user/project/canary_deployments')
}
super.merge(ee_environments_list_data)
end
def environments_folder_list_view_data
ee_environments_folder_list_view_data = {
"canary_deployment_feature_id" => UserCalloutsHelper::CANARY_DEPLOYMENT,
"show-canary-deployment-callout" => show_canary_deployment_callout?(@project).to_s,
"user-callouts-path" => user_callouts_path,
"lock-promotion-svg-path" => image_path('illustrations/lock_promotion.svg'),
"help-canary-deployments-path" => help_page_path('user/project/canary_deployments')
}
super.merge(ee_environments_folder_list_view_data)
end
def metrics_data(project, environment) def metrics_data(project, environment)
ee_metrics_data = { ee_metrics_data = {
"alerts-endpoint" => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json), "alerts-endpoint" => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
......
...@@ -5,6 +5,7 @@ module EE ...@@ -5,6 +5,7 @@ module EE
GOLD_TRIAL = 'gold_trial' GOLD_TRIAL = 'gold_trial'
GEO_ENABLE_HASHED_STORAGE = 'geo_enable_hashed_storage' GEO_ENABLE_HASHED_STORAGE = 'geo_enable_hashed_storage'
GEO_MIGRATE_HASHED_STORAGE = 'geo_migrate_hashed_storage' GEO_MIGRATE_HASHED_STORAGE = 'geo_migrate_hashed_storage'
CANARY_DEPLOYMENT = 'canary_deployment'
def show_gold_trial?(user = current_user) def show_gold_trial?(user = current_user)
return false unless user return false unless user
...@@ -14,6 +15,13 @@ module EE ...@@ -14,6 +15,13 @@ module EE
users_namespaces_clean?(user) users_namespaces_clean?(user)
end end
def show_canary_deployment_callout?(project)
!user_dismissed?(CANARY_DEPLOYMENT) &&
show_promotions? &&
# use :canary_deployments if we create a feature flag for it in the future
!project.feature_available?(:deploy_board)
end
def show_gold_trial_suitable_env? def show_gold_trial_suitable_env?
(::Gitlab.com? || Rails.env.development?) && (::Gitlab.com? || Rails.env.development?) &&
!::Gitlab::Database.read_only? !::Gitlab::Database.read_only?
......
...@@ -10,10 +10,10 @@ module EE ...@@ -10,10 +10,10 @@ module EE
override :feature_names override :feature_names
def feature_names def feature_names
super.merge( super.merge(
cluster_security_warning: 3,
gold_trial: 4, gold_trial: 4,
geo_enable_hashed_storage: 5, geo_enable_hashed_storage: 5,
geo_migrate_hashed_storage: 6) geo_migrate_hashed_storage: 6,
canary_deployment: 7)
end end
end end
end end
......
---
title: Canary deployment callout on the environments page
merge_request: 8457
author:
type: added
...@@ -148,4 +148,45 @@ describe EE::UserCalloutsHelper do ...@@ -148,4 +148,45 @@ describe EE::UserCalloutsHelper do
end end
end end
end end
describe '.show_canary_deployment_callout?' do
let(:project) { build(:project) }
subject { helper.show_canary_deployment_callout?(project) }
before do
allow(helper).to receive(:show_promotions?).and_return(true)
end
context 'when user needs to upgrade to canary deployments' do
before do
allow(project).to receive(:feature_available?).with(:deploy_board).and_return(false)
end
context 'when user has dismissed' do
before do
allow(helper).to receive(:user_dismissed?).and_return(true)
end
it { is_expected.to be_falsey }
end
context 'when user has not dismissed' do
before do
allow(helper).to receive(:user_dismissed?).and_return(false)
end
it { is_expected.to be_truthy }
end
end
context 'when user already has access to canary deployments' do
before do
allow(project).to receive(:feature_available?).with(:deploy_board).and_return(true)
allow(helper).to receive(:user_dismissed?).and_return(false)
end
it { is_expected.to be_falsey }
end
end
end end
...@@ -1567,6 +1567,9 @@ msgstr "" ...@@ -1567,6 +1567,9 @@ msgstr ""
msgid "Can't find HEAD commit for this branch" msgid "Can't find HEAD commit for this branch"
msgstr "" msgstr ""
msgid "Canary Deployments is a popular CI strategy, where a small portion of the fleet is updated to the new version of your application."
msgstr ""
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
...@@ -2481,6 +2484,9 @@ msgstr "" ...@@ -2481,6 +2484,9 @@ msgstr ""
msgid "Connecting..." msgid "Connecting..."
msgstr "" msgstr ""
msgid "Contact sales to upgrade"
msgstr ""
msgid "Container Registry" msgid "Container Registry"
msgstr "" msgstr ""
...@@ -9810,6 +9816,9 @@ msgstr "" ...@@ -9810,6 +9816,9 @@ msgstr ""
msgid "Updating" msgid "Updating"
msgstr "" msgstr ""
msgid "Upgrade plan to unlock Canary Deployments feature"
msgstr ""
msgid "Upgrade your plan to activate Advanced Global Search." msgid "Upgrade your plan to activate Advanced Global Search."
msgstr "" msgstr ""
......
...@@ -29,6 +29,13 @@ describe('Environment table', () => { ...@@ -29,6 +29,13 @@ describe('Environment table', () => {
environments: [mockItem], environments: [mockItem],
canCreateDeployment: false, canCreateDeployment: false,
canReadEnvironment: true, canReadEnvironment: true,
// ee-only start
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
// ee-only end
}); });
expect(vm.$el.getAttribute('class')).toContain('ci-table'); expect(vm.$el.getAttribute('class')).toContain('ci-table');
...@@ -51,6 +58,13 @@ describe('Environment table', () => { ...@@ -51,6 +58,13 @@ describe('Environment table', () => {
environments: [mockItem], environments: [mockItem],
canCreateDeployment: false, canCreateDeployment: false,
canReadEnvironment: true, canReadEnvironment: true,
// ee-only start
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
// ee-only end
}); });
expect(vm.$el.querySelector('.js-deploy-board-row')).toBeDefined(); expect(vm.$el.querySelector('.js-deploy-board-row')).toBeDefined();
...@@ -83,8 +97,41 @@ describe('Environment table', () => { ...@@ -83,8 +97,41 @@ describe('Environment table', () => {
environments: [mockItem], environments: [mockItem],
canCreateDeployment: false, canCreateDeployment: false,
canReadEnvironment: true, canReadEnvironment: true,
// ee-only start
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
// ee-only end
}); });
vm.$el.querySelector('.deploy-board-icon').click(); vm.$el.querySelector('.deploy-board-icon').click();
}); });
// ee-only start
it('should render canary callout', () => {
const mockItem = {
name: 'review',
folderName: 'review',
size: 3,
isFolder: true,
environment_path: 'url',
showCanaryCallout: true,
};
vm = mountComponent(Component, {
environments: [mockItem],
canCreateDeployment: false,
canReadEnvironment: true,
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
});
expect(vm.$el.querySelector('.canary-deployment-callout')).not.toBeNull();
});
// ee-only end
}); });
...@@ -14,6 +14,13 @@ describe('Environment', () => { ...@@ -14,6 +14,13 @@ describe('Environment', () => {
cssContainerClass: 'container', cssContainerClass: 'container',
newEnvironmentPath: 'environments/new', newEnvironmentPath: 'environments/new',
helpPagePath: 'help', helpPagePath: 'help',
// ee-only start
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
// ee-only end
}; };
let EnvironmentsComponent; let EnvironmentsComponent;
...@@ -124,6 +131,70 @@ describe('Environment', () => { ...@@ -124,6 +131,70 @@ describe('Environment', () => {
}); });
}); });
}); });
// ee-only start
describe('canary callout', () => {
it('should render banner underneath second environment', done => {
mock.onGet(mockData.endpoint).reply(
200,
{
environments: [environment, environment],
stopped_count: 1,
available_count: 0,
},
{
'X-nExt-pAge': '2',
'x-page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '',
'X-TOTAL': '37',
'X-Total-Pages': '2',
},
);
component = mountComponent(EnvironmentsComponent, mockData);
setTimeout(() => {
expect(
component.$el
.querySelector('.canary-deployment-callout')
.getAttribute('data-js-canary-promo-key'),
).toBe('1');
done();
}, 0);
});
it('should render banner underneath first environment', done => {
mock.onGet(mockData.endpoint).reply(
200,
{
environments: [environment],
stopped_count: 1,
available_count: 0,
},
{
'X-nExt-pAge': '2',
'x-page': '1',
'X-Per-Page': '1',
'X-Prev-Page': '',
'X-TOTAL': '37',
'X-Total-Pages': '2',
},
);
component = mountComponent(EnvironmentsComponent, mockData);
setTimeout(() => {
expect(
component.$el
.querySelector('.canary-deployment-callout')
.getAttribute('data-js-canary-promo-key'),
).toBe('0');
done();
}, 0);
});
});
// ee-only end
}); });
describe('unsuccessfull request', () => { describe('unsuccessfull request', () => {
......
...@@ -245,4 +245,20 @@ describe('Store', () => { ...@@ -245,4 +245,20 @@ describe('Store', () => {
expect(store.getOpenFolders()[0]).toEqual(store.state.environments[1]); expect(store.getOpenFolders()[0]).toEqual(store.state.environments[1]);
}); });
}); });
// ee-only start
describe('canaryCallout', () => {
it('should add banner underneath the second environment', () => {
store.storeEnvironments(serverData);
expect(store.state.environments[1].showCanaryCallout).toEqual(true);
});
it('should add banner underneath first environment when only one environment', () => {
store.storeEnvironments(serverData.slice(0, 1));
expect(store.state.environments[0].showCanaryCallout).toEqual(true);
});
});
// ee-only end
}); });
...@@ -16,6 +16,13 @@ describe('Environments Folder View', () => { ...@@ -16,6 +16,13 @@ describe('Environments Folder View', () => {
canCreateDeployment: true, canCreateDeployment: true,
canReadEnvironment: true, canReadEnvironment: true,
cssContainerClass: 'container', cssContainerClass: 'container',
// ee-only start
canaryDeploymentFeatureId: 'canary_deployment',
showCanaryDeploymentCallout: true,
userCalloutsPath: '/callouts',
lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
helpCanaryDeploymentsPath: 'help/canary-deployments',
// ee-only end
}; };
beforeEach(() => { beforeEach(() => {
......
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