summaryrefslogtreecommitdiff
path: root/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
diff options
context:
space:
mode:
Diffstat (limited to 'SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m')
-rw-r--r--SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m788
1 files changed, 788 insertions, 0 deletions
diff --git a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
new file mode 100644
index 000000000..410d24386
--- /dev/null
+++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
@@ -0,0 +1,788 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLAddCommand.h"
+#import "SDLAlert.h"
+#import "SDLButtonName.h"
+#import "SDLDeleteCommand.h"
+#import "SDLDeleteCommandResponse.h"
+#import "SDLNotificationConstants.h"
+#import "SDLOnAudioPassThru.h"
+#import "SDLOnButtonEvent.h"
+#import "SDLOnButtonPress.h"
+#import "SDLOnCommand.h"
+#import "SDLPerformAudioPassThru.h"
+#import "SDLPerformAudioPassThruResponse.h"
+#import "SDLReadDID.h"
+#import "SDLReadDIDResponse.h"
+#import "SDLResponseDispatcher.h"
+#import "SDLRPCNotificationNotification.h"
+#import "SDLRPCResponseNotification.h"
+#import "SDLScrollableMessage.h"
+#import "SDLShow.h"
+#import "SDLSoftButton.h"
+#import "SDLSoftButtonType.h"
+#import "SDLSubscribeButton.h"
+#import "SDLSystemAction.h"
+#import "SDLTextAlignment.h"
+#import "SDLUnsubscribeButton.h"
+#import "SDLUnsubscribeButtonResponse.h"
+
+
+QuickSpecBegin(SDLResponseDispatcherSpec)
+
+describe(@"a response dispatcher", ^{
+ __block SDLResponseDispatcher *testDispatcher = nil;
+
+ beforeEach(^{
+ testDispatcher = [[SDLResponseDispatcher alloc] init];
+ });
+
+ it(@"should initialize the NSMapTable properties", ^{
+ expect(testDispatcher.rpcResponseHandlerMap).toNot(beNil());
+ expect(testDispatcher.rpcRequestDictionary).toNot(beNil());
+ expect(testDispatcher.commandHandlerMap).toNot(beNil());
+ expect(testDispatcher.buttonHandlerMap).toNot(beNil());
+ expect(testDispatcher.customButtonHandlerMap).toNot(beNil());
+// expect(testDispatcher.audioPassThruHandler).to(beNil());
+
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0));
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.buttonHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+
+ context(@"storing a request without a handler", ^{
+ __block SDLReadDID *testRPC = nil;
+ __block NSNumber *testCorrelationId = nil;
+
+ beforeEach(^{
+ testRPC = [[SDLReadDID alloc] init];
+ testCorrelationId = @111;
+ testRPC.correlationID = testCorrelationId;
+ });
+
+ it(@"should not store the request", ^{
+ [testDispatcher storeRequest:testRPC handler:nil];
+
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1));
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.buttonHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+
+ context(@"storing a request with a handler", ^{
+ __block SDLRPCRequest *testRequest = nil;
+ __block NSNumber *testCorrelationId = nil;
+ __block BOOL handlerCalled = NO;
+
+ beforeEach(^{
+ testRequest = [[SDLReadDID alloc] init];
+ testCorrelationId = @42;
+
+ testRequest.correlationID = testCorrelationId;
+ [testDispatcher storeRequest:testRequest handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ handlerCalled = YES;
+ }];
+ });
+
+ it(@"should store the request and response", ^{
+ expect(testDispatcher.rpcRequestDictionary[testCorrelationId]).toNot(beNil());
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1));
+
+ expect(testDispatcher.rpcResponseHandlerMap[testCorrelationId]).toNot(beNil());
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1));
+ });
+
+ describe(@"when a response arrives", ^{
+ __block SDLRPCResponse *testResponse = nil;
+
+ beforeEach(^{
+ testResponse = [[SDLReadDIDResponse alloc] init];
+ testResponse.correlationID = testCorrelationId;
+
+ SDLRPCResponseNotification *responseNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveReadDIDResponse object:nil rpcResponse:testResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:responseNotification];
+ });
+
+ it(@"should run the handler", ^{
+ expect(@(handlerCalled)).to(beTruthy());
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0));
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing a show request", ^{
+ __block SDLShow *testShow = nil;
+ __block SDLSoftButton *testSoftButton1 = nil;
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ beforeEach(^{
+ testShow = [[SDLShow alloc] initWithMainField1:@"Test Show" mainField2:nil alignment:SDLTextAlignmentCenter];
+ testShow.correlationID = @1;
+ });
+
+ context(@"with a correct soft button and handler", ^{
+ beforeEach(^{
+ numTimesHandlerCalled = 0;
+
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) {
+ numTimesHandlerCalled++;
+ }];
+ testShow.softButtons = [@[testSoftButton1] mutableCopy];
+ testShow.correlationID = @1;
+ [testDispatcher storeRequest:testShow handler:nil];
+ });
+
+ it(@"should add the soft button to the map", ^{
+ expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil());
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1));
+ });
+
+ describe(@"when button press and button event notifications arrive", ^{
+ __block SDLOnButtonEvent *testButtonEvent = nil;
+ __block SDLOnButtonPress *testButtonPress = nil;
+
+ context(@"that correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.customButtonID = testSoftButton1.softButtonID;
+ testButtonEvent.buttonName = SDLButtonNameCustomButton;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.customButtonID = testSoftButton1.softButtonID;
+ testButtonPress.buttonName = SDLButtonNameCustomButton;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should run the handler for each", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@2));
+ });
+ });
+
+ context(@"that do not correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNameOk;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNameOk;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should not run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+ });
+ });
+
+ context(@"with a correct soft button but no handler", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should not add the soft button", ^{
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+
+ context(@"with a malformed soft button", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should throw an exception if there's no button id", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ testSoftButton1.softButtonID = nil;
+#pragma clang diagnostic pop
+ testShow.softButtons = [@[testSoftButton1] mutableCopy];
+
+ expectAction(^{ [testDispatcher storeRequest:testShow handler:nil]; }).to(raiseException().named(@"MissingIdException"));
+ });
+ });
+
+ context(@"without soft buttons", ^{
+ it(@"should not store the request", ^{
+ [testDispatcher storeRequest:testShow handler:nil];
+
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing a command request", ^{
+ __block SDLAddCommand *testAddCommand = nil;
+ __block UInt32 testCommandId = 0;
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ __block NSNumber *testAddCommandCorrelationId = nil;
+ __block NSNumber *testDeleteCommandCorrelationId = nil;
+
+ context(@"with a handler", ^{
+ beforeEach(^{
+ testCommandId = 1;
+ testAddCommandCorrelationId = @42;
+ numTimesHandlerCalled = 0;
+
+ testAddCommand = [[SDLAddCommand alloc] initWithId:testCommandId vrCommands:nil handler:^(__kindof SDLRPCNotification * _Nonnull notification) {
+ numTimesHandlerCalled++;
+ }];
+ testAddCommand.correlationID = testAddCommandCorrelationId;
+ });
+
+ it(@"should add the command to the map", ^{
+ [testDispatcher storeRequest:testAddCommand handler:nil];
+
+ expect(testDispatcher.commandHandlerMap[testAddCommand.cmdID]).toNot(beNil());
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@1));
+ });
+
+ it(@"should throw an exception if there's no command id", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ testAddCommand.cmdID = nil;
+
+#pragma clang diagnostic pop
+ expectAction(^{ [testDispatcher storeRequest:testAddCommand handler:nil]; }).to(raiseException().named(@"MissingIdException"));
+ });
+
+ describe(@"when button press and button event notifications arrive", ^{
+ __block SDLOnCommand *testOnCommand = nil;
+
+ beforeEach(^{
+ [testDispatcher storeRequest:testAddCommand handler:nil];
+ });
+
+ context(@"that correspond to the created button", ^{
+ beforeEach(^{
+ testOnCommand = [[SDLOnCommand alloc] init];
+ testOnCommand.cmdID = @(testCommandId);
+ testOnCommand.triggerSource = SDLTriggerSourceMenu;
+
+ SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand];
+
+ [[NSNotificationCenter defaultCenter] postNotification:commandNotification];
+ });
+
+ it(@"should run the handler for each", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@1));
+ });
+ });
+
+ context(@"that do not correspond to the created button", ^{
+ beforeEach(^{
+ testOnCommand = [[SDLOnCommand alloc] init];
+ testOnCommand.cmdID = @999;
+
+ SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand];
+
+ [[NSNotificationCenter defaultCenter] postNotification:commandNotification];
+ });
+
+ it(@"should not run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+ });
+
+ describe(@"then deleting the command", ^{
+ __block SDLDeleteCommand *testDeleteCommand = nil;
+ __block SDLDeleteCommandResponse *testDeleteResponse = nil;
+
+ beforeEach(^{
+ [testDispatcher storeRequest:testAddCommand handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}];
+
+ // We need both the delete command and the response for this to work
+ testDeleteCommandCorrelationId = @43;
+
+ testDeleteCommand = [[SDLDeleteCommand alloc] init];
+ testDeleteCommand.correlationID = testDeleteCommandCorrelationId;
+ testDeleteCommand.cmdID = @(testCommandId);
+
+ [testDispatcher storeRequest:testDeleteCommand handler:nil];
+
+ testDeleteResponse = [[SDLDeleteCommandResponse alloc] init];
+ testDeleteResponse.correlationID = testDeleteCommandCorrelationId;
+ testDeleteResponse.success = @YES;
+
+ SDLRPCResponseNotification *deleteCommandNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveDeleteCommandResponse object:nil rpcResponse:testDeleteResponse];
+
+ [[NSNotificationCenter defaultCenter] postNotification:deleteCommandNotification];
+ });
+
+ it(@"should have removed all the handlers", ^{
+ // There should still be the add command request & handler in the dictionaries since we never responded
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1));
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1));
+ });
+ });
+ });
+
+ context(@"without a handler", ^{
+ beforeEach(^{
+ testAddCommand = [[SDLAddCommand alloc] initWithId:1 vrCommands:nil handler:nil];
+ });
+
+ it(@"should not add the command", ^{
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing a subscribe button request", ^{
+ __block SDLSubscribeButton *testSubscribeButton = nil;
+ __block SDLButtonName testButtonName = nil;
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ __block NSNumber *testSubscribeCorrelationId = nil;
+ __block NSNumber *testUnsubscribeCorrelationId = nil;
+
+ context(@"with a handler", ^{
+ beforeEach(^{
+ testButtonName = SDLButtonNameOk;
+ testSubscribeCorrelationId = @42;
+ numTimesHandlerCalled = 0;
+
+ testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:testButtonName handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) {
+ numTimesHandlerCalled++;
+ }];
+ testSubscribeButton.correlationID = testSubscribeCorrelationId;
+ });
+
+ it(@"should add the subscription to the map", ^{
+ [testDispatcher storeRequest:testSubscribeButton handler:nil];
+
+ expect(testDispatcher.buttonHandlerMap[testSubscribeButton.buttonName]).toNot(beNil());
+ expect(testDispatcher.buttonHandlerMap).to(haveCount(@1));
+ });
+
+ it(@"should throw an exception if there's no button name", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ testSubscribeButton.buttonName = nil;
+#pragma clang diagnostic pop
+
+ expectAction(^{ [testDispatcher storeRequest:testSubscribeButton handler:nil]; }).to(raiseException().named(@"MissingIdException"));
+ });
+
+ describe(@"when button press and button event notifications arrive", ^{
+ __block SDLOnButtonEvent *testButtonEvent = nil;
+ __block SDLOnButtonPress *testButtonPress = nil;
+
+ beforeEach(^{
+ [testDispatcher storeRequest:testSubscribeButton handler:nil];
+ });
+
+ context(@"that correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = testButtonName;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = testButtonName;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should run the handler for each", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@2));
+ });
+ });
+
+ context(@"that do not correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNamePreset0;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNamePreset0;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should not run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+ });
+
+ describe(@"then unsubscribing", ^{
+ __block SDLUnsubscribeButton *testUnsubscribe = nil;
+ __block SDLUnsubscribeButtonResponse *testUnsubscribeResponse = nil;
+
+ beforeEach(^{
+ [testDispatcher storeRequest:testSubscribeButton handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}];
+
+ // We need both the delete command and the response for this to work
+ testUnsubscribeCorrelationId = @43;
+
+ testUnsubscribe = [[SDLUnsubscribeButton alloc] init];
+ testUnsubscribe.correlationID = testUnsubscribeCorrelationId;
+ testUnsubscribe.buttonName = testButtonName;
+
+ [testDispatcher storeRequest:testUnsubscribe handler:nil];
+
+ testUnsubscribeResponse = [[SDLUnsubscribeButtonResponse alloc] init];
+ testUnsubscribeResponse.correlationID = testUnsubscribeCorrelationId;
+ testUnsubscribeResponse.success = @YES;
+
+ SDLRPCResponseNotification *unsubscribeNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveUnsubscribeButtonResponse object:nil rpcResponse:testUnsubscribeResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:unsubscribeNotification];
+ });
+
+ it(@"should have removed all the handlers", ^{
+ // There should still be the add command request & handler in the dictionaries since we never responded
+ expect(testDispatcher.commandHandlerMap).to(haveCount(@0));
+ expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1));
+ expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1));
+ });
+ });
+ });
+
+ context(@"without a handler", ^{
+ beforeEach(^{
+ testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:SDLButtonNameOk handler:nil];
+ });
+
+ it(@"should not add the subscription", ^{
+ expect(testDispatcher.buttonHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing an alert request", ^{
+ __block SDLAlert *testAlert = nil;
+ __block SDLSoftButton *testSoftButton1 = nil;
+
+ beforeEach(^{
+ testAlert = [[SDLAlert alloc] initWithAlertText1:@"test 1" alertText2:@"test 1" alertText3:nil duration:1 softButtons:nil];
+ testAlert.correlationID = @1;
+ });
+
+ context(@"with a correct soft button and handler", ^{
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ beforeEach(^{
+ numTimesHandlerCalled = 0;
+
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) {
+ numTimesHandlerCalled++;
+ }];
+
+ testAlert.softButtons = [@[testSoftButton1] mutableCopy];
+ [testDispatcher storeRequest:testAlert handler:nil];
+ });
+
+ it(@"should add the soft button to the map", ^{
+ expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil());
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1));
+ });
+
+ describe(@"when button press and button event notifications arrive", ^{
+ __block SDLOnButtonEvent *testButtonEvent = nil;
+ __block SDLOnButtonPress *testButtonPress = nil;
+
+ context(@"that correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNameCustomButton;
+ testButtonEvent.customButtonID = testSoftButton1.softButtonID;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNameCustomButton;
+ testButtonPress.customButtonID = testSoftButton1.softButtonID;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should run the handler for each", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@2));
+ });
+ });
+
+ context(@"that do not correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNameOk;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNameOk;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should not run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+ });
+ });
+
+ context(@"with a correct soft button but no handler", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should not add the soft button", ^{
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+
+ context(@"with a malformed soft button", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should throw an exception if there's no button id", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ testSoftButton1.softButtonID = nil;
+#pragma clang diagnostic pop
+ testAlert.softButtons = [@[testSoftButton1] mutableCopy];
+
+ expectAction(^{ [testDispatcher storeRequest:testAlert handler:nil]; }).to(raiseException().named(@"MissingIdException"));
+ });
+ });
+
+ context(@"without soft buttons", ^{
+ it(@"should not store the request", ^{
+ [testDispatcher storeRequest:testAlert handler:nil];
+
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing a scrollable message request", ^{
+ __block SDLScrollableMessage *testScrollableMessage = nil;
+ __block SDLSoftButton *testSoftButton1 = nil;
+
+ beforeEach(^{
+ testScrollableMessage = [[SDLScrollableMessage alloc] initWithMessage:@"test" timeout:1 softButtons:nil];
+ testScrollableMessage.correlationID = @1;
+ });
+
+ context(@"with a correct soft button and handler", ^{
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ beforeEach(^{
+ numTimesHandlerCalled = 0;
+
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) {
+ numTimesHandlerCalled++;
+ }];
+
+ testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy];
+ [testDispatcher storeRequest:testScrollableMessage handler:nil];
+ });
+
+ it(@"should add the soft button to the map", ^{
+ expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil());
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1));
+ });
+
+ describe(@"when button press and button event notifications arrive", ^{
+ __block SDLOnButtonEvent *testButtonEvent = nil;
+ __block SDLOnButtonPress *testButtonPress = nil;
+
+ context(@"that correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNameCustomButton;
+ testButtonEvent.customButtonID = testSoftButton1.softButtonID;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNameCustomButton;
+ testButtonPress.customButtonID = testSoftButton1.softButtonID;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should run the handler for each", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@2));
+ });
+ });
+
+ context(@"that do not correspond to the created button", ^{
+ beforeEach(^{
+ testButtonEvent = [[SDLOnButtonEvent alloc] init];
+ testButtonEvent.buttonName = SDLButtonNameOk;
+
+ testButtonPress = [[SDLOnButtonPress alloc] init];
+ testButtonPress.buttonName = SDLButtonNameOk;
+
+ SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent];
+ SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress];
+
+ [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification];
+ [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification];
+ });
+
+ it(@"should not run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+ });
+ });
+
+ context(@"with a correct soft button but no handler", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should not add the soft button", ^{
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+
+ context(@"with a malformed soft button", ^{
+ beforeEach(^{
+ testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil];
+ });
+
+ it(@"should throw an exception if there's no button id", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ testSoftButton1.softButtonID = nil;
+#pragma clang diagnostic pop
+ testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy];
+
+ expectAction(^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; }).to(raiseException().named(@"MissingIdException"));
+ });
+ });
+
+ context(@"without soft buttons", ^{
+ it(@"should not store the request", ^{
+ [testDispatcher storeRequest:testScrollableMessage handler:nil];
+
+ expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0));
+ });
+ });
+ });
+
+ context(@"storing an audio pass thru handler", ^{
+ __block SDLPerformAudioPassThru* testPerformAudioPassThru = nil;
+ __block NSUInteger numTimesHandlerCalled = 0;
+
+ context(@"with a handler", ^{
+ beforeEach(^{
+ testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000 audioDataHandler:^(NSData * _Nullable audioData) {
+ numTimesHandlerCalled++;
+ }];
+
+ testPerformAudioPassThru.correlationID = @1;
+ [testDispatcher storeRequest:testPerformAudioPassThru handler:nil];
+ });
+
+ it(@"should store the handler" ,^{
+// expect(testDispatcher.audioPassThruHandler).toNot(beNil());
+// expect(testDispatcher.audioPassThruHandler).to(equal(testPerformAudioPassThru.audioDataHandler));
+ });
+
+ describe(@"when an on audio data notification arrives", ^{
+ beforeEach(^{
+ SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init];
+
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should run the handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@1));
+ });
+ });
+
+ describe(@"when an on audio data response arrives", ^{
+ beforeEach(^{
+ SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init];
+ performAudioPassThruResponse.success = @YES;
+
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should clear the handler", ^{
+// expect(testDispatcher.audioPassThruHandler).to(beNil());
+ });
+ });
+ });
+
+ context(@"without a handler", ^{
+ beforeEach(^{
+ numTimesHandlerCalled = 0;
+
+ testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000];
+
+ testPerformAudioPassThru.correlationID = @1;
+ [testDispatcher storeRequest:testPerformAudioPassThru handler:nil];
+ });
+
+ describe(@"when an on audio data notification arrives", ^{
+ beforeEach(^{
+ SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init];
+
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should not run a handler", ^{
+ expect(@(numTimesHandlerCalled)).to(equal(@0));
+ });
+ });
+
+ describe(@"when an on audio data response arrives", ^{
+ beforeEach(^{
+ SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init];
+ performAudioPassThruResponse.success = @YES;
+
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should clear the handler", ^{
+// expect(testDispatcher.audioPassThruHandler).to(beNil());
+ });
+ });
+
+ });
+ });
+});
+
+QuickSpecEnd