From 1a5ec3a2ff8376765640a21140d8a73c8c78cd94 Mon Sep 17 00:00:00 2001 From: Greg Leonard <45019882+greg-el@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:34:58 +0100 Subject: [PATCH] Move decorateLink to TrackerControllerImpl --- Sources/Core/Tracker/Tracker.swift | 52 ------------------- .../Core/Tracker/TrackerControllerImpl.swift | 51 +++++++++++++++++- Tests/TestLinkDecorator.swift | 2 +- 3 files changed, 50 insertions(+), 55 deletions(-) diff --git a/Sources/Core/Tracker/Tracker.swift b/Sources/Core/Tracker/Tracker.swift index c399d5e01..cae77446a 100644 --- a/Sources/Core/Tracker/Tracker.swift +++ b/Sources/Core/Tracker/Tracker.swift @@ -386,58 +386,6 @@ class Tracker: NSObject { session?.startChecker() } - private func decorateLinkErrorTemplate(_ extendedParameterName: String) -> String { - "\(extendedParameterName) has been requested in CrossDeviceParameterConfiguration, but it is not set." - } - - func decorateLink(_ url: URL, extendedParameters: CrossDeviceParameterConfiguration? = nil) -> URL? { - var userId: String - switch self.session?.userId { - case .none: - logError(message: "\(url) could not be decorated as session.userId is nil") - return nil - case .some(let id): - userId = id - } - - let extendedParameters = extendedParameters ?? CrossDeviceParameterConfiguration() - - let sessionId = extendedParameters.sessionId ? self.session?.state?.sessionId ?? "" : "" - if (extendedParameters.sessionId && sessionId.isEmpty) { - logDebug(message: "\(decorateLinkErrorTemplate("sessionId")) Ensure an event has been tracked to generate a session before calling this method.") - } - - let sourceId = extendedParameters.sourceId ? self.appId : "" - - let sourcePlatform = extendedParameters.sourcePlatform ? devicePlatformToString(self.devicePlatform) : "" - - let subjectUserId = extendedParameters.subjectUserId ? self.subject?.userId ?? "" : "" - if (extendedParameters.subjectUserId && subjectUserId.isEmpty) { - logDebug(message: "\(decorateLinkErrorTemplate("subjectUserId")) Ensure SubjectConfiguration.userId has been set on your tracker.") - } - - let reason = extendedParameters.reason ?? "" - - let spParameters = [ - userId, - String(Int(Date().timeIntervalSince1970 * 1000)), - sessionId, - subjectUserId.toBase64(), - sourceId.toBase64(), - sourcePlatform, - reason.toBase64() - ].joined(separator: ".").trimmingCharacters(in: ["."]) - - var components = URLComponents(url: url, resolvingAgainstBaseURL: false) - let spQueryParam = URLQueryItem(name: "_sp", value: spParameters) - - // Modification requires exclusive access, we must make a copy - var queryItems = components?.queryItems - components?.queryItems = (queryItems?.filter { $0.name != "_sp" } ?? []) + [spQueryParam] - - return components?.url - } - // MARK: - Notifications management @objc func receiveScreenViewNotification(_ notification: Notification) { diff --git a/Sources/Core/Tracker/TrackerControllerImpl.swift b/Sources/Core/Tracker/TrackerControllerImpl.swift index 3f90e7520..ba6536509 100644 --- a/Sources/Core/Tracker/TrackerControllerImpl.swift +++ b/Sources/Core/Tracker/TrackerControllerImpl.swift @@ -75,11 +75,53 @@ class TrackerControllerImpl: Controller, TrackerController { } func decorateLink(_ url: URL) -> URL? { - return tracker.decorateLink(url) + self.decorateLink(url, extendedParameters: CrossDeviceParameterConfiguration()) } func decorateLink(_ url: URL, extendedParameters: CrossDeviceParameterConfiguration) -> URL? { - return tracker.decorateLink(url, extendedParameters: extendedParameters) + var userId: String + switch self.session?.userId { + case .none: + logError(message: "\(url) could not be decorated as session.userId is nil") + return nil + case .some(let id): + userId = id + } + + let sessionId = extendedParameters.sessionId ? self.session?.sessionId ?? "" : "" + if (extendedParameters.sessionId && sessionId.isEmpty) { + logDebug(message: "\(decorateLinkErrorTemplate("sessionId")) Ensure an event has been tracked to generate a session before calling this method.") + } + + let sourceId = extendedParameters.sourceId ? self.appId : "" + + let sourcePlatform = extendedParameters.sourcePlatform ? devicePlatformToString(self.devicePlatform) : "" + + let subjectUserId = extendedParameters.subjectUserId ? self.subject?.userId ?? "" : "" + if (extendedParameters.subjectUserId && subjectUserId.isEmpty) { + logDebug(message: "\(decorateLinkErrorTemplate("subjectUserId")) Ensure SubjectConfiguration.userId has been set on your tracker.") + } + + let reason = extendedParameters.reason ?? "" + + let spParameters = [ + userId, + String(Int(Date().timeIntervalSince1970 * 1000)), + sessionId, + subjectUserId.toBase64(), + sourceId.toBase64(), + sourcePlatform, + reason.toBase64() + ].joined(separator: ".").trimmingCharacters(in: ["."]) + + var components = URLComponents(url: url, resolvingAgainstBaseURL: false) + let spQueryParam = URLQueryItem(name: "_sp", value: spParameters) + + // Modification requires exclusive access, we must make a copy + let queryItems = components?.queryItems + components?.queryItems = (queryItems?.filter { $0.name != "_sp" } ?? []) + [spQueryParam] + + return components?.url } // MARK: - Properties' setters and getters @@ -296,6 +338,7 @@ class TrackerControllerImpl: Controller, TrackerController { return kSPVersion } + // MARK: - Private methods private var tracker: Tracker { @@ -309,4 +352,8 @@ class TrackerControllerImpl: Controller, TrackerController { private var dirtyConfig: TrackerConfiguration { return serviceProvider.trackerConfiguration } + + private func decorateLinkErrorTemplate(_ extendedParameterName: String) -> String { + "\(extendedParameterName) has been requested in CrossDeviceParameterConfiguration, but it is not set." + } } diff --git a/Tests/TestLinkDecorator.swift b/Tests/TestLinkDecorator.swift index 9bca2a119..cba77bb28 100644 --- a/Tests/TestLinkDecorator.swift +++ b/Tests/TestLinkDecorator.swift @@ -114,7 +114,7 @@ class TestLinkDecorator: XCTestCase { let result = tracker.decorateLink(link, extendedParameters: CrossDeviceParameterConfiguration(sessionId: false, sourceId: false))! - matches(for: "https://example.com?a=a&b=b&_sp=\(tracker.session!.userId!).\(epoch)&b=b", in: result.absoluteString) + matches(for: "https://example.com?a=a&b=b&_sp=\(tracker.session!.userId!).\(epoch)", in: result.absoluteString) } func testMissingFields() {