Commit 65f3749c authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'vs-gql-local-resolver-buy-ci-minutes' into 'master'

Implement local GraphQL resolver for buying CI minutes

See merge request gitlab-org/gitlab!56963
parents 00e27eca 60c8b2f8
import { buildApiUrl } from '~/api/api_utils';
import axios from '~/lib/utils/axios_utils';
const SUBSCRIPTIONS_PATH = '/api/:version/subscriptions';
export function createSubscription(groupId, customer, subscription) {
const url = buildApiUrl(SUBSCRIPTIONS_PATH);
const params = {
selectedGroup: groupId,
customer,
subscription,
};
return axios.post(url, { params });
}
export * from './api/groups_api'; export * from './api/groups_api';
export * from './api/subscriptions_api';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import { resolvers } from './graphql/resolvers';
Vue.use(VueApollo);
const defaultClient = createDefaultClient(resolvers, { assumeImmutableResults: true });
export default new VueApollo({
defaultClient,
});
query seed {
seed @client {
plans
namespaces
newUser
fullName
setupForCompany
}
}
import * as SubscriptionsApi from 'ee/api/subscriptions_api';
// NOTE: These resolvers are temporary and will be removed in the future.
// See https://gitlab.com/gitlab-org/gitlab/-/issues/321643
export const resolvers = {
Mutation: {
purchaseMinutes: (_, { groupId, customer, subscription }) => {
return SubscriptionsApi.createSubscription(groupId, customer, subscription);
},
},
};
import Vue from 'vue'; import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import App from './components/app.vue'; import App from './components/app.vue';
import apolloProvider from './graphql';
import seedQuery from './graphql/queries/seed.query.graphql';
const arrayToGraphqlArray = (arr, typename) =>
Array.from(arr, (item) => Object.assign(item, { __typename: typename }));
const writeInitialDataToApolloProvider = (dataset) => {
const { newUser, fullName, setupForCompany } = dataset;
apolloProvider.clients.defaultClient.cache.writeQuery({
query: seedQuery,
data: {
// eslint-disable-next-line @gitlab/require-i18n-strings
plans: arrayToGraphqlArray(JSON.parse(dataset.ciMinutesPlans), 'Plan'),
// eslint-disable-next-line @gitlab/require-i18n-strings
namespaces: arrayToGraphqlArray(JSON.parse(dataset.groupData), 'Namespace'),
newUser: parseBoolean(newUser),
setupForCompany: parseBoolean(setupForCompany),
fullName,
},
});
};
export default () => { export default () => {
const el = document.getElementById('js-buy-minutes'); const el = document.getElementById('js-buy-minutes');
writeInitialDataToApolloProvider(el.dataset);
return new Vue({ return new Vue({
el, el,
components: { apolloProvider,
App,
},
render(createElement) { render(createElement) {
return createElement(App); return createElement(App);
}, },
......
import * as SubscriptionsApi from 'ee/api/subscriptions_api';
import { resolvers } from 'ee/subscriptions/buy_minutes/graphql/resolvers';
jest.mock('ee/api/subscriptions_api', () => {
return {
createSubscription: jest.fn(),
};
});
describe('~/subscriptions/buy_minutes/graphql/resolvers', () => {
const customer = {
country: 'NL',
address_1: 'Address line 1',
address_2: 'Address line 2',
city: 'City',
state: 'State',
zip_code: 'Zip code',
company: 'My organization',
};
const subscription = {
plan_id: 'abc',
payment_method_id: 'payment_method_id',
products: {
main: {
quantity: 1,
},
},
gl_namespace_id: 1,
gl_namespace_name: 'test',
preview: 'false',
};
describe('Mutation', () => {
it('calls the REST api', async () => {
const expectedArgs = { groupId: 1, customer, subscription };
await resolvers.Mutation.purchaseMinutes(null, expectedArgs);
expect(SubscriptionsApi.createSubscription).toHaveBeenCalledWith(1, customer, subscription);
});
describe('on error', () => {
beforeAll(() => {
SubscriptionsApi.createSubscription.mockResolvedValue({ errors: [1] });
});
it('returns an error array', async () => {
const result = await resolvers.Mutation.purchaseMinutes(null, {
groupId: 1,
customer,
subscription,
});
expect(result).toEqual({ errors: [1] });
});
});
describe('on success', () => {
beforeAll(() => {
SubscriptionsApi.createSubscription.mockResolvedValue({ data: '/foo' });
});
it('returns a redirect location', async () => {
const result = await resolvers.Mutation.purchaseMinutes(null, {
groupId: 1,
customer,
subscription,
});
expect(result).toEqual({ data: '/foo' });
});
});
});
});
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