diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 63235cc2..10f474f4 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -6,6 +6,6 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/labeler@main + - uses: actions/labeler@v4.3.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file diff --git a/support/tests/test_tealium_core/TealiumModulesManagerTests.swift b/support/tests/test_tealium_core/TealiumModulesManagerTests.swift index ab44faf8..177659d4 100644 --- a/support/tests/test_tealium_core/TealiumModulesManagerTests.swift +++ b/support/tests/test_tealium_core/TealiumModulesManagerTests.swift @@ -54,6 +54,7 @@ class TealiumModulesManagerTests: XCTestCase { override func setUp() { super.setUp() + sharedConfig.shouldUseRemotePublishSettings = false // Put setup code here. This method is called before the invocation of each test method in the class. } @@ -403,6 +404,91 @@ class TealiumModulesManagerTests: XCTestCase { } } #endif + + func testDisableLibraryRemovesAllModules() { + sharedConfig.shouldUseRemotePublishSettings = true + var defaultSettings = RemotePublishSettings() + let retriever = MockPublishSettingsRetriever(cachedSettings: defaultSettings) + context.config.dispatchers = [Dispatchers.Collect] + TealiumQueues.backgroundSerialQueue.sync { + let modulesManager = getModulesManager(context, remotePublishSettingsRetriever: retriever) + XCTAssertNotEqual(modulesManager.dispatchers.count, 0) + XCTAssertNotEqual(modulesManager.collectors.count, 0) + + defaultSettings.isEnabled = false + modulesManager.didUpdate(defaultSettings) + XCTAssertEqual(modulesManager.dispatchers.count, 0) + XCTAssertEqual(modulesManager.collectors.count, 0) + } + } + + func testReEnableLibraryAddsAllModulesBack() { + sharedConfig.shouldUseRemotePublishSettings = true + var defaultSettings = RemotePublishSettings() + let retriever = MockPublishSettingsRetriever(cachedSettings: defaultSettings) + context.config.dispatchers = [Dispatchers.Collect] + TealiumQueues.backgroundSerialQueue.sync { + let modulesManager = getModulesManager(context, remotePublishSettingsRetriever: retriever) + XCTAssertNotEqual(modulesManager.dispatchers.count, 0) + XCTAssertNotEqual(modulesManager.collectors.count, 0) + + defaultSettings.isEnabled = false + modulesManager.didUpdate(defaultSettings) + XCTAssertEqual(modulesManager.dispatchers.count, 0) + XCTAssertEqual(modulesManager.collectors.count, 0) + + defaultSettings.isEnabled = true + modulesManager.didUpdate(defaultSettings) + XCTAssertNotEqual(modulesManager.dispatchers.count, 0) + XCTAssertNotEqual(modulesManager.collectors.count, 0) + } + } + + func testDisableLibraryStopsFutureTrackingCalls() { + let trackNotSent = expectation(description: "Track is not sent") + trackNotSent.isInverted = true + TealiumExpectations.expectations["sendTrack"] = trackNotSent + sharedConfig.shouldUseRemotePublishSettings = true + var defaultSettings = RemotePublishSettings() + let retriever = MockPublishSettingsRetriever(cachedSettings: defaultSettings) + context.config.dispatchers = [Dispatchers.Collect] + TealiumQueues.backgroundSerialQueue.sync { + let modulesManager = getModulesManager(context, remotePublishSettingsRetriever: retriever) + let connectivity = ConnectivityModule(context: modulesManager.context, delegate: nil, diskStorage: nil) { _ in } + modulesManager.dispatchManager = DummyDispatchManagerSendTrack(dispatchers: nil, dispatchValidators: nil, dispatchListeners: nil, connectivityManager: connectivity, config: testTealiumConfig) + defaultSettings.isEnabled = false + modulesManager.didUpdate(defaultSettings) + modulesManager.sendTrack(TealiumTrackRequest(data: [:])) + } + waitForExpectations(timeout: 1.0) + } + + func testDisableLibraryDoesntStopRefreshingRemoteSettings() { + let refreshSettings = expectation(description: "Settings are refreshed") + refreshSettings.assertForOverFulfill = false // other events are also being sent so mulitple refresh are expected when running multiple tests at the same time + let notRefreshSettings = expectation(description: "Settings are not refreshed yet") + notRefreshSettings.isInverted = true + sharedConfig.shouldUseRemotePublishSettings = true + var defaultSettings = RemotePublishSettings() + let retriever = MockPublishSettingsRetriever(cachedSettings: defaultSettings) + context.config.dispatchers = [Dispatchers.Collect] + TealiumQueues.backgroundSerialQueue.sync { + let modulesManager = getModulesManager(context, remotePublishSettingsRetriever: retriever) + modulesManager.remotePublishSettingsRetriever = MockPublishSettingsRetriever { + notRefreshSettings.fulfill() + } + defaultSettings.isEnabled = false + modulesManager.didUpdate(defaultSettings) + XCTAssertEqual(modulesManager.dispatchers.count, 0) + XCTAssertEqual(modulesManager.collectors.count, 0) + wait(for: [notRefreshSettings], timeout: 1.0) + modulesManager.remotePublishSettingsRetriever = MockPublishSettingsRetriever { + refreshSettings.fulfill() + } + modulesManager.sendTrack(TealiumTrackRequest(data: [:])) + wait(for: [refreshSettings], timeout: 1.0) + } + } } extension TealiumModulesManagerTests: ModuleDelegate { @@ -496,13 +582,15 @@ class DummyDispatchManagerSendTrack: DispatchManagerProtocol { struct MockPublishSettingsRetriever: TealiumPublishSettingsRetrieverProtocol { - init(cachedSettings: RemotePublishSettings? = nil) { + let onRefresh: () -> Void + init(cachedSettings: RemotePublishSettings? = nil, onRefresh: @escaping () -> Void = { }) { sharedConfig.shouldUseRemotePublishSettings = true + self.onRefresh = onRefresh self.cachedSettings = cachedSettings } var cachedSettings: RemotePublishSettings? func refresh() { - + onRefresh() } } diff --git a/support/tests/test_tealium_tagmanagement/WKWebViewIntegrationTests.swift b/support/tests/test_tealium_tagmanagement/WKWebViewIntegrationTests.swift index 6b700d2e..051eef93 100644 --- a/support/tests/test_tealium_tagmanagement/WKWebViewIntegrationTests.swift +++ b/support/tests/test_tealium_tagmanagement/WKWebViewIntegrationTests.swift @@ -21,7 +21,7 @@ class WKWebViewIntegrationTests: XCTestCase { var expect: XCTestExpectation! var module: TagManagementModule! - var config: TealiumConfig! + let config = TealiumConfig(account: "testAccount", profile: "testProfile", environment: "testEnv") var mockTagmanagement: MockTagManagementWebView! static var processPool = WKProcessPool() static var wkConfig: WKWebViewConfiguration = { @@ -34,7 +34,6 @@ class WKWebViewIntegrationTests: XCTestCase { override func setUp() { super.setUp() userDefaults?.removePersistentDomain(forName: #file) - config = TealiumConfig(account: "testAccount", profile: "testProfile", environment: "testEnv") } func testWKWebViewInstance() { @@ -204,8 +203,7 @@ class WKWebViewIntegrationTests: XCTestCase { } }) }) - - wait(for: [expect], timeout: 5.0) + wait(for: [expect], timeout: 10.0) } func testModuleWithQueryParamProviderChangesUrl() { diff --git a/tealium/core/ModulesManager.swift b/tealium/core/ModulesManager.swift index 28c15343..4b23917d 100644 --- a/tealium/core/ModulesManager.swift +++ b/tealium/core/ModulesManager.swift @@ -72,6 +72,7 @@ public class ModulesManager { } self.setupDispatchers(context: context) + self.setupCollectors(config: newValue) } } private var cachedTrackData: [String: Any]? @@ -183,6 +184,7 @@ public class ModulesManager { if self.config.shouldUseRemotePublishSettings == true { self.remotePublishSettingsRetriever?.refresh() } + guard config.isEnabled != false else { return } let requestData = gatherTrackData(for: request.trackDictionary) let newRequest = TealiumTrackRequest(data: requestData) dispatchManager?.processTrack(newRequest) @@ -256,6 +258,10 @@ extension ModulesManager { } func setupCollectors(config: TealiumConfig) { + guard context.config.isEnabled != false else { + collectors.removeAll() + return + } collectorTypes.forEach { collector in guard !collectors.contains(where: { type(of: $0) == collector }) else { return @@ -280,6 +286,10 @@ extension ModulesManager { } func setupDispatchers(context: TealiumContext) { + guard context.config.isEnabled != false else { + dispatchers.removeAll() + return + } self.config.dispatchers?.forEach { dispatcherType in guard !dispatchers.contains(where: { type(of: $0) == dispatcherType }) else { return