| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| describe("geolocation", function () { |
| var geo = require('cordova/plugin/geolocation'), |
| Position = require('cordova/plugin/Position'), |
| PositionError = require('cordova/plugin/PositionError'), |
| s, e, |
| exec = require('cordova/exec'); |
| |
| beforeEach(function () { |
| s = jasmine.createSpy("success"); |
| e = jasmine.createSpy("error"); |
| exec.reset(); |
| geo.lastPosition = null; // reset the cached position |
| }); |
| |
| describe("getCurrentPosition", function() { |
| describe("and passed-in arguments", function () { |
| it("uses default PositionOptions if none are specified", function () { |
| geo.getCurrentPosition(s, e); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 0]); |
| }); |
| |
| it("uses the enableHighAccuracy option if specified", function () { |
| geo.getCurrentPosition(s, e, {enableHighAccuracy: true}); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [true, 0]); |
| }); |
| |
| it("uses the maximumAge option if specified", function () { |
| geo.getCurrentPosition(s, e, {maximumAge: 100}); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 100]); |
| }); |
| |
| it("uses a timeout value of 0 if specified and negative, which should call the error callback immediately (since we have no cached position)", function () { |
| geo.getCurrentPosition(s, e, {timeout: -1000}); |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter." |
| }); |
| }); |
| |
| it("can be used with one, two or three arguments", function() { |
| expect(function() { geo.getCurrentPosition(s); }).not.toThrow(); |
| expect(function() { geo.getCurrentPosition(s,e); }).not.toThrow(); |
| expect(function() { geo.getCurrentPosition(s,e,{}); }).not.toThrow(); |
| }); |
| |
| it("should throw an exception if used with no arguments", function() { |
| expect(function() { geo.getCurrentPosition();}).toThrow(); |
| }); |
| }); |
| describe("position acquisition", function() { |
| it("should provide a cached position if one exists and has a timestamp value conforming with passed in maximumAge", function() { |
| // Create a date object from 2 seconds ago to store as cached position. |
| var d = new Date(); |
| d.setTime(d.getTime() - 2000); |
| var p = new Position(null, d); |
| geo.lastPosition = p; |
| |
| geo.getCurrentPosition(s, e, {maximumAge:3000}); |
| |
| expect(s).toHaveBeenCalledWith(p); |
| expect(exec).not.toHaveBeenCalled(); |
| }); |
| |
| it("should fire exec if a cached position exists but whose timestamp is longer than the maximumAge parameter", function() { |
| // Create a date object from 2 seconds ago to store as cached position. |
| var d = new Date(); |
| d.setTime(d.getTime() - 2000); |
| var p = new Position(null, d); |
| geo.lastPosition = p; |
| |
| geo.getCurrentPosition(s, e, {maximumAge:100}); |
| |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 100]); |
| }); |
| |
| it("should fire error callback with TIMEOUT code after timeout period has elapsed and no position is available", function() { |
| runs(function() { |
| geo.getCurrentPosition(s, e, {timeout: 50}); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "getLocation", [false, 0]); |
| }); |
| |
| waitsFor(function() { return e.wasCalled; }, 200); |
| |
| runs(function() { |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"Position retrieval timed out." |
| }); |
| }); |
| }); |
| |
| it("should not fire error callback with TIMEOUT if a position is obtained within the timeout period", function() { |
| runs(function() { |
| geo.getCurrentPosition(s, e, {timeout:50}); |
| |
| // Call the success callback to "fake" the native framework returning a (empty) position object. |
| // This should also disable the timeout timer. |
| exec.mostRecentCall.args[0]({}); |
| }); |
| |
| waitsFor(function() { return e.wasCalled || s.wasCalled; }, 200); |
| |
| runs(function() { |
| expect(e).not.toHaveBeenCalled(); |
| expect(s).toHaveBeenCalled(); |
| }); |
| }); |
| |
| it("should fire error callback with POSITION_UNAVAILABLE if error occurs during acquisition before timeout expires", function() { |
| geo.getCurrentPosition(s, e, {timeout: 50}); |
| |
| // Call the error callback to "fake" the native framework returning an error object. |
| var eObj = { |
| code:PositionError.POSITION_UNAVAILABLE |
| }; |
| exec.mostRecentCall.args[1](eObj); |
| |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.POSITION_UNAVAILABLE, |
| message:"" |
| }); |
| }); |
| |
| it("should not fire error callback with TIMEOUT if error occurs during acquisition before timeout expires", function() { |
| runs(function() { |
| geo.getCurrentPosition(s, e, {timeout: 50}); |
| |
| // Call the error callback to "fake" the native framework returning an error object. |
| var eObj = { |
| code:PositionError.POSITION_UNAVAILABLE |
| }; |
| exec.mostRecentCall.args[1](eObj); |
| }); |
| |
| waitsFor(function() { return e.wasCalled; }, 200); |
| |
| runs(function() { |
| expect(e).not.toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"Position retrieval timed out." |
| }); |
| }); |
| }); |
| }); |
| }); |
| |
| describe("watchPosition", function () { |
| describe("arguments", function () { |
| it("uses default PositionOptions if none are specified", function () { |
| var id = geo.watchPosition(s, e); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, false]); |
| }); |
| |
| it("uses the enableHighAccuracy option if specified", function () { |
| var id = geo.watchPosition(s, e, {enableHighAccuracy: true}); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, true]); |
| }); |
| |
| it("uses the maximumAge option if specified", function () { |
| var id = geo.watchPosition(s, e, {maximumAge: 100}); |
| expect(exec).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), "Geolocation", "addWatch", [id, false]); |
| }); |
| |
| it("uses a timeout value of 0 if specified and negative, which should call the error callback immediately", function () { |
| geo.watchPosition(s, e, {timeout: -1000}); |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter." |
| }); |
| }); |
| |
| it("can be used with one, two or three arguments", function() { |
| expect(function() { geo.watchPosition(s); }).not.toThrow(); |
| expect(function() { geo.watchPosition(s,e); }).not.toThrow(); |
| expect(function() { geo.watchPosition(s,e,{}); }).not.toThrow(); |
| }); |
| |
| it("should throw an exception if used with no arguments", function() { |
| expect(function() { geo.watchPosition();}).toThrow(); |
| }); |
| }); |
| describe("position acquisition", function() { |
| it("should invoke the success callback every time the position changes", function() { |
| runs(function() { |
| geo.watchPosition(s, e); |
| }); |
| waits(1); |
| runs(function() { |
| exec.mostRecentCall.args[0]({}); // fake success callback from native |
| expect(s).toHaveBeenCalled(); |
| s.reset(); |
| exec.mostRecentCall.args[0]({}); // fake success callback from native |
| expect(s).toHaveBeenCalled(); |
| }); |
| }); |
| it("should invoke the error callback if position could not be retrieved", function() { |
| geo.watchPosition(s, e); |
| exec.mostRecentCall.args[1]({ |
| code:PositionError.POSITION_UNAVAILABLE |
| }); |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.POSITION_UNAVAILABLE, |
| message:"" |
| }); |
| }); |
| it("should invoke the error callback if no position could be acquired within the specified timeout", function() { |
| runs(function() { |
| geo.watchPosition(s, e, {timeout:50}); |
| }); |
| waitsFor(function() { return e.wasCalled; }, 200); |
| runs(function() { |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"Position retrieval timed out." |
| }); |
| }); |
| }); |
| it("should invoke the error callback if no position could be acquired within the specified timeout, even after successfully retrieving the position once", function() { |
| runs(function() { |
| geo.watchPosition(s, e, {timeout:50}); |
| }); |
| waits(1); |
| runs(function() { |
| exec.mostRecentCall.args[0]({}); // fire new position return |
| expect(s).toHaveBeenCalled(); |
| }); |
| waits(1); |
| runs(function() { |
| // The error callback should NOT be fired, since the timeout should have reset when we fired a new position return above |
| expect(e).not.toHaveBeenCalled(); |
| }); |
| waitsFor(function() { return e.wasCalled; }, 200); |
| runs(function() { |
| // NOW the error callback should be fired with a TIMEOUT error |
| expect(e).toHaveBeenCalledWith({ |
| code:PositionError.TIMEOUT, |
| message:"Position retrieval timed out." |
| }); |
| }); |
| }); |
| }); |
| }); |
| |
| describe("clearWatch", function () { |
| it("should tell native to remove an id from the watch list if it exists", function() { |
| var id = geo.watchPosition(s, e); |
| exec.reset(); |
| geo.clearWatch(id); |
| expect(exec).toHaveBeenCalledWith(null, null, "Geolocation", "clearWatch", [id]); |
| }); |
| it("should not call into native if id does not exist", function() { |
| var id = "this is bat country"; |
| geo.clearWatch(id); |
| expect(exec).not.toHaveBeenCalled(); |
| }); |
| it("watchPosition followed by clearWatch should not invoke any success callbacks", function() { |
| // watchPosition calls native getLocation then addWatch method in order. |
| var id = geo.watchPosition(s, e); |
| // Get ref to getLocation success callback, to fake the native interaction. |
| var getLocationWin = exec.argsForCall[0][0]; |
| |
| // Next clear the watch id, but call the get location success callback as if the native framework has fired it after a clear watch. |
| geo.clearWatch(id); |
| getLocationWin({}); |
| |
| // End result: expect the success callback not to have been called. |
| expect(s).not.toHaveBeenCalled(); |
| }); |
| }); |
| }); |