Skip to content

Commit 650d8e4

Browse files
committed
use uow in services, flask app
1 parent 56d335a commit 650d8e4

File tree

5 files changed

+46
-43
lines changed

5 files changed

+46
-43
lines changed

src/allocation/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22

3+
34
def get_postgres_uri():
45
host = os.environ.get('DB_HOST', 'localhost')
56
port = 54321 if host == 'localhost' else 5432

src/allocation/flask_app.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,35 @@
11
from datetime import datetime
22
from flask import Flask, jsonify, request
3-
from sqlalchemy import create_engine
4-
from sqlalchemy.orm import sessionmaker
53

6-
from allocation import config
7-
from allocation import orm
8-
from allocation import repository
4+
from allocation import unit_of_work
95
from allocation import model
106
from allocation import services
7+
from allocation import orm
118

12-
orm.start_mappers()
13-
get_session = sessionmaker(bind=create_engine(config.get_postgres_uri()))
149
app = Flask(__name__)
10+
orm.start_mappers()
1511

1612

1713
@app.route("/add_batch", methods=['POST'])
1814
def add_batch():
19-
session = get_session()
20-
repo = repository.SqlAlchemyRepository(session)
2115
eta = request.json['eta']
2216
if eta is not None:
2317
eta = datetime.fromisoformat(eta).date()
2418
services.add_batch(
2519
request.json['ref'], request.json['sku'], request.json['qty'], eta,
26-
repo, session
20+
unit_of_work.SqlAlchemyUnitOfWork(),
2721
)
2822
return 'OK', 201
2923

3024

3125
@app.route("/allocate", methods=['POST'])
3226
def allocate_endpoint():
33-
session = get_session()
34-
repo = repository.SqlAlchemyRepository(session)
3527
try:
3628
batchref = services.allocate(
3729
request.json['orderid'],
3830
request.json['sku'],
3931
request.json['qty'],
40-
repo, session
32+
unit_of_work.SqlAlchemyUnitOfWork(),
4133
)
4234
except (model.OutOfStock, services.InvalidSku) as e:
4335
return jsonify({'message': str(e)}), 400

src/allocation/services.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from datetime import date
44

55
from allocation.model import OrderLine
6-
from allocation.repository import AbstractRepository
7-
from allocation import model
6+
from allocation import model, unit_of_work
7+
88

99

1010
class InvalidSku(Exception):
@@ -17,19 +17,22 @@ def is_valid_sku(sku, batches):
1717

1818
def add_batch(
1919
ref: str, sku: str, qty: int, eta: Optional[date],
20-
repo: AbstractRepository, session,
20+
uow: unit_of_work.AbstractUnitOfWork
2121
):
22-
repo.add(model.Batch(ref, sku, qty, eta))
23-
session.commit()
22+
with uow:
23+
uow.batches.add(model.Batch(ref, sku, qty, eta))
24+
uow.commit()
2425

2526

2627
def allocate(
27-
orderid: str, sku: str, qty: int, repo: AbstractRepository, session
28+
orderid: str, sku: str, qty: int,
29+
uow: unit_of_work.AbstractUnitOfWork
2830
) -> str:
2931
line = OrderLine(orderid, sku, qty)
30-
batches = repo.list()
31-
if not is_valid_sku(line.sku, batches):
32-
raise InvalidSku(f'Invalid sku {line.sku}')
33-
batchref = model.allocate(line, batches)
34-
session.commit()
32+
with uow:
33+
batches = uow.batches.list()
34+
if not is_valid_sku(line.sku, batches):
35+
raise InvalidSku(f'Invalid sku {line.sku}')
36+
batchref = model.allocate(line, batches)
37+
uow.commit()
3538
return batchref

src/allocation/unit_of_work.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# pylint: disable=attribute-defined-outside-init
22
from __future__ import annotations
33
import abc
4+
from typing import Callable
45
from sqlalchemy import create_engine
56
from sqlalchemy.orm import sessionmaker
67
from sqlalchemy.orm.session import Session

tests/unit/test_services.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from allocation import repository, services
2+
from allocation import repository, services, unit_of_work
33

44

55
class FakeRepository(repository.AbstractRepository):
@@ -17,38 +17,44 @@ def list(self):
1717
return list(self._batches)
1818

1919

20-
class FakeSession():
21-
committed = False
20+
class FakeUnitOfWork(unit_of_work.AbstractUnitOfWork):
21+
22+
def __init__(self):
23+
self.batches = FakeRepository([])
24+
self.committed = False
2225

2326
def commit(self):
2427
self.committed = True
2528

29+
def rollback(self):
30+
pass
31+
32+
2633

2734
def test_add_batch():
28-
repo, session = FakeRepository([]), FakeSession()
29-
services.add_batch("b1", "CRUNCHY-ARMCHAIR", 100, None, repo, session)
30-
assert repo.get("b1") is not None
31-
assert session.committed
35+
uow = FakeUnitOfWork()
36+
services.add_batch("b1", "CRUNCHY-ARMCHAIR", 100, None, uow)
37+
assert uow.batches.get("b1") is not None
38+
assert uow.committed
3239

3340

3441
def test_allocate_returns_allocation():
35-
repo, session = FakeRepository([]), FakeSession()
36-
services.add_batch("batch1", "COMPLICATED-LAMP", 100, None, repo, session)
37-
result = services.allocate("o1", "COMPLICATED-LAMP", 10, repo, session)
42+
uow = FakeUnitOfWork()
43+
services.add_batch("batch1", "COMPLICATED-LAMP", 100, None, uow)
44+
result = services.allocate("o1", "COMPLICATED-LAMP", 10, uow)
3845
assert result == "batch1"
3946

4047

4148
def test_allocate_errors_for_invalid_sku():
42-
repo, session = FakeRepository([]), FakeSession()
43-
services.add_batch("b1", "AREALSKU", 100, None, repo, session)
49+
uow = FakeUnitOfWork()
50+
services.add_batch("b1", "AREALSKU", 100, None, uow)
4451

4552
with pytest.raises(services.InvalidSku, match="Invalid sku NONEXISTENTSKU"):
46-
services.allocate("o1", "NONEXISTENTSKU", 10, repo, FakeSession())
53+
services.allocate("o1", "NONEXISTENTSKU", 10, uow)
4754

4855

49-
def test_commits():
50-
repo, session = FakeRepository([]), FakeSession()
51-
session = FakeSession()
52-
services.add_batch("b1", "OMINOUS-MIRROR", 100, None, repo, session)
53-
services.allocate("o1", "OMINOUS-MIRROR", 10, repo, session)
54-
assert session.committed is True
56+
def test_allocate_commits():
57+
uow = FakeUnitOfWork()
58+
services.add_batch("b1", "OMINOUS-MIRROR", 100, None, uow)
59+
services.allocate("o1", "OMINOUS-MIRROR", 10, uow)
60+
assert uow.committed

0 commit comments

Comments
 (0)