Commit 800ddce8 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch...

Merge branch '352092-mlunoe-self-managed-subscription-refresh-local-state-upon-license-submit' into 'master'

Fix(SM: Subscription): Refresh local state

See merge request gitlab-org/gitlab!80482
parents cf9fc53c b40b5a91
......@@ -121,6 +121,9 @@ export default {
} else {
this.activationNotification = { title: subscriptionActivationNotificationText };
}
this.$apollo.queries.currentSubscription.refetch();
this.$apollo.queries.pastLicenseHistoryEntries.refetch();
this.$apollo.queries.futureLicenseHistoryEntries.refetch();
},
dismissActivationNotification() {
this.activationNotification = null;
......
......@@ -19,7 +19,7 @@ import {
SUBSCRIPTION_ACTIVATION_FINALIZED_EVENT,
subscriptionActivationForm,
} from '../constants';
import { getErrorsAsData, getLicenseFromData, updateSubscriptionAppCache } from '../graphql/utils';
import { getErrorsAsData, getLicenseFromData } from '../graphql/utils';
import activateSubscriptionMutation from '../graphql/mutations/activate_subscription.mutation.graphql';
const feedbackMap = {
......@@ -124,7 +124,6 @@ export default {
if (license) {
this.$emit(SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT, license);
}
this.updateSubscriptionAppCache(cache, res);
},
})
.catch((error) => {
......@@ -135,7 +134,6 @@ export default {
this.isLoading = false;
});
},
updateSubscriptionAppCache,
},
};
</script>
......
import produce from 'immer';
import getCurrentLicense from './queries/get_current_license.query.graphql';
import getPastLicenseHistory from './queries/get_past_license_history.query.graphql';
export const getLicenseFromData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.license;
export const getErrorsAsData = ({ data } = {}) => data?.gitlabSubscriptionActivate?.errors || [];
export const updateSubscriptionAppCache = (cache, mutation) => {
const license = getLicenseFromData(mutation);
if (!license) {
return;
}
const data = produce({}, (draftData) => {
draftData.currentLicense = license;
});
cache.writeQuery({ query: getCurrentLicense, data });
const pastSubscriptions = cache.readQuery({ query: getPastLicenseHistory });
const pastSubscriptionsData = produce(pastSubscriptions, (draftData) => {
draftData.licenseHistoryEntries.nodes = [
license,
...pastSubscriptions.licenseHistoryEntries.nodes,
];
});
cache.writeQuery({ query: getPastLicenseHistory, data: pastSubscriptionsData });
};
......@@ -33,6 +33,14 @@ RSpec.describe 'Admin views Subscription', :js do
end
end
shared_examples 'no active license' do
it 'displays a message signaling there is not active subscription' do
page.within(find('#content-body', match: :first)) do
expect(page).to have_content('You do not have an active subscription')
end
end
end
context 'with a cloud license' do
let!(:license) { create_current_license(cloud_licensing_enabled: true, plan: License::ULTIMATE_PLAN) }
......@@ -119,19 +127,15 @@ RSpec.describe 'Admin views Subscription', :js do
end
context 'with no active subscription' do
let_it_be(:license) { nil }
let_it_be(:license_to_be_created) { nil }
before do
allow(License).to receive(:current).and_return(license)
License.current.destroy!
visit(admin_subscription_path)
end
it 'displays a message signaling there is not active subscription' do
page.within(find('#content-body', match: :first)) do
expect(page).to have_content('You do not have an active subscription')
end
end
it_behaves_like 'no active license'
it 'does not display the Export License Usage File button' do
expect(page).not_to have_link('Export license usage file', href: admin_license_usage_export_path(format: :csv))
......@@ -144,8 +148,9 @@ RSpec.describe 'Admin views Subscription', :js do
"data": {
"cloudActivationActivate": {
"errors": ["invalid activation code"],
"license": nil
}
"license": license_to_be_created
},
"success": "true"
}
}.to_json, headers: { 'Content-Type' => 'application/json' })
......@@ -160,9 +165,9 @@ RSpec.describe 'Admin views Subscription', :js do
end
context 'when activating a future-dated subscription' do
before do
license_to_be_created = create(:license, data: create(:gitlab_license, { starts_at: Date.today + 1.month, cloud_licensing_enabled: true, plan: License::ULTIMATE_PLAN }).export)
let_it_be(:license_to_be_created) { build(:license, data: build(:gitlab_license, { starts_at: Date.current + 1.month, cloud_licensing_enabled: true, plan: License::ULTIMATE_PLAN }).export) }
before do
stub_request(:post, EE::SUBSCRIPTIONS_GRAPHQL_URL)
.to_return(status: 200, body: {
"data": {
......@@ -180,12 +185,14 @@ RSpec.describe 'Admin views Subscription', :js do
it 'shows a successful future-dated activation message' do
expect(page).to have_content('Your future dated license was successfully added')
end
it_behaves_like 'no active license'
end
context 'when activating a new subscription' do
before do
license_to_be_created = create(:license, data: create(:gitlab_license, { starts_at: Date.today, cloud_licensing_enabled: true, plan: License::ULTIMATE_PLAN }).export)
let_it_be(:license_to_be_created) { build(:license, data: build(:gitlab_license, { starts_at: Date.current, cloud_licensing_enabled: true, plan: License::ULTIMATE_PLAN }).export) }
before do
stub_request(:post, EE::SUBSCRIPTIONS_GRAPHQL_URL)
.to_return(status: 200, body: {
"data": {
......
......@@ -241,6 +241,15 @@ describe('SubscriptionManagementApp', () => {
pastSubscriptionsResolver,
futureSubscriptionsResolver,
]);
jest
.spyOn(wrapper.vm.$apollo.queries.currentSubscription, 'refetch')
.mockImplementation(jest.fn());
jest
.spyOn(wrapper.vm.$apollo.queries.pastLicenseHistoryEntries, 'refetch')
.mockImplementation(jest.fn());
jest
.spyOn(wrapper.vm.$apollo.queries.futureLicenseHistoryEntries, 'refetch')
.mockImplementation(jest.fn());
await waitForPromises();
});
......@@ -270,6 +279,20 @@ describe('SubscriptionManagementApp', () => {
subscriptionActivationFutureDatedNotificationTitle,
);
});
it('calls refetch to update local state', async () => {
await findSubscriptionBreakdown().vm.$emit(
SUBSCRIPTION_ACTIVATION_SUCCESS_EVENT,
license.ULTIMATE_FUTURE_DATED,
);
expect(wrapper.vm.$apollo.queries.currentSubscription.refetch).toHaveBeenCalledTimes(1);
expect(wrapper.vm.$apollo.queries.pastLicenseHistoryEntries.refetch).toHaveBeenCalledTimes(
1,
);
expect(
wrapper.vm.$apollo.queries.futureLicenseHistoryEntries.refetch,
).toHaveBeenCalledTimes(1);
});
});
describe('with active license', () => {
......
......@@ -178,7 +178,6 @@ describe('SubscriptionActivationForm', () => {
const mutationMock = jest.fn().mockResolvedValue(activateLicenseMutationResponse.SUCCESS);
beforeEach(async () => {
createComponentWithApollo({ mutationMock, mountMethod: mount });
jest.spyOn(wrapper.vm, 'updateSubscriptionAppCache').mockImplementation();
await findActivationCodeInput().vm.$emit('input', fakeActivationCode);
await findAgreementCheckboxInput().trigger('click');
findActivateSubscriptionForm().vm.$emit('submit', createFakeEvent());
......@@ -201,10 +200,6 @@ describe('SubscriptionActivationForm', () => {
[activateLicenseMutationResponse.SUCCESS.data.gitlabSubscriptionActivate.license],
]);
});
it('calls the method to update the cache', () => {
expect(wrapper.vm.updateSubscriptionAppCache).toHaveBeenCalledTimes(1);
});
});
describe('when the mutation is not successful', () => {
......
import {
getErrorsAsData,
getLicenseFromData,
updateSubscriptionAppCache,
} from 'ee/admin/subscriptions/show/graphql/utils';
import { activateLicenseMutationResponse } from '../mock_data';
import { getErrorsAsData, getLicenseFromData } from 'ee/admin/subscriptions/show/graphql/utils';
describe('graphQl utils', () => {
describe('getLicenseFromData', () => {
......@@ -63,46 +58,4 @@ describe('graphQl utils', () => {
expect(result).toEqual([]);
});
});
describe('updateSubscriptionAppCache', () => {
const cache = {
readQuery: jest.fn(() => ({ licenseHistoryEntries: { nodes: [] } })),
writeQuery: jest.fn(),
};
it('calls writeQuery the correct number of times', () => {
updateSubscriptionAppCache(cache, activateLicenseMutationResponse.SUCCESS);
expect(cache.writeQuery).toHaveBeenCalledTimes(2);
});
it('calls writeQuery the first time to update the current subscription', () => {
updateSubscriptionAppCache(cache, activateLicenseMutationResponse.SUCCESS);
expect(cache.writeQuery.mock.calls[0][0]).toEqual(
expect.objectContaining({
data: {
currentLicense:
activateLicenseMutationResponse.SUCCESS.data.gitlabSubscriptionActivate.license,
},
}),
);
});
it('calls writeQuery the second time to update the subscription history', () => {
updateSubscriptionAppCache(cache, activateLicenseMutationResponse.SUCCESS);
expect(cache.writeQuery.mock.calls[1][0]).toEqual(
expect.objectContaining({
data: {
licenseHistoryEntries: {
nodes: [
activateLicenseMutationResponse.SUCCESS.data.gitlabSubscriptionActivate.license,
],
},
},
}),
);
});
});
});
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