Skip to content

Commit

Permalink
Persist Debug Feature Flags (#721)
Browse files Browse the repository at this point in the history
* Persiting debug data

* Tests

* Adding some more assertions

* Formatting

* PR comments

* Switching DebugData to Library
  • Loading branch information
Isabel Barrera authored and justinswart committed Aug 5, 2019
1 parent 0061f57 commit dd8fd1c
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ final class FeatureFlagToolsViewController: UITableViewController {

let updatedConfig = config |> \.features .~ features

AppEnvironment.updateDebugData(DebugData(config: updatedConfig))
AppEnvironment.updateConfig(updatedConfig)

self.viewModel.inputs.didUpdateConfig()
Expand Down
12 changes: 7 additions & 5 deletions Kickstarter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
776B6F70215183A400AB0652 /* ChangeEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 776B6F6F215183A400AB0652 /* ChangeEmailViewController.swift */; };
77752F5E219B39EA00E7DA7D /* SettingsAccountWarningCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77752F5D219B39EA00E7DA7D /* SettingsAccountWarningCell.swift */; };
77752F97219B3D7300E7DA7D /* SettingsAccountWarningCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 77752F96219B3D7300E7DA7D /* SettingsAccountWarningCell.xib */; };
777B88E522BD911F0027640F /* CategoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6FB2A3C1FA27D0300B0D282 /* CategoryTests.swift */; };
777C67BB220A0FA5009F8D42 /* SettingsTableViewHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 777C67BA220A0FA5009F8D42 /* SettingsTableViewHeader.swift */; };
777C67F4220A22FD009F8D42 /* SettingsTableViewHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 777C67F3220A22FD009F8D42 /* SettingsTableViewHeader.xib */; };
778215E820F6922100F3D09F /* HelpType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A707BAD31CFFAB9400653B2F /* HelpType.swift */; };
Expand Down Expand Up @@ -224,6 +225,7 @@
77C5E21A214182A2002E1670 /* SettingsPrivacySwitchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 77C5E219214182A2002E1670 /* SettingsPrivacySwitchCell.xib */; };
77C5E252214182CA002E1670 /* SettingsPrivacySwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77C5E251214182CA002E1670 /* SettingsPrivacySwitchCell.swift */; };
77C7B654226E0E54001101AC /* RewardsCollectionViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77C7B653226E0E54001101AC /* RewardsCollectionViewModelTests.swift */; };
77C93C2522C27443005D3195 /* DebugData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 775D922822BD7CFD00442301 /* DebugData.swift */; };
77CD894921791B05003066DA /* ProjectStatsTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77CD894821791B05003066DA /* ProjectStatsTemplate.swift */; };
77CD8981217FA01B003066DA /* ProjectPamphletContentViewControllerConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77CD8980217FA01B003066DA /* ProjectPamphletContentViewControllerConversionTests.swift */; };
77D7A739214187A9003F258C /* SettingsSwitchCellType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D7A738214187A9003F258C /* SettingsSwitchCellType.swift */; };
Expand Down Expand Up @@ -652,7 +654,6 @@
A7FA38A41D9068940041FC9C /* PledgeTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FA38A31D9068940041FC9C /* PledgeTitleCell.swift */; };
A7FA38D91D9068AD0041FC9C /* RewardsTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FA38D81D9068AD0041FC9C /* RewardsTitleCell.swift */; };
A7FC8C061C8F1DEA00C3B49B /* CircleAvatarImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FC8C051C8F1DEA00C3B49B /* CircleAvatarImageView.swift */; };
D002CADF218CF8B7009783F2 /* CategoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01587801EEB2ED6006E7684 /* CategoryTests.swift */; };
D002CAE1218CF8F1009783F2 /* WatchProjectMutation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D002CAE0218CF8F1009783F2 /* WatchProjectMutation.swift */; };
D002CAE3218CF91D009783F2 /* WatchProjectInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = D002CAE2218CF91D009783F2 /* WatchProjectInput.swift */; };
D002CAE5218CF951009783F2 /* GraphMutationWatchProjectResponseEnvelope.swift in Sources */ = {isa = PBXBuildFile; fileRef = D002CAE4218CF951009783F2 /* GraphMutationWatchProjectResponseEnvelope.swift */; };
Expand Down Expand Up @@ -1463,6 +1464,7 @@
77556F5520A0B408008CEA57 /* ThanksViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThanksViewControllerTests.swift; sourceTree = "<group>"; };
7758A83120979BE50018B96D /* DiscoveryProjectCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryProjectCategoryView.swift; sourceTree = "<group>"; };
7758A8352097A8180018B96D /* DiscoveryProjectCategoryView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DiscoveryProjectCategoryView.xib; sourceTree = "<group>"; };
775D922822BD7CFD00442301 /* DebugData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugData.swift; sourceTree = "<group>"; };
775DFA9C215E758400620CED /* GraphMutation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphMutation.swift; sourceTree = "<group>"; };
775DFAD4215EB2AB00620CED /* Service+RequestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Service+RequestHelpers.swift"; sourceTree = "<group>"; };
776B6F6F215183A400AB0652 /* ChangeEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeEmailViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1958,7 +1960,6 @@
D015877B1EEB2ED6006E7684 /* ActivityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityTests.swift; sourceTree = "<group>"; };
D015877C1EEB2ED6006E7684 /* Backing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Backing.swift; sourceTree = "<group>"; };
D015877D1EEB2ED6006E7684 /* BackingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackingTests.swift; sourceTree = "<group>"; };
D01587801EEB2ED6006E7684 /* CategoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CategoryTests.swift; sourceTree = "<group>"; };
D01587811EEB2ED6006E7684 /* ChangePaymentMethodEnvelope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangePaymentMethodEnvelope.swift; sourceTree = "<group>"; };
D01587821EEB2ED6006E7684 /* ChangePaymentMethodEnvelopeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangePaymentMethodEnvelopeTests.swift; sourceTree = "<group>"; };
D01587831EEB2ED6006E7684 /* CheckoutEnvelope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckoutEnvelope.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2891,6 +2892,7 @@
3706408C22A9BE8100889CBD /* DateFormatter.swift */,
3706408F22A9BE9400889CBD /* DateFormatterTests.swift */,
A7F6F0C01DC7EBF7002C118C /* DateProtocol.swift */,
775D922822BD7CFD00442301 /* DebugData.swift */,
77F6E73421222E7C005A5C55 /* EmailFrequency.swift */,
A7C7257F1C85D36D005A016B /* Environment.swift */,
A7ED1F141E830FDC00BFFA01 /* EnvironmentTests.swift */,
Expand Down Expand Up @@ -3516,8 +3518,8 @@
D015877C1EEB2ED6006E7684 /* Backing.swift */,
D015877D1EEB2ED6006E7684 /* BackingTests.swift */,
D6B9DF3E1F72E25A0064A4D8 /* Category.swift */,
D6FB2A3C1FA27D0300B0D282 /* CategoryTests.swift */,
D6AE52271FD1B4BA00BEC788 /* CategoryEnvelope.swift */,
D01587801EEB2ED6006E7684 /* CategoryTests.swift */,
D01587811EEB2ED6006E7684 /* ChangePaymentMethodEnvelope.swift */,
D01587821EEB2ED6006E7684 /* ChangePaymentMethodEnvelopeTests.swift */,
D01587831EEB2ED6006E7684 /* CheckoutEnvelope.swift */,
Expand Down Expand Up @@ -3607,7 +3609,6 @@
D01588251EEB2ED7006E7684 /* VoidEnvelope.swift */,
D01587971EEB2ED6006E7684 /* lenses */,
D01587EE1EEB2ED7006E7684 /* templates */,
D6FB2A3C1FA27D0300B0D282 /* CategoryTests.swift */,
);
path = models;
sourceTree = "<group>";
Expand Down Expand Up @@ -4312,6 +4313,7 @@
A755115B1C8642C3005355CF /* AppEnvironment.swift in Sources */,
A7F441AD1D005A9400FE6FC5 /* ActivitiesViewModel.swift in Sources */,
A75A9DBF1D6F3A3000603D1D /* RewardShippingPickerViewModel.swift in Sources */,
77C93C2522C27443005D3195 /* DebugData.swift in Sources */,
D7A37D7A1E367E5A00EA066D /* MostPopularSearchProjectCellViewModel.swift in Sources */,
A73379111D0E33A600C91445 /* ButtonStyles.swift in Sources */,
A73378FB1D0AE33B00C91445 /* BaseStyles.swift in Sources */,
Expand Down Expand Up @@ -5264,7 +5266,6 @@
D0D10C101EEB4550005EBAD0 /* MessageTests.swift in Sources */,
D0D10C151EEB4550005EBAD0 /* ProjectStatsEnvelopeTests.swift in Sources */,
D0D10C221EEB4550005EBAD0 /* UserTests.swift in Sources */,
D002CADF218CF8B7009783F2 /* CategoryTests.swift in Sources */,
D0D10C171EEB4550005EBAD0 /* PushEnvelopeTests.swift in Sources */,
D0D10C1D1EEB4550005EBAD0 /* UpdatePledgeEnvelopeTests.swift in Sources */,
D0D10C0E1EEB4550005EBAD0 /* ItemTests.swift in Sources */,
Expand All @@ -5276,6 +5277,7 @@
D0D10C111EEB4550005EBAD0 /* MessageThreadTests.swift in Sources */,
D0D10C161EEB4550005EBAD0 /* ProjectTests.swift in Sources */,
D0D10C1A1EEB4550005EBAD0 /* SubmitApplePayEnvelopeTests.swift in Sources */,
777B88E522BD911F0027640F /* CategoryTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
18 changes: 15 additions & 3 deletions Library/AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ public struct AppEnvironment: AppEnvironmentType {
)
}

public static func updateDebugData(_ debugData: DebugData) {
self.replaceCurrentEnvironment(
debugData: debugData
)
}

public static func updateServerConfig(_ config: ServerConfigType) {
let service = Service(serverConfig: config)

Expand All @@ -54,10 +60,12 @@ public struct AppEnvironment: AppEnvironmentType {
}

public static func updateConfig(_ config: Config) {
let debugConfigOrConfig = self.current.debugData?.config ?? config

self.replaceCurrentEnvironment(
config: config,
countryCode: config.countryCode,
koala: AppEnvironment.current.koala |> Koala.lens.config .~ config
config: debugConfigOrConfig,
countryCode: debugConfigOrConfig.countryCode,
koala: AppEnvironment.current.koala |> Koala.lens.config .~ debugConfigOrConfig
)
}

Expand Down Expand Up @@ -124,6 +132,7 @@ public struct AppEnvironment: AppEnvironmentType {
currentUser: User? = AppEnvironment.current.currentUser,
dateType: DateProtocol.Type = AppEnvironment.current.dateType,
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
debugData: DebugData? = AppEnvironment.current.debugData,
device: UIDeviceType = AppEnvironment.current.device,
is1PasswordSupported: @escaping (() -> Bool) = AppEnvironment.current.is1PasswordSupported,
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
Expand Down Expand Up @@ -152,6 +161,7 @@ public struct AppEnvironment: AppEnvironmentType {
currentUser: currentUser,
dateType: dateType,
debounceInterval: debounceInterval,
debugData: debugData,
device: device,
is1PasswordSupported: is1PasswordSupported,
isVoiceOverRunning: isVoiceOverRunning,
Expand Down Expand Up @@ -184,6 +194,7 @@ public struct AppEnvironment: AppEnvironmentType {
currentUser: User? = AppEnvironment.current.currentUser,
dateType: DateProtocol.Type = AppEnvironment.current.dateType,
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
debugData: DebugData? = AppEnvironment.current.debugData,
device: UIDeviceType = AppEnvironment.current.device,
is1PasswordSupported: @escaping (() -> Bool) = AppEnvironment.current.is1PasswordSupported,
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
Expand Down Expand Up @@ -212,6 +223,7 @@ public struct AppEnvironment: AppEnvironmentType {
currentUser: currentUser,
dateType: dateType,
debounceInterval: debounceInterval,
debugData: debugData,
device: device,
is1PasswordSupported: is1PasswordSupported,
isVoiceOverRunning: isVoiceOverRunning,
Expand Down
122 changes: 122 additions & 0 deletions Library/AppEnvironmentTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
@testable import KsApi
@testable import Library
import Prelude
import XCTest

final class AppEnvironmentTests: XCTestCase {
Expand Down Expand Up @@ -204,6 +205,7 @@ final class AppEnvironmentTests: XCTestCase {
ServerConfig.production.webBaseUrl.absoluteString,
env.apiService.serverConfig.webBaseUrl.absoluteString
)
XCTAssertEqual(EnvironmentType.production, env.apiService.serverConfig.environment)
XCTAssertEqual(currentUser, env.currentUser)
XCTAssertEqual(currentUser, env.koala.loggedInUser)
}
Expand Down Expand Up @@ -232,4 +234,124 @@ final class AppEnvironmentTests: XCTestCase {

AppEnvironment.popEnvironment()
}

func testUpdateServerConfig() {
AppEnvironment.pushEnvironment()

// Starts out as production environment
XCTAssertEqual(AppEnvironment.current.apiService.serverConfig.environment, .production)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.apiBaseUrl,
ServerConfig.production.apiBaseUrl
)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.webBaseUrl,
ServerConfig.production.webBaseUrl
)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.apiClientAuth.clientId,
ClientAuth.production.clientId
)
XCTAssertNil(AppEnvironment.current.apiService.serverConfig.basicHTTPAuth)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.graphQLEndpointUrl,
ServerConfig.production.graphQLEndpointUrl
)

let serverConfig = ServerConfig.staging

AppEnvironment.updateServerConfig(serverConfig)

// Updates all properties to staging environment
XCTAssertEqual(AppEnvironment.current.apiService.serverConfig.environment, .staging)
XCTAssertEqual(AppEnvironment.current.apiService.serverConfig.apiBaseUrl, ServerConfig.staging.apiBaseUrl)
XCTAssertEqual(AppEnvironment.current.apiService.serverConfig.webBaseUrl, ServerConfig.staging.webBaseUrl)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.apiClientAuth.clientId,
ClientAuth.development.clientId
)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.basicHTTPAuth?.username,
BasicHTTPAuth.development.username
)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.basicHTTPAuth?.password,
BasicHTTPAuth.development.password
)
XCTAssertEqual(
AppEnvironment.current.apiService.serverConfig.graphQLEndpointUrl,
ServerConfig.staging.graphQLEndpointUrl
)

AppEnvironment.popEnvironment()
}

func testUpdateDebugData() {
AppEnvironment.pushEnvironment()

XCTAssertNil(AppEnvironment.current.debugData)

let debugConfig = Config.template
|> \.features .~ ["hello": true]

AppEnvironment.updateDebugData(DebugData(config: debugConfig))

XCTAssertEqual(AppEnvironment.current.debugData?.config, debugConfig)

AppEnvironment.popEnvironment()
}

func testUpdateConfig_nilDebugData() {
AppEnvironment.pushEnvironment()

XCTAssertNil(AppEnvironment.current.debugData)
XCTAssertNil(AppEnvironment.current.config)
XCTAssertEqual(AppEnvironment.current.countryCode, "US")

let config = Config.template
|> \.countryCode .~ "CA"
|> \.features .~ ["hello": true]

AppEnvironment.updateConfig(config)

XCTAssertEqual(AppEnvironment.current.config, config)
XCTAssertEqual(AppEnvironment.current.countryCode, "CA")

AppEnvironment.popEnvironment()
}

func testUpdateConfig_nonNilDebugData() {
AppEnvironment.pushEnvironment()

XCTAssertNil(AppEnvironment.current.debugData)
XCTAssertNil(AppEnvironment.current.config)
XCTAssertEqual(AppEnvironment.current.countryCode, "US")

let debugConfig = Config.template
|> \.countryCode .~ "CA"
|> \.features .~ ["hello": true]

AppEnvironment.pushEnvironment(debugData: DebugData(config: debugConfig))

XCTAssertNotNil(AppEnvironment.current.debugData)

AppEnvironment.updateConfig(Config.template)

XCTAssertEqual(AppEnvironment.current.config, debugConfig)
XCTAssertEqual(AppEnvironment.current.countryCode, "CA")

AppEnvironment.popEnvironment()
}

func testUpdateLanguage() {
AppEnvironment.pushEnvironment()

XCTAssertEqual(AppEnvironment.current.language, .en)

AppEnvironment.updateLanguage(.fr)

XCTAssertEqual(AppEnvironment.current.language, .fr)

AppEnvironment.popEnvironment()
}
}
10 changes: 10 additions & 0 deletions Library/DebugData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Foundation
import KsApi

public struct DebugData {
public let config: Config?

public init(config: Config?) {
self.config = config
}
}
5 changes: 5 additions & 0 deletions Library/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public struct Environment {
/// The amount of time to debounce signals by. Default value is `0.3`.
public let debounceInterval: DispatchTimeInterval

/// Stored data used for debugging tools
public let debugData: DebugData?

/// The current device running the app.
public let device: UIDeviceType

Expand Down Expand Up @@ -106,6 +109,7 @@ public struct Environment {
currentUser: User? = nil,
dateType: DateProtocol.Type = Date.self,
debounceInterval: DispatchTimeInterval = .milliseconds(300),
debugData: DebugData? = nil,
device: UIDeviceType = UIDevice.current,
environmentVariables: EnvironmentVariables = EnvironmentVariables(),
is1PasswordSupported: @escaping () -> Bool = { ksr_is1PasswordSupported() },
Expand Down Expand Up @@ -133,6 +137,7 @@ public struct Environment {
self.currentUser = currentUser
self.dateType = dateType
self.debounceInterval = debounceInterval
self.debugData = debugData
self.device = device
self.environmentVariables = environmentVariables
self.is1PasswordSupported = is1PasswordSupported
Expand Down

0 comments on commit dd8fd1c

Please sign in to comment.