From 38790fdc84c26b9a09615ee7808dac982ab39361 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Mon, 1 Mar 2021 18:45:15 +0100 Subject: [PATCH] get_alias_infos_with_pagination_v3: handle the case where an alias has 2 contacts that have no activity --- app/api/serializer.py | 21 ++++++++++++++--- tests/api/test_serializer.py | 44 +++++++++++++++++++++++++++++------- tests/utils.py | 11 +++++++++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/app/api/serializer.py b/app/api/serializer.py index 98668130..44790f2b 100644 --- a/app/api/serializer.py +++ b/app/api/serializer.py @@ -226,6 +226,14 @@ def get_alias_infos_with_pagination_v3( .subquery() ) + alias_contact_subquery = ( + db.session.query(Alias.id, func.max(Contact.id).label("max_contact_id")) + .join(Contact, Alias.id == Contact.alias_id, isouter=True) + .filter(Alias.user_id == user.id) + .group_by(Alias.id) + .subquery() + ) + if query: mailboxes_sub = ( db.session.query( @@ -275,14 +283,21 @@ def get_alias_infos_with_pagination_v3( .join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True) .join(Mailbox, Alias.mailbox_id == Mailbox.id, isouter=True) .filter(Alias.id == alias_activity_subquery.c.id) + .filter(Alias.id == alias_contact_subquery.c.id) .filter(Alias.id == mailboxes_sub.c.id) .filter( or_( EmailLog.created_at == alias_activity_subquery.c.latest_email_log_created_at, - alias_activity_subquery.c.latest_email_log_created_at.is_( - None - ), # no email log yet for this alias + and_( + # no email log yet for this alias + alias_activity_subquery.c.latest_email_log_created_at.is_(None), + # to make sure only 1 contact is returned in this case + or_( + Contact.id == alias_contact_subquery.c.max_contact_id, + alias_contact_subquery.c.max_contact_id.is_(None), + ), + ), ) ) ) diff --git a/tests/api/test_serializer.py b/tests/api/test_serializer.py index 226b9948..a3f5d7bc 100644 --- a/tests/api/test_serializer.py +++ b/tests/api/test_serializer.py @@ -1,7 +1,8 @@ from app.api.serializer import get_alias_infos_with_pagination_v3 from app.config import PAGE_LIMIT from app.extensions import db -from app.models import User, Alias, Mailbox +from app.models import User, Alias, Mailbox, Contact +from tests.utils import login, create_user def test_get_alias_infos_with_pagination_v3(flask_client): @@ -18,7 +19,7 @@ def test_get_alias_infos_with_pagination_v3(flask_client): assert len(alias_infos) == 1 alias_info = alias_infos[0] - alias = Alias.query.first() + alias = Alias.first() assert alias_info.alias == alias assert alias_info.mailbox == user.default_mailbox assert alias_info.mailboxes == [user.default_mailbox] @@ -39,7 +40,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_email(flask_client): commit=True, ) - alias = Alias.query.first() + alias = Alias.first() alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.email) assert len(alias_infos) == 1 @@ -57,7 +58,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_mailbox(flask_client): activated=True, commit=True, ) - alias = Alias.query.first() + alias = Alias.first() alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.mailbox.email) assert len(alias_infos) == 1 @@ -71,7 +72,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_mailboxes(flask_client): activated=True, commit=True, ) - alias = Alias.query.first() + alias = Alias.first() mb = Mailbox.create(user_id=user.id, email="mb@gmail.com") alias._mailboxes.append(mb) db.session.commit() @@ -93,7 +94,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_note(flask_client): commit=True, ) - alias = Alias.query.first() + alias = Alias.first() alias.note = "test note" db.session.commit() @@ -111,7 +112,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_name(flask_client): commit=True, ) - alias = Alias.query.first() + alias = Alias.first() alias.name = "Test Name" db.session.commit() @@ -131,7 +132,7 @@ def test_get_alias_infos_with_pagination_v3_no_duplicate(flask_client): commit=True, ) - alias = Alias.query.first() + alias = Alias.first() mb = Mailbox.create(user_id=user.id, email="mb@gmail.com") alias._mailboxes.append(mb) db.session.commit() @@ -140,6 +141,33 @@ def test_get_alias_infos_with_pagination_v3_no_duplicate(flask_client): assert len(alias_infos) == 1 +def test_get_alias_infos_with_pagination_v3_no_duplicate_when_empty_contact( + flask_client, +): + """ + Make sure an alias is returned once when it has 2 contacts that have no email log activity + """ + user = create_user(flask_client) + alias = Alias.first() + + Contact.create( + user_id=user.id, + alias_id=alias.id, + website_email="contact@example.com", + reply_email="rep@sl.local", + ) + + Contact.create( + user_id=user.id, + alias_id=alias.id, + website_email="contact2@example.com", + reply_email="rep2@sl.local", + ) + + alias_infos = get_alias_infos_with_pagination_v3(user) + assert len(alias_infos) == 1 + + def test_get_alias_infos_pinned_alias(flask_client): """Different scenarios with pinned alias""" user = User.create( diff --git a/tests/utils.py b/tests/utils.py index 4656d48c..5de1a4a4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -27,6 +27,17 @@ def login(flask_client) -> User: return user +def create_user(flask_client) -> User: + # create user, user is activated + return User.create( + email="a@b.c", + password="password", + name="Test User", + activated=True, + commit=True, + ) + + def pretty(d): """pretty print as json""" print(json.dumps(d, indent=2))