Skip to content

Commit

Permalink
Merge pull request #17 from oracle-samples/feature-full-export
Browse files Browse the repository at this point in the history
Feature: Activity File Proeprties Management
  • Loading branch information
miquelgall authored Dec 12, 2023
2 parents 0976eb8 + 9db01fd commit efca714
Show file tree
Hide file tree
Showing 9 changed files with 641 additions and 241 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ In order to use this library you need to have access to an Oracle Field Service

`updateActivity(activityId, activityData)`: Update activity details

`setActivityFileProperty(activityId, propertyId, file)`: Set file property

`getActivityFilePropertyMetadata(activityId, propertyId)`: Get file property metadata

`getActivityFilePropertyContent(activityId, propertyId, contentType)`: Get file property content

`getActivityFileProperty(activityId, propertyId)`: Get file property (content and metadata)

### Core: Subscription Management

`getSubscriptions()`: Get existing subscriptions
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
| `createActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-post.html |
| `deleteActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-delete.html |
| `getActivityDetails`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-get.html |
| `setFileProperty`|https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-propertylabel-put.html |
| `getFileProperty`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-propertylabel-get.html |
| `updateActivity`| https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-activities-activityid-patch.html
| `getSubscriptions` | https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofsccore-v1-events-subscriptions-get.html
| `importPlugins` | https://docs.oracle.com/en/cloud/saas/field-service/cxfsc/op-rest-ofscmetadata-v1-plugins-custom-actions-import-post.html
Expand Down
380 changes: 225 additions & 155 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
],
"name": "@ofs-users/proxy",
"type": "module",
"version": "1.8.1",
"version": "1.8.3",
"description": "A Javascript proxy to access Oracle Field Service via REST API",
"main": "dist/ofs.es.js",
"module": "dist/ofs.es.js",
Expand Down Expand Up @@ -46,7 +46,7 @@
}
},
"devDependencies": {
"@babel/preset-typescript": "^7.18.6",
"@babel/preset-typescript": "^7.23.3",
"@faker-js/faker": "^8.3.1",
"@jest/globals": "^29.3.1",
"@rollup/plugin-terser": "^0.2.1",
Expand All @@ -65,6 +65,7 @@
"typescript": "^4.9.4"
},
"dependencies": {
"@ofs-users/proxy": "^1.8.2",
"tslib": "^2.4.1"
}
}
131 changes: 118 additions & 13 deletions src/OFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
OFSGetPropertiesParams,
} from "./model";

