Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.usercentrics.reactnative.extensions

import com.facebook.react.bridge.ReadableMap
import com.usercentrics.sdk.BannerInitCustomization
import com.usercentrics.sdk.PurposeListStyle

internal fun ReadableMap.bannerInitCustomizationFromMap(): BannerInitCustomization {
return BannerInitCustomization(
paddingTop = getIntOrNull("paddingTop"),
paddingBottom = getIntOrNull("paddingBottom"),
paddingStart = getIntOrNull("paddingStart"),
paddingEnd = getIntOrNull("paddingEnd"),
lineSpacingMultiplier = getFloatOrNull("lineSpacingMultiplier"),
titleFontSize = getIntOrNull("titleFontSize"),
bodyFontSize = getIntOrNull("bodyFontSize"),
linkFontSize = getIntOrNull("linkFontSize"),
titleFontBold = getBooleanOrNull("titleFontBold"),
headerPaddingTop = getIntOrNull("headerPaddingTop"),
headerPaddingSides = getIntOrNull("headerPaddingSides"),
headerPaddingBetweenElements = getIntOrNull("headerPaddingBetweenElements"),
buttonBorderColor = getString("buttonBorderColor"),
buttonBorderWidth = getIntOrNull("buttonBorderWidth"),
purposeListStyle = getString("purposeListStyle")?.purposeListStyleFromEnumString(),
stickyHeader = getBooleanOrNull("stickyHeader"),
hideLanguageSwitcher = getBooleanOrNull("hideLanguageSwitcher"),
buttonHeightDp = getIntOrNull("buttonHeightDp"),
buttonHorizontalPaddingDp = getIntOrNull("buttonHorizontalPaddingDp"),
buttonSpacingDp = getIntOrNull("buttonSpacingDp"),
linkUnderline = getBooleanOrNull("linkUnderline"),
showSecondLayerCloseButton = getBooleanOrNull("showSecondLayerCloseButton"),
tabFontSize = getIntOrNull("tabFontSize"),
tabActiveColor = getString("tabActiveColor"),
denyAllButtonBackground = getString("denyAllButtonBackground"),
acceptAllButtonBackground = getString("acceptAllButtonBackground"),
linkColor = getString("linkColor"),
)
}

