Skip to content

Commit 4ce4612

Browse files
author
EliuX
committed
Apply requested changes
1 parent e1eacf7 commit 4ce4612

File tree

9 files changed

+58
-28
lines changed

9 files changed

+58
-28
lines changed

.env.template

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Package where the app is located
2+
export FLASK_APP=time_tracker_api
3+
4+
# The database connection URI. Check out the README.md for more details
5+
DATABASE_URI=mssql+pyodbc://<user>:<password>@time-tracker-srv.database.windows.net/<database>?driver\=ODBC Driver 17 for SQL Server

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ htmlcov/
2727
.env
2828
timetracker-api-postman-collection.json
2929
swagger.json
30+
31+
# Ignore any SQLite generated database
32+
*.db

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,34 @@ a link to the swagger.json with the definition of the api.
8787
## Development
8888
8989
### Test
90-
We are using Pytest](https://docs.pytest.org/en/latest/index.html) for tests. The tests are located in the package
90+
We are using [Pytest](https://docs.pytest.org/en/latest/index.html) for tests. The tests are located in the package
9191
`tests` and use the [conventions for python test discovery](https://docs.pytest.org/en/latest/goodpractices.html#test-discovery).
9292
93-
To run the tests just execute:
93+
#### Integration tests
94+
The [integrations tests](https://en.wikipedia.org/wiki/Integration_testing) verifies that all the components of the app
95+
are working well together. These are the default tests we should run:
9496
95-
```bash
97+
```dotenv
98+
python3 -m pytest -v --ignore=tests/sql_repository_test.py
99+
```
100+
101+
As you may have noticed we are ignoring the tests related with the repository.
102+
103+
104+
#### System tests
105+
In addition to the integration testing we might include tests to the data access layer in order to verify that the
106+
persisted data is being managed the right way, i.e. it actually works. We may classify the execution of all the existing
107+
tests as [system testing](https://en.wikipedia.org/wiki/System_testing):
108+
109+
```dotenv
96110
python3 -m pytest -v
97111
```
98112

113+
The database tests will be done in the table `tests` of the database specified by the variable `DATABASE_URI`. If this
114+
variable is not specified it will automatically connect to `sqlite:///tests.db`. This will do, because we are using SQL
115+
Alchemy to be able connect to any SQL database maintaining the same codebase.
116+
117+
99118
The option `-v` shows which tests failed or succeeded. Have into account that you can also debug each test
100119
(test_* files) with the help of an IDE like PyCharm.
101120

run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"""
55
from time_tracker_api import create_app
66

7-
app = create_app()
8-
print("TimeTracker API server was created")
7+
app = create_app('time_tracker_api.config.ProductionConfig')
8+
print("TimeTracker API server created!")

tests/conftest.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55

66
from time_tracker_api import create_app
77

8-
CONFIGURATIONS = ['AzureSQLDatabaseDevelopTestConfig']
98

10-
11-
@pytest.fixture(scope='session', params=CONFIGURATIONS)
9+
@pytest.fixture(scope='session')
1210
def app(request: FixtureRequest) -> Flask:
13-
return create_app("time_tracker_api.config.%s" % request.param)
11+
return create_app("time_tracker_api.config.TestConfig")
1412

1513

1614
@pytest.fixture

tests/projects/projects_namespace_test.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def test_get_project_should_return_422_for_invalid_id_format(client: FlaskClient
106106
repository_find_mock.assert_called_once_with(str(invalid_id))
107107

108108

109-
def update_project_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture):
109+
def test_update_project_should_succeed_with_valid_data(client: FlaskClient, mocker: MockFixture):
110110
from time_tracker_api.projects.projects_namespace import project_dao
111111

112112
repository_update_mock = mocker.patch.object(project_dao.repository,
@@ -118,7 +118,7 @@ def update_project_should_succeed_with_valid_data(client: FlaskClient, mocker: M
118118

119119
assert 200 == response.status_code
120120
fake_project == json.loads(response.data)
121-
repository_update_mock.assert_called_once_with(valid_id, valid_project_data)
121+
repository_update_mock.assert_called_once_with(str(valid_id), valid_project_data)
122122

123123

124124
def test_update_project_should_reject_bad_request(client: FlaskClient, mocker: MockFixture):
@@ -147,7 +147,9 @@ def test_update_project_should_return_not_found_with_invalid_id(client: FlaskCli
147147
'update',
148148
side_effect=NotFound)
149149

150-
response = client.put("/projects/%s" % invalid_id, json=valid_project_data, follow_redirects=True)
150+
response = client.put("/projects/%s" % invalid_id,
151+
json=valid_project_data,
152+
follow_redirects=True)
151153

152154
assert 404 == response.status_code
153155
repository_update_mock.assert_called_once_with(str(invalid_id), valid_project_data)
@@ -192,8 +194,8 @@ def test_delete_project_should_return_422_for_invalid_id_format(client: FlaskCli
192194
invalid_id = fake.company()
193195

194196
repository_remove_mock = mocker.patch.object(project_dao.repository,
195-
'remove',
196-
side_effect=UnprocessableEntity)
197+
'remove',
198+
side_effect=UnprocessableEntity)
197199

198200
response = client.delete("/projects/%s" % invalid_id, follow_redirects=True)
199201

time_tracker_api/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ def init_app(app: Flask):
4646
add_debug_toolbar(app)
4747

4848

49-
5049
def add_debug_toolbar(app):
5150
app.config['DEBUG_TB_PANELS'] = (
5251
'flask_debugtoolbar.panels.versions.VersionDebugPanel',

time_tracker_api/config.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,44 @@ class Config:
1010
RESTPLUS_VALIDATE = True
1111

1212

13-
class DevelopConfig(Config):
13+
class DevelopmentConfig(Config):
1414
DEBUG = True
1515
FLASK_DEBUG = True
16-
FLASK_ENV = "develop"
16+
FLASK_ENV = "development"
1717

1818

19-
class TestConfig(Config):
19+
class SQLConfig(Config):
20+
SQLALCHEMY_DATABASE_URI = Config.DATABASE_URI
21+
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
22+
SQLALCHEMY_TRACK_MODIFICATIONS = False
23+
24+
25+
class TestConfig(SQLConfig):
2026
TESTING = True
2127
FLASK_DEBUG = True
2228
TEST_TABLE = 'tests'
29+
DATABASE_URI = os.environ.get('DATABASE_URI', 'sqlite:///tests.db')
30+
SQLALCHEMY_DATABASE_URI = DATABASE_URI
2331

2432

25-
class SQLConfig(Config):
26-
SQLALCHEMY_DATABASE_URI = Config.DATABASE_URI
27-
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
28-
SQLALCHEMY_TRACK_MODIFICATIONS = False
33+
class ProductionConfig(Config):
34+
FLASK_ENV = 'production'
2935

3036

3137
class AzureConfig(SQLConfig):
3238
pass
3339

3440

35-
class AzureSQLDatabaseDevelopConfig(DevelopConfig, AzureConfig):
41+
class AzureDevelopmentConfig(DevelopmentConfig, AzureConfig):
3642
pass
3743

3844

39-
class AzureSQLDatabaseDevelopTestConfig(TestConfig, AzureSQLDatabaseDevelopConfig):
45+
class AzureProductionConfig(ProductionConfig, AzureConfig):
4046
pass
4147

4248

43-
DefaultConfig = AzureSQLDatabaseDevelopConfig
49+
DefaultConfig = AzureDevelopmentConfig
50+
ProductionConfig = AzureProductionConfig
4451

4552

4653
class CLIConfig(DefaultConfig):

time_tracker_api/database.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
To know more about protocols and subtyping check out PEP-0544
77
"""
88
import abc
9-
import enum
10-
from datetime import datetime
119

1210
from flask import Flask
1311

@@ -75,4 +73,3 @@ def init_app(app: Flask) -> None:
7573
init_app(app)
7674
global seeder
7775
seeder = SQLSeeder()
78-

0 commit comments

Comments
 (0)