export * from "./model";
export class OFS {
private _credentials!: OFSCredentials;
private _hash!: string;
Expand Down Expand Up @@ -57,7 +58,8 @@ export class OFS {

private _get(
partialURL: string,
params: any = undefined
params: any = undefined,
extraHeaders: Headers = new Headers()
): Promise<OFSResponse> {
var theURL = new URL(partialURL, this._baseURL);
if (params != undefined) {
Expand All @@ -66,6 +68,10 @@ export class OFS {
}
var myHeaders = new Headers();
myHeaders.append("Authorization", this.authorization);
extraHeaders.forEach((value, key) => {
console.log(key, value);
myHeaders.append(key, value);
});
var requestOptions = {
method: "GET",
headers: myHeaders,
Expand All @@ -74,12 +80,24 @@ export class OFS {
.then(async function (response) {
// Your code for handling the data you get from the API
if (response.status < 400) {
var data = await response.json();
var data;
if (
response.headers.get("Content-Type")?.includes("json")
) {
data = await response.json();
} else if (
response.headers.get("Content-Type")?.includes("text")
) {
data = await response.text();
} else {
data = await response.blob();
}
return new OFSResponse(
theURL,
response.status,
undefined,
data
data,
response.headers.get("Content-Type") || undefined
);
} else {
return new OFSResponse(
Expand Down Expand Up @@ -134,27 +152,51 @@ export class OFS {
return fetchPromise;
}

private _put(partialURL: string, requestData: any): Promise<OFSResponse> {
private _put(
partialURL: string,
requestData: any,
contentType: string = "application/json",
fileName?: string
): Promise<OFSResponse> {
var theURL = new URL(partialURL, this._baseURL);
var myHeaders = new Headers();
myHeaders.append("Authorization", this.authorization);
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Content-Type", contentType);
if (contentType == "application/json") {
requestData = JSON.stringify(requestData);
}
if (fileName) {
myHeaders.append(
"Content-Disposition",
`attachment; filename=${fileName}`
);
}
var requestOptions: RequestInit = {
method: "PUT",
headers: myHeaders,
body: JSON.stringify(requestData),
body: requestData,
};
const fetchPromise = fetch(theURL, requestOptions)
.then(async function (response) {
// Your code for handling the data you get from the API
if (response.status < 400) {
var data = await response.json();
return new OFSResponse(
theURL,
response.status,
undefined,
data
);
if (response.status == 204) {
//No data here
return new OFSResponse(
theURL,
response.status,
undefined,
undefined
);
} else {
var data = await response.json();
return new OFSResponse(
theURL,
response.status,
undefined,
data
);
}
} else {
return new OFSResponse(
theURL,
Expand Down Expand Up @@ -319,6 +361,69 @@ export class OFS {
return this._patch(partialURL, data);
}

async getActivityFilePropertyContent(
aid: number,
propertyLabel: string,
nediaType: string = "*/*"
): Promise<OFSResponse> {
var myHeaders = new Headers();
myHeaders.append("Accept", nediaType);
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
return this._get(partialURL, undefined, myHeaders);
}

async getActivityFilePropertyMetadata(
aid: number,
propertyLabel: string
): Promise<OFSResponse> {
var myHeaders = new Headers();
myHeaders.append("Accept", "*/*");
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
return this._get(partialURL, undefined, myHeaders);
}

async getActivityFileProperty(
aid: number,
propertyLabel: string
): Promise<OFSResponse> {
var myHeaders = new Headers();
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
var metadata = await this.getActivityFilePropertyMetadata(
aid,
propertyLabel
);
if (metadata.status < 400) {
var contentType = metadata.contentType;
if (contentType) {
myHeaders.append("Accept", contentType);
}
var content = this._get(partialURL, undefined, myHeaders);
return new OFSResponse(
metadata.url,
metadata.status,
metadata.description,
{
...metadata.data,
content: (await content).data,
},
metadata.contentType
);
} else {
return metadata;
}
}

async setActivityFileProperty(
aid: number,
propertyLabel: string,
blob: Blob,
fileName: string,
contentType: string = "*/*"
): Promise<OFSResponse> {
const partialURL = `/rest/ofscCore/v1/activities/${aid}/${propertyLabel}`;
return this._put(partialURL, blob, contentType, fileName);
}

// Core: User Management
async getUsers(
offset: number = 0,
Expand Down
11 changes: 10 additions & 1 deletion src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ export interface OFSResponseInterface {
description: string | undefined;
data: any;
url: URL;
contentType?: string;
}

export class OFSResponse implements OFSResponseInterface {
status: number = -1;
description: string | undefined;
data: any;
url: URL;
contentType?: string;

constructor(url: URL, status: number, description?: string, data?: any) {
constructor(
url: URL,
status: number,
description?: string,
data?: any,
contentType?: string
) {
this.status = status;
this.description = description;
this.data = data;
this.url = url;
this.contentType = contentType;
}
}

Expand Down
70 changes: 0 additions & 70 deletions test/general/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,76 +31,6 @@ test("Get Subscriptions", async () => {
expect(myProxy.instance).toBe(myCredentials.instance);
});

test("Get Activity Details", async () => {
var aid = 3954799;
var result = await myProxy.getActivityDetails(aid);
expect(result.data.activityId).toBe(aid);
});

test("Get non valid Activity Details", async () => {
var aid = -1;
var result = await myProxy.getActivityDetails(aid);
expect(result.status).toBe(400);
});

test("Create Activity", async () => {
var activityData = {
activityType: "01",
resourceId: "FLUSA",
};
var result = await myProxy.createActivity(activityData);
expect(result.status).toBe(201);
expect(result.data.activityType).toBe(activityData.activityType);
// For cleanup
var activityId = result.data.activityId;
activityList.push(activityId);
});

test("Delete Activity", async () => {
var activityData = {
activityType: "01",
resourceId: "FLUSA",
};
var result = await myProxy.createActivity(activityData);
expect(result.status).toBe(201);
expect(result.data.activityType).toBe(activityData.activityType);
var activityId = result.data.activityId;
activityList.push(activityId);
var result = await myProxy.deleteActivity(activityId);
expect(result.status).toBe(204);
});

test("Update Activity Details", async () => {
var activityData = {
activityType: "01",
resourceId: "FLUSA",
};
var result = await myProxy.createActivity(activityData);
expect(result.status).toBe(201);
var aid = result.data.activityId;
var initialName = "Gizella Quintero";
var data = {
customerName: "NewName",
};
var result = await myProxy.updateActivity(aid, data);
expect(result.data.activityId).toBe(aid);
expect(result.data.customerName).toBe(data.customerName);
expect((await myProxy.getActivityDetails(aid)).data.customerName).toBe(
data.customerName
);
expect(
(await myProxy.updateActivity(aid, { customerName: initialName })).data
.customerName
).toBe(initialName);
activityList.push(aid);
});

test("Update non valid Activity Details", async () => {
var aid = -1;
var result = await myProxy.updateActivity(aid, {});
expect(result.status).toBe(404);
});

test("Update Plugin (path)", async () => {
var result = await myProxy.importPlugins("test/test_plugin.xml");
try {
Expand Down
Loading

0 comments on commit efca714

Please sign in to comment.