---
type: test-plan
work_item_id: ET-007
title: "Test Plan: Спутниковая карта (Схема / Спутник)"
version: 1
status: draft
created_at: 2026-05-31
updated_at: 2026-05-31
authors:
  - "agent:analyst"

test_suites:

  - name: unit-base-layer-state
    type: unit
    description: "Чтение/запись/восстановление выбора подложки"
    cases:
      - id: U-01
        name: "Default — Схема, если localStorage пуст"
        input: "localStorage без ключа 'map-base-layer'"
        expected: "restoreBaseLayerState() выставляет base='schematic'"

      - id: U-02
        name: "Чтение значения 'satellite' из localStorage"
        input: "localStorage['map-base-layer'] = 'satellite'"
        expected: "restoreBaseLayerState() выставляет base='satellite'"

      - id: U-03
        name: "Запись значения при переключении"
        input: "onBaseLayerToggle('satellite')"
        expected: "localStorage['map-base-layer'] === 'satellite'"

      - id: U-04
        name: "Игнор некорректного значения в localStorage"
        input: "localStorage['map-base-layer'] = 'unknown'"
        expected: "restoreBaseLayerState() fallback на 'schematic'"

      - id: U-05
        name: "Toggle на уже активный режим — no-op"
        input: "active=schematic; onBaseLayerToggle('schematic')"
        expected: "Никаких изменений в стиле, localStorage не записывается повторно"

  - name: unit-ui-sync
    type: unit
    description: "Синхронизация .active у кнопок переключателя"
    cases:
      - id: U-10
        name: "syncBaseLayerUI('satellite')"
        input: "DOM с #base-btn-schematic.active и #base-btn-satellite без класса"
        expected: "После: #base-btn-satellite.active=true, #base-btn-schematic.active=false"

      - id: U-11
        name: "syncBaseLayerUI('schematic')"
        input: "DOM с #base-btn-satellite.active"
        expected: "После: #base-btn-schematic.active=true, #base-btn-satellite.active=false"

  - name: integration-maplibre-layers
    type: integration
    description: "Взаимодействие с MapLibre source/layer"
    cases:
      - id: I-01
        name: "Добавление спутникового source при первом включении"
        input: "applyBaseLayer('satellite') впервые"
        expected: "map.getSource('satellite-raster') !== undefined; URL содержит arcgisonline.com"

      - id: I-02
        name: "Добавление спутникового layer при первом включении"
        input: "applyBaseLayer('satellite') впервые"
        expected: "map.getLayer('satellite-base') !== undefined; type='raster'"

      - id: I-03
        name: "Visibility OSM-base после переключения на спутник"
        input: "applyBaseLayer('satellite')"
        expected: "map.getLayoutProperty('osm-base', 'visibility') === 'none'"

      - id: I-04
        name: "Visibility satellite-base после переключения на схему"
        input: "applyBaseLayer('satellite') → applyBaseLayer('schematic')"
        expected: "satellite-base.visibility==='none', osm-base.visibility==='visible'"

      - id: I-05
        name: "Z-order: satellite ниже terrain и trails"
        input: "applyBaseLayer('satellite'); включены hillshade и trails"
        expected: "Layer index(satellite-base) < index(terrain-hillshade) < index(trails-track)"

      - id: I-06
        name: "Position карты сохраняется при переключении"
        input: "center=[37.6,55.75], zoom=10; applyBaseLayer('satellite')"
        expected: "После: getCenter() == [37.6,55.75], getZoom() == 10"

      - id: I-07
        name: "Атрибуция Esri зарегистрирована"
        input: "applyBaseLayer('satellite')"
        expected: "source 'satellite-raster' содержит attribution с упоминанием Esri"

  - name: integration-style-switch
    type: integration
    description: "Поведение при map.setStyle (смена темы)"
    cases:
      - id: I-10
        name: "Спутник восстанавливается после setStyle (тёмная → светлая)"
        input: "active='satellite'; вызывается switchMapStyle()"
        expected: "После idle: layer 'satellite-base' существует; visibility='visible'; osm-base.visibility='none'"

      - id: I-11
        name: "Сохранённое состояние читается из localStorage в rebuildMapOverlays"
        input: "localStorage='satellite'; rebuildMapOverlays() вручную"
        expected: "applyBaseLayer вызван с 'satellite'"

      - id: I-12
        name: "Восстановление выполняется до restoreTerrainState"
        input: "rebuildMapOverlays() с заглушками-shpions"
        expected: "Порядок вызовов: restoreBaseLayerState → restoreTerrainState"

  - name: integration-other-layers
    type: integration
    description: "Совместимость со всеми клиентскими слоями"
    cases:
      - id: I-20
        name: "Маршрут OSRM не теряется при переключении"
        input: "Построен маршрут; applyBaseLayer('satellite')"
        expected: "Layer маршрута существует, координаты не изменились"

      - id: I-21
        name: "GPX-трек не теряется при переключении"
        input: "Загружен GPX; applyBaseLayer('satellite')"
        expected: "Layer gpx-* существует, source.data не изменён"

      - id: I-22
        name: "Recon-круг не теряется при переключении"
        input: "Активен recon; applyBaseLayer('satellite')"
        expected: "Recon-круг отображается на карте"

      - id: I-23
        name: "Hillshade поверх спутника"
        input: "applyBaseLayer('satellite'); включить hillshade"
        expected: "Оба слоя видимы; hillshade выше satellite-base в стиле"

      - id: I-24
        name: "POI halo чёрный на спутнике"
        input: "applyBaseLayer('satellite')"
        expected: "map.getPaintProperty('poi-labels','text-halo-color') === '#000000' (или эквивалент)"

      - id: I-25
        name: "POI halo дефолтный на схеме"
        input: "applyBaseLayer('schematic') после спутника"
        expected: "POI labels вернули halo цвет схемы (#ffffff)"

  - name: e2e-base-layer-workflow
    type: e2e
    description: "Полный пользовательский сценарий"
    cases:
      - id: E-01
        name: "Открыть попап → включить спутник → сохранилось"
        steps:
          - "Открыть приложение (default — Схема)"
          - "Нажать кнопку «Рельеф» в правой панели"
          - "Убедиться: переключатель «Подложка» виден"
          - "Нажать «Спутник»"
          - "Убедиться: спутниковые тайлы загрузились"
          - "Убедиться: атрибуция Esri видна"
          - "Перезагрузить страницу"
          - "Убедиться: после загрузки активен «Спутник»"

      - id: E-02
        name: "Переключение туда-обратно без потери маршрута"
        steps:
          - "Построить маршрут через OSRM (2 точки)"
          - "Переключить на «Спутник»"
          - "Убедиться: маршрут виден на спутнике, статистика сохранена"
          - "Переключить на «Схема»"
          - "Убедиться: маршрут виден на схеме, статистика та же"

      - id: E-03
        name: "Спутник + загрузка GPX"
        steps:
          - "Переключить на «Спутник»"
          - "Загрузить GPX-файл"
          - "Убедиться: трек отрисован поверх спутника"
          - "Убедиться: цвет трека различим"

      - id: E-04
        name: "Спутник + смена темы"
        steps:
          - "Переключить на «Спутник»"
          - "Переключить тёмную тему на светлую"
          - "Дождаться idle"
          - "Убедиться: подложка осталась «Спутник»"
          - "Убедиться: все остальные слои восстановились"

      - id: E-05
        name: "Спутник + переключение единиц измерения"
        steps:
          - "Переключить на «Спутник»"
          - "Открыть попап слоёв и переключить «мили»"
          - "Убедиться: единицы переключились, подложка не сбросилась"

      - id: E-06
        name: "Спутник + hillshade"
        steps:
          - "Переключить на «Спутник»"
          - "Включить «Тени рельефа»"
          - "Убедиться: видны спутник и тени одновременно"

      - id: E-07
        name: "Линейка на спутнике"
        steps:
          - "Переключить на «Спутник»"
          - "Активировать линейку"
          - "Поставить 3 точки на карте"
          - "Убедиться: линия линейки видна на спутнике"
          - "Убедиться: расстояния отображаются"

  - name: e2e-error-handling
    type: e2e
    description: "Поведение при сетевых ошибках"
    cases:
      - id: E-10
        name: "Спутниковые тайлы недоступны (offline)"
        steps:
          - "Включить «Спутник»"
          - "Симулировать offline (DevTools throttling: Offline)"
          - "Сдвинуть карту в новую область"
          - "Убедиться: приложение не падает; видим фон background"
          - "Восстановить сеть → тайлы догружаются"

test_data:
  - name: "test-track-simple.gpx"
    description: "1 трек, 10 точек — для проверки совместимости с GPX"
  - name: "Тестовый OSRM-маршрут"
    description: "2 waypoint в районе [37.6,55.75] → [37.7,55.8]"
