1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-03 18:50:05 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Krishna Acondy
232f4ec3fb chore(*): add tests for SessionManager 2020-11-24 07:42:18 +00:00
17 changed files with 191 additions and 159 deletions

View File

@@ -27,6 +27,16 @@ jobs:
run: npm run lint run: npm run lint
- name: Run unit tests - name: Run unit tests
run: npm test run: npm test
env:
CI: true
CLIENT: ${{secrets.CLIENT}}
SECRET: ${{secrets.SECRET}}
SAS_USERNAME: ${{secrets.SAS_USERNAME}}
SAS_PASSWORD: ${{secrets.SAS_PASSWORD}}
SERVER_URL: ${{secrets.SERVER_URL}}
SERVER_TYPE: ${{secrets.SERVER_TYPE}}
ACCESS_TOKEN: ${{secrets.ACCESS_TOKEN}}
REFRESH_TOKEN: ${{secrets.REFRESH_TOKEN}}
- name: Build Package - name: Build Package
run: npm run package:lib run: npm run package:lib
env: env:

2
.gitignore vendored
View File

@@ -1,2 +1,2 @@
node_modules node_modules
build build

View File

@@ -14,5 +14,5 @@ What code changes have been made to achieve the intent.
- [ ] Code is formatted correctly (`npm run lint:fix`). - [ ] Code is formatted correctly (`npm run lint:fix`).
- [ ] All unit tests are passing (`npm test`). - [ ] All unit tests are passing (`npm test`).
- [ ] All `sasjs-cli` unit tests are passing (`npm test`). - [ ] All `sasjs-tests` unit tests are passing (`npm test`).
- [ ] All `sasjs-tests` are passing (instructions available [here](https://github.com/sasjs/adapter/blob/master/sasjs-tests/README.md)). - [ ] All `sasjs-tests` are passing (instructions available [here](https://github.com/sasjs/adapter/blob/master/sasjs-tests/README.md)).

119
package-lock.json generated
View File

@@ -3688,6 +3688,12 @@
"is-obj": "^2.0.0" "is-obj": "^2.0.0"
} }
}, },
"dotenv": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
"dev": true
},
"duplexer2": { "duplexer2": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@@ -4794,9 +4800,9 @@
} }
}, },
"highlight.js": { "highlight.js": {
"version": "10.4.0", "version": "10.1.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.0.tgz", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.1.1.tgz",
"integrity": "sha512-EfrUGcQ63oLJbj0J0RI9ebX6TAITbsDBLbsjr881L/X5fMO9+oadKzEF21C7R3ULKG6Gv3uoab2HiqVJa/4+oA==", "integrity": "sha512-b4L09127uVa+9vkMgPpdUQP78ickGbHEQTWeBrQFTJZ4/n2aihWOGS0ZoUqAwjVmfjhq/C76HRzkqwZhK4sBbg==",
"dev": true "dev": true
}, },
"hmac-drbg": { "hmac-drbg": {
@@ -4936,6 +4942,14 @@
"dev": true, "dev": true,
"requires": { "requires": {
"resolve-from": "^5.0.0" "resolve-from": "^5.0.0"
},
"dependencies": {
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
}
} }
}, },
"import-local": { "import-local": {
@@ -8563,9 +8577,9 @@
"dev": true "dev": true
}, },
"npm": { "npm": {
"version": "6.14.9", "version": "6.14.8",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.9.tgz", "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.8.tgz",
"integrity": "sha512-yHi1+i9LyAZF1gAmgyYtVk+HdABlLy94PMIDoK1TRKWvmFQAt5z3bodqVwKvzY0s6dLqQPVsRLiwhJfNtiHeCg==", "integrity": "sha512-HBZVBMYs5blsj94GTeQZel7s9odVuuSUHy1+AlZh7rPVux1os2ashvEGLy/STNK7vUjbrCg5Kq9/GXisJgdf6A==",
"dev": true, "dev": true,
"requires": { "requires": {
"JSONStream": "^1.3.5", "JSONStream": "^1.3.5",
@@ -8648,7 +8662,7 @@
"npm-pick-manifest": "^3.0.2", "npm-pick-manifest": "^3.0.2",
"npm-profile": "^4.0.4", "npm-profile": "^4.0.4",
"npm-registry-fetch": "^4.0.7", "npm-registry-fetch": "^4.0.7",
"npm-user-validate": "^1.0.1", "npm-user-validate": "~1.0.0",
"npmlog": "~4.1.2", "npmlog": "~4.1.2",
"once": "~1.4.0", "once": "~1.4.0",
"opener": "^1.5.1", "opener": "^1.5.1",
@@ -8723,6 +8737,17 @@
"humanize-ms": "^1.2.1" "humanize-ms": "^1.2.1"
} }
}, },
"ajv": {
"version": "5.5.2",
"bundled": true,
"dev": true,
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"ansi-align": { "ansi-align": {
"version": "2.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
@@ -9053,6 +9078,11 @@
"mkdirp": "~0.5.0" "mkdirp": "~0.5.0"
} }
}, },
"co": {
"version": "4.6.0",
"bundled": true,
"dev": true
},
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
@@ -9501,6 +9531,11 @@
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"fast-deep-equal": {
"version": "1.1.0",
"bundled": true,
"dev": true
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
@@ -9821,35 +9856,12 @@
"dev": true "dev": true
}, },
"har-validator": { "har-validator": {
"version": "5.1.5", "version": "5.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"ajv": "^6.12.3", "ajv": "^5.3.0",
"har-schema": "^2.0.0" "har-schema": "^2.0.0"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"bundled": true,
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"bundled": true,
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"bundled": true,
"dev": true
}
} }
}, },
"has": { "has": {
@@ -10136,6 +10148,11 @@
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"json-schema-traverse": {
"version": "0.3.1",
"bundled": true,
"dev": true
},
"json-stringify-safe": { "json-stringify-safe": {
"version": "5.0.1", "version": "5.0.1",
"bundled": true, "bundled": true,
@@ -10777,11 +10794,6 @@
"path-key": "^2.0.0" "path-key": "^2.0.0"
} }
}, },
"npm-user-validate": {
"version": "1.0.1",
"bundled": true,
"dev": true
},
"npmlog": { "npmlog": {
"version": "4.1.2", "version": "4.1.2",
"bundled": true, "bundled": true,
@@ -11782,21 +11794,6 @@
"xdg-basedir": "^3.0.0" "xdg-basedir": "^3.0.0"
} }
}, },
"uri-js": {
"version": "4.4.0",
"bundled": true,
"dev": true,
"requires": {
"punycode": "^2.1.0"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"bundled": true,
"dev": true
}
}
},
"url-parse-lax": { "url-parse-lax": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
@@ -12100,6 +12097,12 @@
"path-key": "^2.0.0" "path-key": "^2.0.0"
} }
}, },
"npm-user-validate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-1.0.1.tgz",
"integrity": "sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==",
"dev": true
},
"nwsapi": { "nwsapi": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@@ -13247,9 +13250,9 @@
} }
}, },
"semantic-release": { "semantic-release": {
"version": "17.3.0", "version": "17.2.3",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.3.0.tgz", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.2.3.tgz",
"integrity": "sha512-enhDayMZRP4nWcWAMBFHHB7THRaIcRdUAZv3lxd65pXs2ttzay7IeCvRRrGayRWExtnY0ulwRz5Ycp88Dv/UeQ==", "integrity": "sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@semantic-release/commit-analyzer": "^8.0.0", "@semantic-release/commit-analyzer": "^8.0.0",
@@ -13340,6 +13343,12 @@
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true "dev": true
}, },
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
},
"semver": { "semver": {
"version": "7.3.2", "version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",

View File

@@ -2,7 +2,7 @@
"name": "@sasjs/adapter", "name": "@sasjs/adapter",
"description": "JavaScript adapter for SAS", "description": "JavaScript adapter for SAS",
"scripts": { "scripts": {
"build": "rimraf build && rimraf node && mkdir node && cp -r src/* node && webpack && rimraf build/src && rimraf node", "build": "rimraf build && webpack",
"package:lib": "npm run build && cp ./package.json build && cd build && npm version \"5.0.0\" && npm pack", "package:lib": "npm run build && cp ./package.json build && cd build && npm version \"5.0.0\" && npm pack",
"publish:lib": "npm run build && cd build && npm publish", "publish:lib": "npm run build && cd build && npm publish",
"lint:fix": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'", "lint:fix": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'",
@@ -39,10 +39,11 @@
"@types/isomorphic-fetch": "0.0.35", "@types/isomorphic-fetch": "0.0.35",
"@types/jest": "^26.0.15", "@types/jest": "^26.0.15",
"cp": "^0.2.0", "cp": "^0.2.0",
"dotenv": "^8.2.0",
"jest": "^25.5.4", "jest": "^25.5.4",
"path": "^0.12.7", "path": "^0.12.7",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"semantic-release": "^17.3.0", "semantic-release": "^17.2.3",
"terser-webpack-plugin": "^4.2.3", "terser-webpack-plugin": "^4.2.3",
"ts-jest": "^25.5.1", "ts-jest": "^25.5.1",
"ts-loader": "^8.0.11", "ts-loader": "^8.0.11",

View File

@@ -1357,9 +1357,9 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
}, },
"@sasjs/adapter": { "@sasjs/adapter": {
"version": "1.18.3", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-1.18.3.tgz", "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-1.12.0.tgz",
"integrity": "sha512-wzDFJRyt2dXFeQP+JzqRGunYUbujrAbU/Jc4IWg5URsCkGAzwsNl/4G0xJVbqOTy1MvoZ431rfCnvhkUlg7D3Q==", "integrity": "sha512-0uGQH9ynomWzdBaEujEtcR38q6V7LCgG0mrb1Wellv6cC/IHD3j6WfeZZAgtiMPeOSJjbCDBOlVnzC2TlBqJFw==",
"requires": { "requires": {
"es6-promise": "^4.2.8", "es6-promise": "^4.2.8",
"form-data": "^3.0.0", "form-data": "^3.0.0",

View File

@@ -4,7 +4,7 @@
"homepage": ".", "homepage": ".",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@sasjs/adapter": "^1.18.2", "@sasjs/adapter": "^1.12.0",
"@sasjs/test-framework": "^1.4.0", "@sasjs/test-framework": "^1.4.0",
"@testing-library/jest-dom": "^4.2.4", "@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0", "@testing-library/react": "^9.5.0",

View File

@@ -0,0 +1,9 @@
import React from "react";
import { render } from "@testing-library/react";
import App from "./App";
test("renders learn react link", () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -3,12 +3,12 @@ import { TestSuite } from "@sasjs/test-framework";
const defaultConfig: SASjsConfig = { const defaultConfig: SASjsConfig = {
serverUrl: window.location.origin, serverUrl: window.location.origin,
pathSAS9: '/SASStoredProcess/do', pathSAS9: "/SASStoredProcess/do",
pathSASViya: '/SASJobExecution', pathSASViya: "/SASJobExecution",
appLoc: '/Public/seedapp', appLoc: "/Public/seedapp",
serverType: ServerType.SASViya, serverType: ServerType.SASViya,
debug: false, debug: true,
contextName: 'SAS Job Execution compute context', contextName: "SAS Job Execution compute context",
useComputeApi: false useComputeApi: false
}; };
@@ -57,7 +57,6 @@ export const basicTests = (
}, },
assertion: (sasjsInstance: SASjs) => { assertion: (sasjsInstance: SASjs) => {
const sasjsConfig = sasjsInstance.getSasjsConfig(); const sasjsConfig = sasjsInstance.getSasjsConfig();
return ( return (
sasjsConfig.serverUrl === defaultConfig.serverUrl && sasjsConfig.serverUrl === defaultConfig.serverUrl &&
sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 && sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 &&

View File

@@ -88,7 +88,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
return adapter.request("common/sendArr", data).catch((e) => e); return adapter.request("common/sendArr", data).catch((e) => e);
}, },
assertion: (error: any) => { assertion: (error: any) => {
return !!error && !!error.error && !!error.error.message; return !!error && !!error.body && !!error.body.message;
} }
}, },
{ {
@@ -185,7 +185,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
}; };
return adapter.request("common/sendObj", invalidData).catch((e) => e); return adapter.request("common/sendObj", invalidData).catch((e) => e);
}, },
assertion: (error: any) => !!error && !!error.error && !!error.error.message assertion: (error: any) => !!error && !!error.body && !!error.body.message
}, },
{ {
title: "Single string value", title: "Single string value",
@@ -219,7 +219,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
.catch((e) => e); .catch((e) => e);
}, },
assertion: (error: any) => { assertion: (error: any) => {
return !!error && !!error.error && !!error.error.message; return !!error && !!error.body && !!error.body.message;
} }
}, },
{ {

View File

@@ -23,24 +23,22 @@ export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
}, },
{ {
title: "Make error and capture log", title: "Make error and capture log",
description: "Should make an error and capture log, in the same time it is testing if debug override is working", description: "Should make an error and capture log",
test: async () => { test: async () => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
adapter adapter
.request("common/makeErr", data, {debug: true}) .request("common/makeErr", data)
.then((res) => { .then((res) => {
//no action here, this request must throw error //no action here, this request must throw error
}) })
.catch((err) => { .catch((err) => {
let sasRequests = adapter.getSasRequests(); let sasRequests = adapter.getSasRequests();
let makeErrRequest: any = let makeErrRequest =
sasRequests.find((req) => sasRequests.find((req) =>
req.serviceLink.includes("makeErr") req.serviceLink.includes("makeErr")
) || null; ) || null;
if (!makeErrRequest) resolve(false) resolve(!!makeErrRequest);
resolve(!!(makeErrRequest.logFile && makeErrRequest.logFile.length > 0));
}); });
}); });
}, },

