Skip to content

Commit

Permalink
Add functional test and linter
Browse files Browse the repository at this point in the history
  • Loading branch information
Aschen committed Dec 31, 2019
1 parent 3d8dde9 commit 3aa20df
Show file tree
Hide file tree
Showing 30 changed files with 1,809 additions and 256 deletions.
33 changes: 33 additions & 0 deletions .github/issue_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!--- If you have a question about Kuzzle usage, please use Stackoverflow instead >
<!--- Post here and we will respond https://stackoverflow.com/questions/ask >
<!--- Github issues are limited to bugs and features requests >
<!--- Provide a general summary of the issue in the Title above -->

## Expected Behavior
<!--- Tell us what should happen -->

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->

## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->

## Steps to Reproduce
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. -->
<!--- Please try to provide scripts or commands to reproduce the bug -->
<!--- Use https://gist.github.com/ to host code snippets -->
1.
2.
3.
4.

## Context (Environment)
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
<!--- Include Node.js version, SDK version, Kuzzle version, ElasticSearch version, ... -->
Kuzzle version:
Node.js version:
SDK version:
45 changes: 45 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!--
This template is optional.
It simply serves to provide a guide to allow a better review of pull requests.
-->

<!--
IMPORTANT
Don't forget to add the corresponding "changelog:xxx" label to your PR.
This is part of our release process in order to generate the change log.
-->


## What does this PR do?
<!-- Please fill this section -->

<!--
Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context.
List any dependencies that are required for this change.
-->

### How should this be manually tested?

<!--
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce.
Please also list any relevant details for your test configuration
-->
- Step 1 :
- Step 2 :
- Step 3 :
...

### Other changes

<!--
Please describe here all changes not directly linked to the main issue, but made because of it.
For instance: issues spotted during this PR and fixed on-the-fly, dependencies update, and so on
-->

### Boyscout

<!--
Describe here minor improvements in the code base and not directly linked to the main changes:
typos fixes, better/new comments, small code simplification, new debug messages, and so on.
-->
38 changes: 38 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
jobs:
include:
- stage: Tests
name: "Kourou Lint"
language: node_js
node_js: 12
cache:
directories:
- ~/.npm
- ~/.cache
- node_modules # NPM packages

install:
- cd $TRAVIS_BUILD_DIR/backend
- npm install --silent --unsafe-perm
- npm install --silent --unsafe-perm --only=dev

script:
- npm run test:lint

- stage: Tests
name: "Kourou Functional Tests"
language: node_js
node_js: 12
cache:
directories:
- ~/.npm
- ~/.cache
- node_modules # NPM packages

install:
- cd $TRAVIS_BUILD_DIR/backend
- npm install --silent --unsafe-perm
- npm install --silent --unsafe-perm --only=dev

script:
- bash features/run-kuzzle-stack.sh
- npm run test:functional
9 changes: 9 additions & 0 deletions features/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"rules": {
"func-names": 0,
"no-invalid-this": 0,
"no-console": 0,
"no-new": 0,
"new-cap": 0
}
}
42 changes: 42 additions & 0 deletions features/ApiKey.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Feature: Api Key Management

@security
Scenario: Create an API Key
When I run the command "api-key:create" with:
| --user | "gordon" |
| --description | "Test api key" |
| --id | "gordon-key" |
Then I successfully call the route "security":"searchApiKeys" with args:
| userId | "gordon" |
And I should receive a "hits" array of objects matching:
| _id | _source.description | _source.userId |
| "gordon-key" | "Test api key" | "gordon" |

@security
Scenario: Delete an API Key
Given I successfully call the route "security":"createApiKey" with args:
| _id | "gordon-key" |
| userId | "gordon" |
| body.description | "Test api key" |
When I run the command "api-key:delete" with:
| --user | "gordon" |
| --id | "gordon-key" |
Then I successfully call the route "security":"searchApiKeys" with args:
| userId | "gordon" |
And I should receive a empty "hits" array

@security
Scenario: Search for API key
Given I successfully call the route "security":"createApiKey" with args:
| _id | "gordon-key" |
| userId | "gordon" |
| body.description | "Test api key" |
And I successfully call the route "security":"createApiKey" with args:
| _id | "gordon-key-2" |
| userId | "gordon" |
| body.description | "Other api key" |
When I run the command "api-key:search" with:
| --user | "gordon" |
| --filter | "Test" |
Then I should match stdout with "gordon-key"
And I should not match stdout with "gordon-key-2"
36 changes: 36 additions & 0 deletions features/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: '3'

services:
kuzzle:
image: kuzzleio/plugin-dev:2
command: /run.sh
volumes:
- "./run.sh:/run.sh"
cap_add:
- SYS_PTRACE
ulimits:
nofile: 65536
sysctls:
- net.core.somaxconn=8192
depends_on:
- redis
- elasticsearch
ports:
- "9229:9229"
- "7512:7512"
environment:
- kuzzle_services__storageEngine__client__node=http://elasticsearch:9200
- kuzzle_services__internalCache__node__host=redis
- kuzzle_services__memoryStorage__node__host=redis
- NODE_ENV=development
- DEBUG=kuzzle:*,-kuzzle:entry-point:protocols:websocket

