mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
Every import, the catalog pin and the docs name @hanzo/app and github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and components/rooms.tsx is components/app.tsx.
58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
||
import { charge, quote, saving, term, type SubscriptionPlan } from '@hanzo/app/lib/plans'
|
||
|
||
/**
|
||
* A PLAN'S TERM, PRICED FROM WHAT THE CATALOG STATES.
|
||
*
|
||
* The package states a year's charge (`annualTotal`) and the button quotes it.
|
||
* The live catalog states only `priceAnnual`, a year shown per month, and the button
|
||
* quotes that figure rather than a total made up from it. The saving is
|
||
* 1 − year ÷ (12 × month) either way, and a year reaches checkout as
|
||
* `interval=year` on whatever address checkout has.
|
||
*/
|
||
|
||
const row = (p: Partial<SubscriptionPlan>): SubscriptionPlan => ({
|
||
id: 'dev',
|
||
name: 'Pro',
|
||
description: '',
|
||
priceMonthly: null,
|
||
category: 'personal',
|
||
features: [],
|
||
...p,
|
||
})
|
||
|
||
test('a year the catalog states is quoted as its total, and the saving is computed from it', () => {
|
||
const plan = row({ priceMonthly: 20, priceAnnual: 16.67, annualTotal: 200 })
|
||
expect(quote(plan, 'month')).toBe('$20/month')
|
||
expect(quote(plan, 'year')).toBe('$200/year')
|
||
expect(charge(plan, 'year')).toBe(200)
|
||
expect(saving(plan)).toBe(Math.round((1 - 200 / (12 * 20)) * 100))
|
||
})
|
||
|
||
test('a year stated only per month is quoted per month, and saves what twelve of it save', () => {
|
||
const plan = row({ priceMonthly: 19, priceAnnual: 15.58 })
|
||
expect(quote(plan, 'year')).toBe('$15.58/month, billed yearly')
|
||
expect(charge(plan, 'year')).toBe(186.96)
|
||
expect(saving(plan)).toBe(Math.round((1 - 186.96 / (12 * 19)) * 100))
|
||
})
|
||
|
||
test('a plan with no year sells no year', () => {
|
||
const plan = row({ priceMonthly: 20 })
|
||
expect(quote(plan, 'year')).toBeNull()
|
||
expect(charge(plan, 'year')).toBeNull()
|
||
expect(saving(plan)).toBeNull()
|
||
expect(saving(row({ priceMonthly: 20, annualTotal: 240 })), 'a year that saves nothing is not offered').toBeNull()
|
||
})
|
||
|
||
test('a year reaches checkout as interval=year, keeping the query and the fragment', () => {
|
||
const cart = 'https://hanzo.ai/pay/?plan=dev&returnUrl=https%3A%2F%2Fhanzo.ai%2Fchat#pricing'
|
||
expect(term(cart, 'month')).toBe(cart)
|
||
const year = new URL(term(cart, 'year'))
|
||
expect(`${year.host}${year.pathname}`).toBe('hanzo.ai/pay/')
|
||
expect(year.searchParams.get('plan')).toBe('dev')
|
||
expect(year.searchParams.get('returnUrl')).toBe('https://hanzo.ai/chat')
|
||
expect(year.searchParams.get('interval')).toBe('year')
|
||
expect(year.hash).toBe('#pricing')
|
||
expect(new URL(term('/checkout?plan=dev', 'year')).host, 'a relative address is on the site the checkout is').toBe('hanzo.ai')
|
||
})
|