Files
hanzo.ai/e2e/unit/rewards.spec.ts

64 lines
3.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test'
import { readdirSync, readFileSync, statSync } from 'node:fs'
import { join } from 'node:path'
import { SNAPSHOT, asRules, disclosed, earning, kindsOf, tier } from '../../lib/hanzo/rewards'
import rules from '../../lib/data/rewards-rules.json' with { type: 'json' }
/**
* THE REWARDS RULES ARE THE CLOUD'S SHAPE, AND THE PAGES SAY WHAT POINTS ARE.
*
* The snapshot is the cloud's Rules (apps/rewards rules.go) as it serves them,
* read by the one parser the pages use; an answer of an earlier shape reads as
* no table. The words the rewards surfaces print never call points money: no
* payout, no airdrop, nothing earned as cash, and the founder program offers no
* free compute.
*/
test('the snapshot reads as the cloud’s rules: its tabs, the ladder from Hacker, credit under caps and no payouts', () => {
expect(SNAPSHOT.tabs.map((t) => t.id)).toEqual(['overall', 'builders', 'contributors', 'advocates'])
expect(SNAPSHOT.levels[0]).toEqual({ name: 'Hacker', points: 0, substantive: false })
expect(SNAPSHOT.payouts).toBe(false)
expect(SNAPSHOT.chain.minting).toBe(SNAPSHOT.chain.contract !== '')
expect(SNAPSHOT.redeem.pointsPerDollar).toBe(rules.redeem.pointsPerDollar)
expect(SNAPSHOT.kinds).toHaveLength(rules.kinds.length)
expect(SNAPSHOT.badges.find((b) => b.id === 'zen-pioneer')?.kinds).toEqual([])
})
test('an answer of an earlier shape is no table', () => {
const { tabs: _gone, ...older } = rules
expect(asRules(older)).toBeNull()
expect(asRules({})).toBeNull()
})
test('the ways to earn leave out the ledger’s bookkeeping', () => {
const ids = earning(SNAPSHOT).flatMap((s) => kindsOf(SNAPSHOT, s.id).map((k) => k.id))
for (const book of ['legacy', 'reversal', 'redeem', 'unredeem']) expect(ids).not.toContain(book)
expect(earning(SNAPSHOT).map((s) => s.id)).not.toContain('redeemed')
expect(ids).toContain('tier')
})
test('a bounty’s tier is the kind its label names, and a post’s disclosure is the rules’ quoted line', () => {
expect(tier(SNAPSHOT, ['bounty', 'bounty:standard'])?.id).toBe('bounty-standard')
expect(tier(SNAPSHOT, ['Bounty:Advanced'])?.points).toBe(rules.kinds.find((k) => k.id === 'bounty-advanced')?.points)
expect(tier(SNAPSHOT, ['bounty', 'bug'])).toBeUndefined()
expect(disclosed(SNAPSHOT)).toBe('I earn Hanzo Rewards points.')
})
const ROOT = join(import.meta.dirname, '..', '..')
const SURFACES = ['components/rewards', 'components/beta', 'app/(marketing)/leaderboard', 'app/(marketing)/bounty', 'app/(marketing)/referral', 'app/(marketing)/founder', 'components/settings/General.tsx', 'public/llms.txt']
const files = (path: string): string[] => (statSync(path).isDirectory() ? readdirSync(path).flatMap((n) => files(join(path, n))) : [path])
const commentary = (line: string) => /^\s*(\*|\/\/|\/\*)/.test(line)
test('the rewards surfaces never call points money, and the founder program offers no free compute', () => {
const said: string[] = []
for (const file of SURFACES.flatMap((s) => files(join(ROOT, s)))) {
readFileSync(file, 'utf8')
.split('\n')
.forEach((line, i) => {
if (commentary(line)) return
if (/\b(payouts?|airdrops?|earn money|cash out)\b|compute credits?|pro compute|free pro ai/i.test(line)) said.push(`${file.slice(ROOT.length + 1)}:${i + 1}: ${line.trim()}`)
})
}
expect(said).toEqual([])
})