Skip to content

Commit

Permalink
renames package to epio-search, resets to v1, adds initial tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobdubail committed Jan 9, 2025
1 parent 8ea9d21 commit eb0f12d
Show file tree
Hide file tree
Showing 37 changed files with 275 additions and 50 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@changesets/cli": "^2.27.1",
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@testing-library/react-hooks": "^8.0.1",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"concurrently": "^6.3.0",
Expand Down
49 changes: 0 additions & 49 deletions packages/elasticpress-react/package.json

This file was deleted.

1 change: 1 addition & 0 deletions packages/epio-search/components.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/mjs/components';
File renamed without changes.
1 change: 1 addition & 0 deletions packages/epio-search/hooks.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/mjs/hooks';
File renamed without changes.
7 changes: 7 additions & 0 deletions packages/epio-search/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const config = require('../../jest.config');

module.exports = {
...config,
modulePaths: ['./test'],
setupFilesAfterEnv: ['./jest.setup.ts'],
};
9 changes: 9 additions & 0 deletions packages/epio-search/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { TextDecoder, TextEncoder } from 'util';

// https://github.com/kkomelin/isomorphic-dompurify/issues/91#issuecomment-1012645198
global.TextEncoder = TextEncoder;
// @ts-ignore
global.TextDecoder = TextDecoder;

// @ts-expect-error
global.__10up__HEADLESS_CONFIG = {};
47 changes: 47 additions & 0 deletions packages/epio-search/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@headstartwp/epio-search",
"version": "1.0.0-next.1",
"license": "MIT",
"description": "React components for supercharging your headless WordPress website with ElasticPress.",
"author": "10up <[email protected]> (https://10up.com/)",
"main": "dist/index.js",
"source": "src/index.ts",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./utils": {
"import": "./dist/utils/index.js",
"types": "./dist/utils/index.d.ts"
},
"./hooks": {
"import": "./dist/hooks/index.js",
"types": "./dist/hooks/index.d.ts"
},
"./components": {
"import": "./dist/components/index.js",
"types": "./dist/components/index.d.ts"
}
},
"sideEffects": false,
"scripts": {
"build": "npm run ts && npm run copystyles",
"ts": "tsc -b",
"copystyles": "copyfiles -u 1 src/**/*.css dist",
"dev": "concurrently \"npm run watch:ts\"",
"lint": "eslint src/"
},
"dependencies": {
"wp-types": "^4.67.0"
},
"devDependencies": {
"@types/react": "^17",
"copyfiles": "^2.4.1",
"typescript-plugin-css-modules": "^5.1.0"
},
"peerDependencies": {
"react": ">= 17.0.2"
}
}
File renamed without changes.
80 changes: 80 additions & 0 deletions packages/epio-search/src/hooks/__tests__/use-debounce.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { useDebounce } from '../use-debounce';

jest.useFakeTimers();

