Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support supplying protocolClasses to NetworkConfiguration #887

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

markst
Copy link

@markst markst commented Apr 8, 2024

We wish to use Mocking libraries such as OHHTTPStubs or Mocker to build automated end 2 end testing solution in order to validate our Snowplow events are emitting.

Currently DefaultNetworkConnection provides an empty an array of protocolClasses to the URLSessionConfiguration
This overrides the swizzling performed by HTTPStubs.m

By adding protocolClasses property to NetworkConfiguration we enable supplying the network connection with custom protocols and prevent overriding swizzled properties during testing.

We can supply protocol classes such as:

Snowplow.createTracker() {
    NetworkConfiguration()
        .protocolClasses([CustomURLProtocol.self])

@snowplowcla snowplowcla added the cla:yes [Auto generated] Snowplow Contributor License Agreement has been signed. label Apr 8, 2024
@matus-tomlein
Copy link
Contributor

Hi @markst, thank you for the contribution, that's a useful change!

Could you please add an example test case to showcase how this could work?

@markst
Copy link
Author

markst commented Apr 9, 2024

I guess something along these lines:

import XCTest
import Mocker

class SnowplowMocker: XCTestCase {
    var snowplowTracker: TrackerController?
    
    override func setUp() {
        let endpoint = "*.collector.snplow.net"
        snowplowTracker = Snowplow.createTracker(
            namespace: "DEBUG",
            endpoint: endpoint,
            method: .post
        ) {
            NetworkConfiguration(endpoint: endpoint, method: .post)
                .protocolClasses([MockingURLProtocol.self])
        }
    }
    
    func testScreenViewEvent() {
        let exp = expectation(description: "Expect mocked response requested")
        var mock = Mock(
            url: URL(string: "https://*.collector.snplow.net/com.snowplowanalytics.snowplow/tp2")!,
            statusCode: 200,
            data: [.post:"{}".data(using: .utf8)!]
        )
        mock.onRequestHandler = OnRequestHandler(httpBodyType: [[String:String]].self, callback: { request, postBodyArguments in
            if  let body = request.httpBodyStreamData(),
                let json = try? JSONSerialization.jsonObject(with: body, options: []) {
                // TODO: Validate the body contains expected params
                XCTAssertEqual
            }
            exp.fulfill()
        })
        mock.register()
        
        let event = ScreenView(name: "DemoScreenName", screenId: UUID())
            .type("TestType")
            .entities([])
        let _ = snowplowTracker?.track(event)

        wait(for: [exp], timeout: 5)
    }
}

@matus-tomlein
Copy link
Contributor

Thanks @markst and sorry for the later reply. That example looks good, but I meant if you could please add it to the tracker tests in the PR so that we have this use case covered in CI and can detect any regression. The tracker tests already use the Mocker library so hopefully this should work just adding your snippet in.

@markst
Copy link
Author

markst commented May 17, 2024

Sorry for delay @matus-tomlein. Understood and we'll sort it soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla:yes [Auto generated] Snowplow Contributor License Agreement has been signed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants