Skip to content

Commit

Permalink
add origin, coordinate service; update origin list/detail
Browse files Browse the repository at this point in the history
  • Loading branch information
ntheanh201 committed Dec 15, 2023
1 parent ced1c98 commit 61586db
Show file tree
Hide file tree
Showing 14 changed files with 1,084 additions and 263 deletions.
85 changes: 85 additions & 0 deletions experimental/traffic-portal/src/app/api/coordinate.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* @license Apache-2.0
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
HttpClientTestingModule,
HttpTestingController,
} from "@angular/common/http/testing";
import { TestBed } from "@angular/core/testing";

import { CoordinateService } from "./coordinate.service";

describe("CoordinateService", () => {
let service: CoordinateService;
let httpTestingController: HttpTestingController;
const coordinate = {
id: 1,
lastUpdated: new Date(),
latitude: 1.0,
longitude: -1.0,
name: "test_coordinate",
};

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [CoordinateService],
});
service = TestBed.inject(CoordinateService);
httpTestingController = TestBed.inject(HttpTestingController);
});

it("should be created", () => {
expect(service).toBeTruthy();
});

it("gets multiple Coordinates", async () => {
const responseP = service.getCoordinates();
const req = httpTestingController.expectOne(
`/api/${service.apiVersion}/coordinates`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(0);
req.flush({ response: [coordinate] });
await expectAsync(responseP).toBeResolvedTo([coordinate]);
});

it("gets a single Coordinate by ID", async () => {
const responseP = service.getCoordinates(coordinate.id);
const req = httpTestingController.expectOne(
(r) => r.url === `/api/${service.apiVersion}/coordinates`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(1);
expect(req.request.params.get("id")).toBe(String(coordinate.id));
req.flush({ response: [coordinate] });
await expectAsync(responseP).toBeResolvedTo(coordinate);
});

it("gets a single Coordinate by name", async () => {
const responseP = service.getCoordinates(coordinate.name);
const req = httpTestingController.expectOne(
(r) => r.url === `/api/${service.apiVersion}/coordinates`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(1);
expect(req.request.params.get("name")).toBe(coordinate.name);
req.flush({ response: [coordinate] });
await expectAsync(responseP).toBeResolvedTo(coordinate);
});

afterEach(() => {
httpTestingController.verify();
});
});
83 changes: 83 additions & 0 deletions experimental/traffic-portal/src/app/api/coordinate.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import type { ResponseCoordinate } from "trafficops-types";

import { APIService } from "./base-api.service";

/**
* CoordinateService exposes API functionality relating to Coordinates.
*/
@Injectable()
export class CoordinateService extends APIService {
/**
* Gets a specific Coordinate from Traffic Ops.
*
* @param idOrName Either the integral, unique identifier (number) or name
* (string) of the Coordinate to be returned.
* @returns The requested Coordinate.
*/
public async getCoordinates(
idOrName: number | string
): Promise<ResponseCoordinate>;
/**
* Gets Coordinates from Traffic Ops.
*/
public async getCoordinates(): Promise<Array<ResponseCoordinate>>;

/**
* Gets one or all Coordinates from Traffic Ops.
*
* @param idOrName Optionally the integral, unique identifier (number) or
* name (string) of a single Coordinate to be returned.
* @returns The requested Coordinate(s).
*/
public async getCoordinates(
idOrName?: number | string
): Promise<ResponseCoordinate | Array<ResponseCoordinate>> {
const path = "coordinates";
if (idOrName !== undefined) {
let params;
switch (typeof idOrName) {
case "string":
params = { name: idOrName };
break;
case "number":
params = { id: idOrName };
}
const r = await this.get<[ResponseCoordinate]>(
path,
undefined,
params
).toPromise();
if (r.length !== 1) {
throw new Error(
`Traffic Ops responded with ${r.length} Coordinates by identifier ${idOrName}`
);
}
return r[0];
}
return this.get<Array<ResponseCoordinate>>(path).toPromise();
}

/**
* Injects the Angular HTTP client service into the parent constructor.
*
* @param http The Angular HTTP client service.
*/
constructor(http: HttpClient) {
super(http);
}
}
5 changes: 5 additions & 0 deletions experimental/traffic-portal/src/app/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import { ChangeLogsService } from "src/app/api/change-logs.service";

import { CacheGroupService } from "./cache-group.service";
import { CDNService } from "./cdn.service";
import { CoordinateService } from "./coordinate.service";
import { DeliveryServiceService } from "./delivery-service.service";
import { InvalidationJobService } from "./invalidation-job.service";
import { MiscAPIsService } from "./misc-apis.service";
import { OriginService } from "./origin.service";
import { PhysicalLocationService } from "./physical-location.service";
import { ProfileService } from "./profile.service";
import { ServerService } from "./server.service";
Expand All @@ -43,6 +45,7 @@ export * from "./topology.service";
export * from "./type.service";
export * from "./user.service";
export * from "./origin.service";
export * from "./coordinate.service";

/**
* The API Module contains all logic used to access the Traffic Ops API.
Expand All @@ -65,6 +68,8 @@ export * from "./origin.service";
TopologyService,
TypeService,
UserService,
OriginService,
CoordinateService,
]
})
export class APIModule { }
146 changes: 146 additions & 0 deletions experimental/traffic-portal/src/app/api/origin.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* @license Apache-2.0
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
HttpClientTestingModule,
HttpTestingController,
} from "@angular/common/http/testing";
import { TestBed } from "@angular/core/testing";

import { OriginService } from "./origin.service";

describe("OriginService", () => {
let service: OriginService;
let httpTestingController: HttpTestingController;
const origin = {
cachegroup: null,
cachegroupId: null,
coordinate: null,
coordinateId: null,
deliveryService: "test",
deliveryServiceId: 1,
fqdn: "origin.infra.ciab.test",
id: 1,
ip6Address: null,
ipAddress: null,
isPrimary: false,
lastUpdated: new Date(),
name: "test",
port: null,
profile: null,
profileId: null,
protocol: "http" as never,
tenant: "root",
tenantId: 1,
};

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [OriginService],
});
service = TestBed.inject(OriginService);
httpTestingController = TestBed.inject(HttpTestingController);
});

it("should be created", () => {
expect(service).toBeTruthy();
});

it("gets multiple Origins", async () => {
const responseP = service.getOrigins();
const req = httpTestingController.expectOne(
`/api/${service.apiVersion}/origins`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(0);
req.flush({ response: [origin] });
await expectAsync(responseP).toBeResolvedTo([origin]);
});

it("gets a single Origin by ID", async () => {
const responseP = service.getOrigins(origin.id);
const req = httpTestingController.expectOne(
(r) => r.url === `/api/${service.apiVersion}/origins`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(1);
expect(req.request.params.get("id")).toBe(String(origin.id));
req.flush({ response: [origin] });
await expectAsync(responseP).toBeResolvedTo(origin);
});

it("gets a single Origin by name", async () => {
const responseP = service.getOrigins(origin.name);
const req = httpTestingController.expectOne(
(r) => r.url === `/api/${service.apiVersion}/origins`
);
expect(req.request.method).toBe("GET");
expect(req.request.params.keys().length).toBe(1);
expect(req.request.params.get("name")).toBe(origin.name);
req.flush({ response: [origin] });
await expectAsync(responseP).toBeResolvedTo(origin);
});

it("submits requests to create new Origins", async () => {
const responseP = service.createOrigin({
...origin,
tenantID: origin.tenantId,
});
const req = httpTestingController.expectOne(
`/api/${service.apiVersion}/origins`
);
expect(req.request.method).toBe("POST");
expect(req.request.params.keys().length).toBe(0);
expect(req.request.body).toEqual(origin);
req.flush({ response: origin });
await expectAsync(responseP).toBeResolvedTo(origin);
});

it("submits requests to update existing Origins", async () => {
const responseP = service.updateOrigin(origin);
const req = httpTestingController.expectOne(
`/api/${service.apiVersion}/origins?id=${origin.id}`
);
expect(req.request.method).toBe("PUT");
expect(req.request.params.keys().length).toBe(0);
expect(req.request.body).toEqual(origin);
req.flush({ response: origin });
await expectAsync(responseP).toBeResolvedTo(origin);
});

it("submits requests to delete Origins", async () => {
let responseP = service.deleteOrigin(origin);
let req = httpTestingController.expectOne(
`/api/${service.apiVersion}/origins?id=${origin.id}`
);
expect(req.request.method).toBe("DELETE");
expect(req.request.params.keys().length).toBe(0);
req.flush({ alerts: [] });
await expectAsync(responseP).toBeResolved();

responseP = service.deleteOrigin(origin.id);
req = httpTestingController.expectOne(
`/api/${service.apiVersion}/origins?id=${origin.id}`
);
expect(req.request.method).toBe("DELETE");
expect(req.request.params.keys().length).toBe(0);
req.flush({ alerts: [] });
await expectAsync(responseP).toBeResolved();
});

afterEach(() => {
httpTestingController.verify();
});
});
Loading

0 comments on commit 61586db

Please sign in to comment.