Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/kit

src/kit.test.ts

124 lines · 4.5 KB · TypeScript
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'
import { resolveIntegrationName, resolveSecretName } from './setup.ts'
import { kitUrl, mutationPreview, normalizeKitPath, rejectBroadcastSend } from './safety.ts'
import {
	API_KEY_SETUP_URL,
	DEFAULT_API_KEY_SECRET,
	KIT_CALLBACK_URL,
	OAUTH_CONNECT_URL,
	apiKeySetupUrl,
	oauthConnectUrl,
} from './setup.ts'
import { buildLiquidGreeting, joinEmailBlocks } from './html.ts'

const here = dirname(fileURLToPath(import.meta.url))
const root = join(here, '..')

test('secret and integration names default and suffix accounts', () => {
	assert.equal(resolveIntegrationName(), 'kit')
	assert.equal(resolveSecretName(), DEFAULT_API_KEY_SECRET)
	assert.equal(resolveIntegrationName({ account: 'default' }), 'kit')
	assert.equal(resolveIntegrationName({ account: 'work' }), 'kit-work')
	assert.equal(resolveSecretName({ account: 'work' }), 'kitApiKey-work')
	assert.equal(resolveIntegrationName({ integrationName: 'kit-brand' }), 'kit-brand')
	assert.equal(resolveSecretName({ secretName: 'kitApiKey-brand' }), 'kitApiKey-brand')
})

test('setup URLs are prefilled for OAuth and API key', () => {
	assert.match(OAUTH_CONNECT_URL, /provider=kit/)
	assert.match(OAUTH_CONNECT_URL, /authorizeUrl=https%3A%2F%2Fapi\.kit\.com%2Fv4%2Foauth%2Fauthorize/)
	assert.match(OAUTH_CONNECT_URL, /tokenUrl=https%3A%2F%2Fapi\.kit\.com%2Fv4%2Foauth%2Ftoken/)
	assert.match(OAUTH_CONNECT_URL, /allowedHosts=api\.kit\.com/)
	assert.equal(KIT_CALLBACK_URL, 'https://kody.codes/connect/oauth')
	assert.match(API_KEY_SETUP_URL, /name=kitApiKey/)
	assert.match(API_KEY_SETUP_URL, /allowedHosts=api\.kit\.com/)
	assert.match(API_KEY_SETUP_URL, /scope=user/)
	assert.match(oauthConnectUrl('kit-work'), /provider=kit-work/)
	assert.match(apiKeySetupUrl('kitApiKey-work'), /name=kitApiKey-work/)
})

test('mutationPreview dryRun skips confirm', () => {
	const preview = mutationPreview(
		{ dryRun: true },
		{
			method: 'POST',
			path: '/subscribers',
			body: { email_address: 'ada@example.com' },
		},
	)
	assert.deepEqual(preview, {
		dryRun: true,
		method: 'POST',
		path: '/subscribers',
		body: { email_address: 'ada@example.com' },
	})
})

test('mutationPreview requires confirm for live writes', () => {
	assert.throws(
		() =>
			mutationPreview(
				{},
				{ method: 'POST', path: '/broadcasts', body: { subject: 'Hi' } },
			),
		/confirm: true/,
	)
	assert.equal(
		mutationPreview(
			{ confirm: true },
			{ method: 'POST', path: '/broadcasts', body: { subject: 'Hi' } },
		),
		null,
	)
})

test('broadcast helpers refuse send_at and send statuses', () => {
	assert.throws(
		() => rejectBroadcastSend({ send_at: '2026-01-01T00:00:00Z' }, 'createBroadcastDraft'),
		/draft-only/,
	)
	assert.throws(
		() => rejectBroadcastSend({ status: 'published' }, 'updateBroadcast'),
		/draft-only/,
	)
	rejectBroadcastSend({ subject: 'Hello' }, 'createBroadcastDraft')
})

test('kitUrl stays on api.kit.com/v4', () => {
	assert.equal(normalizeKitPath('/subscribers'), '/subscribers')
	assert.match(kitUrl('/account'), /^https:\/\/api\.kit\.com\/v4\/account$/)
	assert.match(kitUrl('/broadcasts', { per_page: 5 }), /per_page=5/)
	assert.throws(() => normalizeKitPath('https://example.com/v4/account'), /api\.kit\.com/)
})

test('html builders stay generic', () => {
	const greeting = buildLiquidGreeting({
		withName: 'Hey {{ subscriber.first_name }}',
		withoutName: 'Hey there',
	})
	assert.match(greeting, /subscriber\.first_name/)
	assert.equal(joinEmailBlocks(['<p>A</p>', '<p>B</p>']), '<p>A</p>\n\n<p>B</p>')
})

test('package is public MIT official kit with disabled job', () => {
	const manifest = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
	assert.equal(manifest.name, '@kody/kit')
	assert.equal(manifest.license, 'MIT')
	assert.equal(manifest.private, false)
	assert.equal(manifest.kody.id, 'kit')
	assert.equal(manifest.kody.jobs['account-health'].enabled, false)
	const readme = readFileSync(join(root, 'README.md'), 'utf8')
	assert.match(readme, /## Intent/)
	assert.match(readme, /https:\/\/kody\.codes\/@kody\/kit/)
	assert.doesNotMatch(readme, /\/community\/[0-9a-f-]{36}/)
	assert.doesNotMatch(readme, /hello@kentcdodds\.com/)
	assert.doesNotMatch(readme, /betterWithKent/)
	assert.doesNotMatch(readme, /KIT_TEMPLATES/)
	const icon = readFileSync(join(root, 'community-icon.svg'), 'utf8')
	assert.match(icon, /#44B1FF/)
	assert.match(icon, /Official Kit wordmark/)
})