Improved domainsList reducer test

This commit is contained in:
Alejandro Celaya
2021-08-22 09:00:58 +02:00
parent 69cb3bd619
commit 8e71b2e2b1
3 changed files with 60 additions and 16 deletions

View File

@@ -32,24 +32,26 @@ const DefaultDomain: FC = () => (
export const DomainRow: FC<DomainRowProps> = ({ domain, editDomainRedirects, defaultRedirects }) => { export const DomainRow: FC<DomainRowProps> = ({ domain, editDomainRedirects, defaultRedirects }) => {
const [ isOpen, toggle ] = useToggle(); const [ isOpen, toggle ] = useToggle();
const { domain: authority, isDefault, redirects } = domain;
const domainId = `domainEdit${authority.replace('.', '')}`;
return ( return (
<tr> <tr>
<td>{domain.isDefault ? <DefaultDomain /> : ''}</td> <td>{isDefault ? <DefaultDomain /> : ''}</td>
<th>{domain.domain}</th> <th>{authority}</th>
<td>{domain.redirects?.baseUrlRedirect ?? <Nr fallback={defaultRedirects?.baseUrlRedirect} />}</td> <td>{redirects?.baseUrlRedirect ?? <Nr fallback={defaultRedirects?.baseUrlRedirect} />}</td>
<td>{domain.redirects?.regular404Redirect ?? <Nr fallback={defaultRedirects?.regular404Redirect} />}</td> <td>{redirects?.regular404Redirect ?? <Nr fallback={defaultRedirects?.regular404Redirect} />}</td>
<td> <td>
{domain.redirects?.invalidShortUrlRedirect ?? <Nr fallback={defaultRedirects?.invalidShortUrlRedirect} />} {redirects?.invalidShortUrlRedirect ?? <Nr fallback={defaultRedirects?.invalidShortUrlRedirect} />}
</td> </td>
<td className="text-right"> <td className="text-right">
<span id={`domainEdit${domain.domain.replace('.', '')}`}> <span id={domainId}>
<Button outline size="sm" disabled={domain.isDefault} onClick={domain.isDefault ? undefined : toggle}> <Button outline size="sm" disabled={isDefault} onClick={isDefault ? undefined : toggle}>
<FontAwesomeIcon icon={domain.isDefault ? forbiddenIcon : editIcon} /> <FontAwesomeIcon icon={isDefault ? forbiddenIcon : editIcon} />
</Button> </Button>
</span> </span>
{domain.isDefault && ( {isDefault && (
<UncontrolledTooltip target={`domainEdit${domain.domain.replace('.', '')}`} placement="left"> <UncontrolledTooltip target={domainId} placement="left">
Redirects for default domain cannot be edited here. Redirects for default domain cannot be edited here.
<br /> <br />
Use config options or env vars. Use config options or env vars.

View File

@@ -37,12 +37,12 @@ const initialState: DomainsList = {
error: false, error: false,
}; };
type DomainsCombinedAction = ListDomainsAction export type DomainsCombinedAction = ListDomainsAction
& ApiErrorAction & ApiErrorAction
& FilterDomainsAction & FilterDomainsAction
& EditDomainRedirectsAction; & EditDomainRedirectsAction;
const replaceRedirectsOnDomain = (domain: string, redirects: ShlinkDomainRedirects) => export const replaceRedirectsOnDomain = (domain: string, redirects: ShlinkDomainRedirects) =>
(d: ShlinkDomain): ShlinkDomain => d.domain !== domain ? d : { ...d, redirects }; (d: ShlinkDomain): ShlinkDomain => d.domain !== domain ? d : { ...d, redirects };
export default buildReducer<DomainsList, DomainsCombinedAction>({ export default buildReducer<DomainsList, DomainsCombinedAction>({

View File

@@ -3,17 +3,23 @@ import reducer, {
LIST_DOMAINS, LIST_DOMAINS,
LIST_DOMAINS_ERROR, LIST_DOMAINS_ERROR,
LIST_DOMAINS_START, LIST_DOMAINS_START,
ListDomainsAction, FILTER_DOMAINS,
DomainsCombinedAction,
DomainsList,
listDomains as listDomainsAction, listDomains as listDomainsAction,
filterDomains as filterDomainsAction,
replaceRedirectsOnDomain,
} from '../../../src/domains/reducers/domainsList'; } from '../../../src/domains/reducers/domainsList';
import { ShlinkDomain } from '../../../src/api/types'; import { EDIT_DOMAIN_REDIRECTS } from '../../../src/domains/reducers/domainRedirects';
import { ShlinkDomain, ShlinkDomainRedirects } from '../../../src/api/types';
import ShlinkApiClient from '../../../src/api/services/ShlinkApiClient'; import ShlinkApiClient from '../../../src/api/services/ShlinkApiClient';
describe('domainsList', () => { describe('domainsList', () => {
const domains = [ Mock.all<ShlinkDomain>(), Mock.all<ShlinkDomain>(), Mock.all<ShlinkDomain>() ]; const filteredDomains = [ Mock.of<ShlinkDomain>({ domain: 'foo' }), Mock.of<ShlinkDomain>({ domain: 'boo' }) ];
const domains = [ ...filteredDomains, Mock.of<ShlinkDomain>({ domain: 'bar' }) ];
describe('reducer', () => { describe('reducer', () => {
const action = (type: string, args: Partial<ListDomainsAction> = {}): any => Mock.of<ListDomainsAction>( const action = (type: string, args: Partial<DomainsCombinedAction> = {}) => Mock.of<DomainsCombinedAction>(
{ type, ...args }, { type, ...args },
); );
@@ -34,6 +40,32 @@ describe('domainsList', () => {
{ domains, filteredDomains: domains, loading: false, error: false }, { domains, filteredDomains: domains, loading: false, error: false },
); );
}); });
it('filters domains on FILTER_DOMAINS', () => {
expect(reducer(Mock.of<DomainsList>({ domains }), action(FILTER_DOMAINS, { searchTerm: 'oo' }))).toEqual(
{ domains, filteredDomains },
);
});
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'does_not_exist' ],
])('replaces redirects on proper domain on EDIT_DOMAIN_REDIRECTS', (domain) => {
const redirects: ShlinkDomainRedirects = {
baseUrlRedirect: 'bar',
regular404Redirect: 'foo',
invalidShortUrlRedirect: null,
};
expect(reducer(
Mock.of<DomainsList>({ domains, filteredDomains }),
action(EDIT_DOMAIN_REDIRECTS, { domain, redirects }),
)).toEqual({
domains: domains.map(replaceRedirectsOnDomain(domain, redirects)),
filteredDomains: filteredDomains.map(replaceRedirectsOnDomain(domain, redirects)),
});
});
}); });
describe('listDomains', () => { describe('listDomains', () => {
@@ -66,4 +98,14 @@ describe('domainsList', () => {
expect(listDomains).toHaveBeenCalledTimes(1); expect(listDomains).toHaveBeenCalledTimes(1);
}); });
}); });
describe('filterDomains', () => {
it.each([
[ 'foo' ],
[ 'bar' ],
[ 'something' ],
])('creates action as expected', (searchTerm) => {
expect(filterDomainsAction(searchTerm)).toEqual({ type: FILTER_DOMAINS, searchTerm });
});
});
}); });