diff --git a/Sources/EmbraceCommonInternal/Protocols/DispatchableQueue.swift b/Sources/EmbraceCommonInternal/Protocols/DispatchableQueue.swift new file mode 100644 index 00000000..5fb73e6d --- /dev/null +++ b/Sources/EmbraceCommonInternal/Protocols/DispatchableQueue.swift @@ -0,0 +1,16 @@ +// +// Copyright © 2024 Embrace Mobile, Inc. All rights reserved. +// + +import Foundation + +public protocol DispatchableQueue: AnyObject { + func async(_ block: @escaping () -> Void) + func sync(execute block: () -> Void) +} + +extension DispatchQueue: DispatchableQueue { + public func async(_ block: @escaping () -> Void) { + async(group: nil, execute: block) + } +} diff --git a/Sources/EmbraceConfigInternal/EmbraceConfig.swift b/Sources/EmbraceConfigInternal/EmbraceConfig.swift index baa88b04..674ebc50 100644 --- a/Sources/EmbraceConfigInternal/EmbraceConfig.swift +++ b/Sources/EmbraceConfigInternal/EmbraceConfig.swift @@ -20,19 +20,20 @@ public class EmbraceConfig { let configurable: EmbraceConfigurable - let queue: DispatchQueue + let queue: DispatchableQueue public init( configurable: EmbraceConfigurable, options: Options, notificationCenter: NotificationCenter, - logger: InternalLogger + logger: InternalLogger, + queue: DispatchableQueue = DispatchQueue(label: "com.embrace.config", attributes: .concurrent) ) { self.options = options self.notificationCenter = notificationCenter self.logger = logger self.configurable = configurable - self.queue = DispatchQueue(label: "com.embrace.config", attributes: .concurrent) + self.queue = queue update() diff --git a/Sources/EmbraceCore/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRule.swift b/Sources/EmbraceCore/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRule.swift index 1378356a..cdb76702 100644 --- a/Sources/EmbraceCore/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRule.swift +++ b/Sources/EmbraceCore/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRule.swift @@ -25,7 +25,7 @@ class URLSessionTaskCaptureRule { self.rule = rule do { - regex = try NSRegularExpression(pattern: rule.urlRegex, options: .caseInsensitive) + regex = try NSRegularExpression(pattern: rule.urlRegex.removingHttpPrefix(), options: .caseInsensitive) } catch { Embrace.logger.error("Error trying to create regex \"\(rule.urlRegex)\" for rule \(rule.id)!\n\(error.localizedDescription)") regex = nil @@ -88,7 +88,8 @@ class URLSessionTaskCaptureRule { return false } - let matches = regex.matches(in: url, range: NSRange(location: 0, length: url.count)) + let string = url.removingHttpPrefix() + let matches = regex.matches(in: string, range: NSRange(location: 0, length: string.count)) return matches.count > 0 } @@ -104,3 +105,11 @@ class URLSessionTaskCaptureRule { .replacingOccurrences(of: " ", with: "") } } + +extension String { + func removingHttpPrefix() -> String { + return self + .replacingOccurrences(of: "https://", with: "") + .replacingOccurrences(of: "http://", with: "") + } +} diff --git a/Sources/EmbraceCore/Capture/Network/URLSessionTaskHandler.swift b/Sources/EmbraceCore/Capture/Network/URLSessionTaskHandler.swift index d3b7fa8f..9ea46c3c 100644 --- a/Sources/EmbraceCore/Capture/Network/URLSessionTaskHandler.swift +++ b/Sources/EmbraceCore/Capture/Network/URLSessionTaskHandler.swift @@ -31,11 +31,11 @@ protocol URLSessionTaskHandlerDataSource: AnyObject { final class DefaultURLSessionTaskHandler: URLSessionTaskHandler { private var spans: [URLSessionTask: Span] = [:] - private let queue: DispatchQueue + private let queue: DispatchableQueue private let payloadCaptureHandler: NetworkPayloadCaptureHandler weak var dataSource: URLSessionTaskHandlerDataSource? - init(processingQueue: DispatchQueue = DefaultURLSessionTaskHandler.queue(), + init(processingQueue: DispatchableQueue = DefaultURLSessionTaskHandler.queue(), dataSource: URLSessionTaskHandlerDataSource?) { self.queue = processingQueue self.dataSource = dataSource @@ -213,7 +213,7 @@ final class DefaultURLSessionTaskHandler: URLSessionTaskHandler { } private extension DefaultURLSessionTaskHandler { - static func queue() -> DispatchQueue { - .init(label: "com.embrace.URLSessionTaskHandler", qos: .utility) + static func queue() -> DispatchableQueue { + DispatchQueue(label: "com.embrace.URLSessionTaskHandler", qos: .utility) } } diff --git a/Tests/EmbraceConfigInternalTests/EmbraceConfigTests.swift b/Tests/EmbraceConfigInternalTests/EmbraceConfigTests.swift index 36d5fd6e..8aa24cf7 100644 --- a/Tests/EmbraceConfigInternalTests/EmbraceConfigTests.swift +++ b/Tests/EmbraceConfigInternalTests/EmbraceConfigTests.swift @@ -19,7 +19,8 @@ final class EmbraceConfigTests: XCTestCase { configurable: configurable, options: options, notificationCenter: .default, - logger: MockLogger() + logger: MockLogger(), + queue: MockQueue() ) } diff --git a/Tests/EmbraceCoreTests/Capture/Network/DefaultURLSessionTaskHandlerTests.swift b/Tests/EmbraceCoreTests/Capture/Network/DefaultURLSessionTaskHandlerTests.swift index 0fa02d09..bb52c473 100644 --- a/Tests/EmbraceCoreTests/Capture/Network/DefaultURLSessionTaskHandlerTests.swift +++ b/Tests/EmbraceCoreTests/Capture/Network/DefaultURLSessionTaskHandlerTests.swift @@ -71,7 +71,7 @@ class DefaultURLSessionTaskHandlerTests: XCTestCase { func test_onCreateTaskWithoutMethod_SpanNameShouldOnlyBePath() { givenTaskHandler() - givenAnURLSessionTask(urlString: "https://embrace.io/with/path/", method: "") + givenAnURLSessionTask(urlString: "https://embrace.io/with/path", method: "") whenInvokingCreate() thenSpanName(is: "/with/path") } @@ -80,7 +80,7 @@ class DefaultURLSessionTaskHandlerTests: XCTestCase { givenTaskHandler() givenAnURLSessionTask(urlString: "https://embrace-is-great.io") whenInvokingCreate() - thenSpanShouldHaveURLAttribute(withValue: "https://embrace-is-great.io") + thenSpanShouldHaveURLAttribute(withValue: "https://\(testName).embrace-is-great.io") } func test_onCreateTaskHavingMethod_HttpMethodShouldBeSetOnSpanAsAttribute() { @@ -168,13 +168,13 @@ class DefaultURLSessionTaskHandlerTests: XCTestCase { givenTaskHandler() givenRequestsDataSourceWithBlock { originalRequest in var request = originalRequest - request.url = URL(string: "http://www.test.com") + request.url = URL(string: "https://www.test.com") return request } givenAnURLSessionTask(method: "GET") whenInvokingCreate() whenInvokingFinish() - thenSpanHasTheCorrectPath("http://www.test.com") + thenSpanHasTheCorrectPath("https://www.test.com") } func test_requestsDataSource_method() { @@ -207,7 +207,7 @@ class DefaultURLSessionTaskHandlerTests: XCTestCase { private extension DefaultURLSessionTaskHandlerTests { func givenTaskHandler() { dataSource.state = .active - sut = DefaultURLSessionTaskHandler(dataSource: dataSource) + sut = DefaultURLSessionTaskHandler(processingQueue: MockQueue(), dataSource: dataSource) } func givenStateChanged(toState: CaptureServiceState) { @@ -230,7 +230,7 @@ private extension DefaultURLSessionTaskHandlerTests { } func givenAnURLSessionTask(urlString: String = "https://embrace.io", method: String? = nil, body: Data? = nil, response: URLResponse? = nil) { - var url = URL(string: urlString)! + var url = URL(string: urlString.replacingOccurrences(of: "https://", with: "https://\(testName)."))! var request = URLRequest(url: url) request.httpMethod = method if let body = body { diff --git a/Tests/EmbraceCoreTests/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRuleTests.swift b/Tests/EmbraceCoreTests/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRuleTests.swift index d4f67513..990a8727 100644 --- a/Tests/EmbraceCoreTests/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRuleTests.swift +++ b/Tests/EmbraceCoreTests/Capture/Network/NetworkPayloadCapture/URLSessionTaskCaptureRuleTests.swift @@ -145,4 +145,17 @@ class URLSessionTaskCaptureRuleTests: XCTestCase { XCTAssert(rule.shouldTriggerFor(request: request, response: response, error: error)) } + + func test_trigger_match3() { + // given a rule + let rule = URLSessionTaskCaptureRule(rule: rule1) + + // it should trigger for a request matches on everything + let url = URL(string: "https://www.test.com/user/1234")! + var request = URLRequest(url: url) + request.httpMethod = "GET" + let response = HTTPURLResponse(url: url, statusCode: 500, httpVersion: nil, headerFields: nil) + + XCTAssert(rule.shouldTriggerFor(request: request, response: response, error: nil)) + } } diff --git a/Tests/TestSupport/Mocks/MockQueue.swift b/Tests/TestSupport/Mocks/MockQueue.swift new file mode 100644 index 00000000..6e647a5a --- /dev/null +++ b/Tests/TestSupport/Mocks/MockQueue.swift @@ -0,0 +1,17 @@ +// +// Copyright © 2024 Embrace Mobile, Inc. All rights reserved. +// + +import EmbraceCommonInternal + +public class MockQueue: DispatchableQueue { + public func async(_ block: @escaping () -> Void) { + block() + } + + public func sync(execute block: () -> Void) { + block() + } + + public init() {} +}