describe('useDebounce', () => {
it('should debounce the callback function', () => {
const callback = jest.fn();
const delay = 500;
const { result } = renderHook(() => useDebounce(callback, delay));

act(() => {
result.current('arg1');
result.current('arg2');
});

expect(callback).not.toHaveBeenCalled();

act(() => {
jest.advanceTimersByTime(delay);
});

expect(callback).toHaveBeenCalledTimes(1);
expect(callback).toHaveBeenCalledWith('arg2');
});

it('should reset the timer if called again within the delay', () => {
const callback = jest.fn();
const delay = 500;
const { result } = renderHook(() => useDebounce(callback, delay));

act(() => {
result.current('arg1');
});

act(() => {
jest.advanceTimersByTime(delay / 2);
});

act(() => {
result.current('arg2');
});

act(() => {
jest.advanceTimersByTime(delay / 2);
});

expect(callback).not.toHaveBeenCalled();

act(() => {
jest.advanceTimersByTime(delay / 2);
});

expect(callback).toHaveBeenCalledTimes(1);
expect(callback).toHaveBeenCalledWith('arg2');
});

it('should use the latest callback', () => {
const callback1 = jest.fn();
const callback2 = jest.fn();
const delay = 500;
const { result, rerender } = renderHook(({ cb }) => useDebounce(cb, delay), {
initialProps: { cb: callback1 },
});

act(() => {
result.current('arg1');
});

rerender({ cb: callback2 });

act(() => {
jest.advanceTimersByTime(delay);
});

expect(callback1).not.toHaveBeenCalled();
expect(callback2).toHaveBeenCalledTimes(1);
expect(callback2).toHaveBeenCalledWith('arg1');
});
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
39 changes: 39 additions & 0 deletions packages/epio-search/src/utils/__tests__/get-es-endpoint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { getESEndpoint } from '../get-es-endpoint';
import { EPConfig } from '../../types';

describe('getESEndpoint', () => {
it('should return the correct endpoint for elasticpress.io', () => {
const config: EPConfig = {
node: 'https://elasticpress.io',
indexName: 'test-index',
};
const result = getESEndpoint(config);
expect(result).toBe('https://elasticpress.io/api/v1/search/posts/test-index');
});

it('should throw an error if node is not specified', () => {
const config: EPConfig = {
node: '',
indexName: 'test-index',
};
expect(() => getESEndpoint(config)).toThrow('You must specify an ElasticSearch node');
});

it('should return an empty string if elasticpress.io is not the hostname', () => {
const config: EPConfig = {
node: 'https://example.com/elasticpress.io',
indexName: 'test-index',
};
const result = getESEndpoint(config);
expect(result).toBe('');
});

it('should return an empty string for non-elasticpress.io hosts', () => {
const config: EPConfig = {
node: 'https://example.com',
indexName: 'test-index',
};
const result = getESEndpoint(config);
expect(result).toBe('');
});
});
83 changes: 83 additions & 0 deletions packages/epio-search/src/utils/__tests__/run-ep-query.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { runEPQuery } from '../run-ep-query';
import { get } from '../../api';
import { EPSearchParams, EPHitMap, EPPost } from '../../types';

jest.mock('../../api');

describe('runEPQuery', () => {
const mockGet = get as jest.MockedFunction<typeof get>;

const searchState: EPSearchParams = {
searchTerm: 'test',
per_page: 10,
};

const endpoint = '/search';

const hitMap: EPHitMap = (hit) => {
return hit._source as EPPost;
};

const mockResponse = {
took: 0,
timed_out: false,
_shards: {
total: 0,
successful: 0,
skipped: 0,
failed: 0,
},
hits: {
max_score: 0,
total: { value: 2 },
hits: [
{ _id: '1', _source: { post_id: 1, title: 'Post 1' } },
{ _id: '2', _source: { post_id: 2, title: 'Post 2' } },
],
},
};

beforeEach(() => {
mockGet.mockResolvedValue(mockResponse);
});

it('should return results and totalResults', async () => {
const { results, totalResults } = await runEPQuery(searchState, endpoint, hitMap);

expect(results).toEqual([
{ post_id: 1, title: 'Post 1' },
{ post_id: 2, title: 'Post 2' },
]);
expect(totalResults).toBe(2);
});

it('should filter out undefined values from searchState', async () => {
const searchStateWithUndefined: EPSearchParams = {
searchTerm: 'test',
post_type: undefined,
};

await runEPQuery(searchStateWithUndefined, endpoint, hitMap);

expect(mockGet).toHaveBeenCalledWith({ search: 'test' }, endpoint);
});

it('should handle empty response', async () => {
mockGet.mockResolvedValueOnce({
took: 0,
timed_out: false,
_shards: {
total: 0,
successful: 0,
skipped: 0,
failed: 0,
},
hits: { total: { value: 0 }, hits: [], max_score: 0 },
});

const { results, totalResults } = await runEPQuery(searchState, endpoint, hitMap);

expect(results).toEqual([]);
expect(totalResults).toBe(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { EPConfig } from '../types';
export function getESEndpoint(config: EPConfig): string {
const { node, indexName } = config;

if (node.includes('elasticpress.io')) {
if (!node) {
throw new Error('You must specify an ElasticSearch node');
}

const url = new URL(node);
if (['elasticpress.io'].includes(url.host)) {
return `${node}/api/v1/search/posts/${indexName}`;
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions packages/epio-search/utils.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/mjs/utils';
File renamed without changes.

0 comments on commit eb0f12d

Please sign in to comment.