Skip to content

Commit

Permalink
Merge pull request #75 from Relewise/feat/popularity-multiplier-selector
Browse files Browse the repository at this point in the history
Feat: support popularity multiplier selectors
  • Loading branch information
mzanoni authored Aug 13, 2024
2 parents 80479fb + 33f1394 commit eb2ada8
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export * from './purchasedWithMultipleProductsBuilder';
export * from './purchasedWithProductBuilder';
export * from './searchTermBasedProductRecommendationBuilder';
export * from './sortProductsBuilder';
export * from './similarProductsProductBuilder';
export * from './similarProductsProductBuilder';
export * from './popularityMultiplierBuilder';
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Settings } from '../../../builders/settings';
import { PopularProductsRequest } from '../../../models/data-contracts';
import { PopularityMultiplierBuilder } from './popularityMultiplierBuilder';
import { ProductSettingsRecommendationBuilder } from './productSettingsRecommendationBuilder';
import { ProductsRecommendationBuilder } from './productsRecommendationBuilder';

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

constructor(
settings: Settings) {
Expand All @@ -24,13 +26,20 @@ export class PopularProductsBuilder extends ProductSettingsRecommendationBuilder
return this;
}

public setPopularityMultiplier(popularityMultiplierBuilder: (popularityMultiplierBuilder: PopularityMultiplierBuilder) => void) {
popularityMultiplierBuilder(this.popularityMultiplierBuilder);

return this;
}

public build() {
const request: PopularProductsRequest = {
$type: 'Relewise.Client.Requests.Recommendations.PopularProductsRequest, Relewise.Client',
...this.baseBuild(),
settings: this.recommendationSettings,
basedOn: this.basedOnSelection,
sinceMinutesAgo: this.since,
popularityMultiplier: this.popularityMultiplierBuilder.build(),
};

return request;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DataKeyPopularityMultiplierSelector, PopularityMultiplierSelector } from '../../../models/data-contracts';

export class PopularityMultiplierBuilder {
private popularityMultiplierSelector: PopularityMultiplierSelector | null = null;

public setDataKeyPopularityMultiplierSelector(selector: { key?: string | null }): this {
const dataKeyPopularityMultiplierSelector: DataKeyPopularityMultiplierSelector = {
$type: 'Relewise.Client.Requests.PopularityMultiplierSelectors.DataKeyPopularityMultiplierSelector, Relewise.Client',
...selector,
}

this.popularityMultiplierSelector = dataKeyPopularityMultiplierSelector;
return this;
}

build(): PopularityMultiplierSelector | null {
return this.popularityMultiplierSelector;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataValueFactory, ProductRecommendationResponse, ProductsViewedAfterViewingProductBuilder, PurchasedWithProductBuilder, Recommender, UserFactory } from '../../src';
import { DataValueFactory, PopularProductsBuilder, ProductRecommendationResponse, ProductsViewedAfterViewingProductBuilder, PurchasedWithProductBuilder, Recommender, UserFactory } from '../../src';
import { test, expect } from '@jest/globals'

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

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

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

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

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

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

expect(result).not.toBe(undefined);
expect(result!.recommendations?.length).toBeGreaterThan(0);
Expand All @@ -36,18 +36,29 @@ test('ProductsViewedAfterViewingProduct with all conditions', async() => {
displayedAtLocation: 'integration test Conditions',
user: UserFactory.anonymous(),
})
.product({productId: '1'})
.product({ productId: '1' })
.filters(f => f
.addProductDataFilter('ShortDescription', b => b
.addContainsCondition(DataValueFactory.stringCollection(['d']), 'Any')
.addContainsCondition(DataValueFactory.booleanCollection([true]), 'Any')
.addContainsCondition(DataValueFactory.doubleCollection([1]), 'Any')
.addContainsCondition(DataValueFactory.multilingual([{language: 'en-us', value: 'd'}]), 'Any')
.addContainsCondition(DataValueFactory.multiCurrency([{currency: 'USD', amount: 1}]), 'Any'),
.addContainsCondition(DataValueFactory.multilingual([{ language: 'en-us', value: 'd' }]), 'Any')
.addContainsCondition(DataValueFactory.multiCurrency([{ currency: 'USD', amount: 1 }]), 'Any'),
));

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

expect(result).not.toBe(undefined);
expect(result!.recommendations?.length).toEqual(0);
});

test('ProductsViewedAfterViewingProduct with all conditions', async() => {

const recommendationBuilder = new PopularProductsBuilder(settings)
.setPopularityMultiplier(pm => pm.setDataKeyPopularityMultiplierSelector({ key: 'some-data-key' }));

const result: ProductRecommendationResponse | undefined = await recommender.recommendPopularProducts(recommendationBuilder.build());

expect(result).not.toBe(undefined);
expect(result!.recommendations?.length).toBeGreaterThan(0);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { UserFactory } from '../../../../src/factory';
import { test, expect } from '@jest/globals'
import { PopularProductsRequest } from '../../../../src/models/data-contracts';
import { PopularProductsBuilder } from '../../../../src';

function baseBuilder() {
return new PopularProductsBuilder({
language: 'da-DK',
currency: 'DKK',
displayedAtLocation: 'unit test',
user: UserFactory.anonymous(),
});
};

test('setPopularityMultiplier', () => {
const key: string = 'data-key';

const subject: PopularProductsRequest = baseBuilder()
.setPopularityMultiplier(pm => pm.setDataKeyPopularityMultiplierSelector({ key: key }))
.build();

expect(subject.popularityMultiplier?.key).toBe(key);
});

0 comments on commit eb2ada8

Please sign in to comment.