import { Cartesian3 } from "../../../Source/Cesium.js"; import { Rectangle } from "../../../Source/Cesium.js"; import createScene from "../../createScene.js"; import pollToPromise from "../../pollToPromise.js"; import { when } from "../../../Source/Cesium.js"; import { GeocoderViewModel } from "../../../Source/Cesium.js"; describe( "Widgets/Geocoder/GeocoderViewModel", function () { var scene; var mockDestination = new Cartesian3(1.0, 2.0, 3.0); var geocoderResults1 = [ { displayName: "a", destination: mockDestination, }, { displayName: "b", destination: mockDestination, }, { displayName: "c", destination: mockDestination, }, ]; var customGeocoderOptions = { autoComplete: true, geocode: function (input) { return when.resolve(geocoderResults1); }, }; var geocoderResults2 = [ { displayName: "1", destination: mockDestination, }, { displayName: "2", destination: mockDestination, }, ]; var customGeocoderOptions2 = { autoComplete: true, geocode: function (input) { return when.resolve(geocoderResults2); }, }; var noResultsGeocoder = { autoComplete: true, geocode: function (input) { return when.resolve([]); }, }; beforeAll(function () { scene = createScene(); }); afterAll(function () { scene.destroyForSpecs(); }); it("constructor sets expected properties", function () { var flightDuration = 1234; var viewModel = new GeocoderViewModel({ scene: scene, flightDuration: flightDuration, }); expect(viewModel.scene).toBe(scene); expect(viewModel.flightDuration).toBe(flightDuration); expect(viewModel.keepExpanded).toBe(false); }); it("can get and set flight duration", function () { var viewModel = new GeocoderViewModel({ scene: scene, }); viewModel.flightDuration = 324; expect(viewModel.flightDuration).toEqual(324); expect(function () { viewModel.flightDuration = -123; }).toThrowDeveloperError(); }); it("throws is searchText is not a string", function () { var viewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); expect(function () { viewModel.searchText = undefined; }).toThrowDeveloperError(); }); it("moves camera when search command invoked", function () { var viewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); var cameraPosition = Cartesian3.clone(scene.camera.position); viewModel.searchText = "220 Valley Creek Blvd, Exton, PA"; viewModel.search(); return pollToPromise(function () { scene.tweens.update(); return !Cartesian3.equals(cameraPosition, scene.camera.position); }); }); it("constructor throws without scene", function () { expect(function () { return new GeocoderViewModel(); }).toThrowDeveloperError(); }); it("raises the complete event camera finished", function () { var viewModel = new GeocoderViewModel({ scene: scene, flightDuration: 0, geocoderServices: [customGeocoderOptions], }); var spyListener = jasmine.createSpy("listener"); viewModel.complete.addEventListener(spyListener); viewModel.searchText = "-1.0, -2.0"; viewModel.search(); expect(spyListener.calls.count()).toBe(1); viewModel.flightDuration = 1.5; viewModel.searchText = "2.0, 2.0"; viewModel.search(); return pollToPromise(function () { scene.tweens.update(); return spyListener.calls.count() === 2; }); }); it("can be created with a custom geocoder", function () { expect(function () { return new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); }).not.toThrowDeveloperError(); }); it("automatic suggestions can be retrieved", function () { var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); geocoder._searchText = "some_text"; GeocoderViewModel._updateSearchSuggestions(geocoder); expect(geocoder._suggestions.length).toEqual(3); }); it("update search suggestions results in empty list if the query is empty", function () { var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); geocoder._searchText = ""; GeocoderViewModel._updateSearchSuggestions(geocoder); expect(geocoder._suggestions.length).toEqual(0); }); it("can activate selected search suggestion", function () { spyOn(GeocoderViewModel, "flyToDestination"); var destination = new Rectangle(0.0, -0.1, 0.1, 0.1); var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); var suggestion = { displayName: "a", destination: destination }; geocoder._selectedSuggestion = suggestion; geocoder.activateSuggestion(suggestion); expect(geocoder._searchText).toEqual("a"); expect(GeocoderViewModel.flyToDestination).toHaveBeenCalledWith( geocoder, destination ); }); it("if more than one geocoder service is provided, use first result from first geocode in array order", function () { spyOn(GeocoderViewModel, "flyToDestination"); var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [noResultsGeocoder, customGeocoderOptions2], }); geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding geocoder.search(); expect(geocoder._searchText).toEqual(geocoderResults2[0].displayName); expect(GeocoderViewModel.flyToDestination).toHaveBeenCalledWith( geocoder, mockDestination ); }); it("can update autoComplete suggestions list using multiple geocoders", function () { var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions, customGeocoderOptions2], }); geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding GeocoderViewModel._updateSearchSuggestions(geocoder); expect(geocoder._suggestions.length).toEqual( geocoderResults1.length + geocoderResults2.length ); }); it("uses custom destination found callback", function () { spyOn(GeocoderViewModel, "flyToDestination"); var destinationFound = jasmine.createSpy(); var geocoder = new GeocoderViewModel({ scene: scene, geocoderServices: [noResultsGeocoder, customGeocoderOptions2], destinationFound: destinationFound, }); geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding geocoder.search(); expect(geocoder._searchText).toEqual(geocoderResults2[0].displayName); expect(GeocoderViewModel.flyToDestination).not.toHaveBeenCalled(); expect(destinationFound).toHaveBeenCalledWith(geocoder, mockDestination); }); it("automatic suggestions can be navigated by arrow up/down keys", function () { spyOn(GeocoderViewModel, "_adjustSuggestionsScroll"); var viewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); viewModel._searchText = "some_text"; GeocoderViewModel._updateSearchSuggestions(viewModel); expect(viewModel._selectedSuggestion).toEqual(undefined); viewModel._handleArrowDown(viewModel); expect(viewModel._selectedSuggestion.displayName).toEqual("a"); viewModel._handleArrowDown(viewModel); viewModel._handleArrowDown(viewModel); expect(viewModel._selectedSuggestion.displayName).toEqual("c"); viewModel._handleArrowDown(viewModel); expect(viewModel._selectedSuggestion.displayName).toEqual("a"); viewModel._handleArrowDown(viewModel); viewModel._handleArrowUp(viewModel); expect(viewModel._selectedSuggestion.displayName).toEqual("a"); viewModel._handleArrowUp(viewModel); expect(viewModel._selectedSuggestion).toBeUndefined(); }); }, "WebGL" );