Skip to content

Commit d6ca64e

Browse files
authored
add Subscription faker (closes #46) (#47)
1 parent 5c10123 commit d6ca64e

4 files changed

Lines changed: 536 additions & 5 deletions

File tree

‎src/main/java/org/thejavaguy/javafaker/Faker.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public class Faker {
108108
private final EnglandFootBall englandfootball;
109109
private final Mountain mountain;
110110
private final Shipping shipping;
111+
private final Subscription subscription;
111112
private final Vehicle vehicle;
112113

113114
public Faker() {
@@ -227,6 +228,7 @@ public Faker(FakeValuesService fakeValuesService, RandomService random) {
227228
this.englandfootball = new EnglandFootBall(this);
228229
this.mountain = new Mountain(this);
229230
this.shipping = new Shipping(this);
231+
this.subscription = new Subscription(this);
230232
this.vehicle = new Vehicle(this);
231233
}
232234

@@ -737,6 +739,15 @@ public Vehicle vehicle() {
737739
return vehicle;
738740
}
739741

742+
/**
743+
* Returns a Subscription instance for generating subscription-related fake data.
744+
*
745+
* @return a {@link Subscription} instance
746+
*/
747+
public Subscription subscription() {
748+
return subscription;
749+
}
750+
740751
public String resolve(String key) {
741752
return this.fakeValuesService.resolve(key, this, this);
742753
}
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
package org.thejavaguy.javafaker;
2+
3+
import java.math.BigDecimal;
4+
import java.math.RoundingMode;
5+
import java.time.LocalDate;
6+
import java.time.format.DateTimeFormatter;
7+
8+
/**
9+
* Generates realistic subscription and SaaS-related fake data.
10+
*
11+
* @since 1.x.x
12+
*/
13+
public class Subscription {
14+
15+
private final Faker faker;
16+
17+
protected Subscription(Faker faker) {
18+
this.faker = faker;
19+
}
20+
21+
/**
22+
* Returns a random subscription plan name.
23+
*
24+
* @return plan name, e.g., "Professional", "Enterprise"
25+
*/
26+
public String planName() {
27+
return faker.fakeValuesService().fetchString("subscription.plan_names");
28+
}
29+
30+
/**
31+
* Returns a random subscription status.
32+
*
33+
* @return status, e.g., "active", "canceled", "trialing"
34+
*/
35+
public String status() {
36+
return faker.fakeValuesService().fetchString("subscription.statuses");
37+
}
38+
39+
/**
40+
* Returns a random payment method.
41+
*
42+
* @return payment method, e.g., "Credit Card", "PayPal"
43+
*/
44+
public String paymentMethod() {
45+
return faker.fakeValuesService().fetchString("subscription.payment_methods");
46+
}
47+
48+
/**
49+
* Returns a random billing cycle.
50+
*
51+
* @return billing cycle, e.g., "monthly", "annually"
52+
*/
53+
public String billingCycle() {
54+
return faker.fakeValuesService().fetchString("subscription.billing_cycles");
55+
}
56+
57+
/**
58+
* Returns a random payment term.
59+
*
60+
* @return payment term, e.g., "Net 30", "Due on Receipt"
61+
*/
62+
public String paymentTerm() {
63+
return faker.fakeValuesService().fetchString("subscription.payment_terms");
64+
}
65+
66+
/**
67+
* Returns a random currency code.
68+
*
69+
* @return currency code, e.g., "USD", "EUR"
70+
*/
71+
public String currency() {
72+
return faker.fakeValuesService().fetchString("subscription.currencies");
73+
}
74+
75+
/**
76+
* Returns a random subscription feature.
77+
*
78+
* @return feature, e.g., "Unlimited Users", "API Access"
79+
*/
80+
public String feature() {
81+
return faker.fakeValuesService().fetchString("subscription.features");
82+
}
83+
84+
/**
85+
* Returns a random subscription type.
86+
*
87+
* @return subscription type, e.g., "SaaS", "Streaming"
88+
*/
89+
public String subscriptionType() {
90+
return faker.fakeValuesService().fetchString("subscription.subscription_types");
91+
}
92+
93+
/**
94+
* Returns a random cancellation reason.
95+
*
96+
* @return cancellation reason, e.g., "Too expensive"
97+
*/
98+
public String cancellationReason() {
99+
return faker.fakeValuesService().fetchString("subscription.cancellation_reasons");
100+
}
101+
102+
/**
103+
* Returns a random renewal type.
104+
*
105+
* @return renewal type, e.g., "Auto-renew", "Manual renewal"
106+
*/
107+
public String renewalType() {
108+
return faker.fakeValuesService().fetchString("subscription.renewal_types");
109+
}
110+
111+
/**
112+
* Generates a random subscription ID.
113+
*
114+
* @return subscription ID, e.g., "sub_1234567890abcdef"
115+
*/
116+
public String subscriptionId() {
117+
return "sub_" + faker.regexify("[a-z0-9]{16}");
118+
}
119+
120+
/**
121+
* Generates a random customer ID.
122+
*
123+
* @return customer ID, e.g., "cus_1234567890abcdef"
124+
*/
125+
public String customerId() {
126+
return "cus_" + faker.regexify("[a-z0-9]{14}");
127+
}
128+
129+
/**
130+
* Generates a random invoice ID.
131+
*
132+
* @return invoice ID, e.g., "inv_1234567890abcdef"
133+
*/
134+
public String invoiceId() {
135+
return "inv_" + faker.regexify("[a-z0-9]{14}");
136+
}
137+
138+
/**
139+
* Generates a random monthly price between $5 and $500.
140+
*
141+
* @return price as BigDecimal with 2 decimal places
142+
*/
143+
public BigDecimal price() {
144+
return price(5.00, 500.00);
145+
}
146+
147+
/**
148+
* Generates a random price between min and max.
149+
*
150+
* @param min minimum price
151+
* @param max maximum price
152+
* @return price as BigDecimal with 2 decimal places
153+
*/
154+
public BigDecimal price(double min, double max) {
155+
double price = min + (faker.random().nextDouble() * (max - min));
156+
return BigDecimal.valueOf(price).setScale(2, RoundingMode.HALF_UP);
157+
}
158+
159+
/**
160+
* Generates a formatted price string with currency.
161+
*
162+
* @return formatted price, e.g., "$99.99"
163+
*/
164+
public String priceFormatted() {
165+
return "$" + price().toString();
166+
}
167+
168+
/**
169+
* Generates a formatted price with specified currency symbol.
170+
*
171+
* @param currencySymbol the currency symbol to use
172+
* @return formatted price, e.g., "€99.99"
173+
*/
174+
public String priceFormatted(String currencySymbol) {
175+
return currencySymbol + price().toString();
176+
}
177+
178+
/**
179+
* Generates a subscription start date within the last year.
180+
*
181+
* @return start date as LocalDate
182+
*/
183+
public LocalDate startDate() {
184+
int daysBack = faker.random().nextInt(365);
185+
return LocalDate.now().minusDays(daysBack);
186+
}
187+
188+
/**
189+
* Generates a formatted subscription start date.
190+
*
191+
* @param pattern the date format pattern
192+
* @return formatted start date string
193+
*/
194+
public String startDate(String pattern) {
195+
return startDate().format(DateTimeFormatter.ofPattern(pattern));
196+
}
197+
198+
/**
199+
* Generates a subscription end date in the future.
200+
*
201+
* @return end date as LocalDate (1 month to 2 years from now)
202+
*/
203+
public LocalDate endDate() {
204+
int daysAhead = faker.random().nextInt(730) + 30;
205+
return LocalDate.now().plusDays(daysAhead);
206+
}
207+
208+
/**
209+
* Generates a formatted subscription end date.
210+
*
211+
* @param pattern the date format pattern
212+
* @return formatted end date string
213+
*/
214+
public String endDate(String pattern) {
215+
return endDate().format(DateTimeFormatter.ofPattern(pattern));
216+
}
217+
218+
/**
219+
* Generates a next billing date in the future.
220+
*
221+
* @return next billing date as LocalDate (1-30 days from now)
222+
*/
223+
public LocalDate nextBillingDate() {
224+
int daysAhead = faker.random().nextInt(30) + 1;
225+
return LocalDate.now().plusDays(daysAhead);
226+
}
227+
228+
/**
229+
* Generates a trial end date.
230+
*
231+
* @return trial end date as LocalDate (7-30 days from now)
232+
*/
233+
public LocalDate trialEndDate() {
234+
int daysAhead = faker.random().nextInt(24) + 7;
235+
return LocalDate.now().plusDays(daysAhead);
236+
}
237+
238+
/**
239+
* Generates a random trial period in days.
240+
*
241+
* @return trial period in days (7, 14, or 30)
242+
*/
243+
public int trialPeriodDays() {
244+
int[] periods = {7, 14, 30};
245+
return periods[faker.random().nextInt(periods.length)];
246+
}
247+
248+
/**
249+
* Generates a random discount percentage.
250+
*
251+
* @return discount percentage (5-50)
252+
*/
253+
public int discountPercent() {
254+
int[] discounts = {5, 10, 15, 20, 25, 30, 40, 50};
255+
return discounts[faker.random().nextInt(discounts.length)];
256+
}
257+
258+
/**
259+
* Generates a promo/coupon code.
260+
*
261+
* @return coupon code, e.g., "SAVE20", "PROMO2024"
262+
*/
263+
public String couponCode() {
264+
String[] prefixes = {"SAVE", "PROMO", "DEAL", "OFF", "DISCOUNT", "SPECIAL"};
265+
String prefix = prefixes[faker.random().nextInt(prefixes.length)];
266+
int number = faker.random().nextInt(50) + 10;
267+
return prefix + number;
268+
}
269+
270+
/**
271+
* Generates a random user/seat count for a subscription.
272+
*
273+
* @return user count between 1 and 100
274+
*/
275+
public int userCount() {
276+
return faker.random().nextInt(100) + 1;
277+
}
278+
279+
/**
280+
* Generates a random user count within a range.
281+
*
282+
* @param min minimum users
283+
* @param max maximum users
284+
* @return user count within range
285+
*/
286+
public int userCount(int min, int max) {
287+
return faker.random().nextInt(max - min + 1) + min;
288+
}
289+
290+
/**
291+
* Checks if subscription should auto-renew (random).
292+
*
293+
* @return true or false randomly
294+
*/
295+
public boolean autoRenew() {
296+
return faker.random().nextBoolean();
297+
}
298+
299+
/**
300+
* Generates a full plan description combining name and billing cycle.
301+
*
302+
* @return plan description, e.g., "Professional (Monthly)"
303+
*/
304+
public String planDescription() {
305+
String plan = planName();
306+
String cycle = billingCycle();
307+
String capitalizedCycle = cycle.substring(0, 1).toUpperCase() + cycle.substring(1);
308+
return plan + " (" + capitalizedCycle + ")";
309+
}
310+
}
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
en:
22
faker:
33
subscription:
4-
plans: ["Free Trial", "Basic", "Starter", "Essential", "Student", "Bronze", "Standard", "Silver", "Gold", "Platinum", "Professional", "Business", "Diamond", "Premium"]
5-
statuses: ["Active", "Idle", "Blocked", "Pending"]
6-
payment_methods: ["Credit card", "Debit card", "Paypal", "Cash", "Money transfer", "Bitcoins", "Cheque", "Apple Pay", "Google Pay", "WeChat Pay", "Alipay", "Visa checkout"]
7-
subscription_terms: ["Daily", "Weekly", "Monthly", "Annual", "Biennal", "Triennal", "Quinquennal", "Lifetime"]
8-
payment_terms: ["Payment in advance", "Monthly", "Annual", "Full subscription"]
4+
plan_names: ["Free", "Starter", "Basic", "Standard", "Professional", "Pro", "Premium", "Business", "Enterprise", "Ultimate", "Growth", "Scale", "Team", "Individual", "Student", "Family", "Unlimited"]
5+
statuses: ["active", "inactive", "canceled", "expired", "past_due", "trialing", "paused", "pending", "suspended"]
6+
payment_methods: ["Credit Card", "Debit Card", "PayPal", "Bank Transfer", "ACH", "Wire Transfer", "Apple Pay", "Google Pay", "Invoice", "Check", "Cryptocurrency"]
7+
billing_cycles: ["monthly", "quarterly", "semi-annually", "annually", "bi-annually", "weekly", "bi-weekly"]
8+
payment_terms: ["Net 15", "Net 30", "Net 45", "Net 60", "Due on Receipt", "Prepaid"]
9+
currencies: ["USD", "EUR", "GBP", "CAD", "AUD", "JPY", "CHF", "INR", "BRL", "MXN"]
10+
features: ["Unlimited Users", "API Access", "Priority Support", "Custom Branding", "Advanced Analytics", "SSO Integration", "Audit Logs", "Data Export", "Dedicated Account Manager", "Custom Integrations", "99.9% SLA", "24/7 Support", "White Label", "Multi-tenant", "HIPAA Compliance", "SOC 2 Compliance", "Unlimited Storage", "Advanced Security", "Role-based Access", "Custom Workflows"]
11+
subscription_types: ["SaaS", "Streaming", "Membership", "License", "Service", "Content", "Software", "Platform"]
12+
cancellation_reasons: ["Too expensive", "Not using enough", "Found alternative", "Missing features", "Poor customer support", "Technical issues", "Company closed", "Temporary pause", "Switching plans", "Budget cuts"]
13+
renewal_types: ["Auto-renew", "Manual renewal", "No renewal"]

0 commit comments

Comments
 (0)