Skip to content
Snippets Groups Projects
Commit b35a3779 authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Filter group chats by blocked and banned leaders

and exclude last messages from blocked and banned contacts
parent df045399
No related branches found
No related tags found
1 merge request!29Blocked and banned contacts
...@@ -9,6 +9,7 @@ extension GroupChatInfo: FetchableRecord { ...@@ -9,6 +9,7 @@ extension GroupChatInfo: FetchableRecord {
} }
static func request(_ query: Query) -> AdaptedFetchRequest<SQLRequest<GroupChatInfo>> { static func request(_ query: Query) -> AdaptedFetchRequest<SQLRequest<GroupChatInfo>> {
var sqlJoins: [String] = ["INNER JOIN groups g ON g.id = m.groupId"]
var sqlWhere: [String] = [] var sqlWhere: [String] = []
var sqlArguments: StatementArguments = [:] var sqlArguments: StatementArguments = [:]
...@@ -17,6 +18,21 @@ extension GroupChatInfo: FetchableRecord { ...@@ -17,6 +18,21 @@ extension GroupChatInfo: FetchableRecord {
_ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus)) _ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus))
} }
if query.excludeBlockedContacts || query.excludeBannedContacts {
sqlJoins.append("INNER JOIN contacts l ON g.leaderId = l.id")
sqlJoins.append("INNER JOIN contacts s ON m.senderId = s.id")
if query.excludeBlockedContacts {
sqlWhere.append("l.isBlocked != 1")
sqlWhere.append("s.isBlocked != 1")
}
if query.excludeBannedContacts {
sqlWhere.append("l.isBanned != 1")
sqlWhere.append("s.isBanned != 1")
}
}
let sql = """ let sql = """
SELECT SELECT
-- All group columns: -- All group columns:
...@@ -29,9 +45,8 @@ extension GroupChatInfo: FetchableRecord { ...@@ -29,9 +45,8 @@ extension GroupChatInfo: FetchableRecord {
MAX(m.date) AS date MAX(m.date) AS date
FROM FROM
messages m messages m
INNER JOIN groups g \(sqlJoins.joined(separator: "\n"))
ON g.id = m.groupId \(sqlWhere.isEmpty ? "" : "WHERE\n \(sqlWhere.joined(separator: "\n AND "))")
\(sqlWhere.isEmpty ? "" : "WHERE\n \(sqlWhere.joined(separator: "\n "))")
GROUP BY GROUP BY
g.id g.id
ORDER BY ORDER BY
......
...@@ -49,10 +49,18 @@ extension GroupChatInfo { ...@@ -49,10 +49,18 @@ extension GroupChatInfo {
/// - authStatus: Filter groups by auth status. /// - authStatus: Filter groups by auth status.
/// If set, only groups with any of the provided auth statuses will be included. /// If set, only groups with any of the provided auth statuses will be included.
/// If `nil`, the filter is not used. /// If `nil`, the filter is not used.
/// - excludeBlockedContacts: Exclude groups with blocked leaders and last messages from
/// blocked contacts (defaults to `false`).
/// - excludeBannedContacts: Exclude groups with banned leaders and last messages from
/// banned contacts (defaults to `false`).
public init( public init(
authStatus: Set<Group.AuthStatus>? = nil authStatus: Set<Group.AuthStatus>? = nil,
excludeBlockedContacts: Bool = false,
excludeBannedContacts: Bool = false
) { ) {
self.authStatus = authStatus self.authStatus = authStatus
self.excludeBlockedContacts = excludeBlockedContacts
self.excludeBannedContacts = excludeBannedContacts
} }
/// Filter groups by auth status /// Filter groups by auth status
...@@ -60,5 +68,11 @@ extension GroupChatInfo { ...@@ -60,5 +68,11 @@ extension GroupChatInfo {
/// If set, only groups with any of the provided auth statuses will be included. /// If set, only groups with any of the provided auth statuses will be included.
/// If `nil`, the filter is not used. /// If `nil`, the filter is not used.
public var authStatus: Set<Group.AuthStatus>? public var authStatus: Set<Group.AuthStatus>?
/// Exclude groups with blocked leaders and last messages from blocked contacts.
public var excludeBlockedContacts: Bool
/// Exclude groups with banned leaders and last messages from banned contacts.
public var excludeBannedContacts: Bool
} }
} }
...@@ -139,4 +139,240 @@ final class GroupChatInfoGRDBTests: XCTestCase { ...@@ -139,4 +139,240 @@ final class GroupChatInfoGRDBTests: XCTestCase {
] ]
) )
} }
func testExcludeMessagesFromBlockedContacts() throws {
// Mock up contacts:
let contactA = try db.saveContact(.stub("A"))
let contactB = try db.saveContact(.stub("B"))
let contactC = try db.saveContact(.stub("C").withBlocked(true))
// Mock up groups:
let groupA = try db.saveGroup(.stub(
"A",
leaderId: contactA.id,
createdAt: .stub(1)
))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactC.id))
let groupB = try db.saveGroup(.stub(
"B",
leaderId: contactB.id,
createdAt: .stub(2)
))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactC.id))
let groupC = try db.saveGroup(.stub(
"C",
leaderId: contactC.id,
createdAt: .stub(3)
))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactC.id))
// Mock up messages in group A:
try db.saveMessage(.stub(
from: contactA,
to: groupA,
at: 1,
isUnread: true
))
let groupA_message_fromB_at2 = try db.saveMessage(.stub(
from: contactB,
to: groupA,
at: 2,
isUnread: true
))
let groupA_message_fromC_at3 = try db.saveMessage(.stub(
from: contactC,
to: groupA,
at: 3,
isUnread: true
))
// Mock up messages in group B:
let groupB_message_fromC_at4 = try db.saveMessage(.stub(
from: contactC,
to: groupB,
at: 4,
isUnread: true
))
// Mock up messages in group C:
try db.saveMessage(.stub(
from: contactA,
to: groupC,
at: 5,
isUnread: true
))
let groupC_message_fromC_at6 = try db.saveMessage(.stub(
from: contactC,
to: groupC,
at: 6,
isUnread: true
))
// Fetch group chats excluding messages from blocked contacts:
XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBlockedContacts: true)), [
GroupChatInfo(
group: groupA,
lastMessage: groupA_message_fromB_at2,
unreadCount: 2
),
])
// Fetch group chats including messages from blocked contacts:
XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBlockedContacts: false)), [
GroupChatInfo(
group: groupC,
lastMessage: groupC_message_fromC_at6,
unreadCount: 2
),
GroupChatInfo(
group: groupB,
lastMessage: groupB_message_fromC_at4,
unreadCount: 1
),
GroupChatInfo(
group: groupA,
lastMessage: groupA_message_fromC_at3,
unreadCount: 3
),
])
}
func testExcludeMessagesFromBannedContacts() throws {
// Mock up contacts:
let contactA = try db.saveContact(.stub("A"))
let contactB = try db.saveContact(.stub("B"))
let contactC = try db.saveContact(.stub("C").withBanned(true))
// Mock up groups:
let groupA = try db.saveGroup(.stub(
"A",
leaderId: contactA.id,
createdAt: .stub(1)
))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactC.id))
let groupB = try db.saveGroup(.stub(
"B",
leaderId: contactB.id,
createdAt: .stub(2)
))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactC.id))
let groupC = try db.saveGroup(.stub(
"C",
leaderId: contactC.id,
createdAt: .stub(3)
))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactA.id))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactB.id))
try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactC.id))
// Mock up messages in group A:
try db.saveMessage(.stub(
from: contactA,
to: groupA,
at: 1,
isUnread: true
))
let groupA_message_fromB_at2 = try db.saveMessage(.stub(
from: contactB,
to: groupA,
at: 2,
isUnread: true
))
let groupA_message_fromC_at3 = try db.saveMessage(.stub(
from: contactC,
to: groupA,
at: 3,
isUnread: true
))
// Mock up messages in group B:
let groupB_message_fromC_at4 = try db.saveMessage(.stub(
from: contactC,
to: groupB,
at: 4,
isUnread: true
))
// Mock up messages in group C:
try db.saveMessage(.stub(
from: contactA,
to: groupC,
at: 5,
isUnread: true
))
let groupC_message_fromC_at6 = try db.saveMessage(.stub(
from: contactC,
to: groupC,
at: 6,
isUnread: true
))
// Fetch group chats excluding messages from banned contacts:
XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBannedContacts: true)), [
GroupChatInfo(
group: groupA,
lastMessage: groupA_message_fromB_at2,
unreadCount: 2
),
])
// Fetch group chats including messages from banned contacts:
XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBannedContacts: false)), [
GroupChatInfo(
group: groupC,
lastMessage: groupC_message_fromC_at6,
unreadCount: 2
),
GroupChatInfo(
group: groupB,
lastMessage: groupB_message_fromC_at4,
unreadCount: 1
),
GroupChatInfo(
group: groupA,
lastMessage: groupA_message_fromC_at3,
unreadCount: 3
),
])
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment