Files
payloadcms/test/collections-rest/int.spec.ts
2023-09-13 13:04:06 -04:00

1118 lines
34 KiB
TypeScript

import { randomBytes } from 'crypto';
import { initPayloadTest } from '../helpers/configHelpers';
import type { Relation } from './config';
import config, { customIdNumberSlug, customIdSlug, errorOnHookSlug, pointSlug, relationSlug, slug } from './config';
import payload from '../../src';
import { RESTClient } from '../helpers/rest';
import type { ErrorOnHook, Post } from './payload-types';
import { mapAsync } from '../../src/utilities/mapAsync';
let client: RESTClient;
describe('collections-rest', () => {
beforeAll(async () => {
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
client = new RESTClient(await config, { serverURL, defaultSlug: slug });
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
beforeEach(async () => {
await clearDocs();
});
describe('CRUD', () => {
it('should create', async () => {
const data = {
title: 'title',
};
const doc = await createPost(data);
expect(doc).toMatchObject(data);
});
it('should find', async () => {
const post1 = await createPost();
const post2 = await createPost();
const { status, result } = await client.find<Post>();
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(2);
const expectedDocs = [post1, post2];
expect(result.docs).toHaveLength(expectedDocs.length);
expect(result.docs).toEqual(expect.arrayContaining(expectedDocs));
});
it('should find where id', async () => {
const post1 = await createPost();
await createPost();
const { status, result } = await client.find<Post>({
query: {
id: { equals: post1.id },
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs[0].id).toEqual(post1.id);
});
it('should find with pagination false', async () => {
const post1 = await createPost();
const post2 = await createPost();
const { docs, totalDocs } = await payload.find({
collection: slug,
pagination: false,
});
const expectedDocs = [post1, post2];
expect(docs).toHaveLength(expectedDocs.length);
expect(docs).toEqual(expect.arrayContaining(expectedDocs));
expect(totalDocs).toEqual(2);
});
it('should update existing', async () => {
const {
id,
description,
} = await createPost({ description: 'desc' });
const updatedTitle = 'updated-title';
const {
status,
doc: updated,
} = await client.update<Post>({
id,
data: { title: updatedTitle },
});
expect(status).toEqual(200);
expect(updated.title).toEqual(updatedTitle);
expect(updated.description).toEqual(description); // Check was not modified
});
describe('Bulk operations', () => {
it('should bulk update', async () => {
await mapAsync([...Array(11)], async (_, i) => {
await createPost({ description: `desc ${i}` });
});
const description = 'updated';
const {
status,
docs,
} = await client.updateMany<Post>({
where: { title: { equals: 'title' } },
data: { description },
});
expect(status).toEqual(200);
expect(docs[0].title).toEqual('title'); // Check was not modified
expect(docs[0].description).toEqual(description);
expect(docs.pop().description).toEqual(description);
});
it('should not bulk update with a bad query', async () => {
await mapAsync([...Array(2)], async (_, i) => {
await createPost({ description: `desc ${i}` });
});
const description = 'updated';
const { status, docs: noDocs, errors } = await client.updateMany<Post>({
where: { missing: { equals: 'title' } },
data: { description },
});
expect(status).toEqual(400);
expect(noDocs).toBeUndefined();
expect(errors).toHaveLength(1);
const { docs } = await payload.find({
collection: slug,
});
expect(docs[0].description).not.toEqual(description);
expect(docs.pop().description).not.toEqual(description);
});
it('should not bulk update with a bad relationship query', async () => {
await mapAsync([...Array(2)], async (_, i) => {
await createPost({ description: `desc ${i}` });
});
const description = 'updated';
const { status: relationFieldStatus, docs: relationFieldDocs, errors: relationFieldErrors } = await client.updateMany<Post>({
where: { 'relationField.missing': { equals: 'title' } },
data: { description },
});
const { status: relationMultiRelationToStatus } = await client.updateMany<Post>({
where: { 'relationMultiRelationTo.missing': { equals: 'title' } },
data: { description },
});
const { docs } = await payload.find({
collection: slug,
});
expect(relationFieldStatus).toEqual(400);
expect(relationMultiRelationToStatus).toEqual(400);
expect(docs[0].description).not.toEqual(description);
expect(docs.pop().description).not.toEqual(description);
});
it('should not bulk update with a read restricted field query', async () => {
const { id } = await payload.create({
collection: slug,
data: {
restrictedField: 'restricted',
},
});
const description = 'description';
const result = await client.updateMany({
where: { restrictedField: { equals: 'restricted' } },
data: { description },
});
const doc = await payload.findByID({
collection: slug,
id,
});
expect(result.status).toEqual(400);
expect(result.errors).toHaveLength(1);
expect(result.errors[0].message).toEqual('The following path cannot be queried: restrictedField');
expect(doc.description).toBeUndefined();
});
it('should return formatted errors for bulk updates', async () => {
const text = 'bulk-update-test-errors';
const errorDoc = await payload.create({
collection: errorOnHookSlug,
data: {
text,
errorBeforeChange: true,
},
});
const successDoc = await payload.create({
collection: errorOnHookSlug,
data: {
text,
errorBeforeChange: false,
},
});
const update = 'update';
const result = await client.updateMany<ErrorOnHook>({
slug: errorOnHookSlug,
where: { text: { equals: text } },
data: { text: update },
});
expect(result.status).toEqual(400);
expect(result.docs).toHaveLength(1);
expect(result.docs[0].id).toEqual(successDoc.id);
expect(result.errors).toHaveLength(1);
expect(result.errors[0].message).toBeDefined();
expect(result.errors[0].id).toEqual(errorDoc.id);
expect(result.docs[0].text).toEqual(update);
});
it('should bulk delete', async () => {
const count = 11;
await mapAsync([...Array(count)], async (_, i) => {
await createPost({ description: `desc ${i}` });
});
const { status, docs } = await client.deleteMany<Post>({
where: { title: { equals: 'title' } },
});
expect(status).toEqual(200);
expect(docs[0].title).toEqual('title'); // Check was not modified
expect(docs).toHaveLength(count);
});
it('should return formatted errors for bulk deletes', async () => {
await payload.create({
collection: errorOnHookSlug,
data: {
text: 'test',
errorAfterDelete: true,
},
});
await payload.create({
collection: errorOnHookSlug,
data: {
text: 'test',
errorAfterDelete: false,
},
});
const result = await client.deleteMany({
slug: errorOnHookSlug,
where: { text: { equals: 'test' } },
});
expect(result.status).toEqual(400);
expect(result.docs).toHaveLength(1);
expect(result.errors).toHaveLength(1);
expect(result.errors[0].message).toBeDefined();
expect(result.errors[0].id).toBeDefined();
});
});
describe('Custom ID', () => {
describe('string', () => {
it('should create', async () => {
const customId = `custom-${randomBytes(32).toString('hex').slice(0, 12)}`;
const customIdName = 'custom-id-name';
const { doc } = await client.create({ slug: customIdSlug, data: { id: customId, name: customIdName } });
expect(doc.id).toEqual(customId);
expect(doc.name).toEqual(customIdName);
});
it('should find', async () => {
const customId = `custom-${randomBytes(32).toString('hex').slice(0, 12)}`;
const { doc } = await client.create({ slug: customIdSlug, data: { id: customId, name: 'custom-id-name' } });
const { doc: foundDoc } = await client.findByID({ slug: customIdSlug, id: customId });
expect(foundDoc.id).toEqual(doc.id);
});
it('should query - equals', async () => {
const customId = `custom-${randomBytes(32).toString('hex').slice(0, 12)}`;
const { doc } = await client.create({ slug: customIdSlug, data: { id: customId, name: 'custom-id-name' } });
const { result } = await client.find({ slug: customIdSlug, query: { id: { equals: customId } } });
expect(result.docs.map(({ id }) => id)).toContain(doc.id);
});
it('should query - like', async () => {
const customId = `custom-${randomBytes(32).toString('hex').slice(0, 12)}`;
const { doc } = await client.create({ slug: customIdSlug, data: { id: customId, name: 'custom-id-name' } });
const { result } = await client.find({ slug: customIdSlug, query: { id: { like: 'custom' } } });
expect(result.docs.map(({ id }) => id)).toContain(doc.id);
});
it('should update', async () => {
const customId = `custom-${randomBytes(32).toString('hex').slice(0, 12)}`;
const { doc } = await client.create({ slug: customIdSlug, data: { id: customId, data: { name: 'custom-id-name' } } });
const { doc: updatedDoc } = await client.update({ slug: customIdSlug, id: doc.id, data: { name: 'updated' } });
expect(updatedDoc.name).toEqual('updated');
});
});
describe('number', () => {
it('should create', async () => {
const customId = Math.floor(Math.random() * (1_000_000)) + 1;
const { doc } = await client.create({ slug: customIdNumberSlug, data: { id: customId, name: 'custom-id-number-name' } });
expect(doc.id).toEqual(customId);
});
it('should find', async () => {
const customId = Math.floor(Math.random() * (1_000_000)) + 1;
const { doc } = await client.create({ slug: customIdNumberSlug, data: { id: customId, name: 'custom-id-number-name' } });
const { doc: foundDoc } = await client.findByID({ slug: customIdNumberSlug, id: customId });
expect(foundDoc.id).toEqual(doc.id);
});
it('should update', async () => {
const customId = Math.floor(Math.random() * (1_000_000)) + 1;
const { doc } = await client.create({ slug: customIdNumberSlug, data: { id: customId, name: 'custom-id-number-name' } });
const { doc: updatedDoc } = await client.update({ slug: customIdNumberSlug, id: doc.id, data: { name: 'updated' } });
expect(updatedDoc.name).toEqual('updated');
});
it('should allow querying by in', async () => {
const id = 98234698237;
await client.create({ slug: customIdNumberSlug, data: { id, name: 'query using in operator' } });
const { result: { docs } } = await client.find({
slug: customIdNumberSlug,
query: {
id: {
in: `${id}, ${2349856723948764}`,
},
},
});
expect(docs).toHaveLength(1);
});
});
});
it('should delete', async () => {
const { id } = await createPost();
const { status, doc } = await client.delete<Post>(id);
expect(status).toEqual(200);
expect(doc.id).toEqual(id);
});
it('should include metadata', async () => {
await createPosts(11);
const { result } = await client.find<Post>();
expect(result.totalDocs).toBeGreaterThan(0);
expect(result.limit).toBe(10);
expect(result.page).toBe(1);
expect(result.pagingCounter).toBe(1);
expect(result.hasPrevPage).toBe(false);
expect(result.hasNextPage).toBe(true);
expect(result.prevPage).toBeNull();
expect(result.nextPage).toBe(2);
});
});
describe('Querying', () => {
it.todo('should allow querying by a field within a group');
describe('Relationships', () => {
let post: Post;
let relation: Relation;
let relation2: Relation;
const nameToQuery = 'name';
const nameToQuery2 = 'name2';
beforeEach(async () => {
({ doc: relation } = await client.create<Relation>({
slug: relationSlug,
data: {
name: nameToQuery,
},
}));
({ doc: relation2 } = await client.create<Relation>({
slug: relationSlug,
data: {
name: nameToQuery2,
},
}));
post = await createPost({
relationField: relation.id,
});
await createPost(); // Extra post to allow asserting totalDoc count
});
describe('regular relationship', () => {
it('query by property value', async () => {
const { status, result } = await client.find<Post>({
query: {
'relationField.name': {
equals: relation.name,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post]);
expect(result.totalDocs).toEqual(1);
});
it('query by id', async () => {
const { status, result } = await client.find<Post>({
query: {
relationField: {
equals: relation.id,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post]);
expect(result.totalDocs).toEqual(1);
});
});
it('should query nested relationship - hasMany', async () => {
const post1 = await createPost({
relationHasManyField: [relation.id, relation2.id],
});
const { status, result } = await client.find<Post>({
query: {
'relationHasManyField.name': {
equals: relation.name,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
// Query second relationship
const { status: status2, result: result2 } = await client.find<Post>({
query: {
'relationHasManyField.name': {
equals: relation2.name,
},
},
});
expect(status2).toEqual(200);
expect(result2.docs).toEqual([post1]);
expect(result2.totalDocs).toEqual(1);
});
describe('relationTo multi', () => {
it('nested by id', async () => {
const post1 = await createPost({
relationMultiRelationTo: { relationTo: relationSlug, value: relation.id },
});
await createPost();
const { status, result } = await client.find<Post>({
query: {
'relationMultiRelationTo.value': {
equals: relation.id,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
});
describe('relationTo multi hasMany', () => {
it('nested by id', async () => {
const post1 = await createPost({
relationMultiRelationToHasMany: [
{ relationTo: relationSlug, value: relation.id },
{ relationTo: relationSlug, value: relation2.id },
],
});
await createPost();
const { status, result } = await client.find<Post>({
query: {
'relationMultiRelationToHasMany.value': {
equals: relation.id,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
// Query second relation
const { status: status2, result: result2 } = await client.find<Post>({
query: {
'relationMultiRelationToHasMany.value': {
equals: relation.id,
},
},
});
expect(status2).toEqual(200);
expect(result2.docs).toEqual([post1]);
expect(result2.totalDocs).toEqual(1);
});
it.todo('nested by property value');
});
});
describe('Edge cases', () => {
it('should query a localized field without localization configured', async () => {
const test = 'test';
await createPost({ fakeLocalization: test });
const { status, result } = await client.find({
query: {
fakeLocalization: {
equals: test,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(1);
});
});
describe('Operators', () => {
it('equals', async () => {
const valueToQuery = 'valueToQuery';
const post1 = await createPost({ title: valueToQuery });
await createPost();
const { status, result } = await client.find<Post>({
query: {
title: {
equals: valueToQuery,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([post1]);
});
it('not_equals', async () => {
const post1 = await createPost({ title: 'not-equals' });
const post2 = await createPost();
const { status, result } = await client.find<Post>({
query: {
title: {
not_equals: post1.title,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([post2]);
});
it('in', async () => {
const post1 = await createPost({ title: 'my-title' });
await createPost();
const { status, result } = await client.find<Post>({
query: {
title: {
in: [post1.title],
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
it('not_in', async () => {
const post1 = await createPost({ title: 'not-me' });
const post2 = await createPost();
const { status, result } = await client.find<Post>({
query: {
title: {
not_in: [post1.title],
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post2]);
expect(result.totalDocs).toEqual(1);
});
it('like', async () => {
const post1 = await createPost({ title: 'prefix-value' });
const { status, result } = await client.find<Post>({
query: {
title: {
like: post1.title?.substring(0, 6),
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
describe('like - special characters', () => {
const specialCharacters = '~!@#$%^&*()_+-+[]{}|;:"<>,.?/})';
it.each(specialCharacters.split(''))('like - special characters - %s', async (character) => {
const post1 = await createPost({
title: specialCharacters,
});
const query = {
query: {
title: {
like: character,
},
},
};
const { status, result } = await client.find<Post>(query);
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
});
it('like - cyrillic characters', async () => {
const post1 = await createPost({ title: 'Тест' });
const { status, result } = await client.find<Post>({
query: {
title: {
like: 'Тест',
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
it('like - cyrillic characters in multiple words', async () => {
const post1 = await createPost({ title: 'привет, это тест полезной нагрузки' });
const { status, result } = await client.find<Post>({
query: {
title: {
like: 'привет нагрузки',
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post1]);
expect(result.totalDocs).toEqual(1);
});
it('like - partial word match', async () => {
const post = await createPost({ title: 'separate words should partially match' });
const { status, result } = await client.find<Post>({
query: {
title: {
like: 'words partial',
},
},
});
expect(status).toEqual(200);
expect(result.docs).toEqual([post]);
expect(result.totalDocs).toEqual(1);
});
it('exists - true', async () => {
const postWithDesc = await createPost({ description: 'exists' });
await createPost({ description: undefined });
const { status, result } = await client.find<Post>({
query: {
description: {
exists: true,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([postWithDesc]);
});
it('exists - false', async () => {
const postWithoutDesc = await createPost({ description: undefined });
await createPost({ description: 'exists' });
const { status, result } = await client.find<Post>({
query: {
description: {
exists: false,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([postWithoutDesc]);
});
describe('numbers', () => {
let post1: Post;
let post2: Post;
beforeEach(async () => {
post1 = await createPost({ number: 1 });
post2 = await createPost({ number: 2 });
});
it('greater_than', async () => {
const { status, result } = await client.find<Post>({
query: {
number: {
greater_than: 1,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([post2]);
});
it('greater_than_equal', async () => {
const { status, result } = await client.find<Post>({
query: {
number: {
greater_than_equal: 1,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(2);
const expectedDocs = [post1, post2];
expect(result.docs).toHaveLength(expectedDocs.length);
expect(result.docs).toEqual(expect.arrayContaining(expectedDocs));
});
it('less_than', async () => {
const { status, result } = await client.find<Post>({
query: {
number: {
less_than: 2,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([post1]);
});
it('less_than_equal', async () => {
const { status, result } = await client.find<Post>({
query: {
number: {
less_than_equal: 2,
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(2);
const expectedDocs = [post1, post2];
expect(result.docs).toHaveLength(expectedDocs.length);
expect(result.docs).toEqual(expect.arrayContaining(expectedDocs));
});
});
describe('near', () => {
const point = [10, 20];
const [lat, lng] = point;
it('should return a document near a point', async () => {
const near = `${lat + 0.01}, ${lng + 0.01}, 10000`;
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
near,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(1);
});
it('should not return a point far away', async () => {
const near = `${lng + 1}, ${lat - 1}, 5000`;
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
near,
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(0);
});
it('should sort find results by nearest distance', async () => {
// creating twice as many records as we are querying to get a random sample
await mapAsync([...Array(10)], async () => {
// setTimeout used to randomize the creation timestamp
setTimeout(async () => {
await payload.create({
collection: pointSlug,
data: {
// only randomize longitude to make distance comparison easy
point: [Math.random(), 0],
},
});
}, Math.random());
});
const { result } = await client.find({
slug: pointSlug,
query: {
// querying large enough range to include all docs
point: { near: '0, 0, 100000, 0' },
},
limit: 5,
});
const { docs } = result;
let previous = 0;
docs.forEach((({ point: coordinates }) => {
// the next document point should always be greater than the one before
expect(previous).toBeLessThanOrEqual(coordinates[0]);
[previous] = coordinates;
}));
});
});
describe('within', () => {
type Point = [number, number];
const polygon: Point[] = [
[9.0, 19.0], // bottom-left
[9.0, 21.0], // top-left
[11.0, 21.0], // top-right
[11.0, 19.0], // bottom-right
[9.0, 19.0], // back to starting point to close the polygon
];
it('should return a document with the point inside the polygon', async () => {
// There should be 1 total points document populated by default with the point [10, 20]
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
within: {
type: 'Polygon',
coordinates: [polygon],
},
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(1);
});
it('should not return a document with the point outside a smaller polygon', async () => {
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
within: {
type: 'Polygon',
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
},
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(0);
});
});
describe('intersects', () => {
type Point = [number, number];
const polygon: Point[] = [
[9.0, 19.0], // bottom-left
[9.0, 21.0], // top-left
[11.0, 21.0], // top-right
[11.0, 19.0], // bottom-right
[9.0, 19.0], // back to starting point to close the polygon
];
it('should return a document with the point intersecting the polygon', async () => {
// There should be 1 total points document populated by default with the point [10, 20]
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
intersects: {
type: 'Polygon',
coordinates: [polygon],
},
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(1);
});
it('should not return a document with the point not intersecting a smaller polygon', async () => {
const { status, result } = await client.find({
slug: pointSlug,
query: {
point: {
intersects: {
type: 'Polygon',
coordinates: [polygon.map((vertex) => vertex.map((coord) => coord * 0.1))], // Reduce polygon to 10% of its size
},
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(0);
});
});
it('or', async () => {
const post1 = await createPost({ title: 'post1' });
const post2 = await createPost({ title: 'post2' });
await createPost();
const { status, result } = await client.find<Post>({
query: {
or: [
{
title: {
equals: post1.title,
},
},
{
title: {
equals: post2.title,
},
},
],
},
});
expect(status).toEqual(200);
const expectedDocs = [post1, post2];
expect(result.totalDocs).toEqual(expectedDocs.length);
expect(result.docs).toEqual(expect.arrayContaining(expectedDocs));
});
it('or - 1 result', async () => {
const post1 = await createPost({ title: 'post1' });
await createPost();
const { status, result } = await client.find<Post>({
query: {
or: [
{
title: {
equals: post1.title,
},
},
{
title: {
equals: 'non-existent',
},
},
],
},
});
expect(status).toEqual(200);
const expectedDocs = [post1];
expect(result.totalDocs).toEqual(expectedDocs.length);
expect(result.docs).toEqual(expect.arrayContaining(expectedDocs));
});
it('and', async () => {
const description = 'description';
const post1 = await createPost({ title: 'post1', description });
await createPost({ title: 'post2', description }); // Diff title, same desc
await createPost();
const { status, result } = await client.find<Post>({
query: {
and: [
{
title: {
equals: post1.title,
},
},
{
description: {
equals: description,
},
},
],
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([post1]);
});
describe('limit', () => {
beforeEach(async () => {
await mapAsync([...Array(50)], async (_, i) => createPost({ title: 'limit-test', number: i }));
});
it('should query a limited set of docs', async () => {
const { status, result } = await client.find<Post>({
limit: 15,
query: {
title: {
equals: 'limit-test',
},
},
});
expect(status).toEqual(200);
expect(result.docs).toHaveLength(15);
});
it('should query all docs when limit=0', async () => {
const { status, result } = await client.find<Post>({
limit: 0,
query: {
title: {
equals: 'limit-test',
},
},
});
expect(status).toEqual(200);
expect(result.totalDocs).toEqual(50);
});
});
it('can query deeply nested fields within rows, tabs, collapsibles', async () => {
const withDeeplyNestedField = await createPost({ D1: { D2: { D3: { D4: 'nested message' } } } });
const { result } = await client.find<Post>({
query: {
'D1.D2.D3.D4': {
equals: 'nested message',
},
},
});
expect(result.totalDocs).toEqual(1);
expect(result.docs).toEqual([withDeeplyNestedField]);
});
});
});
});
async function createPost(overrides?: Partial<Post>) {
const { doc } = await client.create<Post>({ data: { title: 'title', ...overrides } });
return doc;
}
async function createPosts(count: number) {
await mapAsync([...Array(count)], async () => {
await createPost();
});
}
async function clearDocs(): Promise<void> {
const allDocs = await payload.find({ collection: slug, limit: 100 });
const ids = allDocs.docs.map((doc) => doc.id);
await mapAsync(ids, async (id) => {
await payload.delete({ collection: slug, id });
});
}