1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-06 20:10:05 +00:00

Compare commits

..

21 Commits

Author SHA1 Message Date
Yury Shkoda
784bd20ee0 Merge pull request #814 from sasjs/issue-811-fixed
Issue 811 fixed
2023-07-05 10:27:04 +03:00
Yury Shkoda
61db1e0609 test: fixed unit tests 2023-06-23 18:04:48 +03:00
Yury Shkoda
5c589a6af3 chore: reverted dev changes to build.yml 2023-06-23 17:52:46 +03:00
Yury Shkoda
275cd6dbd3 chore: debugging 2023-06-23 17:20:16 +03:00
Yury Shkoda
d874e07889 fix(file-uploader): fixed parsing response for SASJS 2023-06-23 16:37:25 +03:00
Yury Shkoda
1648cf28d5 chore: Merge branch 'master' of github.com:sasjs/adapter into issue-811-fixed 2023-06-23 15:26:01 +03:00
a4aaeba31c fix: file upload with sasjs server type, json not parsed 2023-06-22 12:48:40 +02:00
Yury Shkoda
6bf68a315c fix(sasjs-utils): fixed imports 2023-06-22 13:37:07 +03:00
Allan Bowe
c0f78d0c1e fix: updating example.html to use v4 of the adapter 2023-06-22 08:56:32 +01:00
Yury Shkoda
e0aebc169f chore: debugging 2023-06-21 18:28:39 +03:00
Yury Shkoda
9a50e5cb63 chore: debugging 2023-06-21 18:16:20 +03:00
Yury Shkoda
a51923dad7 chore: debugging 2023-06-21 18:01:21 +03:00
Yury Shkoda
9aee77f0e3 chore: debugging 2023-06-21 17:44:24 +03:00
Yury Shkoda
c32d037063 chore: debugging 2023-06-21 17:34:16 +03:00
Yury Shkoda
94f7492c31 chore: debugging 2023-06-21 17:19:13 +03:00
Yury Shkoda
d29e0a0f57 chore(sasjs-tests): bumped node-sass 2023-06-21 16:36:22 +03:00
Yury Shkoda
8d7cc11db5 chore(sasjs-tests): bumped node-sass 2023-06-21 16:35:33 +03:00
Yury Shkoda
28e9d1cc6b test(get-token): covered getTokenRequestErrorPrefix 2023-06-21 16:34:26 +03:00
Yury Shkoda
375cec48ca feat(get-token): improved error prefix 2023-06-21 16:33:45 +03:00
7d826685f7 Merge pull request #813 from sasjs/sasjs-job-execute
fix: issue with parsing json in sasjs job executor
2023-06-15 16:08:08 +02:00
f42f6bca00 fix: issue with parsing json in sasjs job executor 2023-06-14 15:08:11 +02:00
26 changed files with 2758 additions and 17138 deletions

View File

@@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
node-version: [lts/fermium]
node-version: [lts/hydrogen]
steps:
- uses: actions/checkout@v2
@@ -22,17 +22,17 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: npm
# - name: Check npm audit
# run: npm audit --production --audit-level=low
- 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: Check code style
run: npm run lint
# - name: Run unit tests
# run: npm test
- name: Run unit tests
run: npm test
- name: Build Package
run: npm run package:lib
@@ -72,27 +72,19 @@ jobs:
npm install -g replace-in-files-cli
cd sasjs-tests
replace-in-files --regex='"@sasjs/adapter".*' --replacement='"@sasjs/adapter":"latest",' ./package.json
npm i --legacy-peer-deps
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_DEV }}",' ./public/config.json
replace-in-files --regex='"password".*' --replacement='"password":"${{ secrets.SASJS_PASSWORD_DEV }}",' ./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 update:adapter
pm2 start --name sasjs-test npm -- start
cat ./public/config.json
cat ../cypress.json
- name: Sleep for 10 seconds
uses: jakejarvis/wait-action@master
with:
time: '10s'
- name: Run cypress on sasjs
run: |
ss -lntu
replace-in-files --regex='"sasjsTestsUrl".*' --replacement='"sasjsTestsUrl":"http://localhost:3000",' ./cypress.json
replace-in-files --regex='"username".*' --replacement='"username":"${{ secrets.SASJS_USERNAME_DEV }}",' ./cypress.json
replace-in-files --regex='"password".*' --replacement='"password":"${{ secrets.SASJS_PASSWORD_DEV }}",' ./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-tests/sasjs-cypress-run.sh ${{ secrets.MATRIX_TOKEN }} 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

View File

