diff --git a/src/lib/query.ts b/src/lib/query.ts index ba9a1cfd..3415ab73 100644 --- a/src/lib/query.ts +++ b/src/lib/query.ts @@ -201,6 +201,24 @@ export class Query extends BaseQuery { return this; } + /** + * @method notExists + * @memberof Query + * @description Returns the raw (JSON) query based on the filters applied on Query object. + * @example + * import contentstack from '@contentstack/delivery-sdk' + * + * const stack = contentstack.Stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" }); + * const query = stack.contentType("contentTypeUid").entry().query(); + * const result = notExists('fieldUid').find() + * + * @returns {Query} + */ + notExists(key: string): Query { + this._parameters[key] = { '$exists': false }; + return this; + } + /** * @method or * @memberof Query @@ -215,19 +233,35 @@ export class Query extends BaseQuery { * * @returns {Query} */ - notExists(key: string): Query { - this._parameters[key] = { '$exists': false }; + or(...queries: Query[]): Query { + const paramsList: BaseQueryParameters[] = []; + for (const queryItem of queries) { + paramsList.push(queryItem._parameters); + } + this._parameters.$or = paramsList; return this; } - or(...queries: Query[]): Query { - const combinedQuery: any = { $or: [] }; - for (const query of queries) { - combinedQuery.$or.push(query._parameters); + /** + * @method and + * @memberof Query + * @description Returns the raw (JSON) query based on the filters applied on Query object. + * @example + * import contentstack from '@contentstack/delivery-sdk' + * + * const stack = contentstack.Stack({ apiKey: "apiKey", deliveryToken: "deliveryToken", environment: "environment" }); + * const query1 = await contentType.Entry().query().containedIn('fieldUID', ['value']); + * const query2 = await contentType.Entry().query().where('fieldUID', QueryOperation.EQUALS, 'value2'); + * const query = await contentType.Entry().query().and(query1, query2).find(); + * + * @returns {Query} + */ + and(...queries: Query[]): Query { + const paramsList: BaseQueryParameters[] = []; + for (const queryItem of queries) { + paramsList.push(queryItem._parameters); } - const newQuery: Query = Object.create(this); - newQuery._parameters = combinedQuery; - - return newQuery; + this._parameters.$and = paramsList; + return this; } } diff --git a/test/api/entry-queryables.spec.ts b/test/api/entry-queryables.spec.ts index d05d9919..f5657243 100644 --- a/test/api/entry-queryables.spec.ts +++ b/test/api/entry-queryables.spec.ts @@ -37,13 +37,14 @@ describe('Query Operators API test cases', () => { expect((query.entries[0] as any).multi_line).not.toBeDefined() } }); + it('should return entries matching any of the conditions - or', async () => { const query1: Query = await makeEntries('contenttype_uid').query().containedIn('title', ['value']); const query2: Query = await makeEntries('contenttype_uid').query().where('title', QueryOperation.EQUALS, 'value2'); const query = await makeEntries('contenttype_uid').query().or(query1, query2).find(); if (query.entries) { - expect(query.entries).toHaveLength(2); + expect(query.entries.length).toBeGreaterThan(0); expect(query.entries[0]._version).toBeDefined(); expect(query.entries[0].locale).toBeDefined(); expect(query.entries[0].uid).toBeDefined(); @@ -54,6 +55,45 @@ describe('Query Operators API test cases', () => { expect(query.entries[1].title).toBe('value'); } }); + + it('should return entries when at least 1 entry condition is matching - or', async () => { + const query1: Query = await makeEntries('contenttype_uid').query().containedIn('title', ['value0']); + const query2: Query = await makeEntries('contenttype_uid').query().where('title', QueryOperation.EQUALS, 'value2'); + const query = await makeEntries('contenttype_uid').query().or(query1, query2).find(); + + if (query.entries) { + expect(query.entries.length).toBeGreaterThan(0); + expect(query.entries[0]._version).toBeDefined(); + expect(query.entries[0].locale).toBeDefined(); + expect(query.entries[0].uid).toBeDefined(); + expect(query.entries[0].title).toBe('value2'); + } + }); + + it('should return entry both conditions are matching - and', async () => { + const query1: Query = await makeEntries('contenttype_uid').query().containedIn('title', ['value']); + const query2: Query = await makeEntries('contenttype_uid').query().where('locale', QueryOperation.EQUALS, 'en-us'); + const query = await makeEntries('contenttype_uid').query().and(query1, query2).find(); + + if (query.entries) { + expect(query.entries.length).toBeGreaterThan(0); + expect(query.entries[0]._version).toBeDefined(); + expect(query.entries[0].locale).toBeDefined(); + expect(query.entries[0].uid).toBeDefined(); + expect(query.entries[0].title).toBe('value'); + } + }); + + it('should return null when any one condition is not matching - and', async () => { + const query1: Query = await makeEntries('contenttype_uid').query().containedIn('title', ['value0']); + const query2: Query = await makeEntries('contenttype_uid').query().where('locale', QueryOperation.EQUALS, 'fr-fr'); + const query = await makeEntries('contenttype_uid').query().and(query1, query2).find(); + + if (query.entries) { + expect(query.entries).toHaveLength(0); + + } + }); }); function makeEntries(contentTypeUid = ''): Entries { diff --git a/test/unit/entry-queryable.spec.ts b/test/unit/entry-queryable.spec.ts index e3c12acd..06763e25 100644 --- a/test/unit/entry-queryable.spec.ts +++ b/test/unit/entry-queryable.spec.ts @@ -36,5 +36,11 @@ describe('Query Operators API test cases', () => { const query2: Query = await contentType.Entry().query().where('fieldUID', QueryOperation.EQUALS, 'value2'); const query = await contentType.Entry().query().or(query1, query2); expect(query._parameters).toStrictEqual({ '$or': [ {'fieldUID': {'$in': ['value']}}, { 'fieldUID': 'value2' } ] }); - }); + }); + it('should return entry when both conditions are matching - and', async () => { + const query1: Query = await contentType.Entry().query().containedIn('fieldUID', ['value']); + const query2: Query = await contentType.Entry().query().where('fieldUID', QueryOperation.EQUALS, 'value2'); + const query = await contentType.Entry().query().and(query1, query2); + expect(query._parameters).toStrictEqual({ '$and': [ {'fieldUID': {'$in': ['value']}}, { 'fieldUID': 'value2' } ] }); + }); }); \ No newline at end of file