feat: zobrazení stavu objednávky Bolt Food jako progress stepper
CI / Generate TypeScript types (push) Successful in 9s
CI / Server unit tests (push) Successful in 21s
CI / Build server (push) Successful in 24s
CI / Build client (push) Successful in 35s
CI / Playwright E2E tests (push) Successful in 1m22s
CI / Build and push Docker image (push) Successful in 41s
CI / Notify (push) Successful in 2s
CI / Generate TypeScript types (push) Successful in 9s
CI / Server unit tests (push) Successful in 21s
CI / Build server (push) Successful in 24s
CI / Build client (push) Successful in 35s
CI / Playwright E2E tests (push) Successful in 1m22s
CI / Build and push Docker image (push) Successful in 41s
CI / Notify (push) Successful in 2s
Jak to funguje: - OrderGroup má nové pole boltOrderState (raw order_state z Bolt API). Polling scheduler ho ukládá při každé změně a rozesílá přes Socket.io, takže stepper se posouvá živě všem uživatelům. - Komponenta BoltOrderProgress vykresluje čtyři kroky (Přijato → Příprava → Na cestě → Doručeno) pod časy skupiny. Známé stavy se mapují explicitně, neznámé heuristikou podle klíčových slov, zrušená objednávka se zobrazí červeně. Tooltip ukazuje raw stav, aktivní krok pulzuje, dokud sledování běží. - Po doručení (nebo zmizení objednávky z API) se token smaže, ale boltOrderState zůstává "delivered" — dokončený stepper je vidět po zbytek dne. Vynuluje se při změně/zrušení odkazu nebo návratu skupiny do stavu uzamčeno. - Nastavení odkazu nově spustí okamžitý poll, stepper se tak objeví do vteřiny místo čekání na další tik scheduleru. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,10 +97,27 @@ describe('setGroupBoltTracking', () => {
|
||||
expect(d.groups![0].boltTrackingToken).toBe(TOKEN);
|
||||
});
|
||||
|
||||
test('prázdná hodnota sledování zruší', async () => {
|
||||
test('prázdná hodnota sledování zruší včetně stavu', async () => {
|
||||
await setGroupBoltTracking(CREATOR, groupId, SHARE_URL, TODAY);
|
||||
const d = await setGroupBoltTracking(CREATOR, groupId, '', TODAY);
|
||||
expect(d.groups![0].boltTrackingToken).toBeUndefined();
|
||||
expect(d.groups![0].boltOrderState).toBeUndefined();
|
||||
});
|
||||
|
||||
test('nový token vynuluje stav předchozí objednávky', async () => {
|
||||
await setGroupBoltTracking(CREATOR, groupId, SHARE_URL, TODAY);
|
||||
await storage.updateData<ClientData>(`2025-01-10_extra`, (current) => {
|
||||
current!.groups![0].boltOrderState = 'preparing';
|
||||
return current!;
|
||||
});
|
||||
// Stejný token stav nemění
|
||||
let d = await setGroupBoltTracking(CREATOR, groupId, SHARE_URL, TODAY);
|
||||
expect(d.groups![0].boltOrderState).toBe('preparing');
|
||||
// Jiný token stav vynuluje
|
||||
const otherUrl = `https://food.bolt.eu/sharedActiveOrder/${'b'.repeat(64)}`;
|
||||
d = await setGroupBoltTracking(CREATOR, groupId, otherUrl, TODAY);
|
||||
expect(d.groups![0].boltOrderState).toBeUndefined();
|
||||
expect(d.groups![0].boltTrackingToken).toBe('b'.repeat(64));
|
||||
});
|
||||
|
||||
test('odmítne neplatný odkaz', async () => {
|
||||
@@ -143,6 +160,7 @@ describe('checkBoltTracking', () => {
|
||||
const after = computeDeliveryHHMM(1800);
|
||||
const group = await getGroup();
|
||||
expect([before, after]).toContain(group.deliveryAt);
|
||||
expect(group.boltOrderState).toBe('waiting_preparation');
|
||||
expect(group.boltTrackingToken).toBe(TOKEN);
|
||||
expect(mockEmit).toHaveBeenCalledWith('message', expect.anything());
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(
|
||||
@@ -167,6 +185,7 @@ describe('checkBoltTracking', () => {
|
||||
await checkBoltTracking();
|
||||
const group = await getGroup();
|
||||
expect(group.boltTrackingToken).toBeUndefined();
|
||||
expect(group.boltOrderState).toBe('delivered');
|
||||
expect(group.deliveryAt).toMatch(/^\d{2}:\d{2}$/);
|
||||
});
|
||||
|
||||
@@ -175,6 +194,17 @@ describe('checkBoltTracking', () => {
|
||||
await checkBoltTracking();
|
||||
const group = await getGroup();
|
||||
expect(group.boltTrackingToken).toBeUndefined();
|
||||
expect(group.boltOrderState).toBe('delivered');
|
||||
});
|
||||
|
||||
test('aktualizuje boltOrderState při změně stavu beze změny času', async () => {
|
||||
mockedAxios.post.mockResolvedValue(boltResponse({ order_state: 'waiting_preparation', expected_time_to_client_in_seconds: 1800 }));
|
||||
await checkBoltTracking();
|
||||
mockedAxios.post.mockResolvedValue(boltResponse({ order_state: 'preparing', expected_time_to_client_in_seconds: 1800 }));
|
||||
await checkBoltTracking();
|
||||
const group = await getGroup();
|
||||
expect(group.boltOrderState).toBe('preparing');
|
||||
expect(group.boltTrackingToken).toBe(TOKEN);
|
||||
});
|
||||
|
||||
test('chybová odpověď Bolt API (code != 0) se počítá jako selhání', async () => {
|
||||
|
||||
Reference in New Issue
Block a user