Skip to content

Commit 6f6c680

Browse files
added tests for the ChatChannelViewModel
1 parent dd8c699 commit 6f6c680

File tree

3 files changed

+221
-15
lines changed

3 files changed

+221
-15
lines changed

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -142,27 +142,16 @@ public class ChatChannelViewModel: ObservableObject, ChatChannelControllerDelega
142142
}
143143

144144
func showReactionOverlay() {
145-
let view: UIView = topVC()!.view
145+
guard let view: UIView = topVC()?.view else {
146+
currentSnapshot = UIImage(systemName: "photo")
147+
return
148+
}
146149
UIGraphicsBeginImageContext(view.frame.size)
147150
view.layer.render(in: UIGraphicsGetCurrentContext()!)
148151
currentSnapshot = UIGraphicsGetImageFromCurrentImageContext()
149152
UIGraphicsEndImageContext()
150153
}
151154

152-
func topVC() -> UIViewController? {
153-
let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
154-
155-
if var topController = keyWindow?.rootViewController {
156-
while let presentedViewController = topController.presentedViewController {
157-
topController = presentedViewController
158-
}
159-
160-
return topController
161-
}
162-
163-
return nil
164-
}
165-
166155
// MARK: - private
167156

168157
private func setupChannelController() {
@@ -187,6 +176,20 @@ public class ChatChannelViewModel: ObservableObject, ChatChannelControllerDelega
187176
}
188177
}
189178

179+
private func topVC() -> UIViewController? {
180+
let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
181+
182+
if var topController = keyWindow?.rootViewController {
183+
while let presentedViewController = topController.presentedViewController {
184+
topController = presentedViewController
185+
}
186+
187+
return topController
188+
}
189+
190+
return nil
191+
}
192+
190193
private func save(lastDate: Date) {
191194
currentDate = lastDate
192195
timer?.invalidate()

StreamChatSwiftUI.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208
84C94D422757C16D007FE2B9 /* ChatChannelListTestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94D412757C16D007FE2B9 /* ChatChannelListTestHelpers.swift */; };
209209
84C94D442757C704007FE2B9 /* MoreChannelActionsViewModel_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94D432757C704007FE2B9 /* MoreChannelActionsViewModel_Tests.swift */; };
210210
84C94D462757D1CA007FE2B9 /* ImageLoader_Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94D452757D1CA007FE2B9 /* ImageLoader_Mock.swift */; };
211+
84C94D492758BE1C007FE2B9 /* ChatChannelViewModel_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C94D482758BE1C007FE2B9 /* ChatChannelViewModel_Tests.swift */; };
211212
84EDBC37274FE5CD0057218D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 84EDBC36274FE5CD0057218D /* Localizable.strings */; };
212213
/* End PBXBuildFile section */
213214

@@ -446,6 +447,7 @@
446447
84C94D412757C16D007FE2B9 /* ChatChannelListTestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelListTestHelpers.swift; sourceTree = "<group>"; };
447448
84C94D432757C704007FE2B9 /* MoreChannelActionsViewModel_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreChannelActionsViewModel_Tests.swift; sourceTree = "<group>"; };
448449
84C94D452757D1CA007FE2B9 /* ImageLoader_Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLoader_Mock.swift; sourceTree = "<group>"; };
450+
84C94D482758BE1C007FE2B9 /* ChatChannelViewModel_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelViewModel_Tests.swift; sourceTree = "<group>"; };
449451
84EDBC36274FE5CD0057218D /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
450452
/* End PBXFileReference section */
451453

@@ -941,10 +943,19 @@
941943
isa = PBXGroup;
942944
children = (
943945
84C94C7D27567CC2007FE2B9 /* ChatChannelList */,
946+
84C94D472758BDB2007FE2B9 /* ChatChannel */,
944947
);
945948
path = Tests;
946949
sourceTree = "<group>";
947950
};
951+
84C94D472758BDB2007FE2B9 /* ChatChannel */ = {
952+
isa = PBXGroup;
953+
children = (
954+
84C94D482758BE1C007FE2B9 /* ChatChannelViewModel_Tests.swift */,
955+
);
956+
path = ChatChannel;
957+
sourceTree = "<group>";
958+
};
948959
/* End PBXGroup section */
949960

