Initial import of zappier-edge from zapier monorepo

This commit is contained in:
George Lambert 2026-09-11 15:35:50 -04:00
commit 525edd7469
128 changed files with 20479 additions and 0 deletions

86
tests/meter.test.ts Normal file
View file

@ -0,0 +1,86 @@
import express from 'express';
import request from 'supertest';
import { apiKeyAuth, Customer, InMemoryCustomerRepo } from '../src/auth';
import { meter } from '../src/meter';
import { DEFAULT_PRICING } from '../src/pricing';
import { InMemoryUsageRepo } from '../src/usage';
const FREE_ADA: Customer = { id: 'cust_1', name: 'Ada', tierId: 'free', apiKey: 'key-ada' };
function buildApp(seed: Customer[] = [FREE_ADA]) {
const customers = new InMemoryCustomerRepo(seed);
const usage = new InMemoryUsageRepo();
const app = express();
app.use(express.json());
app.use(apiKeyAuth(customers));
app.post('/transform', meter('transform', usage, DEFAULT_PRICING), (req, res) =>
res.json({ quote: res.locals.quote }),
);
app.post('/storage', meter('storage', usage, DEFAULT_PRICING), (req, res) =>
res.json({ quote: res.locals.quote }),
);
app.post('/experimental', meter('experimental', usage, DEFAULT_PRICING), (req, res) =>
res.json({ quote: res.locals.quote }),
);
return { app, usage };
}
describe('meter middleware', () => {
it('quotes a fixed endpoint at the multiplied tier price and records usage', async () => {
const { app, usage } = buildApp();
const res = await request(app)
.post('/transform')
.set('x-api-key', 'key-ada')
.send({ text: 'hi' });
expect(res.status).toBe(200);
expect(res.body.quote.totalCents).toBe(4); // free tier, multiplier 1
const entries = usage.listFor('cust_1');
expect(entries).toHaveLength(1);
expect(entries[0].endpointId).toBe('transform');
expect(entries[0].cents).toBe(4);
});
it('charges per KB of metadata on variable endpoints', async () => {
const { app } = buildApp();
const res = await request(app)
.post('/storage')
.set('x-api-key', 'key-ada')
.send({ metadata: { note: 'x'.repeat(2048) } });
// JSON of metadata is 2059 bytes -> 3 KB -> list 10 + 3 * 1 = 13
expect(res.body.quote.totalCents).toBe(13);
});
it('applies a per-customer multiplier override', async () => {
const { app } = buildApp([
{ id: 'cust_vip', name: 'Vip', tierId: 'free', apiKey: 'key-vip', multiplierOverride: 0.5 },
]);
const res = await request(app)
.post('/transform')
.set('x-api-key', 'key-vip')
.send({ text: 'hi' });
expect(res.body.quote.totalCents).toBe(2); // list 4 x override 0.5
});
it('returns 401 when no customer is attached', async () => {
const usage = new InMemoryUsageRepo();
const app = express();
app.use(express.json());
app.post('/transform', meter('transform', usage, DEFAULT_PRICING), (req, res) =>
res.json({}),
);
const res = await request(app).post('/transform').send({ text: 'hi' });
expect(res.status).toBe(401);
expect(usage.listFor('cust_1')).toHaveLength(0);
});
it('returns 403 for an endpoint with no price rule on the caller tier', async () => {
const { app, usage } = buildApp();
const res = await request(app)
.post('/experimental')
.set('x-api-key', 'key-ada')
.send({});
expect(res.status).toBe(403);
expect(res.body.error).toMatch(/No price rule/);
expect(usage.listFor('cust_1')).toHaveLength(0);
});
});