Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Integrate with the automated API testing framework #18

Open
wants to merge 1 commit into
base: develop
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
65 changes: 64 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
.env
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Newman tests
newman

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env*

# next.js build output
.next
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,27 @@ Configuration for the application is at `config/default.js` and `config/producti
- `KAFKA_ERROR_TOPIC`: The error topic at which bus api will publish any errors
- `KAFKA_MESSAGE_ORIGINATOR`: The originator value for the kafka messages
- `SKILLS_ERROR_TOPIC`: Kafka topic for report operation error
- `AUTOMATED_TESTING_NAME_PREFIX`:: the name prefix for every `Skill`/`Taxonomy` record

**NOTE** AUTH0 related configuration normally is shared on challenge forum.


Configuration for testing is at `config/test.js`, only add such new configurations different from `config/default.js`
- API_BASE_URL: the api base url
- API_VERSION: the api version
- WAIT_TIME: wait time used in test, default is 6000 or 6 seconds
- AUTH_V2_URL: The auth v2 url
- AUTH_V2_CLIENT_ID: The auth v2 client id
- AUTH_V3_URL: The auth v3 url
- ADMIN_CREDENTIALS_USERNAME: The user's username with admin role
- ADMIN_CREDENTIALS_PASSWORD: The user's password with admin role
- COPILOT_CREDENTIALS_USERNAME: The user's username with copilot role
- COPILOT_CREDENTIALS_PASSWORD: The user's password with copilot role
- USER_CREDENTIALS_USERNAME: The user's username with user role
- USER_CREDENTIALS_PASSWORD: The user's password with user role
- AUTOMATED_TESTING_REPORTERS_FORMAT: indicates reporters format. It is an array of the formats. e.g. `['html']` produces html format. `['cli', 'json', 'junit', 'html']` is the full format.
*For the details of the supported format, please refer to https://www.npmjs.com/package/newman#reporters*.

## DB and Elasticsearch In Docker
- Navigate to the directory `docker-pgsql-es` folder. Rename `sample.env` to `.env` and change any values if required.
- Run `docker-compose up -d` to have docker instances of pgsql and elasticsearch to use with the api
Expand Down Expand Up @@ -122,6 +140,8 @@ Setup your Postgresql DB and Elasticsearch instance and ensure that they are up
| `npm run delete-index` | Delete Elasticsearch indexes. Use `-- --force` flag to skip confirmation |
| `npm run generate:doc:permissions` | Generate [permissions.html](docs/permissions.html) |
| `npm run generate:doc:permissions:dev` | Generate [permissions.html](docs/permissions.html) on any changes (useful during development). |
| `npm run test:newman` | Run the postman E2E tests. |
| `npm run test:newman:clear` | Clear the testing data which is brought by the postman E2E tests. |

## JWT Authentication
Authentication is handled via Authorization (Bearer) token header field. Token is a JWT token.
Expand Down Expand Up @@ -173,3 +193,60 @@ These tokens have been signed with the secret `CLIENT_SECRET`. This secret shoul

- [permissions.html](docs/permissions.html) - the list of all permissions in Skills API.
- [swagger.yaml](docs/swagger.yaml) - the Swagger API Definition.

## Running tests

### Configuration
Test configuration is at `config/test.js`. You don't need to change them.

The following test parameters can be set in config file or in env variables:

- WAIT_TIME: wait time
- AUTH_V2_URL: The auth v2 url
- AUTH_V2_CLIENT_ID: The auth v2 client id
- AUTH_V3_URL: The auth v3 url
- ADMIN_CREDENTIALS_USERNAME: The user's username with admin role
- ADMIN_CREDENTIALS_PASSWORD: The user's password with admin role
- COPILOT_CREDENTIALS_USERNAME: The user's username with copilot role
- COPILOT_CREDENTIALS_PASSWORD: The user's password with copilot role
- USER_CREDENTIALS_USERNAME: The user's username with user role
- USER_CREDENTIALS_PASSWORD: The user's password with user role
- AUTOMATED_TESTING_REPORTERS_FORMAT: indicates reporters format. It is an array of the formats.

### Prepare

- Start local environment by running the `docker-compose up` from `docker-pgsql-es` folder. Make sure you have set the environment like `sample.env` form that folder.

### Running E2E tests with Postman

#### `Start` the app server before running e2e tests. You may need to set the env variables by calling `source env.sh` before calling `npm run test:newman`.

- Make sure the db and es are started
```bash
$ cd skills-api

