Skip to content

Commit

Permalink
Updates EmbraceConfigurable.update method to take completion handler
Browse files Browse the repository at this point in the history
This is used to post `embraceConfigUpdated` notification
  • Loading branch information
atreat committed Sep 16, 2024
1 parent 54c71d4 commit 0d1c169
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 105 deletions.
15 changes: 13 additions & 2 deletions Sources/EmbraceConfigInternal/EmbraceConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,18 @@ public class EmbraceConfig {
}

public func update() {
configurable.update()
configurable.update { [weak self] didChange, error in
if let error = error {
self?.logger.error(
"Failed update in EmbraceConfig",
attributes: [ "error.message": error.localizedDescription ]
)
}

if didChange {
self?.notificationCenter.post(name: .embraceConfigUpdated, object: self)
}
}
}

// MARK: - Notifications
Expand All @@ -68,7 +79,7 @@ public class EmbraceConfig {
}
}

extension EmbraceConfig: EmbraceConfigurable {
extension EmbraceConfig /* EmbraceConfigurable delegation */ {
public var isSDKEnabled: Bool {
return configurable.isSDKEnabled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,6 @@ public class RemoteConfig {
self.deviceIdHexValue = deviceIdHexValue
self.deviceIdUsedDigits = deviceIdUsedDigits
}

public func update() {
guard updating == false else {
return
}

updating = true
fetcher.fetch { [self] newPayload in
defer { updating = false }
guard let newPayload = newPayload else {
return
}

payload = newPayload
}
}
}

extension RemoteConfig: EmbraceConfigurable {
Expand All @@ -66,6 +50,32 @@ extension RemoteConfig: EmbraceConfigurable {
error: UInt(max(payload.internalLogsErrorLimit, 0))
)
}

public func update(completion: @escaping (Bool, (any Error)?) -> Void) {
guard updating == false else {
completion(false, nil)
return
}

updating = true
fetcher.fetch { [weak self] newPayload in
defer { self?.updating = false }
guard let strongSelf = self else {
completion(false, nil)
return
}

guard let newPayload = newPayload else {
completion(false, nil)
return
}

let didUpdate = strongSelf.payload != newPayload
strongSelf.payload = newPayload

completion(didUpdate, nil)
}
}
}

extension RemoteConfig {
Expand Down
6 changes: 5 additions & 1 deletion Sources/EmbraceConfiguration/EmbraceConfigurable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@ import Foundation
var networkPayloadCaptureRules: [NetworkPayloadCaptureRule] { get }

/// Tell the configurable implementation it should update if possible.
func update()
/// - Parameters:
/// - completion: A completion block that takes two parameters (didChange, error). Completion block should pass `true`
/// if the configuration now has different values and `false` if not in the case of an error updating, the completion block should
/// return `false` and an Error object describing the issue.
func update(completion: @escaping (Bool, Error?) -> Void)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public class DefaultConfig: EmbraceConfigurable {

public let networkPayloadCaptureRules = [NetworkPayloadCaptureRule]()

public func update() { /* No op */ }
public func update(completion: (Bool, (any Error)?) -> Void) {
completion(false, nil)
}

public init() { }
}
Expand Down
35 changes: 35 additions & 0 deletions Tests/EmbraceConfigInternalTests/EmbraceConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ final class EmbraceConfigTests: XCTestCase {
)
}

// MARK: Update if Needed

func test_updateIfNeeded_returnsTrueIfUpdateOccurs() {
let mockConfig = MockEmbraceConfigurable()
mockConfig.updateExpectation.expectedFulfillmentCount = 1
Expand Down Expand Up @@ -49,6 +51,37 @@ final class EmbraceConfigTests: XCTestCase {
wait(for: [mockConfig.updateExpectation], timeout: 1)
}

func test_updateIfNeeded_postsNotificationIf_configDidChange() {
let mockConfig = MockEmbraceConfigurable()
mockConfig.updateCompletionParamDidUpdate = true
mockConfig.updateExpectation.expectedFulfillmentCount = 1

let config = buildConfig(configurable: mockConfig)

let notificationExpectation = expectation(forNotification: .embraceConfigUpdated, object: config)

let result1 = config.updateIfNeeded()
XCTAssertTrue(result1)
wait(for: [notificationExpectation])
}

func test_updateIfNeeded_doesNot_postNotificationIf_configDidNotChange() {
let mockConfig = MockEmbraceConfigurable()
mockConfig.updateCompletionParamDidUpdate = false
mockConfig.updateExpectation.expectedFulfillmentCount = 1

let config = buildConfig(configurable: mockConfig)

let notificationExpectation = expectation(forNotification: .embraceConfigUpdated, object: config)
notificationExpectation.isInverted = true

let result1 = config.updateIfNeeded()
XCTAssertTrue(result1)
wait(for: [notificationExpectation], timeout: .shortTimeout)
}

// MARK: appDidBecomeActive

func test_appDidBecomeActive_callsUpdate() {
let mockConfig = MockEmbraceConfigurable()
mockConfig.updateExpectation.expectedFulfillmentCount = 1
Expand Down Expand Up @@ -92,6 +125,8 @@ final class EmbraceConfigTests: XCTestCase {
wait(for: [mockConfig.updateExpectation], timeout: 1)
}

// MARK: Configurable Delegation

func test_isSDKEnabled_callsUnderlyingConfigurable() {
let mockConfig = MockEmbraceConfigurable()
let config = buildConfig(configurable: mockConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import XCTest
import TestSupport
@testable import EmbraceConfigInternal
@testable import EmbraceConfiguration

final class RemoteConfigTests: XCTestCase {

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import TestSupport
@testable import EmbraceCore
@testable import EmbraceConfigInternal
import EmbraceStorageInternal
@testable import EmbraceConfiguration

class NetworkPayloadCaptureHandlerTests: XCTestCase {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import XCTest
import TestSupport
@testable import EmbraceCore
@testable import EmbraceConfigInternal
@testable import EmbraceConfiguration
import EmbraceStorageInternal

class URLSessionTaskCaptureRuleTests: XCTestCase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import XCTest
import TestSupport
import EmbraceStorageInternal
import EmbraceConfigInternal
import EmbraceConfiguration
import OpenTelemetryApi

class DefaultInternalLoggerTests: XCTestCase {
Expand Down
11 changes: 2 additions & 9 deletions Tests/EmbraceCoreTests/Options/Embrace+OptionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,8 @@
import XCTest
import EmbraceCore
import EmbraceConfigInternal

class MockEmbraceConfigurable: EmbraceConfigurable {
var isSDKEnabled: Bool = true
var isBackgroundSessionEnabled: Bool = true
var isNetworkSpansForwardingEnabled: Bool = true
var networkPayloadCaptureRules: [NetworkPayloadCaptureRule] = []
var internalLogLimits: InternalLogLimits = InternalLogLimits()
func update() { }
}
import EmbraceConfiguration
import TestSupport

final class Embrace_OptionsTests: XCTestCase {

Expand Down
102 changes: 102 additions & 0 deletions Tests/TestSupport/Mocks/MockEmbraceConfigurable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//
// Copyright © 2024 Embrace Mobile, Inc. All rights reserved.
//

import Foundation
import EmbraceConfigInternal
import EmbraceConfiguration
import XCTest

public class MockEmbraceConfigurable: EmbraceConfigurable {

public init(
isSDKEnabled: Bool = false,
isBackgroundSessionEnabled: Bool = false,
isNetworkSpansForwardingEnabled: Bool = false,
internalLogLimits: InternalLogLimits = InternalLogLimits(),
networkPayloadCaptureRules: [NetworkPayloadCaptureRule] = [],
updateCompletionParamDidUpdate: Bool = false,
updateCompletionParamError: Error? = nil
) {
self._isSDKEnabled = isSDKEnabled
self._isBackgroundSessionEnabled = isBackgroundSessionEnabled
self._isNetworkSpansForwardingEnabled = isNetworkSpansForwardingEnabled
self._internalLogLimits = internalLogLimits
self._networkPayloadCaptureRules = networkPayloadCaptureRules
self.updateCompletionParamDidUpdate = updateCompletionParamDidUpdate
self.updateCompletionParamError = updateCompletionParamError
}

private var _isSDKEnabled: Bool
public let isSDKEnabledExpectation = XCTestExpectation(description: "isSDKEnabled called")
public var isSDKEnabled: Bool {
get {
isSDKEnabledExpectation.fulfill()
return _isSDKEnabled
}
set {
_isSDKEnabled = newValue
}
}

private var _isBackgroundSessionEnabled: Bool
public let isBackgroundSessionEnabledExpectation = XCTestExpectation(
description: "isBackgroundSessionEnabled called"
)
public var isBackgroundSessionEnabled: Bool {
get {
isBackgroundSessionEnabledExpectation.fulfill()
return _isBackgroundSessionEnabled
}
set {
_isBackgroundSessionEnabled = newValue
}
}

private var _isNetworkSpansForwardingEnabled: Bool
public let isNetworkSpansForwardingEnabledExpectation = XCTestExpectation(
description: "isNetworkSpansForwardingEnabled called" )
public var isNetworkSpansForwardingEnabled: Bool {
get {
isNetworkSpansForwardingEnabledExpectation.fulfill()
return _isNetworkSpansForwardingEnabled
}
set {
_isNetworkSpansForwardingEnabled = newValue
}
}

private var _internalLogLimits: InternalLogLimits
public let internalLogLimitsExpectation = XCTestExpectation(description: "internalLogLimits called")
public var internalLogLimits: InternalLogLimits {
get {
internalLogLimitsExpectation.fulfill()
return _internalLogLimits
}
set {
_internalLogLimits = newValue
}
}

private var _networkPayloadCaptureRules: [NetworkPayloadCaptureRule]
public let networkPayloadCaptureRulesExpectation = XCTestExpectation(
description: "networkPayloadCaptureRules called"
)
public var networkPayloadCaptureRules: [NetworkPayloadCaptureRule] {
get {
networkPayloadCaptureRulesExpectation.fulfill()
return _networkPayloadCaptureRules
}
set {
_networkPayloadCaptureRules = newValue
}
}

public let updateExpectation = XCTestExpectation(description: "update called")
public var updateCompletionParamDidUpdate: Bool
public var updateCompletionParamError: Error?
public func update(completion: @escaping (Bool, (any Error)?) -> Void) {
updateExpectation.fulfill()
completion(updateCompletionParamDidUpdate, updateCompletionParamError)
}
}

0 comments on commit 0d1c169

Please sign in to comment.