feat(robot): add guided hotspot binding flow

This commit is contained in:
2026-08-16 14:27:43 +08:00
parent 54443232dd
commit b7a1590ca1
7 changed files with 855 additions and 18 deletions

View File

@@ -6,11 +6,13 @@ import {
getAiHardwareAgentConfiguration,
getAiHardwareAssignment,
getAiHardwareOverview,
getAiHardwareProvisioningCapabilities,
getAiHardwareConfigurationCatalog,
updateAiHardwareAgentConfiguration,
updateAiHardwareAssignment,
createAiHardwareOperationId,
recoverAiHardwareCredential,
openAiHardwareProvisioningPortal,
} from '@/lib/ai-hardware';
const hostApiFetchMock = vi.hoisted(() => vi.fn());
@@ -57,6 +59,37 @@ describe('AI hardware renderer API', () => {
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/works/ai-hardware', undefined);
});
it('reads the Main-owned provisioning capability and opens only the fixed portal action', async () => {
hostApiFetchMock
.mockResolvedValueOnce({ success: true, data: { guided_hotspot_binding: true } })
.mockResolvedValueOnce({ success: true, data: { opened: true } });
await expect(getAiHardwareProvisioningCapabilities()).resolves.toEqual({
guidedHotspotBinding: true,
});
await expect(openAiHardwareProvisioningPortal()).resolves.toEqual({ opened: true });
expect(hostApiFetchMock).toHaveBeenNthCalledWith(
1,
'/api/works/ai-hardware/provisioning-capabilities',
undefined,
);
expect(hostApiFetchMock).toHaveBeenNthCalledWith(
2,
'/api/works/ai-hardware/provisioning-portal/open',
{ method: 'POST', body: '{}' },
);
});
it.each([
{ guided_hotspot_binding: 'true' },
{ guided_hotspot_binding: false, portal_url: 'http://unsafe.example' },
])('rejects malformed or expanded provisioning capability data', async (data) => {
hostApiFetchMock.mockResolvedValueOnce({ success: true, data });
await expect(getAiHardwareProvisioningCapabilities()).rejects.toMatchObject({
code: 'AI_HARDWARE_INVALID_RESPONSE',
});
});
it('strictly reads the safe configuration catalog and encodes the TTS dependency', async () => {
const catalog = {
schema_version: 1,