Skip to content

Commit

Permalink
[MBL-897] Feature Flag Use of AI Project Tab (#1841)
Browse files Browse the repository at this point in the history
* Added feature flag with tests

* Update RemoteConfigFeature+HelpersTests.swift

corrections to helper tests

* formatting

* Update Library/RemoteConfig/RemoteConfigFeature+HelpersTests.swift

Co-authored-by: Scott Clampet <110618242+scottkicks@users.noreply.github.com>

* Update Library/RemoteConfig/RemoteConfigFeature+HelpersTests.swift

Co-authored-by: Scott Clampet <110618242+scottkicks@users.noreply.github.com>

* updated snapshot tests

---------

Co-authored-by: Scott Clampet <110618242+scottkicks@users.noreply.github.com>
  • Loading branch information
msadoon and scottkicks committed Aug 2, 2023
1 parent 6266d87 commit 0e82d13
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 315 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
313 changes: 43 additions & 270 deletions KsApi/GraphAPI.swift
Expand Up @@ -578,182 +578,6 @@ public enum GraphAPI {
}
}

/// Autogenerated input type of TriggerCapiEvent
public struct TriggerCapiEventInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap

/// - Parameters:
/// - projectId
/// - eventName
/// - externalId
/// - userEmail
/// - appData
/// - customData
/// - waitForConsent
/// - testEventCode
/// - clientMutationId: A unique identifier for the client performing the mutation.
public init(projectId: GraphQLID, eventName: String, externalId: String, userEmail: Swift.Optional<String?> = nil, appData: Swift.Optional<AppDataInput?> = nil, customData: Swift.Optional<CustomDataInput?> = nil, waitForConsent: Swift.Optional<Bool?> = nil, testEventCode: Swift.Optional<String?> = nil, clientMutationId: Swift.Optional<String?> = nil) {
graphQLMap = ["projectId": projectId, "eventName": eventName, "externalId": externalId, "userEmail": userEmail, "appData": appData, "customData": customData, "waitForConsent": waitForConsent, "testEventCode": testEventCode, "clientMutationId": clientMutationId]
}

public var projectId: GraphQLID {
get {
return graphQLMap["projectId"] as! GraphQLID
}
set {
graphQLMap.updateValue(newValue, forKey: "projectId")
}
}

public var eventName: String {
get {
return graphQLMap["eventName"] as! String
}
set {
graphQLMap.updateValue(newValue, forKey: "eventName")
}
}

public var externalId: String {
get {
return graphQLMap["externalId"] as! String
}
set {
graphQLMap.updateValue(newValue, forKey: "externalId")
}
}

public var userEmail: Swift.Optional<String?> {
get {
return graphQLMap["userEmail"] as? Swift.Optional<String?> ?? Swift.Optional<String?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "userEmail")
}
}

public var appData: Swift.Optional<AppDataInput?> {
get {
return graphQLMap["appData"] as? Swift.Optional<AppDataInput?> ?? Swift.Optional<AppDataInput?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "appData")
}
}

public var customData: Swift.Optional<CustomDataInput?> {
get {
return graphQLMap["customData"] as? Swift.Optional<CustomDataInput?> ?? Swift.Optional<CustomDataInput?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "customData")
}
}

public var waitForConsent: Swift.Optional<Bool?> {
get {
return graphQLMap["waitForConsent"] as? Swift.Optional<Bool?> ?? Swift.Optional<Bool?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "waitForConsent")
}
}

public var testEventCode: Swift.Optional<String?> {
get {
return graphQLMap["testEventCode"] as? Swift.Optional<String?> ?? Swift.Optional<String?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "testEventCode")
}
}

/// A unique identifier for the client performing the mutation.
public var clientMutationId: Swift.Optional<String?> {
get {
return graphQLMap["clientMutationId"] as? Swift.Optional<String?> ?? Swift.Optional<String?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "clientMutationId")
}
}
}

/// Parameters for sharing app data and device information with the Conversions API
public struct AppDataInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap

/// - Parameters:
/// - advertiserTrackingEnabled: Use this field to specify ATT permission on an iOS 14.5+ device.
/// - applicationTrackingEnabled: A person can choose to enable ad tracking on an app level. Your SDK should allow an app developer to put an opt-out setting into their app. Use this field to specify the person's choice.
/// - extinfo: Extended device information, such as screen width and height. Required only for native.
public init(advertiserTrackingEnabled: Bool, applicationTrackingEnabled: Bool, extinfo: [String]) {
graphQLMap = ["advertiserTrackingEnabled": advertiserTrackingEnabled, "applicationTrackingEnabled": applicationTrackingEnabled, "extinfo": extinfo]
}

/// Use this field to specify ATT permission on an iOS 14.5+ device.
public var advertiserTrackingEnabled: Bool {
get {
return graphQLMap["advertiserTrackingEnabled"] as! Bool
}
set {
graphQLMap.updateValue(newValue, forKey: "advertiserTrackingEnabled")
}
}

