Обработчик тестового события с полной визуализацией карты DOM Leaflet - PullRequest
0 голосов
/ 30 мая 2020

У меня есть компонент под названием «Карта», отвечающий за управление всем, что мне нужно для рендеринга карты с помощью плагина Leaflet (только создать контейнер для карты, запросить карту листовки для рендеринга и запросить маркеры для рендеринга), и он работает отлично.

Компонент My Map:

import React, { Component } from 'react';
import L from 'leaflet';

class Map extends Component {
  constructor(props) {
    super(props);
    this.mapId = `map-${uniqueID()}`;
    this._map = null;
    this.state = {
      markers: []
    };
    //some more code
  }

  componentDidMount() {
    // ...create map using Leaflet plugin inside $(".my-component > .map")
    // ...render markers
  }

  addZoomEndHandler(handler) {
    this._map.on('zoomend', handler);
  }

  addEventHandlers = (markers) => {
    markers.forEach((m) => {
      const marker = m;
      marker.eventHandlers = {
        click(e) {
          marker.onClick && marker.onClick(e);
        }
        //some other events
      };
    });
  }

  //some more code

  render() {
    return (
      <div className="my-component map-container">
        <div id={this.mapId} className="map">
        </div>
      </div>
    );
  }
}

Сейчас я пытаюсь написать несколько тестов с использованием Enzyme и Jest, но у меня возникли некоторые проблемы.

Вот один из моих неудачных тестов:

it('should trigger the marker click event', (done) => {
  const onMarkerClickMock = jest.fn(),
    myMarkers = [{
                  id: '0',
                  geolocation: { coordinates: [38.734577, -9.21739], type: 'Point' },
                  onClick: onMarkerClickMock
                }],
    markerSelector = '#path__0';


  $.ajax.mockImplementationOnce((request) => {
    expect(request.url).toContain(`https://maps.google.com/maps/api/js?v=3.&key=${myKey}`);
    return new Promise((resolve) => {
      fs.readFile(`${__dirname}test-data/google.js`, 'utf8', (err, data) => {
        request.success(resolve(data));
      });
    });
  });

  const map = mount(<Map markers={myMarkers} />);

  setTimeout(() => {
    const markers = map.state('markers');
    expect(markers).toHaveLength(1);
    expect(typeof markers[0].onClick).toBe('function');
    expect(markers[0].onClick).toEqual(onMarkerClickMock);
    map.find(markerSelector).simulate('click');         // <- failing here
    expect(onMarkerClickMock).toHaveBeenCalledTimes(1);
    done();
  }, 500);
});

Сначала у меня были проблемы с setTimeOut, а затем я понял, что мне нужно вызвать done() внутри него. Теперь, когда вызывается map.find(markerSelector), он выдает следующее сообщение об ошибке:

Метод «simulate» предназначен для запуска на 1 узле. Вместо этого был найден 0.

Я сделал map.html(), и он вернул только это:

<div class="my-component map-container" role="button" tabindex="0">
    <div id="map-61bb504b-8c6d-fb91-e743-e67f4b6b3f8a" class="map"></div>
</div>

Но я ожидал, что он вернул что-то вроде этого с визуализированной картой листовок:

<div class="my-component map-container" role="button" tabindex="0">
   <div id="map-61bb504b-8c6d-fb91-e743-e67f4b6b3f8a" class="map leaflet-container leaflet-fade-anim leaflet-grab leaflet-touch-drag" tabindex="0" style="position: relative; outline: none;">
      <div class="leaflet-pane leaflet-map-pane" style="transform: translate3d(-319px, 0px, 0px);">
         <div class="leaflet-pane leaflet-tile-pane">
            <div class="leaflet-layer " style="z-index: 1; opacity: 1;">
               <div class="leaflet-tile-container leaflet-zoom-animated" style="z-index: 18; transform: translate3d(0px, 0px, 0px) scale(1);">
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(268px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124766!3i98632!4i256!2m3!1e0!2sm!3i515229400!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=99746" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(524px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124767!3i98632!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=94189" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(268px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124766!3i98633!4i256!2m3!1e0!2sm!3i515227686!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=14690" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(524px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124767!3i98633!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=98859" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(12px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124765!3i98632!4i256!2m3!1e0!2sm!3i515229400!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=40319" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(780px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124768!3i98632!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=22545" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(12px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124765!3i98633!4i256!2m3!1e0!2sm!3i515227686!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=86334" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(780px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124768!3i98633!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=27215" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(-244px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124764!3i98632!4i256!2m3!1e0!2sm!3i515218768!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=61271" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(1036px, -73px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124769!3i98632!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=81972" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(-244px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124764!3i98633!4i256!2m3!1e0!2sm!3i515216758!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=41588" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
                  <div class="leaflet-tile leaflet-tile-loaded" data-pending="0" style="width: 256px; height: 256px; transform: translate3d(1036px, 183px, 0px); opacity: 1;"><img draggable="false" alt="" role="presentation" src="https://maps.google.com/maps/vt?pb=!1m5!1m4!1i18!2i124769!3i98633!4i256!2m3!1e0!2sm!3i515229832!3m12!2spt!3sUS!5e18!12m4!1e68!2m2!1sset!2sRoadmap!12m3!1e37!2m1!1ssmartmaps!4e0&amp;key=AIzaSyCwHM3UZdSmdNOW2WvFH8UuG4YtgKCv000&amp;token=86642" style="width: 256px; height: 256px; user-select: none; border: 0px; padding: 0px; margin: 0px; max-width: none; position: absolute; visibility: visible;"></div>
               </div>
            </div>
         </div>
         <div class="leaflet-pane leaflet-shadow-pane"></div>
         <div class="leaflet-pane leaflet-overlay-pane">
            <svg pointer-events="none" class="leaflet-zoom-animated" width="704" height="480" viewBox="260 -40 704 480" style="transform: translate3d(260px, -40px, 0px);">
               <g>
                  <path class="leaflet-interactive" stroke="#e8008b" stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="#e8008b" fill-opacity="1" fill-rule="evenodd" d="M613,200L600.3538070924236,134.9409774905928A 66.27671238780022,66,0,0,1,654.709286557388,148.49332062917586 z" id="path__0" type="" networkelement="0"></path>
               </g>
            </svg>
         </div>
         <div class="leaflet-pane leaflet-marker-pane"></div>
         <div class="leaflet-pane leaflet-tooltip-pane"></div>
         <div class="leaflet-pane leaflet-popup-pane"></div>
         <div class="leaflet-proxy leaflet-zoom-animated" style="transform: translate3d(3.19404e+07px, 2.52501e+07px, 0px) scale(131072);"></div>
      </div>
      <div class="leaflet-control-container">
         <div class="leaflet-top leaflet-left"></div>
         <div class="leaflet-top leaflet-right"></div>
         <div class="leaflet-bottom leaflet-left" style="margin-bottom: 20px;"></div>
         <div class="leaflet-bottom leaflet-right" style="margin-bottom: 20px;">
            <div class="leaflet-control-zoom leaflet-bar leaflet-control"><a class="leaflet-control-zoom-in leaflet-disabled" href="#" title="Zoom in" role="button" aria-label="Zoom in">+</a><a class="leaflet-control-zoom-out" href="#" title="Zoom out" role="button" aria-label="Zoom out">−</a></div>
            <div class="leaflet-control-attribution leaflet-control"><a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a> | Map © 2020 <a target="_blank" href="https://developers.google.com/maps/">Google</a></div>
         </div>
      </div>
   </div>
</div>

Почему mount() не полностью отображает мой компонент? Что мне здесь не хватает? Кто-нибудь может мне помочь? Я просто хочу подтвердить, что моя функция маркера onClick() вызывается ...

...