internal fun String.purposeListStyleFromEnumString(): PurposeListStyle? {
return when (this) {
"BOXED" -> PurposeListStyle.BOXED
"FLAT" -> PurposeListStyle.FLAT
else -> null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal fun ReadableMap.bannerSettingsFromMap(context: Context): BannerSettings
secondLayerStyleSettings = rawSecondLayerStyleSettings?.secondLayerStyleSettingsFromMap(context),
generalStyleSettings = rawGeneralStyleSettings?.generalStyleSettingsFromMap(context),
variantName = getString("variantName"),
initCustomization = getMap("initCustomization")?.bannerInitCustomizationFromMap(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ internal fun ReadableMap.getBooleanOrNull(key: String): Boolean? {
}
}

internal fun ReadableMap.getFloatOrNull(key: String): Float? {
return getDoubleOrNull(key)?.toFloat()
}

internal fun List<*>.serialize(): WritableArray {
val array = Arguments.createArray()
forEach { value ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,9 @@ internal fun ReadableMap.usercentricsOptionsFromMap(): UsercentricsOptions {
options.initTimeoutMillis = it.toLong()
}

getMap("bannerCustomization")?.let {
options.bannerCustomization = it.bannerInitCustomizationFromMap()
}

return options
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.usercentrics.reactnative.extensions

import com.facebook.react.bridge.JavaOnlyMap
import com.usercentrics.sdk.PurposeListStyle
import org.junit.Assert.*
import org.junit.Test

class BannerInitCustomizationExtensionsTest {

@Test
fun `bannerInitCustomizationFromMap maps all fields`() {
val map = JavaOnlyMap().apply {
putInt("paddingTop", 16)
putInt("paddingBottom", 16)
putInt("paddingStart", 8)
putInt("paddingEnd", 8)
putDouble("lineSpacingMultiplier", 1.2)
putInt("titleFontSize", 18)
putInt("bodyFontSize", 14)
putInt("linkFontSize", 14)
putBoolean("titleFontBold", true)
putInt("headerPaddingTop", 12)
putInt("headerPaddingSides", 12)
putInt("headerPaddingBetweenElements", 4)
putString("buttonBorderColor", "#004dcf")
putInt("buttonBorderWidth", 1)
putString("purposeListStyle", "FLAT")
putBoolean("stickyHeader", true)
putBoolean("hideLanguageSwitcher", false)
putInt("buttonHeightDp", 48)
putInt("buttonHorizontalPaddingDp", 16)
putInt("buttonSpacingDp", 8)
putBoolean("linkUnderline", true)
putBoolean("showSecondLayerCloseButton", true)
putInt("tabFontSize", 14)
putString("tabActiveColor", "#004dcf")
putString("denyAllButtonBackground", "#ffffff")
putString("acceptAllButtonBackground", "#004dcf")
putString("linkColor", "#004dcf")
}

val customization = map.bannerInitCustomizationFromMap()

assertEquals(16, customization.paddingTop)
assertEquals(16, customization.paddingBottom)
assertEquals(8, customization.paddingStart)
assertEquals(8, customization.paddingEnd)
assertEquals(1.2f, customization.lineSpacingMultiplier)
assertEquals(18, customization.titleFontSize)
assertEquals(14, customization.bodyFontSize)
assertEquals(14, customization.linkFontSize)
assertEquals(true, customization.titleFontBold)
assertEquals(12, customization.headerPaddingTop)
assertEquals(12, customization.headerPaddingSides)
assertEquals(4, customization.headerPaddingBetweenElements)
assertEquals("#004dcf", customization.buttonBorderColor)
assertEquals(1, customization.buttonBorderWidth)
assertEquals(PurposeListStyle.FLAT, customization.purposeListStyle)
assertEquals(true, customization.stickyHeader)
assertEquals(false, customization.hideLanguageSwitcher)
assertEquals(48, customization.buttonHeightDp)
assertEquals(16, customization.buttonHorizontalPaddingDp)
assertEquals(8, customization.buttonSpacingDp)
assertEquals(true, customization.linkUnderline)
assertEquals(true, customization.showSecondLayerCloseButton)
assertEquals(14, customization.tabFontSize)
assertEquals("#004dcf", customization.tabActiveColor)
assertEquals("#ffffff", customization.denyAllButtonBackground)
assertEquals("#004dcf", customization.acceptAllButtonBackground)
assertEquals("#004dcf", customization.linkColor)
}

@Test
fun `bannerInitCustomizationFromMap omits unset fields instead of defaulting`() {
val map = JavaOnlyMap()

val customization = map.bannerInitCustomizationFromMap()

assertNull(customization.paddingTop)
assertNull(customization.buttonBorderColor)
assertNull(customization.purposeListStyle)
assertNull(customization.stickyHeader)
}

@Test
fun `purposeListStyleFromEnumString maps known values and returns null otherwise`() {
assertEquals(PurposeListStyle.BOXED, "BOXED".purposeListStyleFromEnumString())
assertEquals(PurposeListStyle.FLAT, "FLAT".purposeListStyleFromEnumString())
assertNull("UNKNOWN".purposeListStyleFromEnumString())
}

@Test
fun `usercentricsOptionsFromMap maps nested bannerCustomization`() {
val map = JavaOnlyMap().apply {
putString("settingsId", "123")
putMap("bannerCustomization", JavaOnlyMap().apply {
putInt("paddingTop", 16)
putString("purposeListStyle", "FLAT")
})
}

val options = map.usercentricsOptionsFromMap()

assertEquals(16, options.bannerCustomization?.paddingTop)
assertEquals(PurposeListStyle.FLAT, options.bannerCustomization?.purposeListStyle)
}
}
53 changes: 53 additions & 0 deletions ios/Extensions/BannerInitCustomization+Dict.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Foundation
import Usercentrics

extension BannerInitCustomization {
convenience init?(from dictionary: NSDictionary?) {
guard let dictionary = dictionary else { return nil }

self.init(
paddingTop: (dictionary["paddingTop"] as? Int32).map { KotlinInt(value: $0) },
paddingBottom: (dictionary["paddingBottom"] as? Int32).map { KotlinInt(value: $0) },
Comment thread
uc-brunosilva marked this conversation as resolved.
paddingStart: (dictionary["paddingStart"] as? Int32).map { KotlinInt(value: $0) },
paddingEnd: (dictionary["paddingEnd"] as? Int32).map { KotlinInt(value: $0) },
lineSpacingMultiplier: (dictionary["lineSpacingMultiplier"] as? Double).map { KotlinFloat(value: Float($0)) },
titleFontSize: (dictionary["titleFontSize"] as? Int32).map { KotlinInt(value: $0) },
bodyFontSize: (dictionary["bodyFontSize"] as? Int32).map { KotlinInt(value: $0) },
linkFontSize: (dictionary["linkFontSize"] as? Int32).map { KotlinInt(value: $0) },
titleFontBold: (dictionary["titleFontBold"] as? Bool).map { KotlinBoolean(value: $0) },
headerPaddingTop: (dictionary["headerPaddingTop"] as? Int32).map { KotlinInt(value: $0) },
headerPaddingSides: (dictionary["headerPaddingSides"] as? Int32).map { KotlinInt(value: $0) },
headerPaddingBetweenElements: (dictionary["headerPaddingBetweenElements"] as? Int32).map { KotlinInt(value: $0) },
buttonBorderColor: dictionary["buttonBorderColor"] as? String,
buttonBorderWidth: (dictionary["buttonBorderWidth"] as? Int32).map { KotlinInt(value: $0) },
purposeListStyle: PurposeListStyle.from(enumString: dictionary["purposeListStyle"] as? String),
stickyHeader: (dictionary["stickyHeader"] as? Bool).map { KotlinBoolean(value: $0) },
hideLanguageSwitcher: (dictionary["hideLanguageSwitcher"] as? Bool).map { KotlinBoolean(value: $0) },
buttonHeightDp: (dictionary["buttonHeightDp"] as? Int32).map { KotlinInt(value: $0) },
buttonHorizontalPaddingDp: (dictionary["buttonHorizontalPaddingDp"] as? Int32).map { KotlinInt(value: $0) },
buttonSpacingDp: (dictionary["buttonSpacingDp"] as? Int32).map { KotlinInt(value: $0) },
linkUnderline: (dictionary["linkUnderline"] as? Bool).map { KotlinBoolean(value: $0) },
showSecondLayerCloseButton: (dictionary["showSecondLayerCloseButton"] as? Bool).map { KotlinBoolean(value: $0) },
tabFontSize: (dictionary["tabFontSize"] as? Int32).map { KotlinInt(value: $0) },
tabActiveColor: dictionary["tabActiveColor"] as? String,
denyAllButtonBackground: dictionary["denyAllButtonBackground"] as? String,
acceptAllButtonBackground: dictionary["acceptAllButtonBackground"] as? String,
linkColor: dictionary["linkColor"] as? String
)
}
}

extension PurposeListStyle {
static func from(enumString: String?) -> PurposeListStyle? {
guard let enumString = enumString else { return nil }

switch enumString {
case "BOXED":
return .boxed
case "FLAT":
return .flat
default:
return nil
}
}
}
7 changes: 6 additions & 1 deletion ios/Extensions/BannerSettings+Dict.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Usercentrics
import UsercentricsUI
import UIKit

Expand All @@ -16,10 +17,14 @@ extension BannerSettings {
let secondLayerStyleSettingsDict = dictionary["secondLayerStyleSettings"] as? NSDictionary
let secondLayerSettings = SecondLayerStyleSettings(from: secondLayerStyleSettingsDict, bannerFontHolder: bannerFontHolder)

let initCustomizationDict = dictionary["initCustomization"] as? NSDictionary
let initCustomization = BannerInitCustomization(from: initCustomizationDict)

self.init(generalStyleSettings: generalStyleSettings,
firstLayerStyleSettings: firstLayerSettings,
secondLayerStyleSettings: secondLayerSettings,
variantName: dictionary["variantName"] as? String)
variantName: dictionary["variantName"] as? String,
initCustomization: initCustomization)
}
}

Expand Down
4 changes: 4 additions & 0 deletions ios/Extensions/UsercentricsOptions+Dict.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public extension UsercentricsOptions {
options.initTimeoutMillis = Int64(initTimeoutMillis)
}

if let bannerCustomizationDict = dictionary["bannerCustomization"] as? NSDictionary {
options.bannerCustomization = BannerInitCustomization(from: bannerCustomizationDict)
}

return options
}
}
Expand Down
4 changes: 2 additions & 2 deletions sample/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2816,7 +2816,7 @@ SPEC CHECKSUMS:
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f
RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585
RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23
RCTTypeSafety: 4aefa8328ab1f86da273f08517f1f6b343f6c2cc
Expand Down Expand Up @@ -2850,7 +2850,7 @@ SPEC CHECKSUMS:
React-Mapbuffer: e4a65db5f4df53369f39558c0cf2f480f6d3d6c7
React-microtasksnativemodule: 86334c5c06315e0bccb7b6e6f2c905e92f98b615
react-native-safe-area-context: eda63a662750758c1fdd7e719c9f1026c8d161cb
react-native-usercentrics: 04e3b7f3afa0f0d105c316b1d6f4aea5b5fbfe0c
react-native-usercentrics: 61e591b5b3d23360ec528b086e374cf53bbaeba0
react-native-webview: 83c663c5bdf1357d3e7c00986260cb888ea0e328
React-NativeModulesApple: 8c7eb6057b00c191a11ad5ced41826ec5a0e4d78
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
Expand Down
104 changes: 104 additions & 0 deletions sample/ios/sampleTests/BannerInitCustomizationDictTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import XCTest

