Skip to content

Commit abf19f8

Browse files
author
EliuX
committed
Refactor codebase to use solution of #25
1 parent 80c41eb commit abf19f8

23 files changed

+516
-198
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ automatically [pip](https://pip.pypa.io/en/stable/) as well.
3939
4040
4141
- Install the [Microsoft ODBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server?view=sql-server-ver15)
42-
in your operative system. Then you have to check out how is called the SQL Driver installation.
42+
in your operative system. Then you have to check out what is the name of the SQL Driver installation.
4343
Check it out with:
4444
4545
```bash
@@ -55,7 +55,7 @@ Driver=/usr/local/lib/libmsodbcsql.17.dylib
5555
UsageCount=2
5656
```
5757

58-
Then when you specify the driver name, e.g. _DBC Driver 17 for SQL Server_ in the `DATABASE_URI`. E.g.
58+
Then specify the driver name, in this case _DBC Driver 17 for SQL Server_ in the `DATABASE_URI`, e.g.:
5959

6060
```.dotenv
6161
DATABASE_URI=mssql+pyodbc://<user>:<password>@time-tracker-srv.database.windows.net/<database>?driver\=ODBC Driver 17 for SQL Server

cli.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
from flask_script import Manager
77

88
from time_tracker_api import create_app
9+
10+
app = create_app('time_tracker_api.config.CLIConfig')
11+
912
from time_tracker_api.api import api
1013

11-
app = create_app()
1214
cli_manager = Manager(app)
1315

1416

@@ -44,6 +46,23 @@ def gen_postman_collection(filename='timetracker-api-postman-collection.json',
4446
save_data(parsed_json, filename)
4547

4648

49+
@cli_manager.command
50+
def seed():
51+
from time_tracker_api.database import seeder as seed
52+
seed()
53+
54+
55+
@cli_manager.command
56+
def re_create_db():
57+
print('This is going to drop all tables and seed again the database')
58+
confirm_answer = input('Do you confirm (Y) you want to remove all your data?\n')
59+
if confirm_answer.upper() == 'Y':
60+
from time_tracker_api.database import seeder
61+
seeder.fresh()
62+
else:
63+
print('\nThis action was cancelled!')
64+
65+
4766
def save_data(data: str, filename: str) -> None:
4867
""" Save text content to a file """
4968
if filename:

requirements/dev.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ Faker==4.0.2
1414
# Coverage
1515
coverage==4.5.1
1616

17-
# SQL database (MS SQL)
18-
flask_sqlalchemy==2.4.1
17+
# The Debug Toolbar
18+
Flask-DebugToolbar==0.11.0

requirements/prod.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ Jinja2==2.11.1
1313
gunicorn==20.0.4
1414

1515
#Swagger support for Restful API
16-
flask-restplus==0.13.0
16+
flask-restplus==0.12.1
1717

1818
#CLI support
19-
Flask-Script==2.0.6
19+
Flask-Script==2.0.6
20+
21+
# SQL database (MS SQL)
22+
flask_sqlalchemy==2.4.1
23+
24+
# Handling requests
25+
requests==2.23.0

tests/conftest.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ def client(app: Flask) -> FlaskClient:
2222

2323

2424
@pytest.fixture(scope="module")
25-
def sql_repository(app: Flask):
26-
with app.app_context():
27-
from .resources import TestModel
28-
from time_tracker_api.sql_repository import db
25+
def sql_repository():
26+
from .resources import PersonSQLModel
27+
from time_tracker_api.database import seeder
28+
from time_tracker_api.sql_repository import db
2929

30-
db.create_all()
31-
print("Models for test created!")
30+
seeder.fresh()
3231

33-
from time_tracker_api.sql_repository import SQLRepository
34-
yield SQLRepository(TestModel)
32+
from time_tracker_api.sql_repository import SQLRepository
33+
yield SQLRepository(PersonSQLModel)
3534

36-
print("Models for test removed!")
37-
db.drop_all()
35+
db.drop_all()
36+
print("Models for test removed!")
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
from flask import json
2+
from flask.testing import FlaskClient
3+
from pytest_mock import MockFixture
24

35

4-
def test_list_should_return_nothing(client):
5-
"""Should return an empty array"""
6+
def test_list_all_elements(client: FlaskClient, mocker: MockFixture):
7+
"""Should return all elements in a list"""
8+
from time_tracker_api.projects.projects_namespace import project_dao
9+
repository_find_all_mock = mocker.patch.object(project_dao.repository, 'find_all', return_value=[])
10+
611
response = client.get("/projects", follow_redirects=True)
712

813
assert 200 == response.status_code
914

1015
json_data = json.loads(response.data)
1116
assert [] == json_data
17+
repository_find_all_mock.assert_called_once()

tests/resources.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
from time_tracker_api.sql_repository import db
1+
from time_tracker_api.sql_repository import db, SQLAuditedModel
22

33

4-
class TestModel(db.Model):
4+
class PersonSQLModel(db.Model, SQLAuditedModel):
5+
__tablename__ = 'tests'
56
id = db.Column(db.Integer, primary_key=True)
6-
name = db.Column(db.String(80), unique=True, nullable=False)
7+
name = db.Column(db.String(80), unique=False, nullable=False)
78
email = db.Column(db.String(120), unique=True, nullable=False)
89
age = db.Column(db.Integer, nullable=False)
910

tests/smoke_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
def test_app_exists(app):
32
"""Does app exists"""
43
assert app is not None

tests/sql_repository_test.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@
88

99
def test_create(sql_repository):
1010
"""Should create a new Entry"""
11-
from .resources import TestModel
1211
global sample_element
13-
sample_element = TestModel(name=fake.name(),
14-
email=fake.safe_email(),
15-
age=fake.pyint(min_value=10, max_value=80))
12+
sample_element = dict(name=fake.name(),
13+
email=fake.safe_email(),
14+
age=fake.pyint(min_value=10, max_value=80))
1615

1716
result = sql_repository.create(sample_element)
1817

1918
assert result is not None
2019
assert result.id is not None
20+
assert result.created_at is not None
21+
assert result.created_by is not None
22+
assert result.updated_at is None
23+
assert result.updated_by is None
2124

2225
existing_elements_registry.append(result)
2326

@@ -43,6 +46,9 @@ def test_update(sql_repository):
4346
assert updated_element.id == existing_element.id
4447
assert updated_element.name == "Jon Snow"
4548
assert updated_element.age == 34
49+
assert updated_element.updated_at is not None
50+
assert updated_element.updated_at > updated_element.created_at
51+
assert updated_element.updated_by is not None
4652

4753

4854
def test_find_all(sql_repository):
@@ -54,10 +60,10 @@ def test_find_all(sql_repository):
5460

5561
def test_find_all_that_contains_property_with_string(sql_repository):
5662
"""Find all elements that have a property that partially contains a string (case-insensitive)"""
57-
from .resources import TestModel
58-
new_element = TestModel(name='Ramsay Snow',
59-
email=fake.safe_email(),
60-
age=fake.pyint(min_value=10, max_value=80))
63+
fake_name = fake.name()
64+
new_element = dict(name="%s Snow" % fake_name,
65+
email=fake.safe_email(),
66+
age=fake.pyint(min_value=10, max_value=80))
6167
sql_repository.create(new_element)
6268
existing_elements_registry.append(new_element)
6369

@@ -67,8 +73,8 @@ def test_find_all_that_contains_property_with_string(sql_repository):
6773
search_jon_result = sql_repository.find_all_contain_str('name', 'Jon')
6874
assert len(search_jon_result) == 1
6975

70-
search_ram_result = sql_repository.find_all_contain_str('name', 'RAM')
71-
assert search_ram_result[0] is new_element
76+
search_ram_result = sql_repository.find_all_contain_str('name', fake_name)
77+
assert search_ram_result[0].name == new_element['name']
7278

7379

7480
def test_delete_existing_element(sql_repository):

tests/time_entries/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)