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

Filter contact chat infos by isBlocked and isBanned status

parent 2b3db8f3
No related branches found
No related tags found
1 merge request!29Blocked and banned contacts
...@@ -17,6 +17,16 @@ extension ContactChatInfo: FetchableRecord { ...@@ -17,6 +17,16 @@ extension ContactChatInfo: FetchableRecord {
_ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus)) _ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus))
} }
if let isBlocked = query.isBlocked {
sqlWhere.append("AND c2.isBlocked = :isBlocked")
_ = sqlArguments.append(contentsOf: StatementArguments(["isBlocked": isBlocked]))
}
if let isBanned = query.isBanned {
sqlWhere.append("AND c2.isBanned = :isBanned")
_ = sqlArguments.append(contentsOf: StatementArguments(["isBanned": isBanned]))
}
let sql = """ let sql = """
SELECT SELECT
-- All contact columns: -- All contact columns:
......
...@@ -51,12 +51,24 @@ extension ContactChatInfo { ...@@ -51,12 +51,24 @@ extension ContactChatInfo {
/// If set, only chats with contacts that have any of the provided /// If set, only chats with contacts that have any of the provided
/// auth statuses will be included. /// auth statuses will be included.
/// If `nil` (default), the filter is not used. /// If `nil` (default), the filter is not used.
/// - isBlocked: Filter by other contact's `isBlocked` status.
/// If `true`, only chats with blocked contacts are included.
/// If `false`, only chats with non-blocked contacts are included.
/// If `nil` (default), the filter is not used.
/// - isBanned: Filter by other contact's `isBanned` status
/// If `true`, only chats with banned contacts are included.
/// If `false`, only chats with non-banned contacts are included.
/// If `nil` (default), the filter is not used.
public init( public init(
userId: Contact.ID, userId: Contact.ID,
authStatus: Set<Contact.AuthStatus>? = nil authStatus: Set<Contact.AuthStatus>? = nil,
isBlocked: Bool? = nil,
isBanned: Bool? = nil
) { ) {
self.userId = userId self.userId = userId
self.authStatus = authStatus self.authStatus = authStatus
self.isBlocked = isBlocked
self.isBanned = isBanned
} }
/// Current user's contact ID /// Current user's contact ID
...@@ -68,5 +80,19 @@ extension ContactChatInfo { ...@@ -68,5 +80,19 @@ extension ContactChatInfo {
/// auth statuses will be included. /// auth statuses will be included.
/// If `nil`, the filter is not used. /// If `nil`, the filter is not used.
public var authStatus: Set<Contact.AuthStatus>? public var authStatus: Set<Contact.AuthStatus>?
/// Filter by other contact's `isBlocked` status
///
/// If `true`, only chats with blocked contacts are included.
/// If `false`, only chats with non-blocked contacts are included.
/// If `nil`, the filter is not used.
public var isBlocked: Bool?
/// Filter by other contact's `isBanned` status
///
/// If `true`, only chats with banned contacts are included.
/// If `false`, only chats with non-banned contacts are included.
/// If `nil`, the filter is not used.
public var isBanned: Bool?
} }
} }
...@@ -259,4 +259,258 @@ final class ContactChatInfoGRDBTests: XCTestCase { ...@@ -259,4 +259,258 @@ final class ContactChatInfoGRDBTests: XCTestCase {
] ]
) )
} }
func testFetchingByContactBlockedStatus() throws {
// Mock up contacts:
let contactA = try db.saveContact(.stub("A").withBlocked(false))
let contactB = try db.saveContact(.stub("B").withBlocked(true))
let contactC = try db.saveContact(.stub("C").withBlocked(false))
let contactD = try db.saveContact(.stub("D").withBlocked(true))
// Mock up conversation between contact A and B:
try db.saveMessage(.stub(
from: contactA,
to: contactB,
at: 1,
isUnread: false
))
try db.saveMessage(.stub(
from: contactB,
to: contactA,
at: 2,
isUnread: true
))
let lastMessage_betweenAandB_at3 = try db.saveMessage(.stub(
from: contactA,
to: contactB,
at: 3,
isUnread: true
))
// Mock up conversation between contact A and C:
try db.saveMessage(.stub(
from: contactA,
to: contactC,
at: 4,
isUnread: false
))
let lastMessage_betweenAandC_at5 = try db.saveMessage(.stub(
from: contactC,
to: contactA,
at: 5,
isUnread: true
))
// Mock up conversation between contact A and D:
try db.saveMessage(.stub(
from: contactA,
to: contactD,
at: 6,
isUnread: false
))
let lastMessage_betweenAandD_at7 = try db.saveMessage(.stub(
from: contactD,
to: contactA,
at: 7,
isUnread: false
))
// Fetch chats between contact A and blocked contacts:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBlocked: true
)),
[
ContactChatInfo(
contact: contactD,
lastMessage: lastMessage_betweenAandD_at7,
unreadCount: 0
),
ContactChatInfo(
contact: contactB,
lastMessage: lastMessage_betweenAandB_at3,
unreadCount: 2
),
]
)
// Fetch chats between contact A and non-blocked contacts:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBlocked: false
)),
[
ContactChatInfo(
contact: contactC,
lastMessage: lastMessage_betweenAandC_at5,
unreadCount: 1
),
]
)
// Fetch chats between contact A and other contacts, regardless its `isBlocked` status:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBlocked: nil
)),
[
ContactChatInfo(
contact: contactD,
lastMessage: lastMessage_betweenAandD_at7,
unreadCount: 0
),
ContactChatInfo(
contact: contactC,
lastMessage: lastMessage_betweenAandC_at5,
unreadCount: 1
),
ContactChatInfo(
contact: contactB,
lastMessage: lastMessage_betweenAandB_at3,
unreadCount: 2
),
]
)
}
func testFetchingByContactBannedStatus() throws {
// Mock up contacts:
let contactA = try db.saveContact(.stub("A").withBanned(false))
let contactB = try db.saveContact(.stub("B").withBanned(true))
let contactC = try db.saveContact(.stub("C").withBanned(false))
let contactD = try db.saveContact(.stub("D").withBanned(true))
// Mock up conversation between contact A and B:
try db.saveMessage(.stub(
from: contactA,
to: contactB,
at: 1,
isUnread: false
))
try db.saveMessage(.stub(
from: contactB,
to: contactA,
at: 2,
isUnread: true
))
let lastMessage_betweenAandB_at3 = try db.saveMessage(.stub(
from: contactA,
to: contactB,
at: 3,
isUnread: true
))
// Mock up conversation between contact A and C:
try db.saveMessage(.stub(
from: contactA,
to: contactC,
at: 4,
isUnread: false
))
let lastMessage_betweenAandC_at5 = try db.saveMessage(.stub(
from: contactC,
to: contactA,
at: 5,
isUnread: true
))
// Mock up conversation between contact A and D:
try db.saveMessage(.stub(
from: contactA,
to: contactD,
at: 6,
isUnread: false
))
let lastMessage_betweenAandD_at7 = try db.saveMessage(.stub(
from: contactD,
to: contactA,
at: 7,
isUnread: false
))
// Fetch chats between contact A and banned contacts:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBanned: true
)),
[
ContactChatInfo(
contact: contactD,
lastMessage: lastMessage_betweenAandD_at7,
unreadCount: 0
),
ContactChatInfo(
contact: contactB,
lastMessage: lastMessage_betweenAandB_at3,
unreadCount: 2
),
]
)
// Fetch chats between contact A and non-banned contacts:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBanned: false
)),
[
ContactChatInfo(
contact: contactC,
lastMessage: lastMessage_betweenAandC_at5,
unreadCount: 1
),
]
)
// Fetch chats between contact A and other contacts, regardless its `isBanned` status:
XCTAssertNoDifference(
try db.fetchContactChatInfos(ContactChatInfo.Query(
userId: contactA.id,
isBanned: nil
)),
[
ContactChatInfo(
contact: contactD,
lastMessage: lastMessage_betweenAandD_at7,
unreadCount: 0
),
ContactChatInfo(
contact: contactC,
lastMessage: lastMessage_betweenAandC_at5,
unreadCount: 1
),
ContactChatInfo(
contact: contactB,
lastMessage: lastMessage_betweenAandB_at3,
unreadCount: 2
),
]
)
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment