From f5b9fa3eb23494df7007ab2d26be61b53e519c7d Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 16 Aug 2023 22:31:20 +0300 Subject: [PATCH] test: Update of semantics - Strapi build types, added more complex query with dynamic zones. - Fixed test description to be more fluent in reading. - Added test for _isDefined util --- package.json | 2 +- tests/build-types.test.ts | 67 ++++++++++++++----- tests/data.test.ts | 4 +- ...ion.test.ts => dynamic-population.test.ts} | 10 +-- tests/empty-operators.test.ts | 12 ++-- tests/fields.test.ts | 10 +-- tests/filters-complex-level.test.ts | 45 +++++++------ tests/filters-one-level.test.ts | 32 ++++----- tests/pagination.test.ts | 2 +- ...performanceTest.js => performance-test.js} | 0 tests/population.test.ts | 21 +++--- tests/public-functions.test.ts | 14 ++-- tests/sort.test.ts | 26 +++---- tests/utils.test.ts | 17 +++-- 14 files changed, 152 insertions(+), 110 deletions(-) rename tests/{morph-population.test.ts => dynamic-population.test.ts} (95%) rename tests/{performanceTest.js => performance-test.js} (100%) diff --git a/package.json b/package.json index 377c346..d4ab9c5 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "build": "npm run clean && npm run build:esm && npm run build:cjs && npm run pretty", "prepack": "npm run build", "test": "npm run build && jest", - "speed": "node tests/performanceTest.js", + "speed": "node tests/performance-test.js", "coverage": "jest --coverage", "semantic-release": "semantic-release" }, diff --git a/tests/build-types.test.ts b/tests/build-types.test.ts index 01f3b82..890bdbd 100644 --- a/tests/build-types.test.ts +++ b/tests/build-types.test.ts @@ -5,13 +5,13 @@ const strapiService = { $and: [ { attribute: { - $eq: "attribute", + $eq: "value", }, }, { nested: { attribute: { - $eq: "attribute", + $eq: "value", }, }, }, @@ -22,7 +22,14 @@ const strapiService = { attribute: { filters: { attribute: { - $eq: "attribute", + $eq: "value", + }, + }, + }, + dynamicZone: { + on: { + component: { + fields: ["attribute"], }, }, }, @@ -32,6 +39,7 @@ const strapiService = { locale: "uk", pagination: { page: 5, + pageSize: 24, withCount: true, }, }; @@ -41,13 +49,13 @@ const entityService = { $and: [ { attribute: { - $eq: "attribute", + $eq: "value", }, }, { nested: { attribute: { - $eq: "attribute", + $eq: "value", }, }, }, @@ -58,13 +66,21 @@ const entityService = { attribute: { filters: { attribute: { - $eq: "attribute", + $eq: "value", + }, + }, + }, + dynamicZone: { + on: { + component: { + fields: ["attribute"], }, }, }, }, fields: ["attribute"], page: 5, + pageSize: 24, }; const queryEngine = { @@ -72,13 +88,13 @@ const queryEngine = { $and: [ { attribute: { - $eq: "attribute", + $eq: "value", }, }, { nested: { attribute: { - $eq: "attribute", + $eq: "value", }, }, }, @@ -89,30 +105,47 @@ const queryEngine = { attribute: { where: { attribute: { - $eq: "attribute", + $eq: "value", + }, + }, + }, + dynamicZone: { + on: { + component: { + select: ["attribute"], }, }, }, }, select: ["attribute"], start: 5, + limit: 24, }; -describe("Strapi query build types", () => { - it("should build strapi proper structure queries", () => { +describe("Strapi query builder", () => { + it("should build proper strapi structure of queries", () => { const query = new SQBuilder() .sort("attribute") .asc() .fields("attribute") - .filters("attribute", (b) => b.eq("attribute")) - .filters("nested.attribute", (b) => b.eq("attribute")) - .populate("attribute", (b) => b.filters("attribute").eq("attribute")) + .filters("attribute", (b) => b.eq("value")) + .filters("nested.attribute", (b) => b.eq("value")) + .populate("attribute", (b) => b.filters("attribute").eq("value")) + .populate("dynamicZone", (dynamicZoneBuilder) => { + dynamicZoneBuilder.on("component", (b) => b.fields("attribute")); + }) .publicationState("preview") .locale("uk"); - const serviceBuilt = query.page(5, true).buildStrapiService(); - const entityServiceBuilt = query.page(5, true).buildEntityService(); - const queryEngineBuilt = query.pageStart(5).buildQueryEngine(); + const serviceBuilt = query.page(5, true).pageSize(24).buildStrapiService(); + const entityServiceBuilt = query + .page(5, true) + .pageSize(24) + .buildEntityService(); + const queryEngineBuilt = query + .pageStart(5) + .pageLimit(24) + .buildQueryEngine(); expect(serviceBuilt).toEqual(strapiService); expect(entityServiceBuilt).toEqual(entityService); diff --git a/tests/data.test.ts b/tests/data.test.ts index b16c570..0f17818 100644 --- a/tests/data.test.ts +++ b/tests/data.test.ts @@ -2,8 +2,8 @@ import SQBuilder from "../lib/cjs"; const dataObject = { key: "value", data: ["value2"] }; -describe("Data", () => { - it("should be data", () => { +describe("Data operator", () => { + it("should be same as input", () => { const query = new SQBuilder().data(dataObject).build(); expect(query.data).toEqual(dataObject); }); diff --git a/tests/morph-population.test.ts b/tests/dynamic-population.test.ts similarity index 95% rename from tests/morph-population.test.ts rename to tests/dynamic-population.test.ts index 4df8c47..0236055 100644 --- a/tests/morph-population.test.ts +++ b/tests/dynamic-population.test.ts @@ -6,8 +6,8 @@ const mainKey2 = "key2"; const keyType1 = "keyType1"; const keyType2 = "ketType2"; -describe("Populate morph ", () => { - it("Morph single population", () => { +describe("Dynamic zone operator", () => { + it("should create proper query", () => { const builtQuery = new SQBuilder() .populate(mainKey, (keyBuilder) => { keyBuilder @@ -27,7 +27,7 @@ describe("Populate morph ", () => { expect(builtQuery).toEqual(morphQuery); }); - it("Morph multiple population", () => { + it("should create multiple dynamic zones query", () => { const builtQuery = new SQBuilder() .populate(mainKey, (keyBuilder) => { keyBuilder @@ -60,7 +60,7 @@ describe("Populate morph ", () => { expect(builtQuery).toEqual(twoMorphQuery); }); - it("Morph same key", () => { + it("should select last population for same dynamic zones", () => { const builtQuery = new SQBuilder() .populate(mainKey, (keyBuilder) => { keyBuilder @@ -93,7 +93,7 @@ describe("Populate morph ", () => { expect(builtQuery).toEqual(morphQuery); }); - it("Morph population join", () => { + it("should join", () => { const query1 = new SQBuilder().populate(mainKey, (keyBuilder) => { keyBuilder .on(keyType1, (typeBuilder) => { diff --git a/tests/empty-operators.test.ts b/tests/empty-operators.test.ts index 684fca5..629f26a 100644 --- a/tests/empty-operators.test.ts +++ b/tests/empty-operators.test.ts @@ -5,22 +5,22 @@ const emptyObject = {}; const attribute = "attr"; describe("Empty operators", () => { - it("Logical empty", () => { + it("should be empty for logical filters", () => { const query = new SQBuilder().or().and().not().build(); expect(query).toEqual(emptyObject); }); - it("Filters empty", () => { + it("should be empty for filters without selected operator", () => { const query = new SQBuilder().filters(attribute).filters(attribute).build(); expect(query).toEqual(emptyObject); }); - it("Attribute filters empty", () => { - const query = new SQBuilder(); + it("should be empty for all operators without filters request", () => { + const query = new SQBuilder(); for (const attr of attributeFilters) { - const fnAttr = attr.replace("$", "") as keyof SQBuilder; - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + const fnAttr = attr.replace("$", "") as keyof SQBuilder; + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder query[fnAttr](attribute); } diff --git a/tests/fields.test.ts b/tests/fields.test.ts index 3db75b5..a069d28 100644 --- a/tests/fields.test.ts +++ b/tests/fields.test.ts @@ -5,20 +5,20 @@ const filed1 = "key2"; const getFields = (key: string, key2: string) => ({ fields: [key, key2] }); -describe("Fields query", () => { - it("Chain", () => { +describe("Field operator", () => { + it("should create query by chain", () => { const builtQuery = new SQBuilder().fields(field).fields(filed1).build(); expect(builtQuery).toEqual(getFields(field, filed1)); }); - it("Array", () => { + it("should create query by array", () => { const builtQuery = new SQBuilder().fields([field, filed1]).build(); expect(builtQuery).toEqual(getFields(field, filed1)); }); - it("Same keys", () => { + it("should merge same keys", () => { const builtQuery = new SQBuilder() .fields([field, filed1, field, filed1]) .build(); @@ -26,7 +26,7 @@ describe("Fields query", () => { expect(builtQuery).toEqual(getFields(field, filed1)); }); - it("Join", () => { + it("should join query and merge same keys", () => { const query1 = new SQBuilder().fields([field]); const query2 = new SQBuilder().fields([filed1]); const query3 = new SQBuilder().fields([field]); diff --git a/tests/filters-complex-level.test.ts b/tests/filters-complex-level.test.ts index 5003d24..bd513ae 100644 --- a/tests/filters-complex-level.test.ts +++ b/tests/filters-complex-level.test.ts @@ -1,18 +1,20 @@ import SQBuilder from "../lib/cjs"; -describe("Filters - complex cases", () => { - it("Double nested - without root attribute", () => { +describe("Filters operator", () => { + it("should create nested filters without attribute", () => { const builtQuery = new SQBuilder() .and() - .filters() - .with((nestedBuilder) => - nestedBuilder - .or() - .filters("createdAt") - .lte("date1") - .filters("createdAt") - .gte("date2") + .filters((b) => + b.with((nestedBuilder) => + nestedBuilder + .or() + .filters("createdAt") + .lte("date1") + .filters("createdAt") + .gte("date2") + ) ) + .filters() .with((nestedBuilder) => nestedBuilder @@ -27,17 +29,18 @@ describe("Filters - complex cases", () => { expect(builtQuery).toEqual(doubleNestedOrInRootAnd); }); - it("Double nested - with few attribute", () => { + it("should create nested filters with attribute", () => { const builtQuery = new SQBuilder() .and() - .filters("attribute1") - .with((nestedBuilder) => - nestedBuilder - .or() - .filters("createdAt") - .lte("date1") - .filters("createdAt") - .gte("date2") + .filters("attribute1", (b) => + b.with((nestedBuilder) => + nestedBuilder + .or() + .filters("createdAt") + .lte("date1") + .filters("createdAt") + .gte("date2") + ) ) .filters("attribute2") .with((nestedBuilder) => @@ -53,7 +56,7 @@ describe("Filters - complex cases", () => { expect(builtQuery).toEqual(doubleNestedWithAttributes); }); - it("Complex filter with many nested filters, negations, inline building and wrong operations", () => { + it("should create complex query", () => { const builtQuery = new SQBuilder() .or() .filters("attribute1") @@ -105,7 +108,7 @@ describe("Filters - complex cases", () => { ) .filters() .with((nestedBuilder) => - // Try attach not filter specific data + // Try to create illegal operators on nested filter operator nestedBuilder .or() .filters("createdAt") diff --git a/tests/filters-one-level.test.ts b/tests/filters-one-level.test.ts index 8f88765..5764554 100644 --- a/tests/filters-one-level.test.ts +++ b/tests/filters-one-level.test.ts @@ -50,11 +50,11 @@ const getTwoResults = (type: string, negateRoot = false) => }, }; -describe("Filters - one level", () => { - it("Attributes", () => { +describe("Filters operator", () => { + it("should create filter query for all operators", () => { for (const atr of attributeFilters) { const fnAttr = atr.replace("$", ""); - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder const builtQuery = new SQBuilder() .filters(attribute) [fnAttr](value) @@ -64,10 +64,10 @@ describe("Filters - one level", () => { } }); - it("Attributes duplicates", () => { + it("should not duplicate filter query for all operators", () => { for (const attr of attributeFilters) { const fnAttr = attr.replace("$", ""); - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder const builtQuery = new SQBuilder() .filters(attribute) [fnAttr](value) @@ -79,10 +79,10 @@ describe("Filters - one level", () => { } }); - it("Two attributes with same key", () => { + it("should create query for single attribute and all operators", () => { for (const attr of attributeFilters) { const fnAttr = attr.replace("$", ""); - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder const builtQuery = new SQBuilder() .and() .filters(attribute) @@ -95,10 +95,10 @@ describe("Filters - one level", () => { } }); - it("Attribute negation", () => { + it("should create query with not for single attribute and all operators", () => { for (const atr of attributeFilters) { const fnAttr = atr.replace("$", ""); - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder const builtQuery = new SQBuilder() .filters(attribute) .not() @@ -109,10 +109,10 @@ describe("Filters - one level", () => { } }); - it("Root negation", () => { + it("should add not operator to root query", () => { for (const attr of attributeFilters) { const fnAttr = attr.replace("$", ""); - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) + // @ts-ignore TODO: Typescript won't iterate by keyof SQBuilder const builtQuery = new SQBuilder() .not() .and() @@ -126,14 +126,10 @@ describe("Filters - one level", () => { } }); - it("Join filters", () => { - const type = attributeFilters[0]; - const fnAttr = type.replace("$", ""); - - // @ts-ignore FIXME Why is it impossible (It's works but ts can't inherit function type from class by key) - const query = new SQBuilder().filters(attribute)[fnAttr](value); + it("should join filters", () => { + const query = new SQBuilder().filters(attribute).eq(value); const builtQuery = new SQBuilder().joinFilters(query).build(); - expect(builtQuery).toEqual(getResult(type)); + expect(builtQuery).toEqual(getResult("$eq")); }); }); diff --git a/tests/pagination.test.ts b/tests/pagination.test.ts index 5056da3..f2b386a 100644 --- a/tests/pagination.test.ts +++ b/tests/pagination.test.ts @@ -15,7 +15,7 @@ const paginationEntityQueryEngine = { pagination: { page: page, pageSize: size }, }; -describe("Pagination query", () => { +describe("Pagination operator", () => { it("should create offset pagination for strapi service", () => { const queryBuilder = new SQBuilder().pageStart(page, true).pageLimit(size); const service = queryBuilder.buildStrapiService(); diff --git a/tests/performanceTest.js b/tests/performance-test.js similarity index 100% rename from tests/performanceTest.js rename to tests/performance-test.js diff --git a/tests/population.test.ts b/tests/population.test.ts index 8568d49..e4103be 100644 --- a/tests/population.test.ts +++ b/tests/population.test.ts @@ -22,20 +22,20 @@ const fullQuery = { }, }; -describe("Populate query", () => { - it("Populate all", () => { +describe("Population operator", () => { + it("should populate all", () => { const builtQuery = new SQBuilder().populate("*").build(); expect(builtQuery).toEqual(getAllPopulate); }); - it("Populate all query engine", () => { + it("should populate all with true for query engine", () => { const builtQuery = new SQBuilder().populate("*").buildQueryEngine(); expect(builtQuery).toEqual(populateAllQueryEngine); }); - it("Populate keys with same key", () => { + it("should merge same keys", () => { const builtQuery = new SQBuilder() .populate([key1, key2]) .populate(key1) @@ -44,7 +44,7 @@ describe("Populate query", () => { expect(builtQuery).toEqual(getKeyPopulation); }); - it("Complex populate", () => { + it("should create nested population", () => { const builtQuery = new SQBuilder() .populate(key1, (key1Builder) => { key1Builder @@ -60,11 +60,14 @@ describe("Populate query", () => { expect(builtQuery).toEqual(fullQuery); }); - it("Illegal actions in complex populate", () => { + it("should skip illegal operators of population", () => { const builtQuery = new SQBuilder() .populate(key1, (key1Builder) => { key1Builder - .page(1) + .page(1, true) + .pageSize(24) + .locale("ua") + .publicationState("preview") .sort([key1]) .sort({ key: key2, type: "desc" }) .fields([key1, key2]) @@ -78,7 +81,7 @@ describe("Populate query", () => { expect(builtQuery).toEqual(fullQuery); }); - it("Key rewrite in complex populate", () => { + it("should select last population of same keys", () => { const builtQuery = new SQBuilder() .populate(key1) .populate(key1, (key1Builder) => { @@ -95,7 +98,7 @@ describe("Populate query", () => { expect(builtQuery).toEqual(fullQuery); }); - it("Complex merging in populate", () => { + it("should merge population", () => { const sortQuery = new SQBuilder() .sort([key1]) .sort({ key: key2, type: "desc" }); diff --git a/tests/public-functions.test.ts b/tests/public-functions.test.ts index 9395feb..7e7b449 100644 --- a/tests/public-functions.test.ts +++ b/tests/public-functions.test.ts @@ -20,8 +20,8 @@ const pubState = { publicationState: "preview" }; const locale = { locale: "uk" }; -describe("Readonly", () => { - it("Is readonly", () => { +describe("Utils function", () => { + it("should read only block modification", () => { const query = new SQBuilder() .populate(key1, (key1Builder) => { key1Builder @@ -53,12 +53,12 @@ describe("Readonly", () => { expect(query.build()).toEqual(fullQuery); }); - it("Publication state", () => { + it("should publication state works", () => { const builtQuery = new SQBuilder().publicationState("preview").build(); expect(builtQuery).toEqual(pubState); }); - it("Publication state - query builder eg entity service", () => { + it("should be publication state omitted for query engine", () => { const builtQuery = new SQBuilder() .publicationState("preview") .build("queryEngine"); @@ -66,18 +66,18 @@ describe("Readonly", () => { expect(builtQuery).toEqual({}); }); - it("Locale", () => { + it("should locale works for strapi service", () => { const builtQuery = new SQBuilder().locale("uk").build(); expect(builtQuery).toEqual(locale); }); - it("Locale - query builder eg entity service", () => { + it("should be locale omitted for query engine", () => { const builtQuery = new SQBuilder().locale("uk").build("queryEngine"); expect(builtQuery).toEqual({}); }); - it("Join All", () => { + it("should join queries", () => { const query1 = new SQBuilder() .sort({ key: key1, type: "asc" }) .fields(key1) diff --git a/tests/sort.test.ts b/tests/sort.test.ts index 3ea069b..d8f647d 100644 --- a/tests/sort.test.ts +++ b/tests/sort.test.ts @@ -14,14 +14,14 @@ const getFewDiffSorts = (key1: string, key2: string) => ({ sort: [{ [key1]: "asc" }, { [key2]: "desc" }], }); -describe("Sorting query", () => { - it("String", () => { +describe("Sort operator", () => { + it("should sort by string", () => { const builtQuery = new SQBuilder().sort(oneKey).build(); expect(builtQuery).toEqual(getOneSort(oneKey)); }); - it("Object", () => { + it("should sort by object", () => { const builtQuery = new SQBuilder() .sort({ key: oneKey, type: "asc" }) .build(); @@ -29,7 +29,7 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getOneSort(oneKey)); }); - it("Order", () => { + it("should change order", () => { const builtQuery = new SQBuilder() .sort({ key: oneKey, type: "desc" }) .build(); @@ -37,7 +37,7 @@ describe("Sorting query", () => { expect(builtQuery).not.toEqual(getOneSort(oneKey)); }); - it("Chain direction", () => { + it("should sort by chain", () => { const builtQuery = new SQBuilder() .sort(oneKey) .asc() @@ -48,7 +48,7 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getFewDiffSorts(oneKey, secondKey)); }); - it("Change all direction", () => { + it("should change root direction", () => { const builtQuery = new SQBuilder({ defaultSort: "desc" }) .sort(oneKey) .desc() @@ -60,7 +60,7 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getFewSorts(oneKey, secondKey)); }); - it("Same keys", () => { + it("should merge same keys", () => { const builtQuery = new SQBuilder() .sort([ { key: oneKey, type: "asc" }, @@ -72,13 +72,13 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getOneSort(oneKey)); }); - it("String array", () => { + it("should sort by string array", () => { const builtQuery = new SQBuilder().sort([oneKey, secondKey]).build(); expect(builtQuery).toEqual(getFewSorts(oneKey, secondKey)); }); - it("Object array", () => { + it("should sort by object array", () => { const builtQuery = new SQBuilder() .sort([ { key: oneKey, type: "asc" }, @@ -89,7 +89,7 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getFewSorts(oneKey, secondKey)); }); - it("Chain", () => { + it("should sort by chain of different forms", () => { const builtQuery = new SQBuilder() .sort(oneKey) .sort({ key: secondKey, type: "asc" }) @@ -98,7 +98,7 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getFewSorts(oneKey, secondKey)); }); - it("Deep by key", () => { + it("should create deep sort", () => { const builtQuery = new SQBuilder() .sort([{ key: `${oneKey}.${secondKey}`, type: "asc" }]) .build(); @@ -106,9 +106,9 @@ describe("Sorting query", () => { expect(builtQuery).toEqual(getDeepSort(oneKey, secondKey)); }); - it("Merging", () => { + it("should join sort", () => { const query1 = new SQBuilder().sort([oneKey]); - const query2 = new SQBuilder().sort([secondKey]); + const query2 = new SQBuilder().sort(secondKey); const builtQuery = query1.joinSort(query2).build(); diff --git a/tests/utils.test.ts b/tests/utils.test.ts index e0ffce2..a701f0d 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,4 +1,4 @@ -import { _set, _union, _unionBy } from "../lib/cjs/query-utils"; +import { _set, _union, _unionBy, _isDefined } from "../lib/cjs/query-utils"; const objectSet = { one: { @@ -19,24 +19,31 @@ const obj5 = { key: "five", value: "value1" }; const objArray = [obj1, obj2, obj5, obj3, obj4]; -describe("Empty operators", () => { - it("Set", () => { +describe("Utils", () => { + it("should set value with path notation", () => { const object = _set({}, "one.two.free", "value"); const addedAnotherKey = _set(object, "one.two.four", "value2"); expect(addedAnotherKey).toEqual(objectSet); }); - it("Union", () => { + it("should union values", () => { const arr1 = ["value1", "value1", "value2"]; const arr2 = ["value2"]; const union = _union(arr1, arr2); expect(union).toEqual(array); }); - it("UnionBy", () => { + it("should union by", () => { const arr1 = [obj1, obj2, obj5]; const arr2 = [obj3, obj4, obj5, obj1, obj2]; const union = _unionBy((b) => b.key, arr1, arr2); expect(union).toEqual(objArray); }); + + it("should detect undefined or null", () => { + expect(_isDefined(undefined)).toBe(false); + expect(_isDefined(null)).toBe(false); + expect(_isDefined(0)).toBe(true); + expect(_isDefined(false)).toBe(true); + }); });