Commit 086d1b0d authored by Angelo Gulina's avatar Angelo Gulina Committed by Nicolò Maria Mezzopera

Add buttons for subscription management

parent 877dc25a
...@@ -7,9 +7,11 @@ import { ...@@ -7,9 +7,11 @@ import {
licensedToHeaderText, licensedToHeaderText,
manageSubscriptionButtonText, manageSubscriptionButtonText,
notificationType, notificationType,
removeLicense,
subscriptionDetailsHeaderText, subscriptionDetailsHeaderText,
subscriptionType, subscriptionType,
syncSubscriptionButtonText, syncSubscriptionButtonText,
uploadLicense,
} from '../constants'; } from '../constants';
import SubscriptionActivationModal from './subscription_activation_modal.vue'; import SubscriptionActivationModal from './subscription_activation_modal.vue';
import SubscriptionDetailsCard from './subscription_details_card.vue'; import SubscriptionDetailsCard from './subscription_details_card.vue';
...@@ -22,11 +24,13 @@ export const modalId = 'subscription-activation-modal'; ...@@ -22,11 +24,13 @@ export const modalId = 'subscription-activation-modal';
export default { export default {
i18n: { i18n: {
enterActivationCode,
licensedToHeaderText, licensedToHeaderText,
manageSubscriptionButtonText, manageSubscriptionButtonText,
removeLicense,
subscriptionDetailsHeaderText, subscriptionDetailsHeaderText,
syncSubscriptionButtonText, syncSubscriptionButtonText,
enterActivationCode, uploadLicense,
}, },
modal: { modal: {
id: modalId, id: modalId,
...@@ -43,7 +47,7 @@ export default { ...@@ -43,7 +47,7 @@ export default {
SubscriptionDetailsUserInfo, SubscriptionDetailsUserInfo,
SubscriptionSyncNotifications: () => import('./subscription_sync_notifications.vue'), SubscriptionSyncNotifications: () => import('./subscription_sync_notifications.vue'),
}, },
inject: ['subscriptionSyncPath'], inject: ['customersPortalUrl', 'licenseUploadPath', 'subscriptionSyncPath'],
props: { props: {
subscription: { subscription: {
type: Object, type: Object,
...@@ -63,10 +67,16 @@ export default { ...@@ -63,10 +67,16 @@ export default {
}; };
}, },
computed: { computed: {
canManageSubscription() {
return this.customersPortalUrl;
},
canSyncSubscription() { canSyncSubscription() {
return this.subscriptionSyncPath && this.subscription.type === subscriptionType.CLOUD; return this.subscriptionSyncPath && this.isCloudType;
}, },
canManageSubscription() { canUploadLicense() {
return this.licenseUploadPath && this.isLegacyType;
},
canRemoveLicense() {
return false; return false;
}, },
hasSubscription() { hasSubscription() {
...@@ -75,9 +85,21 @@ export default { ...@@ -75,9 +85,21 @@ export default {
hasSubscriptionHistory() { hasSubscriptionHistory() {
return Boolean(this.subscriptionList.length); return Boolean(this.subscriptionList.length);
}, },
isCloudType() {
return this.subscription.type === subscriptionType.CLOUD;
},
isLegacyType() {
return this.subscription.type === subscriptionType.LEGACY;
},
shouldShowFooter() { shouldShowFooter() {
return some( return some(
pick(this, ['canSyncSubscription', 'canMangeSubscription', 'hasSubscription']), pick(this, [
'hasSubscription',
'canDeleteSubscription',
'canManageSubscription',
'canSyncSubscription',
'canUploadSubscription',
]),
Boolean, Boolean,
); );
}, },
...@@ -144,9 +166,33 @@ export default { ...@@ -144,9 +166,33 @@ export default {
> >
{{ $options.i18n.enterActivationCode }} {{ $options.i18n.enterActivationCode }}
</gl-button> </gl-button>
<gl-button v-if="canManageSubscription"> <gl-button
v-if="canUploadLicense"
:href="licenseUploadPath"
category="secondary"
variant="confirm"
data-testid="license-upload-action"
>
{{ $options.i18n.uploadLicense }}
</gl-button>
<gl-button
v-if="canManageSubscription"
:href="customersPortalUrl"
target="_blank"
category="secondary"
variant="confirm"
data-testid="subscription-manage-action"
>
{{ $options.i18n.manageSubscriptionButtonText }} {{ $options.i18n.manageSubscriptionButtonText }}
</gl-button> </gl-button>
<gl-button
v-if="canRemoveLicense"
category="secondary"
variant="danger"
data-testid="license-remove-action"
>
{{ $options.i18n.removeLicense }}
</gl-button>
</template> </template>
</subscription-details-card> </subscription-details-card>
</div> </div>
......
...@@ -37,6 +37,8 @@ export const detailsLabels = { ...@@ -37,6 +37,8 @@ export const detailsLabels = {
startsAt: s__('SuperSonics|Started'), startsAt: s__('SuperSonics|Started'),
}; };
export const removeLicense = __('Remove license');
export const uploadLicense = __('Upload license');
export const uploadLegacyLicense = s__('SuperSonics|Upload a legacy license'); export const uploadLegacyLicense = s__('SuperSonics|Upload a legacy license');
export const billableUsersTitle = s__('CloudLicense|Billable users'); export const billableUsersTitle = s__('CloudLicense|Billable users');
export const maximumUsersTitle = s__('CloudLicense|Maximum users'); export const maximumUsersTitle = s__('CloudLicense|Maximum users');
......
...@@ -25,6 +25,7 @@ export default () => { ...@@ -25,6 +25,7 @@ export default () => {
const { const {
buySubscriptionPath, buySubscriptionPath,
customersPortalUrl,
freeTrialPath, freeTrialPath,
hasActiveLicense, hasActiveLicense,
licenseUploadPath, licenseUploadPath,
...@@ -40,6 +41,7 @@ export default () => { ...@@ -40,6 +41,7 @@ export default () => {
provide: { provide: {
buySubscriptionPath, buySubscriptionPath,
connectivityHelpURL, connectivityHelpURL,
customersPortalUrl,
freeTrialPath, freeTrialPath,
licenseUploadPath, licenseUploadPath,
subscriptionSyncPath, subscriptionSyncPath,
......
...@@ -18,6 +18,7 @@ import { ...@@ -18,6 +18,7 @@ import {
licensedToHeaderText, licensedToHeaderText,
notificationType, notificationType,
subscriptionDetailsHeaderText, subscriptionDetailsHeaderText,
subscriptionType,
} from 'ee/pages/admin/cloud_licenses/constants'; } from 'ee/pages/admin/cloud_licenses/constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -31,20 +32,24 @@ describe('Subscription Breakdown', () => { ...@@ -31,20 +32,24 @@ describe('Subscription Breakdown', () => {
const [, legacyLicense] = subscriptionHistory; const [, legacyLicense] = subscriptionHistory;
const connectivityHelpURL = 'connectivity/help/url'; const connectivityHelpURL = 'connectivity/help/url';
const customersPortalUrl = 'customers.dot';
const licenseUploadPath = '/license/upload/';
const subscriptionSyncPath = '/sync/path/'; const subscriptionSyncPath = '/sync/path/';
const findDetailsCards = () => wrapper.findAllComponents(SubscriptionDetailsCard); const findDetailsCards = () => wrapper.findAllComponents(SubscriptionDetailsCard);
const findDetailsCardFooter = () => wrapper.find('.gl-card-footer'); const findDetailsCardFooter = () => wrapper.find('.gl-card-footer');
const findDetailsHistory = () => wrapper.findComponent(SubscriptionDetailsHistory); const findDetailsHistory = () => wrapper.findComponent(SubscriptionDetailsHistory);
const findDetailsUserInfo = () => wrapper.findComponent(SubscriptionDetailsUserInfo); const findDetailsUserInfo = () => wrapper.findComponent(SubscriptionDetailsUserInfo);
const findLicenseUploadAction = () => wrapper.findByTestId('license-upload-action');
const findSubscriptionActivationAction = () => const findSubscriptionActivationAction = () =>
wrapper.findByTestId('subscription-activation-action'); wrapper.findByTestId('subscription-activation-action');
const findSubscriptionMangeAction = () => wrapper.findByTestId('subscription-manage-action');
const findSubscriptionSyncAction = () => wrapper.findByTestId('subscription-sync-action'); const findSubscriptionSyncAction = () => wrapper.findByTestId('subscription-sync-action');
const findSubscriptionActivationModal = () => wrapper.findComponent(SubscriptionActivationModal); const findSubscriptionActivationModal = () => wrapper.findComponent(SubscriptionActivationModal);
const findSubscriptionSyncNotifications = () => const findSubscriptionSyncNotifications = () =>
wrapper.findComponent(SubscriptionSyncNotifications); wrapper.findComponent(SubscriptionSyncNotifications);
const createComponent = ({ props, stubs } = {}) => { const createComponent = ({ props = {}, provide = {}, stubs = {} } = {}) => {
glModalDirective = jest.fn(); glModalDirective = jest.fn();
wrapper = extendedWrapper( wrapper = extendedWrapper(
shallowMount(SubscriptionBreakdown, { shallowMount(SubscriptionBreakdown, {
...@@ -57,7 +62,10 @@ describe('Subscription Breakdown', () => { ...@@ -57,7 +62,10 @@ describe('Subscription Breakdown', () => {
}, },
provide: { provide: {
connectivityHelpURL, connectivityHelpURL,
customersPortalUrl,
licenseUploadPath,
subscriptionSyncPath, subscriptionSyncPath,
...provide,
}, },
propsData: { propsData: {
subscription: license.ULTIMATE, subscription: license.ULTIMATE,
...@@ -122,12 +130,6 @@ describe('Subscription Breakdown', () => { ...@@ -122,12 +130,6 @@ describe('Subscription Breakdown', () => {
expect(findDetailsCardFooter().exists()).toBe(true); expect(findDetailsCardFooter().exists()).toBe(true);
}); });
it('shows a button to sync the subscription', () => {
createComponent({ stubs: { GlCard, SubscriptionDetailsCard } });
expect(findSubscriptionSyncAction().exists()).toBe(true);
});
it('shows a button to activate a new subscription', () => { it('shows a button to activate a new subscription', () => {
createComponent({ stubs: { GlCard, SubscriptionDetailsCard } }); createComponent({ stubs: { GlCard, SubscriptionDetailsCard } });
...@@ -142,7 +144,62 @@ describe('Subscription Breakdown', () => { ...@@ -142,7 +144,62 @@ describe('Subscription Breakdown', () => {
expect(findSubscriptionActivationModal().attributes('modalid')).toBe(modalId); expect(findSubscriptionActivationModal().attributes('modalid')).toBe(modalId);
}); });
it.todo('shows a button to manage the subscription'); describe('footer buttons', () => {
it.each`
url | type | shouldShow
${subscriptionSyncPath} | ${subscriptionType.CLOUD} | ${true}
${subscriptionSyncPath} | ${subscriptionType.LEGACY} | ${false}
${''} | ${subscriptionType.CLOUD} | ${false}
${''} | ${subscriptionType.LEGACY} | ${false}
${undefined} | ${subscriptionType.CLOUD} | ${false}
${undefined} | ${subscriptionType.LEGACY} | ${false}
`(
'with url is $url and type is $type the sync buttons is shown: $shouldShow',
({ url, type, shouldShow }) => {
const provide = { subscriptionSyncPath: url };
const props = { subscription: { ...license.ULTIMATE, type } };
const stubs = { GlCard, SubscriptionDetailsCard };
createComponent({ props, provide, stubs });
expect(findSubscriptionSyncAction().exists()).toBe(shouldShow);
},
);
it.each`
url | type | shouldShow
${licenseUploadPath} | ${subscriptionType.LEGACY} | ${true}
${licenseUploadPath} | ${subscriptionType.CLOUD} | ${false}
${''} | ${subscriptionType.LEGACY} | ${false}
${''} | ${subscriptionType.CLOUD} | ${false}
${undefined} | ${subscriptionType.LEGACY} | ${false}
${undefined} | ${subscriptionType.CLOUD} | ${false}
`(
'with url is $url and type is $type the upload buttons is shown: $shouldShow',
({ url, type, shouldShow }) => {
const provide = { licenseUploadPath: url };
const props = { subscription: { ...license.ULTIMATE, type } };
const stubs = { GlCard, SubscriptionDetailsCard };
createComponent({ props, provide, stubs });
expect(findLicenseUploadAction().exists()).toBe(shouldShow);
},
);
it.each`
url | shouldShow
${customersPortalUrl} | ${true}
${''} | ${false}
${undefined} | ${false}
`('with url is $url the manage buttons is shown: $shouldShow', ({ url, shouldShow }) => {
const provide = { customersPortalUrl: url };
const stubs = { GlCard, SubscriptionDetailsCard };
createComponent({ provide, stubs });
expect(findSubscriptionMangeAction().exists()).toBe(shouldShow);
});
it.todo('should show a remove subscription button');
});
describe('with a legacy license', () => { describe('with a legacy license', () => {
beforeEach(() => { beforeEach(() => {
......
...@@ -34676,6 +34676,9 @@ msgstr "" ...@@ -34676,6 +34676,9 @@ msgstr ""
msgid "Upload file" msgid "Upload file"
msgstr "" msgstr ""
msgid "Upload license"
msgstr ""
msgid "Upload object map" msgid "Upload object map"
msgstr "" msgstr ""
......
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