Skip to content

Commit 8e88fad

Browse files
authored
Use max file size for validating attachments defined in Stream's Dashboard (#490)
1 parent c6844f2 commit 8e88fad

File tree

9 files changed

+116
-36
lines changed

9 files changed

+116
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44
# Upcoming
55

6-
### 🔄 Changed
6+
### ✅ Added
7+
- Use max file size for validating attachments defined in Stream's Dashboard [#490](https://github.com/GetStream/stream-chat-swiftui/pull/490)
78

89
# [4.56.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.56.0)
910
_May 21, 2024_

Sources/StreamChatSwiftUI/ChatChannel/Composer/MessageComposerViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ open class MessageComposerViewModel: ObservableObject {
678678

679679
do {
680680
let fileSize = try AttachmentFile(url: url).size
681-
let canAdd = fileSize < chatClient.config.maxAttachmentSize
681+
let canAdd = fileSize < chatClient.maxAttachmentSize(for: url)
682682
attachmentSizeExceeded = !canAdd
683683
return canAdd
684684
} catch {

Sources/StreamChatSwiftUI/ChatChannel/Composer/PhotoAssetsUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class PhotoAssetLoader: NSObject, ObservableObject {
5656
_ = url?.startAccessingSecurityScopedResource()
5757
if let assetURL = url,
5858
let file = try? AttachmentFile(url: assetURL),
59-
file.size >= chatClient.config.maxAttachmentSize {
59+
file.size >= chatClient.maxAttachmentSize(for: assetURL) {
6060
return true
6161
} else {
6262
return false
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// Copyright © 2024 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import StreamChat
6+
7+
extension ChatClient {
8+
/// The maximum attachment size for the file URL.
9+
///
10+
/// The max attachment size can be set from the Stream's Dashboard App Settings.
11+
///
12+
/// - Parameter fileURL: The file URL of the attachment.
13+
/// - Returns: The maximum allowed size for the attachment in bytes.
14+
func maxAttachmentSize(for fileURL: URL) -> Int64 {
15+
let attachmentType = AttachmentType(fileExtension: fileURL.pathExtension)
16+
let maxAttachmentSize: Int64?
17+
switch attachmentType {
18+
case .image:
19+
maxAttachmentSize = appSettings?.imageUploadConfig.sizeLimitInBytes
20+
default:
21+
maxAttachmentSize = appSettings?.fileUploadConfig.sizeLimitInBytes
22+
}
23+
if let maxAttachmentSize, maxAttachmentSize > 0 {
24+
return maxAttachmentSize
25+
} else {
26+
return config.maxAttachmentSize
27+
}
28+
}
29+
}

StreamChatSwiftUI.xcodeproj/project.pbxproj

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
/* Begin PBXBuildFile section */
1010
402C54482B6AAC0100672BFB /* StreamChatSwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; };
1111
402C54492B6AAC0100672BFB /* StreamChatSwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12+
4F7DD9A02BFC7C6100599AA6 /* ChatClient+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7DD99F2BFC7C6100599AA6 /* ChatClient+Extensions.swift */; };
13+
4F7DD9A22BFCB2EF00599AA6 /* ChatClientExtensions_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7DD9A12BFCB2EF00599AA6 /* ChatClientExtensions_Tests.swift */; };
1214
8205B4142AD41CC700265B84 /* StreamSwiftTestHelpers in Frameworks */ = {isa = PBXBuildFile; productRef = 8205B4132AD41CC700265B84 /* StreamSwiftTestHelpers */; };
1315
8205B4182AD4267200265B84 /* StreamSwiftTestHelpers in Frameworks */ = {isa = PBXBuildFile; productRef = 8205B4172AD4267200265B84 /* StreamSwiftTestHelpers */; };
1416
820A61A029D6D78E002257FB /* QuotedReply_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820A619F29D6D78E002257FB /* QuotedReply_Tests.swift */; };
@@ -546,6 +548,8 @@
546548

547549
/* Begin PBXFileReference section */
548550
4A65451E274BA170003C5FA8 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
551+
4F7DD99F2BFC7C6100599AA6 /* ChatClient+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatClient+Extensions.swift"; sourceTree = "<group>"; };
552+
4F7DD9A12BFCB2EF00599AA6 /* ChatClientExtensions_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatClientExtensions_Tests.swift; sourceTree = "<group>"; };
549553
820A619F29D6D78E002257FB /* QuotedReply_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuotedReply_Tests.swift; sourceTree = "<group>"; };
550554
825AADF3283CCDB000237498 /* ThreadPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadPage.swift; sourceTree = "<group>"; };
551555
829AB4D128578ACF002DC629 /* StreamTestCase+Tags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StreamTestCase+Tags.swift"; sourceTree = "<group>"; };
@@ -1733,23 +1737,24 @@
17331737
isa = PBXGroup;
17341738
children = (
17351739
8465FD392746A95600AF091E /* AutoLayoutHelpers.swift */,
1736-
8465FD3A2746A95600AF091E /* DateFormatter+Extensions.swift */,
1737-
8465FD3C2746A95600AF091E /* UIFont+Extensions.swift */,
1738-
8465FD3D2746A95600AF091E /* ImageCDN.swift */,
1739-
8465FD3E2746A95600AF091E /* UIColor+Extensions.swift */,
1740-
8465FD3F2746A95600AF091E /* UIImage+Extensions.swift */,
1741-
8465FD402746A95600AF091E /* DateUtils.swift */,
1740+
8465FD452746A95600AF091E /* Cache.swift */,
17421741
8465FD412746A95600AF091E /* ChatChannelNamer.swift */,
1743-
91B79FD6284E21E0005B6E4F /* ChatUserNamer.swift */,
1744-
8465FD422746A95600AF091E /* InputTextView.swift */,
1745-
8465FD432746A95600AF091E /* NSLayoutConstraint+Extensions.swift */,
1742+
4F7DD99F2BFC7C6100599AA6 /* ChatClient+Extensions.swift */,
17461743
8465FD442746A95600AF091E /* ChatMessage+Extensions.swift */,
1747-
8465FD452746A95600AF091E /* Cache.swift */,
1748-
8465FD462746A95600AF091E /* VideoPreviewLoader.swift */,
17491744
8465FD472746A95600AF091E /* ChatMessageReactionAppeareance.swift */,
1745+
91B79FD6284E21E0005B6E4F /* ChatUserNamer.swift */,
1746+
8465FD3A2746A95600AF091E /* DateFormatter+Extensions.swift */,
1747+
8465FD402746A95600AF091E /* DateUtils.swift */,
1748+
8465FD3D2746A95600AF091E /* ImageCDN.swift */,
17501749
8465FD482746A95600AF091E /* ImageMerger.swift */,
1750+
8465FD422746A95600AF091E /* InputTextView.swift */,
1751+
8465FD432746A95600AF091E /* NSLayoutConstraint+Extensions.swift */,
17511752
8465FD492746A95600AF091E /* NukeImageProcessor.swift */,
1753+
8465FD3E2746A95600AF091E /* UIColor+Extensions.swift */,
1754+
8465FD3C2746A95600AF091E /* UIFont+Extensions.swift */,
1755+
8465FD3F2746A95600AF091E /* UIImage+Extensions.swift */,
17521756
A3D7B0DE2840E23100E308B3 /* UIView+AccessibilityIdentifier.swift */,
1757+
8465FD462746A95600AF091E /* VideoPreviewLoader.swift */,
17531758
);
17541759
path = Common;
17551760
sourceTree = "<group>";
@@ -1976,6 +1981,7 @@
19761981
84C94D52275A135F007FE2B9 /* Utils */ = {
19771982
isa = PBXGroup;
19781983
children = (
1984+
4F7DD9A12BFCB2EF00599AA6 /* ChatClientExtensions_Tests.swift */,
19791985
91CC203B283C4C250049A146 /* URLUtils_Tests.swift */,
19801986
84C94D53275A1380007FE2B9 /* DateUtils_Tests.swift */,
19811987
84C94D55275A1AE1007FE2B9 /* StringExtensions_Tests.swift */,
@@ -2587,6 +2593,7 @@
25872593
8465FD8A2746A95700AF091E /* DiscardAttachmentButton.swift in Sources */,
25882594
8482094E2ACFFCD900EF3261 /* Throttler.swift in Sources */,
25892595
84EADEBD2B28C2EC0046B50C /* RecordingState.swift in Sources */,
2596+
4F7DD9A02BFC7C6100599AA6 /* ChatClient+Extensions.swift in Sources */,
25902597
82D64C1B2AD7E5B700C5C79E /* ImageCaching.swift in Sources */,
25912598
82D64C062AD7E5B700C5C79E /* Graphics.swift in Sources */,
25922599
8465FDCB2746A95700AF091E /* ChatChannelListView.swift in Sources */,
@@ -2688,6 +2695,7 @@
26882695
84E0478C284A444E00BAFA17 /* TestRequest.swift in Sources */,
26892696
84CAD77B284E5AAA00F28C17 /* MessageListViewLastGroupHeader_Tests.swift in Sources */,
26902697
84779C772AEBCA6E000A6A68 /* ReactionsIconProvider_Tests.swift in Sources */,
2698+
4F7DD9A22BFCB2EF00599AA6 /* ChatClientExtensions_Tests.swift in Sources */,
26912699
91CC203C283C4C250049A146 /* URLUtils_Tests.swift in Sources */,
26922700
84B2B5DA281985DA00479CEE /* FileAttachmentsView_Tests.swift in Sources */,
26932701
848399F227601231003075E4 /* ReactionsOverlayView_Tests.swift in Sources */,

StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@
44

55
import Foundation
66
@testable import StreamChat
7+
@testable import StreamChatTestTools
78

89
public extension ChatClient {
910
/// Create a new instance of mock `ChatClient`
1011
static func mock(
1112
isLocalStorageEnabled: Bool = false,
1213
customCDNClient: CDNClient? = nil
13-
) -> ChatClient {
14+
) -> ChatClient_Mock {
1415
var config = ChatClientConfig(apiKey: .init("--== Mock ChatClient ==--"))
1516
config.customCDNClient = customCDNClient
1617
config.isLocalStorageEnabled = isLocalStorageEnabled
1718
config.isClientInActiveMode = false
1819
config.maxAttachmentCountPerMessage = 10
1920

20-
return .init(
21+
return ChatClient_Mock(
2122
config: config,
23+
workerBuilders: [],
2224
environment: .init(
23-
apiClientBuilder: APIClient_Mock.init,
25+
apiClientBuilder: APIClient_Spy.init,
2426
webSocketClientBuilder: {
2527
WebSocketClient_Mock(
2628
sessionConfiguration: $0,
@@ -54,20 +56,3 @@ extension ChatClient {
5456
)
5557
}
5658
}
57-
58-
// ===== TEMP =====
59-
60-
class APIClient_Mock: APIClient {
61-
override func request<Response>(
62-
endpoint: Endpoint<Response>,
63-
completion: @escaping (Result<Response, Error>) -> Void
64-
) where Response: Decodable {
65-
// Do nothing for now
66-
}
67-
}
68-
69-
class WebSocketClient_Mock: WebSocketClient {
70-
override func connect() {
71-
// Do nothing for now
72-
}
73-
}

StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerViewModel_Tests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
@testable import StreamChat
66
@testable import StreamChatSwiftUI
7+
@testable import StreamChatTestTools
78
import XCTest
89

910
class MessageComposerViewModel_Tests: StreamChatTestCase {
@@ -492,6 +493,24 @@ class MessageComposerViewModel_Tests: StreamChatTestCase {
492493
XCTAssert(alertShown == true)
493494
}
494495

496+
func test_messageComposerVM_maxSizeExceededWithAppSettingsConfiguration() {
497+
// Given
498+
let expectedValue: Int64 = 5
499+
chatClient.mockedAppSettings = .mock(imageUploadConfig: .mock(
500+
sizeLimitInBytes: expectedValue
501+
))
502+
let viewModel = makeComposerViewModel()
503+
504+
// When
505+
let newAsset = defaultAsset
506+
viewModel.imageTapped(newAsset) // will not be added because of small max attachment size.
507+
let alertShown = viewModel.attachmentSizeExceeded
508+
509+
// Then
510+
XCTAssert(viewModel.addedAssets.isEmpty)
511+
XCTAssert(alertShown == true)
512+
}
513+
495514
func test_messageComposerVM_mentionUsers() {
496515
// Given
497516
let viewModel = makeComposerViewModel()

StreamChatSwiftUITests/Tests/StreamChatTestCase.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
@testable import StreamChat
66
@testable import StreamChatSwiftUI
7-
@_exported import StreamChatTestTools
7+
@_exported @testable import StreamChatTestTools
88
@_exported import StreamSwiftTestHelpers
99
import XCTest
1010

@@ -13,7 +13,7 @@ open class StreamChatTestCase: XCTestCase {
1313

1414
public static var currentUserId: String = .unique
1515

16-
public var chatClient: ChatClient = {
16+
public var chatClient: ChatClient_Mock = {
1717
let client = ChatClient.mock(isLocalStorageEnabled: false)
1818
let tokenValue =
1919
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoibHVrZV9za3l3YWxrZXIifQ.b6EiC8dq2AHk0JPfI-6PN-AM9TVzt8JV-qB1N9kchlI"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// Copyright © 2024 Stream.io Inc. All rights reserved.
3+
//
4+
5+
@testable import StreamChat
6+
@testable import StreamChatSwiftUI
7+
@testable import StreamChatTestTools
8+
import XCTest
9+
10+
final class ChatClientExtensions_Tests: StreamChatTestCase {
11+
func test_maxAttachmentSize_file() {
12+
// Given
13+
let expectedValue: Int64 = 512
14+
chatClient.mockedAppSettings = .mock(fileUploadConfig: .mock(
15+
sizeLimitInBytes: expectedValue
16+
))
17+
18+
// When
19+
let size = chatClient.maxAttachmentSize(for: .localYodaQuote)
20+
21+
// Then
22+
XCTAssertEqual(size, expectedValue)
23+
}
24+
25+
func test_maxAttachmentSize_image() {
26+
// Given
27+
let expectedValue: Int64 = 256
28+
chatClient.mockedAppSettings = .mock(imageUploadConfig: .mock(
29+
sizeLimitInBytes: expectedValue
30+
))
31+
32+
// When
33+
let size = chatClient.maxAttachmentSize(for: .localYodaImage)
34+
35+
// Then
36+
XCTAssertEqual(size, expectedValue)
37+
}
38+
}

0 commit comments

Comments
 (0)