Skip to content

Commit c2cfef7

Browse files
committed
feat(Resolve): Resolve address suggestions
Retrieve GBR formatted fully resolved addresses
1 parent 06ce31d commit c2cfef7

File tree

2 files changed

+144
-4
lines changed

2 files changed

+144
-4
lines changed

lib/resources/autocomplete.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { listMethod } from "./resource";
2-
import { AddressSuggestionResponse } from "@ideal-postcodes/api-typings";
1+
import { listMethod, retrieveMethod } from "./resource";
2+
import { AddressSuggestionResponse, GbrResolveResponse } from "../types";
33
import { OptionalStringMap } from "../util";
44
import { Client } from "../client";
55
import { HttpResponse } from "../agent";
@@ -64,3 +64,19 @@ export interface List {
6464

6565
export const list: List = (client, request) =>
6666
listMethod<Request, AddressSuggestionResponse>({ resource, client })(request);
67+
68+
export interface GbrResponse extends HttpResponse {
69+
body: GbrResolveResponse;
70+
}
71+
72+
export interface Gbr {
73+
(client: Client, id: string, request: Request): Promise<GbrResponse>;
74+
}
75+
76+
// Resolves address to the GBR format
77+
export const gbr: Gbr = (client, id, request) =>
78+
retrieveMethod<Request, GbrResolveResponse>({
79+
resource,
80+
client,
81+
action: "gbr",
82+
})(id, request);

test/autocomplete.resource.ts

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as sinon from "sinon";
22
import { IdpcRequestFailedError, IdpcBalanceDepletedError } from "../lib/error";
33
import { errors, autocomplete } from "@ideal-postcodes/api-fixtures";
4-
import { list } from "../lib/resources/autocomplete";
4+
import { list, gbr } from "../lib/resources/autocomplete";
55
import { HttpVerb } from "../lib/agent";
66
import { Client, defaults } from "../lib/index";
77
import { assert } from "chai";
88
import { newConfig, toResponse } from "./helper/index";
99

10-
describe("AutocompleteResource", () => {
10+
describe("AutocompleteResource: List", () => {
1111
afterEach(() => sinon.restore());
1212

1313
const api_key = "foo";
@@ -42,6 +42,7 @@ describe("AutocompleteResource", () => {
4242
.resolves(toResponse(autocomplete.success, expectedRequest));
4343

4444
list(client, { query }).then((response) => {
45+
//@ts-ignore
4546
assert.deepEqual(response.body, autocomplete.success.body);
4647
done();
4748
});
@@ -74,3 +75,126 @@ describe("AutocompleteResource", () => {
7475
});
7576
});
7677
});
78+
79+
describe("AutocompleteResource: Resolve", () => {
80+
const fixture = {
81+
description: "UDPRN address retrieval",
82+
url: "/v1/udprn/23747208",
83+
query: {
84+
api_key: "<VALID_API_KEY>",
85+
},
86+
headers: {},
87+
httpStatus: 200,
88+
body: {
89+
result: {
90+
postcode: "SW1A 0AA",
91+
postcode_inward: "0AA",
92+
postcode_outward: "SW1A",
93+
post_town: "LONDON",
94+
dependant_locality: "",
95+
double_dependant_locality: "",
96+
thoroughfare: "",
97+
dependant_thoroughfare: "",
98+
building_number: "",
99+
building_name: "Houses Of Parliament",
100+
sub_building_name: "",
101+
po_box: "",
102+
department_name: "",
103+
organisation_name: "House Of Commons",
104+
udprn: 23747208,
105+
umprn: "",
106+
postcode_type: "L",
107+
su_organisation_indicator: "",
108+
delivery_point_suffix: "1A",
109+
line_1: "House Of Commons",
110+
line_2: "Houses Of Parliament",
111+
line_3: "",
112+
premise: "Houses Of Parliament",
113+
longitude: -0.1246375,
114+
latitude: 51.4998415,
115+
eastings: 530268,
116+
northings: 179545,
117+
country: "England",
118+
traditional_county: "Greater London",
119+
administrative_county: "",
120+
postal_county: "London",
121+
county: "London",
122+
district: "Westminster",
123+
ward: "St James's",
124+
uprn: "10033540874",
125+
dataset: "paf",
126+
id: "paf_23747208",
127+
country_iso: "GBR",
128+
},
129+
code: 2000,
130+
message: "Success",
131+
},
132+
};
133+
134+
afterEach(() => sinon.restore());
135+
136+
const api_key = "foo";
137+
const id = "paf_123456";
138+
const query = { api_key };
139+
const client = new Client(newConfig());
140+
const expectedRequest = {
141+
method: "GET" as HttpVerb,
142+
header: defaults.header,
143+
query,
144+
timeout: client.config.timeout,
145+
url: `https://api.ideal-postcodes.co.uk/v1/autocomplete/addresses/${id}/gbr`,
146+
};
147+
148+
describe("contract", () => {
149+
it("generates API request on agent", (done) => {
150+
const stub = sinon
151+
.stub(client.config.agent, "http")
152+
.resolves(toResponse(fixture, expectedRequest));
153+
154+
gbr(client, id, { query }).then(() => {
155+
sinon.assert.calledOnce(stub);
156+
sinon.assert.calledWithExactly(stub, expectedRequest);
157+
done();
158+
});
159+
});
160+
});
161+
162+
it("returns resolved address", (done) => {
163+
sinon
164+
.stub(client.config.agent, "http")
165+
.resolves(toResponse(fixture, expectedRequest));
166+
167+
gbr(client, id, { query }).then((response) => {
168+
//@ts-ignore
169+
assert.deepEqual(response.body, fixture.body);
170+
done();
171+
});
172+
});
173+
174+
it("returns non API errors (e.g. connection error)", (done) => {
175+
sinon.stub(client.config.agent, "http").rejects(new Error("timeout!"));
176+
177+
gbr(client, id, { query })
178+
.then(() => {
179+
done(new Error("Promise should be rejected"));
180+
})
181+
.catch((error) => {
182+
assert.instanceOf(error, Error);
183+
done();
184+
});
185+
});
186+
187+
it("returns API errors", (done) => {
188+
sinon
189+
.stub(client.config.agent, "http")
190+
.resolves(toResponse(errors.balanceDepleted, expectedRequest));
191+
192+
gbr(client, id, { query })
193+
.then(() => done(new Error("Promise should be rejected")))
194+
.catch((error) => {
195+
assert.instanceOf(error, IdpcBalanceDepletedError);
196+
assert.isTrue(error instanceof IdpcRequestFailedError);
197+
done();
198+
});
199+
});
200+
});

0 commit comments

Comments
 (0)