feat: integrate token point usage v2
This commit is contained in:
@@ -592,12 +592,31 @@ describe('works square host api routes', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('loads current token plan usage through the Works Square API', async () => {
|
||||
it('loads and safely projects the V2 token point balance through the Works Square API', async () => {
|
||||
const points = {
|
||||
plan_code: 'mastery',
|
||||
plan_name: '精通',
|
||||
cycle_start: '2026-09-01T00:00:00Z',
|
||||
cycle_end: '2026-09-08T00:00:00Z',
|
||||
next_refresh_at: '2026-09-08T00:00:00Z',
|
||||
weekly_allowance: '500.00',
|
||||
weekly_used: '100.00',
|
||||
weekly_reserved: '25.00',
|
||||
weekly_remaining: '375.00',
|
||||
permanent_total: '50.00',
|
||||
permanent_used: '0.00',
|
||||
permanent_reserved: '0.00',
|
||||
permanent_remaining: '50.00',
|
||||
total_remaining: '425.00',
|
||||
entitlement_source: 'self',
|
||||
family_shared: false,
|
||||
can_manage_membership: true,
|
||||
upgrade_action: 'self_service',
|
||||
shared_available: null,
|
||||
ignored_internal_field: 'do-not-project',
|
||||
};
|
||||
const fetchMock = vi.fn().mockResolvedValueOnce(
|
||||
new Response(JSON.stringify({
|
||||
five_hour_remaining_percent: 72.5,
|
||||
weekly_remaining_percent: 48,
|
||||
}), { status: 200 }),
|
||||
new Response(JSON.stringify(points), { status: 200 }),
|
||||
);
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
const response = createResponse();
|
||||
@@ -605,7 +624,7 @@ describe('works square host api routes', () => {
|
||||
const handled = await handleWorksRoutes(
|
||||
createRequest('GET', undefined, { 'x-niancode-access-token': 'access-token' }),
|
||||
response.res,
|
||||
new URL('http://127.0.0.1/api/works/billing/token-usage'),
|
||||
new URL('http://127.0.0.1/api/works/billing/points'),
|
||||
{} as never,
|
||||
);
|
||||
|
||||
@@ -613,13 +632,30 @@ describe('works square host api routes', () => {
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.json()).toEqual({
|
||||
success: true,
|
||||
usage: {
|
||||
five_hour_remaining_percent: 72.5,
|
||||
weekly_remaining_percent: 48,
|
||||
points: {
|
||||
plan_code: 'mastery',
|
||||
plan_name: '精通',
|
||||
cycle_start: '2026-09-01T00:00:00Z',
|
||||
cycle_end: '2026-09-08T00:00:00Z',
|
||||
next_refresh_at: '2026-09-08T00:00:00Z',
|
||||
weekly_allowance: '500.00',
|
||||
weekly_used: '100.00',
|
||||
weekly_reserved: '25.00',
|
||||
weekly_remaining: '375.00',
|
||||
permanent_total: '50.00',
|
||||
permanent_used: '0.00',
|
||||
permanent_reserved: '0.00',
|
||||
permanent_remaining: '50.00',
|
||||
total_remaining: '425.00',
|
||||
entitlement_source: 'self',
|
||||
family_shared: false,
|
||||
can_manage_membership: true,
|
||||
upgrade_action: 'self_service',
|
||||
shared_available: null,
|
||||
},
|
||||
});
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
'https://square.nianxx.cn/api/billing/token-usage',
|
||||
'https://square.nianxx.cn/api/billing/points',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -629,6 +665,95 @@ describe('works square host api routes', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects an invalid V2 token point balance instead of forwarding it to Renderer', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValueOnce(
|
||||
new Response(JSON.stringify({
|
||||
plan_code: 'mastery',
|
||||
plan_name: '精通',
|
||||
weekly_remaining: '-1.00',
|
||||
entitlement_source: 'self',
|
||||
family_shared: false,
|
||||
can_manage_membership: true,
|
||||
upgrade_action: 'self_service',
|
||||
}), { status: 200 }),
|
||||
));
|
||||
const response = createResponse();
|
||||
|
||||
const handled = await handleWorksRoutes(
|
||||
createRequest('GET', undefined, { 'x-niancode-access-token': 'access-token' }),
|
||||
response.res,
|
||||
new URL('http://127.0.0.1/api/works/billing/points'),
|
||||
{} as never,
|
||||
);
|
||||
|
||||
expect(handled).toBe(true);
|
||||
expect(response.statusCode).toBe(502);
|
||||
expect(response.json()).toEqual({
|
||||
success: false,
|
||||
error: 'Works Square returned an invalid token point balance',
|
||||
});
|
||||
});
|
||||
|
||||
it('removes exact plan and point values from a family-shared balance', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn().mockResolvedValueOnce(
|
||||
new Response(JSON.stringify({
|
||||
plan_code: 'excellence',
|
||||
plan_name: '卓越',
|
||||
cycle_start: '2026-09-01T00:00:00Z',
|
||||
cycle_end: '2026-09-08T00:00:00Z',
|
||||
next_refresh_at: '2026-09-08T00:00:00Z',
|
||||
weekly_allowance: '1000.00',
|
||||
weekly_used: '100.00',
|
||||
weekly_reserved: '25.00',
|
||||
weekly_remaining: '875.00',
|
||||
permanent_total: '50.00',
|
||||
permanent_used: '0.00',
|
||||
permanent_reserved: '0.00',
|
||||
permanent_remaining: '50.00',
|
||||
total_remaining: '925.00',
|
||||
entitlement_source: 'shared_group',
|
||||
family_shared: true,
|
||||
can_manage_membership: false,
|
||||
upgrade_action: 'contact_family_owner',
|
||||
shared_available: true,
|
||||
}), { status: 200 }),
|
||||
));
|
||||
const response = createResponse();
|
||||
|
||||
await handleWorksRoutes(
|
||||
createRequest('GET', undefined, { 'x-niancode-access-token': 'access-token' }),
|
||||
response.res,
|
||||
new URL('http://127.0.0.1/api/works/billing/points'),
|
||||
{} as never,
|
||||
);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.json()).toEqual({
|
||||
success: true,
|
||||
points: {
|
||||
plan_code: null,
|
||||
plan_name: null,
|
||||
cycle_start: null,
|
||||
cycle_end: null,
|
||||
next_refresh_at: null,
|
||||
weekly_allowance: null,
|
||||
weekly_used: null,
|
||||
weekly_reserved: null,
|
||||
weekly_remaining: null,
|
||||
permanent_total: null,
|
||||
permanent_used: null,
|
||||
permanent_reserved: null,
|
||||
permanent_remaining: null,
|
||||
total_remaining: null,
|
||||
entitlement_source: 'shared_group',
|
||||
family_shared: true,
|
||||
can_manage_membership: false,
|
||||
upgrade_action: 'contact_family_owner',
|
||||
shared_available: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('loads the current Agent Profile through the Works Square API', async () => {
|
||||
const profile = {
|
||||
display_name: '小泥',
|
||||
|
||||
Reference in New Issue
Block a user