Skip to content

Commit 5cfb6d1

Browse files
authored
Handle user banned events in livestream controller (#3777)
* Handle user banned and unbanned events in livestream controller * Add test coverage * Update CHANGELOG.md * Fix typo
1 parent 31ca27b commit 5cfb6d1

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
77
### ✅ Added
88
- Handle member-related events in `LivestreamChannelController` [#3775](https://github.com/GetStream/stream-chat-swift/pull/3775)
99
- Handle channel truncation events in `LivestreamChannelController` [#3775](https://github.com/GetStream/stream-chat-swift/pull/3775)
10+
- Handle user banned events in `LivestreamChannelController` [#3777](https://github.com/GetStream/stream-chat-swift/pull/3777)
1011
- Add a completion block to `LivestreamChannelController.resume()` to observe possible errors [#3774](https://github.com/GetStream/stream-chat-swift/pull/3774)
1112
### 🐞 Fixed
1213
- Fix pending message being added to `LivestreamChannelController.messages` when in paused state [#3774](https://github.com/GetStream/stream-chat-swift/pull/3774)

DemoApp/Screens/Livestream/DemoLivestreamChatChannelVC.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ class DemoLivestreamChatChannelVC: _ViewController,
355355
) {
356356
channelAvatarView.content = (livestreamChannelController.channel, client.currentUserId)
357357
updateNavigationTitle()
358+
messageComposerVC.updateContent()
358359
}
359360

360361
func livestreamChannelController(
@@ -505,6 +506,13 @@ class DemoLivestreamComposerVC: ComposerVC {
505506
override var isCommandsEnabled: Bool {
506507
false
507508
}
509+
510+
override var isSendMessageEnabled: Bool {
511+
if livestreamChannelController?.channel?.membership?.isBannedFromChannel == true {
512+
return false
513+
}
514+
return super.isSendMessageEnabled
515+
}
508516
}
509517

510518
private extension UIView {

Sources/StreamChat/Controllers/ChannelController/LivestreamChannelController.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,10 @@ public class LivestreamChannelController: DataStoreProvider, EventsControllerDel
914914
is NotificationInviteRejectedEvent:
915915
updateChannelFromDataStore()
916916

917+
case is UserBannedEvent,
918+
is UserUnbannedEvent:
919+
updateChannelFromDataStore()
920+
917921
case let channelTruncatedEvent as ChannelTruncatedEvent:
918922
channel = channelTruncatedEvent.channel
919923
if let message = channelTruncatedEvent.message {

Tests/StreamChatTests/Controllers/ChannelController/LivestreamChannelController_Tests.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,102 @@ extension LivestreamChannelController_Tests {
13571357
}
13581358
}
13591359

1360+
func test_didReceiveEvent_userBannedEvent_updatesChannelFromDataStore() {
1361+
// Given - Set up initial channel in database
1362+
let cid = controller.cid!
1363+
1364+
let userId = UserId.unique
1365+
let membership = MemberPayload.dummy(user: .dummy(userId: userId))
1366+
1367+
// Save initial channel to database
1368+
let initialChannelPayload = ChannelPayload.dummy(
1369+
channel: .dummy(cid: cid), membership: membership
1370+
)
1371+
try! client.databaseContainer.writeSynchronously { session in
1372+
try session.saveChannel(payload: initialChannelPayload)
1373+
}
1374+
1375+
// Load initial data
1376+
let exp = expectation(description: "sync completes")
1377+
controller.synchronize { _ in
1378+
exp.fulfill()
1379+
}
1380+
client.mockAPIClient.test_simulateResponse(.success(initialChannelPayload))
1381+
1382+
waitForExpectations(timeout: defaultTimeout)
1383+
XCTAssertEqual(controller.channel?.membership?.isBannedFromChannel, false)
1384+
1385+
// Ban member
1386+
try! client.databaseContainer.writeSynchronously { session in
1387+
try session.saveMember(payload: .dummy(user: .dummy(userId: userId), isMemberBanned: true), channelId: cid)
1388+
}
1389+
1390+
let event = UserBannedEvent(
1391+
cid: cid,
1392+
user: .mock(id: userId),
1393+
ownerId: .unique,
1394+
createdAt: .unique,
1395+
reason: nil,
1396+
expiredAt: nil,
1397+
isShadowBan: nil
1398+
)
1399+
1400+
// When
1401+
controller.eventsController(
1402+
EventsController(notificationCenter: client.eventNotificationCenter),
1403+
didReceiveEvent: event
1404+
)
1405+
1406+
// Then
1407+
XCTAssertEqual(controller.channel?.membership?.isBannedFromChannel, true)
1408+
}
1409+
1410+
func test_didReceiveEvent_userUnbannedEvent_updatesChannelFromDataStore() {
1411+
// Given - Set up initial channel in database
1412+
let cid = controller.cid!
1413+
1414+
let userId = UserId.unique
1415+
let membership = MemberPayload.dummy(user: .dummy(userId: userId), isMemberBanned: true)
1416+
1417+
// Save initial channel to database
1418+
let initialChannelPayload = ChannelPayload.dummy(
1419+
channel: .dummy(cid: cid), membership: membership
1420+
)
1421+
try! client.databaseContainer.writeSynchronously { session in
1422+
try session.saveChannel(payload: initialChannelPayload)
1423+
}
1424+
1425+
// Load initial data
1426+
let exp = expectation(description: "sync completes")
1427+
controller.synchronize { _ in
1428+
exp.fulfill()
1429+
}
1430+
client.mockAPIClient.test_simulateResponse(.success(initialChannelPayload))
1431+
1432+
waitForExpectations(timeout: defaultTimeout)
1433+
XCTAssertEqual(controller.channel?.membership?.isBannedFromChannel, true)
1434+
1435+
// Unban member
1436+
try! client.databaseContainer.writeSynchronously { session in
1437+
try session.saveMember(payload: .dummy(user: .dummy(userId: userId), isMemberBanned: false), channelId: cid)
1438+
}
1439+
1440+
let event = UserUnbannedEvent(
1441+
cid: cid,
1442+
user: .mock(id: userId),
1443+
createdAt: .unique
1444+
)
1445+
1446+
// When
1447+
controller.eventsController(
1448+
EventsController(notificationCenter: client.eventNotificationCenter),
1449+
didReceiveEvent: event
1450+
)
1451+
1452+
// Then
1453+
XCTAssertEqual(controller.channel?.membership?.isBannedFromChannel, false)
1454+
}
1455+
13601456
func test_didReceiveEvent_channelTruncatedEvent_updatesChannelAndMessages() {
13611457
// Given - Set up initial channel with messages
13621458
let cid = controller.cid!

0 commit comments

Comments
 (0)