Refactor Filter type to accept Is, Is Not, Contains, Does not Contain (#128)
* Refactor Filter type to accept Is, Is Not, Contains, Does not Contain * Remove any and add tests
This commit is contained in:
@ -3,10 +3,8 @@ import Companies from '../Companies';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import { lightTheme } from '../../../layout/styles/themes';
|
||||
import { GET_COMPANIES } from '../../../services/api/companies';
|
||||
import { mockData } from '../__tests__/__data__/mock-data';
|
||||
import { mockCompaniesData } from '../__tests__/__data__/mock-data';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { SEARCH_COMPANY_QUERY } from '../../../services/api/search/search';
|
||||
import { mockCompanySearchData } from '../../../services/api/search/__data__/mock-search-data';
|
||||
|
||||
const component = {
|
||||
title: 'Companies',
|
||||
@ -26,7 +24,7 @@ const mocks = [
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
companies: mockData,
|
||||
companies: mockCompaniesData,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -40,28 +38,24 @@ const mocks = [
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
companies: mockData,
|
||||
companies: mockCompaniesData,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
variables: { where: { name: { _ilike: '%%' } }, limit: 5 },
|
||||
},
|
||||
result: mockCompanySearchData,
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: GET_COMPANIES,
|
||||
variables: {
|
||||
orderBy: [{ created_at: 'desc' }],
|
||||
where: { domain_name: { _eq: 'linkedin-searched.com' } },
|
||||
where: { domain_name: { _ilike: '%aircal%' } },
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
companies: mockData,
|
||||
companies: mockCompaniesData.filter(
|
||||
(company) =>
|
||||
company.domain_name && company.domain_name.includes('aircal'),
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -138,7 +138,9 @@ it('Checks insert data is appending a new line', async () => {
|
||||
});
|
||||
|
||||
it('Checks filters are working', async () => {
|
||||
const { getByText } = render(<CompaniesDefault />);
|
||||
const { getByText, queryByText, getByPlaceholderText } = render(
|
||||
<CompaniesDefault />,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Airbnb')).toBeDefined();
|
||||
@ -154,10 +156,12 @@ it('Checks filters are working', async () => {
|
||||
const urlFilter = getByText('Url');
|
||||
fireEvent.click(urlFilter);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('linkedin-searched.com')).toBeDefined();
|
||||
});
|
||||
const filterSearch = getByPlaceholderText('Url');
|
||||
fireEvent.change(filterSearch, { target: { value: 'aircal' } });
|
||||
|
||||
const filterByLinkedinOption = getByText('linkedin-searched.com');
|
||||
fireEvent.click(filterByLinkedinOption);
|
||||
await waitFor(() => {
|
||||
expect(getByText('aircall.io')).toBeDefined();
|
||||
const airbnbResult = queryByText('Airbnb');
|
||||
expect(airbnbResult).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { GraphqlQueryCompany } from '../../../../interfaces/company.interface';
|
||||
import { GraphqlQueryCompany } from '../../../../interfaces/entities/company.interface';
|
||||
|
||||
export const mockData: Array<GraphqlQueryCompany> = [
|
||||
export const mockCompaniesData: Array<GraphqlQueryCompany> = [
|
||||
{
|
||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
||||
domain_name: 'airbnb.com',
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
import {
|
||||
Company,
|
||||
mapToCompany,
|
||||
} from '../../interfaces/entities/company.interface';
|
||||
import { Company } from '../../interfaces/entities/company.interface';
|
||||
import { FaLink, FaBuilding } from 'react-icons/fa';
|
||||
import { SEARCH_COMPANY_QUERY } from '../../services/api/search/search';
|
||||
import { FilterConfigType } from '../../interfaces/filters/interface';
|
||||
|
||||
export const availableFilters = [
|
||||
@ -11,64 +7,42 @@ export const availableFilters = [
|
||||
key: 'company_name',
|
||||
label: 'Company',
|
||||
icon: <FaBuilding />,
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.name,
|
||||
value: mapToCompany(company),
|
||||
}),
|
||||
},
|
||||
selectedValueRender: (company) => company.name || '',
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (company) => ({
|
||||
name: { _eq: company.name },
|
||||
label: 'Contains',
|
||||
id: 'like',
|
||||
whereTemplate: (searchString) => ({
|
||||
name: { _ilike: `%${searchString}%` },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { name: { _eq: company.name } },
|
||||
label: 'Does not contain',
|
||||
id: 'not_like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_not: { name: { _ilike: `%${searchString}%` } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterConfigType<Company, Company>,
|
||||
} satisfies FilterConfigType<Company, string>,
|
||||
{
|
||||
key: 'company_domain_name',
|
||||
label: 'Url',
|
||||
icon: <FaLink />,
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (company) => ({
|
||||
render: (company) => company.domainName,
|
||||
value: mapToCompany(company),
|
||||
}),
|
||||
},
|
||||
selectedValueRender: (company) => company.domainName || '',
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (company) => ({
|
||||
domain_name: { _eq: company.domainName },
|
||||
label: 'Contains',
|
||||
id: 'like',
|
||||
whereTemplate: (searchString) => ({
|
||||
domain_name: { _ilike: `%${searchString}%` },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { domain_name: { _eq: company.domainName } },
|
||||
label: 'Does not contain',
|
||||
id: 'not_like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_not: { domain_name: { _ilike: `%${searchString}%` } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterConfigType<Company, Company>,
|
||||
} satisfies FilterConfigType<Company, string>,
|
||||
];
|
||||
|
||||
@ -3,7 +3,7 @@ import People from '../People';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import { lightTheme } from '../../../layout/styles/themes';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { mockData } from '../__tests__/__data__/mock-data';
|
||||
import { mockPeopleData } from '../__tests__/__data__/mock-data';
|
||||
import { GET_PEOPLE } from '../../../services/api/people';
|
||||
import { SEARCH_PEOPLE_QUERY } from '../../../services/api/search/search';
|
||||
|
||||
@ -25,7 +25,7 @@ const mocks = [
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
people: mockData,
|
||||
people: mockPeopleData,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -39,7 +39,7 @@ const mocks = [
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
people: mockData,
|
||||
people: mockPeopleData,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { GraphqlQueryPerson } from '../../../../interfaces/person.interface';
|
||||
import { GraphqlQueryPerson } from '../../../../interfaces/entities/person.interface';
|
||||
|
||||
export const mockData: Array<GraphqlQueryPerson> = [
|
||||
export const mockPeopleData: Array<GraphqlQueryPerson> = [
|
||||
{
|
||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||
__typename: 'Person',
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PeopleFilter should render the filter city 1`] = `
|
||||
exports[`PeopleFilter should render the filter city which is text search 1`] = `
|
||||
Object {
|
||||
"city": Object {
|
||||
"_eq": "Paris",
|
||||
"_ilike": "%Paris%",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`PeopleFilter should render the filter company_name which relation search 1`] = `
|
||||
Object {
|
||||
"company": Object {
|
||||
"name": Object {
|
||||
"_eq": "test-name",
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
@ -1,20 +1,18 @@
|
||||
import { cityFilter } from '../people-filters';
|
||||
import { cityFilter, companyFilter } from '../people-filters';
|
||||
|
||||
describe('PeopleFilter', () => {
|
||||
it(`should render the filter ${cityFilter.key}`, () => {
|
||||
it(`should render the filter ${companyFilter.key} which relation search`, () => {
|
||||
expect(
|
||||
cityFilter.operands[0].whereTemplate({
|
||||
companyFilter.operands[0].whereTemplate({
|
||||
id: 'test-id',
|
||||
city: 'Paris',
|
||||
email: 'john@doe.com',
|
||||
firstname: 'John',
|
||||
lastname: 'Doe',
|
||||
phone: '0123456789',
|
||||
creationDate: new Date(),
|
||||
pipes: [],
|
||||
company: null,
|
||||
__typename: 'people',
|
||||
name: 'test-name',
|
||||
domainName: 'test-domain-name',
|
||||
__typename: 'companies',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`should render the filter ${cityFilter.key} which is text search`, () => {
|
||||
expect(cityFilter.operands[0].whereTemplate('Paris')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
import { FaEnvelope, FaMapPin, FaUser, FaBuilding } from 'react-icons/fa';
|
||||
import {
|
||||
Person,
|
||||
mapToPerson,
|
||||
} from '../../interfaces/entities/person.interface';
|
||||
import {
|
||||
SEARCH_COMPANY_QUERY,
|
||||
SEARCH_PEOPLE_QUERY,
|
||||
} from '../../services/api/search/search';
|
||||
import { Person } from '../../interfaces/entities/person.interface';
|
||||
import { SEARCH_COMPANY_QUERY } from '../../services/api/search/search';
|
||||
import {
|
||||
Company,
|
||||
mapToCompany,
|
||||
@ -17,45 +11,31 @@ export const fullnameFilter = {
|
||||
key: 'fullname',
|
||||
label: 'People',
|
||||
icon: <FaUser />,
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
_or: [
|
||||
{ firstname: { _ilike: `%${searchInput}%` } },
|
||||
{ lastname: { _ilike: `%${searchInput}%` } },
|
||||
],
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => `${person.firstname} ${person.lastname}`,
|
||||
value: mapToPerson(person),
|
||||
}),
|
||||
},
|
||||
selectedValueRender: (person) => `${person.firstname} ${person.lastname}`,
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
_and: [
|
||||
{ firstname: { _eq: `${person.firstname}` } },
|
||||
{ lastname: { _eq: `${person.lastname}` } },
|
||||
label: 'Contains',
|
||||
id: 'like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_or: [
|
||||
{ firstname: { _ilike: `%${searchString}%` } },
|
||||
{ lastname: { _ilike: `%${searchString}%` } },
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
label: 'Does not contain',
|
||||
id: 'not_like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_not: {
|
||||
_and: [
|
||||
{ firstname: { _eq: `${person.firstname}` } },
|
||||
{ lastname: { _eq: `${person.lastname}` } },
|
||||
{ firstname: { _ilike: `%${searchString}%` } },
|
||||
{ lastname: { _ilike: `%${searchString}%` } },
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
} satisfies FilterConfigType<Person, string>;
|
||||
|
||||
export const companyFilter = {
|
||||
key: 'company_name',
|
||||
@ -63,8 +43,8 @@ export const companyFilter = {
|
||||
icon: <FaBuilding />,
|
||||
searchConfig: {
|
||||
query: SEARCH_COMPANY_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
name: { _ilike: `%${searchInput}%` },
|
||||
template: (searchString: string) => ({
|
||||
name: { _ilike: `%${searchString}%` },
|
||||
}),
|
||||
resultMapper: (data) => ({
|
||||
value: mapToCompany(data),
|
||||
@ -74,15 +54,15 @@ export const companyFilter = {
|
||||
selectedValueRender: (company) => company.name || '',
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
label: 'Is',
|
||||
id: 'is',
|
||||
whereTemplate: (company) => ({
|
||||
company: { name: { _eq: company.name } },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
label: 'Is not',
|
||||
id: 'is_not',
|
||||
whereTemplate: (company) => ({
|
||||
_not: { company: { name: { _eq: company.name } } },
|
||||
}),
|
||||
@ -94,71 +74,49 @@ export const emailFilter = {
|
||||
key: 'email',
|
||||
label: 'Email',
|
||||
icon: <FaEnvelope />,
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
email: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => person.email,
|
||||
value: mapToPerson(person),
|
||||
}),
|
||||
},
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
email: { _eq: person.email },
|
||||
label: 'Contains',
|
||||
id: 'like',
|
||||
whereTemplate: (searchString) => ({
|
||||
email: { _ilike: `%${searchString}%` },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
_not: { email: { _eq: person.email } },
|
||||
label: 'Does not contain',
|
||||
id: 'not_like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_not: { email: { _ilike: `%${searchString}%` } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
selectedValueRender: (person) => person.email || '',
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
} satisfies FilterConfigType<Person, string>;
|
||||
|
||||
export const cityFilter = {
|
||||
key: 'city',
|
||||
label: 'City',
|
||||
icon: <FaMapPin />,
|
||||
searchConfig: {
|
||||
query: SEARCH_PEOPLE_QUERY,
|
||||
template: (searchInput: string) => ({
|
||||
city: { _ilike: `%${searchInput}%` },
|
||||
}),
|
||||
resultMapper: (person) => ({
|
||||
render: (person) => person.city,
|
||||
value: mapToPerson(person),
|
||||
}),
|
||||
},
|
||||
operands: [
|
||||
{
|
||||
label: 'Equal',
|
||||
id: 'equal',
|
||||
whereTemplate: (person) => ({
|
||||
city: { _eq: person.city },
|
||||
label: 'Contains',
|
||||
id: 'like',
|
||||
whereTemplate: (searchString) => ({
|
||||
city: { _ilike: `%${searchString}%` },
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Not equal',
|
||||
id: 'not-equal',
|
||||
whereTemplate: (person) => ({
|
||||
_not: { city: { _eq: person.city } },
|
||||
label: 'Does not contain',
|
||||
id: 'not_like',
|
||||
whereTemplate: (searchString) => ({
|
||||
_not: { city: { _ilike: `%${searchString}%` } },
|
||||
}),
|
||||
},
|
||||
],
|
||||
selectedValueRender: (person) => person.email || '',
|
||||
} satisfies FilterConfigType<Person, Person>;
|
||||
} satisfies FilterConfigType<Person, string>;
|
||||
|
||||
export const availableFilters = [
|
||||
fullnameFilter,
|
||||
companyFilter,
|
||||
emailFilter,
|
||||
cityFilter,
|
||||
] satisfies FilterConfigType<Person, any>[];
|
||||
] satisfies FilterConfigType<Person>[];
|
||||
|
||||
Reference in New Issue
Block a user