get_alias_infos_with_pagination_v3: handle the case where an alias has 2 contacts that have no activity

This commit is contained in:
Son NK 2021-03-01 18:45:15 +01:00
parent 3a142ca2f8
commit 38790fdc84
3 changed files with 65 additions and 11 deletions

View File

@ -226,6 +226,14 @@ def get_alias_infos_with_pagination_v3(
.subquery() .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: if query:
mailboxes_sub = ( mailboxes_sub = (
db.session.query( db.session.query(
@ -275,14 +283,21 @@ def get_alias_infos_with_pagination_v3(
.join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True) .join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
.join(Mailbox, Alias.mailbox_id == Mailbox.id, isouter=True) .join(Mailbox, Alias.mailbox_id == Mailbox.id, isouter=True)
.filter(Alias.id == alias_activity_subquery.c.id) .filter(Alias.id == alias_activity_subquery.c.id)
.filter(Alias.id == alias_contact_subquery.c.id)
.filter(Alias.id == mailboxes_sub.c.id) .filter(Alias.id == mailboxes_sub.c.id)
.filter( .filter(
or_( or_(
EmailLog.created_at EmailLog.created_at
== alias_activity_subquery.c.latest_email_log_created_at, == alias_activity_subquery.c.latest_email_log_created_at,
alias_activity_subquery.c.latest_email_log_created_at.is_( and_(
None # no email log yet for this alias
), # 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),
),
),
) )
) )
) )

View File

@ -1,7 +1,8 @@
from app.api.serializer import get_alias_infos_with_pagination_v3 from app.api.serializer import get_alias_infos_with_pagination_v3
from app.config import PAGE_LIMIT from app.config import PAGE_LIMIT
from app.extensions import db 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): 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 assert len(alias_infos) == 1
alias_info = alias_infos[0] alias_info = alias_infos[0]
alias = Alias.query.first() alias = Alias.first()
assert alias_info.alias == alias assert alias_info.alias == alias
assert alias_info.mailbox == user.default_mailbox assert alias_info.mailbox == user.default_mailbox
assert alias_info.mailboxes == [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, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.email) alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.email)
assert len(alias_infos) == 1 assert len(alias_infos) == 1
@ -57,7 +58,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_mailbox(flask_client):
activated=True, activated=True,
commit=True, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.mailbox.email) alias_infos = get_alias_infos_with_pagination_v3(user, query=alias.mailbox.email)
assert len(alias_infos) == 1 assert len(alias_infos) == 1
@ -71,7 +72,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_mailboxes(flask_client):
activated=True, activated=True,
commit=True, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
mb = Mailbox.create(user_id=user.id, email="mb@gmail.com") mb = Mailbox.create(user_id=user.id, email="mb@gmail.com")
alias._mailboxes.append(mb) alias._mailboxes.append(mb)
db.session.commit() db.session.commit()
@ -93,7 +94,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_note(flask_client):
commit=True, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
alias.note = "test note" alias.note = "test note"
db.session.commit() db.session.commit()
@ -111,7 +112,7 @@ def test_get_alias_infos_with_pagination_v3_query_alias_name(flask_client):
commit=True, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
alias.name = "Test Name" alias.name = "Test Name"
db.session.commit() db.session.commit()
@ -131,7 +132,7 @@ def test_get_alias_infos_with_pagination_v3_no_duplicate(flask_client):
commit=True, commit=True,
) )
alias = Alias.query.first() alias = Alias.first()
mb = Mailbox.create(user_id=user.id, email="mb@gmail.com") mb = Mailbox.create(user_id=user.id, email="mb@gmail.com")
alias._mailboxes.append(mb) alias._mailboxes.append(mb)
db.session.commit() db.session.commit()
@ -140,6 +141,33 @@ def test_get_alias_infos_with_pagination_v3_no_duplicate(flask_client):
assert len(alias_infos) == 1 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): def test_get_alias_infos_pinned_alias(flask_client):
"""Different scenarios with pinned alias""" """Different scenarios with pinned alias"""
user = User.create( user = User.create(

View File

@ -27,6 +27,17 @@ def login(flask_client) -> User:
return 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): def pretty(d):
"""pretty print as json""" """pretty print as json"""
print(json.dumps(d, indent=2)) print(json.dumps(d, indent=2))