View File

@@ -17,8 +17,7 @@ import {
CsrfToken, CsrfToken,
EditContextInput, EditContextInput,
ErrorResponse, ErrorResponse,
JobDefinition, JobDefinition
PollOptions
} from './types' } from './types'
import { formatDataForRequest } from './utils/formatDataForRequest' import { formatDataForRequest } from './utils/formatDataForRequest'
import { SessionManager } from './SessionManager' import { SessionManager } from './SessionManager'
@@ -155,7 +154,6 @@ export class SASViyaApiClient {
context.name, context.name,
accessToken, accessToken,
null, null,
false,
true, true,
true true
).catch((err) => err) ).catch((err) => err)
@@ -166,27 +164,30 @@ export class SASViyaApiClient {
for (const promise of promises) results.push(await promise()) for (const promise of promises) results.push(await promise())
results.forEach((result: any, index: number) => { results.forEach((result: any, index: number) => {
if (result && result.log) { if (result && result.error && result.error.details) {
try { try {
const resultParsed = result.log const resultParsed = result.error.details
let sysUserId = ''
const sysUserIdLog = resultParsed if (resultParsed && resultParsed.body) {
.split('\n') let sysUserId = ''
.find((line: string) => line.startsWith('SYSUSERID='))
if (sysUserIdLog) { const sysUserIdLog = resultParsed.body
sysUserId = sysUserIdLog.replace('SYSUSERID=', '') .split('\n')
.find((line: string) => line.startsWith('SYSUSERID='))
executableContexts.push({ if (sysUserIdLog) {
createdBy: contextsList[index].createdBy, sysUserId = sysUserIdLog.replace('SYSUSERID=', '')
id: contextsList[index].id,
name: contextsList[index].name, executableContexts.push({
version: contextsList[index].version, createdBy: contextsList[index].createdBy,
attributes: { id: contextsList[index].id,
sysUserId name: contextsList[index].name,
} version: contextsList[index].version,
}) attributes: {
sysUserId
}
})
}
} }
} catch (error) { } catch (error) {
throw error throw error
@@ -425,11 +426,10 @@ export class SASViyaApiClient {
* @param linesOfCode - an array of code lines to execute. * @param linesOfCode - an array of code lines to execute.
* @param contextName - the context to execute the code in. * @param contextName - the context to execute the code in.
* @param accessToken - an access token for an authorized user. * @param accessToken - an access token for an authorized user.
* @param sessionId - optional session ID to reuse.
* @param data - execution data. * @param data - execution data.
* @param debug - when set to true, the log will be returned. * @param debug - when set to true, the log will be returned.
* @param expectWebout - when set to true, the automatic _webout fileref will be checked for content, and that content returned. This fileref is used when the Job contains a SASjs web request (as opposed to executing arbitrary SAS code). * @param expectWebout - when set to true, the automatic _webout fileref will be checked for content, and that content returned. This fileref is used when the Job contains a SASjs web request (as opposed to executing arbitrary SAS code).
* @param waitForResult - when set to true, function will return the session
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async executeScript( public async executeScript(
jobPath: string, jobPath: string,
@@ -437,10 +437,8 @@ export class SASViyaApiClient {
contextName: string, contextName: string,
accessToken?: string, accessToken?: string,
data = null, data = null,
debug: boolean = false,
expectWebout = false, expectWebout = false,
waitForResult = true, waitForResult = true
pollOptions?: PollOptions
): Promise<any> { ): Promise<any> {
try { try {
const headers: any = { const headers: any = {
@@ -469,7 +467,7 @@ export class SASViyaApiClient {
_OMITTEXTLOG: true _OMITTEXTLOG: true
} }
if (debug) { if (this.debug) {
jobArguments['_OMITTEXTLOG'] = false jobArguments['_OMITTEXTLOG'] = false
jobArguments['_OMITSESSIONRESULTS'] = false jobArguments['_OMITSESSIONRESULTS'] = false
jobArguments['_DEBUG'] = 131 jobArguments['_DEBUG'] = 131
@@ -537,7 +535,7 @@ export class SASViyaApiClient {
return session return session
} }
if (debug) { if (this.debug) {
console.log(`Job has been submitted for '${fileName}'.`) console.log(`Job has been submitted for '${fileName}'.`)
console.log( console.log(
`You can monitor the job progress at '${this.serverUrl}${ `You can monitor the job progress at '${this.serverUrl}${
@@ -546,12 +544,7 @@ export class SASViyaApiClient {
) )
} }
const jobStatus = await this.pollJobState( const jobStatus = await this.pollJobState(postedJob, etag, accessToken)
postedJob,
etag,
accessToken,
pollOptions
)
const { result: currentJob } = await this.request<Job>( const { result: currentJob } = await this.request<Job>(
`${this.serverUrl}/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`, `${this.serverUrl}/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
@@ -565,7 +558,7 @@ export class SASViyaApiClient {
const logLink = currentJob.links.find((l) => l.rel === 'log') const logLink = currentJob.links.find((l) => l.rel === 'log')
if (debug && logLink) { if (this.debug && logLink) {
log = await this.request<any>( log = await this.request<any>(
`${this.serverUrl}${logLink.href}/content?limit=10000`, `${this.serverUrl}${logLink.href}/content?limit=10000`,
{ {
@@ -581,7 +574,7 @@ export class SASViyaApiClient {
} }
if (jobStatus === 'failed' || jobStatus === 'error') { if (jobStatus === 'failed' || jobStatus === 'error') {
return Promise.reject({ job: currentJob, log }) return Promise.reject({ error: currentJob.error, log })
} }
let resultLink let resultLink
@@ -613,10 +606,12 @@ export class SASViyaApiClient {
throw err throw err
}) })
return Promise.reject({ return Promise.reject(
status: 500, new ErrorResponse('Job execution failed.', {
log: log status: 500,
}) body: log
})
)
} }
} }
return { return {
@@ -640,7 +635,6 @@ export class SASViyaApiClient {
contextName, contextName,
accessToken, accessToken,
data, data,
debug,
false, false,
true true
) )
@@ -957,17 +951,14 @@ export class SASViyaApiClient {
* @param accessToken - an optional access token for an authorized user. * @param accessToken - an optional access token for an authorized user.
* @param waitForResult - a boolean indicating if the function should wait for a result. * @param waitForResult - a boolean indicating if the function should wait for a result.
* @param expectWebout - a boolean indicating whether to expect a _webout response. * @param expectWebout - a boolean indicating whether to expect a _webout response.
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async executeComputeJob( public async executeComputeJob(
sasJob: string, sasJob: string,
contextName: string, contextName: string,
debug?: boolean,
data?: any, data?: any,
accessToken?: string, accessToken?: string,
waitForResult = true, waitForResult = true,
expectWebout = false, expectWebout = false
pollOptions?: PollOptions
) { ) {
if (isRelativePath(sasJob) && !this.rootFolderName) { if (isRelativePath(sasJob) && !this.rootFolderName) {
throw new Error( throw new Error(
@@ -1050,10 +1041,8 @@ export class SASViyaApiClient {
contextName, contextName,
accessToken, accessToken,
data, data,
debug,
expectWebout, expectWebout,
waitForResult, waitForResult
pollOptions
) )
} }
@@ -1246,21 +1235,13 @@ export class SASViyaApiClient {
this.folderMap.set(path, itemsAtRoot) this.folderMap.set(path, itemsAtRoot)
} }
// REFACTOR: set default value for 'pollOptions' attribute
private async pollJobState( private async pollJobState(
postedJob: any, postedJob: any,
etag: string | null, etag: string | null,
accessToken?: string, accessToken?: string
pollOptions?: PollOptions
) { ) {
let POLL_INTERVAL = 100 const MAX_POLL_COUNT = 1000
let MAX_POLL_COUNT = 1000 const POLL_INTERVAL = 100
if (pollOptions) {
POLL_INTERVAL = pollOptions.POLL_INTERVAL || POLL_INTERVAL
MAX_POLL_COUNT = pollOptions.MAX_POLL_COUNT || MAX_POLL_COUNT
}
let postedJobState = '' let postedJobState = ''
let pollCount = 0 let pollCount = 0
const headers: any = { const headers: any = {

View File

@@ -32,8 +32,7 @@ import {
CsrfToken, CsrfToken,
UploadFile, UploadFile,
EditContextInput, EditContextInput,
ErrorResponse, ErrorResponse
PollOptions
} from './types' } from './types'
import { SASViyaApiClient } from './SASViyaApiClient' import { SASViyaApiClient } from './SASViyaApiClient'
import { SAS9ApiClient } from './SAS9ApiClient' import { SAS9ApiClient } from './SAS9ApiClient'
@@ -219,8 +218,7 @@ export default class SASjs {
linesOfCode, linesOfCode,
contextName, contextName,
accessToken, accessToken,
null, null
this.sasjsConfig.debug
) )
} }
@@ -713,15 +711,13 @@ export default class SASjs {
* @param accessToken - a valid access token that is authorised to execute compute jobs. * @param accessToken - a valid access token that is authorised to execute compute jobs.
* The access token is not required when the user is authenticated via the browser. * The access token is not required when the user is authenticated via the browser.
* @param waitForResult - a boolean that indicates whether the function needs to wait for execution to complete. * @param waitForResult - a boolean that indicates whether the function needs to wait for execution to complete.
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async startComputeJob( public async startComputeJob(
sasJob: string, sasJob: string,
data: any, data: any,
config: any = {}, config: any = {},
accessToken?: string, accessToken?: string,
waitForResult?: boolean, waitForResult?: boolean
pollOptions?: PollOptions
) { ) {
config = { config = {
...this.sasjsConfig, ...this.sasjsConfig,
@@ -738,12 +734,10 @@ export default class SASjs {
return this.sasViyaApiClient?.executeComputeJob( return this.sasViyaApiClient?.executeComputeJob(
sasJob, sasJob,
config.contextName, config.contextName,
config.debug,
data, data,
accessToken, accessToken,
!!waitForResult, !!waitForResult,
false, false
pollOptions
) )
} }
@@ -772,7 +766,6 @@ export default class SASjs {
?.executeComputeJob( ?.executeComputeJob(
sasJob, sasJob,
config.contextName, config.contextName,
config.debug,
data, data,
accessToken, accessToken,
waitForResult, waitForResult,
@@ -902,8 +895,8 @@ export default class SASjs {
return responseJson return responseJson
}) })
.catch(async (response) => { .catch(async (e) => {
if (needsRetry(JSON.stringify(response))) { if (needsRetry(JSON.stringify(e))) {
if (this.retryCountJeseApi < requestRetryLimit) { if (this.retryCountJeseApi < requestRetryLimit) {
let retryResponse = await this.executeJobViaJesApi( let retryResponse = await this.executeJobViaJesApi(
sasJob, sasJob,
@@ -924,11 +917,11 @@ export default class SASjs {
} }
} }
if (response?.log) { if (e?.log) {
this.appendSasjsRequest(response.log, sasJob, null) this.appendSasjsRequest(e.log, sasJob, null)
} }
if (response.toString().includes('Job was not found')) { if (e.toString().includes('Job was not found')) {
reject( reject(
new ErrorResponse('Service not found on the server.', { new ErrorResponse('Service not found on the server.', {
sasJob: sasJob sasJob: sasJob
@@ -936,7 +929,7 @@ export default class SASjs {
) )
} }
reject(new ErrorResponse('Job execution failed.', response)) reject(new ErrorResponse('Job execution failed.', e))
}) })
) )
} }

View File

@@ -0,0 +1,38 @@
import dotenv from 'dotenv'
import { SessionManager } from '../SessionManager'
import { CsrfToken } from '../types'
describe('SessionManager', () => {
const setCsrfToken = jest
.fn()
.mockImplementation((csrfToken: CsrfToken) => console.log(csrfToken))
beforeAll(() => {
dotenv.config()
})
it('should instantiate', () => {
const sessionManager = new SessionManager(
'http://test-server.com',
'test context',
setCsrfToken
)
expect(sessionManager).toBeInstanceOf(SessionManager)
expect(sessionManager.debug).toBeFalsy()
expect((sessionManager as any).serverUrl).toEqual('http://test-server.com')
expect((sessionManager as any).contextName).toEqual('test context')
})
it('should set the debug flag', () => {
const sessionManager = new SessionManager(
'http://test-server.com',
'test context',
setCsrfToken
)
sessionManager.debug = true
expect(sessionManager.debug).toBeTruthy()
})
})

View File

@@ -1,4 +0,0 @@
export interface PollOptions {
MAX_POLL_COUNT?: number
POLL_INTERVAL?: number
}

View File

@@ -12,4 +12,3 @@ export * from './SASjsWaitingRequest'
export * from './ServerType' export * from './ServerType'
export * from './Session' export * from './Session'
export * from './UploadFile' export * from './UploadFile'
export * from './PollOptions'

View File

@@ -47,7 +47,6 @@ const browserConfig = {
const nodeConfig = { const nodeConfig = {
...browserConfig, ...browserConfig,
target: 'node', target: 'node',
entry: './node/index.ts',
output: { output: {
...browserConfig.output, ...browserConfig.output,
path: path.resolve(__dirname, 'build', 'node') path: path.resolve(__dirname, 'build', 'node')