Skip to content

Integrate with the automated API testing framework #552

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

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ lib-cov
coverage
*.lcov

# Newman tests
newman

# nyc test coverage
.nyc_output

Expand Down
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ To be able to change and test `taas-es-processor` locally you can follow the nex
| `npm run build` | Build source code for production run into `dist` folder. |
| `npm run start` | Start app in the production mode from prebuilt `dist` folder. |
| `npm run dev` | Start app in the development mode using `nodemon`. |
| `npm run start:test` | Start app in the test mode. |
| `npm run test` | Run tests. |
| `npm run init-db` | Initializes Database. |
| `npm run create-index` | Create Elasticsearch indexes. Use `-- --force` flag to skip confirmation |
Expand All @@ -222,6 +223,9 @@ To be able to change and test `taas-es-processor` locally you can follow the nex
| `npm run migrate:undo` | Revert most recent migration. |
| `npm run demo-payment-scheduler` | Create 1000 Work Periods Payment records in with status "scheduled" and various "amount" |
| `npm run emsi-mapping` | mapping EMSI tags to topcoder skills |
| `npm run mock-api` | Starts the mock api |
| `npm test:newman` | Starts E2E tests with newman |
| `npm test:newman:clear` | Clears the data produced during E2E tests |

## Import and Export data

Expand Down Expand Up @@ -306,9 +310,73 @@ The following parameters can be set in the config file or via env variables:

## Testing

### Unit Tests

- Run `npm run test` to execute unit tests
- Run `npm run cov` to execute unit tests and generate coverage report.

### E2E Postman Tests

1. In the `taas-apis` root directory create `.env` file with the next environment variables.

```bash
# Auth0 config
AUTH_SECRET=
AUTH0_URL=
AUTH0_AUDIENCE=
AUTH0_AUDIENCE_UBAHN=
AUTH0_CLIENT_ID=
AUTH0_CLIENT_SECRET=
AUTH_V2_URL=
AUTH_V2_CLIENT_ID=
AUTH_V3_URL=
# Following configs are used to generate tokens.
ADMIN_CREDENTIALS_USERNAME=
ADMIN_CREDENTIALS_PASSWORD=
MANAGER_CREDENTIALS_USERNAME=
MANAGER_CREDENTIALS_PASSWORD=
COPILOT_CREDENTIALS_USERNAME=
COPILOT_CREDENTIALS_PASSWORD=
USER_CREDENTIALS_USERNAME=
USER_CREDENTIALS_PASSWORD=
# Locally deployed services
ES_HOST=http://localhost:9200
DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres
BUSAPI_URL=http://localhost:8002/v5
MOCK_API_PORT=4000
API_BASE_URL=http://localhost:3000
TC_API=http://localhost:4000/v5
TOPCODER_USERS_API=http://localhost:4000/v3/users
TOPCODER_MEMBERS_API=http://localhost:4000/v3/members
```
1. Install npm dependencies
```bash
npm install
```
1. Start services and mock api and make sure taas-es-processor started properly by viewing logs.

```bash
npm run services:up
npm run mock-api
```
1. Start taas-api in test mode
```bash
npm run start:test
```
1. Create Database tables and Elasticsearch indexes
```bash
npm run init-db
npm run create-index
```
1. Run tests
```bash
npm run test:newman
```
1. Clear test data produced during tests
```bash
npm run test:newman:clear
```

## 📋 Code Guidelines

