diff options
author | 2018-08-07 15:09:08 +0100 | |
---|---|---|
committer | 2018-08-07 15:09:16 +0100 | |
commit | af54db6c136138c66cf5ca72419989525a0baa5c (patch) | |
tree | 8519aeab8d45277c51797c7dc23aacf3b56ed1bb /tests | |
parent | A wizard is never late, nor is he early. (diff) |
Initial project layout for django
Diffstat (limited to 'tests')
-rw-r--r-- | tests/__init__.py | 42 | ||||
-rw-r--r-- | tests/test_api.py | 25 | ||||
-rw-r--r-- | tests/test_api_bot_bigbrother.py | 152 | ||||
-rw-r--r-- | tests/test_api_bot_infractions.py | 134 | ||||
-rw-r--r-- | tests/test_api_bot_off_topic_names.py | 134 | ||||
-rw-r--r-- | tests/test_api_bot_snake.py | 64 | ||||
-rw-r--r-- | tests/test_api_bot_tags.py | 72 | ||||
-rw-r--r-- | tests/test_api_bot_users.py | 28 | ||||
-rw-r--r-- | tests/test_api_docs.py | 95 | ||||
-rw-r--r-- | tests/test_clean_logs.py | 74 | ||||
-rw-r--r-- | tests/test_database.py | 31 | ||||
-rw-r--r-- | tests/test_decorators.py | 48 | ||||
-rw-r--r-- | tests/test_jams.py | 11 | ||||
-rw-r--r-- | tests/test_mixins.py | 66 | ||||
-rw-r--r-- | tests/test_oauth_backend.py | 39 | ||||
-rw-r--r-- | tests/test_roots.py | 85 | ||||
-rw-r--r-- | tests/test_rst.py | 11 | ||||
-rw-r--r-- | tests/test_staff.py | 15 | ||||
-rw-r--r-- | tests/test_utilities.py | 25 | ||||
-rw-r--r-- | tests/test_utils.py | 73 | ||||
-rw-r--r-- | tests/test_websocket.py | 12 | ||||
-rw-r--r-- | tests/test_wiki.py | 34 |
22 files changed, 0 insertions, 1270 deletions
diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 1f3ca1a4..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,42 +0,0 @@ -import os - -from flask import Blueprint -from flask_testing import TestCase - -os.environ["BOT_API_KEY"] = "abcdefg" # This is a constant, must be done first -os.environ["PAPERTRAIL_ADDRESS"] = 'localhost' # satisfies coverage -os.environ["DATADOG_ADDRESS"] = 'localhost' # satisfies coverage - -if "FLASK_DEBUG" in os.environ: - del os.environ["FLASK_DEBUG"] # Some unit tests fail if this is set - -from app import manager -from gunicorn_config import _when_ready as when_ready - -when_ready() - -manager.app.tests_blueprint = Blueprint("tests", __name__) -manager.load_views(manager.app.tests_blueprint, "pysite/views/tests") -manager.app.register_blueprint(manager.app.tests_blueprint) -app = manager.app - -app.config["WTF_CSRF_CHECK_DEFAULT"] = False - - -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.config['WIKI_SUBDOMAIN'] = f'http://wiki.{server_name}' - app.config['TEST_HEADER'] = {'X-API-Key': 'abcdefg', 'Content-Type': 'application/json'} - app.allow_subdomain_redirects = True - - return app diff --git a/tests/test_api.py b/tests/test_api.py deleted file mode 100644 index b20dc0c5..00000000 --- a/tests/test_api.py +++ /dev/null @@ -1,25 +0,0 @@ -from tests import SiteTest, app - -class ApiEndpoints(SiteTest): - """ Test cases for the api subdomain """ - 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_route_errors(self): - """ Check api route errors """ - from pysite.base_route import APIView - from pysite.constants import ErrorCodes - - av = APIView() - av.error(ErrorCodes.unauthorized) - av.error(ErrorCodes.bad_data_format) - diff --git a/tests/test_api_bot_bigbrother.py b/tests/test_api_bot_bigbrother.py deleted file mode 100644 index b1060e72..00000000 --- a/tests/test_api_bot_bigbrother.py +++ /dev/null @@ -1,152 +0,0 @@ -import json - -from tests import SiteTest, app - - -class EmptyDatabaseEndpointTests(SiteTest): - def test_api_docs_get_all(self): - response = self.client.get( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertIsInstance(response.json, list) - - def test_fetching_single_entry_returns_404(self): - response = self.client.get( - '/bot/bigbrother?user_id=01932', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert404(response) - self.assertIsInstance(response.json['error_message'], str) - - -class AddingAnEntryEndpointTests(SiteTest): - GOOD_DATA = { - 'user_id': '42', - 'channel_id': '55' - } - GOOD_DATA_JSON = json.dumps(GOOD_DATA) - - def setUp(self): - response = self.client.post( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=self.GOOD_DATA_JSON - ) - self.assertEqual(response.status_code, 204) - - def test_entry_is_in_all_entries(self): - response = self.client.get( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertIn(self.GOOD_DATA, response.json) - - def test_can_fetch_entry_with_param_lookup(self): - response = self.client.get( - f'/bot/bigbrother?user_id={self.GOOD_DATA["user_id"]}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertEqual(response.json, self.GOOD_DATA) - - -class UpdatingAnEntryEndpointTests(SiteTest): - ORIGINAL_DATA = { - 'user_id': '300', - 'channel_id': '400' - } - ORIGINAL_DATA_JSON = json.dumps(ORIGINAL_DATA) - UPDATED_DATA = { - 'user_id': '300', - 'channel_id': '500' - } - UPDATED_DATA_JSON = json.dumps(UPDATED_DATA) - - def setUp(self): - response = self.client.post( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=self.ORIGINAL_DATA_JSON - ) - self.assertEqual(response.status_code, 204) - - def test_can_update_data(self): - response = self.client.post( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=self.UPDATED_DATA_JSON - ) - self.assertEqual(response.status_code, 204) - - -class DeletingAnEntryEndpointTests(SiteTest): - SAMPLE_DATA = { - 'user_id': '101', - 'channel_id': '202' - } - SAMPLE_DATA_JSON = json.dumps(SAMPLE_DATA) - - def setUp(self): - response = self.client.post( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=self.SAMPLE_DATA_JSON - ) - self.assertEqual(response.status_code, 204) - - def test_delete_entry_returns_204(self): - response = self.client.delete( - f'/bot/bigbrother?user_id={self.SAMPLE_DATA["user_id"]}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 204) - - -class SchemaValidationTests(SiteTest): - def test_get_with_invalid_user_id_param_returns_400(self): - response = self.client.get( - '/bot/bigbrother?user_id=lemon-is-not-a-number', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - - self.assert400(response) - self.assertIsInstance(response.json['error_message'], str) - - def test_post_with_invalid_data_returns_400(self): - bad_data_json = json.dumps({ - 'user_id': "I'M A NUMBER I SWEAR", - 'channel_id': '42' - }) - - response = self.client.post( - '/bot/bigbrother', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=bad_data_json - ) - - self.assert400(response) - self.assertIsInstance(response.json['error_message'], str) - - def test_delete_with_invalid_user_id_param_returns_400(self): - response = self.client.delete( - '/bot/bigbrother?user_id=totally-a-valid-number', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - - self.assert400(response) - self.assertIsInstance(response.json['error_message'], str) diff --git a/tests/test_api_bot_infractions.py b/tests/test_api_bot_infractions.py deleted file mode 100644 index 58453e9b..00000000 --- a/tests/test_api_bot_infractions.py +++ /dev/null @@ -1,134 +0,0 @@ -import json - -from tests import SiteTest, app - -TEST_USER_ID = "test" - - -class ApiBotInfractionsEndpoint(SiteTest): - - def test_infraction_create_invalid(self): - # Invalid infraction type - post_data_invalid_type = json.dumps( - {"type": "not_a_type", "reason": "test", "user_id": TEST_USER_ID, "actor_id": TEST_USER_ID} - ) - response = self.client.post("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=post_data_invalid_type) - self.assert400(response) - - def test_infraction_kick(self): - post_data_valid = json.dumps( - {"type": "kick", "reason": "test", "user_id": TEST_USER_ID, "actor_id": TEST_USER_ID} - ) - response = self.client.post("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=post_data_valid) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertTrue("id" in response.json["infraction"]) - infraction_id = response.json["infraction"]["id"] - response = self.client.get(f"/bot/infractions/id/{infraction_id}", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"]) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertTrue("id" in response.json["infraction"]) - self.assertEqual(response.json["infraction"]["id"], infraction_id) - self.assertTrue("active" in response.json["infraction"]) - self.assertFalse(response.json["infraction"]["active"]) - - def test_infraction_ban(self): - post_data_valid = json.dumps( - {"type": "ban", "reason": "baddie", "user_id": TEST_USER_ID, "actor_id": TEST_USER_ID} - ) - response = self.client.post("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=post_data_valid) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertTrue("id" in response.json["infraction"]) - infraction_id = response.json["infraction"]["id"] - - # Check if the ban is currently applied - response = self.client.get(f"/bot/infractions/user/{TEST_USER_ID}/ban/current", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"]) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertIsNotNone(response.json["infraction"]) - self.assertTrue("id" in response.json["infraction"]) - self.assertEqual(response.json["infraction"]["id"], infraction_id) - self.assertIsNone(response.json["infraction"]["expires_at"]) - self.assertTrue(response.json["infraction"]["active"]) - - # Update the expiration to 1d - patch_data_valid = json.dumps( - {"id": infraction_id, "duration": "1d"} - ) - response = self.client.patch("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=patch_data_valid) - self.assert200(response) - self.assertTrue("success" in response.json) - self.assertTrue("infraction" in response.json) - self.assertTrue(response.json["success"]) - self.assertIsNotNone(response.json["infraction"]["expires_at"]) - self.assertTrue(response.json["infraction"]["active"]) - - # Disable the ban - patch_data_valid = json.dumps( - {"id": infraction_id, "active": False} - ) - response = self.client.patch("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=patch_data_valid) - self.assert200(response) - self.assertTrue("success" in response.json) - self.assertTrue("infraction" in response.json) - self.assertTrue(response.json["success"]) - self.assertFalse(response.json["infraction"]["active"]) - - # Check if there is no active ban anymore - response = self.client.get(f"/bot/infractions/user/{TEST_USER_ID}/ban/current", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"]) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertIsNone(response.json["infraction"]) - - # Re-activate the ban - patch_data_valid = json.dumps( - {"id": infraction_id, "active": True} - ) - response = self.client.patch("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=patch_data_valid) - self.assert200(response) - self.assertTrue("success" in response.json) - self.assertTrue("infraction" in response.json) - self.assertTrue(response.json["success"]) - self.assertTrue(response.json["infraction"]["active"]) - - # Create a new ban - post_data_valid = json.dumps( - {"type": "ban", "reason": "baddie v2.0", "user_id": TEST_USER_ID, "actor_id": TEST_USER_ID} - ) - response = self.client.post("/bot/infractions", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"], - data=post_data_valid) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertTrue("id" in response.json["infraction"]) - new_infraction_id = response.json["infraction"]["id"] - - # Check if the old ban is now disabled - response = self.client.get(f"/bot/infractions/id/{infraction_id}", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"]) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertFalse(response.json["infraction"]["active"]) - - # Check if the current ban infraction is the new infraction - response = self.client.get(f"/bot/infractions/user/{TEST_USER_ID}/ban/current", app.config["API_SUBDOMAIN"], - headers=app.config["TEST_HEADER"]) - self.assert200(response) - self.assertTrue("infraction" in response.json) - self.assertEqual(response.json["infraction"]["id"], new_infraction_id) diff --git a/tests/test_api_bot_off_topic_names.py b/tests/test_api_bot_off_topic_names.py deleted file mode 100644 index 6227ddef..00000000 --- a/tests/test_api_bot_off_topic_names.py +++ /dev/null @@ -1,134 +0,0 @@ -"""Tests the `/api/bot/off-topic-names` endpoint.""" - -from tests import SiteTest, app - - -class EmptyDatabaseOffTopicEndpointTests(SiteTest): - """Tests fetching all entries from the endpoint with an empty database.""" - - def test_get_returns_empty_list(self): - response = self.client.get( - '/bot/off-topic-names', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertEqual(response.json, []) - - -class AddingANameOffTopicEndpointTests(SiteTest): - """Tests adding a channel name to the database.""" - - def test_returns_400_on_bad_data(self): - response = self.client.post( - '/bot/off-topic-names?name=my%20TOTALLY%20VALID%20CHANNE%20NAME', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert400(response) - - def test_can_add_new_package(self): - response = self.client.post( - '/bot/off-topic-names?name=lemons-lemon-shop', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - -class AddingChannelNamesToDatabaseEndpointTests(SiteTest): - """Tests fetching names from the database with GET.""" - - CHANNEL_NAME = 'bisks-disks' - - def setUp(self): - response = self.client.post( - f'/bot/off-topic-names?name={self.CHANNEL_NAME}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - def test_name_is_in_all_entries(self): - response = self.client.get( - '/bot/off-topic-names', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertIn(self.CHANNEL_NAME, response.json) - - -class AllowsNumbersInNames(SiteTest): - """Tests that the site allows names with numbers in them.""" - - def test_allows_numbers_in_names(self): - response = self.client.post( - f'/bot/off-topic-names?name=totallynot42', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - -class RandomSampleEndpointTests(SiteTest): - """Tests fetching random names from the website with GET.""" - - CHANNEL_NAME_1 = 'chicken-shed' - CHANNEL_NAME_2 = 'robot-kindergarten' - - def setUp(self): - response = self.client.post( - f'/bot/off-topic-names?name={self.CHANNEL_NAME_1}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - response = self.client.post( - f'/bot/off-topic-names?name={self.CHANNEL_NAME_2}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - def test_returns_limited_names_with_random_query_param(self): - response = self.client.get( - '/bot/off-topic-names?random_items=1', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertEqual(len(response.json), 1) - - -class DeletingANameEndpointTests(SiteTest): - """Tests deleting a name from the database using DELETE.""" - - CHANNEL_NAME = 'duck-goes-meow' - - def setUp(self): - response = self.client.post( - f'/bot/off-topic-names?name={self.CHANNEL_NAME}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - - def test_deleting_random_name_returns_deleted_0(self): - response = self.client.delete( - '/bot/off-topic-names?name=my-totally-random-name', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertEqual(response.json['deleted'], 0) - - def test_deleting_channel_name_returns_deleted_1(self): - response = self.client.delete( - f'/bot/off-topic-names?name={self.CHANNEL_NAME}', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assert200(response) - self.assertEqual(response.json['deleted'], 1) diff --git a/tests/test_api_bot_snake.py b/tests/test_api_bot_snake.py deleted file mode 100644 index fcc18409..00000000 --- a/tests/test_api_bot_snake.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Tests the `/api/bot/snake_` endpoints.""" - -from tests import SiteTest, app - - -class TestSnakeFactsAPI(SiteTest): - """GET method - get snake fact""" - - def test_snake_facts(self): - response = self.client.get( - '/bot/snake_facts', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), str) - - -class TestSnakeIdiomAPI(SiteTest): - """GET method - get snake idiom""" - - def test_snake_idiom(self): - response = self.client.get( - '/bot/snake_idioms', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), str) - - -class TestSnakeQuizAPI(SiteTest): - """GET method - get snake quiz""" - - def test_snake_quiz(self): - response = self.client.get( - '/bot/snake_quiz', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), dict) - - -class TestSnakeNameAPI(SiteTest): - """GET method - get a single snake name, or all of them.""" - - def test_snake_names(self): - response = self.client.get( - '/bot/snake_names', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), dict) - - def test_snake_names_all(self): - response = self.client.get( - '/bot/snake_names?get_all=True', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), list) diff --git a/tests/test_api_bot_tags.py b/tests/test_api_bot_tags.py deleted file mode 100644 index fa06e0fa..00000000 --- a/tests/test_api_bot_tags.py +++ /dev/null @@ -1,72 +0,0 @@ -import json -from tests import SiteTest, app - - -class ApiBotTagsEndpoint(SiteTest): - - def test_api_tags(self): - """ Check tag API """ - - post_data = json.dumps({ - 'tag_name': 'testing', - 'tag_content': 'testing' - }) - - get_data = json.dumps({ - 'tag_name': 'testing' - }) - - bad_data = json.dumps({ - 'not_a_valid_key': 'gross_faceman' - }) - - # POST method - no headers - response = self.client.post('/bot/tags', app.config['API_SUBDOMAIN']) - self.assertEqual(response.status_code, 401) - - # POST method - no data - response = self.client.post('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 400) - - # POST method - bad data - response = self.client.post('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=bad_data) - self.assertEqual(response.status_code, 400) - - # POST method - save tag - response = self.client.post('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=post_data) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, {"success": True}) - - # GET method - no headers - response = self.client.get('/bot/tags', app.config['API_SUBDOMAIN']) - self.assertEqual(response.status_code, 401) - - # GET method - get all tags - response = self.client.get('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 200) - self.assertEqual(type(response.json), list) - - # GET method - get specific tag - response = self.client.get('/bot/tags?tag_name=testing', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.json, { - 'tag_content': 'testing', - 'tag_name': 'testing' - }) - self.assertEqual(response.status_code, 200) - - # DELETE method - no headers - response = self.client.delete('/bot/tags', app.config['API_SUBDOMAIN']) - self.assertEqual(response.status_code, 401) - - # DELETE method - no data - response = self.client.delete('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 400) - - # DELETE method - bad data - response = self.client.delete('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=bad_data) - self.assertEqual(response.status_code, 400) - - # DELETE method - delete the testing tag - response = self.client.delete('/bot/tags', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=get_data) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, {"success": True}) diff --git a/tests/test_api_bot_users.py b/tests/test_api_bot_users.py deleted file mode 100644 index eda3713e..00000000 --- a/tests/test_api_bot_users.py +++ /dev/null @@ -1,28 +0,0 @@ -import json -from tests import SiteTest, app - - -class ApiBotUsersEndpoint(SiteTest): - def test_api_user(self): - """ Check insert user """ - single_data = json.dumps( - {'user_id': "1234", 'roles': ["5678"], "username": "test", "discriminator": "0000", "avatar": "http://some/url"} - ) - list_data = json.dumps([ - {'user_id': "1234", 'roles': ["5678"], "username": "test", "discriminator": "0000", "avatar": "http://some/url"} - ]) - - response = self.client.get('/bot/users?user_id=1234', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertTrue("data" in response.json) - - response = self.client.post('/bot/users', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=single_data) - self.assertTrue("success" in response.json) - - response = self.client.post('/bot/users/complete', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=single_data) - self.assertTrue("inserted" in response.json) - - response = self.client.post('/bot/users', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=list_data) - self.assertTrue("success" in response.json) - - response = self.client.post('/bot/users/complete', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=list_data) - self.assertTrue("inserted" in response.json) diff --git a/tests/test_api_docs.py b/tests/test_api_docs.py deleted file mode 100644 index 945a73bc..00000000 --- a/tests/test_api_docs.py +++ /dev/null @@ -1,95 +0,0 @@ -import json - -from tests import SiteTest, app - - -class ApiDocsEndpoint(SiteTest): - """ Check documentation metadata API """ - - bad_data = json.dumps({'package': 'whatever', 'correct format': False}) - unknown_package_json = json.dumps({'package': "whatever"}) - - def test_api_docs_get_all(self): - """ GET - all entries """ - response = self.client.get('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 200) - self.assertIsInstance(response.json, list) - - def test_api_docs_get_unknown(self): - """ GET - unknown package """ - response = self.client.get('/bot/docs?package=whatever', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, []) - - def test_api_docs_get_multi_unknown(self): - """ GET - multiple unknown packages """ - response = self.client.get('/bot/docs?package=whatever&package=everwhat', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 200) - self.assertIsInstance(response.json, list) - - def test_api_docs_post_no_data(self): - """ POST - no data """ - response = self.client.post('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 400) - - def test_api_docs_post_bad_data(self): - """ POST - malformed data """ - response = self.client.post('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=self.bad_data) - self.assertEqual(response.status_code, 400) - - def test_api_docs_delete_bad(self): - """ DELETE - missing request body """ - response = self.client.delete('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 400) - - def test_api_docs_delete_unknown(self): - """ DELETE - unknown package """ - response = self.client.delete('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=self.unknown_package_json) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json['deleted'], 0) - - -class SinglePackageApiDocsEndpointTests(SiteTest): - """ Test the API docs endpoint with a single package added """ - - valid_data = { - 'package': "lemonapi", - 'base_url': "http://example.com/", - 'inventory_url': "http://example.com/object.inv" - } - delete_data_json = json.dumps({'package': valid_data['package']}) - valid_data_json = json.dumps(valid_data) - - def setUp(self): - """ POST valid data to the server for use in this test case """ - response = self.client.post('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=self.valid_data_json) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, {"success": True}) - - def test_api_docs_get_valid(self): - """ GET - added package is in all entries """ - response = self.client.get('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER']) - self.assertEqual(response.status_code, 200) - self.assertIn(self.valid_data, response.json) - - def test_api_docs_get_detail(self): - """ GET - added package detail """ - response = self.client.get( - f'/bot/docs?package={self.valid_data["package"]}', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, [self.valid_data]) - - def test_api_docs_get_partly_known(self): - """ GET - added package is the only package for query with another unknown package """ - response = self.client.get( - f'/bot/docs?package={self.valid_data["package"]}&package=whatever', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'] - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, [self.valid_data]) - - def test_api_docs_delete_all(self): - """ DELETE - added package """ - response = self.client.delete('/bot/docs', app.config['API_SUBDOMAIN'], headers=app.config['TEST_HEADER'], data=self.delete_data_json) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json['deleted'], 1) diff --git a/tests/test_clean_logs.py b/tests/test_clean_logs.py deleted file mode 100644 index 1c3449b4..00000000 --- a/tests/test_clean_logs.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Tests the `/api/bot/clean` endpoint.""" -import json - -from tests import SiteTest, app - - -class TestCleanLogAPI(SiteTest): - """ - Tests submitting a clean log and - verifies that we get a UUID in return. - - Also ensures that we get a 400 if we send in bad data. - """ - - def test_returns_400_on_bad_data(self): - bad_data = json.dumps({ - "scubfire": "testiclaes" - }) - - response = self.client.post( - '/bot/clean', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=bad_data - ) - self.assert400(response) - - def test_submit_clean_log(self): - good_data = json.dumps({ - "log_data": [ - { - "author": "something", - "user_id": "12345151", - "role_id": "4818413", - "content": "testy", - "timestamp": "this way comes", - "embeds": [{"fire":"nanny"}], - "attachments": ["<Attachment>"], - } - ] - }) - - response = self.client.post( - '/bot/clean', - app.config['API_SUBDOMAIN'], - headers=app.config['TEST_HEADER'], - data=good_data - ) - - log_id = response.json.get("log_id") - - self.assert200(response) - self.assertIsNotNone(log_id) - self.assertGreater(len(log_id), 2) - self.assertEqual(type(log_id), str) - - -class TestCleanLogFrontEnd(SiteTest): - """ - Tests the frontend for - viewing the clean logs. - - Best I can do with our current - system is check if I'm redirected, - since this is behind OAuth. - """ - - def test_clean_log_frontend_returns_302(self): - response = self.client.get( - f'/bot/clean_logs/1', - 'http://pytest.local' - ) - - self.assertEqual(response.status_code, 302)
\ No newline at end of file diff --git a/tests/test_database.py b/tests/test_database.py deleted file mode 100644 index 237cd68d..00000000 --- a/tests/test_database.py +++ /dev/null @@ -1,31 +0,0 @@ -from tests import SiteTest - -class DatabaseTests(SiteTest): - """ Test cases for the database module """ - def test_table_actions(self): - import string - import secrets - from pysite.database import RethinkDB - - alphabet = string.ascii_letters - generated_table_name = ''.join(secrets.choice(alphabet) for i in range(8)) - - rdb = RethinkDB() - # Create table name and expect it to work - result = rdb.create_table(generated_table_name) - self.assertEqual(result, True) - - # Create the same table name and expect it to already exist - result = rdb.create_table(generated_table_name) - self.assertEqual(result, False) - - # Drop table and expect it to work - result = rdb.drop_table(generated_table_name) - self.assertEqual(result, True) - - # Drop the same table and expect it to already be gone - result = rdb.drop_table(generated_table_name) - self.assertEqual(result, False) - - # This is to get some more code coverage - self.assertEqual(rdb.teardown_request('_'), None) diff --git a/tests/test_decorators.py b/tests/test_decorators.py deleted file mode 100644 index 5a3915b8..00000000 --- a/tests/test_decorators.py +++ /dev/null @@ -1,48 +0,0 @@ -from schema import Schema -from werkzeug.datastructures import ImmutableMultiDict -from werkzeug.exceptions import BadRequest - -from pysite.constants import ValidationTypes -from pysite.decorators import api_params -from tests import SiteTest - - -class DuckRequest: - """A quacking request with the `args` parameter used in schema validation.""" - - def __init__(self, args): - self.args = args - - -class DecoratorTests(SiteTest): - def test_decorator_api_json(self): - """ Check the json validation decorator """ - SCHEMA = Schema([{"user_id": int, "role": int}]) - - @api_params(schema=SCHEMA, validation_type=ValidationTypes.json) - def try_json_type(data): - return data - - with self.assertRaises(AttributeError): - try_json_type("not json") - - def test_decorator_params(self): - """ Check the params validation decorator """ - - response = self.client.post('/testparams?test=params') - - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, [{'test': 'params'}]) - - def test_duplicate_params_with_dict_schema_raises_400(self): - """Check that duplicate parameters with a dictionary schema return 400 Bad Request""" - - response = self.client.get('/testparams?segfault=yes&segfault=no') - self.assert400(response) - - def test_single_params_with_dict_schema(self): - """Single parameters with a dictionary schema and `allow_duplicate_keys=False` return 200""" - - response = self.client.get('/testparams?segfault=yes') - self.assert200(response) - self.assertEqual(response.json, {'segfault': 'yes'}) diff --git a/tests/test_jams.py b/tests/test_jams.py deleted file mode 100644 index cf0d8952..00000000 --- a/tests/test_jams.py +++ /dev/null @@ -1,11 +0,0 @@ -from tests import SiteTest, app - -class JamsEndpoint(SiteTest): - """ Test cases for the root endpoint and error handling """ - - def test_jams_page(self): - """ Check the jams path responds with 200 OK """ - response = self.client.get('/jams', 'http://'+app.config['SERVER_NAME']) - self.assertEqual(response.status_code, 200) - - diff --git a/tests/test_mixins.py b/tests/test_mixins.py deleted file mode 100644 index 27e61b22..00000000 --- a/tests/test_mixins.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -from tests import SiteTest, manager - -class MixinTests(SiteTest): - """ Test cases for mixins """ - - def test_handler_5xx(self): - """ Check error view returns error message """ - from werkzeug.exceptions import InternalServerError - from pysite.views.error_handlers import http_5xx - - error_view = http_5xx.Error500View() - error_message = error_view.get(InternalServerError) - self.assertEqual(error_message[1], 500) - - def test_route_view_runtime_error(self): - """ Check that wrong values for route view setup raises runtime error """ - from pysite.base_route import RouteView - - rv = RouteView() - - with self.assertRaises(RuntimeError): - rv.setup(manager, 'sdfsdf') - - def test_oauth_property(self): - """ Make sure the oauth property works""" - from flask import Blueprint - - from pysite.route_manager import RouteView - from pysite.oauth import OAuthBackend - - class TestRoute(RouteView): - name = "test" - path = "/test" - - tr = TestRoute() - tr.setup(manager, Blueprint("test", "test_name")) - self.assertIsInstance(tr.oauth, OAuthBackend) - - def test_user_data_property(self): - """ Make sure the user_data property works""" - from flask import Blueprint - - from pysite.route_manager import RouteView - - class TestRoute(RouteView): - name = "test" - path = "/test" - - tr = TestRoute() - tr.setup(manager, Blueprint("test", "test_name")) - self.assertIsNone(tr.user_data) - - def test_logged_in_property(self): - """ Make sure the user_data property works""" - from flask import Blueprint - - from pysite.route_manager import RouteView - - class TestRoute(RouteView): - name = "test" - path = "/test" - - tr = TestRoute() - tr.setup(manager, Blueprint("test", "test_name")) - self.assertFalse(tr.logged_in) diff --git a/tests/test_oauth_backend.py b/tests/test_oauth_backend.py deleted file mode 100644 index 473f5c54..00000000 --- a/tests/test_oauth_backend.py +++ /dev/null @@ -1,39 +0,0 @@ -from tests import SiteTest, manager - -class TestOAuthBackend(SiteTest): - """ Test cases for the oauth.py file """ - - def test_get(self): - """ Make sure the get function returns nothing """ - self.assertIsNone(manager.oauth_backend.get()) - - def test_delete(self): - """ Make sure the delete function returns nothing """ - self.assertIsNone(manager.oauth_backend.delete(None)) - - def test_logout(self): - """ Make sure at least apart of logout is working :/ """ - self.assertIsNone(manager.oauth_backend.logout()) - - def test_add_user(self): - """ Make sure function adds values to database and session """ - from flask import session - - from pysite.constants import OAUTH_DATABASE - - sess_id = "hey bro wazup" - fake_token = {"access_token": "access_token", "id": sess_id, "refresh_token": "refresh_token", "expires_at": 5} - fake_user = {"id": 1235678987654321, "username": "Zwacky", "discriminator": "#6660"} - manager.db.conn = manager.db.get_connection() - manager.oauth_backend.add_user(fake_token, fake_user, sess_id) - - self.assertEqual(sess_id, session["session_id"]) - fake_token["snowflake"] = fake_user["id"] - fake_user["user_id"] = fake_user["id"] - del fake_user["id"] - self.assertEqual(fake_token, manager.db.get(OAUTH_DATABASE, sess_id)) - self.assertEqual(fake_user, manager.db.get("users", fake_user["user_id"])) - - manager.db.delete(OAUTH_DATABASE, sess_id) - manager.db.delete("users", fake_user["user_id"]) - manager.db.teardown_request(None) diff --git a/tests/test_roots.py b/tests/test_roots.py deleted file mode 100644 index 1b270178..00000000 --- a/tests/test_roots.py +++ /dev/null @@ -1,85 +0,0 @@ -from tests import SiteTest -from pysite.constants import DISCORD_OAUTH_REDIRECT -from pysite.constants import DISCORD_OAUTH_AUTHORIZED -from pysite.constants import ERROR_DESCRIPTIONS - - -class RootEndpoint(SiteTest): - """ Test cases for the root endpoint and error handling """ - - def test_index(self): - """ Check the root path responds with 200 OK """ - response = self.client.get('/', 'http://pytest.local') - self.assertEqual(response.status_code, 200) - - def test_info_index(self): - """ Check the info index path responds with a 301 """ - response = self.client.get('/info') - self.assertEqual(response.status_code, 301) - - def test_info_help(self): - """ Check the info help path responds with 200 OK """ - response = self.client.get('/info/help') - self.assertEqual(response.status_code, 200) - - def test_info_resources(self): - """ Check the info resources path responds with 200 OK """ - response = self.client.get('/info/resources') - self.assertEqual(response.status_code, 200) - - def test_info_resources_json(self): - """ Check the resources JSON loads correctly """ - response = self.client.get('/static/resources.json') - self.assertEqual(response.status_code, 200) - self.assertIsInstance(response.json, dict) - - def test_info_rules(self): - """ Check the info rules path responds with 200 OK """ - response = self.client.get('/info/help') - 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_error(self): - """ Check the error pages """ - for code in ERROR_DESCRIPTIONS.keys(): - response = self.client.get(f'/error/{code}') - self.assertEqual(response.status_code, code) - - def test_invite(self): - """ Check invite redirects """ - response = self.client.get('/invite') - self.assertEqual(response.status_code, 302) - - def test_ws_test(self): - """ Check ws_test responds """ - response = self.client.get('/ws_test') - self.assertEqual(response.status_code, 200) - - def test_oauth_redirects(self): - """ Check oauth redirects """ - response = self.client.get(DISCORD_OAUTH_REDIRECT) - self.assertEqual(response.status_code, 302) - - def test_oauth_logout(self): - """ Check oauth redirects """ - response = self.client.get('/auth/logout') - self.assertEqual(response.status_code, 302) - - def test_oauth_authorized(self): - """ Check oauth authorization """ - response = self.client.get(DISCORD_OAUTH_AUTHORIZED) - self.assertEqual(response.status_code, 302) - - def test_stats_redirect(self): - """ Check stats path redirects """ - response = self.client.get('/stats') - self.assertEqual(response.status_code, 302) - - def test_500_easter_egg(self): - """ Check the status of the /500 page""" - response = self.client.get("/500") - self.assertEqual(response.status_code, 500) diff --git a/tests/test_rst.py b/tests/test_rst.py deleted file mode 100644 index d6328bc4..00000000 --- a/tests/test_rst.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -import json -from tests import SiteTest, app - -class RstEndpoints(SiteTest): - """ Test cases for staff subdomain """ - - def test_staff_view(self): - """ Check staff view redirects """ - response = self.client.get('/', "http://"+app.config['SERVER_NAME']) - self.assertEqual(response.status_code, 200) diff --git a/tests/test_staff.py b/tests/test_staff.py deleted file mode 100644 index bc911b0c..00000000 --- a/tests/test_staff.py +++ /dev/null @@ -1,15 +0,0 @@ -from tests import SiteTest, app - - -class StaffEndpoints(SiteTest): - """ Test cases for staff subdomain """ - - def test_staff_view(self): - """ Check staff view redirects """ - response = self.client.get('/', app.config['STAFF_SUBDOMAIN']) - self.assertEqual(response.status_code, 302) - - def test_jams_infractions(self): - """ Check staff jams infractions view redirects """ - response = self.client.get('/jams/infractions', app.config['STAFF_SUBDOMAIN']) - self.assertEqual(response.status_code, 302) diff --git a/tests/test_utilities.py b/tests/test_utilities.py deleted file mode 100644 index 61a480e2..00000000 --- a/tests/test_utilities.py +++ /dev/null @@ -1,25 +0,0 @@ -from tests import SiteTest, manager - -class Utilities(SiteTest): - """ Test cases for internal utility code """ - def test_error_view_runtime_error(self): - """ Check that wrong values for error view setup raises runtime error """ - import pysite.base_route - - ev = pysite.base_route.ErrorView() - - with self.assertRaises(RuntimeError): - ev.setup(manager, 'sdfsdf') - - def test_websocket_callback(self): - """ Check that websocket default callbacks work """ - import pysite.websockets - - class TestWS(pysite.websockets.WS): - pass - - try: - TestWS(None).on_message("test") - return False - except NotImplementedError: - return True diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 87c8c186..00000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,73 +0,0 @@ -from datetime import datetime, timedelta, timezone - -from tests import SiteTest -from pysite.utils.time import is_expired, parse_duration - - -class DurationParsingTests(SiteTest): - """Tests the `parse_duration` method provided by `pysite.utils.time`.""" - - SIMPLE_DURATION_STRINGS = ( - ('42s', timedelta(seconds=42)), - ('12m', timedelta(minutes=12)), - ('20h', timedelta(hours=20)), - ('7d', timedelta(days=7)), - ('2w', timedelta(weeks=2)) - ) - COMBINED_DURATION_STRINGS = ( - ('12m30s', timedelta(minutes=12, seconds=30)), - ('20h5m', timedelta(hours=20, minutes=5)), - ('7d10h12s', timedelta(days=7, hours=10, seconds=12)) - ) - - def test_simple_duration_string_parsing(self): - for duration_string, added_delta in self.SIMPLE_DURATION_STRINGS: - timezone_aware_now = datetime.now(timezone.utc) - self.assertAlmostEqual( - parse_duration(duration_string).timestamp(), - (timezone_aware_now + added_delta).timestamp(), - places=-1 # Being off by < 10 seconds is acceptable - ) - - def test_combined_duration_string_parsing(self): - for duration_string, added_delta in self.COMBINED_DURATION_STRINGS: - timezone_aware_now = datetime.now(timezone.utc) - self.assertAlmostEqual( - parse_duration(duration_string).timestamp(), - (timezone_aware_now + added_delta).timestamp(), - places=-1 # Being off by < 10 seconds is acceptable - ) - - def test_empty_duration_raises_valueerror(self): - with self.assertRaises(ValueError): - parse_duration('') - - def test_unknown_char_raises_valueerror(self): - with self.assertRaises(ValueError): - parse_duration('12l') - - def test_valid_unit_without_digits_raises_valueerror(self): - with self.assertRaises(ValueError): - parse_duration('s') - - -class ExpiryTests(SiteTest): - """Tests the `is_expired` method provided by `pysite.utils.time`.""" - - EXPIRY_DELTAS = ( - timedelta(seconds=30), - timedelta(minutes=12), - timedelta(hours=20), - timedelta(days=5), - timedelta(weeks=7) - ) - - def test_datetimes_in_the_past_are_expired(self): - for delta in self.EXPIRY_DELTAS: - date = datetime.now(timezone.utc) - delta - self.assertTrue(is_expired(date)) - - def test_datetimes_in_the_future_are_not_expired(self): - for delta in self.EXPIRY_DELTAS: - date = datetime.now(timezone.utc) + delta - self.assertFalse(is_expired(date)) diff --git a/tests/test_websocket.py b/tests/test_websocket.py deleted file mode 100644 index d8a616bf..00000000 --- a/tests/test_websocket.py +++ /dev/null @@ -1,12 +0,0 @@ -from tests import SiteTest - -class TestWebsocketEcho(SiteTest): - """ Test cases for the echo endpoint """ - def testEcho(self): - """ Check rudimentary websockets handlers work """ - from geventwebsocket.websocket import WebSocket - from pysite.views.ws.echo import EchoWebsocket - ew = EchoWebsocket(WebSocket) - ew.on_open() - ew.on_message('message') - ew.on_close() diff --git a/tests/test_wiki.py b/tests/test_wiki.py deleted file mode 100644 index e16152a1..00000000 --- a/tests/test_wiki.py +++ /dev/null @@ -1,34 +0,0 @@ -import os -from tests import SiteTest, app - -class WikiEndpoints(SiteTest): - """ Test cases for the wiki subdomain """ - def test_wiki_edit(self): - """Test that the wiki edit page redirects to login""" - response = self.client.get("/edit/page", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 302) - - def test_wiki_edit_post_empty_request(self): - """Empty request should redirect to login""" - response = self.client.post("/edit/page", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 302) - - def test_wiki_history(self): - """Test the history show""" - response = self.client.get("/history/show/blahblah-non-existant-page", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 404) # Test that unknown routes 404 - - def test_wiki_diff(self): - """Test whether invalid revision IDs error""" - response = self.client.get("/history/compare/ABC/XYZ", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 404) # Test that unknown revisions 404 - - def test_wiki_special(self): - """Test whether invalid revision IDs error""" - response = self.client.get("/special", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 200) - - def test_wiki_special_all_pages(self): - """Test whether invalid revision IDs error""" - response = self.client.get("/special/all_pages", app.config['WIKI_SUBDOMAIN']) - self.assertEqual(response.status_code, 200) |