950961
/* Begin PBXHeadersBuildPhase section */
@@ -1252,6 +1263,7 @@
12521263
84C94D3927579BB0007FE2B9 /* TestDataModel.xcdatamodeld in Sources */,
12531264
84C94CDB27578B92007FE2B9 /* NSManagedObject+ContextChange.swift in Sources */,
12541265
84C94D0C27578BF2007FE2B9 /* AssertJSONEqual.swift in Sources */,
1266+
84C94D492758BE1C007FE2B9 /* ChatChannelViewModel_Tests.swift in Sources */,
12551267
84C94CE027578B92007FE2B9 /* CurrentUserPayload.swift in Sources */,
12561268
84C94CCD27578B92007FE2B9 /* ChannelUnreadCount_Mock.swift in Sources */,
12571269
84C94CDC27578B92007FE2B9 /* DatabaseContainer_Mock.swift in Sources */,
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//
2+
// Copyright © 2021 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import XCTest
6+
@testable import StreamChatSwiftUI
7+
@testable import StreamChat
8+
9+
class ChatChannelViewModel_Tests: XCTestCase {
10+
11+
private var chatClient: ChatClient = {
12+
let client = ChatClient.mock()
13+
client.currentUserId = .unique
14+
return client
15+
}()
16+
17+
private var streamChat: StreamChat?
18+
19+
override func setUp() {
20+
super.setUp()
21+
streamChat = StreamChat(chatClient: chatClient)
22+
}
23+
24+
func test_chatChannelVM_messagesLoaded() {
25+
// Given
26+
let channelController = makeChannelController()
27+
let viewModel = ChatChannelViewModel(channelController: channelController)
28+
29+
// When
30+
let messages = viewModel.messages
31+
32+
// Then
33+
XCTAssert(messages.count == 1)
34+
}
35+
36+
func test_chatChannelVM_messageGrouping() {
37+
// Given
38+
var messages = [ChatMessage]()
39+
var offset: Double = 200
40+
for i in 0..<16 {
41+
if i % 2 == 0 {
42+
offset += 200
43+
}
44+
let createdAt = Date(timeIntervalSince1970: offset)
45+
let message = ChatMessage.mock(
46+
id: .unique,
47+
cid: .unique,
48+
text: "Test Message \(i)",
49+
author: ChatUser.mock(id: chatClient.currentUserId!),
50+
createdAt: createdAt
51+
)
52+
53+
messages.append(message)
54+
}
55+
let channelController = makeChannelController(messages: messages)
56+
let viewModel = ChatChannelViewModel(channelController: channelController)
57+
58+
// When
59+
let messagesGroupingInfo = viewModel.messagesGroupingInfo
60+
61+
// Then
62+
XCTAssert(messagesGroupingInfo.count == 8)
63+
for (_, groupingInfo) in messagesGroupingInfo {
64+
XCTAssert(groupingInfo.count == 1)
65+
}
66+
}
67+
68+
func test_chatChannelVM_scrollToLastMessage() {
69+
// Given
70+
let messageId: String = .unique
71+
let message = ChatMessage.mock(
72+
id: messageId,
73+
cid: .unique,
74+
text: "Test message",
75+
author: ChatUser.mock(id: chatClient.currentUserId!)
76+
)
77+
let channelController = makeChannelController(messages: [message])
78+
let viewModel = ChatChannelViewModel(channelController: channelController)
79+
80+
// When
81+
viewModel.scrollToLastMessage()
82+
83+
// Then
84+
XCTAssert(viewModel.scrolledId == messageId)
85+
}
86+
87+
func test_chatChannelVM_currentDateString() {
88+
// Given
89+
let expectedDate = "Jan 01"
90+
let channelController = makeChannelController()
91+
let viewModel = ChatChannelViewModel(channelController: channelController)
92+
93+
// When
94+
viewModel.showScrollToLatestButton = true
95+
viewModel.handleMessageAppear(index: 0)
96+
97+
// Then
98+
let dateString = viewModel.currentDateString
99+
XCTAssert(dateString == expectedDate)
100+
}
101+
102+
func test_chatChannelVM_showReactionsOverlay() {
103+
// Given
104+
let channelController = makeChannelController()
105+
let viewModel = ChatChannelViewModel(channelController: channelController)
106+
107+
// When
108+
viewModel.showReactionOverlay()
109+
110+
// Then
111+
XCTAssert(viewModel.currentSnapshot != nil)
112+
XCTAssert(viewModel.reactionsShown == true)
113+
}
114+
115+
func test_chatChannelVM_listRefresh() {
116+
// Given
117+
var messages = [ChatMessage]()
118+
for i in 0..<250 {
119+
let message = ChatMessage.mock(
120+
id: .unique,
121+
cid: .unique,
122+
text: "Test Message \(i)",
123+
author: ChatUser.mock(id: chatClient.currentUserId!)
124+
)
125+
messages.append(message)
126+
}
127+
let channelController = makeChannelController(messages: messages)
128+
let viewModel = ChatChannelViewModel(channelController: channelController)
129+
130+
// When
131+
let initialListId = viewModel.listId
132+
channelController.simulate(messages: messages, changes: [])
133+
134+
// Then
135+
let newListId = viewModel.listId
136+
XCTAssert(initialListId != newListId)
137+
}
138+
139+
func test_chatChannelVM_listNoRefresh() {
140+
// Given
141+
var messages = [ChatMessage]()
142+
for i in 0..<200 {
143+
let message = ChatMessage.mock(
144+
id: .unique,
145+
cid: .unique,
146+
text: "Test Message \(i)",
147+
author: ChatUser.mock(id: chatClient.currentUserId!)
148+
)
149+
messages.append(message)
150+
}
151+
let channelController = makeChannelController(messages: messages)
152+
let viewModel = ChatChannelViewModel(channelController: channelController)
153+
154+
// When
155+
let initialListId = viewModel.listId
156+
channelController.simulate(messages: messages, changes: [])
157+
158+
// Then
159+
let newListId = viewModel.listId
160+
XCTAssert(initialListId == newListId)
161+
}
162+
163+
//MARK: - private
164+
165+
private func makeChannelController(
166+
messages: [ChatMessage] = []
167+
) -> ChatChannelController_Mock {
168+
let channel = ChatChannel.mockDMChannel()
169+
let channelQuery = ChannelQuery(cid: channel.cid)
170+
let channelListQuery = ChannelListQuery(filter: .containMembers(userIds: [chatClient.currentUserId!]))
171+
let channelController = ChatChannelController_Mock(
172+
channelQuery: channelQuery,
173+
channelListQuery: channelListQuery,
174+
client: chatClient
175+
)
176+
var channelMessages = messages
177+
if channelMessages.isEmpty {
178+
let message = ChatMessage.mock(
179+
id: .unique,
180+
cid: channel.cid,
181+
text: "Test message",
182+
author: ChatUser.mock(id: chatClient.currentUserId!)
183+
)
184+
channelMessages = [message]
185+
}
186+
187+
channelController.simulateInitial(channel: channel, messages: channelMessages, state: .initialized)
188+
return channelController
189+
}
190+
191+
}

0 commit comments

Comments
 (0)