@@ -5,9 +5,6 @@ const testingFinishTimeout = Cypress.env('testingFinishTimeout')
context('sasjs-tests', function () {
this.beforeAll(() => {
cy.task('log', 'beforeAll')
cy.task('log', `sasjsTestsUrl: ${sasjsTestsUrl}`)
cy.visit(sasjsTestsUrl)
})
@@ -16,66 +13,35 @@ context('sasjs-tests', function () {
})
it('Should have all tests successfull', (done) => {
cy.task('log', `Should have all tests successfull`)
cy.get('body').then(($body) => {
cy.task('log', `22`)
cy.wait(1000).then(() => {
const startButton = $body.find(
'.ui.massive.icon.primary.left.labeled.button'
)[0]
// ui massive icon primary left labeled button
cy.task('log', `startButton: ${startButton}`)
if (
!startButton ||
(startButton && !Cypress.dom.isVisible(startButton))
) {
cy.task('log', `34`)
cy.task('log', `username: ${username}`)
cy.task('log', `password: ${password}`)
const userNameInput = cy.get('input[placeholder="User Name"]')
const passwordInput = cy.get('input[placeholder="Password"]')
cy.task('log', `userNameInput: ${userNameInput}`)
cy.task('log', `passwordInput: ${passwordInput}`)
cy.get('input[placeholder="User Name"]').type(username)
cy.get('input[placeholder="Password"]').type(password)
const submitBtn = cy.get('.submit-button')
cy.task('log', `submitBtn: ${submitBtn}`)
cy.get('.submit-button').click()
}
cy.get('input[placeholder="User Name"]', { timeout: 40000 })
.should('not.exist')
.then(() => {
cy.task('log', `46`)
cy.get('.ui.massive.icon.primary.left.labeled.button')
.click()
.then(() => {
cy.task('log', `50`)
const loadingButton = $body.find(
'.ui.massive.loading.primary.button'
)[0]
cy.task('log', `loadingButton: ${loadingButton}`)
cy.get('.ui.massive.loading.primary.button', {
timeout: testingFinishTimeout
})
.should('not.exist')
.then(() => {
cy.task('log', `56`)
cy.get('span.icon.failed')
.should('not.exist')
.then(() => {
cy.task('log', `60`)
done()
})
})
@@ -85,46 +51,46 @@ context('sasjs-tests', function () {
})
})
// it('Should have all tests successfull with debug on', (done) => {
// cy.get('body').then(($body) => {
// cy.wait(1000).then(() => {
// const startButton = $body.find(
// '.ui.massive.icon.primary.left.labeled.button'
// )[0]
it('Should have all tests successfull with debug on', (done) => {
cy.get('body').then(($body) => {
cy.wait(1000).then(() => {
const startButton = $body.find(
'.ui.massive.icon.primary.left.labeled.button'
)[0]
// if (
// !startButton ||
// (startButton && !Cypress.dom.isVisible(startButton))
// ) {
// cy.get('input[placeholder="User Name"]').type(username)
// cy.get('input[placeholder="Password"]').type(password)
// cy.get('.submit-button').click()
// }
if (
!startButton ||
(startButton && !Cypress.dom.isVisible(startButton))
) {
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()
// })
// })
// })
// })
// })
// })
// })
// })
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()
})
})
})
})
})
})
})
})
})

View File

@@ -39,11 +39,4 @@ module.exports = (on, config) => {
return launchOptions
}
})
on('task', {
log(message) {
console.log(message)
return null
}
})
}

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/combine/npm/chart.js@2.9.3,npm/jquery@3.5.1,npm/@sasjs/adapter@1"></script>
<script src="https://cdn.jsdelivr.net/combine/npm/chart.js@2.9.3,npm/jquery@3.5.1,npm/@sasjs/adapter@4"></script>
<script>
var sasJs = new SASjs.default({
appLoc: "/Public/app/readme"

File diff suppressed because it is too large Load Diff

View File

@@ -4,15 +4,14 @@
"homepage": ".",
"private": true,
"dependencies": {
"@sasjs/adapter": "4.3.5",
"@sasjs/test-framework": "1.5.7",
"@types/jest": "^26.0.20",
"@types/node": "^14.14.41",
"@types/react": "^17.0.1",
"@types/react-dom": "^17.0.0",
"@types/react": "^16.0.1",
"@types/react-dom": "^16.0.0",
"@types/react-router-dom": "^5.1.7",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react": "^16.0.1",
"react-dom": "^16.0.1",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"typescript": "^4.1.3"
@@ -22,7 +21,7 @@
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"update:adapter": "cd .. && npm run package:lib && cd sasjs-tests && npm i ../build/sasjs-adapter-5.0.0.tgz --legacy-peer-deps",
"update:adapter": "cd .. && npm run package:lib && cd sasjs-tests && npm i ../build/sasjs-adapter-5.0.0.tgz",
"deploy:tests": "rsync -avhe ssh ./build/* --delete $SSH_ACCOUNT:$DEPLOY_PATH || npm run deploy:tests-win",
"deploy:tests-win": "scp %DEPLOY_PATH% ./build/*",
"deploy": "npm run update:adapter && npm run build && npm run deploy:tests"
@@ -43,6 +42,6 @@
]
},
"devDependencies": {
"node-sass": "7.0.3"
"node-sass": "9.0.0"
}
}

