From eed03c71587f6e4c2071321e40441eeff3dbf2a8 Mon Sep 17 00:00:00 2001 From: Edwin Wu Date: Wed, 13 Aug 2025 09:57:44 -0700 Subject: [PATCH] [NC Apple coverage] Add more tests for GNCPlatformTest. PiperOrigin-RevId: 794624452 --- .../apple/Tests/GNCPlatformTest.mm | 259 ++++++++++++++++++ .../platform/implementation/apple/platform.mm | 2 - 2 files changed, 259 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm b/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm index 72467db7..1ab71dd2 100644 --- a/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm +++ b/internal/platform/implementation/apple/Tests/GNCPlatformTest.mm @@ -17,6 +17,77 @@ #import #import +// A custom NSURLProtocol to intercept and fake network requests for testing. +@interface GNCFakeURLProtocol : NSURLProtocol ++ (void)setFakeResponseData:(NSData *)data; ++ (void)setFakeStatusCode:(NSInteger)statusCode; ++ (void)setFakeError:(NSError *)error; ++ (void)clearFakes; +@end + +static NSData *gFakeResponseData = nil; +static NSInteger gFakeStatusCode = 0; +static NSError *gFakeError = nil; + +@implementation GNCFakeURLProtocol + ++ (void)setFakeResponseData:(NSData *)data { + gFakeResponseData = [data copy]; +} + ++ (void)setFakeStatusCode:(NSInteger)statusCode { + gFakeStatusCode = statusCode; +} + ++ (void)setFakeError:(NSError *)error { + gFakeError = [error copy]; +} + ++ (void)clearFakes { + gFakeResponseData = nil; + gFakeStatusCode = 0; + gFakeError = nil; +} + ++ (BOOL)canInitWithRequest:(NSURLRequest *)request { + // Intercept all HTTP/HTTPS requests. + return + [request.URL.scheme isEqualToString:@"http"] || [request.URL.scheme isEqualToString:@"https"]; +} + ++ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { + return request; +} + +- (void)startLoading { + id client = self.client; + NSURLRequest *request = self.request; + + if (gFakeError) { + [client URLProtocol:self didFailWithError:gFakeError]; + return; + } + + NSHTTPURLResponse *response = + [[NSHTTPURLResponse alloc] initWithURL:request.URL + statusCode:gFakeStatusCode + HTTPVersion:@"HTTP/1.1" + headerFields:@{@"Content-Type" : @"text/plain"}]; + + [client URLProtocol:self + didReceiveResponse:response + cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + if (gFakeResponseData) { + [client URLProtocol:self didLoadData:gFakeResponseData]; + } + [client URLProtocolDidFinishLoading:self]; +} + +- (void)stopLoading { + // Required to be implemented, but nothing to do. +} +@end + void GNCEnsureFileAtPath(std::string path) { [NSFileManager.defaultManager createDirectoryAtPath:[@(path.c_str()) stringByDeletingLastPathComponent] @@ -31,6 +102,57 @@ void GNCEnsureFileAtPath(std::string path) { @implementation GNCPlatformTest +- (void)setUp { + [super setUp]; + // Register the fake protocol before each test. + [NSURLProtocol registerClass:[GNCFakeURLProtocol class]]; +} + +- (void)tearDown { + // Unregister the fake protocol and clean up fake data after each test. + [NSURLProtocol unregisterClass:[GNCFakeURLProtocol class]]; + [GNCFakeURLProtocol clearFakes]; + [super tearDown]; +} + +- (void)testSendRequest_Success { + // Arrange: Set up a fake successful response. + std::string responseBody = "{\"status\": \"ok\"}"; + [GNCFakeURLProtocol setFakeResponseData:[NSData dataWithBytes:responseBody.c_str() + length:responseBody.length()]]; + [GNCFakeURLProtocol setFakeStatusCode:200]; + + nearby::api::ImplementationPlatform platform; + nearby::api::WebRequest request; + request.url = "https://example.com/api/status"; + + // Act: Call the method under test. + absl::StatusOr response = platform.SendRequest(request); + + // Assert: Verify the response is successful and contains the fake data. + XCTAssertTrue(response.ok()); + XCTAssertEqual(response->status_code, 200); + XCTAssertEqual(response->body, responseBody); +} + +- (void)testSendRequest_NetworkError { + // Arrange: Set up a fake network error. + [GNCFakeURLProtocol setFakeError:[NSError errorWithDomain:NSURLErrorDomain + code:NSURLErrorNotConnectedToInternet + userInfo:nil]]; + + nearby::api::ImplementationPlatform platform; + nearby::api::WebRequest request; + request.url = "https://example.com/api/status"; + + // Act: Call the method under test. + absl::StatusOr response = platform.SendRequest(request); + + // Assert: Verify that the call resulted in an error status. + XCTAssertFalse(response.ok()); + XCTAssertEqual(response.status().code(), absl::StatusCode::kFailedPrecondition); +} + - (void)testGetCustomSavePath { NSString *expected = [NSURL fileURLWithPath:@"a/b/c.d"].path; std::string actual = nearby::api::ImplementationPlatform::GetCustomSavePath("a/b", "c.d"); @@ -80,10 +202,147 @@ void GNCEnsureFileAtPath(std::string path) { XCTAssertEqualObjects(@(actual.c_str()), expected); } +- (void)testGetCurrentOS { + XCTAssertEqual(nearby::api::ImplementationPlatform::GetCurrentOS(), nearby::api::OSName::kApple); +} + +- (void)testCreateAtomicBoolean { + auto atomic_boolean = nearby::api::ImplementationPlatform::CreateAtomicBoolean(true); + XCTAssertNotEqual(atomic_boolean.get(), nullptr); + XCTAssertTrue(atomic_boolean->Get()); +} + +- (void)testCreateAtomicUint32 { + auto atomic_uint32 = nearby::api::ImplementationPlatform::CreateAtomicUint32(123); + XCTAssertNotEqual(atomic_uint32.get(), nullptr); + XCTAssertEqual(atomic_uint32->Get(), 123); +} + +- (void)testCreateCountDownLatch { + auto count_down_latch = nearby::api::ImplementationPlatform::CreateCountDownLatch(1); + XCTAssertNotEqual(count_down_latch.get(), nullptr); +} + +- (void)testCreateMutex { + auto mutex = nearby::api::ImplementationPlatform::CreateMutex(nearby::api::Mutex::Mode::kRegular); + XCTAssertNotEqual(mutex.get(), nullptr); +} + +- (void)testCreateConditionVariable { + auto mutex = nearby::api::ImplementationPlatform::CreateMutex(nearby::api::Mutex::Mode::kRegular); + auto condition_variable = + nearby::api::ImplementationPlatform::CreateConditionVariable(mutex.get()); + XCTAssertNotEqual(condition_variable.get(), nullptr); +} + +- (void)testCreateBluetoothAdapter { + auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter(); + XCTAssertNotEqual(bluetooth_adapter.get(), nullptr); +} + +- (void)testCreateOutputFile { + NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"test.txt"]; + + auto output_file = nearby::api::ImplementationPlatform::CreateOutputFile(path.UTF8String); + + XCTAssertNotEqual(output_file.get(), nullptr); + XCTAssertTrue([NSFileManager.defaultManager fileExistsAtPath:path]); + + [NSFileManager.defaultManager removeItemAtPath:path error:nil]; +} + +- (void)testCreateInputFile { + NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"test.txt"]; + NSData *data = [@"test data" dataUsingEncoding:NSUTF8StringEncoding]; + [data writeToFile:path atomically:YES]; + + auto input_file = + nearby::api::ImplementationPlatform::CreateInputFile(path.UTF8String, data.length); + + XCTAssertNotEqual(input_file.get(), nullptr); + XCTAssertEqual(input_file->GetTotalSize(), data.length); + XCTAssertEqualObjects(@(input_file->GetFilePath().c_str()), path); + + [NSFileManager.defaultManager removeItemAtPath:path error:nil]; +} + +- (void)testCreateWifiMedium { + auto wifi_medium = nearby::api::ImplementationPlatform::CreateWifiMedium(); + XCTAssertNotEqual(wifi_medium.get(), nullptr); +} + +- (void)testCreateWifiLanMedium { + auto wifi_lan_medium = nearby::api::ImplementationPlatform::CreateWifiLanMedium(); + XCTAssertNotEqual(wifi_lan_medium.get(), nullptr); +} + +- (void)testCreateAwdlMedium { + auto awdl_medium = nearby::api::ImplementationPlatform::CreateAwdlMedium(); + XCTAssertNotEqual(awdl_medium.get(), nullptr); +} + +- (void)testCreateWifiHotspotMedium { + auto wifi_hotspot_medium = nearby::api::ImplementationPlatform::CreateWifiHotspotMedium(); + XCTAssertNotEqual(wifi_hotspot_medium.get(), nullptr); +} + +- (void)testCreateTimer { + auto timer = nearby::api::ImplementationPlatform::CreateTimer(); + XCTAssertNotEqual(timer.get(), nullptr); +} + +- (void)testCreateDeviceInfo { + auto device_info = nearby::api::ImplementationPlatform::CreateDeviceInfo(); + XCTAssertNotEqual(device_info.get(), nullptr); +} + +- (void)testCreatePreferencesManager { + auto preferences_manager = nearby::api::ImplementationPlatform::CreatePreferencesManager("test"); + XCTAssertNotEqual(preferences_manager.get(), nullptr); +} + +- (void)testCreateBluetoothClassicMedium { + auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter(); + auto bluetooth_classic_medium = + nearby::api::ImplementationPlatform::CreateBluetoothClassicMedium(*bluetooth_adapter); + XCTAssertEqual(bluetooth_classic_medium.get(), nullptr); +} + +- (void)testCreateBleMedium { + auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter(); + auto ble_medium = nearby::api::ImplementationPlatform::CreateBleMedium(*bluetooth_adapter); + XCTAssertEqual(ble_medium.get(), nullptr); +} + - (void)testCreateBleV2Medium { auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter(); auto ble_medium = nearby::api::ImplementationPlatform::CreateBleV2Medium(*bluetooth_adapter); XCTAssertNotEqual(ble_medium.get(), nullptr); } +- (void)testCreateServerSyncMedium { + auto server_sync_medium = nearby::api::ImplementationPlatform::CreateServerSyncMedium(); + XCTAssertEqual(server_sync_medium.get(), nullptr); +} + +- (void)testCreateWifiDirectMedium { + auto wifi_direct_medium = nearby::api::ImplementationPlatform::CreateWifiDirectMedium(); + XCTAssertEqual(wifi_direct_medium.get(), nullptr); +} + +- (void)testCreateWebRtcMedium { + auto webrtc_medium = nearby::api::ImplementationPlatform::CreateWebRtcMedium(); + XCTAssertEqual(webrtc_medium.get(), nullptr); +} + +- (void)testCreateInputFileWithPayloadID { + auto input_file = nearby::api::ImplementationPlatform::CreateInputFile(1234, 0); + XCTAssertEqual(input_file.get(), nullptr); +} + +- (void)testCreateOutputFileWithPayloadID { + auto output_file = nearby::api::ImplementationPlatform::CreateOutputFile(1234); + XCTAssertEqual(output_file.get(), nullptr); +} + @end diff --git a/internal/platform/implementation/apple/platform.mm b/internal/platform/implementation/apple/platform.mm index 66a3b781..c36d73e2 100644 --- a/internal/platform/implementation/apple/platform.mm +++ b/internal/platform/implementation/apple/platform.mm @@ -258,12 +258,10 @@ std::unique_ptr ImplementationPlatform::CreateTimer() { return std::make_unique(); } -// TODO(b/261511530): Add implementation. std::unique_ptr ImplementationPlatform::CreateDeviceInfo() { return std::make_unique(); } -// TODO(b/261503919): Add implementation. std::unique_ptr ImplementationPlatform::CreatePreferencesManager( absl::string_view path) { return std::make_unique(path);