Commit 33eb839b authored by Michael Lunøe's avatar Michael Lunøe Committed by Natalia Tepluhina

Refactor(SM: Subscription history): direct import

Remove unnecessary middle-file and import queries
directly where needed
parent f8040dc5
<script> <script>
import { GlAlert, GlButton } from '@gitlab/ui'; import { GlAlert, GlButton, GlSprintf } from '@gitlab/ui';
import { isInFuture } from '~/lib/utils/datetime/date_calculation_utility'; import { isInFuture } from '~/lib/utils/datetime/date_calculation_utility';
import { sprintf } from '~/locale'; import { sprintf } from '~/locale';
import { import {
...@@ -8,12 +8,16 @@ import { ...@@ -8,12 +8,16 @@ import {
subscriptionActivationNotificationText, subscriptionActivationNotificationText,
subscriptionActivationFutureDatedNotificationTitle, subscriptionActivationFutureDatedNotificationTitle,
subscriptionActivationFutureDatedNotificationMessage, subscriptionActivationFutureDatedNotificationMessage,
subscriptionHistoryQueries, subscriptionHistoryFailedTitle,
subscriptionHistoryFailedMessage,
currentSubscriptionsEntryName,
historySubscriptionsEntryName,
subscriptionMainTitle, subscriptionMainTitle,
subscriptionQueries,
exportLicenseUsageBtnText, exportLicenseUsageBtnText,
SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT, SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT,
} from '../constants'; } from '../constants';
import getCurrentLicense from '../graphql/queries/get_current_license.query.graphql';
import getLicenseHistory from '../graphql/queries/get_license_history.query.graphql';
import SubscriptionActivationCard from './subscription_activation_card.vue'; import SubscriptionActivationCard from './subscription_activation_card.vue';
import SubscriptionBreakdown from './subscription_breakdown.vue'; import SubscriptionBreakdown from './subscription_breakdown.vue';
import SubscriptionPurchaseCard from './subscription_purchase_card.vue'; import SubscriptionPurchaseCard from './subscription_purchase_card.vue';
...@@ -24,6 +28,7 @@ export default { ...@@ -24,6 +28,7 @@ export default {
components: { components: {
GlAlert, GlAlert,
GlButton, GlButton,
GlSprintf,
SubscriptionActivationCard, SubscriptionActivationCard,
SubscriptionBreakdown, SubscriptionBreakdown,
SubscriptionPurchaseCard, SubscriptionPurchaseCard,
...@@ -34,6 +39,8 @@ export default { ...@@ -34,6 +39,8 @@ export default {
exportLicenseUsageBtnText, exportLicenseUsageBtnText,
noActiveSubscription, noActiveSubscription,
subscriptionMainTitle, subscriptionMainTitle,
subscriptionHistoryFailedTitle,
subscriptionHistoryFailedMessage,
}, },
props: { props: {
licenseUsageFilePath: { licenseUsageFilePath: {
...@@ -48,15 +55,21 @@ export default { ...@@ -48,15 +55,21 @@ export default {
}, },
apollo: { apollo: {
currentSubscription: { currentSubscription: {
query: subscriptionQueries.query, query: getCurrentLicense,
update({ currentLicense }) { update({ currentLicense }) {
return currentLicense || {}; return currentLicense || {};
}, },
error() {
this.subscriptionFetchError = currentSubscriptionsEntryName;
},
}, },
subscriptionHistory: { subscriptionHistory: {
query: subscriptionHistoryQueries.query, query: getLicenseHistory,
update({ licenseHistoryEntries }) { update({ licenseHistoryEntries }) {
return licenseHistoryEntries.nodes || []; return licenseHistoryEntries?.nodes || [];
},
error() {
this.subscriptionFetchError = historySubscriptionsEntryName;
}, },
}, },
}, },
...@@ -65,6 +78,7 @@ export default { ...@@ -65,6 +78,7 @@ export default {
currentSubscription: {}, currentSubscription: {},
activationNotification: null, activationNotification: null,
subscriptionHistory: [], subscriptionHistory: [],
subscriptionFetchError: null,
}; };
}, },
computed: { computed: {
...@@ -96,6 +110,9 @@ export default { ...@@ -96,6 +110,9 @@ export default {
dismissActivationNotification() { dismissActivationNotification() {
this.activationNotification = null; this.activationNotification = null;
}, },
dismissSubscriptionFetchError() {
this.subscriptionFetchError = null;
},
}, },
}; };
</script> </script>
...@@ -121,6 +138,20 @@ export default { ...@@ -121,6 +138,20 @@ export default {
> >
{{ activationNotification.message }} {{ activationNotification.message }}
</gl-alert> </gl-alert>
<gl-alert
v-if="subscriptionFetchError"
:title="$options.i18n.subscriptionHistoryFailedTitle"
variant="danger"
class="gl-mb-6"
data-testid="subscription-fetch-error-alert"
@dismiss="dismissSubscriptionFetchError"
>
<gl-sprintf :message="$options.i18n.subscriptionHistoryFailedMessage">
<template #subscriptionEntryName>
{{ subscriptionFetchError }}
</template>
</gl-sprintf>
</gl-alert>
<subscription-breakdown <subscription-breakdown
v-if="canShowSubscriptionDetails" v-if="canShowSubscriptionDetails"
:subscription="currentSubscription" :subscription="currentSubscription"
......
...@@ -18,9 +18,9 @@ import { ...@@ -18,9 +18,9 @@ import {
SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT, SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT,
SUBSCRIPTION_ACTIVATION_FINALIZED_EVENT, SUBSCRIPTION_ACTIVATION_FINALIZED_EVENT,
subscriptionActivationForm, subscriptionActivationForm,
subscriptionQueries,
} from '../constants'; } from '../constants';
import { getErrorsAsData, getLicenseFromData, updateSubscriptionAppCache } from '../graphql/utils'; import { getErrorsAsData, getLicenseFromData, updateSubscriptionAppCache } from '../graphql/utils';
import activateSubscriptionMutation from '../graphql/mutations/activate_subscription.mutation.graphql';
const feedbackMap = { const feedbackMap = {
valueMissing: { valueMissing: {
...@@ -103,7 +103,7 @@ export default { ...@@ -103,7 +103,7 @@ export default {
this.isLoading = true; this.isLoading = true;
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: subscriptionQueries.mutation, mutation: activateSubscriptionMutation,
variables: { variables: {
gitlabSubscriptionActivateInput: { gitlabSubscriptionActivateInput: {
activationCode: this.form.fields.activationCode.value, activationCode: this.form.fields.activationCode.value,
......
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
import { PROMO_URL } from 'jh_else_ce/lib/utils/url_utility'; import { PROMO_URL } from 'jh_else_ce/lib/utils/url_utility';
import activateSubscriptionMutation from './graphql/mutations/activate_subscription.mutation.graphql';
import getCurrentLicense from './graphql/queries/get_current_license.query.graphql';
import getLicenseHistory from './graphql/queries/get_license_history.query.graphql';
export const subscriptionMainTitle = s__('SuperSonics|Your subscription'); export const subscriptionMainTitle = s__('SuperSonics|Your subscription');
export const subscriptionActivationNotificationText = s__( export const subscriptionActivationNotificationText = s__(
...@@ -20,6 +17,13 @@ export const subscriptionActivationInsertCode = __( ...@@ -20,6 +17,13 @@ export const subscriptionActivationInsertCode = __(
export const howToActivateSubscription = s__( export const howToActivateSubscription = s__(
'SuperSonics|Learn how to %{linkStart}activate your subscription%{linkEnd}.', 'SuperSonics|Learn how to %{linkStart}activate your subscription%{linkEnd}.',
); );
export const subscriptionHistoryFailedTitle = s__('SuperSonics|Subscription unavailable');
export const subscriptionHistoryFailedMessage = s__(
'SuperSonics|Your %{subscriptionEntryName} cannot be displayed at the moment. Please refresh the page to try again.',
);
export const currentSubscriptionsEntryName = s__('SuperSonics|current subscription');
export const historySubscriptionsEntryName = s__('SuperSonics|history subscriptions');
export const cancelLabel = __('Cancel'); export const cancelLabel = __('Cancel');
export const activateLabel = s__('AdminUsers|Activate'); export const activateLabel = s__('AdminUsers|Activate');
export const activateSubscription = s__('SuperSonics|Activate subscription'); export const activateSubscription = s__('SuperSonics|Activate subscription');
...@@ -39,7 +43,7 @@ export const detailsLabels = { ...@@ -39,7 +43,7 @@ export const detailsLabels = {
email: __('Email'), email: __('Email'),
id: __('ID'), id: __('ID'),
lastSync: __('Last Sync'), lastSync: __('Last Sync'),
name: __('Name'), name: licensedToHeaderText,
plan: __('Plan'), plan: __('Plan'),
expiresAt: __('Renews'), expiresAt: __('Renews'),
startsAt: __('Started'), startsAt: __('Started'),
...@@ -104,15 +108,6 @@ export const subscriptionTypes = { ...@@ -104,15 +108,6 @@ export const subscriptionTypes = {
LICENSE_FILE: 'license_file', LICENSE_FILE: 'license_file',
}; };
export const subscriptionQueries = {
query: getCurrentLicense,
mutation: activateSubscriptionMutation,
};
export const subscriptionHistoryQueries = {
query: getLicenseHistory,
};
export const trialCard = { export const trialCard = {
title: s__('SuperSonics|Free trial'), title: s__('SuperSonics|Free trial'),
description: s__( description: s__(
......
import produce from 'immer'; import produce from 'immer';
import { subscriptionHistoryQueries, subscriptionQueries } from '../constants'; import getCurrentLicense from './queries/get_current_license.query.graphql';
import getLicenseHistory from './queries/get_license_history.query.graphql';
export const getLicenseFromData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.license; export const getLicenseFromData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.license;
export const getErrorsAsData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.errors || []; export const getErrorsAsData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.errors || [];
...@@ -9,18 +10,16 @@ export const updateSubscriptionAppCache = (cache, mutation) => { ...@@ -9,18 +10,16 @@ export const updateSubscriptionAppCache = (cache, mutation) => {
if (!license) { if (!license) {
return; return;
} }
const { query } = subscriptionQueries;
const { query: historyQuery } = subscriptionHistoryQueries;
const data = produce({}, (draftData) => { const data = produce({}, (draftData) => {
draftData.currentLicense = license; draftData.currentLicense = license;
}); });
cache.writeQuery({ query, data }); cache.writeQuery({ query: getCurrentLicense, data });
const subscriptionsList = cache.readQuery({ query: historyQuery }); const subscriptionsList = cache.readQuery({ query: getLicenseHistory });
const subscriptionListData = produce(subscriptionsList, (draftData) => { const subscriptionListData = produce(subscriptionsList, (draftData) => {
draftData.licenseHistoryEntries.nodes = [ draftData.licenseHistoryEntries.nodes = [
license, license,
...subscriptionsList.licenseHistoryEntries.nodes, ...subscriptionsList.licenseHistoryEntries.nodes,
]; ];
}); });
cache.writeQuery({ query: historyQuery, data: subscriptionListData }); cache.writeQuery({ query: getLicenseHistory, data: subscriptionListData });
}; };
import { GlButton } from '@gitlab/ui'; import { GlButton, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import SubscriptionManagementApp from 'ee/admin/subscriptions/show/components/app.vue'; import SubscriptionManagementApp from 'ee/admin/subscriptions/show/components/app.vue';
import SubscriptionActivationCard from 'ee/admin/subscriptions/show/components/subscription_activation_card.vue'; import SubscriptionActivationCard from 'ee/admin/subscriptions/show/components/subscription_activation_card.vue';
import SubscriptionBreakdown from 'ee/admin/subscriptions/show/components/subscription_breakdown.vue'; import SubscriptionBreakdown from 'ee/admin/subscriptions/show/components/subscription_breakdown.vue';
import { import {
noActiveSubscription, noActiveSubscription,
subscriptionActivationNotificationText, subscriptionActivationNotificationText,
subscriptionActivationFutureDatedNotificationTitle, subscriptionActivationFutureDatedNotificationTitle,
subscriptionHistoryQueries, subscriptionHistoryFailedTitle,
subscriptionHistoryFailedMessage,
currentSubscriptionsEntryName,
historySubscriptionsEntryName,
subscriptionMainTitle, subscriptionMainTitle,
subscriptionQueries,
SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT, SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT,
} from 'ee/admin/subscriptions/show/constants'; } from 'ee/admin/subscriptions/show/constants';
import getCurrentLicense from 'ee/admin/subscriptions/show/graphql/queries/get_current_license.query.graphql';
import getLicenseHistory from 'ee/admin/subscriptions/show/graphql/queries/get_license_history.query.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import { useFakeDate } from 'helpers/fake_date'; import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { sprintf } from '~/locale';
import { license, subscriptionHistory } from '../mock_data'; import { license, subscriptionHistory } from '../mock_data';
Vue.use(VueApollo); Vue.use(VueApollo);
...@@ -35,6 +40,8 @@ describe('SubscriptionManagementApp', () => { ...@@ -35,6 +40,8 @@ describe('SubscriptionManagementApp', () => {
const findSubscriptionMainTitle = () => wrapper.findByTestId('subscription-main-title'); const findSubscriptionMainTitle = () => wrapper.findByTestId('subscription-main-title');
const findSubscriptionActivationSuccessAlert = () => const findSubscriptionActivationSuccessAlert = () =>
wrapper.findByTestId('subscription-activation-success-alert'); wrapper.findByTestId('subscription-activation-success-alert');
const findSubscriptionFetchErrorAlert = () =>
wrapper.findByTestId('subscription-fetch-error-alert');
const findExportLicenseUsageFileLink = () => wrapper.findComponent(GlButton); const findExportLicenseUsageFileLink = () => wrapper.findComponent(GlButton);
let currentSubscriptionResolver; let currentSubscriptionResolver;
...@@ -42,8 +49,8 @@ describe('SubscriptionManagementApp', () => { ...@@ -42,8 +49,8 @@ describe('SubscriptionManagementApp', () => {
const createMockApolloProvider = ([subscriptionResolver, historyResolver]) => { const createMockApolloProvider = ([subscriptionResolver, historyResolver]) => {
Vue.use(VueApollo); Vue.use(VueApollo);
return createMockApollo([ return createMockApollo([
[subscriptionQueries.query, subscriptionResolver], [getCurrentLicense, subscriptionResolver],
[subscriptionHistoryQueries.query, historyResolver], [getLicenseHistory, historyResolver],
]); ]);
}; };
...@@ -55,6 +62,9 @@ describe('SubscriptionManagementApp', () => { ...@@ -55,6 +62,9 @@ describe('SubscriptionManagementApp', () => {
licenseUsageFilePath: 'about:blank', licenseUsageFilePath: 'about:blank',
...props, ...props,
}, },
stubs: {
GlSprintf,
},
}), }),
); );
}; };
...@@ -63,6 +73,48 @@ describe('SubscriptionManagementApp', () => { ...@@ -63,6 +73,48 @@ describe('SubscriptionManagementApp', () => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('when failing to fetch subcriptions', () => {
describe('when failing to fetch history subcriptions', () => {
describe.each`
currentFails | historyFails
${true} | ${false}
${false} | ${true}
${true} | ${true}
`(
'with current subscription failing to fetch=$currentFails and history subscriptions failing to fetch=$historyFails',
({ currentFails, historyFails }) => {
const error = new Error('Network error!');
beforeEach(async () => {
currentSubscriptionResolver = currentFails
? jest.fn().mockRejectedValue({ error })
: jest.fn().mockResolvedValue({ data: { currentLicense: license.ULTIMATE } });
subscriptionHistoryResolver = historyFails
? jest.fn().mockRejectedValue({ error })
: jest.fn().mockResolvedValue({
data: { licenseHistoryEntries: { nodes: subscriptionHistory } },
});
createComponent({}, [currentSubscriptionResolver, subscriptionHistoryResolver]);
await waitForPromises();
});
it('renders the error alert', () => {
const alert = findSubscriptionFetchErrorAlert();
const subscriptionEntryName = historyFails
? historySubscriptionsEntryName
: currentSubscriptionsEntryName;
expect(alert.exists()).toBe(true);
expect(alert.props('title')).toBe(subscriptionHistoryFailedTitle);
expect(alert.text().replace(/\s+/g, ' ')).toBe(
sprintf(subscriptionHistoryFailedMessage, { subscriptionEntryName }),
);
});
},
);
});
});
describe('Subscription Activation Form', () => { describe('Subscription Activation Form', () => {
it('shows the main title', () => { it('shows the main title', () => {
currentSubscriptionResolver = jest currentSubscriptionResolver = jest
......
...@@ -9,9 +9,9 @@ import { ...@@ -9,9 +9,9 @@ import {
SUBSCRIPTION_ACTIVATION_FAILURE_EVENT, SUBSCRIPTION_ACTIVATION_FAILURE_EVENT,
SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT, SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT,
SUBSCRIPTION_ACTIVATION_FINALIZED_EVENT, SUBSCRIPTION_ACTIVATION_FINALIZED_EVENT,
subscriptionQueries,
subscriptionActivationForm, subscriptionActivationForm,
} from 'ee/admin/subscriptions/show/constants'; } from 'ee/admin/subscriptions/show/constants';
import activateSubscriptionMutation from 'ee/admin/subscriptions/show/graphql/mutations/activate_subscription.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import { stubComponent } from 'helpers/stub_component'; import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
...@@ -29,7 +29,7 @@ describe('SubscriptionActivationForm', () => { ...@@ -29,7 +29,7 @@ describe('SubscriptionActivationForm', () => {
let wrapper; let wrapper;
const createMockApolloProvider = (resolverMock) => { const createMockApolloProvider = (resolverMock) => {
return createMockApollo([[subscriptionQueries.mutation, resolverMock]]); return createMockApollo([[activateSubscriptionMutation, resolverMock]]);
}; };
const findActivateButton = () => wrapper.findByTestId('activate-button'); const findActivateButton = () => wrapper.findByTestId('activate-button');
......
...@@ -34681,6 +34681,9 @@ msgstr "" ...@@ -34681,6 +34681,9 @@ msgstr ""
msgid "SuperSonics|Subscription details" msgid "SuperSonics|Subscription details"
msgstr "" msgstr ""
msgid "SuperSonics|Subscription unavailable"
msgstr ""
msgid "SuperSonics|Sync subscription details" msgid "SuperSonics|Sync subscription details"
msgstr "" msgstr ""
...@@ -34735,6 +34738,9 @@ msgstr "" ...@@ -34735,6 +34738,9 @@ msgstr ""
msgid "SuperSonics|You'll be charged for %{trueUpLinkStart}users over license%{trueUpLinkEnd} on a quarterly or annual basis, depending on the terms of your agreement." msgid "SuperSonics|You'll be charged for %{trueUpLinkStart}users over license%{trueUpLinkEnd} on a quarterly or annual basis, depending on the terms of your agreement."
msgstr "" msgstr ""
msgid "SuperSonics|Your %{subscriptionEntryName} cannot be displayed at the moment. Please refresh the page to try again."
msgstr ""
msgid "SuperSonics|Your future dated license was successfully added" msgid "SuperSonics|Your future dated license was successfully added"
msgstr "" msgstr ""
...@@ -34747,6 +34753,12 @@ msgstr "" ...@@ -34747,6 +34753,12 @@ msgstr ""
msgid "SuperSonics|Your subscription was successfully activated. You can see the details below." msgid "SuperSonics|Your subscription was successfully activated. You can see the details below."
msgstr "" msgstr ""
msgid "SuperSonics|current subscription"
msgstr ""
msgid "SuperSonics|history subscriptions"
msgstr ""
msgid "Support" msgid "Support"
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