From 7efc921ce662c4d7b2d264e2837c5acb5fe5690c Mon Sep 17 00:00:00 2001 From: EliuX Date: Wed, 22 Apr 2020 12:01:37 -0500 Subject: [PATCH] fix: Close #94 Fix tests to support authentication --- commons/data_access_layer/database.py | 1 - commons/data_access_layer/sql.py | 12 -- tests/commons/data_access_layer/sql_test.py | 7 - tests/conftest.py | 47 +---- .../activities/activities_namespace_test.py | 99 +++++++--- .../customers/customers_namespace_test.py | 125 ++++++++---- .../project_types_namespace_test.py | 124 ++++++++---- .../projects/projects_namespace_test.py | 121 ++++++++---- .../time_entries_namespace_test.py | 182 +++++++++++++----- 9 files changed, 480 insertions(+), 238 deletions(-) diff --git a/commons/data_access_layer/database.py b/commons/data_access_layer/database.py index 077780cf..27bee0ca 100644 --- a/commons/data_access_layer/database.py +++ b/commons/data_access_layer/database.py @@ -36,7 +36,6 @@ def delete(self, id): def init_app(app: Flask) -> None: - init_sql(app) # TODO Delete after the migration to Cosmos DB has finished. init_cosmos_db(app) diff --git a/commons/data_access_layer/sql.py b/commons/data_access_layer/sql.py index c1afb0e2..eb356620 100644 --- a/commons/data_access_layer/sql.py +++ b/commons/data_access_layer/sql.py @@ -4,10 +4,8 @@ from flask_sqlalchemy import SQLAlchemy from commons.data_access_layer.database import CRUDDao, ID_MAX_LENGTH -from time_tracker_api.security import current_user_id db: SQLAlchemy = None -AuditedSQLModel = None def handle_commit_issues(f): @@ -25,16 +23,6 @@ def init_app(app: Flask) -> None: global db db = SQLAlchemy(app) - global AuditedSQLModel - - class AuditedSQLModelClass(): - created_at = db.Column(db.DateTime, server_default=db.func.now()) - updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow) - created_by = db.Column(db.String(ID_MAX_LENGTH), default=current_user_id) - updated_by = db.Column(db.String(ID_MAX_LENGTH), onupdate=current_user_id) - - AuditedSQLModel = AuditedSQLModelClass - class SQLRepository(): def __init__(self, model_type: type): diff --git a/tests/commons/data_access_layer/sql_test.py b/tests/commons/data_access_layer/sql_test.py index 48f220ff..26f992b8 100644 --- a/tests/commons/data_access_layer/sql_test.py +++ b/tests/commons/data_access_layer/sql_test.py @@ -16,10 +16,6 @@ def test_create(sql_repository): assert result is not None assert result.id is not None - assert result.created_at is not None - assert result.created_by is not None - assert result.updated_at is None - assert result.updated_by is None existing_elements_registry.append(result) @@ -43,9 +39,6 @@ def test_update(sql_repository): assert updated_element.id == existing_element.id assert updated_element.name == "Jon Snow" assert updated_element.age == 34 - assert updated_element.updated_at is not None - assert updated_element.updated_at > updated_element.created_at - assert updated_element.updated_by is not None def test_find_all(sql_repository): diff --git a/tests/conftest.py b/tests/conftest.py index 21de5386..5fad738c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,7 @@ from flask.testing import FlaskClient from commons.data_access_layer.cosmos_db import CosmosDBRepository, datetime_str, current_datetime +from commons.data_access_layer.database import init_sql from time_tracker_api import create_app from time_tracker_api.security import get_or_generate_dev_secret_key from time_tracker_api.time_entries.time_entries_model import TimeEntryCosmosDBRepository @@ -14,37 +15,6 @@ fake = Faker() Faker.seed() -TEST_USER = { - "name": "testuser@ioet.com", - "password": "secret" -} - - -class User: - def __init__(self, username, password): - self.username = username - self.password = password - - -class AuthActions: - """Auth actions container in tests""" - - def __init__(self, app, client): - self._app = app - self._client = client - - # def login(self, username=TEST_USER["name"], - # password=TEST_USER["password"]): - # login_url = url_for("security.login", self._app) - # return open_with_basic_auth(self._client, - # login_url, - # username, - # password) - # - # def logout(self): - # return self._client.get(url_for("security.logout", self._app), - # follow_redirects=True) - @pytest.fixture(scope='session') def app() -> Flask: @@ -58,9 +28,12 @@ def client(app: Flask) -> FlaskClient: @pytest.fixture(scope="module") -def sql_model_class(): - from commons.data_access_layer.sql import db, AuditedSQLModel - class PersonSQLModel(db.Model, AuditedSQLModel): +def sql_model_class(app: Flask): + with app.app_context(): + init_sql(app) + + from commons.data_access_layer.sql import db + class PersonSQLModel(db.Model): __tablename__ = 'test' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=False, nullable=False) @@ -186,11 +159,11 @@ def running_time_entry(time_entry_repository: TimeEntryCosmosDBRepository, @pytest.fixture(scope="session") -def valid_jwt(app: Flask) -> str: +def valid_jwt(app: Flask, tenant_id: str, owner_id: str) -> str: expiration_time = datetime.utcnow() + timedelta(seconds=3600) return jwt.encode({ - "iss": "https://securityioet.b2clogin.com/%s/v2.0/" % fake.uuid4(), - "oid": fake.uuid4(), + "iss": "https://securityioet.b2clogin.com/%s/v2.0/" % tenant_id, + "oid": owner_id, 'exp': expiration_time }, key=get_or_generate_dev_secret_key()).decode("UTF-8") diff --git a/tests/time_tracker_api/activities/activities_namespace_test.py b/tests/time_tracker_api/activities/activities_namespace_test.py index 90f3f1d6..508e7f88 100644 --- a/tests/time_tracker_api/activities/activities_namespace_test.py +++ b/tests/time_tracker_api/activities/activities_namespace_test.py @@ -4,8 +4,6 @@ from flask_restplus._http import HTTPStatus from pytest_mock import MockFixture -from time_tracker_api.security import current_user_tenant_id - fake = Faker() valid_activity_data = { @@ -36,34 +34,45 @@ def test_create_activity_should_succeed_with_valid_request(client: FlaskClient, repository_create_mock.assert_called_once() -def test_create_activity_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_create_activity_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao repository_create_mock = mocker.patch.object(activity_dao.repository, 'create', return_value=fake_activity) - response = client.post("/activities", json=None, follow_redirects=True) + response = client.post("/activities", + headers=valid_header, + json=None, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_create_mock.assert_not_called() -def test_list_all_activities(client: FlaskClient, mocker: MockFixture): +def test_list_all_activities(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao repository_find_all_mock = mocker.patch.object(activity_dao.repository, 'find_all', return_value=[]) - response = client.get("/activities", follow_redirects=True) + response = client.get("/activities", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code json_data = json.loads(response.data) assert [] == json_data - repository_find_all_mock.assert_called_once() + repository_find_all_mock.assert_called_once_with(partition_key_value=tenant_id) def test_get_activity_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture, + tenant_id: str, valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao @@ -79,12 +88,12 @@ def test_get_activity_should_succeed_with_valid_id(client: FlaskClient, assert HTTPStatus.OK == response.status_code fake_activity == json.loads(response.data) - repository_find_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + repository_find_mock.assert_called_once_with(str(valid_id), partition_key_value=tenant_id) def test_get_activity_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture, + tenant_id: str, valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao from werkzeug.exceptions import NotFound @@ -101,10 +110,11 @@ def test_get_activity_should_return_not_found_with_invalid_id(client: FlaskClien assert HTTPStatus.NOT_FOUND == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_get_activity_should_return_422_for_invalid_id_format(client: FlaskClient, mocker: MockFixture): +def test_get_activity_should_return_422_for_invalid_id_format(client: FlaskClient, + mocker: MockFixture): from time_tracker_api.activities.activities_namespace import activity_dao from werkzeug.exceptions import UnprocessableEntity @@ -117,41 +127,54 @@ def test_get_activity_should_return_422_for_invalid_id_format(client: FlaskClien response = client.get("/activities/%s" % invalid_id, follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code - repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + repository_find_mock.assert_not_called() -def test_update_activity_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture): +def test_update_activity_should_succeed_with_valid_data(client: FlaskClient, + tenant_id: str, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao repository_update_mock = mocker.patch.object(activity_dao.repository, 'partial_update', return_value=fake_activity) - valid_id = fake.random_int(1, 9999) - response = client.put("/activities/%s" % valid_id, json=valid_activity_data, follow_redirects=True) + valid_id = fake.uuid4() + response = client.put("/activities/%s" % valid_id, + headers=valid_header, + json=valid_activity_data, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_activity == json.loads(response.data) repository_update_mock.assert_called_once_with(str(valid_id), changes=valid_activity_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_activity_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_update_activity_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao repository_update_mock = mocker.patch.object(activity_dao.repository, 'partial_update', return_value=fake_activity) valid_id = fake.random_int(1, 9999) - response = client.put("/activities/%s" % valid_id, json=None, follow_redirects=True) + response = client.put("/activities/%s" % valid_id, + headers=valid_header, + json=None, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_update_mock.assert_not_called() -def test_update_activity_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_update_activity_should_return_not_found_with_invalid_id(client: FlaskClient, + tenant_id: str, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao from werkzeug.exceptions import NotFound @@ -162,16 +185,20 @@ def test_update_activity_should_return_not_found_with_invalid_id(client: FlaskCl side_effect=NotFound) response = client.put("/activities/%s" % invalid_id, + headers=valid_header, json=valid_activity_data, follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_update_mock.assert_called_once_with(str(invalid_id), changes=valid_activity_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_activity_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_activity_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao valid_id = fake.random_int(1, 9999) @@ -180,15 +207,20 @@ def test_delete_activity_should_succeed_with_valid_id(client: FlaskClient, mocke 'delete', return_value=None) - response = client.delete("/activities/%s" % valid_id, follow_redirects=True) + response = client.delete("/activities/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NO_CONTENT == response.status_code assert b'' == response.data repository_remove_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_activity_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_activity_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao from werkzeug.exceptions import NotFound @@ -198,14 +230,19 @@ def test_delete_activity_should_return_not_found_with_invalid_id(client: FlaskCl 'delete', side_effect=NotFound) - response = client.delete("/activities/%s" % invalid_id, follow_redirects=True) + response = client.delete("/activities/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_activity_should_return_422_for_invalid_id_format(client: FlaskClient, mocker: MockFixture): +def test_delete_activity_should_return_422_for_invalid_id_format(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.activities.activities_namespace import activity_dao from werkzeug.exceptions import UnprocessableEntity @@ -215,8 +252,10 @@ def test_delete_activity_should_return_422_for_invalid_id_format(client: FlaskCl 'delete', side_effect=UnprocessableEntity) - response = client.delete("/activities/%s" % invalid_id, follow_redirects=True) + response = client.delete("/activities/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) diff --git a/tests/time_tracker_api/customers/customers_namespace_test.py b/tests/time_tracker_api/customers/customers_namespace_test.py index 707df28a..1777cbe8 100644 --- a/tests/time_tracker_api/customers/customers_namespace_test.py +++ b/tests/time_tracker_api/customers/customers_namespace_test.py @@ -4,8 +4,6 @@ from flask_restplus._http import HTTPStatus from pytest_mock import MockFixture -from time_tracker_api.security import current_user_tenant_id - fake = Faker() valid_customer_data = { @@ -15,41 +13,55 @@ } fake_customer = ({ - "id": fake.random_int(1, 9999) + "id": fake.random_int(1, 9999), }).update(valid_customer_data) -def test_create_customer_should_succeed_with_valid_request(client: FlaskClient, mocker: MockFixture): +def test_create_customer_should_succeed_with_valid_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao repository_create_mock = mocker.patch.object(customer_dao.repository, 'create', return_value=fake_customer) - response = client.post("/customers", json=valid_customer_data, follow_redirects=True) + response = client.post("/customers", + headers=valid_header, + json=valid_customer_data, + follow_redirects=True) assert HTTPStatus.CREATED == response.status_code repository_create_mock.assert_called_once() -def test_create_customer_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_create_customer_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao repository_create_mock = mocker.patch.object(customer_dao.repository, 'create', return_value=fake_customer) - response = client.post("/customers", json=None, follow_redirects=True) + response = client.post("/customers", + headers=valid_header, + json=None, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_create_mock.assert_not_called() -def test_list_all_customers(client: FlaskClient, mocker: MockFixture): +def test_list_all_customers(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao repository_find_all_mock = mocker.patch.object(customer_dao.repository, 'find_all', return_value=[]) - response = client.get("/customers", follow_redirects=True) + response = client.get("/customers", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code json_data = json.loads(response.data) @@ -57,7 +69,10 @@ def test_list_all_customers(client: FlaskClient, mocker: MockFixture): repository_find_all_mock.assert_called_once() -def test_get_customer_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_get_customer_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao valid_id = fake.random_int(1, 9999) @@ -66,15 +81,20 @@ def test_get_customer_should_succeed_with_valid_id(client: FlaskClient, mocker: 'find', return_value=fake_customer) - response = client.get("/customers/%s" % valid_id, follow_redirects=True) + response = client.get("/customers/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_customer == json.loads(response.data) repository_find_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_get_customer_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_get_customer_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao from werkzeug.exceptions import NotFound @@ -84,14 +104,19 @@ def test_get_customer_should_return_not_found_with_invalid_id(client: FlaskClien 'find', side_effect=NotFound) - response = client.get("/customers/%s" % invalid_id, follow_redirects=True) + response = client.get("/customers/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_get_customer_should_return_422_for_invalid_id_format(client: FlaskClient, mocker: MockFixture): +def test_get_customer_should_return_422_for_invalid_id_format(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao from werkzeug.exceptions import UnprocessableEntity @@ -101,14 +126,19 @@ def test_get_customer_should_return_422_for_invalid_id_format(client: FlaskClien 'find', side_effect=UnprocessableEntity) - response = client.get("/customers/%s" % invalid_id, follow_redirects=True) + response = client.get("/customers/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_customer_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture): +def test_update_customer_should_succeed_with_valid_data(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao repository_update_mock = mocker.patch.object(customer_dao.repository, @@ -116,29 +146,40 @@ def test_update_customer_should_succeed_with_valid_data(client: FlaskClient, moc return_value=fake_customer) valid_id = fake.random_int(1, 9999) - response = client.put("/customers/%s" % valid_id, json=valid_customer_data, follow_redirects=True) + response = client.put("/customers/%s" % valid_id, + headers=valid_header, + json=valid_customer_data, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_customer == json.loads(response.data) repository_update_mock.assert_called_once_with(str(valid_id), changes=valid_customer_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_customer_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_update_customer_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao repository_update_mock = mocker.patch.object(customer_dao.repository, 'partial_update', return_value=fake_customer) valid_id = fake.random_int(1, 9999) - response = client.put("/customers/%s" % valid_id, json=None, follow_redirects=True) + response = client.put("/customers/%s" % valid_id, + headers=valid_header, + json=None, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_update_mock.assert_not_called() -def test_update_customer_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_update_customer_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao from werkzeug.exceptions import NotFound @@ -149,16 +190,20 @@ def test_update_customer_should_return_not_found_with_invalid_id(client: FlaskCl side_effect=NotFound) response = client.put("/customers/%s" % invalid_id, + headers=valid_header, json=valid_customer_data, follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_update_mock.assert_called_once_with(str(invalid_id), changes=valid_customer_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_customer_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_customer_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao valid_id = fake.random_int(1, 9999) @@ -167,15 +212,20 @@ def test_delete_customer_should_succeed_with_valid_id(client: FlaskClient, mocke 'delete', return_value=None) - response = client.delete("/customers/%s" % valid_id, follow_redirects=True) + response = client.delete("/customers/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NO_CONTENT == response.status_code assert b'' == response.data repository_remove_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_customer_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_customer_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao from werkzeug.exceptions import NotFound @@ -185,14 +235,19 @@ def test_delete_customer_should_return_not_found_with_invalid_id(client: FlaskCl 'delete', side_effect=NotFound) - response = client.delete("/customers/%s" % invalid_id, follow_redirects=True) + response = client.delete("/customers/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_customer_should_return_422_for_invalid_id_format(client: FlaskClient, mocker: MockFixture): +def test_delete_customer_should_return_422_for_invalid_id_format(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.customers.customers_namespace import customer_dao from werkzeug.exceptions import UnprocessableEntity @@ -202,8 +257,10 @@ def test_delete_customer_should_return_422_for_invalid_id_format(client: FlaskCl 'delete', side_effect=UnprocessableEntity) - response = client.delete("/customers/%s" % invalid_id, follow_redirects=True) + response = client.delete("/customers/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) diff --git a/tests/time_tracker_api/project_types/project_types_namespace_test.py b/tests/time_tracker_api/project_types/project_types_namespace_test.py index 613b0cdc..3d0b3135 100644 --- a/tests/time_tracker_api/project_types/project_types_namespace_test.py +++ b/tests/time_tracker_api/project_types/project_types_namespace_test.py @@ -4,8 +4,6 @@ from flask_restplus._http import HTTPStatus from pytest_mock import MockFixture -from time_tracker_api.security import current_user_tenant_id - fake = Faker() valid_project_type_data = { @@ -21,19 +19,26 @@ }).update(valid_project_type_data) -def test_create_project_type_should_succeed_with_valid_request(client: FlaskClient, mocker: MockFixture): +def test_create_project_type_should_succeed_with_valid_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao repository_create_mock = mocker.patch.object(project_type_dao.repository, 'create', return_value=fake_project_type) - response = client.post("/project-types", json=valid_project_type_data, follow_redirects=True) + response = client.post("/project-types", + headers=valid_header, + json=valid_project_type_data, + follow_redirects=True) assert HTTPStatus.CREATED == response.status_code repository_create_mock.assert_called_once() -def test_create_project_type_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_create_project_type_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao invalid_project_type_data = valid_project_type_data.copy() invalid_project_type_data.update({ @@ -43,59 +48,77 @@ def test_create_project_type_should_reject_bad_request(client: FlaskClient, mock 'create', return_value=fake_project_type) - response = client.post("/project-types", json=invalid_project_type_data, follow_redirects=True) + response = client.post("/project-types", + headers=valid_header, + json=invalid_project_type_data, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_create_mock.assert_not_called() -def test_list_all_project_types(client: FlaskClient, mocker: MockFixture): +def test_list_all_project_types(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao repository_find_all_mock = mocker.patch.object(project_type_dao.repository, 'find_all', return_value=[]) - response = client.get("/project-types", follow_redirects=True) + response = client.get("/project-types", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code assert [] == json.loads(response.data) repository_find_all_mock.assert_called_once() -def test_get_project_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_get_project_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.project_types.project_types_namespace import project_type_dao valid_id = fake.random_int(1, 9999) repository_find_mock = mocker.patch.object(project_type_dao.repository, 'find', return_value=fake_project_type) - response = client.get("/project-types/%s" % valid_id, follow_redirects=True) + response = client.get("/project-types/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_project_type == json.loads(response.data) repository_find_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_get_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_get_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.project_types.project_types_namespace import project_type_dao from werkzeug.exceptions import NotFound - invalid_id = fake.random_int(1, 9999) + invalid_id = str(fake.random_int(1, 9999)) repository_find_mock = mocker.patch.object(project_type_dao.repository, 'find', side_effect=NotFound) - response = client.get("/project-types/%s" % invalid_id, follow_redirects=True) + response = client.get("/project-types/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code - repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + repository_find_mock.assert_called_once_with(invalid_id, partition_key_value=tenant_id) def test_get_project_should_response_with_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.project_types.project_types_namespace import project_type_dao from werkzeug.exceptions import UnprocessableEntity @@ -105,14 +128,19 @@ def test_get_project_should_response_with_unprocessable_entity_for_invalid_id_fo 'find', side_effect=UnprocessableEntity) - response = client.get("/project-types/%s" % invalid_id, follow_redirects=True) + response = client.get("/project-types/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_project_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_succeed_with_valid_data(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.project_types.project_types_namespace import project_type_dao repository_update_mock = mocker.patch.object(project_type_dao.repository, @@ -120,16 +148,21 @@ def test_update_project_should_succeed_with_valid_data(client: FlaskClient, mock return_value=fake_project_type) valid_id = fake.random_int(1, 9999) - response = client.put("/project-types/%s" % valid_id, json=valid_project_type_data, follow_redirects=True) + response = client.put("/project-types/%s" % valid_id, + headers=valid_header, + json=valid_project_type_data, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_project_type == json.loads(response.data) repository_update_mock.assert_called_once_with(str(valid_id), changes=valid_project_type_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_project_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao invalid_project_type_data = valid_project_type_data.copy() invalid_project_type_data.update({ @@ -140,13 +173,19 @@ def test_update_project_should_reject_bad_request(client: FlaskClient, mocker: M return_value=fake_project_type) valid_id = fake.random_int(1, 9999) - response = client.put("/project-types/%s" % valid_id, json=invalid_project_type_data, follow_redirects=True) + response = client.put("/project-types/%s" % valid_id, + headers=valid_header, + json=invalid_project_type_data, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_update_mock.assert_not_called() -def test_update_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao from werkzeug.exceptions import NotFound @@ -157,16 +196,20 @@ def test_update_project_should_return_not_found_with_invalid_id(client: FlaskCli side_effect=NotFound) response = client.put("/project-types/%s" % invalid_id, + headers=valid_header, json=valid_project_type_data, follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_update_mock.assert_called_once_with(str(invalid_id), changes=valid_project_type_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao valid_id = fake.random_int(1, 9999) @@ -175,15 +218,20 @@ def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, mocker 'delete', return_value=None) - response = client.delete("/project-types/%s" % valid_id, follow_redirects=True) + response = client.delete("/project-types/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NO_CONTENT == response.status_code assert b'' == response.data repository_remove_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao from werkzeug.exceptions import NotFound @@ -193,15 +241,19 @@ def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskCli 'delete', side_effect=NotFound) - response = client.delete("/project-types/%s" % invalid_id, follow_redirects=True) + response = client.delete("/project-types/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) def test_delete_project_should_return_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + tenant_id: str, + valid_header: dict): from time_tracker_api.project_types.project_types_namespace import project_type_dao from werkzeug.exceptions import UnprocessableEntity @@ -211,8 +263,10 @@ def test_delete_project_should_return_unprocessable_entity_for_invalid_id_format 'delete', side_effect=UnprocessableEntity) - response = client.delete("/project-types/%s" % invalid_id, follow_redirects=True) + response = client.delete("/project-types/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) diff --git a/tests/time_tracker_api/projects/projects_namespace_test.py b/tests/time_tracker_api/projects/projects_namespace_test.py index e8707dc3..6c7ff5eb 100644 --- a/tests/time_tracker_api/projects/projects_namespace_test.py +++ b/tests/time_tracker_api/projects/projects_namespace_test.py @@ -4,8 +4,6 @@ from flask_restplus._http import HTTPStatus from pytest_mock import MockFixture -from time_tracker_api.security import current_user_tenant_id - fake = Faker() valid_project_data = { @@ -20,19 +18,26 @@ }).update(valid_project_data) -def test_create_project_should_succeed_with_valid_request(client: FlaskClient, mocker: MockFixture): +def test_create_project_should_succeed_with_valid_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.projects.projects_namespace import project_dao repository_create_mock = mocker.patch.object(project_dao.repository, 'create', return_value=fake_project) - response = client.post("/projects", json=valid_project_data, follow_redirects=True) + response = client.post("/projects", + headers=valid_header, + json=valid_project_data, + follow_redirects=True) assert HTTPStatus.CREATED == response.status_code repository_create_mock.assert_called_once() -def test_create_project_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_create_project_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.projects.projects_namespace import project_dao invalid_project_data = valid_project_data.copy() invalid_project_data.update({ @@ -42,41 +47,56 @@ def test_create_project_should_reject_bad_request(client: FlaskClient, mocker: M 'create', return_value=fake_project) - response = client.post("/projects", json=invalid_project_data, follow_redirects=True) + response = client.post("/projects", + headers=valid_header, + json=invalid_project_data, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_create_mock.assert_not_called() -def test_list_all_projects(client: FlaskClient, mocker: MockFixture): +def test_list_all_projects(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.projects.projects_namespace import project_dao repository_find_all_mock = mocker.patch.object(project_dao.repository, 'find_all', return_value=[]) - response = client.get("/projects", follow_redirects=True) + response = client.get("/projects", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code assert [] == json.loads(response.data) repository_find_all_mock.assert_called_once() -def test_get_project_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_get_project_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao valid_id = fake.random_int(1, 9999) repository_find_mock = mocker.patch.object(project_dao.repository, 'find', return_value=fake_project) - response = client.get("/projects/%s" % valid_id, follow_redirects=True) + response = client.get("/projects/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_project == json.loads(response.data) repository_find_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_get_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_get_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao from werkzeug.exceptions import NotFound @@ -86,15 +106,19 @@ def test_get_project_should_return_not_found_with_invalid_id(client: FlaskClient 'find', side_effect=NotFound) - response = client.get("/projects/%s" % invalid_id, follow_redirects=True) + response = client.get("/projects/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) def test_get_project_should_response_with_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao from werkzeug.exceptions import UnprocessableEntity @@ -104,14 +128,19 @@ def test_get_project_should_response_with_unprocessable_entity_for_invalid_id_fo 'find', side_effect=UnprocessableEntity) - response = client.get("/projects/%s" % invalid_id, follow_redirects=True) + response = client.get("/projects/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_project_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_succeed_with_valid_data(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao repository_update_mock = mocker.patch.object(project_dao.repository, @@ -119,16 +148,21 @@ def test_update_project_should_succeed_with_valid_data(client: FlaskClient, mock return_value=fake_project) valid_id = fake.random_int(1, 9999) - response = client.put("/projects/%s" % valid_id, json=valid_project_data, follow_redirects=True) + response = client.put("/projects/%s" % valid_id, + headers=valid_header, + json=valid_project_data, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_project == json.loads(response.data) repository_update_mock.assert_called_once_with(str(valid_id), changes=valid_project_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_update_project_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.projects.projects_namespace import project_dao invalid_project_data = valid_project_data.copy() invalid_project_data.update({ @@ -139,13 +173,19 @@ def test_update_project_should_reject_bad_request(client: FlaskClient, mocker: M return_value=fake_project) valid_id = fake.random_int(1, 9999) - response = client.put("/projects/%s" % valid_id, json=invalid_project_data, follow_redirects=True) + response = client.put("/projects/%s" % valid_id, + headers=valid_header, + json=invalid_project_data, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_update_mock.assert_not_called() -def test_update_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_update_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao from werkzeug.exceptions import NotFound @@ -156,16 +196,20 @@ def test_update_project_should_return_not_found_with_invalid_id(client: FlaskCli side_effect=NotFound) response = client.put("/projects/%s" % invalid_id, + headers=valid_header, json=valid_project_data, follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_update_mock.assert_called_once_with(str(invalid_id), changes=valid_project_data, - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao valid_id = fake.random_int(1, 9999) @@ -174,15 +218,20 @@ def test_delete_project_should_succeed_with_valid_id(client: FlaskClient, mocker 'delete', return_value=None) - response = client.delete("/projects/%s" % valid_id, follow_redirects=True) + response = client.delete("/projects/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NO_CONTENT == response.status_code assert b'' == response.data repository_remove_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) -def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao from werkzeug.exceptions import NotFound @@ -192,15 +241,19 @@ def test_delete_project_should_return_not_found_with_invalid_id(client: FlaskCli 'delete', side_effect=NotFound) - response = client.delete("/projects/%s" % invalid_id, follow_redirects=True) + response = client.delete("/projects/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) def test_delete_project_should_return_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.projects.projects_namespace import project_dao from werkzeug.exceptions import UnprocessableEntity @@ -210,8 +263,10 @@ def test_delete_project_should_return_unprocessable_entity_for_invalid_id_format 'delete', side_effect=UnprocessableEntity) - response = client.delete("/projects/%s" % invalid_id, follow_redirects=True) + response = client.delete("/projects/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id()) + partition_key_value=tenant_id) diff --git a/tests/time_tracker_api/time_entries/time_entries_namespace_test.py b/tests/time_tracker_api/time_entries/time_entries_namespace_test.py index 34d34259..f3fe83bb 100644 --- a/tests/time_tracker_api/time_entries/time_entries_namespace_test.py +++ b/tests/time_tracker_api/time_entries/time_entries_namespace_test.py @@ -8,7 +8,6 @@ from pytest_mock import MockFixture from commons.data_access_layer.cosmos_db import current_datetime -from time_tracker_api.security import current_user_tenant_id fake = Faker() @@ -30,7 +29,8 @@ def test_create_time_entry_with_invalid_date_range_should_raise_bad_request_error(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_container_create_item_mock = mocker.patch.object(time_entries_dao.repository.container, 'create_item', @@ -40,14 +40,18 @@ def test_create_time_entry_with_invalid_date_range_should_raise_bad_request_erro invalid_time_entry_input.update({ "end_date": str(yesterday.isoformat()) }) - response = client.post("/time-entries", json=invalid_time_entry_input, follow_redirects=True) + response = client.post("/time-entries", + headers=valid_header, + json=invalid_time_entry_input, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_container_create_item_mock.assert_not_called() def test_create_time_entry_with_end_date_in_future_should_raise_bad_request_error(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_container_create_item_mock = mocker.patch.object(time_entries_dao.repository.container, 'create_item', @@ -56,25 +60,35 @@ def test_create_time_entry_with_end_date_in_future_should_raise_bad_request_erro invalid_time_entry_input.update({ "end_date": str(fake.future_datetime().isoformat()) }) - response = client.post("/time-entries", json=invalid_time_entry_input, follow_redirects=True) + response = client.post("/time-entries", + headers=valid_header, + json=invalid_time_entry_input, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_container_create_item_mock.assert_not_called() -def test_create_time_entry_should_succeed_with_valid_request(client: FlaskClient, mocker: MockFixture): +def test_create_time_entry_should_succeed_with_valid_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_create_mock = mocker.patch.object(time_entries_dao.repository, 'create', return_value=fake_time_entry) - response = client.post("/time-entries", json=valid_time_entry_input, follow_redirects=True) + response = client.post("/time-entries", + headers=valid_header, + json=valid_time_entry_input, + follow_redirects=True) assert HTTPStatus.CREATED == response.status_code repository_create_mock.assert_called_once() -def test_create_time_entry_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_create_time_entry_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao invalid_time_entry_input = valid_time_entry_input.copy() invalid_time_entry_input.update({ @@ -84,43 +98,57 @@ def test_create_time_entry_should_reject_bad_request(client: FlaskClient, mocker 'create', return_value=fake_time_entry) - response = client.post("/time-entries", json=invalid_time_entry_input, follow_redirects=True) + response = client.post("/time-entries", + headers=valid_header, + json=invalid_time_entry_input, + follow_redirects=True) assert HTTPStatus.BAD_REQUEST == response.status_code repository_create_mock.assert_not_called() -def test_list_all_time_entries(client: FlaskClient, mocker: MockFixture): +def test_list_all_time_entries(client: FlaskClient, + mocker: MockFixture, + valid_header: dict): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_find_all_mock = mocker.patch.object(time_entries_dao.repository, 'find_all', return_value=[]) - response = client.get("/time-entries", follow_redirects=True) + response = client.get("/time-entries", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code assert [] == json.loads(response.data) repository_find_all_mock.assert_called_once() -def test_get_time_entry_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_get_time_entry_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_find_mock = mocker.patch.object(time_entries_dao.repository, 'find', return_value=fake_time_entry) valid_id = fake.random_int(1, 9999) - response = client.get("/time-entries/%s" % valid_id, follow_redirects=True) + response = client.get("/time-entries/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code fake_time_entry == json.loads(response.data) repository_find_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) def test_get_time_entry_should_response_with_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import UnprocessableEntity @@ -130,15 +158,20 @@ def test_get_time_entry_should_response_with_unprocessable_entity_for_invalid_id 'find', side_effect=UnprocessableEntity) - response = client.get("/time-entries/%s" % invalid_id, follow_redirects=True) + response = client.get("/time-entries/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_find_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_update_time_entry_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture): +def test_update_time_entry_should_succeed_with_valid_data(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_update_mock = mocker.patch.object(time_entries_dao.repository, 'partial_update', @@ -146,6 +179,7 @@ def test_update_time_entry_should_succeed_with_valid_data(client: FlaskClient, m valid_id = fake.random_int(1, 9999) response = client.put("/time-entries/%s" % valid_id, + headers=valid_header, json=valid_time_entry_input, follow_redirects=True) @@ -153,11 +187,14 @@ def test_update_time_entry_should_succeed_with_valid_data(client: FlaskClient, m fake_time_entry == json.loads(response.data) repository_update_mock.assert_called_once_with(str(valid_id), changes=valid_time_entry_input, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_update_time_entry_should_reject_bad_request(client: FlaskClient, mocker: MockFixture): +def test_update_time_entry_should_reject_bad_request(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao invalid_time_entry_data = valid_time_entry_input.copy() invalid_time_entry_data.update({ @@ -169,6 +206,7 @@ def test_update_time_entry_should_reject_bad_request(client: FlaskClient, mocker valid_id = fake.random_int(1, 9999) response = client.put("/time-entries/%s" % valid_id, + headers=valid_header, json=invalid_time_entry_data, follow_redirects=True) @@ -176,7 +214,10 @@ def test_update_time_entry_should_reject_bad_request(client: FlaskClient, mocker repository_update_mock.assert_not_called() -def test_update_time_entry_should_return_not_found_with_invalid_id(client: FlaskClient, mocker: MockFixture): +def test_update_time_entry_should_return_not_found_with_invalid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import NotFound repository_update_mock = mocker.patch.object(time_entries_dao.repository, @@ -185,34 +226,42 @@ def test_update_time_entry_should_return_not_found_with_invalid_id(client: Flask invalid_id = fake.random_int(1, 9999) response = client.put("/time-entries/%s" % invalid_id, + headers=valid_header, json=valid_time_entry_input, follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_update_mock.assert_called_once_with(str(invalid_id), changes=valid_time_entry_input, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_delete_time_entry_should_succeed_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_delete_time_entry_should_succeed_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_remove_mock = mocker.patch.object(time_entries_dao.repository, 'delete', return_value=None) valid_id = fake.random_int(1, 9999) - response = client.delete("/time-entries/%s" % valid_id, follow_redirects=True) + response = client.delete("/time-entries/%s" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NO_CONTENT == response.status_code assert b'' == response.data repository_remove_mock.assert_called_once_with(str(valid_id), - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) def test_delete_time_entry_should_return_not_found_with_invalid_id(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import NotFound repository_remove_mock = mocker.patch.object(time_entries_dao.repository, @@ -220,16 +269,20 @@ def test_delete_time_entry_should_return_not_found_with_invalid_id(client: Flask side_effect=NotFound) invalid_id = fake.random_int(1, 9999) - response = client.delete("/time-entries/%s" % invalid_id, follow_redirects=True) + response = client.delete("/time-entries/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) def test_delete_time_entry_should_return_unprocessable_entity_for_invalid_id_format(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import UnprocessableEntity repository_remove_mock = mocker.patch.object(time_entries_dao.repository, @@ -237,31 +290,41 @@ def test_delete_time_entry_should_return_unprocessable_entity_for_invalid_id_for side_effect=UnprocessableEntity) invalid_id = fake.word() - response = client.delete("/time-entries/%s" % invalid_id, follow_redirects=True) + response = client.delete("/time-entries/%s" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_remove_mock.assert_called_once_with(str(invalid_id), - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_stop_time_entry_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_stop_time_entry_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_update_mock = mocker.patch.object(time_entries_dao.repository, 'partial_update', return_value=fake_time_entry) valid_id = fake.random_int(1, 9999) - response = client.post("/time-entries/%s/stop" % valid_id, follow_redirects=True) + response = client.post("/time-entries/%s/stop" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code repository_update_mock.assert_called_once_with(str(valid_id), changes={"end_date": mocker.ANY}, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_stop_time_entry_with_id_with_invalid_format(client: FlaskClient, mocker: MockFixture): +def test_stop_time_entry_with_id_with_invalid_format(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import UnprocessableEntity repository_update_mock = mocker.patch.object(time_entries_dao.repository, @@ -269,32 +332,42 @@ def test_stop_time_entry_with_id_with_invalid_format(client: FlaskClient, mocker side_effect=UnprocessableEntity) invalid_id = fake.word() - response = client.post("/time-entries/%s/stop" % invalid_id, follow_redirects=True) + response = client.post("/time-entries/%s/stop" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_update_mock.assert_called_once_with(invalid_id, changes={"end_date": ANY}, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_restart_time_entry_with_valid_id(client: FlaskClient, mocker: MockFixture): +def test_restart_time_entry_with_valid_id(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_update_mock = mocker.patch.object(time_entries_dao.repository, 'partial_update', return_value=fake_time_entry) valid_id = fake.random_int(1, 9999) - response = client.post("/time-entries/%s/restart" % valid_id, follow_redirects=True) + response = client.post("/time-entries/%s/restart" % valid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code repository_update_mock.assert_called_once_with(str(valid_id), changes={"end_date": None}, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_restart_time_entry_with_id_with_invalid_format(client: FlaskClient, mocker: MockFixture): +def test_restart_time_entry_with_id_with_invalid_format(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao from werkzeug.exceptions import UnprocessableEntity repository_update_mock = mocker.patch.object(time_entries_dao.repository, @@ -303,36 +376,47 @@ def test_restart_time_entry_with_id_with_invalid_format(client: FlaskClient, moc peeker=ANY) invalid_id = fake.word() - response = client.post("/time-entries/%s/restart" % invalid_id, follow_redirects=True) + response = client.post("/time-entries/%s/restart" % invalid_id, + headers=valid_header, + follow_redirects=True) assert HTTPStatus.UNPROCESSABLE_ENTITY == response.status_code repository_update_mock.assert_called_once_with(invalid_id, changes={"end_date": None}, - partition_key_value=current_user_tenant_id(), + partition_key_value=tenant_id, peeker=ANY) -def test_get_running_should_call_find_running(client: FlaskClient, mocker: MockFixture): +def test_get_running_should_call_find_running(client: FlaskClient, + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_update_mock = mocker.patch.object(time_entries_dao.repository, 'find_running', return_value=fake_time_entry) - response = client.get("/time-entries/running", follow_redirects=True) + response = client.get("/time-entries/running", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.OK == response.status_code assert json.loads(response.data) is not None - repository_update_mock.assert_called_once_with(partition_key_value=current_user_tenant_id()) + repository_update_mock.assert_called_once_with(partition_key_value=tenant_id) def test_get_running_should_return_not_found_if_find_running_throws_StopIteration(client: FlaskClient, - mocker: MockFixture): + mocker: MockFixture, + valid_header: dict, + tenant_id: str): from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao repository_update_mock = mocker.patch.object(time_entries_dao.repository, 'find_running', side_effect=StopIteration) - response = client.get("/time-entries/running", follow_redirects=True) + response = client.get("/time-entries/running", + headers=valid_header, + follow_redirects=True) assert HTTPStatus.NOT_FOUND == response.status_code - repository_update_mock.assert_called_once_with(partition_key_value=current_user_tenant_id()) + repository_update_mock.assert_called_once_with(partition_key_value=tenant_id)