Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion commons/data_access_layer/cosmos_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ def delete(self, id: str, event_context: EventContext,
'deleted': generate_uuid4()
}, event_context, peeker=peeker, visible_only=True, mapper=mapper)

def delete_permanently(self, id: str, partition_key_value: str) -> None:
def delete_permanently(self, id: str, event_context: EventContext) -> None:
partition_key_value = self.find_partition_key_value(event_context)
self.container.delete_item(id, partition_key_value)

def find_partition_key_value(self, event_context: EventContext):
Expand Down
8 changes: 7 additions & 1 deletion commons/data_access_layer/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ def delete(self, id):

class EventContext():
def __init__(self, container_id: str, action: str, description: str = None,
user_id: str = None, tenant_id: str = None, session_id: str = None):
user_id: str = None, tenant_id: str = None, session_id: str = None,
app_id: str = None):
self._container_id = container_id
self._action = action
self._description = description
self._user_id = user_id
self._tenant_id = tenant_id
self._session_id = session_id
self._app_id = app_id

@property
def container_id(self):
Expand All @@ -66,3 +68,7 @@ def tenant_id(self):
@property
def session_id(self):
return self._session_id

@property
def app_id(self):
return self._app_id
67 changes: 30 additions & 37 deletions migrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,14 @@
from migrate_anything import configure
from migrate_anything.storage import Storage

from time_tracker_api import create_app

from commons.data_access_layer.database import EventContext
from commons.data_access_layer.cosmos_db import cosmos_helper, init_app, \
CosmosDBRepository

class CustomStorage(object):
def __init__(self, file):
self.file = file

def save_migration(self, name, code):
with open(self.file, "a", encoding="utf-8") as file:
file.write("{},{}\n".format(name, code))

def list_migrations(self):
try:
with open(self.file, encoding="utf-8") as file:
return [
line.split(",")
for line in file.readlines()
if line.strip() # Skip empty lines
]
except FileNotFoundError:
return []

def remove_migration(self, name):
migrations = [
migration for migration in self.list_migrations() if migration[0] != name
]

with open(self.file, "w", encoding="utf-8") as file:
for row in migrations:
file.write("{},{}\n".format(*row))
from time_tracker_api import create_app


app = create_app('time_tracker_api.config.CLIConfig')
from commons.data_access_layer.cosmos_db import cosmos_helper, init_app, CosmosDBRepository

if cosmos_helper is None:
init_app(app)
Expand All @@ -59,19 +33,38 @@ def __init__(self, collection_id, app_id):
self.repository = CosmosDBRepository.from_definition(migrations_definition)

def save_migration(self, name, code):
self.repository.create({"id": name,
"name": name,
"code": code,
"app_id": self.app_id})
event_ctx = self.create_event_context('create')
self.repository.create(
data={
"id": name,
"name": name,
"code": code,
"app_id": self.app_id
},
event_context=event_ctx,
)

def list_migrations(self):
migrations = self.repository.find_all(self.app_id)
event_ctx = self.create_event_context('read-many')
migrations = self.repository.find_all(event_context=event_ctx)
return [
[item['name'], item['code']] for item in migrations
]

def remove_migration(self, name):
self.repository.delete_permanently(name, self.app_id)

event_ctx = self.create_event_context('delete-permanently')
self.repository.delete_permanently(id=name, event_context=event_ctx)

def create_event_context(
self,
action: str = None,
description: str = None
) -> EventContext:
return EventContext(
container_id=self.collection_id,
action=action,
description=description,
app_id=self.app_id
)

configure(storage=CosmosDBStorage("migration", "time-tracker-api"))
5 changes: 3 additions & 2 deletions tests/commons/data_access_layer/cosmos_db_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,10 @@ def test_partial_update_should_not_find_element_that_is_already_deleted(cosmos_d


def test_delete_permanently_with_invalid_id_should_fail(cosmos_db_repository: CosmosDBRepository,
event_context: EventContext,
tenant_id: str):
try:
cosmos_db_repository.delete_permanently(fake.uuid4(), tenant_id)
cosmos_db_repository.delete_permanently(fake.uuid4(), event_context)
fail('It should have not found the deleted item')
except Exception as e:
assert type(e) is CosmosResourceNotFoundError
Expand All @@ -527,7 +528,7 @@ def test_delete_permanently_with_valid_id_should_succeed(cosmos_db_repository: C
assert found_item is not None
assert found_item['id'] == sample_item['id']

cosmos_db_repository.delete_permanently(sample_item['id'], event_context.tenant_id)
cosmos_db_repository.delete_permanently(sample_item['id'], event_context)

try:
cosmos_db_repository.find(sample_item['id'], event_context)
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def running_time_entry(time_entry_repository: TimeEntryCosmosDBRepository,
yield created_time_entry

time_entry_repository.delete_permanently(id=created_time_entry.id,
partition_key_value=tenant_id)
event_context=event_context)


@pytest.fixture(scope="session")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_find_interception_with_date_range_should_find(start_date: datetime,
assert len(result) > 0
assert any([existing_item.id == item.id for item in result])
finally:
time_entry_repository.delete_permanently(existing_item.id, partition_key_value=existing_item.tenant_id)
time_entry_repository.delete_permanently(existing_item.id, event_ctx)


def test_find_interception_should_ignore_id_of_existing_item(owner_id: str, tenant_id: str,
Expand All @@ -79,7 +79,7 @@ def test_find_interception_should_ignore_id_of_existing_item(owner_id: str, tena
non_colliding_result is not None
assert not any([existing_item.id == item.id for item in non_colliding_result])
finally:
time_entry_repository.delete_permanently(existing_item.id, partition_key_value=existing_item.tenant_id)
time_entry_repository.delete_permanently(existing_item.id, event_ctx)


def test_find_running_should_return_running_time_entry(running_time_entry,
Expand Down