Skip to content

Commit 8b915f6

Browse files
committed
Adding check to only save datafile in cache if valid.
1 parent ccda0bd commit 8b915f6

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

Sources/Customization/DefaultDatafileHandler.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019-2022, Optimizely, Inc. and contributors
2+
// Copyright 2019-2023, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -158,12 +158,18 @@ open class DefaultDatafileHandler: OPTDatafileHandler {
158158
open func getResponseData(sdkKey: String, response: HTTPURLResponse, url: URL?) -> Data? {
159159
if let url = url, let data = try? Data(contentsOf: url) {
160160
self.logger.d { String(data: data, encoding: .utf8) ?? "" }
161-
self.saveDatafile(sdkKey: sdkKey, dataFile: data)
162-
if let lastModified = response.getLastModified() {
163-
self.sharedDataStore.setLastModified(sdkKey: sdkKey, lastModified: lastModified)
161+
// Check datafile is valid json
162+
do {
163+
// Try deserializing datafile, isValidJSONObject is not applicable here
164+
_ = try JSONSerialization.jsonObject(with: data)
165+
self.saveDatafile(sdkKey: sdkKey, dataFile: data)
166+
if let lastModified = response.getLastModified() {
167+
self.sharedDataStore.setLastModified(sdkKey: sdkKey, lastModified: lastModified)
168+
}
169+
return data
170+
} catch {
171+
print("Error deserializing datafile: \(error.localizedDescription)")
164172
}
165-
166-
return data
167173
}
168174

169175
return nil

Tests/OptimizelyTests-Common/DatafileHandlerTests.swift

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019, 2021, Optimizely, Inc. and contributors
2+
// Copyright 2019, 2021, 2023, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -65,7 +65,65 @@ class DatafileHandlerTests: XCTestCase {
6565
// This is an example of a functional test case.
6666
// Use XCTAssert and related functions to verify your tests produce the correct results.
6767
}
68+
69+
func testDatafileDownloadWith200AndValidDatafile() {
70+
// Datafile and last updated should not be saved in this case
71+
let handler = MockDatafileHandler(statusCode: 200, localResponseData:"{}")
72+
let expectation = XCTestExpectation(description: "no-nil data")
73+
74+
handler.downloadDatafile(sdkKey: sdkKey) { (result) in
75+
if case let .success(data) = result {
76+
XCTAssert(data != nil)
77+
expectation.fulfill()
78+
}
79+
}
80+
81+
wait(for: [expectation], timeout: 3)
82+
XCTAssertTrue(handler.isDatafileSaved(sdkKey: sdkKey))
83+
XCTAssertNotNil(handler.sharedDataStore.getLastModified(sdkKey: sdkKey))
84+
}
85+
6886

87+
func testDatafileDownloadWith200AndInvalidDatafile() {
88+
// Datafile and last updated should not be saved in this case
89+
let handler = MockDatafileHandler(statusCode: 200, localResponseData: "1231")
90+
let expectation = XCTestExpectation(description: "wait to get failure")
91+
92+
handler.downloadDatafile(sdkKey: sdkKey) { (result) in
93+
if case .success(_) = result {
94+
XCTFail()
95+
}
96+
if case .failure(_) = result {
97+
expectation.fulfill()
98+
}
99+
}
100+
101+
wait(for: [expectation], timeout: 3)
102+
XCTAssertFalse(handler.isDatafileSaved(sdkKey: sdkKey))
103+
XCTAssertNil(handler.sharedDataStore.getLastModified(sdkKey: sdkKey))
104+
}
105+
106+
func testStartWith200AndInvalidDatafile() {
107+
let handler = MockDatafileHandler(statusCode: 200, localResponseData: "1231")
108+
let expectation = XCTestExpectation(description: "wait to get failure")
109+
110+
let optimizely = OptimizelyClient(sdkKey: sdkKey,
111+
datafileHandler: handler,
112+
periodicDownloadInterval: 1)
113+
114+
optimizely.start(completion: { result in
115+
if case let .failure(error) = result {
116+
print(error)
117+
XCTAssert(true)
118+
expectation.fulfill()
119+
}
120+
})
121+
122+
wait(for: [expectation], timeout: 3)
123+
XCTAssertFalse(handler.isDatafileSaved(sdkKey: sdkKey))
124+
XCTAssertNil(handler.sharedDataStore.getLastModified(sdkKey: sdkKey))
125+
}
126+
69127
func testDatafileDownload500() {
70128
OTUtils.createDatafileCache(sdkKey: sdkKey)
71129

Tests/OptimizelyTests-MultiClients/DatafileHandlerTests_MultiClients.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2021, Optimizely, Inc. and contributors
2+
// Copyright 2021, 2023, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ class DatafileHandlerTests_MultiClients: XCTestCase {
3939

4040
func testConcurrentDownloadDatafiles() {
4141
// use a shared DatafileHandler instance
42-
let mockHandler = MockDatafileHandler(statusCode: 200)
42+
let mockHandler = MockDatafileHandler(statusCode: 200, localResponseData: "{}")
4343

4444
sdkKeys = OTUtils.makeRandomSdkKeys(100)
4545

@@ -153,7 +153,7 @@ class DatafileHandlerTests_MultiClients: XCTestCase {
153153

154154
func testConcurrentAccessLastModified() {
155155
// use a shared DatafileHandler instance
156-
let mockHandler = MockDatafileHandler(statusCode: 200)
156+
let mockHandler = MockDatafileHandler(statusCode: 200, localResponseData: "{}")
157157

158158
sdkKeys = OTUtils.makeRandomSdkKeys(100)
159159

@@ -241,7 +241,7 @@ class DatafileHandlerTests_MultiClients: XCTestCase {
241241
}
242242

243243
// use a shared DatafileHandler instance
244-
let mockHandler = MockDatafileHandler(statusCode: 200)
244+
let mockHandler = MockDatafileHandler(statusCode: 200, localResponseData: "{}")
245245

246246
let numSdks = 50
247247
sdkKeys = OTUtils.makeRandomSdkKeys(numSdks)

0 commit comments

Comments
 (0)