[ARVADOS-WORKBENCH2] created: 1.1.4-173-gd3f17ba
Git user
git at public.curoverse.com
Mon Jul 2 05:09:31 EDT 2018
at d3f17ba544b22ae76f47401041362bbcefe95aaa (commit)
commit d3f17ba544b22ae76f47401041362bbcefe95aaa
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date: Mon Jul 2 11:09:21 2018 +0200
Create CommonResourceService and OrderBuilder
Feature #13702
Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
diff --git a/package.json b/package.json
index 3db2404..f769acc 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"@types/react-router-dom": "4.2.7",
"@types/react-router-redux": "5.0.15",
"@types/redux-devtools": "3.0.44",
+ "axios-mock-adapter": "^1.15.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"jest-localstorage-mock": "2.2.0",
diff --git a/src/common/api/common-resource-service.test.ts b/src/common/api/common-resource-service.test.ts
new file mode 100644
index 0000000..a07655e
--- /dev/null
+++ b/src/common/api/common-resource-service.test.ts
@@ -0,0 +1,62 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import CommonResourceService from "./common-resource-service";
+import axios from "axios";
+import MockAdapter from "axios-mock-adapter";
+
+describe("CommonResourceService", () => {
+
+ const axiosMock = new MockAdapter(axios);
+
+ beforeEach(() => {
+ axiosMock.reset();
+ });
+
+ it("#delete", async () => {
+ axiosMock
+ .onDelete("/resource/uuid")
+ .reply(200, { deleted_at: "now" });
+
+ const commonResourceService = new CommonResourceService(axios, "resource");
+ const resource = await commonResourceService.delete("uuid");
+ expect(resource).toEqual({ deletedAt: "now" });
+ });
+
+ it("#get", async () => {
+ axiosMock
+ .onGet("/resource/uuid")
+ .reply(200, { modified_at: "now" });
+
+ const commonResourceService = new CommonResourceService(axios, "resource");
+ const resource = await commonResourceService.get("uuid");
+ expect(resource).toEqual({ modifiedAt: "now" });
+ });
+
+ it("#list", async () => {
+ axiosMock
+ .onGet("/resource")
+ .reply(200, {
+ kind: "kind",
+ offset: 2,
+ limit: 10,
+ items: [{
+ modified_at: "now"
+ }],
+ items_available: 20
+ });
+
+ const commonResourceService = new CommonResourceService(axios, "resource");
+ const resource = await commonResourceService.list({ limit: 10, offset: 1 });
+ expect(resource).toEqual({
+ kind: "kind",
+ offset: 2,
+ limit: 10,
+ items: [{
+ modifiedAt: "now"
+ }],
+ itemsAvailable: 20
+ });
+ });
+});
diff --git a/src/common/api/common-resource-service.ts b/src/common/api/common-resource-service.ts
new file mode 100644
index 0000000..e49d2a0
--- /dev/null
+++ b/src/common/api/common-resource-service.ts
@@ -0,0 +1,106 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as _ from "lodash";
+import FilterBuilder from "./filter-builder";
+import OrderBuilder from "./order-builder";
+import { AxiosInstance } from "axios";
+
+export interface Resource {
+ uuid: string;
+ ownerUuid: string;
+ createdAt: string;
+ modifiedByClientUuid: string;
+ modifiedByUserUuid: string;
+ modifiedAt: string;
+ href: string;
+ kind: string;
+ etag: string;
+}
+
+export interface ListArguments {
+ limit: number;
+ offset: number;
+ filters?: FilterBuilder;
+ order?: OrderBuilder;
+ select?: string[];
+ distinct?: boolean;
+ count?: string;
+}
+
+export interface ListResults<T> {
+ kind: string;
+ offset: number;
+ limit: number;
+ items: T[];
+ itemsAvailable: number;
+}
+
+export default class CommonResourceService<T extends Resource> {
+
+ serverApi: AxiosInstance;
+ resourceType: string;
+
+ static mapResponseKeys = (response: any): Promise<any> =>
+ CommonResourceService.mapKeys(_.camelCase)(response.data)
+
+ static mapKeys = (mapFn: (key: string) => string) =>
+ (value: any): any => {
+ switch (true) {
+ case _.isPlainObject(value):
+ return Object
+ .keys(value)
+ .map(key => [key, mapFn(key)])
+ .reduce((newValue, [key, newKey]) => ({
+ ...newValue,
+ [newKey]: CommonResourceService.mapKeys(mapFn)(value[key])
+ }), {});
+ case _.isArray(value):
+ return value.map(CommonResourceService.mapKeys(mapFn));
+ default:
+ return value;
+ }
+ }
+
+ constructor(serverApi: AxiosInstance, resourceType: string) {
+ this.serverApi = serverApi;
+ this.resourceType = "/" + resourceType;
+ }
+
+ create() {
+ throw new Error("Not implemented");
+ }
+
+ delete(uuid: string): Promise<T> {
+ return this.serverApi
+ .delete(this.resourceType + "/" + uuid)
+ .then(CommonResourceService.mapResponseKeys);
+ }
+
+ get(uuid: string) {
+ return this.serverApi
+ .get<T>(this.resourceType + "/" + uuid)
+ .then(CommonResourceService.mapResponseKeys);
+ }
+
+ list(args: ListArguments): Promise<ListResults<T>> {
+ const { filters, order, ...other } = args;
+ const params = {
+ ...other,
+ filters: filters ? filters.get() : undefined,
+ order: order ? order.get() : undefined
+ };
+ return this.serverApi
+ .get(this.resourceType, {
+ params: CommonResourceService.mapKeys(_.snakeCase)(params)
+ })
+ .then(CommonResourceService.mapResponseKeys);
+ }
+
+ update(uuid: string) {
+ throw new Error("Not implemented");
+ }
+
+}
+
diff --git a/src/common/api/order-builder.test.ts b/src/common/api/order-builder.test.ts
new file mode 100644
index 0000000..7647426
--- /dev/null
+++ b/src/common/api/order-builder.test.ts
@@ -0,0 +1,16 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import OrderBuilder from "./order-builder";
+
+describe("OrderBuilder", () => {
+ it("should build correct order query", () => {
+ const orderBuilder = new OrderBuilder();
+ const order = orderBuilder
+ .addAsc("name")
+ .addDesc("modified_at")
+ .get();
+ expect(order).toEqual(`["name asc","modified_at desc"]`);
+ });
+});
diff --git a/src/common/api/order-builder.ts b/src/common/api/order-builder.ts
new file mode 100644
index 0000000..394cce5
--- /dev/null
+++ b/src/common/api/order-builder.ts
@@ -0,0 +1,22 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+
+export default class OrderBuilder {
+ private order: string[] = [];
+
+ addAsc(attribute: string) {
+ this.order.push(`${attribute} asc`);
+ return this;
+ }
+
+ addDesc(attribute: string) {
+ this.order.push(`${attribute} desc`);
+ return this;
+ }
+
+ get() {
+ return `["${this.order.join(`","`)}"]`;
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 9a3379b..d71a561 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -477,6 +477,12 @@ aws4@^1.6.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289"
+axios-mock-adapter@^1.15.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.15.0.tgz#fbc06825d8302c95c3334d21023bba996255d45d"
+ dependencies:
+ deep-equal "^1.0.1"
+
axios at 0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list