Skip to content

Commit

Permalink
Merge pull request #41 from Relewise/feat/objectpath-and-scopes
Browse files Browse the repository at this point in the history
feat: implement objectpath and scopes for filters
  • Loading branch information
mzanoni authored Sep 28, 2023
2 parents c2843b8 + 240eb37 commit 32e68cc
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 23 deletions.
64 changes: 50 additions & 14 deletions lib/src/builders/filterBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { AndFilter, BrandAssortmentFilter, BrandDataFilter, BrandIdFilter, CartDataFilter, ContentCategoryAssortmentFilter, ContentCategoryDataFilter, ContentCategoryHasAncestorFilter, ContentCategoryHasChildFilter, ContentCategoryHasParentFilter, ContentCategoryIdFilter, ContentCategoryLevelFilter, ContentDataFilter, ContentIdFilter, Filter, FilterCollection, OrFilter, ProductAndVariantId, ProductAndVariantIdFilter, ProductAssortmentFilter, ProductCategoryAssortmentFilter, ProductCategoryDataFilter, ProductCategoryHasAncestorFilter, ProductCategoryHasChildFilter, ProductCategoryHasParentFilter, ProductCategoryIdFilter, ProductCategoryLevelFilter, ProductDataFilter, ProductDisplayNameFilter, ProductHasVariantsFilter, ProductIdFilter, ProductListPriceFilter, ProductRecentlyPurchasedByUserFilter, ProductRecentlyViewedByUserFilter, ProductSalesPriceFilter, VariantAssortmentFilter, VariantDataFilter, VariantIdFilter, VariantListPriceFilter, VariantSalesPriceFilter, VariantSpecificationFilter } from '../models/data-contracts';
import { FilterSettingsBuilder } from './filterSettingsBuilder';
import { ConditionBuilder } from './conditionBuilder';

export type EntityDataFilterOptions = {
objectPath?: string[],
filterSettings?: (builder: FilterSettingsBuilder) => void
};

