Skip to content

Commit

Permalink
refactor: migrate preselected filters component (#1422)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Guillermo Cacheda <[email protected]>
  • Loading branch information
annacv and CachedaCodes authored Mar 13, 2024
1 parent 1fcf93d commit 4a38318
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { createLocalVue, mount, Wrapper } from '@vue/test-utils';
import Vue from 'vue';
import Vue, { ComponentOptions } from 'vue';
import Vuex from 'vuex';
import { Dictionary } from '@empathyco/x-utils';
import { createRawFilters } from '../../../../utils/filters';
import { baseSnippetConfig } from '../../../../views/base-config';
import PreselectedFilters from '../preselected-filters.vue';
import { bus } from '../../../../plugins/index';

function renderPreselectedFilters({
filters,
snippetFilters
}: RenderPreselectedFiltersOptions = {}): RenderPreselectedFiltersAPI {
const emit = jest.fn();
const emit = jest.spyOn(bus, 'emit');
const localVue = createLocalVue();
const snippetConfig = Vue.observable({ ...baseSnippetConfig, filters: snippetFilters });
localVue.use(Vuex);

const wrapper = mount(PreselectedFilters, {
const wrapper = mount(PreselectedFilters as ComponentOptions<Vue>, {
provide: {
snippetConfig: snippetConfig
},
Expand All @@ -24,7 +25,7 @@ function renderPreselectedFilters({
},
localVue,
mocks: {
$x: {
emit: {
emit
}
}
Expand All @@ -49,7 +50,6 @@ describe('testing Preselected filters component', () => {

it('does not emit the event when neither filters nor snippet config filters are provided', () => {
const { emit } = renderPreselectedFilters();

expect(emit).not.toHaveBeenCalled();
});

Expand All @@ -65,7 +65,8 @@ describe('testing Preselected filters component', () => {
expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(snippetFilters)
createRawFilters(snippetFilters),
expect.any(Object)
);
});

Expand All @@ -76,7 +77,11 @@ describe('testing Preselected filters component', () => {
});

expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledWith('PreselectedFiltersProvided', createRawFilters(filters));
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(filters),
expect.any(Object)
);
});

it('emits the event using the snippet config filters as payload when both are provided', () => {
Expand All @@ -93,7 +98,8 @@ describe('testing Preselected filters component', () => {
expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(snippetFilters)
createRawFilters(snippetFilters),
expect.any(Object)
);
});

Expand All @@ -107,13 +113,21 @@ describe('testing Preselected filters component', () => {

expect(wrapper.props()).toEqual({ filters: filters });
expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledWith('PreselectedFiltersProvided', createRawFilters(filters));
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(filters),
expect.any(Object)
);

await wrapper.setProps({ filters: newFilters });

expect(wrapper.props()).toEqual({ filters: newFilters });
expect(emit).toHaveBeenCalledTimes(2);
expect(emit).toHaveBeenCalledWith('PreselectedFiltersProvided', createRawFilters(newFilters));
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(newFilters),
expect.any(Object)
);
});

it('emits the event when the snippetConfig filters change', async () => {
Expand All @@ -126,7 +140,11 @@ describe('testing Preselected filters component', () => {

expect(wrapper.props()).toEqual({ filters: filters });
expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledWith('PreselectedFiltersProvided', createRawFilters(filters));
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(filters),
expect.any(Object)
);

await setSnippetConfig({ filters: newFilters });

Expand All @@ -138,7 +156,11 @@ describe('testing Preselected filters component', () => {

// The event is called again with the newFilters provided
expect(emit).toHaveBeenCalledTimes(2);
expect(emit).toHaveBeenCalledWith('PreselectedFiltersProvided', createRawFilters(newFilters));
expect(emit).toHaveBeenCalledWith(
'PreselectedFiltersProvided',
createRawFilters(newFilters),
expect.any(Object)
);
});
});

Expand All @@ -157,7 +179,7 @@ interface RenderPreselectedFiltersOptions {
*/
interface RenderPreselectedFiltersAPI {
/** Mock of the {@link XBus.emit} function. */
emit: jest.Mock;
emit: jest.SpyInstance;
/** The wrapper of the container element.*/
wrapper: Wrapper<Vue>;
/** Helper method to change the snippet config. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,77 @@
<script lang="ts">
import { Component, Inject, Prop, Watch } from 'vue-property-decorator';
import Vue from 'vue';
import { defineComponent, PropType, watch, computed, ref } from 'vue';
import { createRawFilters } from '../../../utils/filters';
import { isArrayEmpty } from '../../../utils/array';
import { SnippetConfig } from '../../../x-installer/api/api.types';
import { useXBus } from '../../../composables/use-x-bus';
import { useHybridInject, useNoElementRender } from '../../../composables';
/**
* This component emits {@link FacetsXEvents.PreselectedFiltersProvided} when a preselected filter
* is set in the snippet config or by using the prop of the component.
*
* @public
*/
@Component
export default class PreselectedFilters extends Vue {
/**
* Injects {@link SnippetConfig} provided by an ancestor as snippetConfig.
*
* @internal
*/
@Inject('snippetConfig')
public snippetConfig?: SnippetConfig;
/**
* A list of filters to preselect.
*
* @remarks Emits the {@link FacetsXEvents.PreselectedFiltersProvided} when the
* component is created.
*
* @public
*/
@Prop({ default: () => [] })
public filters!: string[];
/**
* Gets the provided preselected filters prioritizing the {@link SnippetConfig} over the
* filters prop.
*
* @returns An array of filter's ids.
*/
protected get preselectedFilters(): string[] {
return this.snippetConfig?.filters ?? this.filters;
}
/**
* Emits the {@link FacetsXEvents.PreselectedFiltersProvided} to save
* the provided filters in the state.
*/
@Watch('preselectedFilters')
protected emitPreselectedFilters(): void {
if (!isArrayEmpty(this.preselectedFilters)) {
this.$x.emit('PreselectedFiltersProvided', createRawFilters(this.preselectedFilters));
export default defineComponent({
name: 'PreselectedFilters',
props: {
/**
* A list of filters to preselect.
*
* @remarks Emits the {@link FacetsXEvents.PreselectedFiltersProvided} when the
* component is created.
*
* @public
*/
filters: {
type: Array as PropType<string[]>,
default: () => []
}
},
setup(props) {
const xBus = useXBus();
/**
* Injects {@link SnippetConfig} provided by an ancestor as snippetConfig
* and sets is as a ref to get synced when it changes.
*
* @internal
*/
const snippetConfig = ref(useHybridInject<SnippetConfig>('snippetConfig'));
/**
* Gets the provided preselected filters prioritizing the {@link SnippetConfig} over the
* filters prop.
*
* @returns An array of filter's ids.
* @internal
*/
const preselectedFilters = computed<string[]>(() => {
return snippetConfig.value?.filters ?? props.filters;
});
/**
* Emits the {@link FacetsXEvents.PreselectedFiltersProvided} to save
* the provided filters in the state.
*
* @internal
*/
const emitPreselectedFilters = (): void => {
if (!isArrayEmpty(preselectedFilters.value)) {
xBus.emit('PreselectedFiltersProvided', createRawFilters(preselectedFilters.value));
}
};
/**
* Emits the {@link FacetsXEvents.PreselectedFiltersProvided} when the
* computed prop changes.
*/
watch(preselectedFilters, emitPreselectedFilters, { immediate: true });
},
render() {
return useNoElementRender(this.$slots);
}
/**
* Emits the {@link FacetsXEvents.PreselectedFiltersProvided} when the
* component is created.
*/
created(): void {
this.emitPreselectedFilters();
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
render(): void {}
}
});
</script>

<docs lang="mdx">
Expand Down

0 comments on commit 4a38318

Please sign in to comment.