Skip to content

Commit 11670f5

Browse files
committed
Refactor validators to a separate file
1 parent 58f2e6f commit 11670f5

5 files changed

Lines changed: 128 additions & 130 deletions

File tree

src/serpapi.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@ import {
77
LocationsApiParameters,
88
} from "./types.d.ts";
99
import { EngineMap } from "./engines/index.d.ts";
10-
import {
11-
_internals,
12-
execute,
13-
validateApiKey,
14-
validateTimeout,
15-
} from "./utils.ts";
10+
import { _internals, execute } from "./utils.ts";
11+
import { validateApiKey, validateTimeout } from "./validators.ts";
1612

1713
const ACCOUNT_PATH = "/account";
1814
const LOCATIONS_PATH = "/locations.json";

src/utils.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
1-
import { config } from "./config.ts";
2-
import { InvalidTimeoutError, MissingApiKeyError } from "./errors.ts";
31
import { version } from "../version.ts";
42

53
type UrlParameters = Record<
64
string,
75
string | number | boolean | undefined | null
86
>;
97

10-
export function validateApiKey(value: string | undefined | null): string;
11-
export function validateApiKey(
12-
value: string | undefined | null,
13-
allowNull: boolean,
14-
): string | undefined;
15-
export function validateApiKey(
16-
value: string | undefined | null,
17-
allowNull = false,
18-
): string | undefined {
19-
// `api_key` can be null to support unmetered queries.
20-
if (allowNull && value === null) {
21-
return undefined;
22-
}
23-
const key = value ?? config.api_key;
24-
if (!key) throw new MissingApiKeyError();
25-
return key;
26-
}
27-
28-
export function validateTimeout(value: number | undefined): number {
29-
const timeout = value ?? config.timeout;
30-
if (timeout <= 0) throw new InvalidTimeoutError();
31-
return timeout;
32-
}
33-
348
/**
359
* This `_internals` object is needed to support stubbing/spying of
3610
* fetch, execute and getBaseUrl.

src/validators.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { config } from "./config.ts";
2+
import { InvalidTimeoutError, MissingApiKeyError } from "./errors.ts";
3+
4+
export function validateApiKey(value: string | undefined | null): string;
5+
export function validateApiKey(
6+
value: string | undefined | null,
7+
allowNull: boolean,
8+
): string | undefined;
9+
export function validateApiKey(
10+
value: string | undefined | null,
11+
allowNull = false,
12+
): string | undefined {
13+
// `api_key` can be null to support unmetered queries.
14+
if (allowNull && value === null) {
15+
return undefined;
16+
}
17+
const key = value ?? config.api_key;
18+
if (!key) throw new MissingApiKeyError();
19+
return key;
20+
}
21+
22+
export function validateTimeout(value: number | undefined): number {
23+
const timeout = value ?? config.timeout;
24+
if (timeout <= 0) throw new InvalidTimeoutError();
25+
return timeout;
26+
}

tests/utils_test.ts

Lines changed: 1 addition & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { loadSync } from "https://deno.land/std@0.170.0/dotenv/mod.ts";
22
import {
33
afterAll,
4-
afterEach,
54
beforeAll,
65
describe,
76
it,
@@ -16,110 +15,14 @@ import {
1615
assertEquals,
1716
assertMatch,
1817
assertRejects,
19-
assertThrows,
2018
} from "https://deno.land/std@0.170.0/testing/asserts.ts";
21-
import {
22-
_internals,
23-
buildUrl,
24-
execute,
25-
validateApiKey,
26-
validateTimeout,
27-
} from "../src/utils.ts";
28-
import { config } from "../src/config.ts";
29-
import { InvalidTimeoutError, MissingApiKeyError } from "../src/errors.ts";
19+
import { _internals, buildUrl, execute } from "../src/utils.ts";
3020

3121
loadSync({ export: true });
3222
const BASE_URL = Deno.env.get("ENV_TYPE") === "local"
3323
? "http://localhost:3000"
3424
: "https://serpapi.com";
3525

36-
describe("validateApiKey", () => {
37-
afterEach(() => {
38-
config.api_key = null;
39-
});
40-
41-
it("with no api_key in config", () => {
42-
assertThrows(() => validateApiKey(""), MissingApiKeyError);
43-
assertThrows(() => validateApiKey(undefined), MissingApiKeyError);
44-
assertThrows(() => validateApiKey(null), MissingApiKeyError);
45-
assertEquals(validateApiKey(" "), " ");
46-
assertEquals(validateApiKey("asd"), "asd");
47-
});
48-
49-
it("with api_key in config", () => {
50-
config.api_key = "api_key";
51-
assertThrows(() => validateApiKey(""), MissingApiKeyError);
52-
assertEquals(validateApiKey(undefined), "api_key");
53-
assertEquals(validateApiKey(null), "api_key");
54-
assertEquals(validateApiKey(" "), " ");
55-
assertEquals(validateApiKey("asd"), "asd");
56-
});
57-
58-
it("with empty api_key in config", () => {
59-
config.api_key = "";
60-
assertThrows(() => validateApiKey(""), MissingApiKeyError);
61-
assertThrows(() => validateApiKey(undefined), MissingApiKeyError);
62-
assertThrows(() => validateApiKey(null), MissingApiKeyError);
63-
assertEquals(validateApiKey("api_key_2"), "api_key_2");
64-
assertEquals(validateApiKey(" "), " ");
65-
assertEquals(validateApiKey("asd"), "asd");
66-
});
67-
68-
it("with no api_key in config and allowNull is true", () => {
69-
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
70-
assertThrows(() => validateApiKey(undefined, true), MissingApiKeyError);
71-
assertEquals(validateApiKey(null, true), undefined);
72-
assertEquals(validateApiKey(" ", true), " ");
73-
assertEquals(validateApiKey("asd", true), "asd");
74-
});
75-
76-
it("with api_key in config and allowNull is true", () => {
77-
config.api_key = "api_key";
78-
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
79-
assertEquals(validateApiKey(undefined, true), "api_key");
80-
assertEquals(validateApiKey(null, true), undefined);
81-
assertEquals(validateApiKey(" ", true), " ");
82-
assertEquals(validateApiKey("asd", true), "asd");
83-
});
84-
85-
it("with empty api_key in config and allowNull is true", () => {
86-
config.api_key = "";
87-
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
88-
assertThrows(() => validateApiKey(undefined, true), MissingApiKeyError);
89-
assertEquals(validateApiKey(null, true), undefined);
90-
assertEquals(validateApiKey(" ", true), " ");
91-
assertEquals(validateApiKey("asd", true), "asd");
92-
});
93-
});
94-
95-
describe("validateTimeout", () => {
96-
afterEach(() => {
97-
config.timeout = 60000;
98-
});
99-
100-
it("with invalid timeout", () => {
101-
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
102-
assertThrows(() => validateTimeout(-10), InvalidTimeoutError);
103-
});
104-
105-
it("with timeout set in config", () => {
106-
config.timeout = 10000;
107-
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
108-
assertEquals(validateTimeout(undefined), 10000);
109-
});
110-
111-
it("with invalid timeout set in config", () => {
112-
config.timeout = -1;
113-
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
114-
assertThrows(() => validateTimeout(undefined), InvalidTimeoutError);
115-
});
116-
117-
it("with valid timeout", () => {
118-
assertEquals(validateTimeout(1), 1);
119-
assertEquals(validateTimeout(10000), 10000);
120-
});
121-
});
122-
12326
describe("buildUrl", () => {
12427
let urlStub: Stub;
12528

tests/validators_test.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {
2+
afterEach,
3+
describe,
4+
it,
5+
} from "https://deno.land/std@0.170.0/testing/bdd.ts";
6+
import {
7+
assertEquals,
8+
assertThrows,
9+
} from "https://deno.land/std@0.170.0/testing/asserts.ts";
10+
import { validateApiKey, validateTimeout } from "../src/validators.ts";
11+
import { config } from "../src/config.ts";
12+
import { InvalidTimeoutError, MissingApiKeyError } from "../src/errors.ts";
13+
14+
describe("validateApiKey", () => {
15+
afterEach(() => {
16+
config.api_key = null;
17+
});
18+
19+
it("with no api_key in config", () => {
20+
assertThrows(() => validateApiKey(""), MissingApiKeyError);
21+
assertThrows(() => validateApiKey(undefined), MissingApiKeyError);
22+
assertThrows(() => validateApiKey(null), MissingApiKeyError);
23+
assertEquals(validateApiKey(" "), " ");
24+
assertEquals(validateApiKey("asd"), "asd");
25+
});
26+
27+
it("with api_key in config", () => {
28+
config.api_key = "api_key";
29+
assertThrows(() => validateApiKey(""), MissingApiKeyError);
30+
assertEquals(validateApiKey(undefined), "api_key");
31+
assertEquals(validateApiKey(null), "api_key");
32+
assertEquals(validateApiKey(" "), " ");
33+
assertEquals(validateApiKey("asd"), "asd");
34+
});
35+
36+
it("with empty api_key in config", () => {
37+
config.api_key = "";
38+
assertThrows(() => validateApiKey(""), MissingApiKeyError);
39+
assertThrows(() => validateApiKey(undefined), MissingApiKeyError);
40+
assertThrows(() => validateApiKey(null), MissingApiKeyError);
41+
assertEquals(validateApiKey("api_key_2"), "api_key_2");
42+
assertEquals(validateApiKey(" "), " ");
43+
assertEquals(validateApiKey("asd"), "asd");
44+
});
45+
46+
it("with no api_key in config and allowNull is true", () => {
47+
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
48+
assertThrows(() => validateApiKey(undefined, true), MissingApiKeyError);
49+
assertEquals(validateApiKey(null, true), undefined);
50+
assertEquals(validateApiKey(" ", true), " ");
51+
assertEquals(validateApiKey("asd", true), "asd");
52+
});
53+
54+
it("with api_key in config and allowNull is true", () => {
55+
config.api_key = "api_key";
56+
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
57+
assertEquals(validateApiKey(undefined, true), "api_key");
58+
assertEquals(validateApiKey(null, true), undefined);
59+
assertEquals(validateApiKey(" ", true), " ");
60+
assertEquals(validateApiKey("asd", true), "asd");
61+
});
62+
63+
it("with empty api_key in config and allowNull is true", () => {
64+
config.api_key = "";
65+
assertThrows(() => validateApiKey("", true), MissingApiKeyError);
66+
assertThrows(() => validateApiKey(undefined, true), MissingApiKeyError);
67+
assertEquals(validateApiKey(null, true), undefined);
68+
assertEquals(validateApiKey(" ", true), " ");
69+
assertEquals(validateApiKey("asd", true), "asd");
70+
});
71+
});
72+
73+
describe("validateTimeout", () => {
74+
afterEach(() => {
75+
config.timeout = 60000;
76+
});
77+
78+
it("with invalid timeout", () => {
79+
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
80+
assertThrows(() => validateTimeout(-10), InvalidTimeoutError);
81+
});
82+
83+
it("with timeout set in config", () => {
84+
config.timeout = 10000;
85+
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
86+
assertEquals(validateTimeout(undefined), 10000);
87+
});
88+
89+
it("with invalid timeout set in config", () => {
90+
config.timeout = -1;
91+
assertThrows(() => validateTimeout(0), InvalidTimeoutError);
92+
assertThrows(() => validateTimeout(undefined), InvalidTimeoutError);
93+
});
94+
95+
it("with valid timeout", () => {
96+
assertEquals(validateTimeout(1), 1);
97+
assertEquals(validateTimeout(10000), 10000);
98+
});
99+
});

0 commit comments

Comments
 (0)