Skip to content

Commit a12c32e

Browse files
authored
Merge pull request #203 from companieshouse/BI-8655-add-enhanced-search-api-endpoint-to-sdk
add enhanced search api call
2 parents f2a4458 + 843acbc commit a12c32e

File tree

7 files changed

+245
-1
lines changed

7 files changed

+245
-1
lines changed

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"camelcase-keys": "~6.2.2",
2121
"request": "~2.88.2",
2222
"request-promise-native": "~1.0.9",
23-
"snakecase-keys": "~3.2.0"
23+
"snakecase-keys": "~3.2.0",
24+
"url-search-params-polyfill": "~8.1.1"
2425
},
2526
"devDependencies": {
2627
"@types/chai": "~4.2.14",

src/client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import CompanyFilingHistoryService from "./services/company-filing-history/servi
99
import { RefreshTokenService } from "./services/refresh-token";
1010
import AlphabeticalSearchService from "./services/search/alphabetical-search/service";
1111
import DissolvedSearchService from "./services/search/dissolved-search/service";
12+
import EnhancedSearchService from "./services/search/enhanced-search/service";
1213
import PSCDiscrepancyService from "./services/psc-discrepancies/service";
1314
import PSCDiscrepanciesReportService from "./services/psc-discrepancies-report/service";
1415
import TransactionService from "./services/transaction/service";
@@ -31,6 +32,7 @@ export default class ApiClient {
3132
public readonly refreshToken: RefreshTokenService;
3233
public readonly alphabeticalSearch: AlphabeticalSearchService;
3334
public readonly dissolvedSearch: DissolvedSearchService;
35+
public readonly enhancedSearch: EnhancedSearchService;
3436
public readonly pscDiscrepancies: PSCDiscrepancyService;
3537
public readonly pscDiscrepancyReport: PSCDiscrepanciesReportService;
3638
public readonly transaction: TransactionService;
@@ -50,6 +52,7 @@ export default class ApiClient {
5052
this.mid = new MidService(apiClient);
5153
this.alphabeticalSearch = new AlphabeticalSearchService(apiClient);
5254
this.dissolvedSearch = new DissolvedSearchService(apiClient);
55+
this.enhancedSearch = new EnhancedSearchService(apiClient);
5356
// service on the account/identity domain using the accountClient
5457
// e.g. user profile service can be added here when required
5558
this.refreshToken = new RefreshTokenService(accountClient);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as EnhancedSearchService } from "./service";
2+
export * from "./types";
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { IHttpClient } from "../../../http";
2+
import { CompaniesResource } from "./types";
3+
import Resource from "../../resource";
4+
import "url-search-params-polyfill";
5+
6+
export default class EnhancedSearchService {
7+
constructor (private readonly client: IHttpClient) { }
8+
public async getCompanies (companyName: string | null, location: string | null, incorporatedFrom: string | null,
9+
incorporatedTo: string | null, requestId: string): Promise<Resource<CompaniesResource>> {
10+
const COMPANY_NAME_QUERY = "company_name";
11+
const LOCATION_QUERY = "location";
12+
const INCORPORATED_FROM_QUERY = "incorporated_from";
13+
const INCORPORATED_TO_QUERY = "incorporated_to";
14+
const additionalHeaders = {
15+
"X-Request-ID": requestId,
16+
"Content-Type": "application/json"
17+
}
18+
const buildEnhancedSearchURL = new URLSearchParams("/enhanced-search/companies?");
19+
20+
if (companyName !== null) {
21+
buildEnhancedSearchURL.append(COMPANY_NAME_QUERY, companyName)
22+
}
23+
24+
if (location !== null) {
25+
buildEnhancedSearchURL.append(LOCATION_QUERY, location)
26+
}
27+
28+
if (incorporatedFrom !== null) {
29+
buildEnhancedSearchURL.append(INCORPORATED_FROM_QUERY, incorporatedFrom)
30+
}
31+
32+
if (incorporatedTo !== null) {
33+
buildEnhancedSearchURL.append(INCORPORATED_TO_QUERY, incorporatedTo)
34+
}
35+
36+
const enhancedSearchUrl = buildEnhancedSearchURL.toString();
37+
38+
const resp = await this.client.httpGet(enhancedSearchUrl, additionalHeaders);
39+
40+
const resource: Resource<CompaniesResource> = {
41+
httpStatusCode: resp.status
42+
};
43+
44+
if (resp.error) {
45+
return resource;
46+
}
47+
48+
resource.resource = resp.body as CompaniesResource;
49+
50+
return resource;
51+
}
52+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export interface CompaniesResource {
2+
etag: string;
3+
top_hit: TopHit;
4+
items: Items[];
5+
kind: string;
6+
hits: number;
7+
}
8+
9+
export interface Items {
10+
company_name: string;
11+
company_number: string;
12+
company_status: string;
13+
company_type: string;
14+
kind: string;
15+
links: Links;
16+
date_of_cessation: Date;
17+
date_of_creation: Date;
18+
registered_office_address: Address;
19+
}
20+
21+
export interface Address {
22+
address_line_1: string;
23+
address_line_2: string;
24+
locality: string;
25+
postal_code: string;
26+
premises: string;
27+
country: string;
28+
}
29+
30+
export interface TopHit {
31+
company_name: string;
32+
company_number: string;
33+
company_status: string;
34+
company_type: string;
35+
kind: string;
36+
links: Links;
37+
date_of_cessation: Date;
38+
date_of_creation: Date;
39+
registered_office_address: Address;
40+
}
41+
42+
export interface Links {
43+
company_profile: string;
44+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import chai from "chai";
2+
import sinon from "sinon";
3+
4+
import { EnhancedSearchService } from "../../../../src/services/search/enhanced-search";
5+
import { RequestClient } from "../../../../src/http";
6+
import { CompaniesResource } from "../../../../src/services/search/enhanced-search/types";
7+
import Resource from "../../../../src/services/resource";
8+
9+
const expect = chai.expect;
10+
11+
const requestClient = new RequestClient({ baseUrl: "URL-NOT-USED", oauthToken: "TOKEN-NOT-USED" });
12+
13+
const mockResponseBody : CompaniesResource = ({
14+
etag: "etag",
15+
top_hit: {
16+
company_name: "test company",
17+
company_number: "0000789",
18+
company_status: "active",
19+
company_type: "company type",
20+
kind: "kind",
21+
links: {
22+
company_profile: "/company/FC022000"
23+
},
24+
date_of_cessation: (new Date("19910212")),
25+
date_of_creation: (new Date("19910212")),
26+
registered_office_address: {
27+
address_line_1: "test house",
28+
address_line_2: "test street",
29+
locality: "cardiff",
30+
postal_code: "cf5 6rb",
31+
premises: "premises",
32+
country: "country"
33+
}
34+
},
35+
items: [
36+
{
37+
company_name: "test company",
38+
company_number: "0000789",
39+
company_status: "active",
40+
company_type: "company type",
41+
kind: "kind",
42+
links: {
43+
company_profile: "/company/FC022000"
44+
},
45+
date_of_cessation: (new Date("19910212")),
46+
date_of_creation: (new Date("19910212")),
47+
registered_office_address: {
48+
address_line_1: "test house",
49+
address_line_2: "test street",
50+
locality: "cardiff",
51+
postal_code: "cf5 6rb",
52+
premises: "premises",
53+
country: "country"
54+
}
55+
}
56+
],
57+
kind: "kind",
58+
hits: 1
59+
})
60+
61+
const mockRequestId = "fdskfhsdoifhsffsif";
62+
const testCompanyName = "TEST COMPANY NAME";
63+
const testLocation = "TEST LOCATION";
64+
const testIncorporatedFrom = " TEST INCORPORATED FROM";
65+
const testIncorporatedTo = " TEST INCORPORATED TO";
66+
const searchType = "enhanced";
67+
68+
describe("create an enhanced search GET", () => {
69+
beforeEach(() => {
70+
sinon.reset();
71+
sinon.restore();
72+
});
73+
74+
afterEach(done => {
75+
sinon.reset();
76+
sinon.restore();
77+
done();
78+
});
79+
80+
it("returns an error response on failure", async () => {
81+
const mockGetRequest = {
82+
status: 401,
83+
error: "An error occurred"
84+
};
85+
86+
const mockRequest = sinon.stub(requestClient, "httpGet").resolves(mockGetRequest);
87+
const search: EnhancedSearchService = new EnhancedSearchService(requestClient);
88+
const data: Resource<CompaniesResource> = await search.getCompanies(testCompanyName, testLocation, testIncorporatedFrom, testIncorporatedTo, mockRequestId);
89+
90+
expect(data.httpStatusCode).to.equal(401);
91+
expect(data.resource).to.be.undefined;
92+
});
93+
94+
it("returns enhanced search results correctly", async () => {
95+
const mockGetRequest = {
96+
status: 200,
97+
body: mockResponseBody
98+
};
99+
100+
const mockRequest = sinon.stub(requestClient, "httpGet").resolves(mockGetRequest);
101+
const search: EnhancedSearchService = new EnhancedSearchService(requestClient);
102+
const data: Resource<CompaniesResource> = await search.getCompanies(testCompanyName, testLocation, testIncorporatedFrom, testIncorporatedTo, mockRequestId);
103+
const item = data.resource.items[0];
104+
const mockItem = mockResponseBody.items[0];
105+
106+
expect(data.httpStatusCode).to.equal(200);
107+
expect(data.resource.etag).to.equal(mockResponseBody.etag);
108+
expect(data.resource.top_hit.company_name).to.equal(mockResponseBody.top_hit.company_name);
109+
expect(data.resource.top_hit.company_number).to.equal(mockResponseBody.top_hit.company_number);
110+
expect(data.resource.top_hit.company_status).to.equal(mockResponseBody.top_hit.company_status);
111+
expect(data.resource.top_hit.company_type).to.equal(mockResponseBody.top_hit.company_type);
112+
expect(data.resource.top_hit.kind).to.equal(mockResponseBody.top_hit.kind);
113+
expect(data.resource.top_hit.links.company_profile).to.equal(mockResponseBody.top_hit.links.company_profile);
114+
expect(data.resource.top_hit.date_of_cessation).to.equal(mockResponseBody.top_hit.date_of_cessation);
115+
expect(data.resource.top_hit.date_of_creation).to.equal(mockResponseBody.top_hit.date_of_creation);
116+
expect(data.resource.top_hit.registered_office_address.address_line_1).to.equal(mockResponseBody.top_hit.registered_office_address.address_line_1);
117+
expect(data.resource.top_hit.registered_office_address.address_line_2).to.equal(mockResponseBody.top_hit.registered_office_address.address_line_2);
118+
expect(data.resource.top_hit.registered_office_address.locality).to.equal(mockResponseBody.top_hit.registered_office_address.locality);
119+
expect(data.resource.top_hit.registered_office_address.postal_code).to.equal(mockResponseBody.top_hit.registered_office_address.postal_code);
120+
expect(data.resource.top_hit.registered_office_address.premises).to.equal(mockResponseBody.top_hit.registered_office_address.premises);
121+
expect(data.resource.top_hit.registered_office_address.country).to.equal(mockResponseBody.top_hit.registered_office_address.country);
122+
expect(item.company_name).to.equal(mockItem.company_name);
123+
expect(item.company_number).to.equal(mockItem.company_number);
124+
expect(item.company_status).to.equal(mockItem.company_status);
125+
expect(item.kind).to.equal(mockItem.kind);
126+
expect(item.links.company_profile).to.equal(mockItem.links.company_profile);
127+
expect(item.date_of_cessation).to.equal(mockItem.date_of_cessation);
128+
expect(item.date_of_creation).to.equal(mockItem.date_of_creation);
129+
expect(item.registered_office_address.address_line_1).to.equal(mockItem.registered_office_address.address_line_1);
130+
expect(item.registered_office_address.address_line_2).to.equal(mockItem.registered_office_address.address_line_2);
131+
expect(item.registered_office_address.locality).to.equal(mockItem.registered_office_address.locality);
132+
expect(item.registered_office_address.postal_code).to.equal(mockItem.registered_office_address.postal_code);
133+
expect(item.registered_office_address.premises).to.equal(mockItem.registered_office_address.premises);
134+
expect(data.resource.kind).to.equal(mockResponseBody.kind);
135+
expect(data.resource.hits).to.equal(mockResponseBody.hits);
136+
});
137+
});

0 commit comments

Comments
 (0)