Skip to content

Commit

Permalink
Adding CaptureServiceBuilder (#277)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoEmbrace authored Jul 17, 2024
1 parent ab0323f commit 1d1c86e
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension URLSessionCaptureService {
self.requestsDataSource = requestsDataSource
}

@objc convenience override init() {
@objc public convenience override init() {
self.init(injectTracingHeader: true, requestsDataSource: nil)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension PushNotificationCaptureService {
self.captureData = captureData
}

@objc convenience override init() {
@objc public convenience override init() {
self.init(captureData: false)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension WebViewCaptureService {
self.stripQueryParams = stripQueryParams
}

@objc convenience override init() {
@objc public convenience override init() {
self.init(stripQueryParams: false)
}
}
Expand Down
52 changes: 52 additions & 0 deletions Sources/EmbraceIO/Capture/CaptureService+Helpers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Copyright © 2024 Embrace Mobile, Inc. All rights reserved.
//

import Foundation
import EmbraceCaptureService

@objc public extension CaptureService {
/// Returns a `URLSessionCaptureService` with the given `URLSessionCaptureService.Options`.
/// - Parameter options: `URLSessionCaptureService.Options` used to configure the service.
static func urlSession(
options: URLSessionCaptureService.Options = URLSessionCaptureService.Options()
) -> URLSessionCaptureService {
return URLSessionCaptureService(options: options)
}

/// Returns a `TapCaptureService`.
static func tap() -> TapCaptureService {
return TapCaptureService()
}

/// Returns a `ViewCaptureService`.
static func view() -> ViewCaptureService {
return ViewCaptureService()
}

/// Returns a `WebViewCaptureService` with the given `WebViewCaptureService.Options`.
/// - Parameter options: `WebViewCaptureService.Options` used to configure the service.
static func webView(
options: WebViewCaptureService.Options = WebViewCaptureService.Options()
) -> WebViewCaptureService {
return WebViewCaptureService(options: options)
}

/// Adds a `LowMemoryWarningCaptureService`.
static func lowMemoryWarning() -> LowMemoryWarningCaptureService {
return LowMemoryWarningCaptureService()
}

/// Adds a `LowPowerModeCaptureService`.
static func lowPowerMode() -> LowPowerModeCaptureService {
return LowPowerModeCaptureService()
}

/// Adds a `PushNotificationCaptureService` with the given `PushNotificationCaptureService.Options`.
/// - Parameter options: `PushNotificationCaptureService.Options` used to configure the service.
static func pushNotification(
options: PushNotificationCaptureService.Options = PushNotificationCaptureService.Options()
) -> PushNotificationCaptureService {
return PushNotificationCaptureService(options: options)
}
}
69 changes: 69 additions & 0 deletions Sources/EmbraceIO/Capture/CaptureServiceBuilder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// Copyright © 2024 Embrace Mobile, Inc. All rights reserved.
//

import EmbraceCaptureService
import Foundation

/// Class used to build the list of `CaptureServices` to be used by the `Embrace` instance.
@objc (EMBCaptureServiceBuilder)
public class CaptureServiceBuilder: NSObject {
private var services: [CaptureService] = []

/// Returns the list of `CaptureServices` generated with this builder.
@objc public func build() -> [CaptureService] {
return services
}

/// Adds the given `CaptureService`.
/// - Note: If there was another `CaptureService` already added of the same type, it will be replaced with the new one.
@objc public func add(_ service: CaptureService) {
remove(ofType: type(of: service))
services.append(service)
}

/// Removes a previously added `CaptureService` of the given type, if any.
/// - Parameter type: Type of the `CaptureService` to remove.
@objc public func remove(ofType type: AnyClass) {
services.removeAll(where: { $0.isKind(of: type) })
}

/// Adds the default `CaptureServices` using their corresponding default options.
/// The default services are: `URLSessionCaptureService`, `TapCaptureService`, `ViewCaptureService`,
/// `WebViewCaptureService`, `LowMemoryWarningCaptureService` and `LowPowerModeCaptureService`.
/// - Note: Any existing `CaptureService` previously added will not get replaced by calling this method.
@discardableResult
@objc public func addDefaults() -> Self {
// url session
if !services.contains(where: { $0 is URLSessionCaptureService }) {
add(.urlSession())
}

// tap
if !services.contains(where: { $0 is TapCaptureService }) {
add(.tap())
}

// view
if !services.contains(where: { $0 is ViewCaptureService }) {
add(.view())
}

// web view
if !services.contains(where: { $0 is WebViewCaptureService }) {
add(.webView())
}

// low memory
if !services.contains(where: { $0 is LowMemoryWarningCaptureService }) {
add(.lowMemoryWarning())
}

// low power
if !services.contains(where: { $0 is LowPowerModeCaptureService }) {
add(.lowPowerMode())
}

return self
}
}
33 changes: 0 additions & 33 deletions Sources/EmbraceIO/Capture/CaptureServiceFactory+Platform.swift

This file was deleted.

4 changes: 3 additions & 1 deletion Sources/EmbraceIO/Options/Options+CaptureService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ extension Embrace.Options: ExpressibleByStringLiteral {

public extension Array where Element == CaptureService {
static var automatic: [CaptureService] {
return CaptureServiceFactory.platformCaptureServices
return CaptureServiceBuilder()
.addDefaults()
.build()
}
}
204 changes: 204 additions & 0 deletions Tests/EmbraceIOTests/CaptureServiceBuilderTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
//
// Copyright © 2024 Embrace Mobile, Inc. All rights reserved.
//

@testable import EmbraceIO
import XCTest

// swiftlint:disable force_cast

class CaptureServiceBuilderTests: XCTestCase {

func test_defaults() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding the defaults
builder.addDefaults()

// then the list contains all the default services
let list = builder.build()

XCTAssertEqual(list.count, 6)
XCTAssertNotNil(list.first(where: { $0 is URLSessionCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is TapCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is ViewCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is WebViewCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowMemoryWarningCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowPowerModeCaptureService }))
}

func test_defaultsWithNonEmptyList() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a URLSessionCaptureService with custom options
let options = URLSessionCaptureService.Options(injectTracingHeader: false, requestsDataSource: nil)
builder.add(.urlSession(options: options))

// when adding the defaults
builder.addDefaults()

// then the list contains the correct services
let list = builder.build()

XCTAssertEqual(list.count, 6)
XCTAssertNotNil(list.first(where: { $0 is TapCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is ViewCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is WebViewCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowMemoryWarningCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowPowerModeCaptureService }))

let service = list.first(where: { $0 is URLSessionCaptureService }) as! URLSessionCaptureService
XCTAssertFalse(service.options.injectTracingHeader)
XCTAssertNil(service.options.requestsDataSource)
}

func test_remove() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding the defaults
builder.addDefaults()

// when removing some services
builder.remove(ofType: URLSessionCaptureService.self)
builder.remove(ofType: TapCaptureService.self)
builder.remove(ofType: ViewCaptureService.self)

// then the list contains the correct services
let list = builder.build()

XCTAssertEqual(list.count, 3)
XCTAssertNotNil(list.first(where: { $0 is WebViewCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowMemoryWarningCaptureService }))
XCTAssertNotNil(list.first(where: { $0 is LowPowerModeCaptureService }))
}

func test_replace() {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a default URLSessionCaptureService
builder.add(.urlSession())

// and then adding it again
let options = URLSessionCaptureService.Options(injectTracingHeader: false, requestsDataSource: nil)
builder.add(.urlSession(options: options))

// then the list contains the correct services
let list = builder.build()

XCTAssertEqual(list.count, 1)
let service = list[0] as! URLSessionCaptureService
XCTAssertFalse(service.options.injectTracingHeader)
XCTAssertNil(service.options.requestsDataSource)
}

func test_addUrlSessionCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a URLSessionCaptureService
let options = URLSessionCaptureService.Options(injectTracingHeader: false, requestsDataSource: nil)
builder.add(.urlSession(options: options))

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
let service = list[0] as! URLSessionCaptureService
XCTAssertFalse(service.options.injectTracingHeader)
XCTAssertNil(service.options.requestsDataSource)
}

func test_addTapCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a TapCaptureService
builder.add(.tap())

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
XCTAssertNotNil(list.first(where: { $0 is TapCaptureService }))
}

func test_addViewCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a ViewCaptureService
builder.add(.view())

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
XCTAssertNotNil(list.first(where: { $0 is ViewCaptureService }))
}

func test_addWebViewCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a WebViewCaptureService
let options = WebViewCaptureService.Options(stripQueryParams: true)
builder.add(.webView(options: options))

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
let service = list[0] as! WebViewCaptureService
XCTAssert(service.options.stripQueryParams)
}

func test_addLowMemoryWarningCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a LowMemoryWarningCaptureService
builder.add(.lowMemoryWarning())

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
XCTAssertNotNil(list.first(where: { $0 is LowMemoryWarningCaptureService }))
}

func test_addLowPowerModeCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a LowPowerModeCaptureService
builder.add(.lowPowerMode())

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
XCTAssertNotNil(list.first(where: { $0 is LowPowerModeCaptureService }))
}

func test_addPushNotificationCaptureService() throws {
// given a builder
let builder = CaptureServiceBuilder()

// when adding a PushNotificationCaptureService
let options = PushNotificationCaptureService.Options(captureData: true)
builder.add(.pushNotification(options: options))

// then the list contains the capture service
let list = builder.build()

XCTAssertEqual(list.count, 1)
let service = list[0] as! PushNotificationCaptureService
XCTAssert(service.options.captureData)
}
}

// swiftlint:enable force_cast
Loading

0 comments on commit 1d1c86e

Please sign in to comment.