Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add context api tests #28

Merged
merged 7 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Default Build & Test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run tests
run: npm run lint && npm run test
46 changes: 28 additions & 18 deletions forge/context-driver/memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ module.exports = {
value
})
} catch (err) {
if (err.type === 'TypeError') {
values.push({
key
})
if (err.code === 'INVALID_EXPR') {
throw err
}
values.push({
key
})
}
})
return values
Expand All @@ -51,37 +52,46 @@ module.exports = {
return []
}
} catch (eee) {
console.log(eee)
return []
}
},
delete: async function (projectId, scope) {
delete store[projectId][scope]
if (store[projectId]?.[scope]) {
delete store[projectId][scope]
}
},
clean: async function (projectId, ids) {
const keys = Object.keys(store[projectId])
clean: async function (projectId, activeIds) {
activeIds = activeIds || []
const keys = Object.keys(store[projectId] || {})
if (keys.includes('global')) {
keys.splice(keys.indexOf('global'), 1)
}
if (keys.length === 0) {
return
}
const flows = []
for (const id in ids) {
if (keys.includes(ids[id])) {
flows.push(ids[id])
ids.splice(id, 1)
keys.splice(keys.indexOf(ids[id]), 1)
const ids = []
for (let idx = 0; idx < activeIds.length; idx++) {
const id = activeIds[idx]
const keyIdx = keys.indexOf(id)
if (keyIdx >= 0) {
flows.push(id)
keys.splice(keyIdx, 1)
} else {
ids.push(id)
}
}

for (const key in keys) {
delete store[projectId][keys[key]]
for (let idx = 0; idx < keys.length; idx++) {
const key = keys[idx]
if (store[projectId]?.[key]) {
delete store[projectId][key]
}
}

for (const flowId in flows) {
const flow = flows[flowId]
const nodes = Object.keys(store[projectId][flow].nodes)
for (let idx = 0; idx < flows.length; idx++) {
const flow = flows[idx]
const nodes = Object.keys(store[projectId]?.[flow]?.nodes || {}) || []
for (const nodeId in nodes) {
const node = nodes[nodeId]
if (!ids.includes(node)) {
Expand Down
4 changes: 3 additions & 1 deletion test/unit/drivers/localfs_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ describe('localfs driver', function () {
home: 'var',
driver: {
type: 'localfs',
root: 'tmp'
options: {
root: 'tmp'
}
}
}, {
teamId,
Expand Down
4 changes: 3 additions & 1 deletion test/unit/drivers/memory_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ describe('memory driver', function () {
home: 'var',
driver: {
type: 'memory',
root: 'tmp'
options: {
root: 'tmp'
}
}
}, {
teamId,
Expand Down
111 changes: 67 additions & 44 deletions test/unit/auth_spec.js → test/unit/routes/auth_spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
const should = require('should') // eslint-disable-line
const setup = require('./setup')
const setup = require('../setup')

describe('@flowforge file-server', async function () {
describe('@flowforge file-server', function () {
let app, authServer
before(async function () {
app = await setup.setupApp()
app = await setup.setupApp({
port: 4001,
base_url: 'http://localhost:4002'
})
authServer = setup.authServer({
port: 4002,
authConfig: [
{ token: 'test-token-1', projectId: 'test-project-1' },
{ token: 'test-token-2', projectId: 'test-project-2' }
Expand Down Expand Up @@ -48,17 +52,16 @@ describe('@flowforge file-server', async function () {
should(response.statusCode).eql(401)
})

// TODO: Enable once context in added to file-server
// it('Should return 200 for authenticated request', async function () {
// const response = await app.inject({
// method: 'GET',
// url: '/v1/context/test-project-1/global/keys',
// headers: {
// authorization: 'Bearer test-token-1'
// }
// })
// should(response.statusCode).eql(200)
// })
it('Should return 200 for authenticated request', async function () {
const response = await app.inject({
method: 'GET',
url: '/v1/context/test-project-1/global/keys',
headers: {
authorization: 'Bearer test-token-1'
}
})
should(response.statusCode).eql(200)
})

it('Should return 401 for missing token', async function () {
const response = await app.inject({
Expand All @@ -71,37 +74,35 @@ describe('@flowforge file-server', async function () {
should(response.statusCode).eql(401)
})

// TODO: Enable once context in added to file-server
// it('Should return 401 for bad token', async function () {
// const response = await app.inject({
// method: 'GET',
// url: '/v1/context/test-project-1/global/keys',
// headers: {
// authorization: 'Bearer this is not a valid token'
// }
// })
// should(response.statusCode).eql(401)
// })
it('Should return 401 for bad token when accessing context', async function () {
const response = await app.inject({
method: 'GET',
url: '/v1/context/test-project-1/global/keys',
headers: {
authorization: 'Bearer this is not a valid token'
}
})
should(response.statusCode).eql(401)
})

// TODO: Enable once context in added to file-server
// it('Should return 401 for wrong after token is authenticated and cached', async function () {
// const response1 = await app.inject({
// method: 'GET',
// url: '/v1/context/test-project-1/global/keys',
// headers: {
// authorization: 'Bearer test-token-1'
// }
// })
// should(response1.statusCode).eql(200)
// const response2 = await app.inject({
// method: 'GET',
// url: '/v1/context/test-project-2/global/keys',
// headers: {
// authorization: 'Bearer test-token-1'
// }
// })
// should(response2.statusCode).eql(401)
// })
it('Should return 401 when trying to use cached to access context on another project', async function () {
const response1 = await app.inject({
method: 'GET',
url: '/v1/context/test-project-1/global/keys',
headers: {
authorization: 'Bearer test-token-1'
}
})
should(response1.statusCode).eql(200)
const response2 = await app.inject({
method: 'GET',
url: '/v1/context/test-project-2/global/keys',
headers: {
authorization: 'Bearer test-token-1'
}
})
should(response2.statusCode).eql(401)
})

it('Should return 401 for bad token accessing files', async function () {
const response = await app.inject({
Expand All @@ -125,6 +126,28 @@ describe('@flowforge file-server', async function () {
should(response.statusCode).eql(404)
})

it('Cached token should not permit access to other projects context', async function () {
// 1st, perform a legal operation to prove it is working & to cache the token
const response1 = await app.inject({
method: 'GET',
url: '/v1/context/test-project-1/global/keys',
headers: {
authorization: 'Bearer test-token-1'
}
})
should(response1.statusCode).eql(200)

// now try to use cached token to access a different project
const response2 = await app.inject({
method: 'GET',
url: '/v1/context/test-project-2/global/keys',
headers: {
authorization: 'Bearer test-token-1'
}
})
should(response2.statusCode).eql(401) // 401 because cached token is not valid for this project
})

it('Cached token should not permit access to other projects files', async function () {
const response = await app.inject({
method: 'POST',
Expand Down
Loading