Skip to content

Commit 4dd4b97

Browse files
committed
chore: better default widget/sharing msg generation
1 parent 3c19e24 commit 4dd4b97

3 files changed

Lines changed: 478 additions & 86 deletions

File tree

apps/webapp/src/lib/__tests__/template-config-generator.test.ts

Lines changed: 230 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { generateWidgetConfigFromTemplate } from "../template-config-generator";
2-
import { RewardConfigType } from "@refref/types";
1+
import {
2+
generateWidgetConfigFromTemplate,
3+
mergeWidgetConfig,
4+
type ProductMetadata,
5+
} from "../template-config-generator";
6+
import { RewardConfigType, WidgetConfigType } from "@refref/types";
37

48
describe("Template Config Generator", () => {
59
describe("generateWidgetConfigFromTemplate", () => {
@@ -16,9 +20,12 @@ describe("Template Config Generator", () => {
1620

1721
expect(result.title).toBe("Invite your friends");
1822
expect(result.logoUrl).toBe("");
23+
expect(result.cssVariables).toEqual({
24+
"--widget-primary": "#ff0000",
25+
});
1926
});
2027

21-
it("should generate share message based on reward config", () => {
28+
it("should generate share message for BOTH rewards", () => {
2229
const brandConfig = {
2330
primaryColor: "#3b82f6",
2431
};
@@ -44,10 +51,67 @@ describe("Template Config Generator", () => {
4451
"MyApp",
4552
);
4653

47-
expect(result.shareMessage).toContain("Get 20% off");
48-
expect(result.shareMessage).toContain("I'll earn $10");
49-
expect(result.subtitle).toContain("Earn $10 per referral");
50-
expect(result.subtitle).toContain("Friends get 20% off");
54+
expect(result.title).toBe("Share & Earn Together");
55+
expect(result.shareMessage).toBe("Get 20% off at MyApp!");
56+
expect(result.subtitle).toBe("Earn $10 per referral • Friends get 20% off");
57+
expect(result.triggerText).toBe("Refer & Earn");
58+
expect(result.icon).toBe("gift");
59+
});
60+
61+
it("should handle REFERRER ONLY rewards", () => {
62+
const brandConfig = {
63+
primaryColor: "#10b981",
64+
};
65+
66+
const rewardConfig: RewardConfigType = {
67+
referrer: {
68+
type: "cash",
69+
valueType: "fixed",
70+
value: 15,
71+
currency: "USD",
72+
},
73+
// No referee reward
74+
};
75+
76+
const result = generateWidgetConfigFromTemplate(
77+
brandConfig,
78+
rewardConfig,
79+
"ShopApp",
80+
);
81+
82+
expect(result.title).toBe("Earn with every referral");
83+
expect(result.shareMessage).toBe("Check out ShopApp!");
84+
expect(result.subtitle).toBe("Earn $15 for every successful referral");
85+
expect(result.triggerText).toBe("Earn Rewards");
86+
expect(result.icon).toBe("zap");
87+
});
88+
89+
it("should handle REFEREE ONLY rewards", () => {
90+
const brandConfig = {
91+
primaryColor: "#10b981",
92+
};
93+
94+
const rewardConfig: RewardConfigType = {
95+
// No referrer reward
96+
referee: {
97+
type: "discount",
98+
valueType: "percentage",
99+
value: 25,
100+
validityDays: 30,
101+
},
102+
};
103+
104+
const result = generateWidgetConfigFromTemplate(
105+
brandConfig,
106+
rewardConfig,
107+
"DealApp",
108+
);
109+
110+
expect(result.title).toBe("Share exclusive savings");
111+
expect(result.shareMessage).toBe("Get 25% off at DealApp!");
112+
expect(result.subtitle).toBe("Give your friends 25% off");
113+
expect(result.triggerText).toBe("Share Savings");
114+
expect(result.icon).toBe("heart");
51115
});
52116

53117
it("should handle percentage-based referrer rewards", () => {
@@ -77,10 +141,8 @@ describe("Template Config Generator", () => {
77141
"ShopApp",
78142
);
79143

80-
expect(result.shareMessage).toContain("Get $5 off");
81-
expect(result.shareMessage).toContain("I'll earn 15% cashback");
82-
expect(result.subtitle).toContain("Earn 15% on referrals");
83-
expect(result.subtitle).toContain("Friends get $5 off");
144+
expect(result.shareMessage).toBe("Get $5 off at ShopApp!");
145+
expect(result.subtitle).toBe("Earn 15% per referral • Friends get $5 off");
84146
});
85147

86148
it("should use default values when no rewards configured", () => {
@@ -94,12 +156,165 @@ describe("Template Config Generator", () => {
94156
"Platform",
95157
);
96158

97-
expect(result.shareMessage).toBe(
98-
"Join me on Platform and get exclusive rewards!",
99-
);
159+
expect(result.title).toBe("Invite your friends");
160+
expect(result.shareMessage).toBe("Join me on Platform!");
100161
expect(result.subtitle).toBe(
101162
"Share your referral link and earn rewards when your friends join!",
102163
);
164+
expect(result.triggerText).toBe("Refer & Earn");
165+
expect(result.icon).toBe("gift");
166+
});
167+
168+
it("should handle edge case where rewardConfig exists but has no rewards", () => {
169+
const brandConfig = {
170+
primaryColor: "#6366f1",
171+
};
172+
173+
// RewardConfig exists but both referrer and referee are undefined
174+
const rewardConfig: RewardConfigType = {};
175+
176+
const result = generateWidgetConfigFromTemplate(
177+
brandConfig,
178+
rewardConfig,
179+
"TestPlatform",
180+
);
181+
182+
expect(result.title).toBe("Refer & Earn");
183+
expect(result.shareMessage).toBe("Check out TestPlatform!");
184+
expect(result.subtitle).toBe("Share your referral link with friends");
185+
expect(result.triggerText).toBe("Refer Friends");
186+
expect(result.icon).toBe("star");
187+
});
188+
189+
describe("Currency Formatting", () => {
190+
it("should format different currencies correctly", () => {
191+
const brandConfig = { primaryColor: "#000000" };
192+
193+
const euroReward: RewardConfigType = {
194+
referrer: {
195+
type: "cash",
196+
valueType: "fixed",
197+
value: 15,
198+
currency: "EUR",
199+
},
200+
};
201+
const resultEuro = generateWidgetConfigFromTemplate(
202+
brandConfig,
203+
euroReward,
204+
"App",
205+
);
206+
expect(resultEuro.subtitle).toContain("€15");
207+
208+
const gbpReward: RewardConfigType = {
209+
referrer: {
210+
type: "cash",
211+
valueType: "fixed",
212+
value: 20,
213+
currency: "GBP",
214+
},
215+
};
216+
const resultGBP = generateWidgetConfigFromTemplate(
217+
brandConfig,
218+
gbpReward,
219+
"App",
220+
);
221+
expect(resultGBP.subtitle).toContain("£20");
222+
});
223+
});
224+
225+
describe("Product Metadata Integration", () => {
226+
it("should select platforms based on target audience", () => {
227+
const brandConfig = { primaryColor: "#000000" };
228+
229+
const professionalMeta: ProductMetadata = {
230+
targetAudience: "professional",
231+
};
232+
const resultPro = generateWidgetConfigFromTemplate(
233+
brandConfig,
234+
undefined,
235+
"App",
236+
professionalMeta,
237+
);
238+
expect(resultPro.enabledPlatforms.linkedin).toBe(true);
239+
expect(resultPro.enabledPlatforms.instagram).toBe(false);
240+
241+
const consumerMeta: ProductMetadata = {
242+
targetAudience: "consumer",
243+
};
244+
const resultConsumer = generateWidgetConfigFromTemplate(
245+
brandConfig,
246+
undefined,
247+
"App",
248+
consumerMeta,
249+
);
250+
expect(resultConsumer.enabledPlatforms.instagram).toBe(true);
251+
expect(resultConsumer.enabledPlatforms.linkedin).toBe(false);
252+
});
253+
});
254+
});
255+
256+
describe("mergeWidgetConfig", () => {
257+
it("should merge configs correctly", () => {
258+
const generated: WidgetConfigType = {
259+
title: "Generated Title",
260+
subtitle: "Generated Subtitle",
261+
shareMessage: "Generated Message",
262+
triggerText: "Generated Trigger",
263+
icon: "gift",
264+
position: "bottom-right",
265+
logoUrl: "",
266+
referralLink: "",
267+
productName: "TestApp",
268+
enabledPlatforms: {
269+
facebook: true,
270+
twitter: true,
271+
linkedin: true,
272+
whatsapp: true,
273+
email: true,
274+
instagram: false,
275+
telegram: false,
276+
},
277+
};
278+
279+
const existing = {
280+
title: "Custom Title",
281+
referralLink: "https://example.com/ref/123",
282+
productName: "CustomApp",
283+
};
284+
285+
const merged = mergeWidgetConfig(generated, existing);
286+
287+
expect(merged.title).toBe("Custom Title");
288+
expect(merged.referralLink).toBe("https://example.com/ref/123");
289+
expect(merged.productName).toBe("CustomApp");
290+
expect(merged.subtitle).toBe("Generated Subtitle");
291+
expect(merged.shareMessage).toBe("Generated Message");
292+
});
293+
294+
it("should return generated config when no existing config", () => {
295+
const generated: WidgetConfigType = {
296+
title: "Test Title",
297+
subtitle: "Test Subtitle",
298+
shareMessage: "Test Message",
299+
triggerText: "Test Trigger",
300+
icon: "star",
301+
position: "bottom-right",
302+
logoUrl: "",
303+
referralLink: "",
304+
productName: "App",
305+
enabledPlatforms: {
306+
facebook: true,
307+
twitter: true,
308+
linkedin: true,
309+
whatsapp: true,
310+
email: true,
311+
instagram: false,
312+
telegram: false,
313+
},
314+
};
315+
316+
const merged = mergeWidgetConfig(generated, undefined);
317+
expect(merged).toEqual(generated);
103318
});
104319
});
105-
});
320+
});

0 commit comments

Comments
 (0)