From bedc30d41ff9c3dd8fb59cb6d5c8c16170d69cda Mon Sep 17 00:00:00 2001 From: Christopher Baklid Date: Tue, 20 Feb 2018 21:39:37 +0100 Subject: adds initial unit testing (#22) * Adds Unit Testing * Adds coveralls coverage badge --- .coveragerc | 2 ++ .gitignore | 1 + .travis.yml | 7 ++++ README.md | 2 +- app_test.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ requirements-ci.txt | 4 +++ 6 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 .coveragerc create mode 100644 app_test.py diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..630326b5 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = /usr/*, gunicorn_config.py, deploy.py, app_test.py, app.py diff --git a/.gitignore b/.gitignore index 162115dc..54eef446 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ nosetests.xml coverage.xml *.cover .hypothesis/ +.pytest_cache/ # Translations *.mo diff --git a/.travis.yml b/.travis.yml index 30032dfe..376c1604 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,17 @@ language: python python: - "3.6" +addons: + rethinkdb: "2.3" + +cache: pip + install: - pip install -r requirements.txt - pip install -r requirements-ci.txt script: - snekchek + - py.test app_test.py --cov pysite --cov-report term-missing -v + - coveralls after_success: - python deploy.py diff --git a/README.md b/README.md index f45808e4..5e70d45d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Python Discord website -[![Build Status](https://travis-ci.org/discord-python/site.svg?branch=master)](https://travis-ci.org/discord-python/site) +[![Build Status](https://travis-ci.org/discord-python/site.svg?branch=master)](https://travis-ci.org/discord-python/site) [![Coverage Status](https://coveralls.io/repos/github/discord-python/site/badge.svg?branch=unit-testing)](https://coveralls.io/github/discord-python/site?branch=unit-testing) ### See the wiki for details diff --git a/app_test.py b/app_test.py new file mode 100644 index 00000000..896a47cd --- /dev/null +++ b/app_test.py @@ -0,0 +1,96 @@ +import json # pragma: no cover +import os # pragma: no cover + +from app import app + +from flask_testing import TestCase # pragma: no cover + + +class SiteTest(TestCase): + ''' extend TestCase with flask app instantiation ''' + def create_app(self): + ''' add flask app configuration settings ''' + server_name = 'pytest.local' + app.config['TESTING'] = True + app.config['LIVESERVER_TIMEOUT'] = 10 + app.config['SERVER_NAME'] = server_name + app.config['API_SUBDOMAIN'] = f'http://api.{server_name}' + app.config['STAFF_SUBDOMAIN'] = f'http://staff.{server_name}' + app.allow_subdomain_redirects = True + return app + + +class RootEndpoint(SiteTest): + ''' test cases for the root endpoint and error handling ''' + def test_index(self): + ''' Check the root path reponds with 200 OK ''' + response = self.client.get('/', 'http://pytest.local') + self.assertEqual(response.status_code, 200) + + def test_not_found(self): + ''' Check paths without handlers returns 404 Not Found ''' + response = self.client.get('/nonexistentpath') + self.assertEqual(response.status_code, 404) + + def test_invite(self): + ''' Check invite redirects ''' + response = self.client.get('/invite') + self.assertEqual(response.status_code, 302) + + def test_api_unknown_route(self): + ''' Check api unknown route ''' + response = self.client.get('/', app.config['API_SUBDOMAIN']) + self.assertEqual(response.json, {'error_code': 0, 'error_message': 'Unknown API route'}) + self.assertEqual(response.status_code, 404) + + def test_api_healthcheck(self): + ''' Check healthcheck url responds ''' + response = self.client.get('/healthcheck', app.config['API_SUBDOMAIN']) + self.assertEqual(response.json, {'status': 'ok'}) + self.assertEqual(response.status_code, 200) + + def test_api_tag(self): + ''' Check tag api ''' + os.environ['BOT_API_KEY'] = 'abcdefg' + headers = {'X-API-Key': 'abcdefg', 'Content-Type': 'application/json'} + good_data = json.dumps({ + 'tag_name': 'testing', + 'tag_content': 'testing', + 'tag_category': 'testing'}) + + bad_data = json.dumps({ + 'not_a_valid_key': 'testing', + 'tag_content': 'testing', + 'tag_category': 'testing'}) + + response = self.client.get('/tag', app.config['API_SUBDOMAIN']) + self.assertEqual(response.status_code, 401) + + response = self.client.get('/tag', app.config['API_SUBDOMAIN'], headers=headers) + self.assertEqual(response.status_code, 200) + + response = self.client.post('/tag', app.config['API_SUBDOMAIN'], headers=headers, data=bad_data) + self.assertEqual(response.status_code, 400) + + response = self.client.post('/tag', app.config['API_SUBDOMAIN'], headers=headers, data=good_data) + self.assertEqual(response.json, {'success': True}) + + response = self.client.get('/tag', app.config['API_SUBDOMAIN'], headers=headers, data=good_data) + self.assertEqual(response.json, [{'tag_name': 'testing'}]) + self.assertEqual(response.status_code, 200) + + def test_api_user(self): + ''' Check insert user ''' + os.environ['BOT_API_KEY'] = 'abcdefg' + headers = {'X-API-Key': 'abcdefg', 'Content-Type': 'application/json'} + bad_data = json.dumps({'user_id': 1234, 'role': 5678}) + good_data = json.dumps([{'user_id': 1234, 'role': 5678}]) + + response = self.client.get('/user', app.config['API_SUBDOMAIN'], headers=headers) + self.assertEqual(response.status_code, 405) + + response = self.client.post('/user', app.config['API_SUBDOMAIN'], headers=headers, data=bad_data) + self.assertEqual(response.json, {'error_code': 3, 'error_message': 'Incorrect parameters provided'}) + + response = self.client.post('/user', app.config['API_SUBDOMAIN'], headers=headers, data=good_data) + self.assertEqual(True, "inserted" in response.json) diff --git a/requirements-ci.txt b/requirements-ci.txt index 50d0f297..0ce27166 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -8,3 +8,7 @@ flake8-string-format safety dodgy requests +Flask-Testing +pytest +pytest-cov +python-coveralls -- cgit v1.2.3