export class FilterBuilder {
private filters: (AndFilter
| BrandAssortmentFilter
Expand Down Expand Up @@ -463,17 +469,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addProductDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addProductDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: ProductDataFilter = {
$type: 'Relewise.Client.Requests.Filters.ProductDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand All @@ -488,17 +499,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addVariantDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addVariantDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: VariantDataFilter = {
$type: 'Relewise.Client.Requests.Filters.VariantDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand All @@ -513,17 +529,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addBrandDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addBrandDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: BrandDataFilter = {
$type: 'Relewise.Client.Requests.Filters.BrandDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand Down Expand Up @@ -563,17 +584,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addContentCategoryDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addContentCategoryDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: ContentCategoryDataFilter = {
$type: 'Relewise.Client.Requests.Filters.ContentCategoryDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand All @@ -588,17 +614,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addContentDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addContentDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: ContentDataFilter = {
$type: 'Relewise.Client.Requests.Filters.ContentDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand All @@ -613,17 +644,22 @@ export class FilterBuilder {
* @param filterOutIfKeyIsNotFound
* @param negated
*/
public addProductCategoryDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false): this {
public addProductCategoryDataFilter(key: string, conditionBuilder: (builder: ConditionBuilder) => void, mustMatchAllConditions: boolean = true, filterOutIfKeyIsNotFound: boolean = true, negated: boolean = false, options?: EntityDataFilterOptions): this {
const builder = new ConditionBuilder();
conditionBuilder(builder);

const internalSettingsBuilder = new FilterSettingsBuilder();
options?.filterSettings?.(internalSettingsBuilder);

const filter: ProductCategoryDataFilter = {
$type: 'Relewise.Client.Requests.Filters.ProductCategoryDataFilter, Relewise.Client',
key: key,
filterOutIfKeyIsNotFound: filterOutIfKeyIsNotFound,
mustMatchAllConditions: mustMatchAllConditions,
conditions: builder.build(),
negated: negated,
objectPath: options?.objectPath,
settings: internalSettingsBuilder.build(),
};
this.filters.push(filter);

Expand Down Expand Up @@ -681,7 +717,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -697,7 +733,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -713,7 +749,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -729,7 +765,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -745,7 +781,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -761,7 +797,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -777,7 +813,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand All @@ -793,7 +829,7 @@ export class FilterBuilder {
negated: negated,
};
this.filters.push(filter);

return this;
}

Expand Down
34 changes: 34 additions & 0 deletions lib/src/builders/filterScopesBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ApplyFilterSettings, FilterScopes } from '../models/data-contracts';

export class FilterScopesBuilder {

private fillScope: ApplyFilterSettings | undefined = undefined;
private defaultScope: ApplyFilterSettings | undefined = undefined;

public fill({ apply }: { apply: boolean; }): this {
this.fillScope = {
$type: 'Relewise.Client.Requests.Filters.Settings.ApplyFilterSettings, Relewise.Client',
apply,
};

return this;
}

public default({ apply }: { apply: boolean; }): this {
this.defaultScope = {
$type: 'Relewise.Client.Requests.Filters.Settings.ApplyFilterSettings, Relewise.Client',
apply,
};

return this;
}

public build(): FilterScopes | null {
return this.fillScope || this.defaultScope
? {
fill: this.fillScope,
default: this.defaultScope,
}
: null;
}
}
19 changes: 19 additions & 0 deletions lib/src/builders/filterSettingsBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FilterSettings } from '../models/data-contracts';
import { FilterScopesBuilder } from './filterScopesBuilder';

export class FilterSettingsBuilder {
private scopesBuilder: FilterScopesBuilder = new FilterScopesBuilder();

public scopes(builder: (builder: FilterScopesBuilder) => void): this {
builder(this.scopesBuilder);

return this;
}

public build(): FilterSettings | null {
const scopes = this.scopesBuilder.build();
return scopes
? { scopes: scopes }
: null;
}
}
2 changes: 2 additions & 0 deletions lib/src/builders/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from './settings';
export * from './filterScopesBuilder';
export * from './filterSettingsBuilder';
export * from './dataObjectFilterConditionBuilder';
export * from './filterBuilder';
export * from './paginationBuilder';
Expand Down
19 changes: 18 additions & 1 deletion lib/tests/integration-tests/filters.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,28 @@ test('Product Assortment filter', async() => {
test('Product Id filter', async() => {

const request: ProductSearchRequest = baseBuilder()
.filters(f => f.addProductIdFilter(['1']))
.filters(f => f.addProductIdFilter(['1'])
.addVariantDataFilter('avaliableMarkets', c => c.addGreaterThanCondition(1693526400 - 1)))
.pagination(p => p.setPageSize(20))
.build();

const result = await searcher.searchProducts(request);

expect(result?.results?.length).toBe(1);
});

test('Product Variant Object Path filter', async() => {

const request: ProductSearchRequest = baseBuilder()
.filters(f => f.addVariantDataFilter('avaliableMarkets', c => c.addGreaterThanCondition(1693526400 - 1), undefined, undefined, undefined,
{
objectPath: ['US', 'ValidFromDate'],
filterSettings: s => s.scopes(sc => sc.fill({ apply: true }).default({ apply: false })),
}))
.pagination(p => p.setPageSize(20))
.build();

const result = await searcher.searchProducts(request);

expect(result?.results?.length).toBe(20);
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,7 @@ test('ProductSearch: Relevance modifier without conditions', async() => {
});

test('Product search - data object facets', async() => {
var builder = new ProductSearchBuilder({
language: 'da',
currency: 'DKK',
displayedAtLocation: 'integration test - dataobjects',
user: UserFactory.anonymous(),
});

const request: ProductSearchRequest = builder
const request: ProductSearchRequest = baseProductBuilder()
.facets(f => f.addProductDataObjectFacet(
't',
'Product',
Expand Down

0 comments on commit 32e68cc

Please sign in to comment.