   }
 
   // MARK: - Tests
+  func testOpenRelayMethodReturnsTCPListenerPort() {
+    // Expectations
+    var TCPPortIsReturned: XCTestExpectation?
+
+    // Given
+    let relay = BrowserRelay(with: nonTCPSession,
+                             createVirtualSocketTimeout: streamReceivedTimeout)
+
+    // When
+    TCPPortIsReturned = expectationWithDescription("TCP port is returned")
+    relay.openRelay {
+      port, error in
+      XCTAssertNil(error, "Error during opening relay")
+      XCTAssertNotNil(port, "Listener port should not be nil")
+      TCPPortIsReturned?.fulfill()
+    }
+
+    // Then
+    waitForExpectationsWithTimeout(openRelayTimeout) {
+      error in
+      TCPPortIsReturned = nil
+    }
+  }
+
+  func testClientCanConnectToPortReturnedByRelay() {
+    // Expectations
+    var TCPPortIsReturned: XCTestExpectation?
+    var сlientConnectedToListenerPort: XCTestExpectation?
+
+    // Given
+    // Open
+    TCPPortIsReturned = expectationWithDescription("TCP port is returned")
+    var listenerPort: UInt16 = 0
+    let relay = BrowserRelay(with: nonTCPSession, createVirtualSocketTimeout: streamReceivedTimeout)
+
+    relay.openRelay {
+      port, error in
+      XCTAssertNil(error)
+
+      guard let port = port else {
+        XCTFail("Listener port should not be nil")
+        return
+      }
+
+      listenerPort = port
+      TCPPortIsReturned?.fulfill()
+    }
+
+    waitForExpectationsWithTimeout(streamReceivedTimeout) {
+      error in
+      TCPPortIsReturned = nil
+    }
+
+    // When
+    // Mock client trying to connect to the port returned by Relay
+    сlientConnectedToListenerPort =
+      expectationWithDescription("Mock client is connected to listener port")
+    let clientMock = TCPClientMock(didReadData: unexpectedReadDataHandler,
+                                   didConnect: {
+                                     сlientConnectedToListenerPort?.fulfill()
+                                   },
+                                   didDisconnect: unexpectedDisconnectHandler)
+    clientMock.connectToLocalHost(on: listenerPort, errorHandler: unexpectedErrorHandler)
+
+    // Then
+    waitForExpectationsWithTimeout(clientConnectTimeout) {
+      error in
+      сlientConnectedToListenerPort = nil
+    }
+  }
+
+  func testCloseRelayMethodOnBrowserClosesTCPListenerPort() {
+    // Expectations
+    var TCPPortIsReturned: XCTestExpectation?
+    var clientCantConnectToListener: XCTestExpectation?
+
+    // Given
+    // Open relay and get listener port
+    TCPPortIsReturned = expectationWithDescription("TCP port is returned")
+
+    var listenerPort: UInt16 = 0
+    let relay = BrowserRelay(with: nonTCPSession,
+                             createVirtualSocketTimeout: streamReceivedTimeout)
+    relay.openRelay {
+      port, error in
+      XCTAssertNil(error)
+
+      guard let port = port else {
+        XCTFail("Listener port should not be nil")
+        return
+      }
+
+      listenerPort = port
+      TCPPortIsReturned?.fulfill()
+    }
+
+    waitForExpectationsWithTimeout(openRelayTimeout) {
+      error in
+      TCPPortIsReturned = nil
+    }
+
+    // When
+    // Close relay and trying to connect to the listener port
+    clientCantConnectToListener =
+      expectationWithDescription("Mock client can't connect to listener port")
+    relay.closeRelay()
+
+    let clientMock = TCPClientMock(didReadData: unexpectedReadDataHandler,
+                                   didConnect: {},
+                                   didDisconnect: {
+                                     clientCantConnectToListener?.fulfill()
+                                   })
+
+    clientMock.connectToLocalHost(on: listenerPort, errorHandler: unexpectedErrorHandler)
+
+    // Then
+    waitForExpectationsWithTimeout(clientDisconnectTimeout) {
+      error in
+      clientCantConnectToListener = nil
+    }
+  }
+
   func testMoveDataThrouhgRelayFromAdvertiserToBrowserUsingTCP() {
     // Expectations
     var browserNodeClientReceivedMessage: XCTestExpectation?

    // Cleanup
    advertiserManager.stopAdvertising()
  }

  func testOpenRelayMethodReturnsTCPListenerPort() {
    // Expectations
    var TCPPortIsReturned: XCTestExpectation?

    // Given
    let relay = BrowserRelay(with: nonTCPSession,
                             createVirtualSocketTimeout: streamReceivedTimeout)

    // When
    TCPPortIsReturned = expectationWithDescription("TCP port is returned")
    relay.openRelay {
      port, error in
      XCTAssertNil(error, "Error during opening relay")
      XCTAssertNotNil(port, "Listener port should not be nil")
      TCPPortIsReturned?.fulfill()
    }

    // Then
    waitForExpectationsWithTimeout(openRelayTimeout) {
      error in
      TCPPortIsReturned = nil
    }
  }

  func testClientCanConnectToPortReturnedByRelay() {
    // Expectations
    var TCPPortIsReturned: XCTestExpectation?
    var сlientConnectedToListenerPort: XCTestExpectation?

    // Given
    // Open
    TCPPortIsReturned = expectationWithDescription("TCP port is returned")
    var listenerPort: UInt16 = 0
    let relay = BrowserRelay(with: nonTCPSession, createVirtualSocketTimeout: streamReceivedTimeout)

    relay.openRelay {
      port, error in
      XCTAssertNil(error)

      guard let port = port else {
        XCTFail("Listener port should not be nil")
        return
      }

      listenerPort = port
      TCPPortIsReturned?.fulfill()
    }

    waitForExpectationsWithTimeout(streamReceivedTimeout) {
      error in
      TCPPortIsReturned = nil
    }

    // When
    // Mock client trying to connect to the port returned by Relay
    сlientConnectedToListenerPort =
      expectationWithDescription("Mock client is connected to listener port")
    let clientMock = TCPClientMock(didReadData: unexpectedReadDataHandler,
                                   didConnect: {
                                     сlientConnectedToListenerPort?.fulfill()
                                   },
                                   didDisconnect: unexpectedDisconnectHandler)
    clientMock.connectToLocalHost(on: listenerPort, errorHandler: unexpectedErrorHandler)

    // Then
    waitForExpectationsWithTimeout(clientConnectTimeout) {
      error in
      сlientConnectedToListenerPort = nil
    }
  }

  func testCloseRelayMethodOnBrowserClosesTCPListenerPort() {
    // Expectations
    var TCPPortIsReturned: XCTestExpectation?
    var clientCantConnectToListener: XCTestExpectation?

    // Given
    // Open relay and get listener port
    TCPPortIsReturned = expectationWithDescription("TCP port is returned")

    var listenerPort: UInt16 = 0
    let relay = BrowserRelay(with: nonTCPSession,
                             createVirtualSocketTimeout: streamReceivedTimeout)
    relay.openRelay {
      port, error in
      XCTAssertNil(error)

      guard let port = port else {
        XCTFail("Listener port should not be nil")
        return
      }

      listenerPort = port
      TCPPortIsReturned?.fulfill()
    }

    waitForExpectationsWithTimeout(openRelayTimeout) {
      error in
      TCPPortIsReturned = nil
    }

    // When
    // Close relay and trying to connect to the listener port
    clientCantConnectToListener =
      expectationWithDescription("Mock client can't connect to listener port")
    relay.closeRelay()

    let clientMock = TCPClientMock(didReadData: unexpectedReadDataHandler,
                                   didConnect: {},
                                   didDisconnect: {
                                     clientCantConnectToListener?.fulfill()
                                   })

    clientMock.connectToLocalHost(on: listenerPort, errorHandler: unexpectedErrorHandler)

    // Then
    waitForExpectationsWithTimeout(clientDisconnectTimeout) {
      error in
      clientCantConnectToListener = nil
    }
  }
}


    // Connect to browser's native TCP listener port
    let browserNodeClientMock = TCPClientMock(didReadData: {
                                                [weak self] data in
                                                guard let strongSelf = self else { return }

                                                let receivedMessage = String(
                                                  data: data,
                                                  encoding: NSUTF8StringEncoding
                                                )

                                                XCTAssertEqual(strongSelf.randomMessage,
                                                               receivedMessage,
                                                               "Received message is wrong")

                                                browserNodeClientReceivedMessage?.fulfill()
                                              },
                                              didConnect: {},
                                              didDisconnect: unexpectedDisconnectHandler)

