Skip to content

Commit e288332

Browse files
committed
Fix caching key using original URL instead of final resized URL
buildCachingKey was called with the original URL, so different resize variants of the same image shared the same cache key. Now it uses the final URL produced by buildImageURL, which includes the resize query parameters. Also fix test target membership for StreamCDN_Tests and add tests covering the caching key correctness for resized images.
1 parent d0aa17a commit e288332

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

Sources/StreamChat/APIClient/CDNClient/StreamCDNRequester.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ open class StreamCDNRequester: CDNRequester, @unchecked Sendable {
2727
completion: @escaping (Result<CDNRequest, Error>) -> Void
2828
) {
2929
let finalURL = buildImageURL(from: url, resize: options.resize)
30-
let cachingKey = buildCachingKey(for: url)
30+
let cachingKey = buildCachingKey(for: finalURL)
3131
completion(.success(CDNRequest(url: finalURL, cachingKey: cachingKey)))
3232
}
3333

StreamChat.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@
713713
StreamChatTests/APIClient/HTTPHeader_Tests.swift,
714714
StreamChatTests/APIClient/RequestDecoder_Tests.swift,
715715
StreamChatTests/APIClient/RequestEncoder_Tests.swift,
716-
StreamChatTests/APIClient/StreamCDNClient_Tests.swift,
716+
StreamChatTests/APIClient/CDNClient/StreamCDN_Tests.swift,
717717
StreamChatTests/Audio/AudioAnalysisEngine_Tests.swift,
718718
StreamChatTests/Audio/AudioPlaybackContext_Tests.swift,
719719
StreamChatTests/Audio/AudioPlaybackRate_Tests.swift,

Tests/StreamChatTests/APIClient/CDNClient/StreamCDN_Tests.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,61 @@ final class StreamCDNRequester_Tests: XCTestCase {
110110
waitForExpectations(timeout: 1)
111111
}
112112

113+
func test_imageRequest_cachingKey_includesResizeParamsFromOptions() {
114+
let url = URL(string: "\(baseUrl)/image.jpg")!
115+
let expectation = expectation(description: "Completion called")
116+
117+
sut.imageRequest(for: url, options: .init(resize: CDNImageResize(width: 40, height: 60, resizeMode: "clip"))) { result in
118+
let request = try! result.get()
119+
let key = request.cachingKey!
120+
121+
XCTAssertTrue(key.contains("w="), "Caching key should contain width from resize options")
122+
XCTAssertTrue(key.contains("h="), "Caching key should contain height from resize options")
123+
XCTAssertTrue(key.contains("resize=clip"), "Caching key should contain resize mode")
124+
expectation.fulfill()
125+
}
126+
127+
waitForExpectations(timeout: 1)
128+
}
129+
130+
func test_imageRequest_cachingKey_differentResizeProducesDifferentKeys() {
131+
let url = URL(string: "\(baseUrl)/image.jpg")!
132+
let smallResize = CDNImageResize(width: 40, height: 40, resizeMode: "clip")
133+
let largeResize = CDNImageResize(width: 200, height: 200, resizeMode: "clip")
134+
135+
let expectation1 = expectation(description: "Small resize")
136+
let expectation2 = expectation(description: "Large resize")
137+
var smallKey: String?
138+
var largeKey: String?
139+
140+
sut.imageRequest(for: url, options: .init(resize: smallResize)) { result in
141+
smallKey = try! result.get().cachingKey
142+
expectation1.fulfill()
143+
}
144+
sut.imageRequest(for: url, options: .init(resize: largeResize)) { result in
145+
largeKey = try! result.get().cachingKey
146+
expectation2.fulfill()
147+
}
148+
149+
waitForExpectations(timeout: 1)
150+
XCTAssertNotEqual(smallKey, largeKey, "Different resize dimensions must produce different caching keys")
151+
}
152+
153+
func test_imageRequest_cachingKey_noResize_hasNoResizeParams() {
154+
let url = URL(string: "\(baseUrl)/image.jpg")!
155+
let expectation = expectation(description: "Completion called")
156+
157+
sut.imageRequest(for: url, options: .init()) { result in
158+
let request = try! result.get()
159+
let key = request.cachingKey!
160+
XCTAssertFalse(key.contains("w="), "Caching key without resize should not contain width")
161+
XCTAssertFalse(key.contains("h="), "Caching key without resize should not contain height")
162+
expectation.fulfill()
163+
}
164+
165+
waitForExpectations(timeout: 1)
166+
}
167+
113168
func test_imageRequest_cachingKey_nonStreamCDNRequester_returnsFullURL() {
114169
let url = URL(string: "https://www.google.com/image.jpg?token=abc")!
115170
let expectation = expectation(description: "Completion called")

0 commit comments

Comments
 (0)