Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create module tests #1303

Merged
merged 55 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
9017a64
feat(xcontrols): add skeleton (#1278)
mgg709 Sep 13, 2023
02f6f2d
feat(xcontrols): add store module (#1285)
AnaOstio Sep 15, 2023
6534e8f
feat(xcontrols): add actions (#1288)
mgg709 Sep 20, 2023
b52ff8c
feat(xcontrols): add emitter (#1290)
mgg709 Sep 20, 2023
3844630
feat(xcontrols): add experience-controls component (#1297)
AnaOstio Sep 22, 2023
39c73f6
test: test mutations
annacv Sep 25, 2023
62fddd9
feat(experience-controls): tests for the experience-controls componen…
CachedaCodes Sep 26, 2023
7516213
feat: add status mutations to module
annacv Sep 26, 2023
00e5684
test: add fetchMock util + actions test
annacv Sep 26, 2023
13a7269
test: add fetchMock util + actions test
annacv Sep 26, 2023
4ebbaab
feat(xcontrols): add request mapper (#1300)
mgg709 Sep 27, 2023
47c23fa
test: PR comments
annacv Sep 27, 2023
ce7af6f
feat(xcontrols): create response mapper (#1305)
AnaOstio Sep 28, 2023
67653dd
Merge branch 'feature/EMP-1944-create-config-module-xcontrols' of htt…
annacv Sep 29, 2023
2fd6e72
Merge branch 'feature/EMP-1939-create-endpoint-adapter' of https://gi…
annacv Sep 29, 2023
85fde5d
test: PR comments
annacv Oct 2, 2023
347a135
feat(xcontrols): update the xperience-controls module with adapter (#…
AnaOstio Oct 3, 2023
068146f
Merge remote-tracking branch 'origin/main' into feature/EMP-1939-crea…
CachedaCodes Oct 3, 2023
53c0a4f
install missing deps for `x-types`
diegopf Oct 3, 2023
d9ceae5
export `PlatformExperienceControlsRequest`
diegopf Oct 3, 2023
13b9d67
remove unnecessary eslint-disable comment
diegopf Oct 3, 2023
2278faf
refactor `ExperienceControlsRequestMapper` comment
diegopf Oct 3, 2023
5189842
use `ExperienceControlsResponse` type for experienceControlsEndpointA…
diegopf Oct 3, 2023
408c798
change default endpoint for experienceControlsEndpointAdapter
diegopf Oct 3, 2023
9703847
add test for experienceControlsEndpointAdapter
diegopf Oct 3, 2023
173cf6d
extend experienceControlsAdapter to point to test
diegopf Oct 3, 2023
ccc2143
update branch
annacv Oct 3, 2023
feb8138
chore: update import
annacv Oct 3, 2023
168dd72
skip test
diegopf Oct 3, 2023
566e1f8
enable test again
diegopf Oct 3, 2023
966d21f
chore: change object assign to vue set
CachedaCodes Oct 3, 2023
e574c4f
skip test again
CachedaCodes Oct 4, 2023
ef75c33
restore test
CachedaCodes Oct 4, 2023
6d4246f
remove tests from svg package scripts
CachedaCodes Oct 4, 2023
b070a52
Merge branch 'feature/EMP-1939-create-endpoint-adapter' of https://gi…
annacv Oct 4, 2023
1c0ea5e
feat: WIP update tests using Xcontrols adapter
annacv Oct 4, 2023
52614e4
feat: update store Xcontrols util
annacv Oct 5, 2023
c8ee72f
feat: add cancelFetchAndSaveControls in the module actions & types
annacv Oct 5, 2023
3f9e379
test: update tests
annacv Oct 5, 2023
c97e3c4
test: create XControls stub
annacv Oct 5, 2023
2bc91f4
test: add & update tests
annacv Oct 5, 2023
a74248a
chore: rm comment
annacv Oct 5, 2023
41de164
update branch
annacv Oct 5, 2023
5ad9857
feat: add release tag in actions types
annacv Oct 5, 2023
7fa1f35
feat: add getter test
annacv Oct 5, 2023
c4f36d5
Update packages/x-components/src/x-modules/experience-controls/store/…
annacv Oct 9, 2023
33b80f0
Update packages/x-components/src/x-modules/experience-controls/store/…
annacv Oct 9, 2023
0a6ec50
Update packages/x-components/src/x-modules/experience-controls/store/…
annacv Oct 9, 2023
1ccc932
chore: PR changes
annacv Oct 9, 2023
8cc9431
chore: PR changes
annacv Oct 9, 2023
eaf1521
Update packages/x-components/src/x-modules/experience-controls/store/…
annacv Oct 10, 2023
766ffee
Update packages/x-components/src/x-modules/experience-controls/store/…
annacv Oct 10, 2023
c203485
chore: Rollback pnpm-lock.yaml file changes
annacv Oct 10, 2023
c2b8cbe
chore: fix imports
annacv Oct 10, 2023
3cc085d
chore: rm mutations tests
annacv Oct 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ExperienceControlsResponse } from '@empathyco/x-types';

/**
* Creates a {@link @empathyco/x-types#ExperienceControlsResponse |
annacv marked this conversation as resolved.
Show resolved Hide resolved
* experience controls response} stub.
*
* @returns An experience controls stub.
*
* @internal
*/
export function getExperienceControlsStub(): ExperienceControlsResponse {
return createExperienceControlsStub();
}

/**
* Creates an experience controls response.
*
* @returns An experience controls response.
*/
export function createExperienceControlsStub(): ExperienceControlsResponse {
return {
controls: { numberOfCarousels: 10, resultsPerCarousels: 21 },
events: { ColumnsNumberProvided: 6 }
};
}
28 changes: 27 additions & 1 deletion packages/x-components/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ function mergeStates<State extends Dictionary>(
}

/**
* Makes a clean install of the's the {@link XPlugin} into the passed Vue object.
* Makes a clean install of the {@link XPlugin} into the passed Vue object.
* This also resets the bus, and all the hardcoded dependencies of the XPlugin.
*
* @param options - The options for installing the {@link XPlugin}. The
Expand Down Expand Up @@ -221,3 +221,29 @@ export function createXModule<
): XModule<XStoreModule<State, Getters, Mutations, Actions>> {
return xModule;
}

/**
* Mocks a `fetch` API call.
*
* @param response - The expected response resolved by calling `fetch()`.
* @returns A Promise object.
*
* @internal
*/
export function getFetchMock(
response: unknown
): (url: string, params: RequestInit) => Promise<Response> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return _url => {
Copy link
Contributor Author

@annacv annacv Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 Signal not included here as it threw an error.

return new Promise<Response>(resolve => {
setTimeout(() => {
resolve({
ok: true,
status: 200,
json: () => Promise.resolve(response),
text: () => Promise.resolve(JSON.stringify(response))
} as Response);
});
});
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { mount, Wrapper } from '@vue/test-utils';
import Vue from 'vue';
import { XPlugin } from '../../../../plugins/index';
import { installNewXPlugin } from '../../../../__tests__/utils';
import { experienceControlsXModule } from '../../x-module';
import { getXComponentXModuleName, isXComponent } from '../../../../components/index';
import ExperienceControls from '../experience-controls.vue';

function renderExperienceControls(): RenderExperienceControlsApi {
XPlugin.resetInstance();
annacv marked this conversation as resolved.
Show resolved Hide resolved
const [, localVue] = installNewXPlugin();
XPlugin.registerXModule(experienceControlsXModule);

const wrapper = mount(ExperienceControls, {
localVue
});

return {
wrapper
};
}

describe('testing experience controls component', () => {
it('is an XComponent which has an XModule', () => {
const { wrapper } = renderExperienceControls();
expect(isXComponent(wrapper.vm)).toEqual(true);
expect(getXComponentXModuleName(wrapper.vm)).toEqual('experienceControls');
});

// eslint-disable-next-line max-len
it('listens to the event ExperienceControlsEventsChanged and emits the events on the payload', () => {
const { wrapper } = renderExperienceControls();

const eventsFromExperienceControls = {
ExtraParamsProvided: {
warehouse: 'Magrathea'
},
SortChanged: 'price:desc'
};

const extraParamsProvidedListener = jest.fn();
wrapper.vm.$x.on('ExtraParamsProvided').subscribe(extraParamsProvidedListener);

const sortChangedListener = jest.fn();
wrapper.vm.$x.on('SortChanged').subscribe(sortChangedListener);

wrapper.vm.$x.emit('ExperienceControlsEventsChanged', eventsFromExperienceControls);

expect(extraParamsProvidedListener).toHaveBeenCalledTimes(1);
expect(extraParamsProvidedListener).toHaveBeenCalledWith({
warehouse: 'Magrathea'
});

expect(sortChangedListener).toHaveBeenCalledTimes(1);
expect(sortChangedListener).toHaveBeenCalledWith('price:desc');
});
});

interface RenderExperienceControlsApi {
/** The wrapper for the experience controls component. */
wrapper: Wrapper<Vue>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import Vuex from 'vuex';
import { createLocalVue } from '@vue/test-utils';
import { getMockedAdapter, installNewXPlugin } from '../../../../__tests__/utils';
import { getExperienceControlsStub } from '../../../../__stubs__/experience-controls-subs.factory';
import { createExperienceControlsStore, resetExperienceControlsStateWith } from './utils';

describe('testing experience controls module actions', () => {
const mockedResponse = getExperienceControlsStub();

const adapter = getMockedAdapter({
experienceControls: mockedResponse
});

const localVue = createLocalVue();
localVue.config.productionTip = false; // Silent production console messages.
localVue.use(Vuex);
const store = createExperienceControlsStore();
annacv marked this conversation as resolved.
Show resolved Hide resolved
installNewXPlugin({ adapter, store }, localVue);

beforeEach(() => {
resetExperienceControlsStateWith(store);
});

describe('fetchControls', () => {
it('should return controls', async () => {
annacv marked this conversation as resolved.
Show resolved Hide resolved
const experienceControls = await store.dispatch(
'fetchExperienceControlsResponse',
store.getters.experienceControlsRequest
);
expect(experienceControls).toEqual(mockedResponse);
});
});

describe('fetchAndSaveControls', () => {
it('should request and store controls and events in the state', async () => {
resetExperienceControlsStateWith(store, {});
annacv marked this conversation as resolved.
Show resolved Hide resolved

const actionPromise = store.dispatch(
'fetchAndSaveExperienceControlsResponse',
store.getters.experienceControlsRequest
);
expect(store.state.status).toEqual('loading');
await actionPromise;

expect(store.state.controls).toEqual(mockedResponse.controls);
expect(store.state.events).toEqual(mockedResponse.events);
expect(store.state.status).toEqual('success');
});

it('should cancel the previous request if it is not yet resolved', async () => {
const initialExperienceControls = store.state.controls;
adapter.experienceControls.mockResolvedValueOnce(mockedResponse);

const firstRequest = store.dispatch(
'fetchAndSaveExperienceControlsResponse',
store.getters.experienceControlsRequest
);
const secondRequest = store.dispatch(
'fetchAndSaveExperienceControlsResponse',
store.getters.experienceControlsRequest
);

await firstRequest;
expect(store.state.status).toEqual('loading');
expect(store.state.controls).toBe(initialExperienceControls);
await secondRequest;
expect(store.state.status).toEqual('success');
expect(store.state.controls).toEqual(mockedResponse.controls);
});
});

describe('cancelFetchAndSaveControls', () => {
it('should cancel the request and do not modify the stored controls', async () => {
resetExperienceControlsStateWith(store, {
controls: { numberOfCarousels: 20, resultsPerCarousels: 6 }
});
const previousControls = store.state.controls;
await Promise.all([
store.dispatch(
'fetchAndSaveExperienceControlsResponse',
store.getters.experienceControlsRequest
),
store.dispatch('cancelFetchAndSaveControls')
]);
expect(store.state.controls).toEqual(previousControls);
expect(store.state.status).toEqual('success');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ExperienceControlsRequest } from '@empathyco/x-types';
import { createExperienceControlsStore, resetExperienceControlsStateWith } from './utils';

describe('testing experience controls module getters', () => {
const store = createExperienceControlsStore();
annacv marked this conversation as resolved.
Show resolved Hide resolved

beforeEach(() => {
resetExperienceControlsStateWith(store);
});

describe(`request getter`, () => {
it('should return a request object', () => {
resetExperienceControlsStateWith(store, {
params: {
store: 'es'
}
});

expect(store.getters.experienceControlsRequest).toEqual<ExperienceControlsRequest>({
extraParams: {
store: 'es'
}
});
});
});
});
annacv marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Dictionary } from '@empathyco/x-utils';
import { XEventsTypes } from '../../../../wiring/index';
import { createExperienceControlsStore } from './utils';

describe('testing experience controls module mutations', () => {
const store = createExperienceControlsStore();

describe('setControls', () => {
it('should update the state with the new controls', () => {
const controls: Dictionary<unknown> = {
numberOfCarousels: 10,
resultsPerCarousels: 21
};
store.commit('setControls', controls);

expect(store.state.controls).toEqual<Dictionary<unknown>>({
numberOfCarousels: 10,
resultsPerCarousels: 21
});
});
});

describe('setEvents', () => {
it('should update the state with the new events', () => {
const events: Partial<XEventsTypes> = {
UserAcceptedAQuery: 'sandal',
ColumnsNumberProvided: 6
};
store.commit('setEvents', events);

expect(store.state.events).toEqual<Partial<XEventsTypes>>({
UserAcceptedAQuery: 'sandal',
ColumnsNumberProvided: 6
});
});
});

describe('setParams', () => {
it('should update the state with the new parameters', () => {
const params: Dictionary<unknown> = {
section: 'kids',
store: 'Gijón',
season: 'autum'
};
store.commit('setParams', params);

expect(store.state.params).toEqual<Partial<Dictionary<unknown>>>({
section: 'kids',
store: 'Gijón',
season: 'autum'
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { DeepPartial } from '@empathyco/x-utils';
import Vuex, { Store } from 'vuex';
import { createLocalVue } from '@vue/test-utils';
import { resetStoreModuleState } from '../../../../__tests__/utils';
import { experienceControlsXStoreModule } from '../module';
import {
ExperienceControlsActions,
ExperienceControlsGetters,
ExperienceControlsMutations,
ExperienceControlsState
} from '../types';
import { SafeStore } from '../../../../store/__tests__/utils';

/**
* Resets the experience controls module state, optionally modifying its default values.
*
* @param store - Experience controls store state.
* @param state - Partial experience controls store state to replace the original one.
*
* @internal
*/
export function resetExperienceControlsStateWith(
store: Store<ExperienceControlsState>,
state?: DeepPartial<ExperienceControlsState>
): void {
resetStoreModuleState(store, experienceControlsXStoreModule.state(), state);
}

/**
* Creates an experience controls store with the state passed as parameter.
*
* @param state - Partial experience controls store state to replace the original one.
annacv marked this conversation as resolved.
Show resolved Hide resolved
* @returns Store - The new store created.
*
* @internal
*/
export function createExperienceControlsStore(): Store<ExperienceControlsState> {
const localVue = createLocalVue();
localVue.config.productionTip = false; // Silent production console messages.
localVue.use(Vuex);

const store: SafeStore<
ExperienceControlsState,
ExperienceControlsGetters,
ExperienceControlsMutations,
ExperienceControlsActions
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
> = new Store(experienceControlsXStoreModule as any);

return store;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* eslint-disable max-len */
import Vue from 'vue';
import { setStatus } from '../../../store/utils/status-store.utils';
import { fetchAndSaveExperienceControlsResponse } from './actions/fetch-and-save-experience-controls.action';
import {
cancelFetchAndSaveControls,
fetchAndSaveExperienceControlsResponse
} from './actions/fetch-and-save-experience-controls.action';
import { fetchExperienceControlsResponse } from './actions/fetch-experience-controls.action';
import { experienceControlsRequest } from './getters/experience-controls-results-request.getter';
import { ExperienceControlsXStoreModule } from './types';
Expand Down Expand Up @@ -36,6 +39,7 @@ export const experienceControlsXStoreModule: ExperienceControlsXStoreModule = {
},
actions: {
fetchExperienceControlsResponse,
fetchAndSaveExperienceControlsResponse
fetchAndSaveExperienceControlsResponse,
cancelFetchAndSaveControls
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export interface ExperienceControlsActions {
* @param request - The request to fetch the experience controls.
*/
fetchAndSaveExperienceControlsResponse(request: ExperienceControlsRequest | null): void;

/**
* Cancels the {@link ExperienceControlsActions. fetchAndSaveExperienceControlsResponse}.
annacv marked this conversation as resolved.
Show resolved Hide resolved
*/
cancelFetchAndSaveControls: () => void;
}

/**
Expand Down
Loading