blob: 799974fb7c04f790bb644d4dfa08d3f00624fcc6 [file] [log] [blame]
/*
*
* Copyright (c) 2023 Project CHIP Authors
*
* 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
*
* http://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.
*/
#import <Matter/Matter.h>
#import <XCTest/XCTest.h>
@interface MTRDataValueParserTests : XCTestCase
@end
@implementation MTRDataValueParserTests
- (void)setUp
{
// Per-test setup, runs before each test.
[super setUp];
[self setContinueAfterFailure:NO];
}
- (void)test001_UnsignedIntAttribute
{
// Pressure Measurement, Tolerance
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0403) attributeID:@(3)],
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(5));
XCTAssertNil(report.error);
}
- (void)test002_SignedIntAttribute
{
// Pressure Measurement, MeasuredValue
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0403) attributeID:@(2)],
MTRDataKey : @ {
MTRTypeKey : MTRSignedIntegerValueType,
MTRValueKey : @(7),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(7));
XCTAssertNil(report.error);
}
- (void)test003_BooleanAttribute
{
// On/Off, OnOff
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0006) attributeID:@(0)],
MTRDataKey : @ {
MTRTypeKey : MTRBooleanValueType,
MTRValueKey : @(YES),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(YES));
XCTAssertNil(report.error);
}
- (void)test004_StringAttribute
{
// Basic Information, SerialNumber
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0028) attributeID:@(0xf)],
MTRDataKey : @ {
MTRTypeKey : MTRUTF8StringValueType,
MTRValueKey : @"hello",
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @"hello");
XCTAssertNil(report.error);
}
- (void)test005_OctetStringAttribute
{
// Thread Network Diagnostics, ChannelPage0Mask
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(5) clusterID:@(0x0035) attributeID:@(0x3c)],
MTRDataKey : @ {
MTRTypeKey : MTROctetStringValueType,
MTRValueKey : [@"binary" dataUsingEncoding:NSUTF8StringEncoding],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, [@"binary" dataUsingEncoding:NSUTF8StringEncoding]);
XCTAssertNil(report.error);
}
- (void)test006_NullableOctetStringAttribute
{
// Thread Network Diagnostics, ChannelPage0Mask
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(5) clusterID:@(0x0035) attributeID:@(0x3c)],
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNil(report.value);
XCTAssertNil(report.error);
}
- (void)test007_FloatAttribute
{
// Media Playback, PlaybackSpeed
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0x0506) attributeID:@(4)],
MTRDataKey : @ {
MTRTypeKey : MTRFloatValueType,
MTRValueKey : @(1.5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(1.5));
XCTAssertNil(report.error);
}
- (void)test008_DoubleAttribute
{
// Unit Testing, float_double
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0xFFF1FC05) attributeID:@(0x18)],
MTRDataKey : @ {
MTRTypeKey : MTRDoubleValueType,
MTRValueKey : @(1.5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(1.5));
XCTAssertNil(report.error);
}
- (void)test009_NullableDoubleAttribute
{
// Unit Testing, nullable_float_double
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0xFFF1FC05) attributeID:@(0x4018)],
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNil(report.value);
XCTAssertNil(report.error);
}
- (void)test010_StructAttribute
{
// Basic Information, CapabilityMinima
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0028) attributeID:@(0x0013)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // CaseSessionsPerFabric
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(4),
},
},
@{
MTRContextTagKey : @(1), // SubscriptionsPerFabric
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(3),
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[MTRBasicInformationClusterCapabilityMinimaStruct class]]);
MTRBasicInformationClusterCapabilityMinimaStruct * data = report.value;
XCTAssertEqualObjects(data.caseSessionsPerFabric, @(4));
XCTAssertEqualObjects(data.subscriptionsPerFabric, @(3));
XCTAssertNil(report.error);
}
- (void)test011_StructAttributeOtherOrder
{
// Basic Information, CapabilityMinima
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0028) attributeID:@(0x0013)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // SubscriptionsPerFabric
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(3),
},
},
@{
MTRContextTagKey : @(0), // CaseSessionsPerFabric
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(4),
},
},
]
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[MTRBasicInformationClusterCapabilityMinimaStruct class]]);
MTRBasicInformationClusterCapabilityMinimaStruct * data = report.value;
XCTAssertEqualObjects(data.caseSessionsPerFabric, @(4));
XCTAssertEqualObjects(data.subscriptionsPerFabric, @(3));
XCTAssertNil(report.error);
}
- (void)test012_ListAttribute
{
// Descriptor, DeviceTypeList
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x001d) attributeID:@(0)],
MTRDataKey : @ {
MTRTypeKey : MTRArrayValueType,
MTRValueKey : @[
@{
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // DeviceType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(100),
},
},
@{
MTRContextTagKey : @(1), // Revision
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(17),
},
},
],
},
},
@{
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // Revision
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(19),
},
},
@{
MTRContextTagKey : @(0), // DeviceType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(200),
},
},
],
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[NSArray class]]);
NSArray * array = report.value;
XCTAssertTrue([array[0] isKindOfClass:[MTRDescriptorClusterDeviceTypeStruct class]]);
MTRDescriptorClusterDeviceTypeStruct * deviceType = array[0];
XCTAssertEqualObjects(deviceType.deviceType, @(100));
XCTAssertEqualObjects(deviceType.revision, @(17));
XCTAssertTrue([array[1] isKindOfClass:[MTRDescriptorClusterDeviceTypeStruct class]]);
deviceType = array[1];
XCTAssertEqualObjects(deviceType.deviceType, @(200));
XCTAssertEqualObjects(deviceType.revision, @(19));
XCTAssertNil(report.error);
}
- (void)test013_UnsignedIntAttributeSignMismatch
{
// Pressure Measurement, Tolerance
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0403) attributeID:@(3)],
MTRDataKey : @ {
MTRTypeKey : MTRSignedIntegerValueType,
MTRValueKey : @(5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test014_SignedIntAttributeSignMismatch
{
// Pressure Measurement, MeasuredValue
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0403) attributeID:@(2)],
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(7),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test015_UnknownAttribute
{
// On/Off, nonexistent attribute
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(7) attributeID:@(0x1000)],
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(7),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeUnknownSchema);
}
- (void)test016_UnknownCluster
{
// Unknown cluster.
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0xFFF1FFF1) attributeID:@(0)],
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(7),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeUnknownSchema);
}
- (void)test017_StringVsOctetStringMismatch
{
// Basic Information, SerialNumber
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0028) attributeID:@(0xf)],
MTRDataKey : @ {
MTRTypeKey : MTROctetStringValueType,
MTRValueKey : [@"binary" dataUsingEncoding:NSUTF8StringEncoding],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test018_OctetStringVsStringMismatch
{
// Thread Network Diagnostics, ChannelPage0Mask
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(5) clusterID:@(0x0035) attributeID:@(0x3c)],
MTRDataKey : @ {
MTRTypeKey : MTRUTF8StringValueType,
MTRValueKey : @"hello",
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test019_DoubleVsFloatMismatch
{
// Unit Testing, float_double
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0xFFF1FC05) attributeID:@(0x18)],
MTRDataKey : @ {
MTRTypeKey : MTRFloatValueType,
MTRValueKey : @(1.5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
// If float was encoded, decoding as double is allowed.
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertEqualObjects(report.value, @(1.5));
XCTAssertNil(report.error);
}
- (void)test020_FloatVsDoubleMismatch
{
// Media Playback, PlaybackSpeed
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0x0506) attributeID:@(4)],
MTRDataKey : @ {
MTRTypeKey : MTRDoubleValueType,
MTRValueKey : @(1.5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test021_StringVsNullMismatch
{
// Basic Information, SerialNumber
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0028) attributeID:@(0xf)],
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test022_OctetStringVsNullMismatch
{
// Unit Testing, octet_string
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0xFFF1FC05) attributeID:@(0x19)],
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test023_DoubleVsNullMismatch
{
// Unit Testing, float_double
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(17) clusterID:@(0xFFF1FC05) attributeID:@(0x18)],
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test024_StructFieldIntegerTypeMismatch
{
// Descriptor, DeviceTypeList
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x001d) attributeID:@(0)],
MTRDataKey : @ {
MTRTypeKey : MTRArrayValueType,
MTRValueKey : @[
@{
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // DeviceType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(100),
},
},
@{
MTRContextTagKey : @(1), // Revision
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(17),
},
},
],
},
},
@{
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // Revision
MTRDataKey : @ {
MTRTypeKey : MTRSignedIntegerValueType, // Wrong type here.
MTRValueKey : @(19),
},
},
@{
MTRContextTagKey : @(0), // DeviceType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(200),
},
},
],
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test025_EventPayloadWithSystemUptime
{
// Access Control, AccessControlExtensionChanged
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0x001F) eventID:@(1)],
MTREventNumberKey : @(180),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeSystemUpTime),
MTREventSystemUpTimeKey : @(27.5),
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // AdminNodeID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(177),
},
},
@{
MTRContextTagKey : @(2), // AdminPasscodeID
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
},
@{
MTRContextTagKey : @(3), // ChangeType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(MTRAccessControlChangeTypeAdded),
},
},
@{
MTRContextTagKey : @(4), // LatestValue
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // Data
MTRDataKey : @ {
MTRTypeKey : MTROctetStringValueType,
MTRValueKey : [@"extension" dataUsingEncoding:NSUTF8StringEncoding],
},
},
],
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertNotNil(report.path);
XCTAssertEqualObjects(report.path.endpoint, @(0));
XCTAssertEqualObjects(report.path.cluster, @(0x001F));
XCTAssertEqualObjects(report.path.event, @(1));
XCTAssertEqualObjects(report.eventNumber, @(180));
XCTAssertEqualObjects(report.priority, @(MTREventPriorityInfo));
XCTAssertEqual(report.eventTimeType, MTREventTimeTypeSystemUpTime);
XCTAssertEqual(report.systemUpTime, 27.5);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[MTRAccessControlClusterAccessControlExtensionChangedEvent class]]);
MTRAccessControlClusterAccessControlExtensionChangedEvent * payload = report.value;
XCTAssertEqualObjects(payload.adminNodeID, @(177));
XCTAssertNil(payload.adminPasscodeID);
XCTAssertEqualObjects(payload.changeType, @(MTRAccessControlChangeTypeAdded));
XCTAssertNotNil(payload.latestValue);
XCTAssertTrue([payload.latestValue isKindOfClass:[MTRAccessControlClusterAccessControlExtensionStruct class]]);
XCTAssertEqualObjects(payload.latestValue.data, [@"extension" dataUsingEncoding:NSUTF8StringEncoding]);
XCTAssertNil(report.error);
}
- (void)test026_EventReportWithTimestampDate
{
// Basic Information, Shutdown
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0x0028) eventID:@(1)],
MTREventNumberKey : @(190),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate),
MTREventTimestampDateKey : [NSDate date],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertNotNil(report.path);
XCTAssertEqualObjects(report.path.endpoint, @(0));
XCTAssertEqualObjects(report.path.cluster, @(0x0028));
XCTAssertEqualObjects(report.path.event, @(1));
XCTAssertEqualObjects(report.eventNumber, @(190));
XCTAssertEqualObjects(report.priority, @(MTREventPriorityInfo));
XCTAssertEqual(report.eventTimeType, MTREventTimeTypeTimestampDate);
XCTAssertEqualObjects(report.timestampDate, input[MTREventTimestampDateKey]);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[MTRBasicInformationClusterShutDownEvent class]]);
}
- (void)test027_AttributeWithDataAndError
{
// Pressure Measurement, Tolerance
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x0403) attributeID:@(3)],
MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeTimeout userInfo:nil],
// Include data too, which should be ignored.
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(5),
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNil(report.value);
XCTAssertEqualObjects(report.error, input[MTRErrorKey]);
}
- (void)test028_EventReportWithDataAndError
{
// Basic Information, Shutdown
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0x0028) eventID:@(1)],
MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeTimeout userInfo:nil],
// All the other keys should be ignored
MTREventNumberKey : @(190),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate),
MTREventTimestampDateKey : [NSDate date],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertNotNil(report.path);
XCTAssertEqualObjects(report.path.endpoint, @(0));
XCTAssertEqualObjects(report.path.cluster, @(0x0028));
XCTAssertEqualObjects(report.path.event, @(1));
XCTAssertEqualObjects(report.eventNumber, @(0));
XCTAssertEqualObjects(report.priority, @(0));
XCTAssertNil(report.value);
XCTAssertEqualObjects(report.error, input[MTRErrorKey]);
}
- (void)test029_EventPayloadFailingSchemaCheck
{
// Access Control, AccessControlExtensionChanged
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0x001F) eventID:@(1)],
MTREventNumberKey : @(180),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeSystemUpTime),
MTREventSystemUpTimeKey : @(27.5),
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // AdminNodeID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(177),
},
},
@{
MTRContextTagKey : @(2), // AdminPasscodeID
MTRDataKey : @ {
MTRTypeKey : MTRNullValueType,
},
},
@{
MTRContextTagKey : @(3), // ChangeType
MTRDataKey : @ {
MTRTypeKey : MTRSignedIntegerValueType, // Should be unsigned
MTRValueKey : @(MTRAccessControlChangeTypeAdded),
},
},
@{
MTRContextTagKey : @(4), // LatestValue
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(1), // Data
MTRDataKey : @ {
MTRTypeKey : MTROctetStringValueType,
MTRValueKey : [@"extension" dataUsingEncoding:NSUTF8StringEncoding],
},
},
],
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test030_EventReportWithUnknownCluster
{
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0xFF1FF1) eventID:@(0)],
MTREventNumberKey : @(190),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate),
MTREventTimestampDateKey : [NSDate date],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeUnknownSchema);
}
- (void)test031_EventReportWithUnknownEvent
{
NSDictionary * input = @{
MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(0x0028) eventID:@(1000)],
MTREventNumberKey : @(190),
MTREventPriorityKey : @(MTREventPriorityInfo),
MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate),
MTREventTimestampDateKey : [NSDate date],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[],
},
};
NSError * error;
__auto_type * report = [[MTREventReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(report);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeUnknownSchema);
}
- (void)test032_VeryLongListAttribute
{
NSDictionary * singleListItem = @{
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // DeviceType
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(100),
},
},
@{
MTRContextTagKey : @(1), // Revision
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(17),
},
},
],
},
};
NSUInteger arrayLength = 1000;
NSMutableArray * inputArray = [[NSMutableArray alloc] initWithCapacity:arrayLength];
for (NSUInteger i = 0; i < arrayLength; ++i) {
[inputArray addObject:singleListItem];
}
// Descriptor, DeviceTypeList
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(0x001d) attributeID:@(0)],
MTRDataKey : @ {
MTRTypeKey : MTRArrayValueType,
MTRValueKey : inputArray,
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNil(error);
XCTAssertNotNil(report);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[NSArray class]]);
NSArray * array = report.value;
XCTAssertTrue(array.count == inputArray.count);
for (id item in array) {
XCTAssertTrue([item isKindOfClass:[MTRDescriptorClusterDeviceTypeStruct class]]);
MTRDescriptorClusterDeviceTypeStruct * deviceType = item;
XCTAssertEqualObjects(deviceType.deviceType, @(100));
XCTAssertEqualObjects(deviceType.revision, @(17));
}
XCTAssertNil(report.error);
}
- (void)test033_CommandResponse
{
NSDictionary * input = @{
MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0)
clusterID:@(MTRClusterIDTypeGroupsID)
commandID:@(MTRCommandIDTypeClusterGroupsCommandAddGroupResponseID)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // Status
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(1),
},
},
@{
MTRContextTagKey : @(1), // GroupID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(0x176),
},
},
],
},
};
NSError * error;
__auto_type * payload = [[MTRGroupsClusterAddGroupResponseParams alloc] initWithResponseValue:input error:&error];
XCTAssertNil(error);
XCTAssertNotNil(payload);
XCTAssertEqualObjects(payload.status, @(1));
XCTAssertEqualObjects(payload.groupID, @(0x176));
}
- (void)test034_CommandResponseWrongCommandID
{
NSDictionary * input = @{
MTRCommandPathKey :
[MTRCommandPath commandPathWithEndpointID:@(0)
clusterID:@(MTRClusterIDTypeGroupsID)
commandID:@(MTRCommandIDTypeClusterGroupsCommandGetGroupMembershipResponseID)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // Status
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(1),
},
},
@{
MTRContextTagKey : @(1), // GroupID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(0x176),
},
},
],
},
};
NSError * error;
__auto_type * payload = [[MTRGroupsClusterAddGroupResponseParams alloc] initWithResponseValue:input error:&error];
XCTAssertNil(payload);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test035_CommandResponseWrongClusterID
{
NSDictionary * input = @{
MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0)
clusterID:@(MTRClusterIDTypeOnOffID)
commandID:@(MTRCommandIDTypeClusterGroupsCommandAddGroupResponseID)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // Status
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(1),
},
},
@{
MTRContextTagKey : @(1), // GroupID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(0x176),
},
},
],
},
};
NSError * error;
__auto_type * payload = [[MTRGroupsClusterAddGroupResponseParams alloc] initWithResponseValue:input error:&error];
XCTAssertNil(payload);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)test036_CommandResponseWrongData
{
NSDictionary * input = @{
MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0)
clusterID:@(MTRClusterIDTypeGroupsID)
commandID:@(MTRCommandIDTypeClusterGroupsCommandAddGroupResponseID)],
MTRDataKey : @ {
MTRTypeKey : MTRStructureValueType,
MTRValueKey : @[
@{
MTRContextTagKey : @(0), // Status
MTRDataKey : @ {
MTRTypeKey : MTRSignedIntegerValueType, // Wrong data type
MTRValueKey : @(1),
},
},
@{
MTRContextTagKey : @(1), // GroupID
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(0x176),
},
},
],
},
};
NSError * error;
__auto_type * payload = [[MTRGroupsClusterAddGroupResponseParams alloc] initWithResponseValue:input error:&error];
XCTAssertNil(payload);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, MTRErrorCodeSchemaMismatch);
}
- (void)globalListAttributeHelper:(NSNumber *)clusterID
{
// clusterID, AcceptedCommandList
NSDictionary * input = @{
MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:clusterID attributeID:@(0xFFF9)],
MTRDataKey : @ {
MTRTypeKey : MTRArrayValueType,
MTRValueKey : @[
@{
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(5),
},
},
@{
MTRDataKey : @ {
MTRTypeKey : MTRUnsignedIntegerValueType,
MTRValueKey : @(8),
},
},
],
},
};
NSError * error;
__auto_type * report = [[MTRAttributeReport alloc] initWithResponseValue:input error:&error];
XCTAssertNotNil(report);
XCTAssertNil(error);
XCTAssertEqualObjects(input[MTRAttributePathKey], report.path);
XCTAssertNotNil(report.value);
XCTAssertTrue([report.value isKindOfClass:[NSArray class]]);
NSArray * array = report.value;
XCTAssertTrue([array[0] isKindOfClass:[NSNumber class]]);
XCTAssertEqualObjects(array[0], @(5));
XCTAssertTrue([array[1] isKindOfClass:[NSNumber class]]);
XCTAssertEqualObjects(array[1], @(8));
XCTAssertNil(report.error);
}
- (void)test037_GlobalListAttributeStandardCluster
{
// OnOff cluster.
[self globalListAttributeHelper:@(0x0006)];
}
- (void)test037_GlobalListAttributeManufacturerSpecific
{
// Manufacturer specific cluster IDs start at 0xFC00.
[self globalListAttributeHelper:@(0xFFF4FD01)];
}
@end