Skip to content

Commit 80c41eb

Browse files
author
EliuX
committed
Fixes #25 Tests sql repository
1 parent f9e6b9d commit 80c41eb

File tree

4 files changed

+132
-16
lines changed

4 files changed

+132
-16
lines changed

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,35 @@ automatically [pip](https://pip.pypa.io/en/stable/) as well.
3636
3737
The `stage` can be `dev` or `prod`.
3838
Remember to do it with Python 3.
39+
40+
41+
- 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.
43+
Check it out with:
44+
45+
```bash
46+
vim /usr/local/etc/odbcinst.ini
47+
```
48+
49+
It may display something like
50+
51+
```.ini
52+
[ODBC Driver 17 for SQL Server]
53+
Description=Microsoft ODBC Driver 17 for SQL Server
54+
Driver=/usr/local/lib/libmsodbcsql.17.dylib
55+
UsageCount=2
56+
```
57+
58+
Then when you specify the driver name, e.g. _DBC Driver 17 for SQL Server_ in the `DATABASE_URI`. E.g.
59+
60+
```.dotenv
61+
DATABASE_URI=mssql+pyodbc://<user>:<password>@time-tracker-srv.database.windows.net/<database>?driver\=ODBC Driver 17 for SQL Server
62+
```
63+
64+
To troubleshoot issues regarding this part please check out:
65+
- [Install the Microsoft ODBC driver for SQL Server (macOS)](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/install-microsoft-odbc-driver-sql-server-macos?view=sql-server-ver15).
66+
- Github issue [odbcinst: SQLRemoveDriver failed with Unable to find component name](https://github.com/Microsoft/homebrew-mssql-preview/issues/2).
67+
- Stack overflow solution to [Can't open lib 'ODBC Driver 13 for SQL Server'? Sym linking issue?](https://stackoverflow.com/questions/44527452/cant-open-lib-odbc-driver-13-for-sql-server-sym-linking-issue).
3968

4069
### How to use it
4170
- Set the env var `FLASK_APP` to `time_tracker_api` and start the app:
@@ -122,7 +151,6 @@ the win.
122151
[API import restrictions and known issues](https://docs.microsoft.com/en-us/azure/api-management/api-management-api-import-restrictions)
123152
in Azure.
124153

125-
126154
## License
127155

128156
Copyright 2020 ioet Inc. All Rights Reserved.

tests/conftest.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def client(app: Flask) -> FlaskClient:
2121
return c
2222

2323

24-
@pytest.fixture()
25-
def repository(app: Flask):
24+
@pytest.fixture(scope="module")
25+
def sql_repository(app: Flask):
2626
with app.app_context():
2727
from .resources import TestModel
2828
from time_tracker_api.sql_repository import db
@@ -31,4 +31,7 @@ def repository(app: Flask):
3131
print("Models for test created!")
3232

3333
from time_tracker_api.sql_repository import SQLRepository
34-
return SQLRepository(TestModel)
34+
yield SQLRepository(TestModel)
35+
36+
print("Models for test removed!")
37+
db.drop_all()

tests/sql_repository_test.py

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,83 @@
11
from faker import Faker
2-
from flask import Flask
32

43
fake = Faker()
54

5+
existing_elements_registry = []
6+
last_deleted_element = None
67

7-
def test_create_entry(repository, app: Flask):
8+
9+
def test_create(sql_repository):
810
"""Should create a new Entry"""
9-
assert repository is not None
1011
from .resources import TestModel
11-
sample_model = TestModel(name=fake.name(),
12-
email=fake.safe_email(),
13-
age = fake.pyint(min_value=10, max_value=80))
12+
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))
16+
17+
result = sql_repository.create(sample_element)
18+
19+
assert result is not None
20+
assert result.id is not None
21+
22+
existing_elements_registry.append(result)
23+
24+
25+
def test_find(sql_repository):
26+
"""Should find created element"""
27+
existing_element = existing_elements_registry[0]
28+
29+
found_element = sql_repository.find(existing_element.id)
30+
31+
assert found_element is not None
32+
assert found_element.id is not None
33+
34+
35+
def test_update(sql_repository):
36+
"""Updates an existing element"""
37+
existing_element = existing_elements_registry[0]
38+
39+
updated_element = sql_repository.update(existing_element.id,
40+
dict(name="Jon Snow", age=34))
41+
42+
assert updated_element is not None
43+
assert updated_element.id == existing_element.id
44+
assert updated_element.name == "Jon Snow"
45+
assert updated_element.age == 34
46+
47+
48+
def test_find_all(sql_repository):
49+
"""Find all existing elements"""
50+
existing_elements = sql_repository.find_all()
51+
52+
assert all(e in existing_elements_registry for e in existing_elements)
53+
54+
55+
def test_find_all_that_contains_property_with_string(sql_repository):
56+
"""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))
61+
sql_repository.create(new_element)
62+
existing_elements_registry.append(new_element)
63+
64+
search_snow_result = sql_repository.find_all_contain_str('name', 'Snow')
65+
assert len(search_snow_result) == 2
66+
67+
search_jon_result = sql_repository.find_all_contain_str('name', 'Jon')
68+
assert len(search_jon_result) == 1
69+
70+
search_ram_result = sql_repository.find_all_contain_str('name', 'RAM')
71+
assert search_ram_result[0] is new_element
72+
73+
74+
def test_delete_existing_element(sql_repository):
75+
"""Should delete created element"""
76+
existing_element = existing_elements_registry[0]
77+
78+
result = sql_repository.remove(existing_element.id)
79+
80+
assert result is None
1481

15-
repository.create(sample_model)
82+
global last_deleted_model
83+
last_deleted_model = existing_elements_registry.pop()

time_tracker_api/sql_repository.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import urllib.parse
2-
31
from flask import Flask
42
from flask_sqlalchemy import SQLAlchemy
53

@@ -16,12 +14,31 @@ class SQLRepository():
1614
def __init__(self, model_type: type):
1715
self.model_type = model_type
1816

19-
def create(self, model: dict) -> dict:
20-
db.session.add(model)
17+
def create(self, element: dict) -> dict:
18+
db.session.add(element)
2119
db.session.commit()
20+
return element
21+
22+
def find(self, id: int) -> dict:
23+
return self.model_type.query.filter_by(id=id).first_or_404()
2224

23-
def find_all(self):
25+
def find_all(self) -> list:
2426
return self.model_type.query.all()
2527

28+
def update(self, id: int, new_data: dict) -> dict:
29+
model = self.model_type.query.filter_by(id=id)
30+
model.update(new_data)
31+
return model.first_or_404()
32+
33+
def remove(self, id: int) -> None:
34+
found_element = self.find(id)
35+
db.session.delete(found_element)
36+
db.session.commit()
37+
38+
def find_all_contain_str(self, property, text) -> list:
39+
return self.model_type.query\
40+
.filter(getattr(self.model_type, property).contains(text))\
41+
.all()
42+
2643

2744
repository_model = SQLRepository

0 commit comments

Comments
 (0)