"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importDefault(require("react"));
var react_2 = require("@testing-library/react");
var user_event_1 = __importDefault(require("@testing-library/user-event"));
var ramda_1 = require("ramda");
var jest_mocks_1 = require("@googlemaps/jest-mocks");
var constants_1 = require("../constants");
var usePolygonDrawing_1 = require("./components/PolygonDrawing/usePolygonDrawing");
var helpers = __importStar(require("./helpers"));
var ReltioMap_1 = require("./ReltioMap");
jest.mock('@vis.gl/react-google-maps', function () { return (__assign(__assign({}, jest.requireActual('@vis.gl/react-google-maps')), { MapControl: function (_a) {
        var children = _a.children;
        return react_1.default.createElement(react_1.default.Fragment, null, children);
    } })); });
describe('ReltioMap tests', function () {
    var defaultProps = {
        onOverlayUpdated: jest.fn(),
        onMarkerClicked: jest.fn(),
        isSearchEnabled: true,
        defaultZoom: 10,
        defaultCenter: { lat: 1, lng: 1 },
        mapKey: 'mapKey',
        loadingElement: react_1.default.createElement("div", null, "loading element")
    };
    var setUp = function (props) {
        if (props === void 0) { props = defaultProps; }
        var user = user_event_1.default.setup();
        return __assign(__assign({}, (0, react_2.render)(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, props)))), { user: user });
    };
    /**
     * Map click payload: must expose lat()/lng() for serialization and equals() for polygonRingHelpers
     */
    var mapMouseEventWith = function (lat, lng) { return ({
        latLng: {
            lat: function () { return lat; },
            lng: function () { return lng; },
            equals: function (other) {
                var oLat = typeof other.lat === 'function'
                    ? other.lat()
                    : other.lat;
                var oLng = typeof other.lng === 'function'
                    ? other.lng()
                    : other.lng;
                return oLat === lat && oLng === lng;
            }
        }
    }); };
    beforeAll(function () {
        (0, jest_mocks_1.initialize)();
        var OriginalMap = google.maps.Map;
        jest.spyOn(google.maps, 'Map').mockImplementation(function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var mapInstance = new (OriginalMap.bind.apply(OriginalMap, __spreadArray([void 0], args, false)))();
            mapInstance.setOptions = jest.fn();
            mapInstance.get = jest.fn(function () { return undefined; });
            return mapInstance;
        });
        var overlayView = new jest_mocks_1.OverlayView();
        for (var property in overlayView) {
            if (!global.google.maps.OverlayView.prototype.hasOwnProperty(property)) {
                global.google.maps.OverlayView.prototype[property] = overlayView[property];
            }
        }
    });
    afterEach(function () {
        jest.clearAllMocks();
        jest_mocks_1.mockInstances.clearAll();
    });
    var getEventHandler = function (target, event) {
        var _a, _b;
        return ((_a = (0, ramda_1.findLast)(function (_a) {
            var instance = _a[0], googleEventName = _a[1];
            return instance === target && googleEventName === event;
        }, global.google.maps.event.addListener.mock.calls)) === null || _a === void 0 ? void 0 : _a[2]) || ((_b = (0, ramda_1.findLast)(function (_a) {
            var name = _a[0];
            return name === event;
        }, target.addListener.mock.calls)) === null || _b === void 0 ? void 0 : _b[1]);
    };
    var getLastInstance = function (instance) { return (0, ramda_1.last)(jest_mocks_1.mockInstances.get(instance)); };
    var getFirstInstance = function (instance) { var _a; return (_a = jest_mocks_1.mockInstances.get(instance)) === null || _a === void 0 ? void 0 : _a[0]; };
    describe('general behaviour', function () {
        it('should render map controls', function () { return __awaiter(void 0, void 0, void 0, function () {
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true }));
                        _a = expect;
                        return [4 /*yield*/, react_2.screen.findByLabelText('Draw area')];
                    case 1:
                        _a.apply(void 0, [_b.sent()]).toBeInTheDocument();
                        expect(react_2.screen.getByText('Search as I move the map')).toBeInTheDocument();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should combine mapOptions', function () { return __awaiter(void 0, void 0, void 0, function () {
            var mapOptions;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        mapOptions = { mapTypeControl: true };
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, mapOptions: mapOptions }));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(google.maps.Map).toHaveBeenCalledWith(expect.any(HTMLElement), expect.objectContaining({
                                    fullscreenControl: false,
                                    mapTypeControl: true,
                                    streetViewControl: false
                                }));
                            })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should not render map controls', function () { return __awaiter(void 0, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, isSearchEnabled: false }));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(react_2.screen.queryByLabelText('Draw area')).not.toBeInTheDocument();
                            })];
                    case 1:
                        _a.sent();
                        expect(react_2.screen.queryByText('Search as I move the map')).not.toBeInTheDocument();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should render markers correctly', function () { return __awaiter(void 0, void 0, void 0, function () {
            var markers, onMarkerClick, markerMock;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        markers = [
                            {
                                point: { lat: 1, lng: 1 },
                                visible: true,
                                id: '123',
                                entity: { uri: 'testUri', type: 'testType' },
                                label: 'testMarker'
                            }
                        ];
                        onMarkerClick = jest.fn();
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, onMarkerClicked: onMarkerClick, markers: markers }));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                markerMock = getLastInstance(jest_mocks_1.AdvancedMarkerElement);
                                expect(markerMock).toBeDefined();
                            })];
                    case 1:
                        _a.sent();
                        getEventHandler(markerMock, 'click')();
                        expect(onMarkerClick).toHaveBeenCalled();
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('fitting bounds behavior', function () {
        it('should fit map bounds correctly if markers loaded later than map', function () {
            var fitMapBoundsForMarkers = jest.spyOn(helpers, 'fitMapBoundsForMarkers');
            var fitMapBoundsForOverlay = jest.spyOn(helpers, 'fitMapBoundsForOverlay');
            var rerender = setUp(__assign(__assign({}, defaultProps), { markers: [] })).rerender;
            expect(fitMapBoundsForMarkers).not.toHaveBeenCalled();
            expect(fitMapBoundsForOverlay).not.toHaveBeenCalled();
            var newProps = __assign(__assign({}, defaultProps), { markers: [
                    {
                        point: { lat: 1, lng: 1 },
                        visible: true,
                        id: '1',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    },
                    {
                        point: { lat: 2, lng: 2 },
                        visible: true,
                        id: '2',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    }
                ] });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            var mapMock = getLastInstance(jest_mocks_1.Map);
            expect(fitMapBoundsForOverlay).not.toHaveBeenCalled();
            expect(fitMapBoundsForMarkers).toHaveBeenCalledWith(newProps.markers, mapMock, undefined);
        });
        it('should fit map bounds correctly if markers loaded later than map and activeOverlay is not null', function () {
            var activeOverlay = {
                type: constants_1.POLYGON_DRAWING_MODE,
                path: [
                    { lat: 1, lng: 1 },
                    { lat: 2, lng: 2 }
                ]
            };
            var fitMapBoundsForMarkers = jest.spyOn(helpers, 'fitMapBoundsForMarkers');
            var fitMapBoundsForOverlay = jest.spyOn(helpers, 'fitMapBoundsForOverlay');
            var rerender = setUp(__assign(__assign({}, defaultProps), { markers: [], activeOverlay: activeOverlay })).rerender;
            expect(fitMapBoundsForMarkers).not.toHaveBeenCalled();
            expect(fitMapBoundsForOverlay).not.toHaveBeenCalledWith(activeOverlay);
            var newProps = __assign(__assign({}, defaultProps), { activeOverlay: activeOverlay, markers: [
                    {
                        point: { lat: 1, lng: 1 },
                        visible: true,
                        id: '1',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    },
                    {
                        point: { lat: 2, lng: 2 },
                        visible: true,
                        id: '2',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    }
                ] });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            expect(fitMapBoundsForOverlay).toHaveBeenCalledTimes(1);
            var mapMock = getLastInstance(jest_mocks_1.Map);
            expect(fitMapBoundsForMarkers).toHaveBeenCalledWith(newProps.markers, mapMock, activeOverlay);
        });
        it('should not fit map bounds when markers changed and "Search when I move the map" mode is on', function () {
            var fitMapBoundsForMarkers = jest.spyOn(helpers, 'fitMapBoundsForMarkers');
            var fitMapBoundsForOverlay = jest.spyOn(helpers, 'fitMapBoundsForOverlay');
            var rerender = setUp(__assign(__assign({}, defaultProps), { isSearchOnMapMove: false, markers: [] })).rerender;
            var newProps = __assign(__assign({}, defaultProps), { isSearchOnMapMove: true, markers: [
                    {
                        point: { lat: 1, lng: 1 },
                        visible: true,
                        id: '1',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    },
                    {
                        point: { lat: 2, lng: 2 },
                        visible: true,
                        id: '2',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    }
                ] });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            expect(fitMapBoundsForMarkers).toHaveBeenCalledTimes(0);
            expect(fitMapBoundsForOverlay).toHaveBeenCalledTimes(0);
        });
        it('should fit map bounds when activeOverlay changed', function () {
            var fitMapBoundsForMarkers = jest.spyOn(helpers, 'fitMapBoundsForMarkers');
            var fitMapBoundsForOverlay = jest.spyOn(helpers, 'fitMapBoundsForOverlay');
            var rerender = setUp(__assign(__assign({}, defaultProps), { activeOverlay: null })).rerender;
            var newProps = __assign(__assign({}, defaultProps), { activeOverlay: {
                    type: constants_1.POLYGON_DRAWING_MODE,
                    path: [
                        { lat: 1, lng: 1 },
                        { lat: 2, lng: 2 }
                    ]
                } });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            var mapMock = getLastInstance(jest_mocks_1.Map);
            expect(fitMapBoundsForOverlay).toHaveBeenCalledTimes(1);
            expect(fitMapBoundsForMarkers).toHaveBeenCalledTimes(0);
            expect(fitMapBoundsForOverlay).toHaveBeenCalledWith(mapMock, newProps.activeOverlay);
        });
        it('should run fit map bounds only once when activeOverlay and markers are changed simultaneously', function () {
            var fitMapBoundsForMarkers = jest.spyOn(helpers, 'fitMapBoundsForMarkers');
            var fitMapBoundsForOverlay = jest.spyOn(helpers, 'fitMapBoundsForOverlay');
            var rerender = setUp(__assign(__assign({}, defaultProps), { activeOverlay: null })).rerender;
            var newProps = __assign(__assign({}, defaultProps), { activeOverlay: {
                    type: constants_1.POLYGON_DRAWING_MODE,
                    path: [
                        { lat: 1, lng: 1 },
                        { lat: 2, lng: 2 }
                    ]
                }, markers: [
                    {
                        point: { lat: 1, lng: 1 },
                        visible: true,
                        id: '1',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    },
                    {
                        point: { lat: 2, lng: 2 },
                        visible: true,
                        id: '2',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    }
                ] });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            var mapMock = getLastInstance(jest_mocks_1.Map);
            expect(fitMapBoundsForMarkers).toHaveBeenCalledTimes(1);
            expect(fitMapBoundsForOverlay).toHaveBeenCalledTimes(0);
            expect(fitMapBoundsForMarkers).toHaveBeenCalledWith(newProps.markers, mapMock, newProps.activeOverlay);
        });
        it('should align zoom level when fit map bounds for single marker', function () {
            var rerender = setUp(__assign(__assign({}, defaultProps), { activeOverlay: null })).rerender;
            var newProps = __assign(__assign({}, defaultProps), { markers: [
                    {
                        point: { lat: 1, lng: 1 },
                        visible: true,
                        id: '1',
                        entity: { uri: 'testUri', type: 'testType' },
                        label: 'testMarker'
                    }
                ] });
            rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
            var mapMock = getLastInstance(jest_mocks_1.Map);
            expect(mapMock.fitBounds.mock.calls[0][0].extend.mock.calls[0]).toEqual([{ lat: 1, lng: 1 }]);
            expect(mapMock.fitBounds.mock.calls[0][0].extend.mock.calls).toHaveLength(3);
        });
    });
    describe('polygon behavior', function () {
        it('should render Polygon if "activeOverlay" prop is polygon and there is no enabled drawing mode', function () { return __awaiter(void 0, void 0, void 0, function () {
            var activeOverlay, _a, user, rerender, polygon, newProps;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        activeOverlay = {
                            type: constants_1.POLYGON_DRAWING_MODE,
                            path: [
                                { lat: 1, lng: 1 },
                                { lat: 2, lng: 2 }
                            ]
                        };
                        _a = setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: activeOverlay })), user = _a.user, rerender = _a.rerender;
                        polygon = getLastInstance(jest_mocks_1.Polygon);
                        expect(polygon.setOptions).toHaveBeenCalledWith(expect.objectContaining({ paths: activeOverlay.path }));
                        newProps = __assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: null });
                        rerender(react_1.default.createElement(ReltioMap_1.ReltioMap, __assign({}, newProps)));
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 1:
                        _b.sent();
                        expect(polygon.setMap).toHaveBeenCalledWith(null);
                        return [2 /*return*/];
                }
            });
        }); });
        it('should not render Polygon if "activeOverlay" is not a polygon', function () { return __awaiter(void 0, void 0, void 0, function () {
            var activeOverlay;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        activeOverlay = {
                            type: 'bounds-rectangle',
                            path: [{ lat: 1, lng: 1 }]
                        };
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: activeOverlay }));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(jest_mocks_1.mockInstances.get(jest_mocks_1.Polygon)).toHaveLength(0);
                            })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onOverlayUpdated on polygon mouse up', function () { return __awaiter(void 0, void 0, void 0, function () {
            var activeOverlay, onOverlayUpdated, polygon;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        activeOverlay = {
                            type: constants_1.POLYGON_DRAWING_MODE,
                            path: [
                                { lat: 1, lng: 1 },
                                { lat: 2, lng: 2 }
                            ]
                        };
                        onOverlayUpdated = jest.fn();
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: activeOverlay, onOverlayUpdated: onOverlayUpdated }));
                        polygon = getLastInstance(jest_mocks_1.Polygon);
                        getEventHandler(polygon, 'mouseup')();
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(onOverlayUpdated).toHaveBeenCalledWith({
                                    type: constants_1.POLYGON_DRAWING_MODE,
                                    data: []
                                });
                            })];
                    case 1:
                        _a.sent();
                        expect(polygon.setOptions).toHaveBeenCalledWith(expect.objectContaining({ paths: activeOverlay.path }));
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onOverlayUpdated on polygon drag end', function () { return __awaiter(void 0, void 0, void 0, function () {
            var activeOverlay, onOverlayUpdated, polygon;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        activeOverlay = {
                            type: constants_1.POLYGON_DRAWING_MODE,
                            path: [
                                { lat: 1, lng: 1 },
                                { lat: 2, lng: 2 }
                            ]
                        };
                        onOverlayUpdated = jest.fn();
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: activeOverlay, onOverlayUpdated: onOverlayUpdated }));
                        polygon = getLastInstance(jest_mocks_1.Polygon);
                        getEventHandler(polygon, 'dragend')();
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(onOverlayUpdated).toHaveBeenCalledWith({
                                    type: constants_1.POLYGON_DRAWING_MODE,
                                    data: []
                                });
                            })];
                    case 1:
                        _a.sent();
                        expect(polygon.setOptions).toHaveBeenCalledWith(expect.objectContaining({ paths: activeOverlay.path }));
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('drawing behavior', function () {
        it("shouldn't enable double-click zoom suppression before entering draw mode", function () { return __awaiter(void 0, void 0, void 0, function () {
            var mapMock;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true }));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        expect(mapMock.setOptions).not.toHaveBeenCalledWith({ disableDoubleClickZoom: true });
                        return [2 /*return*/];
                }
            });
        }); });
        it('should toggle double-click zoom suppression when entering and leaving polygon drawing mode', function () { return __awaiter(void 0, void 0, void 0, function () {
            var user, mapMock;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        user = setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            draggableCursor: usePolygonDrawing_1.MAP_DRAWING_CROSSHAIR_CURSOR
                        }));
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            disableDoubleClickZoom: true,
                            clickableIcons: false
                        }));
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Clear area'))];
                    case 3:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({ disableDoubleClickZoom: false }));
                        return [2 /*return*/];
                }
            });
        }); });
        it("shouldn't attach polygon drawing listeners when polygon drawing is disabled", function () { return __awaiter(void 0, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        setUp(__assign({}, defaultProps));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(react_2.screen.queryByLabelText('Draw area')).not.toBeInTheDocument();
                            })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        }); });
        it("shouldn't render TopRightMapControls when polygon drawing is disabled", function () { return __awaiter(void 0, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        setUp(__assign({}, defaultProps));
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(react_2.screen.queryByLabelText('Draw area')).not.toBeInTheDocument();
                            })];
                    case 1:
                        _a.sent();
                        expect(react_2.screen.queryByLabelText('Clear area')).not.toBeInTheDocument();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onOverlayUpdated after polygon completing with correct vertex coordinates', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onOverlayUpdated, OriginalPolygon, polygonPathSpy, user, mapMock, mapDiv, clickHandler;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onOverlayUpdated = jest.fn();
                        OriginalPolygon = google.maps.Polygon;
                        polygonPathSpy = jest.spyOn(google.maps, 'Polygon').mockImplementation(function (opts) {
                            var instance = new OriginalPolygon(opts);
                            var raw = opts === null || opts === void 0 ? void 0 : opts.paths;
                            var ring = !raw
                                ? []
                                : 'getArray' in raw
                                    ? raw.getArray()
                                    : raw;
                            var mvc = new google.maps.MVCArray();
                            mvc.getArray = jest.fn(function () { return ring; });
                            instance.getPath = jest.fn(function () { return mvc; });
                            return instance;
                        });
                        user = setUp(__assign(__assign({}, defaultProps), { onOverlayUpdated: onOverlayUpdated, enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                var m = getLastInstance(jest_mocks_1.Map);
                                if (!m) {
                                    throw new Error('Map not ready');
                                }
                                return m;
                            })];
                    case 1:
                        mapMock = _a.sent();
                        mapDiv = document.createElement('div');
                        mapMock.getDiv = jest.fn(function () { return mapDiv; });
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        clickHandler = getEventHandler(mapMock, 'click');
                        (0, react_2.act)(function () {
                            clickHandler(mapMouseEventWith(1, 2));
                            clickHandler(mapMouseEventWith(3, 4));
                            clickHandler(mapMouseEventWith(5, 6));
                        });
                        (0, react_2.act)(function () {
                            mapDiv.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true, composed: true }));
                        });
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(onOverlayUpdated).toHaveBeenCalled();
                            })];
                    case 3:
                        _a.sent();
                        expect(onOverlayUpdated.mock.calls[0][0]).toEqual(expect.objectContaining({
                            type: constants_1.POLYGON_DRAWING_MODE,
                            data: [
                                [1, 2],
                                [3, 4],
                                [5, 6]
                            ]
                        }));
                        polygonPathSpy.mockRestore();
                        return [2 /*return*/];
                }
            });
        }); });
        it('completes the ring when the first vertex marker is clicked after three map clicks', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onOverlayUpdated, OriginalPolygon, polygonPathSpy, user, mapMock, mapDiv, clickHandler, firstVertexMarker;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onOverlayUpdated = jest.fn();
                        OriginalPolygon = google.maps.Polygon;
                        polygonPathSpy = jest.spyOn(google.maps, 'Polygon').mockImplementation(function (opts) {
                            var instance = new OriginalPolygon(opts);
                            var raw = opts === null || opts === void 0 ? void 0 : opts.paths;
                            var ring = !raw
                                ? []
                                : 'getArray' in raw
                                    ? raw.getArray()
                                    : raw;
                            var mvc = new google.maps.MVCArray();
                            mvc.getArray = jest.fn(function () { return ring; });
                            instance.getPath = jest.fn(function () { return mvc; });
                            return instance;
                        });
                        user = setUp(__assign(__assign({}, defaultProps), { onOverlayUpdated: onOverlayUpdated, enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                var m = getLastInstance(jest_mocks_1.Map);
                                if (!m) {
                                    throw new Error('Map not ready');
                                }
                                return m;
                            })];
                    case 1:
                        mapMock = _a.sent();
                        mapDiv = document.createElement('div');
                        mapMock.getDiv = jest.fn(function () { return mapDiv; });
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        clickHandler = getEventHandler(mapMock, 'click');
                        (0, react_2.act)(function () {
                            clickHandler(mapMouseEventWith(1, 2));
                            clickHandler(mapMouseEventWith(3, 4));
                            clickHandler(mapMouseEventWith(5, 6));
                        });
                        firstVertexMarker = getFirstInstance(jest_mocks_1.AdvancedMarkerElement);
                        expect(firstVertexMarker).toBeDefined();
                        (0, react_2.act)(function () {
                            getEventHandler(firstVertexMarker, 'click')(__assign(__assign({}, mapMouseEventWith(0, 0)), { stop: jest.fn() }));
                        });
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(onOverlayUpdated).toHaveBeenCalled();
                            })];
                    case 3:
                        _a.sent();
                        expect(onOverlayUpdated.mock.calls[0][0]).toEqual(expect.objectContaining({
                            type: constants_1.POLYGON_DRAWING_MODE,
                            data: [
                                [1, 2],
                                [3, 4],
                                [5, 6]
                            ]
                        }));
                        polygonPathSpy.mockRestore();
                        return [2 /*return*/];
                }
            });
        }); });
        it('clears the in-progress draw on map mouseleave so double-click does not complete a polygon', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onOverlayUpdated, user, mapMock, mapDiv, clickHandler;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onOverlayUpdated = jest.fn();
                        user = setUp(__assign(__assign({}, defaultProps), { onOverlayUpdated: onOverlayUpdated, enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        mapDiv = document.createElement('div');
                        mapMock.getDiv = jest.fn(function () { return mapDiv; });
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        clickHandler = getEventHandler(mapMock, 'click');
                        (0, react_2.act)(function () {
                            clickHandler(mapMouseEventWith(1, 2));
                            clickHandler(mapMouseEventWith(3, 4));
                            clickHandler(mapMouseEventWith(5, 6));
                        });
                        (0, react_2.act)(function () {
                            mapDiv.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));
                        });
                        (0, react_2.act)(function () {
                            mapDiv.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true, composed: true }));
                        });
                        expect(onOverlayUpdated).not.toHaveBeenCalled();
                        return [2 /*return*/];
                }
            });
        }); });
        it('ignores a second double-click after completion until draw mode is toggled', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onOverlayUpdated, OriginalPolygon, polygonPathSpy, user, mapMock, mapDiv, clickHandler;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onOverlayUpdated = jest.fn();
                        OriginalPolygon = google.maps.Polygon;
                        polygonPathSpy = jest.spyOn(google.maps, 'Polygon').mockImplementation(function (opts) {
                            var instance = new OriginalPolygon(opts);
                            var raw = opts === null || opts === void 0 ? void 0 : opts.paths;
                            var ring = !raw
                                ? []
                                : 'getArray' in raw
                                    ? raw.getArray()
                                    : raw;
                            var mvc = new google.maps.MVCArray();
                            mvc.getArray = jest.fn(function () { return ring; });
                            instance.getPath = jest.fn(function () { return mvc; });
                            return instance;
                        });
                        user = setUp(__assign(__assign({}, defaultProps), { onOverlayUpdated: onOverlayUpdated, enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        mapDiv = document.createElement('div');
                        mapMock.getDiv = jest.fn(function () { return mapDiv; });
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        clickHandler = getEventHandler(mapMock, 'click');
                        (0, react_2.act)(function () {
                            clickHandler(mapMouseEventWith(1, 2));
                            clickHandler(mapMouseEventWith(3, 4));
                            clickHandler(mapMouseEventWith(5, 6));
                        });
                        (0, react_2.act)(function () {
                            mapDiv.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true, composed: true }));
                        });
                        return [4 /*yield*/, (0, react_2.waitFor)(function () {
                                expect(onOverlayUpdated).toHaveBeenCalledTimes(1);
                            })];
                    case 3:
                        _a.sent();
                        onOverlayUpdated.mockClear();
                        (0, react_2.act)(function () {
                            mapDiv.dispatchEvent(new MouseEvent('dblclick', { bubbles: true, cancelable: true, composed: true }));
                        });
                        expect(onOverlayUpdated).not.toHaveBeenCalled();
                        polygonPathSpy.mockRestore();
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onOverlayUpdated on "Clear area" button correctly', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onOverlayUpdated, activeOverlay, user;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onOverlayUpdated = jest.fn();
                        activeOverlay = {
                            type: constants_1.POLYGON_DRAWING_MODE,
                            path: [
                                { lat: 1, lng: 1 },
                                { lat: 2, lng: 2 }
                            ]
                        };
                        user = setUp(__assign(__assign({}, defaultProps), { enablePolygonDrawing: true, activeOverlay: activeOverlay, onOverlayUpdated: onOverlayUpdated })).user;
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Clear area'))];
                    case 1:
                        _a.sent();
                        expect(onOverlayUpdated).toHaveBeenCalledWith(null);
                        return [2 /*return*/];
                }
            });
        }); });
    });
    describe('"Search when I move the map" behavior', function () {
        it('should call props.onMapBoundsChanged with current map bounds and reset drawingMode on change isSearchOnMapMove(true)', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onMapBoundsChanged, mapBoundsPolygon, user, mapMock;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onMapBoundsChanged = jest.fn();
                        mapBoundsPolygon = [
                            [1, 2],
                            [3, 4]
                        ];
                        user = setUp(__assign(__assign({}, defaultProps), { onMapBoundsChanged: onMapBoundsChanged, enablePolygonDrawing: true })).user;
                        jest.spyOn(helpers, 'getMapBoundsPolygon').mockImplementation(function () { return mapBoundsPolygon; });
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            draggableCursor: usePolygonDrawing_1.MAP_DRAWING_CROSSHAIR_CURSOR
                        }));
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            disableDoubleClickZoom: true,
                            clickableIcons: false
                        }));
                        return [4 /*yield*/, user.click(react_2.screen.getByText('Search as I move the map'))];
                    case 3:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({ disableDoubleClickZoom: false }));
                        expect(onMapBoundsChanged).toHaveBeenCalledWith(mapBoundsPolygon);
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onMapBoundsChanged with null on change isSearchOnMapMove(false)', function () { return __awaiter(void 0, void 0, void 0, function () {
            var onMapBoundsChanged, user, mapMock;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        onMapBoundsChanged = jest.fn();
                        user = setUp(__assign(__assign({}, defaultProps), { onMapBoundsChanged: onMapBoundsChanged, enablePolygonDrawing: true })).user;
                        return [4 /*yield*/, (0, react_2.waitFor)(function () { return getLastInstance(jest_mocks_1.Map); })];
                    case 1:
                        mapMock = _a.sent();
                        return [4 /*yield*/, user.click(react_2.screen.getByLabelText('Draw area'))];
                    case 2:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            draggableCursor: usePolygonDrawing_1.MAP_DRAWING_CROSSHAIR_CURSOR
                        }));
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({
                            disableDoubleClickZoom: true,
                            clickableIcons: false
                        }));
                        return [4 /*yield*/, user.click(react_2.screen.getByText('Search as I move the map'))];
                    case 3:
                        _a.sent();
                        return [4 /*yield*/, user.click(react_2.screen.getByText('Search as I move the map'))];
                    case 4:
                        _a.sent();
                        expect(mapMock.setOptions).toHaveBeenCalledWith(expect.objectContaining({ disableDoubleClickZoom: false }));
                        expect(onMapBoundsChanged).toHaveBeenCalledWith(null);
                        return [2 /*return*/];
                }
            });
        }); });
        it('should call props.onMapBoundsChanged on google map idle if "Search when I move the map" mode is on', function () {
            jest.useFakeTimers();
            var onMapBoundsChanged = jest.fn();
            var mapBoundsPolygon = [
                [1, 2],
                [3, 4]
            ];
            setUp(__assign(__assign({}, defaultProps), { onMapBoundsChanged: onMapBoundsChanged, enablePolygonDrawing: true, isSearchOnMapMove: true }));
            jest.spyOn(helpers, 'getMapBoundsPolygon').mockImplementation(function () { return mapBoundsPolygon; });
            expect(react_2.screen.getByLabelText('Search as I move the map').checked).toBe(true);
            expect(onMapBoundsChanged).not.toHaveBeenCalled();
            getEventHandler(getLastInstance(jest_mocks_1.Map), 'idle')();
            jest.runOnlyPendingTimers();
            expect(onMapBoundsChanged).toHaveBeenCalledWith(mapBoundsPolygon);
            expect(onMapBoundsChanged).toHaveBeenCalledTimes(1);
            jest.useRealTimers();
        });
        it('should call props.onMapBoundsChanged on google map idle only once after several map movement', function () {
            jest.useFakeTimers();
            var onMapBoundsChanged = jest.fn();
            var mapBoundsPolygon = [
                [1, 2],
                [3, 4]
            ];
            setUp(__assign(__assign({}, defaultProps), { onMapBoundsChanged: onMapBoundsChanged, enablePolygonDrawing: true, isSearchOnMapMove: true }));
            jest.spyOn(helpers, 'getMapBoundsPolygon').mockImplementation(function () { return mapBoundsPolygon; });
            expect(react_2.screen.getByLabelText('Search as I move the map').checked).toBe(true);
            var mapMock = getLastInstance(jest_mocks_1.Map);
            getEventHandler(mapMock, 'idle')();
            getEventHandler(mapMock, 'dragstart')();
            getEventHandler(mapMock, 'idle')();
            getEventHandler(mapMock, 'zoom_changed')();
            getEventHandler(mapMock, 'idle')();
            expect(onMapBoundsChanged).not.toHaveBeenCalled();
            jest.runOnlyPendingTimers();
            expect(onMapBoundsChanged).toHaveBeenCalledWith(mapBoundsPolygon);
            expect(onMapBoundsChanged).toHaveBeenCalledTimes(1);
            jest.useRealTimers();
        });
        it('should not call props.onMapBoundsChanged on google map idle if "Search when I move the map" mode is off', function () {
            jest.useFakeTimers();
            var onMapBoundsChanged = jest.fn();
            setUp(__assign(__assign({}, defaultProps), { onMapBoundsChanged: onMapBoundsChanged, enablePolygonDrawing: true, isSearchOnMapMove: false }));
            expect(react_2.screen.getByLabelText('Search as I move the map').checked).toBe(false);
            getEventHandler(getLastInstance(jest_mocks_1.Map), 'idle')();
            jest.runOnlyPendingTimers();
            expect(onMapBoundsChanged).not.toHaveBeenCalled();
            jest.useRealTimers();
        });
    });
});
