fix(geolocation): improve geolocation validation (#471)
This commit is contained in:
parent
88a11a3fbd
commit
a88d30140c
|
|
@ -18,6 +18,7 @@
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import * as network from './network';
|
import * as network from './network';
|
||||||
import * as types from './types';
|
import * as types from './types';
|
||||||
|
import { helper } from './helper';
|
||||||
|
|
||||||
export interface BrowserContextDelegate {
|
export interface BrowserContextDelegate {
|
||||||
pages(): Promise<Page[]>;
|
pages(): Promise<Page[]>;
|
||||||
|
|
@ -58,7 +59,7 @@ export class BrowserContext {
|
||||||
if (this._options.viewport)
|
if (this._options.viewport)
|
||||||
this._options.viewport = { ...this._options.viewport };
|
this._options.viewport = { ...this._options.viewport };
|
||||||
if (this._options.geolocation)
|
if (this._options.geolocation)
|
||||||
this._options.geolocation = { ...this._options.geolocation };
|
this._options.geolocation = verifyGeolocation(this._options.geolocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize() {
|
async _initialize() {
|
||||||
|
|
@ -100,16 +101,8 @@ export class BrowserContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setGeolocation(geolocation: types.Geolocation | null): Promise<void> {
|
async setGeolocation(geolocation: types.Geolocation | null): Promise<void> {
|
||||||
if (geolocation) {
|
if (geolocation)
|
||||||
geolocation.accuracy = geolocation.accuracy || 0;
|
geolocation = verifyGeolocation(geolocation);
|
||||||
const { longitude, latitude, accuracy } = geolocation;
|
|
||||||
if (longitude !== undefined && (longitude < -180 || longitude > 180))
|
|
||||||
throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`);
|
|
||||||
if (latitude !== undefined && (latitude < -90 || latitude > 90))
|
|
||||||
throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`);
|
|
||||||
if (accuracy < 0)
|
|
||||||
throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`);
|
|
||||||
}
|
|
||||||
this._options.geolocation = geolocation || undefined;
|
this._options.geolocation = geolocation || undefined;
|
||||||
await this._delegate.setGeolocation(geolocation);
|
await this._delegate.setGeolocation(geolocation);
|
||||||
}
|
}
|
||||||
|
|
@ -121,3 +114,16 @@ export class BrowserContext {
|
||||||
this._closed = true;
|
this._closed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function verifyGeolocation(geolocation: types.Geolocation): types.Geolocation {
|
||||||
|
const result = { ...geolocation };
|
||||||
|
result.accuracy = result.accuracy || 0;
|
||||||
|
const { longitude, latitude, accuracy } = result;
|
||||||
|
if (!helper.isNumber(longitude) || longitude < -180 || longitude > 180)
|
||||||
|
throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`);
|
||||||
|
if (!helper.isNumber(latitude) || latitude < -90 || latitude > 90)
|
||||||
|
throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`);
|
||||||
|
if (!helper.isNumber(accuracy) || accuracy < 0)
|
||||||
|
throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,9 @@ export type Credentials = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Geolocation = {
|
export type Geolocation = {
|
||||||
longitude?: number;
|
longitude: number;
|
||||||
latitude?: number;
|
latitude: number;
|
||||||
accuracy?: number | undefined;
|
accuracy?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SelectOption = {
|
export type SelectOption = {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,15 @@ module.exports.describe = function ({ testRunner, expect, FFOX, WEBKIT }) {
|
||||||
}
|
}
|
||||||
expect(error.message).toContain('Invalid longitude "200"');
|
expect(error.message).toContain('Invalid longitude "200"');
|
||||||
});
|
});
|
||||||
|
it('should throw with missing latitude', async({context}) => {
|
||||||
|
let error = null;
|
||||||
|
try {
|
||||||
|
await context.setGeolocation({longitude: 10});
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Invalid latitude "undefined"');
|
||||||
|
});
|
||||||
it('should not modify passed default options object', async({newContext}) => {
|
it('should not modify passed default options object', async({newContext}) => {
|
||||||
const geolocation = { longitude: 10, latitude: 10 };
|
const geolocation = { longitude: 10, latitude: 10 };
|
||||||
const options = { geolocation };
|
const options = { geolocation };
|
||||||
|
|
@ -49,6 +58,16 @@ module.exports.describe = function ({ testRunner, expect, FFOX, WEBKIT }) {
|
||||||
await context.setGeolocation({ longitude: 20, latitude: 20 });
|
await context.setGeolocation({ longitude: 20, latitude: 20 });
|
||||||
expect(options.geolocation).toBe(geolocation);
|
expect(options.geolocation).toBe(geolocation);
|
||||||
});
|
});
|
||||||
|
it('should throw with missing longitude in default options', async({newContext}) => {
|
||||||
|
let error = null;
|
||||||
|
try {
|
||||||
|
const context = await newContext({ geolocation: {latitude: 10} });
|
||||||
|
await context.close();
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Invalid longitude "undefined"');
|
||||||
|
});
|
||||||
it('should use context options', async({newContext, server}) => {
|
it('should use context options', async({newContext, server}) => {
|
||||||
const options = { geolocation: { longitude: 10, latitude: 10 }, permissions: {} };
|
const options = { geolocation: { longitude: 10, latitude: 10 }, permissions: {} };
|
||||||
options.permissions[server.PREFIX] = ['geolocation'];
|
options.permissions[server.PREFIX] = ['geolocation'];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue