Commit f99110a2 authored by Michael Lunøe's avatar Michael Lunøe Committed by Olena Horal-Koretska

Feat(Purchase Flow): local resolver for step state

parent e8906a60
mutation updateActiveStep($id: String) {
updateActiveStep(id: $id) @client
}
import produce from 'immer';
import activeStepQuery from './queries/active_step.query.graphql';
import stepListQuery from './queries/step_list.query.graphql';
function updateActiveStep(_, { id }, { cache }) {
const sourceData = cache.readQuery({ query: activeStepQuery });
const { stepList } = cache.readQuery({ query: stepListQuery });
const activeStep = stepList.find((step) => step.id === id);
const data = produce(sourceData, (draftData) => {
draftData.activeStep = {
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Step',
id: activeStep.id,
};
});
return cache.writeQuery({ query: activeStepQuery, data });
}
function activateNextStep(parent, _, { cache }) {
const sourceData = cache.readQuery({ query: activeStepQuery });
const { stepList } = cache.readQuery({ query: stepListQuery });
const index = stepList.findIndex((step) => step.id === sourceData.activeStep.id);
const activeStep = stepList[index + 1];
const data = produce(sourceData, (draftData) => {
draftData.activeStep = {
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Step',
id: activeStep.id,
};
});
return cache.writeQuery({ query: activeStepQuery, data });
}
export default {
Mutation: {
updateActiveStep,
activateNextStep,
},
};
type Step {
id: ID
}
extend type Query {
activeStep: Step
}
extend type Query {
stepList: [Step]
}
extend type Mutation {
updateActiveStep(id: ID!): Boolean
}
import { createMockClient } from 'mock-apollo-client';
import activateNextStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/activate_next_step.mutation.graphql';
import updateStepMutation from 'ee/vue_shared/purchase_flow/graphql/mutations/update_active_step.mutation.graphql';
import activeStepQuery from 'ee/vue_shared/purchase_flow/graphql/queries/active_step.query.graphql';
import stepListQuery from 'ee/vue_shared/purchase_flow/graphql/queries/step_list.query.graphql';
import resolvers from 'ee/vue_shared/purchase_flow/graphql/resolvers';
import typeDefs from 'ee/vue_shared/purchase_flow/graphql/typedefs.graphql';
import { STEPS } from '../mock_data';
describe('ee/vue_shared/purchase_flow/graphql/resolvers', () => {
let mockClient;
beforeEach(async () => {
mockClient = createMockClient({ resolvers, typeDefs });
mockClient.cache.writeQuery({
query: stepListQuery,
data: {
stepList: STEPS,
},
});
mockClient.cache.writeQuery({
query: activeStepQuery,
data: {
activeStep: STEPS[0],
},
});
});
describe('Query', () => {
describe('stepListQuery', () => {
it('stores the stepList', async () => {
const queryResult = await mockClient.query({ query: stepListQuery });
expect(queryResult.data.stepList).toMatchObject(
STEPS.map(({ id }) => {
return { id };
}),
);
});
it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore();
await mockClient.query({ query: stepListQuery }).catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
});
describe('activeStepQuery', () => {
it('stores the activeStep', async () => {
const queryResult = await mockClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[0].id });
});
it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore();
await mockClient.query({ query: activeStepQuery }).catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
});
});
describe('Mutation', () => {
describe('updateActiveStep', () => {
it('updates the active step', async () => {
await mockClient.mutate({
mutation: updateStepMutation,
variables: { id: STEPS[1].id },
});
const queryResult = await mockClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id });
});
it('throws an error when STEP is not present', async () => {
const id = 'does not exist';
await mockClient
.mutate({
mutation: updateStepMutation,
variables: { id },
})
.catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore();
await mockClient
.mutate({
mutation: updateStepMutation,
variables: { id: STEPS[1].id },
})
.catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
});
describe('activateNextStep', () => {
it('updates the active step to the next', async () => {
await mockClient.mutate({
mutation: activateNextStepMutation,
});
const queryResult = await mockClient.query({ query: activeStepQuery });
expect(queryResult.data.activeStep).toMatchObject({ id: STEPS[1].id });
});
it('throws an error when out of bounds', async () => {
await mockClient.mutate({
mutation: activateNextStepMutation,
});
await mockClient
.mutate({
mutation: activateNextStepMutation,
})
.catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
it('throws an error when cache is not initiated properly', async () => {
mockClient.clearStore();
await mockClient
.mutate({
mutation: activateNextStepMutation,
})
.catch((e) => {
expect(e instanceof Error).toBe(true);
});
});
});
});
});
export const STEPS = [
{ __typename: 'Step', id: 'firstStep' },
{ __typename: 'Step', id: 'secondStep' },
];
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