### General Requirements
Expand Down
26 changes: 21 additions & 5 deletions config/test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
module.exports = {
LOG_LEVEL: process.env.LOG_LEVEL || 'info',
AUTH0_URL: 'http://example.com',
AUTH0_AUDIENCE: 'http://example.com',
AUTH0_AUDIENCE_UBAHN: 'http://example.com',
AUTH0_CLIENT_ID: 'fake_id',
AUTH0_CLIENT_SECRET: 'fake_secret'
AUTH_V2_URL: process.env.AUTH_V2_URL,
AUTH_V2_CLIENT_ID: process.env.AUTH_V2_CLIENT_ID,
AUTH_V3_URL: process.env.AUTH_V3_URL,
MOCK_API_PORT: process.env.MOCK_API_PORT || 4000,
ADMIN_CREDENTIALS_USERNAME: process.env.ADMIN_CREDENTIALS_USERNAME,
ADMIN_CREDENTIALS_PASSWORD: process.env.ADMIN_CREDENTIALS_PASSWORD,
MANAGER_CREDENTIALS_USERNAME: process.env.MANAGER_CREDENTIALS_USERNAME,
MANAGER_CREDENTIALS_PASSWORD: process.env.MANAGER_CREDENTIALS_PASSWORD,
COPILOT_CREDENTIALS_USERNAME: process.env.COPILOT_CREDENTIALS_USERNAME,
COPILOT_CREDENTIALS_PASSWORD: process.env.COPILOT_CREDENTIALS_PASSWORD,
USER_CREDENTIALS_USERNAME: process.env.USER_CREDENTIALS_USERNAME,
USER_CREDENTIALS_PASSWORD: process.env.USER_CREDENTIALS_PASSWORD,
WAIT_TIME: 6000,
AUTOMATED_TESTING_REPORTERS_FORMAT: process.env.AUTOMATED_TESTING_REPORTERS_FORMAT
? process.env.AUTOMATED_TESTING_REPORTERS_FORMAT.split(',')
: ['cli', 'html'],
AUTOMATED_TESTING_NAME_PREFIX: process.env.AUTOMATED_TESTING_NAME_PREFIX || 'POSTMANE2E-',
API_BASE_URL: process.env.API_BASE_URL || 'http://localhost:3000',
TC_API: process.env.TC_API || 'http://localhost:4000/v5',
TOPCODER_USERS_API: process.env.TOPCODER_USERS_API || 'http://localhost:4000/v3/users',
TOPCODER_MEMBERS_API: process.env.TOPCODER_MEMBERS_API || 'http://localhost:4000/v3/members'
}
26 changes: 26 additions & 0 deletions env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

export AUTH_SECRET=""
export AUTH0_URL=https://topcoder-dev.auth0.com/oauth/token
export AUTH0_AUDIENCE=https://m2m.topcoder-dev.com/
export AUTH0_AUDIENCE_UBAHN=https://u-bahn.topcoder.com
export AUTH0_CLIENT_ID=
export AUTH0_CLIENT_SECRET=
export BUSAPI_URL=http://localhost:8002/v5
export AUTH_V2_URL=https://topcoder-dev.auth0.com/oauth/ro
export AUTH_V2_CLIENT_ID=
export AUTH_V3_URL=https://api.topcoder-dev.com/v3/authorizations
export ADMIN_CREDENTIALS_USERNAME=jcori
export ADMIN_CREDENTIALS_PASSWORD=
export MANAGER_CREDENTIALS_USERNAME=TonyJ
export MANAGER_CREDENTIALS_PASSWORD=
export COPILOT_CREDENTIALS_USERNAME=TCConnCopilot
export COPILOT_CREDENTIALS_PASSWORD=
export USER_CREDENTIALS_USERNAME=isbilir
export USER_CREDENTIALS_PASSWORD=
export ES_HOST=http://localhost:9200
export DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres
export MOCK_API_PORT=4000
export API_BASE_URL=http://localhost:3000
export TC_API=http://localhost:4000/v5
export TOPCODER_USERS_API=http://localhost:4000/v3/users
export TOPCODER_MEMBERS_API=http://localhost:4000/v3/members
133 changes: 133 additions & 0 deletions mock-api/mock-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* The mock APIs.
*/

const config = require('config')
const express = require('express')
const cors = require('cors')
const logger = require('../src/common/logger')
const _ = require('lodash')

const skills = [{ name: 'EJB', id: '23e00d92-207a-4b5b-b3c9-4c5662644941' },
{ name: 'Dropwizard', id: '7d076384-ccf6-4e43-a45d-1b24b1e624aa' },
{ name: 'NGINX', id: 'cbac57a3-7180-4316-8769-73af64893158' },
{ name: 'Machine Learning', id: 'a2b4bc11-c641-4a19-9eb7-33980378f82e' },
{ name: 'Force.com', id: '94eae221-1158-4aa9-a6a4-50ecb0bbb8b6' },
{ name: 'Database', id: '2742759c-d0f9-4456-9482-e558aa960969' },
{ name: 'Winforms', id: 'b81859b6-4c50-45d8-afcb-71b35d16ea1e' },
{ name: 'User Interface (Ui)', id: '17b61c7a-98dc-498d-ba8d-c52b6677d73c' },
{ name: 'Photoshop', id: '30d01540-ebed-46b6-88e7-4c210de63862' },
{ name: 'Docker', id: 'bd417c10-d81a-45b6-85a9-d79efe86b9bb' },
{ name: '.NET', id: '4fce6ced-3610-443c-92eb-3f6d76b34f5c' }]