/// A person can choose to enable ad tracking on an app level. Your SDK should allow an app developer to put an opt-out setting into their app. Use this field to specify the person's choice.
public var applicationTrackingEnabled: Bool {
get {
return graphQLMap["applicationTrackingEnabled"] as! Bool
}
set {
graphQLMap.updateValue(newValue, forKey: "applicationTrackingEnabled")
}
}

/// Extended device information, such as screen width and height. Required only for native.
public var extinfo: [String] {
get {
return graphQLMap["extinfo"] as! [String]
}
set {
graphQLMap.updateValue(newValue, forKey: "extinfo")
}
}
}

/// A map that includes additional business data about the CAPI event.
public struct CustomDataInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap

/// - Parameters:
/// - currency: The currency for the value specified, if applicable. Currency must be a valid ISO 4217 three-digit currency code.
/// - value: A numeric value associated with this event. This could be a monetary value or a value in some other metric.
public init(currency: Swift.Optional<String?> = nil, value: Swift.Optional<String?> = nil) {
graphQLMap = ["currency": currency, "value": value]
}

/// The currency for the value specified, if applicable. Currency must be a valid ISO 4217 three-digit currency code.
public var currency: Swift.Optional<String?> {
get {
return graphQLMap["currency"] as? Swift.Optional<String?> ?? Swift.Optional<String?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "currency")
}
}

/// A numeric value associated with this event. This could be a monetary value or a value in some other metric.
public var value: Swift.Optional<String?> {
get {
return graphQLMap["value"] as? Swift.Optional<String?> ?? Swift.Optional<String?>.none
}
set {
graphQLMap.updateValue(newValue, forKey: "value")
}
}
}

/// Autogenerated input type of TriggerThirdPartyEvent
public struct TriggerThirdPartyEventInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap
Expand Down Expand Up @@ -927,6 +751,49 @@ public enum GraphAPI {
}
}

/// Parameters for sharing app data and device information with the Conversions API
public struct AppDataInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap

/// - Parameters:
/// - advertiserTrackingEnabled: Use this field to specify ATT permission on an iOS 14.5+ device.
/// - applicationTrackingEnabled: A person can choose to enable ad tracking on an app level. Your SDK should allow an app developer to put an opt-out setting into their app. Use this field to specify the person's choice.
/// - extinfo: Extended device information, such as screen width and height. Required only for native.
public init(advertiserTrackingEnabled: Bool, applicationTrackingEnabled: Bool, extinfo: [String]) {
graphQLMap = ["advertiserTrackingEnabled": advertiserTrackingEnabled, "applicationTrackingEnabled": applicationTrackingEnabled, "extinfo": extinfo]
}

/// Use this field to specify ATT permission on an iOS 14.5+ device.
public var advertiserTrackingEnabled: Bool {
get {
return graphQLMap["advertiserTrackingEnabled"] as! Bool
}
set {
graphQLMap.updateValue(newValue, forKey: "advertiserTrackingEnabled")
}
}

/// A person can choose to enable ad tracking on an app level. Your SDK should allow an app developer to put an opt-out setting into their app. Use this field to specify the person's choice.
public var applicationTrackingEnabled: Bool {
get {
return graphQLMap["applicationTrackingEnabled"] as! Bool
}
set {
graphQLMap.updateValue(newValue, forKey: "applicationTrackingEnabled")
}
}

/// Extended device information, such as screen width and height. Required only for native.
public var extinfo: [String] {
get {
return graphQLMap["extinfo"] as! [String]
}
set {
graphQLMap.updateValue(newValue, forKey: "extinfo")
}
}
}

/// Autogenerated input type of UnwatchProject
public struct UnwatchProjectInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap
Expand Down Expand Up @@ -4539,100 +4406,6 @@ public enum GraphAPI {
}
}

public final class TriggerCapiEventMutation: GraphQLMutation {
/// The raw GraphQL definition of this operation.
public let operationDefinition: String =
"""
mutation triggerCAPIEvent($input: TriggerCapiEventInput!) {
triggerCAPIEvent(input: $input) {
__typename
success
}
}
"""

public let operationName: String = "triggerCAPIEvent"

public var input: TriggerCapiEventInput

public init(input: TriggerCapiEventInput) {
self.input = input
}

public var variables: GraphQLMap? {
return ["input": input]
}

public struct Data: GraphQLSelectionSet {
public static let possibleTypes: [String] = ["Mutation"]

public static var selections: [GraphQLSelection] {
return [
GraphQLField("triggerCAPIEvent", arguments: ["input": GraphQLVariable("input")], type: .object(TriggerCapiEvent.selections)),
]
}

public private(set) var resultMap: ResultMap

public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}

public init(triggerCapiEvent: TriggerCapiEvent? = nil) {
self.init(unsafeResultMap: ["__typename": "Mutation", "triggerCAPIEvent": triggerCapiEvent.flatMap { (value: TriggerCapiEvent) -> ResultMap in value.resultMap }])
}

/// Triggers Meta's CAPI event for native
public var triggerCapiEvent: TriggerCapiEvent? {
get {
return (resultMap["triggerCAPIEvent"] as? ResultMap).flatMap { TriggerCapiEvent(unsafeResultMap: $0) }
}
set {
resultMap.updateValue(newValue?.resultMap, forKey: "triggerCAPIEvent")
}
}

public struct TriggerCapiEvent: GraphQLSelectionSet {
public static let possibleTypes: [String] = ["TriggerCapiEventPayload"]

public static var selections: [GraphQLSelection] {
return [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLField("success", type: .nonNull(.scalar(Bool.self))),
]
}

public private(set) var resultMap: ResultMap

public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}

public init(success: Bool) {
self.init(unsafeResultMap: ["__typename": "TriggerCapiEventPayload", "success": success])
}

public var __typename: String {
get {
return resultMap["__typename"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "__typename")
}
}

public var success: Bool {
get {
return resultMap["success"]! as! Bool
}
set {
resultMap.updateValue(newValue, forKey: "success")
}
}
}
}
}

