mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
feat(tours): plan ski tours on the piste router in the planner
A ski tour with a discipline now sends its legs to the piste router and takes back runs, lifts and trails: each stretch is coloured by its grade in the area's scheme, links and lift rides down are dotted, and a leg the router cannot plan stays straight and unrouted with its reason and the one change that would plan it. Snowshoe and winter hike legs off the piste data follow summer paths instead, said so. The router's time and heights are used once every leg is planned, and the options, the build and the time are saved with the tour. - skiRouteRepo and api: one request per tour, batched, remembered unless the answer may change, offline legs failed as offline - planner: router options per discipline, leg steps and failure rows with fixes, a piste route summary, draft and reopen keep the options - admin: switch for the piste router under Tours - i18n: new ski keys in all 27 locales, ski info and time texts rewritten
This commit is contained in:
@@ -2,7 +2,7 @@ import { act, renderHook, waitFor } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { adminApi } from '../../../api/client';
|
||||
import { cycleMapAdminApi, hikingMapAdminApi } from '../../../api/tourBaseMaps';
|
||||
import { cycleMapAdminApi, hikingMapAdminApi, skiRoutingAdminApi } from '../../../api/tourBaseMaps';
|
||||
import { wandererAdminApi } from '../../../api/wanderer';
|
||||
import { useAddonStore } from '../../../store/addonStore';
|
||||
import type { Addon } from './addonModel';
|
||||
@@ -40,6 +40,7 @@ beforeEach(() => {
|
||||
vi.spyOn(wandererAdminApi, 'get').mockResolvedValue({ enabled: false });
|
||||
vi.spyOn(hikingMapAdminApi, 'get').mockResolvedValue({ enabled: true });
|
||||
vi.spyOn(cycleMapAdminApi, 'get').mockResolvedValue({ enabled: true });
|
||||
vi.spyOn(skiRoutingAdminApi, 'get').mockResolvedValue({ enabled: true });
|
||||
});
|
||||
afterEach(() => vi.restoreAllMocks());
|
||||
|
||||
@@ -52,7 +53,7 @@ async function loaded() {
|
||||
const enabledOf = (addons: Addon[], id: string) => addons.find((a) => a.id === id)?.enabled;
|
||||
|
||||
/** One of the map switches under Tours, by its key. */
|
||||
function mapSwitch(manager: ReturnType<typeof useAddonManager>, key: 'hiking' | 'cycle') {
|
||||
function mapSwitch(manager: ReturnType<typeof useAddonManager>, key: 'hiking' | 'cycle' | 'ski') {
|
||||
const found = manager.mapSwitches.find((entry) => entry.key === key);
|
||||
if (!found) throw new Error(`no ${key} map switch`);
|
||||
return found;
|
||||
@@ -149,6 +150,16 @@ describe('useAddonManager', () => {
|
||||
expect(mapSwitch(result.current, 'hiking').enabled).toBe(true);
|
||||
});
|
||||
|
||||
it('FE-HOOK-ADDONMGR-010: the piste router switch under Tours loads on, flips and saves on its own (SKI-02)', async () => {
|
||||
const update = vi.spyOn(skiRoutingAdminApi, 'update').mockResolvedValue({ enabled: false });
|
||||
const { result } = await loaded();
|
||||
await waitFor(() => expect(mapSwitch(result.current, 'ski').enabled).toBe(true));
|
||||
await act(() => mapSwitch(result.current, 'ski').toggle());
|
||||
expect(update).toHaveBeenCalledWith(false);
|
||||
expect(mapSwitch(result.current, 'ski').enabled).toBe(false);
|
||||
expect(mapSwitch(result.current, 'cycle').enabled).toBe(true);
|
||||
});
|
||||
|
||||
it('FE-HOOK-ADDONMGR-008: a failed save puts the switch under Tours back and says so', async () => {
|
||||
vi.spyOn(wandererAdminApi, 'update').mockRejectedValue(new Error('500'));
|
||||
const { result } = await loaded();
|
||||
|
||||
Reference in New Issue
Block a user