@frak-labs/core-sdk
Version:
Core SDK of the Frak wallet, low level library to interact directly with the frak ecosystem.
330 lines (303 loc) • 10.8 kB
text/typescript
import { describe, expect, it } from "vitest";
import type { InteractionTypeKey } from "../constants/interactionTypes";
import type { EstimatedReward, MerchantReward, RuleConditions } from "../types";
import {
formatBestReward,
selectBestReward,
selectDisplayCampaign,
} from "./select";
const NOW = new Date("2025-01-15T00:00:00Z");
const unix = (iso: string) => Math.floor(new Date(iso).getTime() / 1000);
function fixedReward(eur: number): EstimatedReward {
return {
payoutType: "fixed",
amount: { amount: eur, eurAmount: eur, usdAmount: eur, gbpAmount: eur },
};
}
function uncappedPercentage(percent: number): EstimatedReward {
return { payoutType: "percentage", percent, percentOf: "purchase_amount" };
}
function startsAtCondition(iso: string): RuleConditions {
return [{ field: "time.timestamp", operator: "gte", value: unix(iso) }];
}
function campaign(opts: {
id: string;
interactionTypeKey?: InteractionTypeKey;
referrer?: EstimatedReward;
referee?: EstimatedReward;
conditions?: RuleConditions;
expiresAt?: string | null;
defaultLockupSeconds?: number;
}): MerchantReward {
return {
campaignId: opts.id,
name: opts.id,
interactionTypeKey: opts.interactionTypeKey ?? "purchase",
conditions: opts.conditions ?? [],
referrer: opts.referrer,
referee: opts.referee,
expiresAt: opts.expiresAt,
defaultLockupSeconds: opts.defaultLockupSeconds,
};
}
describe("selectDisplayCampaign", () => {
it("returns undefined for an empty set", () => {
expect(selectDisplayCampaign([], { now: NOW })).toBeUndefined();
});
it("picks the highest-reward live campaign", () => {
const result = selectDisplayCampaign(
[
campaign({ id: "low", referrer: fixedReward(2) }),
campaign({ id: "high", referrer: fixedReward(9) }),
],
{ now: NOW }
);
expect(result?.status).toBe("live");
expect(result?.campaign.campaignId).toBe("high");
});
it("prefers a live campaign over a richer upcoming one", () => {
const result = selectDisplayCampaign(
[
campaign({
id: "upcoming-rich",
referrer: fixedReward(50),
conditions: startsAtCondition("2025-03-01T00:00:00Z"),
}),
campaign({ id: "live-poor", referrer: fixedReward(3) }),
],
{ now: NOW }
);
expect(result?.status).toBe("live");
expect(result?.campaign.campaignId).toBe("live-poor");
});
it("falls back to the soonest-starting upcoming campaign", () => {
const result = selectDisplayCampaign(
[
campaign({
id: "later",
referrer: fixedReward(50),
conditions: startsAtCondition("2025-04-01T00:00:00Z"),
}),
campaign({
id: "sooner",
referrer: fixedReward(5),
conditions: startsAtCondition("2025-02-01T00:00:00Z"),
}),
],
{ now: NOW }
);
expect(result?.status).toBe("upcoming");
expect(result?.campaign.campaignId).toBe("sooner");
expect(result?.startsAt?.toISOString()).toBe(
"2025-02-01T00:00:00.000Z"
);
});
it("skips expired campaigns", () => {
const result = selectDisplayCampaign(
[
campaign({
id: "expired",
referrer: fixedReward(99),
expiresAt: "2025-01-01T00:00:00Z",
}),
campaign({ id: "active", referrer: fixedReward(4) }),
],
{ now: NOW }
);
expect(result?.campaign.campaignId).toBe("active");
});
it("only considers campaigns matching targetInteraction", () => {
const result = selectDisplayCampaign(
[
campaign({
id: "referral-rich",
interactionTypeKey: "referral",
referrer: fixedReward(50),
}),
campaign({
id: "purchase-poor",
interactionTypeKey: "purchase",
referrer: fixedReward(4),
}),
],
{ now: NOW, targetInteraction: "purchase" }
);
expect(result?.campaign.campaignId).toBe("purchase-poor");
});
it("ranks by the referee side when audience is 'referee'", () => {
const rewards = [
campaign({
id: "rich-referrer",
referrer: fixedReward(50),
referee: fixedReward(2),
}),
campaign({
id: "rich-referee",
referrer: fixedReward(1),
referee: fixedReward(9),
}),
];
expect(
selectDisplayCampaign(rewards, { now: NOW })?.campaign.campaignId
).toBe("rich-referrer");
expect(
selectDisplayCampaign(rewards, { now: NOW, audience: "referee" })
?.campaign.campaignId
).toBe("rich-referee");
});
});
describe("formatBestReward", () => {
it("returns undefined for an empty set", () => {
expect(formatBestReward([], { now: NOW })).toBeUndefined();
});
it("formats the selected campaign's referrer reward by default", () => {
const formatted = formatBestReward(
[
campaign({ id: "low", referrer: fixedReward(2) }),
campaign({ id: "high", referrer: fixedReward(50) }),
],
{ now: NOW }
);
expect(formatted).toContain("50");
});
it("formats the referee reward when audience is 'referee'", () => {
const formatted = formatBestReward(
[
campaign({
id: "c",
referrer: fixedReward(50),
referee: fixedReward(3),
}),
],
{ now: NOW, audience: "referee" }
);
expect(formatted).toContain("3");
expect(formatted).not.toContain("50");
});
it("ignores expired campaigns (does not advertise a stale reward)", () => {
expect(
formatBestReward(
[
campaign({
id: "expired",
referrer: fixedReward(99),
expiresAt: "2025-01-01T00:00:00Z",
}),
],
{ now: NOW }
)
).toBeUndefined();
});
it("renders an uncapped percentage reward as a percent string", () => {
expect(
formatBestReward(
[campaign({ id: "c", referrer: uncappedPercentage(10) })],
{ now: NOW }
)
).toBe("10 %");
});
});
describe("selectBestReward", () => {
it("returns undefined for an empty set", () => {
expect(selectBestReward([], { now: NOW })).toBeUndefined();
});
it("exposes the formatted reward and its payout type", () => {
const best = selectBestReward(
[campaign({ id: "c", referrer: fixedReward(50) })],
{ now: NOW }
);
expect(best?.formatted).toContain("50");
expect(best?.payoutType).toBe("fixed");
expect(best?.minPurchaseAmount).toBeUndefined();
expect(best?.lockupDurationDays).toBeUndefined();
});
it("surfaces the minimum purchase amount when the campaign gates on one", () => {
const best = selectBestReward(
[
campaign({
id: "c",
referrer: fixedReward(50),
conditions: [
{
field: "purchase.amount",
operator: "gte",
value: 25,
},
],
}),
],
{ now: NOW }
);
expect(best?.minPurchaseAmount).toContain("25");
});
it("surfaces the lockup duration in whole days", () => {
const best = selectBestReward(
[
campaign({
id: "c",
referrer: fixedReward(50),
defaultLockupSeconds: 7 * 86_400,
}),
],
{ now: NOW }
);
expect(best?.lockupDurationDays).toBe(7);
});
it("omits a zero lockup", () => {
const best = selectBestReward(
[
campaign({
id: "c",
referrer: fixedReward(50),
defaultLockupSeconds: 0,
}),
],
{ now: NOW }
);
expect(best?.lockupDurationDays).toBeUndefined();
});
it("surfaces the raw referrer and referee rewards for the breakdown", () => {
const referrer = uncappedPercentage(10);
const referee = fixedReward(3);
const best = selectBestReward(
[campaign({ id: "c", referrer, referee })],
{ now: NOW }
);
expect(best?.referrerReward).toEqual(referrer);
expect(best?.refereeReward).toEqual(referee);
});
it("leaves the referee reward undefined when the campaign has none", () => {
const best = selectBestReward(
[campaign({ id: "c", referrer: fixedReward(50) })],
{ now: NOW }
);
expect(best?.refereeReward).toBeUndefined();
});
it("surfaces the raw minimum purchase value alongside the formatted string", () => {
const best = selectBestReward(
[
campaign({
id: "c",
referrer: fixedReward(50),
conditions: [
{
field: "purchase.amount",
operator: "gte",
value: 25,
},
],
}),
],
{ now: NOW }
);
expect(best?.minPurchaseValue).toBe(25);
expect(best?.minPurchaseAmount).toContain("25");
});
it("leaves minPurchaseValue undefined when the campaign has no minimum", () => {
const best = selectBestReward(
[campaign({ id: "c", referrer: fixedReward(50) })],
{ now: NOW }
);
expect(best?.minPurchaseValue).toBeUndefined();
});
});