Skip to content

Commit

Permalink
feat(data-fetching): wrapping up first pass at data-fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Jun 24, 2024
1 parent fb0e26b commit 3b73131
Show file tree
Hide file tree
Showing 21 changed files with 506 additions and 68 deletions.
159 changes: 159 additions & 0 deletions packages/core/src/data/fetchFn/__tests__/fetchPost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { expectTypeOf } from 'expect-type';
import { PostParams } from '../..';
import { DRAFT_POST_ID, VALID_AUTH_TOKEN } from '../../../../test/server-handlers';
import { PostEntity } from '../../types';
import { fetchPost } from '../fetchPost';

describe('fetchPost', () => {
it('fetches data properly', async () => {
const { data } = await fetchPost({
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});

it('fetch by id', async () => {
const { data } = await fetchPost({ params: { id: 64 } });

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
});

it('throws error if not found', async () => {
await expect(fetchPost({ params: { id: 123123123 } })).rejects.toThrow();
});

it('errors if fetches draft posts without authToken', async () => {
await expect(fetchPost({ params: { id: DRAFT_POST_ID } })).rejects.toThrow();
});

it('fetches draft posts with authToken', async () => {
const { data } = await fetchPost({
params: { id: DRAFT_POST_ID, authToken: VALID_AUTH_TOKEN },
});

expect(data?.post.id).toBe(57);
});

it('fetches draft posts with authToken and alternativePreviewAuthorizationHeader', async () => {
const { data } = await fetchPost({
params: { id: DRAFT_POST_ID, authToken: VALID_AUTH_TOKEN },
options: {
alternativePreviewAuthorizationHeader: true,
},
});

expect(data?.post.id).toBe(57);
});

it('errors if fetches revisions without authToken', async () => {
await expect(
fetchPost({ params: { id: DRAFT_POST_ID, revision: true } }),
).rejects.toThrow();
});

it('fetches revisions with authToken', async () => {
const { data } = await fetchPost({
params: { id: 64, revision: true, authToken: 'Fake Auth Token' },
});

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
// ensure fields that don't exists in revisions are returned
expect(data.post.format).toBe('standard');
expect(data.post?.terms?.category[0]?.slug).toBe('news');
});

it('fetches revisions with authToken and alternativePreviewAuthorizationHeader', async () => {
const { data } = await fetchPost({
params: {
id: 64,
revision: true,
authToken: 'Fake Auth Token',
},
options: {
alternativePreviewAuthorizationHeader: true,
},
});

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
// ensure fields that don't exists in revisions are returned
expect(data.post.format).toBe('standard');
expect(data.post?.terms?.category[0]?.slug).toBe('news');
});

it('reads param from the url and sets isMainQuery flag', async () => {
const result = await fetchPost({
path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto/',
params: {
fullPath:
'https://js1.10up.com/2020/05/07/modi-qui-dignissimos-sed-assumenda-sint-iusto/',
},
});

expect(result.data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
expect(result.isMainQuery).toBe(true);

const result2 = await fetchPost({
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(result2.data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
expect(result2.isMainQuery).toBe(false);
});

it('matches post.link with current path when matchCurrentPath is set', async () => {
await expect(
fetchPost({
path: '/another-path',
params: {
slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto',
matchCurrentPath: true,
},
}),
).rejects.toThrow();

const { data } = await fetchPost({
path: '/another-path',
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});

it('matches post.link with fullPath when set', async () => {
const { data } = await fetchPost({
path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto',
params: {
// force post path mapping against this path
fullPath:
'https://js1.10up.com/2020/05/07/modi-qui-dignissimos-sed-assumenda-sint-iusto',
},
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});
});

describe('fetchPost types', () => {
it('allows overriding types', async () => {
interface Book extends PostEntity {
isbn: string;
}

interface BookParams extends PostParams {
isbn: string;
}

const { data } = await fetchPost<Book, BookParams>({ params: { isbn: 'sdasd' } });

expectTypeOf(data.post).toMatchTypeOf<
| {
isbn: string;
}
| undefined
>();
});
});
203 changes: 203 additions & 0 deletions packages/core/src/data/fetchFn/__tests__/fetchPosts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import { expectTypeOf } from 'expect-type';

import { PostEntity, PostsArchiveParams, fetchPosts } from '../..';
import { setHeadlessConfig } from '../../../utils';

describe('fetchPosts', () => {
beforeEach(() => {
setHeadlessConfig({
useWordPressPlugin: true,
});
});

it('fetches data properly', async () => {
const { data } = await fetchPosts({ params: { per_page: 2 } });

expect(data.posts).toHaveLength(2);
});

it('returns queried object for category archives', async () => {
const { data, pageType } = await fetchPosts({
params: { category: 'uncategorized', per_page: 1 },
});

expect(data.posts).toHaveLength(1);
expect(data.queriedObject.term?.slug).toBe('uncategorized');
expect(pageType.isAuthorArchive).toBe(false);
expect(pageType.isCategoryArchive).toBe(true);
expect(pageType.isSearch).toBe(false);
expect(pageType.isTaxonomyArchive).toBe(true);
expect(pageType.isTagArchive).toBe(false);
});

it('returns queried objects for utf8 encoded slugs', async () => {
const { data } = await fetchPosts({ params: { category: 'الأخبار-المالية', per_page: 1 } });

expect(data.posts).toHaveLength(1);
expect(data.queriedObject.term?.slug).toBe('الأخبار-المالية');
});

it('returns queried object for author archives', async () => {
const { data, pageType } = await fetchPosts({ params: { author: 'jane', per_page: 1 } });

expect(data.posts).toHaveLength(1);
expect(data.queriedObject.author?.slug).toBe('jane');
expect(pageType.isAuthorArchive).toBe(true);
expect(pageType.isCategoryArchive).toBe(false);
expect(pageType.isSearch).toBe(false);
expect(pageType.isTaxonomyArchive).toBe(false);
expect(pageType.isTagArchive).toBe(false);
});

it('returns queried object when querying by id', async () => {
const { data } = await fetchPosts({ params: { author: 3 } });

expect(data?.queriedObject.author?.id).toBe(3);
expect(data?.queriedObject.author?.slug).toBe('jane');

const result2 = await fetchPosts({ params: { category: 5 } });

expect(result2.data.queriedObject.term?.id).toBe(5);
expect(result2.data.queriedObject.term?.slug).toBe('news');
});

it('does not throw error if throwIfNotFound is passed', async () => {
const { data } = await fetchPosts({
params: { category: 'random category that does not exist' },
options: {
throwIfNotFound: false,
},
});

expect(data).toMatchObject({
posts: [],
});
});

it('reads param from the url and sets isMainQuery flag', async () => {
let result = await fetchPosts({ path: '/author/jane' });

expect(result.data.queriedObject.author?.slug).toBe('jane');
expect(result.isMainQuery).toBe(true);

result = await fetchPosts({ params: { author: 'jane' } });

expect(result.data.queriedObject.author?.slug).toBe('jane');
expect(result.isMainQuery).toBe(false);

result = await fetchPosts({ params: { taxonomy: 'category' }, path: '/news' });

expect(result.data.queriedObject.term?.slug).toBe('news');
expect(result.isMainQuery).toBe(true);
});

it('works with nested taxonomy', async () => {
const { data, isMainQuery } = await fetchPosts({
path: '/parent-category/news',
params: { taxonomy: 'category' },
});

expect(data.queriedObject.term?.slug).toBe('news');
expect(isMainQuery).toBe(true);
});

it('does not crash when not found but throwIfNotFound is set to false', async () => {
const { data } = await fetchPosts({
path: '/i-do-not-exist',
params: { taxonomy: 'category' },
options: {
throwIfNotFound: false,
},
});

expect(data.posts).toHaveLength(0);
});

it('does not crash when invalid page param when throwIfNotFound is set to false', async () => {
const { data } = await fetchPosts({
path: '/news/page/10',
params: { taxonomy: 'category' },
options: {
throwIfNotFound: false,
},
});

expect(data.posts).toHaveLength(0);
});

it('throws params.matchArchivepath is true and path does not match', async () => {
await expect(
fetchPosts({
path: 'https://js1.10up.com/category/asdasd/uncategorized',
params: { category: 'uncategorized', per_page: 1, matchArchivePath: true },
}),
).rejects.toThrow(
`Posts were found but did not match current path: "https://js1.10up.com/category/asdasd/uncategorized"`,
);
});

it('throws matchArchivepath config option is true and path does not match', async () => {
setHeadlessConfig({
useWordPressPlugin: true,
customTaxonomies: (defaultTaxonomies) => {
return defaultTaxonomies.map((taxonomy) => ({
...taxonomy,
matchArchivePath: true,
}));
},
});

await expect(
fetchPosts({
path: 'https://js1.10up.com/category/asdasd/uncategorized',
params: { category: 'uncategorized', per_page: 2 },
}),
).rejects.toThrow(
`Posts were found but did not match current path: "https://js1.10up.com/category/asdasd/uncategorized"`,
);
});

it('does not throws when matchArchivepath config option is true and path matches', async () => {
setHeadlessConfig({
useWordPressPlugin: true,
customTaxonomies: (defaultTaxonomies) => {
return defaultTaxonomies.map((taxonomy) => ({
...taxonomy,
matchArchivePath: true,
}));
},
});

const { data } = await fetchPosts({
// Need this bc source url removal is not working in the tests
path: 'https://js1.10up.com/category/uncategorized',
params: {
category: 'uncategorized',
per_page: 1,
},
});

expect(data.queriedObject.term?.slug).toBe('uncategorized');
});
});

describe('fetcPosts types', () => {
it('allows overriding types', async () => {
interface Book extends PostEntity {
isbn: string;
}

interface BookParams extends PostsArchiveParams {
isbn: string;
}

const { data } = await fetchPosts<Book, BookParams>({ params: { isbn: 'sdasd' } });

expectTypeOf(data?.posts).toMatchTypeOf<
| Array<{
isbn: string;
}>
| undefined
>();
});
});
Loading

0 comments on commit 3b73131

Please sign in to comment.