1a12fb870b
- New /developers/ page with API docs, SDKs, pricing, use cases - OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics - Case study: Glasskiosken i Flatenbadet — complete ROI analysis - Updated /order/ with recurring missions and frequency dropdown
82 lines
2.8 KiB
JavaScript
82 lines
2.8 KiB
JavaScript
/**
|
|
* quiXzoom Frilans Payout — Tests
|
|
* Vitest test suite
|
|
*/
|
|
|
|
import { describe, it, expect, beforeAll } from 'vitest';
|
|
import { getMarket, listMarkets, calculatePayout, MARKETS } from '../markets.mjs';
|
|
|
|
describe('Frilans Payout Engine', () => {
|
|
|
|
describe('Markets', () => {
|
|
it('should list all 8 markets', () => {
|
|
const markets = listMarkets();
|
|
expect(markets).toHaveLength(8);
|
|
});
|
|
|
|
it('should get Sweden market', () => {
|
|
const market = getMarket('SE');
|
|
expect(market).toBeDefined();
|
|
expect(market.currency).toBe('SEK');
|
|
expect(market.tax_rate).toBe(0.30);
|
|
});
|
|
|
|
it('should have Stripe Connect in all markets', () => {
|
|
const markets = listMarkets();
|
|
markets.forEach(m => {
|
|
expect(m.stripe_connect_available).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Payout Calculation', () => {
|
|
it('should calculate Sweden payout with platform tax', () => {
|
|
const market = getMarket('SE');
|
|
const result = calculatePayout(1000, market, 'platform');
|
|
|
|
expect(result.gross_amount).toBe(1000);
|
|
expect(result.platform_fee).toBe(150); // 15%
|
|
expect(result.processing_fee).toBe(60); // 6%
|
|
expect(result.tax_amount).toBe(255); // 30% of 850
|
|
expect(result.net_amount).toBe(535); // 1000 - 150 - 60 - 255
|
|
});
|
|
|
|
it('should calculate Sweden payout with self tax', () => {
|
|
const market = getMarket('SE');
|
|
const result = calculatePayout(1000, market, 'self');
|
|
|
|
expect(result.gross_amount).toBe(1000);
|
|
expect(result.platform_fee).toBe(150);
|
|
expect(result.processing_fee).toBe(60);
|
|
expect(result.tax_amount).toBe(0); // No tax withheld
|
|
expect(result.net_amount).toBe(790); // 1000 - 150 - 60
|
|
});
|
|
|
|
it('should calculate US payout', () => {
|
|
const market = getMarket('US');
|
|
const result = calculatePayout(100, market, 'platform');
|
|
|
|
expect(result.gross_amount).toBe(100);
|
|
expect(result.platform_fee).toBe(15); // 15%
|
|
expect(result.processing_fee).toBe(3); // 2.9%
|
|
expect(result.tax_amount).toBe(13); // 15% of 85
|
|
});
|
|
});
|
|
|
|
describe('Market Availability', () => {
|
|
it('should have frilans in SE, NO, DK, GB', () => {
|
|
expect(getMarket('SE').frilans_available).toBe(true);
|
|
expect(getMarket('NO').frilans_available).toBe(true);
|
|
expect(getMarket('DK').frilans_available).toBe(true);
|
|
expect(getMarket('GB').frilans_available).toBe(true);
|
|
});
|
|
|
|
it('should NOT have frilans in FI, DE, NL, US', () => {
|
|
expect(getMarket('FI').frilans_available).toBe(false);
|
|
expect(getMarket('DE').frilans_available).toBe(false);
|
|
expect(getMarket('NL').frilans_available).toBe(false);
|
|
expect(getMarket('US').frilans_available).toBe(false);
|
|
});
|
|
});
|
|
});
|