mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
[NC Apple coverage] Add tests for nearby::apple::GattClient.
PiperOrigin-RevId: 826566302
This commit is contained in:
committed by
Copybara-Service
parent
ca1ab209b7
commit
3cdee32f14
@@ -38,6 +38,7 @@ objc_library(
|
||||
"GNCWifiHotspotMediumTest.mm",
|
||||
"GNCWifiLanMediumTest.mm",
|
||||
"UtilsTest.mm",
|
||||
"ble_gatt_client_test.mm",
|
||||
"ble_gatt_server_test.mm",
|
||||
"ble_l2cap_server_socket_test.mm",
|
||||
"ble_l2cap_socket_test.mm",
|
||||
@@ -48,6 +49,8 @@ objc_library(
|
||||
"network_utils_test.mm",
|
||||
],
|
||||
deps = [
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:cancellation_flag",
|
||||
"//internal/platform/implementation:comm",
|
||||
@@ -57,6 +60,7 @@ objc_library(
|
||||
"//internal/platform/implementation/apple:Shared",
|
||||
"//internal/platform/implementation/apple:ble_v2",
|
||||
"//internal/platform/implementation/apple:network_utils",
|
||||
"//internal/platform/implementation/apple/Flags",
|
||||
"//internal/platform/implementation/apple/Mediums/BLE",
|
||||
"//internal/platform/implementation/apple/Mediums/BLE/Tests:BLETestsLib",
|
||||
"//internal/platform/implementation/apple/Mediums/CoreLocation/CLLocationManager/Fake",
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/apple/ble_gatt_client.h"
|
||||
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/implementation/ble.h"
|
||||
#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTCharacteristic.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEGATTClient.h"
|
||||
#import "internal/platform/implementation/apple/ble_utils.h"
|
||||
|
||||
/**
|
||||
* Fake implementation for GNCBLEGATTClient.
|
||||
* TODO: b/434870979 - Move GNCFakeGNCBLEGATTClient to a separate file so it can be used by other
|
||||
* tests.
|
||||
*/
|
||||
@interface GNCFakeGNCBLEGATTClient : NSObject
|
||||
|
||||
/**
|
||||
* The characteristic to return when `characteristicWithUUID:serviceUUID:completionHandler:` is
|
||||
* called.
|
||||
*/
|
||||
|
||||
@property(nonatomic) GNCBLEGATTCharacteristic *characteristicToReturn;
|
||||
/**
|
||||
* The value to return when `readValueForCharacteristic:completionHandler:` is called.
|
||||
*/
|
||||
|
||||
@property(nonatomic) NSData *valueToReturn;
|
||||
/**
|
||||
* The error to return through completion handlers if not nil.
|
||||
*/
|
||||
|
||||
@property(nonatomic) NSError *errorToReturn;
|
||||
|
||||
/** Tracks if disconnect has been called. */
|
||||
@property(nonatomic) BOOL disconnectCalled;
|
||||
|
||||
@end
|
||||
|
||||
@implementation GNCFakeGNCBLEGATTClient
|
||||
|
||||
- (void)discoverCharacteristicsWithUUIDs:(NSArray<CBUUID *> *)characteristicUUIDs
|
||||
serviceUUID:(CBUUID *)serviceUUID
|
||||
completionHandler:
|
||||
(nullable GNCDiscoverCharacteristicsCompletionHandler)completionHandler {
|
||||
if (completionHandler) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completionHandler(_errorToReturn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)characteristicWithUUID:(CBUUID *)characteristicUUID
|
||||
serviceUUID:(CBUUID *)serviceUUID
|
||||
completionHandler:(nullable GNCGetCharacteristicCompletionHandler)completionHandler {
|
||||
if (completionHandler) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completionHandler(_errorToReturn ? nil : _characteristicToReturn, _errorToReturn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)readValueForCharacteristic:(GNCBLEGATTCharacteristic *)characteristic
|
||||
completionHandler:
|
||||
(nullable GNCReadCharacteristicValueCompletionHandler)completionHandler {
|
||||
if (completionHandler) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
completionHandler(_errorToReturn ? nil : _valueToReturn, _errorToReturn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)disconnect {
|
||||
_disconnectCalled = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface GNCGattClientTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCGattClientTest {
|
||||
std::unique_ptr<nearby::apple::GattClient> _gattClient;
|
||||
GNCFakeGNCBLEGATTClient *_fakeGNCBLEGATTClient;
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
_fakeGNCBLEGATTClient = [[GNCFakeGNCBLEGATTClient alloc] init];
|
||||
_gattClient =
|
||||
std::make_unique<nearby::apple::GattClient>((GNCBLEGATTClient *)_fakeGNCBLEGATTClient);
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableGattClientDisconnection,
|
||||
false);
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testDiscoverServiceAndCharacteristicsSuccess {
|
||||
nearby::Uuid serviceUUID = nearby::Uuid([[CBUUID UUIDWithString:@"FEF3"] UUIDString].UTF8String);
|
||||
nearby::Uuid characteristicUUID =
|
||||
nearby::Uuid([[CBUUID UUIDWithString:@"B2B4"] UUIDString].UTF8String);
|
||||
std::vector<nearby::Uuid> characteristicUUIDs = {characteristicUUID};
|
||||
|
||||
BOOL result = _gattClient->DiscoverServiceAndCharacteristics(serviceUUID, characteristicUUIDs);
|
||||
XCTAssertTrue(result);
|
||||
}
|
||||
|
||||
- (void)testDiscoverServiceAndCharacteristicsFailure {
|
||||
nearby::Uuid serviceUUID = nearby::Uuid([[CBUUID UUIDWithString:@"FEF3"] UUIDString].UTF8String);
|
||||
nearby::Uuid characteristicUUID =
|
||||
nearby::Uuid([[CBUUID UUIDWithString:@"B2B4"] UUIDString].UTF8String);
|
||||
std::vector<nearby::Uuid> characteristicUUIDs = {characteristicUUID};
|
||||
_fakeGNCBLEGATTClient.errorToReturn = [NSError errorWithDomain:@"test" code:1 userInfo:nil];
|
||||
|
||||
BOOL result = _gattClient->DiscoverServiceAndCharacteristics(serviceUUID, characteristicUUIDs);
|
||||
XCTAssertFalse(result);
|
||||
}
|
||||
|
||||
- (void)testGetCharacteristicSuccess {
|
||||
nearby::Uuid serviceUUID = nearby::Uuid([[CBUUID UUIDWithString:@"FEF3"] UUIDString].UTF8String);
|
||||
nearby::Uuid characteristicUUID =
|
||||
nearby::Uuid([[CBUUID UUIDWithString:@"B2B4"] UUIDString].UTF8String);
|
||||
GNCBLEGATTCharacteristic *characteristic =
|
||||
[[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"]
|
||||
serviceUUID:[CBUUID UUIDWithString:@"FEF3"]
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyRead];
|
||||
_fakeGNCBLEGATTClient.characteristicToReturn = characteristic;
|
||||
|
||||
std::optional<nearby::api::ble::GattCharacteristic> result =
|
||||
_gattClient->GetCharacteristic(serviceUUID, characteristicUUID);
|
||||
XCTAssertTrue(result.has_value());
|
||||
}
|
||||
|
||||
- (void)testGetCharacteristicFailure {
|
||||
nearby::Uuid serviceUUID = nearby::Uuid([[CBUUID UUIDWithString:@"FEF3"] UUIDString].UTF8String);
|
||||
nearby::Uuid characteristicUUID =
|
||||
nearby::Uuid([[CBUUID UUIDWithString:@"B2B4"] UUIDString].UTF8String);
|
||||
_fakeGNCBLEGATTClient.errorToReturn = [NSError errorWithDomain:@"test" code:1 userInfo:nil];
|
||||
|
||||
std::optional<nearby::api::ble::GattCharacteristic> result =
|
||||
_gattClient->GetCharacteristic(serviceUUID, characteristicUUID);
|
||||
XCTAssertFalse(result.has_value());
|
||||
}
|
||||
|
||||
- (void)testReadCharacteristicSuccess {
|
||||
_fakeGNCBLEGATTClient.valueToReturn = [@"test" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
GNCBLEGATTCharacteristic *characteristic =
|
||||
[[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"]
|
||||
serviceUUID:[CBUUID UUIDWithString:@"FEF3"]
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyRead];
|
||||
nearby::api::ble::GattCharacteristic cppCharacteristic =
|
||||
nearby::apple::CPPGATTCharacteristicFromObjC(characteristic);
|
||||
|
||||
std::optional<std::string> result = _gattClient->ReadCharacteristic(cppCharacteristic);
|
||||
XCTAssertTrue(result.has_value());
|
||||
XCTAssertEqual(result.value(), "test");
|
||||
}
|
||||
|
||||
- (void)testReadCharacteristicFailure {
|
||||
_fakeGNCBLEGATTClient.errorToReturn = [NSError errorWithDomain:@"test" code:1 userInfo:nil];
|
||||
GNCBLEGATTCharacteristic *characteristic =
|
||||
[[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"]
|
||||
serviceUUID:[CBUUID UUIDWithString:@"FEF3"]
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyRead];
|
||||
nearby::api::ble::GattCharacteristic cppCharacteristic =
|
||||
nearby::apple::CPPGATTCharacteristicFromObjC(characteristic);
|
||||
|
||||
std::optional<std::string> result = _gattClient->ReadCharacteristic(cppCharacteristic);
|
||||
XCTAssertFalse(result.has_value());
|
||||
}
|
||||
|
||||
- (void)testWriteCharacteristicReturnsFalse {
|
||||
GNCBLEGATTCharacteristic *characteristic =
|
||||
[[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"]
|
||||
serviceUUID:[CBUUID UUIDWithString:@"FEF3"]
|
||||
permissions:CBAttributePermissionsWriteable
|
||||
properties:CBCharacteristicPropertyWrite];
|
||||
nearby::api::ble::GattCharacteristic cppCharacteristic =
|
||||
nearby::apple::CPPGATTCharacteristicFromObjC(characteristic);
|
||||
BOOL result = _gattClient->WriteCharacteristic(
|
||||
cppCharacteristic, "test", nearby::api::ble::GattClient::WriteType::kWithResponse);
|
||||
XCTAssertFalse(result);
|
||||
}
|
||||
|
||||
- (void)testSetCharacteristicSubscriptionReturnsFalse {
|
||||
GNCBLEGATTCharacteristic *characteristic =
|
||||
[[GNCBLEGATTCharacteristic alloc] initWithUUID:[CBUUID UUIDWithString:@"B2B4"]
|
||||
serviceUUID:[CBUUID UUIDWithString:@"FEF3"]
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyNotify];
|
||||
nearby::api::ble::GattCharacteristic cppCharacteristic =
|
||||
nearby::apple::CPPGATTCharacteristicFromObjC(characteristic);
|
||||
BOOL result = _gattClient->SetCharacteristicSubscription(cppCharacteristic, true,
|
||||
[](absl::string_view value) {});
|
||||
XCTAssertFalse(result);
|
||||
}
|
||||
|
||||
- (void)testDisconnectWhenFlagEnabled {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableGattClientDisconnection,
|
||||
YES);
|
||||
_gattClient->Disconnect();
|
||||
XCTAssertTrue(_fakeGNCBLEGATTClient.disconnectCalled);
|
||||
}
|
||||
|
||||
- (void)testDisconnectWhenFlagDisabled {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableGattClientDisconnection,
|
||||
NO);
|
||||
_gattClient->Disconnect();
|
||||
XCTAssertFalse(_fakeGNCBLEGATTClient.disconnectCalled);
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user