Skip to content

Commit b17109d

Browse files
committed
add search service
add alphabetical search POST to search service add headers to http POST add post tests for alphabetical search update http POST test
1 parent ac96ba4 commit b17109d

File tree

8 files changed

+149
-5
lines changed

8 files changed

+149
-5
lines changed

src/client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { BasketService, OrderService, CertificateService, CertifiedCopiesService
77
import { PaymentService } from "./services/payment/";
88
import CompanyFilingHistoryService from "./services/company-filing-history/service";
99
import { RefreshTokenService } from "./services/refresh-token";
10+
import AlphabeticalSearchService from "./services/search/alphabetical-search/service";
1011

1112
/**
1213
* ApiClient is the class that all service objects hang off.
@@ -24,6 +25,7 @@ export default class ApiClient {
2425
public readonly order: OrderService;
2526
public readonly mid : MidService;
2627
public readonly refreshToken: RefreshTokenService;
28+
public readonly alphabeticalSearch: AlphabeticalSearchService;
2729

2830
constructor (readonly apiClient: IHttpClient, readonly accountClient: IHttpClient) {
2931
// services on the api domain using the apiClient
@@ -38,6 +40,7 @@ export default class ApiClient {
3840
this.payment = new PaymentService(apiClient); // TODO split payments url/domain into a separate config item and http client
3941
this.order = new OrderService(apiClient);
4042
this.mid = new MidService(apiClient);
43+
this.alphabeticalSearch = new AlphabeticalSearchService(apiClient);
4144
// service on the account/identity domain using the accountClient
4245
// e.g. user profile service can be added here when required
4346
this.refreshToken = new RefreshTokenService(accountClient);

src/http/http-client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default interface IHttpClient {
6464
* @param url the url relative to the base url
6565
*/
6666
httpGet(url: string): Promise<HttpResponse>;
67-
httpPost(url: string, body?: any): Promise<HttpResponse>;
67+
httpPost(url: string, body?: any, headers?: Headers): Promise<HttpResponse>;
6868
httpPatch(url: string, body?: any, headers?: Headers): Promise<HttpResponse>;
6969
httpPut(url: string, body?: any, headers?: Headers): Promise<HttpResponse>;
7070
httpDelete(url: string): Promise<HttpResponse>;
@@ -124,7 +124,7 @@ export abstract class AbstractClient implements IHttpClient {
124124
*/
125125
public abstract httpGet(url: string): Promise<HttpResponse>;
126126

127-
public abstract httpPost(url: string, body?: any): Promise<HttpResponse>;
127+
public abstract httpPost(url: string, body?: any, headers?: Headers): Promise<HttpResponse>;
128128

129129
public abstract httpPatch(url: string, body?: any, headers?: Headers): Promise<HttpResponse>;
130130

src/http/request-client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ export default class RequestClient extends AbstractClient {
1010
return this.request({ method: "GET", url });
1111
}
1212

13-
public async httpPost (url: string, body?: any): Promise<HttpResponse> {
14-
return this.request({ method: "POST", url, body });
13+
public async httpPost (url: string, body?: any, headers?: Headers): Promise<HttpResponse> {
14+
return this.request({ method: "POST", url, body, headers });
1515
}
1616

1717
public async httpPatch (url: string, body?: any, headers?: Headers): Promise<HttpResponse> {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as AlphabeticalSearchService } from "./service";
2+
export * from "./types";
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { IHttpClient } from "../../../http";
2+
import { AlphabeticalSearchPostRequest, CompaniesResource } from "./types";
3+
import Resource from "../../resource";
4+
5+
export default class AlphabeticalSearchService {
6+
constructor (private readonly client: IHttpClient) { }
7+
public async getCompanies (companyName: AlphabeticalSearchPostRequest, requestId: string): Promise<Resource<CompaniesResource>> {
8+
const additionalHeaders = {
9+
"X-Request-ID": requestId,
10+
"Content-Type": "application/json"
11+
}
12+
13+
const resp = await this.client.httpPost("/alphabetical-search/corporate-name", companyName, additionalHeaders);
14+
15+
const resource: Resource<CompaniesResource> = {
16+
httpStatusCode: resp.status
17+
};
18+
19+
if (resp.error) {
20+
return resource;
21+
}
22+
23+
resource.resource = resp.body as CompaniesResource;
24+
25+
return resource;
26+
}
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export interface CompaniesResource {
2+
searchType: string;
3+
topHit: string;
4+
results: Result[];
5+
}
6+
7+
export interface Result {
8+
ID: string;
9+
company_type: string;
10+
items: Items;
11+
links: Links;
12+
}
13+
14+
export interface Items {
15+
company_number: string;
16+
company_status: string;
17+
corporate_name: string;
18+
record_type: string;
19+
}
20+
21+
export interface Links {
22+
self: string;
23+
}
24+
25+
// AlphabeticalSearchPostRequest
26+
export interface AlphabeticalSearchPostRequest {
27+
company_name: string
28+
}

test/http/http-client.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AbstractClient, HttpResponse } from "../../src/http";
33
const expect = chai.expect;
44

55
class TestClient extends AbstractClient {
6-
public httpPost (url: string, body: any): Promise<HttpResponse> {
6+
public httpPost (url: string, body: any, headers: any): Promise<HttpResponse> {
77
throw new Error("Method not implemented.");
88
}
99

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import chai from "chai";
2+
import sinon from "sinon";
3+
4+
import { AlphabeticalSearchService } from "../../../../src/services/search/alphabetical-search";
5+
import { RequestClient } from "../../../../src/http";
6+
import { AlphabeticalSearchPostRequest, CompaniesResource } from "../../../../src/services/search/alphabetical-search/types";
7+
import Resource from "../../../../src/services/resource";
8+
const expect = chai.expect;
9+
10+
const requestClient = new RequestClient({ baseUrl: "URL-NOT-USED", oauthToken: "TOKEN-NOT-USED" });
11+
12+
const mockResponseBody : CompaniesResource = ({
13+
searchType: "",
14+
topHit: "TEST COMPANY",
15+
results: [
16+
{
17+
ID: "FC022000",
18+
company_type: "oversea-company",
19+
items: {
20+
company_number: "FC022000",
21+
company_status: "active",
22+
corporate_name: "corporate name",
23+
record_type: "record type"
24+
},
25+
links: {
26+
self: "/company/FC022000"
27+
}
28+
}
29+
]
30+
});
31+
32+
const mockRequestBody: AlphabeticalSearchPostRequest = ({
33+
company_name: "TEST"
34+
});
35+
36+
const mockRequestId = "fdskfhsdoifhsffsif";
37+
38+
describe("create a alphabetical search POST", () => {
39+
beforeEach(() => {
40+
sinon.reset();
41+
sinon.restore();
42+
});
43+
44+
afterEach(done => {
45+
sinon.reset();
46+
sinon.restore();
47+
done();
48+
});
49+
50+
it("returns an error response on failure", async () => {
51+
const mockPostRequest = {
52+
status: 401,
53+
error: "An error occurred"
54+
};
55+
56+
const mockRequest = sinon.stub(requestClient, "httpPost").resolves(mockPostRequest);
57+
const search: AlphabeticalSearchService = new AlphabeticalSearchService(requestClient);
58+
const data: Resource<CompaniesResource> = await search.getCompanies(mockRequestBody, mockRequestId);
59+
60+
expect(data.httpStatusCode).to.equal(401);
61+
expect(data.resource).to.be.undefined;
62+
});
63+
64+
it("returns alphabetical search results correctly", async () => {
65+
const mockPostRequest = {
66+
status: 200,
67+
body: mockResponseBody
68+
};
69+
70+
const mockRequest = sinon.stub(requestClient, "httpPost").resolves(mockPostRequest);
71+
const search: AlphabeticalSearchService = new AlphabeticalSearchService(requestClient);
72+
const data: Resource<CompaniesResource> = await search.getCompanies(mockRequestBody, mockRequestId);
73+
74+
expect(data.httpStatusCode).to.equal(200);
75+
expect(data.resource.topHit).to.equal(mockResponseBody.topHit);
76+
expect(data.resource.results[0].ID).to.equal(mockResponseBody.results[0].ID);
77+
expect(data.resource.results[0].company_type).to.equal(mockResponseBody.results[0].company_type)
78+
expect(data.resource.results[0].items.company_number).to.equal(mockResponseBody.results[0].items.company_number);
79+
expect(data.resource.results[0].items.company_status).to.equal(mockResponseBody.results[0].items.company_status);
80+
expect(data.resource.results[0].items.corporate_name).to.equal(mockResponseBody.results[0].items.corporate_name);
81+
expect(data.resource.results[0].items.record_type).to.equal(mockResponseBody.results[0].items.record_type);
82+
expect(data.resource.results[0].links).to.equal(mockResponseBody.results[0].links);
83+
});
84+
});

0 commit comments

Comments
 (0)