mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 17:46:06 +00:00
feat(billing): defer the cardless trial for invited collaborators
An account that signs up through an invitation works on the inviter's billing, so handing it a trial at signup spent its only trial before it owned anything. The trial is now held back for collaborators and claimed only explicitly: a Start Free Trial button on the new-workspace and billing screens calls the new POST /api/billing/trial endpoint, which grants the once-per-account trial atomically. Nothing starts the clock as a side effect, and pure collaborators no longer see a trial-ending banner about work that is not theirs.
This commit is contained in:
@@ -407,6 +407,53 @@ describe('POST /api/auth/register', () => {
|
||||
expect(created.billingTrialConsumedAt).toBeNull();
|
||||
});
|
||||
|
||||
// Registering through an invitation is the one case where the trial is held
|
||||
// back even on an instance with no SMTP: the account is verified and created,
|
||||
// but it joined somebody else's workspace and does not need a trial to work
|
||||
// there. Creating a workspace of its own is what starts the clock.
|
||||
it('grants no trial to an invited collaborator even without a verification step', async () => {
|
||||
vi.stubEnv('SMTP_HOST', '');
|
||||
vi.stubEnv('SMTP_USER', '');
|
||||
vi.stubEnv('SMTP_PASSWORD', '');
|
||||
const scenario = await seedProject();
|
||||
const invitation = await createInvitation({
|
||||
invitedById: scenario.owner.id,
|
||||
scope: 'PROJECT',
|
||||
projectId: scenario.project.id,
|
||||
email: '[email protected]',
|
||||
role: 'COMMENTATOR',
|
||||
});
|
||||
signedOut();
|
||||
|
||||
const response = await callRoute(
|
||||
register,
|
||||
registerRequest({
|
||||
name: 'Invited Guest',
|
||||
email: '[email protected]',
|
||||
password: PASSWORD,
|
||||
invitationToken: invitation.token,
|
||||
})
|
||||
);
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
const created = await db.user.findUniqueOrThrow({ where: { email: '[email protected]' } });
|
||||
expect(created.emailVerified).toBeInstanceOf(Date);
|
||||
expect(created.trialEndsAt).toBeNull();
|
||||
expect(created.billingTrialConsumedAt).toBeNull();
|
||||
});
|
||||
|
||||
it('starts the trial for somebody signing themselves up without SMTP', async () => {
|
||||
vi.stubEnv('SMTP_HOST', '');
|
||||
vi.stubEnv('SMTP_USER', '');
|
||||
vi.stubEnv('SMTP_PASSWORD', '');
|
||||
|
||||
await post({ name: 'Self Hosted', email: '[email protected]', password: PASSWORD });
|
||||
|
||||
const created = await db.user.findUniqueOrThrow({ where: { email: '[email protected]' } });
|
||||
expect(created.trialEndsAt).toBeInstanceOf(Date);
|
||||
expect(created.billingTrialConsumedAt).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it('reports the rate limit budget on a successful registration', async () => {
|
||||
const response = await post({
|
||||
name: 'Rate Limited',
|
||||
|
||||
Reference in New Issue
Block a user