Skip to content

Commit fd4572c

Browse files
authored
Async/await variations of existing RC Swift API tests (#8825)
1 parent fc2cf7b commit fd4572c

File tree

3 files changed

+170
-12
lines changed

3 files changed

+170
-12
lines changed

FirebaseRemoteConfig.podspec

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ app update.
8282
# Run Swift API tests on a real backend.
8383
s.test_spec 'swift-api-tests' do |swift_api|
8484
swift_api.scheme = { :code_coverage => true }
85-
swift_api.platforms = {
86-
:ios => ios_deployment_target,
87-
:osx => osx_deployment_target,
88-
:tvos => tvos_deployment_target
89-
}
85+
86+
# Use recent platform versions to enable async await testing
87+
swift_api.ios.deployment_target = "15.0"
88+
swift_api.osx.deployment_target = "12.0"
89+
swift_api.tvos.deployment_target = "15.0"
9090
swift_api.source_files = 'FirebaseRemoteConfig/Tests/SwiftAPI/*.swift',
9191
'FirebaseRemoteConfig/Tests/FakeUtils/*.[hm]',
9292
'FirebaseRemoteConfig/Tests/FakeUtils/*.swift'
@@ -100,11 +100,11 @@ app update.
100100
# Run Swift API tests and tests requiring console changes on a Fake Console.
101101
s.test_spec 'fake-console-tests' do |fake_console|
102102
fake_console.scheme = { :code_coverage => true }
103-
fake_console.platforms = {
104-
:ios => ios_deployment_target,
105-
:osx => osx_deployment_target,
106-
:tvos => tvos_deployment_target
107-
}
103+
104+
# Use recent platform versions to enable async await testing
105+
fake_console.ios.deployment_target = "15.0"
106+
fake_console.osx.deployment_target = "12.0"
107+
fake_console.tvos.deployment_target = "15.0"
108108
fake_console.source_files = 'FirebaseRemoteConfig/Tests/SwiftAPI/*.swift',
109109
'FirebaseRemoteConfig/Tests/FakeUtils/*.[hm]',
110110
'FirebaseRemoteConfig/Tests/FakeUtils/*.swift',

FirebaseRemoteConfig/Tests/SwiftAPI/APITests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,8 @@ class APITests: APITestBase {
283283
// MARK: - Private Helpers
284284

285285
private func waitForExpectations() {
286-
let kFIRStorageIntegrationTestTimeout = 10.0
287-
waitForExpectations(timeout: kFIRStorageIntegrationTestTimeout,
286+
let kTestTimeout = 10.0
287+
waitForExpectations(timeout: kTestTimeout,
288288
handler: { (error) -> Void in
289289
if let error = error {
290290
print(error)
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import FirebaseCore
16+
@testable import FirebaseRemoteConfig
17+
18+
import XCTest
19+
20+
/// String constants used for testing.
21+
private enum Constants {
22+
static let key1 = "Key1"
23+
static let jedi = "Jedi"
24+
static let sith = "Sith_Lord"
25+
static let value1 = "Value1"
26+
static let obiwan = "Obi-Wan"
27+
static let yoda = "Yoda"
28+
static let darthSidious = "Darth Sidious"
29+
}
30+
31+
class AsyncAwaitTests: APITestBase {
32+
var console: RemoteConfigConsole!
33+
34+
override func setUp() {
35+
super.setUp()
36+
if APITests.useFakeConfig {
37+
fakeConsole.config = [Constants.key1: Constants.value1]
38+
} else {
39+
console = RemoteConfigConsole()
40+
console.updateRemoteConfigValue(Constants.obiwan, forKey: Constants.jedi)
41+
}
42+
}
43+
44+
override func tearDown() {
45+
super.tearDown()
46+
47+
// If using RemoteConfigConsole, reset remote config values.
48+
if !APITests.useFakeConfig {
49+
console.removeRemoteConfigValue(forKey: Constants.sith)
50+
console.removeRemoteConfigValue(forKey: Constants.jedi)
51+
}
52+
}
53+
54+
func testFetchThenActivate() async throws {
55+
let status = try await config.fetch()
56+
XCTAssertEqual(status, RemoteConfigFetchStatus.success)
57+
let success = try await config.activate()
58+
XCTAssertTrue(success)
59+
}
60+
61+
func testFetchWithExpirationThenActivate() async throws {
62+
let status = try await config.fetch(withExpirationDuration: 0)
63+
XCTAssertEqual(status, RemoteConfigFetchStatus.success)
64+
_ = try await config.activate()
65+
XCTAssertEqual(config[Constants.key1].stringValue, Constants.value1)
66+
}
67+
68+
func testFetchAndActivate() async throws {
69+
let status = try await config.fetchAndActivate()
70+
XCTAssertEqual(status, .successFetchedFromRemote)
71+
XCTAssertEqual(config[Constants.key1].stringValue, Constants.value1)
72+
}
73+
74+
// Contrast with testChangedActivateWillNotFlag in FakeConsole.swift.
75+
func testUnchangedActivateWillFlag() async throws {
76+
let status = try await config.fetch()
77+
XCTAssertEqual(status, RemoteConfigFetchStatus.success)
78+
let changed = try await config.activate()
79+
XCTAssertEqual(config[Constants.key1].stringValue, Constants.value1)
80+
XCTAssertTrue(!APITests.useFakeConfig || changed)
81+
XCTAssertEqual(config[Constants.key1].stringValue, Constants.value1)
82+
}
83+
84+
func testFetchAndActivateUnchangedConfig() async throws {
85+
guard APITests.useFakeConfig == false else { return }
86+
87+
XCTAssertEqual(config.settings.minimumFetchInterval, 0)
88+
89+
// Represents pre-fetch occurring sometime in past.
90+
let status = try await config.fetch()
91+
XCTAssertEqual(status, .success)
92+
93+
// Represents a `fetchAndActivate` being made to pull latest changes from Remote Config.
94+
let status2 = try await config.fetchAndActivate()
95+
// Since no updates to remote config have occurred we use the `.successUsingPreFetchedData`.
96+
// The behavior of the next test changed in Firebase 7.0.0.
97+
// It's an open question which is correct, but it should only
98+
// be changed in a major release.
99+
// See https://github.com/firebase/firebase-ios-sdk/pull/8788
100+
// XCTAssertEqual(status, .successUsingPreFetchedData)
101+
XCTAssertEqual(status2, .successFetchedFromRemote)
102+
// The `lastETagUpdateTime` should either be older or the same time as `lastFetchTime`.
103+
if let lastFetchTime = try? XCTUnwrap(config.lastFetchTime) {
104+
XCTAssertLessThanOrEqual(Double(config.settings.lastETagUpdateTime),
105+
Double(lastFetchTime.timeIntervalSince1970))
106+
} else {
107+
XCTFail("Could not unwrap lastFetchTime.")
108+
}
109+
}
110+
111+
// MARK: - RemoteConfigConsole Tests
112+
113+
func testFetchConfigThenUpdateConsoleThenFetchAgain() async throws {
114+
guard APITests.useFakeConfig == false else { return }
115+
116+
_ = try await config.fetchAndActivate()
117+
let configValue = try? XCTUnwrap(config.configValue(forKey: Constants.jedi).stringValue)
118+
XCTAssertEqual(configValue, Constants.obiwan)
119+
120+
// Synchronously update the console.
121+
console.updateRemoteConfigValue(Constants.yoda, forKey: Constants.jedi)
122+
123+
_ = try await config.fetchAndActivate()
124+
let configValue2 = try? XCTUnwrap(config.configValue(forKey: Constants.jedi).stringValue)
125+
XCTAssertEqual(configValue2, Constants.yoda)
126+
}
127+
128+
func testFetchConfigThenAddValueOnConsoleThenFetchAgain() async throws {
129+
guard APITests.useFakeConfig == false else { return }
130+
131+
// Ensure no Sith Lord has been written to Remote Config yet.
132+
_ = try await config.fetchAndActivate()
133+
XCTAssertTrue(config.configValue(forKey: Constants.sith).dataValue.isEmpty)
134+
135+
// Synchronously update the console
136+
console.updateRemoteConfigValue(Constants.darthSidious, forKey: Constants.sith)
137+
138+
// Verify the Sith Lord can now be fetched from Remote Config
139+
_ = try await config.fetchAndActivate()
140+
let configValue = try? XCTUnwrap(config.configValue(forKey: Constants.sith).stringValue)
141+
XCTAssertEqual(configValue, Constants.darthSidious)
142+
}
143+
144+
func testFetchConfigThenDeleteValueOnConsoleThenFetchAgain() async throws {
145+
guard APITests.useFakeConfig == false else { return }
146+
147+
_ = try await config.fetchAndActivate()
148+
let configValue = try? XCTUnwrap(config.configValue(forKey: Constants.jedi).stringValue)
149+
XCTAssertEqual(configValue, Constants.obiwan)
150+
151+
// Synchronously delete value on the console.
152+
console.removeRemoteConfigValue(forKey: Constants.jedi)
153+
154+
_ = try await config.fetchAndActivate()
155+
XCTAssertTrue(config.configValue(forKey: Constants.jedi).dataValue.isEmpty,
156+
"Remote config should have been deleted.")
157+
}
158+
}

0 commit comments

Comments
 (0)