@testable import Usercentrics
@testable import react_native_usercentrics

class BannerInitCustomizationDictTests: XCTestCase {

func testFromDictWithAllValuesSet() {
let dict: NSDictionary = [
"paddingTop": 16,
"paddingBottom": 16,
"paddingStart": 8,
"paddingEnd": 8,
"lineSpacingMultiplier": 1.2,
"titleFontSize": 18,
"bodyFontSize": 14,
"linkFontSize": 14,
"titleFontBold": true,
"headerPaddingTop": 12,
"headerPaddingSides": 12,
"headerPaddingBetweenElements": 4,
"buttonBorderColor": "#004dcf",
"buttonBorderWidth": 1,
"purposeListStyle": "FLAT",
"stickyHeader": true,
"hideLanguageSwitcher": false,
"buttonHeightDp": 48,
"buttonHorizontalPaddingDp": 16,
"buttonSpacingDp": 8,
"linkUnderline": true,
"showSecondLayerCloseButton": true,
"tabFontSize": 14,
"tabActiveColor": "#004dcf",
"denyAllButtonBackground": "#ffffff",
"acceptAllButtonBackground": "#004dcf",
"linkColor": "#004dcf",
]

let customization = BannerInitCustomization(from: dict)!

XCTAssertEqual(16, customization.paddingTop?.int32Value)
XCTAssertEqual(16, customization.paddingBottom?.int32Value)
XCTAssertEqual(8, customization.paddingStart?.int32Value)
XCTAssertEqual(8, customization.paddingEnd?.int32Value)
XCTAssertEqual(1.2, customization.lineSpacingMultiplier?.floatValue ?? -1, accuracy: 0.0001)
XCTAssertEqual(18, customization.titleFontSize?.int32Value)
XCTAssertEqual(14, customization.bodyFontSize?.int32Value)
XCTAssertEqual(14, customization.linkFontSize?.int32Value)
XCTAssertEqual(true, customization.titleFontBold?.boolValue)
XCTAssertEqual(12, customization.headerPaddingTop?.int32Value)
XCTAssertEqual(12, customization.headerPaddingSides?.int32Value)
XCTAssertEqual(4, customization.headerPaddingBetweenElements?.int32Value)
XCTAssertEqual("#004dcf", customization.buttonBorderColor)
XCTAssertEqual(1, customization.buttonBorderWidth?.int32Value)
XCTAssertEqual(.flat, customization.purposeListStyle)
XCTAssertEqual(true, customization.stickyHeader?.boolValue)
XCTAssertEqual(false, customization.hideLanguageSwitcher?.boolValue)
XCTAssertEqual(48, customization.buttonHeightDp?.int32Value)
XCTAssertEqual(16, customization.buttonHorizontalPaddingDp?.int32Value)
XCTAssertEqual(8, customization.buttonSpacingDp?.int32Value)
XCTAssertEqual(true, customization.linkUnderline?.boolValue)
XCTAssertEqual(true, customization.showSecondLayerCloseButton?.boolValue)
XCTAssertEqual(14, customization.tabFontSize?.int32Value)
XCTAssertEqual("#004dcf", customization.tabActiveColor)
XCTAssertEqual("#ffffff", customization.denyAllButtonBackground)
XCTAssertEqual("#004dcf", customization.acceptAllButtonBackground)
XCTAssertEqual("#004dcf", customization.linkColor)
}

func testFromDictWithNoValuesSetOmitsFields() {
let dict: NSDictionary = [:]
let customization = BannerInitCustomization(from: dict)!

XCTAssertNil(customization.paddingTop)
XCTAssertNil(customization.buttonBorderColor)
XCTAssertNil(customization.purposeListStyle)
}

func testFromNilDictionaryReturnsNil() {
XCTAssertNil(BannerInitCustomization(from: nil))
}

func testPurposeListStyleFromEnumString() {
XCTAssertEqual(.boxed, PurposeListStyle.from(enumString: "BOXED"))
XCTAssertEqual(.flat, PurposeListStyle.from(enumString: "FLAT"))
XCTAssertNil(PurposeListStyle.from(enumString: "UNKNOWN"))
XCTAssertNil(PurposeListStyle.from(enumString: nil))
}

func testUsercentricsOptionsBannerCustomizationFromDict() {
let dict: NSDictionary = [
"settingsId": "123",
"bannerCustomization": [
"paddingTop": 16,
"purposeListStyle": "FLAT",
],
]

let options = UsercentricsOptions.initialize(from: dict)!

XCTAssertEqual(16, options.bannerCustomization?.paddingTop?.int32Value)
XCTAssertEqual(.flat, options.bannerCustomization?.purposeListStyle)
}
}
Loading
Loading