Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MBL-897] Feature Flag Use of AI Project Tab #1841

Merged
merged 8 commits into from
Aug 2, 2023
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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())
}
}
Comment on lines +42 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice add


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
Original file line number Diff line number Diff line change
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"
}
}
}