frontitygit
Version:
A Frontity source package for the REST API of self-hosted and WordPress.com sites
214 lines (198 loc) • 6.75 kB
text/typescript
import { createStore, InitializedStore, observe } from "@frontity/connect";
import clone from "clone-deep";
import wpSource from "../../../";
import WpSource from "../../../../types";
import Api from "../../api";
// JSON mocks
import { mockResponse } from "./mocks/helpers";
import cat1 from "./mocks/category/cat-1.json";
import cat1Posts from "./mocks/category/cat-1-posts.json";
import cat1PostsPage2 from "./mocks/category/cat-1-posts-page-2.json";
import cat1PostsCpt from "./mocks/category/cat-1-posts-cpt.json";
let store: InitializedStore<WpSource>;
let api: jest.Mocked<Api>;
beforeEach(() => {
store = createStore<WpSource>(clone(wpSource()));
store.state.source.url = "https://test.frontity.org";
store.actions.source.init();
api = store.libraries.source.api as jest.Mocked<Api>;
});
describe("category", () => {
test("doesn't exist in source.category", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse(cat1Posts, {
"X-WP-Total": "5",
"X-WP-TotalPages": "2",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/");
expect(store.state.source).toMatchSnapshot();
});
test("was populated but not accessed", async () => {
// Add category to the store
await store.libraries.source.populate({
state: store.state,
response: mockResponse([cat1]),
});
// Mock Api responses
api.get = jest.fn().mockResolvedValueOnce(
mockResponse(cat1PostsPage2, {
"X-WP-Total": "5",
"X-WP-TotalPages": "2",
})
);
// Observe changes in isFetching and isReady properties
const dataState = [];
observe(() => {
const { isFetching, isReady } = store.state.source.get(
"/category/cat-1/page/2/"
);
dataState.push({ isFetching, isReady });
});
// Fetch entities
await store.actions.source.fetch("/category/cat-1/page/2/");
expect(api.get).toHaveBeenCalledTimes(1);
expect(store.state.source).toMatchSnapshot();
// Values history of isFetching and isReady
expect(dataState).toEqual([
// First values are from a different object.
{ isFetching: false, isReady: false },
// Fetch starts.
{ isFetching: true, isReady: false },
// Intermediate values.
{ isFetching: false, isReady: false },
// Fetch ends.
{ isFetching: false, isReady: true },
]);
});
test("fetchs from a different endpoint with extra params", async () => {
// Add custom post endpoint and params
store.state.source.postEndpoint = "multiple-post-type";
store.state.source.params = { type: ["post", "cpt"] };
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse(cat1PostsCpt, {
"X-WP-Total": "5",
"X-WP-TotalPages": "2",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/");
expect(api.get.mock.calls).toMatchSnapshot();
expect(store.state.source).toMatchSnapshot();
});
test("returns 404 if category doesn't exist in WP", async () => {
// Mock Api responses
api.get = jest.fn().mockResolvedValue(mockResponse([]));
// Fetch entities
await store.actions.source.fetch("/category/non-existent/");
expect(api.get).toHaveBeenCalledTimes(1);
expect(store.state.source).toMatchSnapshot();
});
test("returns 404 if the page fetched is out of range", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(mockResponse([]));
// Fetch entities
await store.actions.source.fetch("/category/cat-1/page/3");
expect(store.state.source).toMatchSnapshot();
});
test("doesn't return 404 if the first page is empty", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse([], {
"X-WP-Total": "0",
"X-WP-TotalPages": "0",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/");
expect(store.state.source).toMatchSnapshot();
});
test("doesn't return 404 if the first page is empty (no headers)", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(mockResponse([], {}));
// Fetch entities
await store.actions.source.fetch("/category/cat-1/");
expect(store.state.source).toMatchSnapshot();
});
test("is requested with any query param", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse(cat1Posts, {
"X-WP-Total": "5",
"X-WP-TotalPages": "2",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/?some=param");
expect(store.state.source).toMatchSnapshot();
});
test("with a search", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse(cat1Posts, {
"X-WP-Total": "5",
"X-WP-TotalPages": "3",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/?s=some+search");
expect(store.state.source).toMatchSnapshot();
});
test("with a search with pagination", async () => {
// Mock Api responses
api.get = jest
.fn()
.mockResolvedValueOnce(mockResponse([cat1]))
.mockResolvedValueOnce(
mockResponse(cat1PostsPage2, {
"X-WP-Total": "5",
"X-WP-TotalPages": "3",
})
);
// Fetch entities
await store.actions.source.fetch("/category/cat-1/page/2?s=some+search");
expect(store.state.source).toMatchSnapshot();
});
test("Unknown URL should return a 404 even if it's substring matches a path", async () => {
api.get = jest.fn((_) =>
Promise.resolve(
mockResponse(cat1Posts, {
"X-WP-Total": "5",
"X-WP-TotalPages": "2",
})
)
);
await store.actions.source.fetch("/category/undefined/cat-1/");
expect(
(store.state.source.data as any)["/category/undefined/cat-1/"]
.errorStatusText
).toBe(
"You have tried to access content at route: /category/undefined/cat-1/ but it does not exist"
);
expect(store.state.source).toMatchSnapshot();
});
});