chore: ai, public course and other ui improvements

This commit is contained in:
Rotimi Best
2026-05-09 06:05:03 +01:00
parent 5717dd8004
commit c31ad63955
318 changed files with 20668 additions and 4788 deletions
@@ -0,0 +1,55 @@
import { describe, expect, it } from 'vitest';
import { computePurchasedTokenOverflow } from '@api/services/agent/usage';
describe('computePurchasedTokenOverflow', () => {
it('returns 0 when usage stays within allowance', () => {
expect(
computePurchasedTokenOverflow({
allowance: 1000,
monthlyUsageBefore: 500,
requestTokens: 400
})
).toBe(0);
});
it('returns partial overflow when request crosses allowance boundary', () => {
expect(
computePurchasedTokenOverflow({
allowance: 1000,
monthlyUsageBefore: 900,
requestTokens: 200
})
).toBe(100);
});
it('charges entire request against credits when allowance already exhausted', () => {
expect(
computePurchasedTokenOverflow({
allowance: 1000,
monthlyUsageBefore: 1200,
requestTokens: 50
})
).toBe(50);
});
it('handles zero allowance', () => {
expect(
computePurchasedTokenOverflow({
allowance: 0,
monthlyUsageBefore: 0,
requestTokens: 10
})
).toBe(10);
});
});
describe('leaderboard percentage split', () => {
it('allocates shares that sum to 1', () => {
const rows = [{ tokens: 30 }, { tokens: 70 }];
const total = rows.reduce((sum, row) => sum + row.tokens, 0);
const percentages = rows.map((row) => (total > 0 ? row.tokens / total : 0));
expect(percentages).toEqual([0.3, 0.7]);
expect(percentages.reduce((a, b) => a + b, 0)).toBeCloseTo(1);
});
});
@@ -290,6 +290,38 @@ describe('buildUpdatedQuestions', () => {
});
});
describe('in-exercise section assignment', () => {
const sectionA = 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa';
const sectionB = 'bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb';
it('sets exerciseSectionId when provided', () => {
const current = makeQuestion({ exerciseSectionId: sectionA });
const patch: QuestionPatch = { id: 1, exerciseSectionId: sectionB };
const [result] = buildUpdatedQuestions([current], [patch], EXERCISE_ID);
expect(result.exerciseSectionId).toBe(sectionB);
});
it('clears exerciseSectionId when patch passes null', () => {
const current = makeQuestion({ exerciseSectionId: sectionA });
const patch: QuestionPatch = { id: 1, exerciseSectionId: null };
const [result] = buildUpdatedQuestions([current], [patch], EXERCISE_ID);
expect(result.exerciseSectionId).toBeNull();
});
it('omits exerciseSectionId when patch does not mention it', () => {
const current = makeQuestion({ exerciseSectionId: sectionA });
const patch: QuestionPatch = { id: 1, points: 2 };
const [result] = buildUpdatedQuestions([current], [patch], EXERCISE_ID);
expect(result).not.toHaveProperty('exerciseSectionId');
});
});
describe('safety guarantees', () => {
it('throws when the patched id is not in the exercise', () => {
const current = makeQuestion({ id: 1 });