# NOTE:
# if tables and data already exist, please run first

# $ npm run delete-data

# to drop data and tables

$ npm run create-db
$ npm run migrations up
```

To run postman e2e tests.

```bash
npm run test:newman
```

To clear the testing data from postman e2e tests.

```bash
npm run test:newman:clear
```

## Running tests in CI
- TBD
54 changes: 54 additions & 0 deletions Verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Topcoder Skills API

## E2E testing with Postman

You should be able to find the tests result from the command window of running `npm run test:newman` for each test case.

Below is a sample output result of finding resources by member.

```
skill-api

Iteration 1/3

❏ taxonomies / create taxonomy
↳ create taxonomy by admin
POST http://127.0.0.1:3001/api/1.0/taxonomies [200 OK, 449B, 84ms]
✓ Status code is 200

Iteration 2/3

↳ create taxonomy by admin
POST http://127.0.0.1:3001/api/1.0/taxonomies [200 OK, 447B, 34ms]
✓ Status code is 200

Iteration 3/3

↳ create taxonomy by admin
POST http://127.0.0.1:3001/api/1.0/taxonomies [200 OK, 404B, 33ms]
✓ Status code is 200

┌─────────────────────────┬───────────────────┬──────────────────┐
│ │ executed │ failed │
├─────────────────────────┼───────────────────┼──────────────────┤
│ iterations │ 3 │ 0 │
├─────────────────────────┼───────────────────┼──────────────────┤
│ requests │ 3 │ 0 │
├─────────────────────────┼───────────────────┼──────────────────┤
│ test-scripts │ 3 │ 0 │
├─────────────────────────┼───────────────────┼──────────────────┤
│ prerequest-scripts │ 3 │ 0 │
├─────────────────────────┼───────────────────┼──────────────────┤
│ assertions │ 3 │ 0 │
├─────────────────────────┴───────────────────┴──────────────────┤
│ total run duration: 273ms │
├────────────────────────────────────────────────────────────────┤
│ total data received: 496B (approx) │
├────────────────────────────────────────────────────────────────┤
│ average response time: 50ms [min: 33ms, max: 84ms, s.d.: 23ms] │
└────────────────────────────────────────────────────────────────┘
```

Then you can run `npm run test:newman:clear` to delete all testing data by above postman tests.
If 'socket hang up' appears while running the `npm run test:newman`. You can increase the `WAIT_TIME` from the `default/test.js`.
Then run `npm run test:newman:clear` before calling `npm run test:newman` again.
6 changes: 4 additions & 2 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = {
ES: {
HOST: process.env.ES_HOST || 'http://localhost:9200',
ES_REFRESH: process.env.ES_REFRESH || 'true',
ES_API_VERSION: process.env.ES_API_VERSION || "7.4",
ES_API_VERSION: process.env.ES_API_VERSION || '7.4',

ELASTICCLOUD: {
id: process.env.ELASTICCLOUD_ID,
Expand All @@ -59,5 +59,7 @@ module.exports = {
},
MAX_BATCH_SIZE: parseInt(process.env.MAX_BATCH_SIZE, 10) || 10000,
MAX_BULK_SIZE: parseInt(process.env.MAX_BULK_SIZE, 10) || 100
}
},

AUTOMATED_TESTING_NAME_PREFIX: process.env.AUTOMATED_TESTING_NAME_PREFIX || 'POSTMANE2E-'
}
19 changes: 19 additions & 0 deletions config/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* The configuration file.
*/

module.exports = {
API_BASE_URL: 'http://localhost:3001/api',
API_VERSION: '1.0',
WAIT_TIME: 6000,
AUTH_V2_URL: process.env.AUTH_V2_URL || 'https://topcoder-dev.auth0.com/oauth/ro',
AUTH_V2_CLIENT_ID: process.env.AUTH_V2_CLIENT_ID || '',
AUTH_V3_URL: process.env.AUTH_V3_URL || 'https://api.topcoder-dev.com/v3/authorizations',
ADMIN_CREDENTIALS_USERNAME: process.env.ADMIN_CREDENTIALS_USERNAME || '',
ADMIN_CREDENTIALS_PASSWORD: process.env.ADMIN_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 || '',
AUTOMATED_TESTING_REPORTERS_FORMAT: process.env.AUTOMATED_TESTING_REPORTERS_FORMAT || ['cli', 'html']
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"create-index": "node scripts/es/createIndex.js",
"delete-index": "node scripts/es/deleteIndex.js",
"generate:doc:permissions": "node scripts/permissions-doc",
"generate:doc:permissions:dev": "npx nodemon --watch scripts/permissions-doc --watch src --ext js,jsx,hbs --exec npm run generate:doc:permissions"
"generate:doc:permissions:dev": "npx nodemon --watch scripts/permissions-doc --watch src --ext js,jsx,hbs --exec npm run generate:doc:permissions",
"test:newman": "NODE_ENV=test node test/postman/newman.js",
"test:newman:clear": "NODE_ENV=test node test/postman/clearTestData.js"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -48,7 +50,8 @@
},
"devDependencies": {
"nodemon": "^2.0.12",
"standard": "^14.3.0"
"standard": "^14.3.0",
"tc-api-testing-lib": "topcoder-platform/api-automated-testing.git"
},
"engines": {
"node": "12.x"
Expand Down
23 changes: 22 additions & 1 deletion src/common/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ const config = require('config')
const busApi = require('@topcoder-platform/topcoder-bus-api-wrapper')
const busApiClient = busApi(_.pick(config, ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', 'AUTH0_CLIENT_ID',
'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', 'KAFKA_ERROR_TOPIC', 'AUTH0_PROXY_SERVER_URL']))
const request = require('superagent')
const m2mAuth = require('tc-core-library-js').auth.m2m
const m2m = m2mAuth(_.pick(config, ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', 'AUTH0_PROXY_SERVER_URL']))

/**
* get auth user handle or id
Expand Down Expand Up @@ -130,11 +133,29 @@ async function publishError (topic, payload, action) {
await busApiClient.postEvent(message)
}

/**
* Uses superagent to proxy post request
* @param {String} url the url
* @param {Object} data the query parameters, optional
* @returns {Object} the response
*/
async function postRequest (url, data) {
const m2mToken = await m2m.getMachineToken(config.AUTH0_CLIENT_ID, config.AUTH0_CLIENT_SECRET)

return request
.post(url)
.set('Authorization', `Bearer ${m2mToken}`)
.set('Content-Type', 'application/json')
.set('Accept', 'application/json')
.send(data)
}

module.exports = {
getAuthUser,
injectSearchMeta,
setLastModifiedHeader,
getControllerMethods,
omitAuditFields,
publishError
publishError,
postRequest
}
19 changes: 19 additions & 0 deletions src/modules/cleanup/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Controller for cleaning up test data
*/

const service = require('./service')

/**
* Get all resources of a challenge
* @param {Object} req the request
* @param {Object} res the response
*/
async function cleanUpTestData (req, res) {
await service.cleanUpTestData()
res.sendStatus(200)
}

module.exports = {
cleanUpTestData
}
15 changes: 15 additions & 0 deletions src/modules/cleanup/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* The Clean up data routes.
*/

const Controller = require('./controller')

module.exports = {
'/skills/internal/jobs/clean': {
post: {
method: Controller.cleanUpTestData,
auth: 'jwt',
permission: 'skill.delete'
}
}
}
Loading