redis:
image: redis:5

elasticsearch:
image: kuzzleio/elasticsearch:7
ports:
- "9200:9200"
ulimits:
nofile: 65536
30 changes: 30 additions & 0 deletions features/docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh

set -e

log () {
echo "[$(date --rfc-3339 seconds)] - $1"
}

elastic_host=${kuzzle_services__db__client__host:-http://elasticsearch:9200}

log "Waiting for elasticsearch"
while ! curl -f -s -o /dev/null "$elastic_host"
do
log "Still trying to connect to $elastic_host"
sleep 1
done
# create a tmp index just to force the shards to init
curl -XPUT -s -o /dev/null "$elastic_host/%25___tmp"
log "Elasticsearch is up. Waiting for shards..."
E=$(curl -s "$elastic_host/_cluster/health?wait_for_status=yellow&wait_for_active_shards=1&timeout=60s")
curl -XDELETE -s -o /dev/null "$elastic_host/%25___tmp"

if ! (echo ${E} | grep -E '"status":"(yellow|green)"' > /dev/null); then
log "Could not connect to elasticsearch in time. Aborting..."
exit 1
fi

log "Starting Kuzzle..."

exec ./bin/start-kuzzle-server
3 changes: 3 additions & 0 deletions features/fixtures/fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// See https://docs.kuzzle.io/core/2/api/controllers/admin/load-fixtures/

module.exports = {};
9 changes: 9 additions & 0 deletions features/fixtures/mappings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// See https://docs.kuzzle.io/core/2/api/controllers/admin/load-mappings/
module.exports = {
'nyc-open-data': {
'yellow-taxi': {
properties: {
}
}
}
};
22 changes: 22 additions & 0 deletions features/fixtures/securities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// See https://docs.kuzzle.io/core/2/api/controllers/admin/load-securities/

module.exports = {
users: {
gordon: {
content: {
profileIds: ['default']
}
},
'test-admin': {
content: {
profileIds: ['admin']
},
credentials: {
local: {
username: 'test-admin',
password: 'password'
}
}
}
}
};
12 changes: 12 additions & 0 deletions features/run-kuzzle-stack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e

docker-compose -f features/docker/docker-compose.yml up -d

echo "[$(date --rfc-3339 seconds)] - Starting Kuzzle..."
while ! curl -f -s -o /dev/null http://localhost:7512
do
echo "[$(date --rfc-3339 seconds)] - Still trying to connect to Kuzzle"
sleep 5
done
31 changes: 31 additions & 0 deletions features/step_definitions/cli-steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const
execa = require('execa'),
{
Then
} = require('cucumber');

Then('I run the command {string} with:', async function (command, dataTable) {
const argsObject = this.parseObject(dataTable);

const args = [];

for (const [arg, value] of Object.entries(argsObject)) {
args.push(arg);
args.push(value);
}

const { stdout } = await execa('./bin/run', [command, ...args])

this.props.result = stdout;
});

Then(/I should( not)? match stdout with "(.*?)"/, function (not, rawRegexp) {
const regexp = new RegExp(rawRegexp);

if (not) {
should(this.props.result).not.match(regexp);
}
else {
should(this.props.result).match(regexp);
}
});
50 changes: 50 additions & 0 deletions features/step_definitions/collection-steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const
{
Then,
Given
} = require('cucumber'),
should = require('should');

Given('a collection {string}:{string}', async function (index, collection) {
this.props.result = await this.sdk.collection.create(index, collection);

this.props.index = index;
this.props.collection = collection;
});

Given('an existing collection {string}:{string}', async function (index, collection) {
if (!await this.sdk.index.exists(index)) {
throw new Error(`Index ${index} does not exist`);
}

if (!await this.sdk.collection.exists(index, collection)) {
throw new Error(`Collection ${index}:${collection} does not exist`);
}

this.props.index = index;
this.props.collection = collection;
});

Then('I list collections in index {string}', async function (index) {
this.props.result = await this.sdk.collection.list(index);
});

Then(/I should( not)? see the collection "(.*?)":"(.*?)"/, async function (not, index, collection) {
const { collections } = await this.sdk.collection.list(index);

const collectionNames = collections.map(({ name }) => name);

if (not) {
should(collectionNames).not.containEql(collection);
} else {
should(collectionNames).containEql(collection);
}
});

Then('I get mappings of collection {string}:{string}', async function (index, collection) {
this.props.result = await this.sdk.collection.getMapping(index, collection);
});

Then('I refresh the collection', function () {
return this.sdk.collection.refresh(this.props.index, this.props.collection);
});
Loading

0 comments on commit 3aa20df

Please sign in to comment.