Skip to content

Commit a3a7da9

Browse files
committed
test: Add test methods in user_service test class
1 parent c465cbf commit a3a7da9

File tree

4 files changed

+325
-34
lines changed

4 files changed

+325
-34
lines changed

app/service/email_service.py

+3
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,8 @@ async def send_email(to, subject: str, body: str, attachment_path: str | None =
5252
log.info(f"Send email to {to} successfully, From: {username} {attachment_message}")
5353
except Exception as e:
5454
log.error(f"Failed to send email to {to}, Error: {e}")
55+
return False
5556
finally:
5657
server.quit()
58+
59+
return True

app/service/user_service.py

+22-19
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,6 @@
1717
_log = logging.getLogger(__name__)
1818

1919

20-
async def send_creation_email(user: UserDTO):
21-
"""
22-
Send creation email to user with background task
23-
:param user: created user information
24-
"""
25-
_log.debug(f"UserService Sending creation email on background task to user: {user.email}")
26-
to = user.email
27-
app_name = app_settings.APP_NAME
28-
app_url = app_settings.APP_URL
29-
subject = f"Welcome to the {app_name}"
30-
body = f"Hello {user.first_name},\n\n" \
31-
f"Welcome to the {app_name}. Your account has been created successfully.\n\n" \
32-
f"Please visit {app_url} to login to your account.\n\n" \
33-
f"{app_name} Team."
34-
await email_service.send_email(to, subject, body)
35-
_log.debug(f"UserService Creation email sent to user: {user.email}")
36-
37-
3820
class UserService:
3921
"""
4022
User Business Logic Service that is responsible for handling business logic for User entity operations.
@@ -48,6 +30,7 @@ class UserService:
4830
def __init__(self, user_repository: UserRepository = Depends()):
4931
_log.info("UserService Initializing")
5032
self.repository = user_repository
33+
self.email_service = email_service
5134

5235
async def user_create_validation(self, user_create: UserCreate):
5336
"""
@@ -63,6 +46,26 @@ async def user_create_validation(self, user_create: UserCreate):
6346
raise BusinessException(ErrorCodes.ALREADY_EXISTS,
6447
f"User with email already exists: {user_create.email}")
6548

49+
async def send_creation_email(self, user: UserDTO):
50+
"""
51+
Send creation email to user with background task
52+
:param user: created user information
53+
"""
54+
_log.debug(f"Sending creation email on background task")
55+
if user is None:
56+
raise BusinessException(ErrorCodes.NOT_FOUND, "User not found")
57+
58+
to = user.email
59+
app_name = app_settings.APP_NAME
60+
app_url = app_settings.APP_URL
61+
subject = f"Welcome to the {app_name}"
62+
body = f"Hello {user.first_name},\n\n" \
63+
f"Welcome to the {app_name}. Your account has been created successfully.\n\n" \
64+
f"Please visit {app_url} to login to your account.\n\n" \
65+
f"{app_name} Team."
66+
await self.email_service.send_email(to, subject, body)
67+
_log.debug(f"Sent Creation email sent to user: {user.email}")
68+
6669
async def create(self, user_create: UserCreate, token_data: JWTUser) -> UserDTO:
6770
_log.debug(f"UserService Creating user: {user_create} with: {type(user_create)}")
6871

@@ -83,7 +86,7 @@ async def create(self, user_create: UserCreate, token_data: JWTUser) -> UserDTO:
8386

8487
_log.debug(f"UserService User created: {result.user_id}")
8588
try:
86-
await send_creation_email(result)
89+
await self.send_creation_email(result)
8790
except Exception as e:
8891
_log.error(f"UserService Error sending creation email: {e}")
8992
return result

test/repository/test_user_repository.py

+77
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,18 @@ class TestUserRepository(unittest.IsolatedAsyncioTestCase):
111111
"""
112112

113113
def __init__(self, *args, **kwargs):
114+
"""
115+
Initializes the TestUserRepository class.
116+
:param args: arguments
117+
:param kwargs: keyword arguments
118+
"""
114119
_log.info("Initializing TestUserRepository")
115120
super(TestUserRepository, self).__init__(*args, **kwargs)
116121

117122
async def asyncSetUp(self):
123+
"""
124+
Sets up the resources required for the tests.
125+
"""
118126
_log.info("Setting up each resources.")
119127
self.container = MongoDbContainer(image="mongo:latest")
120128
self.container.start()
@@ -124,6 +132,9 @@ async def asyncSetUp(self):
124132
await init_beanie(document_models=entities, database=self.db)
125133

126134
async def asyncTearDown(self):
135+
"""
136+
Tears down the resources after the tests.
137+
"""
127138
_log.info("Tearing down each resources.")
128139
await self.db.get_collection(_collection_name).delete_many({})
129140
self.client.close()
@@ -132,6 +143,9 @@ async def asyncTearDown(self):
132143
# region create entity tests
133144
@pytest.mark.asyncio
134145
async def test_given_min_entity_when_insert_then_successfully_created(self):
146+
"""
147+
Test case to create a user entity with minimal data and verify the creation process.
148+
"""
135149
_log.info("test_given_min_entity_when_insert_then_successfully_created")
136150
# Given
137151
entity = _get_min_entity()
@@ -157,6 +171,9 @@ async def test_given_min_entity_when_insert_then_successfully_created(self):
157171

158172
@pytest.mark.asyncio
159173
async def test_given_full_entity_when_insert_then_successfully_created(self):
174+
"""
175+
Test case to create a user entity with full data and verify the creation process.
176+
"""
160177
_log.info("test_given_full_entity_when_insert_then_successfully_created")
161178

162179
# Given
@@ -183,6 +200,9 @@ async def test_given_full_entity_when_insert_then_successfully_created(self):
183200

184201
@pytest.mark.asyncio
185202
async def test_given_invalid_entity_when_insert_then_fail(self):
203+
"""
204+
Test case to handle invalid user entity creation attempts.
205+
"""
186206
_log.info("test_given_invalid_entity_when_insert_then_fail")
187207

188208
# Given
@@ -199,6 +219,9 @@ async def test_given_invalid_entity_when_insert_then_fail(self):
199219
# region update entity tests
200220
@pytest.mark.asyncio
201221
async def test_given_entity_when_update_then_successfully_updated(self):
222+
"""
223+
Test case to update a user entity and verify the changes are correctly applied.
224+
"""
202225
_log.info("test_given_entity_when_update_then_successfully_updated")
203226

204227
# Given
@@ -236,6 +259,9 @@ async def test_given_entity_when_update_then_successfully_updated(self):
236259

237260
@pytest.mark.asyncio
238261
async def test_given_invalid_userid_when_update_then_fail(self):
262+
"""
263+
Test case to handle invalid user ID during update attempts.
264+
"""
239265
_log.info("test_given_invalid_entity_when_update_then_fail")
240266

241267
# inti entity
@@ -251,6 +277,9 @@ async def test_given_invalid_userid_when_update_then_fail(self):
251277

252278
@pytest.mark.asyncio
253279
async def test_given_invalid_username_when_update_then_fail(self):
280+
"""
281+
Test case to handle invalid username during update attempts.
282+
"""
254283
_log.info("test_given_invalid_entity_when_update_then_fail")
255284

256285
# inti entity
@@ -266,6 +295,9 @@ async def test_given_invalid_username_when_update_then_fail(self):
266295

267296
@pytest.mark.asyncio
268297
async def test_given_invalid_email_when_update_then_fail(self):
298+
"""
299+
Test case to handle invalid email during update attempts.
300+
"""
269301
_log.info("test_given_invalid_entity_when_update_then_fail")
270302

271303
# inti entity
@@ -291,6 +323,9 @@ async def test_given_invalid_email_when_update_then_fail(self):
291323

292324
@pytest.mark.asyncio
293325
async def test_given_deleted_entity_when_retrieve_then_should_fail(self):
326+
"""
327+
Test case to handle deleted user entity retrieval attempts.
328+
"""
294329
_log.info("test_given_entity_when_delete_then_successfully_deleted")
295330

296331
# Given
@@ -309,6 +344,9 @@ async def test_given_deleted_entity_when_retrieve_then_should_fail(self):
309344

310345
@pytest.mark.asyncio
311346
async def test_given_random_id_when_delete_then_should_fail(self):
347+
"""
348+
Test case to handle deletion attempts for non-existent user entities.
349+
"""
312350
_log.info("test_given_entity_when_delete_then_successfully_deleted")
313351

314352
repository = _get_repo()
@@ -327,6 +365,9 @@ async def test_given_random_id_when_delete_then_should_fail(self):
327365
# success case with default values
328366
@pytest.mark.asyncio
329367
async def test_given_entity_when_find_then_success(self):
368+
"""
369+
Test case to find user entities and verify the results.
370+
"""
330371
_log.info("test_given_entity_when_find_then_success")
331372

332373
# Given
@@ -346,6 +387,9 @@ async def test_given_entity_when_find_then_success(self):
346387
# success case with mongodb query
347388
@pytest.mark.asyncio
348389
async def test_given_native_mogo_query_when_find_with_query_then_success(self):
390+
"""
391+
Test case to find user entities with a MongoDB query and verify the results.
392+
"""
349393
_log.info("test_given_entity_when_find_with_query_then_success")
350394

351395
# Given
@@ -365,6 +409,9 @@ async def test_given_native_mogo_query_when_find_with_query_then_success(self):
365409
# success case with query, page, size, sort
366410
@pytest.mark.asyncio
367411
async def test_given_native_mogo_query_when_find_with_query_page_size_sort_then_success(self):
412+
"""
413+
Test case to find user entities with a MongoDB query, pagination, and sorting, and verify the results.
414+
"""
368415
_log.info("test_given_entity_when_find_with_query_page_size_sort_then_success")
369416

370417
# Given
@@ -384,6 +431,9 @@ async def test_given_native_mogo_query_when_find_with_query_page_size_sort_then_
384431
# success case with dict convert to query, page, size, sort
385432
@pytest.mark.asyncio
386433
async def test_given_dict_when_find_with_query_then_success(self):
434+
"""
435+
Test case to find user entities with a dictionary query, pagination, and sorting, and verify the results.
436+
"""
387437
_log.info("test_given_entity_when_find_with_invalid_query_then_fail")
388438

389439
# Given
@@ -405,6 +455,9 @@ async def test_given_dict_when_find_with_query_then_success(self):
405455
# fail case with invalid query
406456
@pytest.mark.asyncio
407457
async def test_given_invalid_query_when_find_with_invalid_query_then_fail(self):
458+
"""
459+
Test case to handle invalid query attempts during user entity retrieval.
460+
"""
408461
_log.info("test_given_entity_when_find_with_invalid_query_then_fail")
409462

410463
# Given
@@ -422,6 +475,9 @@ async def test_given_invalid_query_when_find_with_invalid_query_then_fail(self):
422475
# success case with count
423476
@pytest.mark.asyncio
424477
async def test_given_entity_when_count_then_success(self):
478+
"""
479+
Test case to count user entities and verify the results.
480+
"""
425481
_log.info("test_given_entity_when_count_then_success")
426482

427483
# Given
@@ -440,6 +496,9 @@ async def test_given_entity_when_count_then_success(self):
440496
# fail case with count
441497
@pytest.mark.asyncio
442498
async def test_given_invalid_query_when_count_with_invalid_query_then_fail(self):
499+
"""
500+
Test case to handle invalid query attempts during user entity count.
501+
"""
443502
_log.info("test_given_entity_when_count_with_invalid_query_then_fail")
444503

445504
# Given
@@ -457,6 +516,9 @@ async def test_given_invalid_query_when_count_with_invalid_query_then_fail(self)
457516
# success case with valid user_id retrieve
458517
@pytest.mark.asyncio
459518
async def test_given_entity_when_retrieve_then_success(self):
519+
"""
520+
Test case to retrieve a user entity by user ID and verify the results.
521+
"""
460522
_log.info("test_given_entity_when_retrieve_then_success")
461523

462524
# Given
@@ -479,6 +541,9 @@ async def test_given_entity_when_retrieve_then_success(self):
479541
# fail case with invalid user_id retrieve
480542
@pytest.mark.asyncio
481543
async def test_given_invalid_user_id_when_retrieve_then_fail(self):
544+
"""
545+
Test case to handle invalid user ID during user entity retrieval.
546+
"""
482547
_log.info("test_given_invalid_user_id_when_retrieve_then_fail")
483548

484549
# Given
@@ -494,6 +559,9 @@ async def test_given_invalid_user_id_when_retrieve_then_fail(self):
494559
# success case with valid email retrieve_by_email
495560
@pytest.mark.asyncio
496561
async def test_given_entity_when_retrieve_by_email_then_success(self):
562+
"""
563+
Test case to retrieve a user entity by email and verify the results.
564+
"""
497565
_log.info("test_given_entity_when_retrieve_by_email_then_success")
498566

499567
# Given
@@ -516,6 +584,9 @@ async def test_given_entity_when_retrieve_by_email_then_success(self):
516584
# fail case with invalid email retrieve_by_email
517585
@pytest.mark.asyncio
518586
async def test_given_invalid_email_when_retrieve_by_email_then_fail(self):
587+
"""
588+
Test case to handle invalid email during user entity retrieval by email.
589+
"""
519590
_log.info("test_given_invalid_email_when_retrieve_by_email_then_fail")
520591

521592
# Given
@@ -531,6 +602,9 @@ async def test_given_invalid_email_when_retrieve_by_email_then_fail(self):
531602
# success case with valid username retrieve_by_username
532603
@pytest.mark.asyncio
533604
async def test_given_entity_when_retrieve_by_username_then_success(self):
605+
"""
606+
Test case to retrieve a user entity by username and verify the results.
607+
"""
534608
_log.info("test_given_entity_when_retrieve_by_username_then_success")
535609

536610
# Given
@@ -553,6 +627,9 @@ async def test_given_entity_when_retrieve_by_username_then_success(self):
553627
# fail case with invalid username retrieve_by_username
554628
@pytest.mark.asyncio
555629
async def test_given_invalid_username_when_retrieve_by_username_then_fail(self):
630+
"""
631+
Test case to handle invalid username during user entity retrieval by username.
632+
"""
556633
_log.info("test_given_invalid_username_when_retrieve_by_username_then_fail")
557634

558635
# Given

0 commit comments

Comments
 (0)