Skip to content

Commit eb2ada8

Browse files
authored
Merge pull request #75 from Relewise/feat/popularity-multiplier-selector
Feat: support popularity multiplier selectors
2 parents 80479fb + 33f1394 commit eb2ada8

File tree

5 files changed

+70
-7
lines changed

5 files changed

+70
-7
lines changed

packages/client/src/builders/recommendation/products/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export * from './purchasedWithMultipleProductsBuilder';
1313
export * from './purchasedWithProductBuilder';
1414
export * from './searchTermBasedProductRecommendationBuilder';
1515
export * from './sortProductsBuilder';
16-
export * from './similarProductsProductBuilder';
16+
export * from './similarProductsProductBuilder';
17+
export * from './popularityMultiplierBuilder';

packages/client/src/builders/recommendation/products/popularProductsBuilder.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Settings } from '../../../builders/settings';
22
import { PopularProductsRequest } from '../../../models/data-contracts';
3+
import { PopularityMultiplierBuilder } from './popularityMultiplierBuilder';
34
import { ProductSettingsRecommendationBuilder } from './productSettingsRecommendationBuilder';
45
import { ProductsRecommendationBuilder } from './productsRecommendationBuilder';
56

67
export class PopularProductsBuilder extends ProductSettingsRecommendationBuilder implements ProductsRecommendationBuilder<PopularProductsRequest> {
78
private since: number = 0;
89
private basedOnSelection: 'MostPurchased' | 'MostViewed' = 'MostPurchased';
10+
private popularityMultiplierBuilder: PopularityMultiplierBuilder = new PopularityMultiplierBuilder();
911

1012
constructor(
1113
settings: Settings) {
@@ -24,13 +26,20 @@ export class PopularProductsBuilder extends ProductSettingsRecommendationBuilder
2426
return this;
2527
}
2628

29+
public setPopularityMultiplier(popularityMultiplierBuilder: (popularityMultiplierBuilder: PopularityMultiplierBuilder) => void) {
30+
popularityMultiplierBuilder(this.popularityMultiplierBuilder);
31+
32+
return this;
33+
}
34+
2735
public build() {
2836
const request: PopularProductsRequest = {
2937
$type: 'Relewise.Client.Requests.Recommendations.PopularProductsRequest, Relewise.Client',
3038
...this.baseBuild(),
3139
settings: this.recommendationSettings,
3240
basedOn: this.basedOnSelection,
3341
sinceMinutesAgo: this.since,
42+
popularityMultiplier: this.popularityMultiplierBuilder.build(),
3443
};
3544

3645
return request;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { DataKeyPopularityMultiplierSelector, PopularityMultiplierSelector } from '../../../models/data-contracts';
2+
3+
export class PopularityMultiplierBuilder {
4+
private popularityMultiplierSelector: PopularityMultiplierSelector | null = null;
5+
6+
public setDataKeyPopularityMultiplierSelector(selector: { key?: string | null }): this {
7+
const dataKeyPopularityMultiplierSelector: DataKeyPopularityMultiplierSelector = {
8+
$type: 'Relewise.Client.Requests.PopularityMultiplierSelectors.DataKeyPopularityMultiplierSelector, Relewise.Client',
9+
...selector,
10+
}
11+
12+
this.popularityMultiplierSelector = dataKeyPopularityMultiplierSelector;
13+
return this;
14+
}
15+
16+
build(): PopularityMultiplierSelector | null {
17+
return this.popularityMultiplierSelector;
18+
}
19+
}

packages/client/tests/integration-tests/productRecommendations.integration.test.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DataValueFactory, ProductRecommendationResponse, ProductsViewedAfterViewingProductBuilder, PurchasedWithProductBuilder, Recommender, UserFactory } from '../../src';
1+
import { DataValueFactory, PopularProductsBuilder, ProductRecommendationResponse, ProductsViewedAfterViewingProductBuilder, PurchasedWithProductBuilder, Recommender, UserFactory } from '../../src';
22
import { test, expect } from '@jest/globals'
33

44
const { npm_config_API_KEY: API_KEY, npm_config_DATASET_ID: DATASET_ID, npm_config_SERVER_URL: SERVER_URL } = process.env;
@@ -14,15 +14,15 @@ const settings = {
1414

1515
test('PurchasedWithProduct', async() => {
1616

17-
const result: ProductRecommendationResponse | undefined = await recommender.recommendPurchasedWithProduct(new PurchasedWithProductBuilder(settings).product({productId: '1'}).build());
17+
const result: ProductRecommendationResponse | undefined = await recommender.recommendPurchasedWithProduct(new PurchasedWithProductBuilder(settings).product({ productId: '1' }).build());
1818

1919
expect(result).not.toBe(undefined);
2020
expect(result!.recommendations?.length).toBeGreaterThan(0);
2121
});
2222

2323
test('ProductsViewedAfterViewingProduct', async() => {
2424

25-
const result: ProductRecommendationResponse | undefined = await recommender.recommendProductsViewedAfterViewingProduct(new ProductsViewedAfterViewingProductBuilder(settings).product({productId: '1'}).build());
25+
const result: ProductRecommendationResponse | undefined = await recommender.recommendProductsViewedAfterViewingProduct(new ProductsViewedAfterViewingProductBuilder(settings).product({ productId: '1' }).build());
2626

2727
expect(result).not.toBe(undefined);
2828
expect(result!.recommendations?.length).toBeGreaterThan(0);
@@ -36,18 +36,29 @@ test('ProductsViewedAfterViewingProduct with all conditions', async() => {
3636
displayedAtLocation: 'integration test Conditions',
3737
user: UserFactory.anonymous(),
3838
})
39-
.product({productId: '1'})
39+
.product({ productId: '1' })
4040
.filters(f => f
4141
.addProductDataFilter('ShortDescription', b => b
4242
.addContainsCondition(DataValueFactory.stringCollection(['d']), 'Any')
4343
.addContainsCondition(DataValueFactory.booleanCollection([true]), 'Any')
4444
.addContainsCondition(DataValueFactory.doubleCollection([1]), 'Any')
45-
.addContainsCondition(DataValueFactory.multilingual([{language: 'en-us', value: 'd'}]), 'Any')
46-
.addContainsCondition(DataValueFactory.multiCurrency([{currency: 'USD', amount: 1}]), 'Any'),
45+
.addContainsCondition(DataValueFactory.multilingual([{ language: 'en-us', value: 'd' }]), 'Any')
46+
.addContainsCondition(DataValueFactory.multiCurrency([{ currency: 'USD', amount: 1 }]), 'Any'),
4747
));
4848

4949
const result: ProductRecommendationResponse | undefined = await recommender.recommendProductsViewedAfterViewingProduct(recommendationBuilder.build());
5050

5151
expect(result).not.toBe(undefined);
5252
expect(result!.recommendations?.length).toEqual(0);
53+
});
54+
55+
test('ProductsViewedAfterViewingProduct with all conditions', async() => {
56+
57+
const recommendationBuilder = new PopularProductsBuilder(settings)
58+
.setPopularityMultiplier(pm => pm.setDataKeyPopularityMultiplierSelector({ key: 'some-data-key' }));
59+
60+
const result: ProductRecommendationResponse | undefined = await recommender.recommendPopularProducts(recommendationBuilder.build());
61+
62+
expect(result).not.toBe(undefined);
63+
expect(result!.recommendations?.length).toBeGreaterThan(0);
5364
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { UserFactory } from '../../../../src/factory';
2+
import { test, expect } from '@jest/globals'
3+
import { PopularProductsRequest } from '../../../../src/models/data-contracts';
4+
import { PopularProductsBuilder } from '../../../../src';
5+
6+
function baseBuilder() {
7+
return new PopularProductsBuilder({
8+
language: 'da-DK',
9+
currency: 'DKK',
10+
displayedAtLocation: 'unit test',
11+
user: UserFactory.anonymous(),
12+
});
13+
};
14+
15+
test('setPopularityMultiplier', () => {
16+
const key: string = 'data-key';
17+
18+
const subject: PopularProductsRequest = baseBuilder()
19+
.setPopularityMultiplier(pm => pm.setDataKeyPopularityMultiplierSelector({ key: key }))
20+
.build();
21+
22+
expect(subject.popularityMultiplier?.key).toBe(key);
23+
});

0 commit comments

Comments
 (0)