public final class TriggerThirdPartyEventMutation: GraphQLMutation {
/// The raw GraphQL definition of this operation.
public let operationDefinition: String =
Expand Down
7 changes: 7 additions & 0 deletions Library/RemoteConfig/RemoteConfigFeature+Helpers.swift
Expand Up @@ -20,3 +20,10 @@ public func featureFacebookLoginInterstitialEnabled() -> Bool {
(AppEnvironment.current.remoteConfigClient?
.isFeatureEnabled(featureKey: RemoteConfigFeature.facebookLoginInterstitialEnabled) ?? false)
}

public func featureUseOfAIProjectTabEnabled() -> Bool {
return AppEnvironment.current.userDefaults
.remoteConfigFeatureFlags[RemoteConfigFeature.useOfAIProjectTab.rawValue] ??
(AppEnvironment.current.remoteConfigClient?
.isFeatureEnabled(featureKey: RemoteConfigFeature.useOfAIProjectTab) ?? false)
}
27 changes: 27 additions & 0 deletions Library/RemoteConfig/RemoteConfigFeature+HelpersTests.swift
Expand Up @@ -39,6 +39,15 @@ final class RemoteConfigFeatureHelpersTests: TestCase {
}
}

func testCreatorDashboard_RemoteConfig_FeatureFlag_True() {
let mockRemoteConfigClient = MockRemoteConfigClient()
|> \.features .~ [RemoteConfigFeature.creatorDashboardEnabled.rawValue: true]

withEnvironment(remoteConfigClient: mockRemoteConfigClient) {
XCTAssertTrue(featureCreatorDashboardEnabled())
}
}

func testCreatorDashboard_RemoteConfig_FeatureFlag_False() {
let mockRemoteConfigClient = MockRemoteConfigClient()
|> \.features .~ [RemoteConfigFeature.creatorDashboardEnabled.rawValue: false]
Expand All @@ -47,4 +56,22 @@ final class RemoteConfigFeatureHelpersTests: TestCase {
XCTAssertFalse(featureCreatorDashboardEnabled())
}
}

func testUseOfAIProjectTab_RemoteConfig_FeatureFlag_False() {
let mockRemoteConfigClient = MockRemoteConfigClient()
|> \.features .~ [RemoteConfigFeature.useOfAIProjectTab.rawValue: false]

withEnvironment(remoteConfigClient: mockRemoteConfigClient) {
XCTAssertFalse(featureUseOfAIProjectTabEnabled())
}
}

func testUseOfAIProjectTab_RemoteConfig_FeatureFlag_True() {
let mockRemoteConfigClient = MockRemoteConfigClient()
|> \.features .~ [RemoteConfigFeature.useOfAIProjectTab.rawValue: true]

withEnvironment(remoteConfigClient: mockRemoteConfigClient) {
XCTAssertTrue(featureUseOfAIProjectTabEnabled())
}
}
}
2 changes: 2 additions & 0 deletions Library/RemoteConfig/RemoteConfigFeature.swift
Expand Up @@ -4,6 +4,7 @@ public enum RemoteConfigFeature: String, CaseIterable {
case consentManagementDialogEnabled = "consent_management_dialog"
case creatorDashboardEnabled = "creator_dashboard"
case facebookLoginInterstitialEnabled = "facebook_interstitial"
case useOfAIProjectTab = "use_of_ai_project_tab"
}

extension RemoteConfigFeature: CustomStringConvertible {
Expand All @@ -12,6 +13,7 @@ extension RemoteConfigFeature: CustomStringConvertible {
case .consentManagementDialogEnabled: return "Consent Management Dialog"
case .creatorDashboardEnabled: return "Creator Dashboard"
case .facebookLoginInterstitialEnabled: return "Facebook Login Interstitial"
case .useOfAIProjectTab: return "Use of AI Project Tab"
}
}
}

0 comments on commit 0e82d13

Please sign in to comment.