mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-11 09:24:35 +00:00
30
.github/vpn/config.ovpn
vendored
Normal file
30
.github/vpn/config.ovpn
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
cipher AES-256-CBC
|
||||
setenv FORWARD_COMPATIBLE 1
|
||||
client
|
||||
server-poll-timeout 4
|
||||
nobind
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 443 tcp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
remote vpn.analytium.co.uk 1194 udp
|
||||
dev tun
|
||||
dev-type tun
|
||||
ns-cert-type server
|
||||
setenv opt tls-version-min 1.0 or-highest
|
||||
reneg-sec 604800
|
||||
sndbuf 0
|
||||
rcvbuf 0
|
||||
# NOTE: LZO commands are pushed by the Access Server at connect time.
|
||||
# NOTE: The below line doesn't disable LZO.
|
||||
comp-lzo no
|
||||
verb 3
|
||||
setenv PUSH_PEER_INFO
|
||||
|
||||
ca ca.crt
|
||||
cert user.crt
|
||||
key user.key
|
||||
tls-auth tls.key 1
|
||||
67
.github/workflows/build.yml
vendored
67
.github/workflows/build.yml
vendored
@@ -4,7 +4,6 @@
|
||||
name: SASjs Build
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
@@ -22,19 +21,77 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
|
||||
- name: Check npm audit
|
||||
run: npm audit --production --audit-level=low
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Check code style
|
||||
run: npm run lint
|
||||
|
||||
- name: Run unit tests
|
||||
run: npm test
|
||||
- name: Generate coverage report
|
||||
uses: artiomtr/jest-coverage-report-action@v2.0-rc.2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Package
|
||||
run: npm run package:lib
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- name: Install SSH Key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
with:
|
||||
key: ${{ secrets.DCGITLAB_KEY }}
|
||||
known_hosts: 'placeholder'
|
||||
|
||||
- name: Write VPN Files
|
||||
run: |
|
||||
echo "$CA_CRT" > .github/vpn/ca.crt
|
||||
echo "$USER_CRT" > .github/vpn/user.crt
|
||||
echo "$USER_KEY" > .github/vpn/user.key
|
||||
echo "$TLS_KEY" > .github/vpn/tls.key
|
||||
shell: bash
|
||||
env:
|
||||
CA_CRT: ${{ secrets.CA_CRT}}
|
||||
USER_CRT: ${{ secrets.USER_CRT }}
|
||||
USER_KEY: ${{ secrets.USER_KEY }}
|
||||
TLS_KEY: ${{ secrets.TLS_KEY }}
|
||||
|
||||
- name: Install Open VPN
|
||||
run: |
|
||||
sudo apt install apt-transport-https
|
||||
sudo wget https://swupdate.openvpn.net/repos/openvpn-repo-pkg-key.pub
|
||||
sudo apt-key add openvpn-repo-pkg-key.pub
|
||||
sudo wget -O /etc/apt/sources.list.d/openvpn3.list https://swupdate.openvpn.net/community/openvpn3/repos/openvpn3-focal.list
|
||||
sudo apt update
|
||||
sudo apt install openvpn3=16~beta+focal
|
||||
|
||||
- name: Start Open VPN 3
|
||||
run: openvpn3 session-start --config .github/vpn/config.ovpn
|
||||
|
||||
- name: Deploy sasjs-tests
|
||||
run: |
|
||||
npm install -g replace-in-files-cli
|
||||
cd sasjs-tests
|
||||
replace-in-files --regex='"@sasjs/adapter".*' --replacement='"@sasjs/adapter":"latest",' ./package.json
|
||||
npm i
|
||||
replace-in-files --regex='"serverUrl".*' --replacement='"serverUrl":"${{ secrets.SASJS_SERVER_URL }}",' ./public/config.json
|
||||
replace-in-files --regex='"userName".*' --replacement='"userName":"${{ secrets.SASJS_USERNAME }}",' ./public/config.json
|
||||
replace-in-files --regex='"password".*' --replacement='"password":"${{ secrets.SASJS_PASSWORD }}",' ./public/config.json
|
||||
replace-in-files --regex='"serverType".*' --replacement='"serverType":"SASJS",' ./public/config.json
|
||||
npm run update:adapter && npm run build
|
||||
scp -o stricthostkeychecking=no -r ./build/* ${{ secrets.DCGITLAB_DEPLOY_PATH_VIYA }}
|
||||
|
||||
- name: Run cypress on sasjs
|
||||
run: |
|
||||
replace-in-files --regex='"sasjsTestsUrl".*' --replacement='"sasjsTestsUrl":"${{ secrets.SASJS_TEST_URL_VIYA }}",' ./cypress.json
|
||||
replace-in-files --regex='"username".*' --replacement='"username":"${{ secrets.SASJS_USERNAME }}",' ./cypress.json
|
||||
replace-in-files --regex='"password".*' --replacement='"password":"${{ secrets.SASJS_PASSWORD }}",' ./cypress.json
|
||||
sh ./sasjs-cypress-run.sh ${{ secrets.DISCORD_WEBHOOK }} https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}
|
||||
|
||||
# For some reason if coverage report action is run before other commands, those commands can't access the directories and files on which they depend on
|
||||
- name: Generate coverage report
|
||||
uses: artiomtr/jest-coverage-report-action@v2.0-rc.2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
4
.github/workflows/npmpublish.yml
vendored
4
.github/workflows/npmpublish.yml
vendored
@@ -14,12 +14,16 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Check code style
|
||||
run: npm run lint
|
||||
|
||||
- name: Build Project
|
||||
run: npm run build
|
||||
|
||||
- name: Semantic Release
|
||||
uses: cycjimmy/semantic-release-action@v2
|
||||
env:
|
||||
|
||||
10
.npmignore
10
.npmignore
@@ -4,3 +4,13 @@ docs/
|
||||
*.md
|
||||
*.spec.ts
|
||||
.all-contributorsrc
|
||||
cypress/
|
||||
.gitpod.yml
|
||||
.prettierrc
|
||||
cypress.json
|
||||
jest.config.js
|
||||
sasjs-cypress-run.sh
|
||||
tsconfig.json
|
||||
tslint.json
|
||||
typedoc.json
|
||||
webpack.config.js
|
||||
|
||||
@@ -16,5 +16,5 @@ No PR (that involves a non-trivial code change) should be merged, unless all ite
|
||||
|
||||
|
||||
- [ ] All `sasjs-cli` 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)).
|
||||
- (CI Runs this) All `sasjs-tests` are passing. If you want to run it manually (instructions available [here](https://github.com/sasjs/adapter/blob/master/sasjs-tests/README.md)).
|
||||
- [ ] [Data Controller](https://datacontroller.io) builds and is functional on both SAS 9 and Viya
|
||||
|
||||
11
cypress.json
Normal file
11
cypress.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"chromeWebSecurity": false,
|
||||
"defaultCommandTimeout": 20000,
|
||||
"env": {
|
||||
"sasjsTestsUrl": "",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"screenshotOnRunFailure": false,
|
||||
"testingFinishTimeout": 600000
|
||||
}
|
||||
}
|
||||
78
cypress/integration/sasjs.tests.ts
Normal file
78
cypress/integration/sasjs.tests.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
const sasjsTestsUrl = Cypress.env('sasjsTestsUrl')
|
||||
const username = Cypress.env('username')
|
||||
const password = Cypress.env('password')
|
||||
const testingFinishTimeout = Cypress.env('testingFinishTimeout')
|
||||
|
||||
context('sasjs-tests', function () {
|
||||
this.beforeAll(() => {
|
||||
cy.visit(sasjsTestsUrl)
|
||||
})
|
||||
|
||||
this.beforeEach(() => {
|
||||
cy.reload()
|
||||
})
|
||||
|
||||
it('Should have all tests successfull', (done) => {
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('input[placeholder="User Name"]').length > 0) {
|
||||
cy.get('input[placeholder="User Name"]').type(username)
|
||||
cy.get('input[placeholder="Password"]').type(password)
|
||||
cy.get('.submit-button').click()
|
||||
}
|
||||
|
||||
cy.get('input[placeholder="User Name"]', { timeout: 40000 })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.ui.massive.icon.primary.left.labeled.button')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('.ui.massive.loading.primary.button', {
|
||||
timeout: testingFinishTimeout
|
||||
})
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('span.icon.failed')
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('Should have all tests successfull with debug on', (done) => {
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find('input[placeholder="User Name"]').length > 0) {
|
||||
cy.get('input[placeholder="User Name"]').type(username)
|
||||
cy.get('input[placeholder="Password"]').type(password)
|
||||
cy.get('.submit-button').click()
|
||||
}
|
||||
|
||||
cy.get('.ui.fitted.toggle.checkbox label')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('input[placeholder="User Name"]', { timeout: 40000 })
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('.ui.massive.icon.primary.left.labeled.button')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.get('.ui.massive.loading.primary.button', {
|
||||
timeout: testingFinishTimeout
|
||||
})
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
cy.get('span.icon.failed')
|
||||
.should('not.exist')
|
||||
.then(() => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
31
cypress/plugins/cy-ts-preprocessor.js
Normal file
31
cypress/plugins/cy-ts-preprocessor.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const wp = require('@cypress/webpack-preprocessor')
|
||||
|
||||
const webpackOptions = {
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loaders: ['ts-loader'],
|
||||
exclude: [/node_modules/]
|
||||
},
|
||||
{
|
||||
test: /\.(html|css)$/,
|
||||
loader: 'raw-loader',
|
||||
exclude: /\.async\.(html|css)$/
|
||||
},
|
||||
{
|
||||
test: /\.async\.(html|css)$/,
|
||||
loaders: ['file?name=[name].[hash].[ext]', 'extract']
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
const options = {
|
||||
webpackOptions
|
||||
}
|
||||
|
||||
module.exports = wp(options)
|
||||
42
cypress/plugins/index.js
Normal file
42
cypress/plugins/index.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
const wp = require('@cypress/webpack-preprocessor')
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
|
||||
const options = {
|
||||
webpackOptions: require('../webpack.config.js')
|
||||
}
|
||||
on('file:preprocessor', wp(options))
|
||||
|
||||
on('before:browser:launch', (browser = {}, launchOptions) => {
|
||||
if (browser.name === 'chrome') {
|
||||
launchOptions.args.push('--disable-site-isolation-trials')
|
||||
launchOptions.args.push('--auto-open-devtools-for-tabs')
|
||||
launchOptions.args.push('--aggressive-cache-discard')
|
||||
launchOptions.args.push('--disable-cache')
|
||||
launchOptions.args.push('--disable-application-cache')
|
||||
launchOptions.args.push('--disable-offline-load-stale-cache')
|
||||
launchOptions.args.push('--disk-cache-size=0')
|
||||
|
||||
return launchOptions
|
||||
}
|
||||
})
|
||||
}
|
||||
10
cypress/tsconfig.json
Normal file
10
cypress/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"baseUrl": "../node_modules",
|
||||
"target": "es6",
|
||||
"lib": ["es2019", "dom"],
|
||||
"types": ["cypress"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
23
cypress/webpack.config.js
Normal file
23
cypress/webpack.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: [/node_modules/],
|
||||
use: [
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
// skip typechecking for speed
|
||||
transpileOnly: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
9534
package-lock.json
generated
9534
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -8,15 +8,17 @@
|
||||
"build": "rimraf build && rimraf node && mkdir node && copyfiles -u 1 \"./src/**/*\" ./node && webpack && rimraf build/src && rimraf node",
|
||||
"package:lib": "npm run build && copyfiles ./package.json ./checkNodeVersion.js build && cd build && npm version \"5.0.0\" && npm pack",
|
||||
"publish:lib": "npm run build && cd build && npm publish",
|
||||
"lint:fix": "npx prettier --loglevel silent --write \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --write \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint": "npx prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --check \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint:silent": "npx prettier --loglevel silent --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --check \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint:fix": "npx prettier --loglevel silent --write \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --write \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --write \"cypress/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint": "npx prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --check \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --check \"cypress/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"lint:silent": "npx prettier --loglevel silent --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --check \"sasjs-tests/src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\" && npx prettier --loglevel silent --check \"cypress/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
||||
"test": "jest --silent --coverage",
|
||||
"prepublishOnly": "cp -r ./build/* . && rm -rf ./build",
|
||||
"postpublish": "git clean -fd",
|
||||
"semantic-release": "semantic-release",
|
||||
"typedoc": "node createTSDocs",
|
||||
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks && git config core.autocrlf false || true"
|
||||
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks && git config core.autocrlf false || true",
|
||||
"cypress": "cypress open",
|
||||
"cy:run": "cypress run"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -41,9 +43,13 @@
|
||||
},
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@cypress/webpack-preprocessor": "5.9.1",
|
||||
"@types/form-data": "2.5.0",
|
||||
"cypress": "7.7.0",
|
||||
"typedoc-neo-theme": "1.1.1",
|
||||
"typedoc-plugin-external-module-name": "4.0.6",
|
||||
"@types/axios": "0.14.0",
|
||||
"@types/express": "4.17.13",
|
||||
"@types/form-data": "2.5.0",
|
||||
"@types/jest": "27.4.0",
|
||||
"@types/mime": "2.0.3",
|
||||
"@types/pem": "1.9.6",
|
||||
|
||||
10
sasjs-cypress-run.sh
Executable file
10
sasjs-cypress-run.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
if npm run cy:run -- --spec "cypress/integration/sasjs.tests.ts" ; then
|
||||
echo "Cypress sasjs testing passed!"
|
||||
else
|
||||
curl -X POST --header "Content-Type:application/json" --data '{"username":"GitHub CI - Adapter SASJS-TESTS (FAIL)", "content":"Automated sasjs-tests failed on the @sasjs/adapter PR on following link.\n'$2'", "avatar_url":"https://i.ibb.co/Lpk7Xvq/error-outline.png"}' $1
|
||||
|
||||
echo "Cypress sasjs testing failed!"
|
||||
exit 1
|
||||
fi
|
||||
7666
sasjs-tests/package-lock.json
generated
7666
sasjs-tests/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ export const basicTests = (
|
||||
'Should fail on first attempt and should log the user in on second attempt',
|
||||
test: async () => {
|
||||
await adapter.logOut()
|
||||
await adapter.logIn('invalid', 'invalid')
|
||||
await adapter.logIn('invalid', 'invalid').catch((err: any) => {})
|
||||
return await adapter.logIn(userName, password)
|
||||
},
|
||||
assertion: (response: any) =>
|
||||
@@ -161,26 +161,17 @@ export const basicTests = (
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Request with extra attributes on JES approach',
|
||||
description:
|
||||
'Should complete successful request with extra attributes present in response',
|
||||
title: 'Web request',
|
||||
description: 'Should run the request with old web approach',
|
||||
test: async () => {
|
||||
const config: Partial<SASjsConfig> = {
|
||||
useComputeApi: false
|
||||
}
|
||||
|
||||
return await adapter.request(
|
||||
'common/sendArr',
|
||||
stringData,
|
||||
config,
|
||||
undefined,
|
||||
undefined,
|
||||
['file', 'data']
|
||||
)
|
||||
return await adapter.request('common/sendArr', stringData, config)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
const responseKeys: any = Object.keys(response)
|
||||
return responseKeys.includes('file') && responseKeys.includes('data')
|
||||
return response.table1[0][0] === stringData.table1[0].col1
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,9 +1,35 @@
|
||||
import SASjs from '@sasjs/adapter'
|
||||
import { TestSuite } from '@sasjs/test-framework'
|
||||
|
||||
const stringData: any = { table1: [{ col1: 'first col value' }] }
|
||||
|
||||
export const computeTests = (adapter: SASjs): TestSuite => ({
|
||||
name: 'Compute',
|
||||
tests: [
|
||||
{
|
||||
title: 'Compute API request',
|
||||
description: 'Should run the request with compute API approach',
|
||||
test: async () => {
|
||||
return await adapter.request('common/sendArr', stringData)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
return response.table1[0][0] === stringData.table1[0].col1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'JES API request',
|
||||
description: 'Should run the request with JES API approach',
|
||||
test: async () => {
|
||||
const config = {
|
||||
useComputeApi: false
|
||||
}
|
||||
|
||||
return await adapter.request('common/sendArr', stringData, config)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
return response.table1[0][0] === stringData.table1[0].col1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Start Compute Job - not waiting for result',
|
||||
description: 'Should start a compute job and return the session',
|
||||
|
||||
@@ -138,7 +138,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
|
||||
result =
|
||||
result &&
|
||||
res.table1[index][3] ===
|
||||
(multipleRowsWithNulls.table1[index].col4 || ' ')
|
||||
(multipleRowsWithNulls.table1[index].col4 || '')
|
||||
})
|
||||
return result
|
||||
}
|
||||
@@ -164,7 +164,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
|
||||
result =
|
||||
result &&
|
||||
res.table1[index][3] ===
|
||||
(multipleColumnsWithNulls.table1[index].col4 || ' ')
|
||||
(multipleColumnsWithNulls.table1[index].col4 || '')
|
||||
})
|
||||
return result
|
||||
}
|
||||
@@ -329,7 +329,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
|
||||
result =
|
||||
result &&
|
||||
res.table1[index].COL4 ===
|
||||
(multipleRowsWithNulls.table1[index].col4 || ' ')
|
||||
(multipleRowsWithNulls.table1[index].col4 || '')
|
||||
})
|
||||
return result
|
||||
}
|
||||
@@ -358,7 +358,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
|
||||
result =
|
||||
result &&
|
||||
res.table1[index].COL4 ===
|
||||
(multipleColumnsWithNulls.table1[index].col4 || ' ')
|
||||
(multipleColumnsWithNulls.table1[index].col4 || '')
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ const moreSpecialCharData: any = {
|
||||
]
|
||||
}
|
||||
|
||||
const stringData: any = { table1: [{ col1: 'first col value' }] }
|
||||
|
||||
const getWideData = () => {
|
||||
const cols: any = {}
|
||||
for (let i = 1; i <= 10000; i++) {
|
||||
@@ -269,6 +271,34 @@ export const specialCaseTests = (adapter: SASjs): TestSuite => ({
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Request with extra attributes on JES approach',
|
||||
description:
|
||||
'Should complete successful request with extra attributes present in response',
|
||||
test: async () => {
|
||||
if (adapter.getSasjsConfig().serverType !== 'SASVIYA')
|
||||
return Promise.resolve('skip')
|
||||
|
||||
const config = {
|
||||
useComputeApi: false
|
||||
}
|
||||
|
||||
return await adapter.request(
|
||||
'common/sendArr',
|
||||
stringData,
|
||||
config,
|
||||
undefined,
|
||||
undefined,
|
||||
['file', 'data']
|
||||
)
|
||||
},
|
||||
assertion: (response: any) => {
|
||||
if (response === 'skip') return true
|
||||
|
||||
const responseKeys: any = Object.keys(response)
|
||||
return responseKeys.includes('file') && responseKeys.includes('data')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Special missing values',
|
||||
description: 'Should support special missing values',
|
||||
|
||||
@@ -257,6 +257,12 @@ export class AuthManager {
|
||||
const isLoggedIn = loginResponse !== 'authErr'
|
||||
const userName = isLoggedIn ? this.extractUserName(loginResponse) : ''
|
||||
|
||||
if (!isLoggedIn) {
|
||||
//We will logout to make sure cookies are removed and login form is presented
|
||||
//Residue can happen in case of session expiration
|
||||
await this.logOut()
|
||||
}
|
||||
|
||||
return { isLoggedIn, userName }
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ export class WebJobExecutor extends BaseJobExecutor {
|
||||
if (jobUri.length > 0) {
|
||||
apiUrl += '&_job=' + jobUri
|
||||
/**
|
||||
* Using both _job and _program parameters will cause a conflict in the JES web app, as it’s not clear whether or not the server should make the extra fetch for the job uri.
|
||||
* Using both _job and _program parameters will cause a conflict in the JES web app, as it's not clear whether or not the server should make the extra fetch for the job uri.
|
||||
* To handle this, we add the extra underscore and recreate the _program variable in the SAS side of the SASjs adapter so it remains available for backend developers.
|
||||
*/
|
||||
apiUrl = apiUrl.replace('_program=', '__program=')
|
||||
@@ -169,13 +169,17 @@ export class WebJobExecutor extends BaseJobExecutor {
|
||||
? res.result.log.map((logLine: any) => logLine.line).join('\n')
|
||||
: res.result.log
|
||||
|
||||
const resObj =
|
||||
this.serverType === ServerType.Sasjs
|
||||
? {
|
||||
result: res.result._webout,
|
||||
log: parsedSasjsServerLog
|
||||
}
|
||||
: res
|
||||
const resObj = res
|
||||
|
||||
if (this.serverType === ServerType.Sasjs) {
|
||||
if (res.result._webout < 1)
|
||||
throw new JobExecutionError(
|
||||
0,
|
||||
'Job execution failed',
|
||||
parsedSasjsServerLog
|
||||
)
|
||||
}
|
||||
|
||||
this.requestClient!.appendRequest(resObj, sasJob, config.debug)
|
||||
|
||||
let jsonResponse = res.result
|
||||
|
||||
Reference in New Issue
Block a user