const projects = [

{ id: 111, name: 'Project-111', invites: 1, members: [{ userId: 40158994 }, { userId: 88774634 }] },
{ id: 112, name: 'Project-112', invites: 1, members: [{ userId: 40158994 }, { userId: 88774634 }] },
{ id: 113, name: 'Project-113', invites: 1, members: [{ userId: 40158994 }, { userId: 88774634 }] },
{ id: 222, name: 'Project-222', invites: 1, members: [] }
]

const app = express()
app.set('port', config.MOCK_API_PORT || 4000)
app.use(cors())
app.use(express.json())
app.use((req, res, next) => {
logger.info({ component: 'Mock Api', message: `${req.method} ${req.url}` })
next()
})

app.get('/v5/projects', (req, res) => {
let results = _.cloneDeep(projects)
if (req.query.name) {
results = _.filter(results, ['name', req.query.name])
}
res.status(200).json(results)
})

app.get('/v5/projects/:projectId', (req, res) => {
const project = _.find(projects, project => project.id.toString() === req.params.projectId)
if (project) {
res.json(project)
} else {
res.status(404).end()
}
})

app.post('/v5/projects/:projectId/members', (req, res) => {
res.status(200).json(req.body)
})

app.get('/v5/projects/:projectId/members', (req, res) => {
const project = _.find(projects, project => project.id.toString() === req.params.projectId)
res.status(200).json(project.members)
})

app.delete('/v5/projects/:projectId/members/:memberId', (req, res) => {
const project = _.find(projects, project => project.id.toString() === req.params.projectId)
const member = _.find(project.members, member => member.userId.toString() === req.params.memberId)
if (member) {
res.status(204).end()
} else { res.status(404).end() }
})

app.get('/v5/projects/:projectId/invites', (req, res) => {
const project = _.find(projects, project => project.id.toString() === req.params.projectId)
res.status(200).json({ invites: project.invites })
})

app.get('/v5/skills/:skillId', (req, res) => {
const foundSkill = _.find(skills, ['id', req.params.skillId])
if (foundSkill) {
res.status(200).json(foundSkill)
} else {
res.status(404).end()
}
})

app.get('/v5/skills', (req, res) => {
res.status(200).json(skills)
})

app.get('/v5/users', (req, res) => {
res.status(200).json([{ id: '00000000-0000-0000-0000-000000000000' }])
})

app.get('/v5/users/:userId', (req, res) => {
if (_.includes(['99999999-9999-9999-9999-999999999999'], req.params.userId)) {
res.status(404).end()
} else {
res.status(200).json({ id: req.params.userId, userId: req.params.userId, handle: 'userHandle', firstName: 'firstName', lastName: 'lastName' })
}
})

app.get('/v5/members/:userHandle', (req, res) => {
res.status(200).json({ email: 'test@gmail.com', handle: req.params.userHandle })
})

app.get('/v5/members', (req, res) => {
res.status(200).json([{ handleLower: 'userhandle' }])
})

app.get('/v3/users', (req, res) => {
res.status(200).json({ result: { content: [{ email: 'test@gmail.com', firstName: 'firstName', lastName: 'lastName', handle: 'userhandle', id: 1 }] } })
})

app.get('/v3/members/_search', (req, res) => {
res.status(200).json({ result: { content: [{ email: 'test@gmail.com', firstName: 'firstName', lastName: 'lastName', handle: 'userhandle', userId: 1 }] } })
})

app.use((req, res) => {
res.status(404).json({ error: 'route not found' })
})

app.use((err, req, res, next) => {
logger.logFullError(err, { component: 'Mock Api', signature: `${req.method}_${req.url}` })
res.status(500).json({
error: err.message
})
})

app.listen(app.get('port'), '0.0.0.0', () => {
logger.info({ component: 'Mock Api', message: `Mock Api listening on port ${app.get('port')}` })
})
Loading