View File

@@ -2,7 +2,7 @@
"userName": "",
"password": "",
"sasJsConfig": {
"serverUrl": "https://sas9.4gl.io",
"serverUrl": "",
"appLoc": "/Public/app/adapter-tests/services",
"serverType": "SASJS",
"debug": false,

View File

@@ -1,9 +1,7 @@
{
"$schema": "https://cli.sasjs.io/sasjsconfig-schema.json",
"serviceConfig": {
"serviceFolders": [
"sasjs/common"
]
"serviceFolders": ["sasjs/common"]
},
"defaultTarget": "4gl",
"targets": [
@@ -28,4 +26,4 @@
}
}
]
}
}

View File

@@ -11,7 +11,7 @@ const Login = (): ReactElement<{}> => {
const handleSubmit = useCallback(
(e: any) => {
e.preventDefault()
appContext.adapter.logIn(username, password).then((res: any) => {
appContext.adapter.logIn(username, password).then((res) => {
appContext.setIsLoggedIn(res.isLoggedIn)
})
},

View File

@@ -9,7 +9,7 @@ import * as formatDataModule from '../../../utils/formatDataForRequest'
import * as fetchLogsModule from '../../../utils/fetchLogByChunks'
import { PollOptions } from '../../../types'
import { ComputeJobExecutionError, NotFoundError } from '../../../types/errors'
import { Logger, LogLevel } from '@sasjs/utils'
import { Logger, LogLevel } from '@sasjs/utils/logger'
const sessionManager = new (<jest.Mock<SessionManager>>SessionManager)()
const requestClient = new (<jest.Mock<RequestClient>>RequestClient)()

View File

@@ -1,4 +1,4 @@
import { Logger, LogLevel } from '@sasjs/utils'
import { Logger, LogLevel } from '@sasjs/utils/logger'
import { RequestClient } from '../../../request/RequestClient'
import { mockAuthConfig, mockJob } from './mockResponses'
import { pollJobState } from '../pollJobState'

View File

@@ -1,4 +1,4 @@
import { Logger, LogLevel } from '@sasjs/utils'
import { Logger, LogLevel } from '@sasjs/utils/logger'
import { RequestClient } from '../../../request/RequestClient'
import * as fetchLogsModule from '../../../utils/fetchLogByChunks'
import * as writeStreamModule from '../writeStream'

View File

@@ -5,7 +5,7 @@ import {
fileExists,
readFile,
deleteFile
} from '@sasjs/utils'
} from '@sasjs/utils/file'
describe('writeStream', () => {
const filename = 'test.txt'

View File

@@ -1,7 +1,7 @@
import { prefixMessage } from '@sasjs/utils/error'
import { RequestClient } from '../request/RequestClient'
import { getTokenRequestErrorPrefix } from './getTokenRequestErrorPrefix'
import { ServerType } from '@sasjs/utils'
import { ServerType } from '@sasjs/utils/types'
/**
* Exchanges the auth code for an access token for the given client.

View File

@@ -4,7 +4,6 @@ import { RequestClient } from '../request/RequestClient'
import { CertificateError } from '../types/errors'
import { getTokenRequestErrorPrefix } from './getTokenRequestErrorPrefix'
// TODO: update func docs
/**
* Exchange the auth code for access / refresh tokens for the given client / secret pair.
* @param requestClient - the pre-configured HTTP request client.
@@ -31,10 +30,11 @@ export async function getAccessTokenForViya(
Authorization: 'Basic ' + token,
Accept: 'application/json'
}
const dataJson = {
const dataJson = new URLSearchParams({
grant_type: 'authorization_code',
code: authCode
}
})
const data = new URLSearchParams(dataJson)
const authResponse = await requestClient

View File

@@ -1,7 +1,7 @@
import { prefixMessage } from '@sasjs/utils/error'
import { RequestClient } from '../request/RequestClient'
import { getTokenRequestErrorPrefix } from './getTokenRequestErrorPrefix'
import { ServerType } from '@sasjs/utils'
import { ServerType } from '@sasjs/utils/types'
/**
* Exchanges the refresh token for an access token for the given client.

View File

@@ -1,4 +1,4 @@
import { AuthConfig } from '@sasjs/utils'
import { AuthConfig } from '@sasjs/utils/types'
import { generateToken, mockSasjsAuthResponse } from './mockResponses'
import { RequestClient } from '../../request/RequestClient'
import { getAccessTokenForSasjs } from '../getAccessTokenForSasjs'

View File

@@ -1,4 +1,4 @@
import { AuthConfig } from '@sasjs/utils'
import { AuthConfig } from '@sasjs/utils/types'
import * as NodeFormData from 'form-data'
import { generateToken, mockAuthResponse } from './mockResponses'
import { RequestClient } from '../../request/RequestClient'

View File

@@ -1,4 +1,4 @@
import { AuthConfig } from '@sasjs/utils'
import { AuthConfig } from '@sasjs/utils/types'
import * as refreshTokensModule from '../refreshTokensForViya'
import { generateToken, mockAuthResponse } from './mockResponses'
import { getTokens } from '../getTokens'

View File

@@ -1,4 +1,4 @@
import { ServerType } from '@sasjs/utils'
import { ServerType } from '@sasjs/utils/types'
import { generateToken, mockAuthResponse } from './mockResponses'
import { RequestClient } from '../../request/RequestClient'
import { refreshTokensForSasjs } from '../refreshTokensForSasjs'

View File

@@ -1,4 +1,4 @@
import { AuthConfig, ServerType } from '@sasjs/utils'
import { AuthConfig, ServerType } from '@sasjs/utils/types'
import * as NodeFormData from 'form-data'
import { generateToken, mockAuthResponse } from './mockResponses'
import { RequestClient } from '../../request/RequestClient'

View File

@@ -93,15 +93,24 @@ export class FileUploader extends BaseJobExecutor {
this.requestClient,
config.serverUrl
)
break
case ServerType.Sas9:
jsonResponse =
typeof res.result === 'string'
? parseWeboutResponse(res.result, uploadUrl)
: res.result
break
case ServerType.Sasjs:
jsonResponse =
typeof res.result === 'string'
? getValidJson(res.result)
: res.result
break
}
} else if (this.serverType !== ServerType.Sasjs) {
} else {
jsonResponse =
typeof res.result === 'string'
? getValidJson(res.result)

View File

@@ -93,8 +93,10 @@ export class SasjsJobExecutor extends BaseJobExecutor {
)
}
const { result } = res.result
if (result && result.trim()) res.result = getValidJson(result)
const { result } = res
if (result && typeof result === 'string' && result.trim())
res.result = getValidJson(result)
this.requestClient!.appendRequest(res, sasJob, config.debug)

View File

@@ -2,7 +2,7 @@ import * as pem from 'pem'
import * as http from 'http'
import * as https from 'https'
import { app, mockedAuthResponse } from './SAS_server_app'
import { ServerType } from '@sasjs/utils'
import { ServerType } from '@sasjs/utils/types'
import SASjs from '../SASjs'
import * as axiosModules from '../utils/createAxiosInstance'
import {
@@ -213,7 +213,7 @@ describe('RequestClient - Self Signed Server', () => {
serverType: ServerType.SasViya
})
const expectedError = 'self signed certificate'
const expectedError = 'self-signed certificate'
const rejectionErrorMessage = await adapterWithoutCertificate
.getAccessToken('clientId', 'clientSecret', 'authCode')

View File

@@ -2,7 +2,7 @@ import { SessionManager } from '../SessionManager'
import { RequestClient } from '../request/RequestClient'
import * as dotenv from 'dotenv'
import axios from 'axios'
import { Logger, LogLevel } from '@sasjs/utils'
import { Logger, LogLevel } from '@sasjs/utils/logger'
import { Session, Context } from '../types'
jest.mock('axios')

View File

@@ -7,7 +7,7 @@ describe('RootFolderNotFoundError', () => {
const error = new RootFolderNotFoundError(
'/myProject',
'https://analytium.co.uk',
'https://sas.4gl.io',
token
)
@@ -19,7 +19,7 @@ describe('RootFolderNotFoundError', () => {
it('when access token is not provided, error message should not contain scopes', () => {
const error = new RootFolderNotFoundError(
'/myProject',
'https://analytium.co.uk'
'https://sas.4gl.io'
)
expect(error).toBeInstanceOf(RootFolderNotFoundError)
@@ -30,7 +30,7 @@ describe('RootFolderNotFoundError', () => {
it('should include the folder path and SASDrive URL in the message', () => {
const folderPath = '/myProject'
const serverUrl = 'https://analytium.co.uk'
const serverUrl = 'https://sas.4gl.io'
const error = new RootFolderNotFoundError(folderPath, serverUrl)
expect(error).toBeInstanceOf(RootFolderNotFoundError)