From 6b3fe196a0456b6bd30aa5fc6750dbd86cf283f5 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 6 Apr 2021 12:19:42 -0400 Subject: [PATCH 1/4] Fixed wrong queued menu getting sent Signed-off-by: NicoleYarroch --- SmartDeviceLink/private/SDLMenuManager.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/private/SDLMenuManager.m b/SmartDeviceLink/private/SDLMenuManager.m index ea6e1cd74..2e917c79d 100644 --- a/SmartDeviceLink/private/SDLMenuManager.m +++ b/SmartDeviceLink/private/SDLMenuManager.m @@ -71,6 +71,9 @@ @interface SDLMenuManager() @property (assign, nonatomic) UInt32 lastMenuId; @property (copy, nonatomic) NSArray *oldMenuCells; +@property (copy, nonatomic) NSArray *queuedDeleteMenuCells; +@property (copy, nonatomic) NSArray *queuedAddMenuCells; + @end UInt32 const ParentIdNotFound = UINT32_MAX; @@ -400,6 +403,8 @@ - (void)sdl_updateMenuWithCellsToDelete:(NSArray *)deleteCells ce if (self.inProgressUpdate != nil) { // There's an in progress update, we need to put this on hold self.hasQueuedUpdate = YES; + self.queuedAddMenuCells = addCells; + self.queuedDeleteMenuCells = deleteCells; return; } __weak typeof(self) weakself = self; @@ -412,7 +417,10 @@ - (void)sdl_updateMenuWithCellsToDelete:(NSArray *)deleteCells ce } if (weakself.hasQueuedUpdate) { - [weakself sdl_updateMenuWithCellsToDelete:deleteCells cellsToAdd:addCells completionHandler:nil]; + SDLLogD(@"Sending queued menu updates"); + [weakself sdl_updateMenuWithCellsToDelete:self.queuedDeleteMenuCells cellsToAdd:self.queuedAddMenuCells completionHandler:nil]; + weakself.queuedDeleteMenuCells = @[]; + weakself.queuedAddMenuCells = @[]; weakself.hasQueuedUpdate = NO; } }]; From 017b2ce90333054773f6eff62dc6131452a82899 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 7 Apr 2021 09:30:57 -0400 Subject: [PATCH 2/4] Added test cases for queued menu updates Signed-off-by: NicoleYarroch --- .../DevAPISpecs/SDLMenuManagerSpec.m | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m index c14e177a6..797201b89 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m @@ -34,6 +34,9 @@ @interface SDLMenuManager() @property (assign, nonatomic) UInt32 lastMenuId; @property (copy, nonatomic) NSArray *oldMenuCells; +@property (copy, nonatomic) NSArray *queuedDeleteMenuCells; +@property (copy, nonatomic) NSArray *queuedAddMenuCells; + - (BOOL)sdl_shouldRPCsIncludeImages:(NSArray *)cells; - (void)sdl_displayCapabilityDidUpdate; @@ -621,6 +624,116 @@ - (void)sdl_displayCapabilityDidUpdate; expect(adds).to(haveCount(6)); }); }); + + describe(@"updating the menu when the existing menu has not finished updloading", ^{ + __block NSArray *testCurrentMenuCells = nil; + __block NSArray *testQueuedMenuCells = nil; + + beforeEach(^{ + testCurrentMenuCells = @[textOnlyCell, textAndImageCell]; + testQueuedMenuCells = @[textOnlyCell, textOnlyCell2]; + }); + + context(@"dynamic updates off", ^{ + beforeEach(^{ + testManager.dynamicMenuUpdatesMode = SDLDynamicMenuUpdatesModeForceOff; + OCMStub([mockFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg invokeBlock]]); + testManager.menuCells = testCurrentMenuCells; + }); + + it(@"should save the menu cells that are queued and send them when the current menu finishes uploading", ^{ + testManager.inProgressUpdate = @[]; + testManager.menuCells = testQueuedMenuCells; + + expect(testManager.hasQueuedUpdate).to(beTrue()); + expect(testManager.queuedDeleteMenuCells).to(haveCount(2)); + expect(testManager.queuedDeleteMenuCells).to(contain(textOnlyCell)); + expect(testManager.queuedDeleteMenuCells).to(contain(textAndImageCell)); + + expect(testManager.queuedAddMenuCells).to(haveCount(2)); + expect(testManager.queuedAddMenuCells).to(contain(textOnlyCell)); + expect(testManager.queuedAddMenuCells).to(contain(textOnlyCell2)); + + expect(mockConnectionManager.receivedRequests).to(haveCount(2)); + NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass:%@", [SDLDeleteCommand class]]; + NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate]; + NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass:%@", [SDLAddCommand class]]; + NSArray *adds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate]; + expect(deletes).to(haveCount(0)); + expect(adds).to(haveCount(2)); + + // When the current menu finishes uploading it should send the queued menu + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + + expect(testManager.inProgressUpdate).to(beNil()); + expect(testManager.hasQueuedUpdate).to(beFalse()); + expect(testManager.queuedDeleteMenuCells).to(haveCount(0)); + expect(testManager.queuedAddMenuCells).to(haveCount(0)); + + // Respond to the delete and add commands sent for the queued menu - (4 total) + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + + NSArray *queuedMenuDeletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate]; + NSArray *queuedMenuAdds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate]; + expect(queuedMenuDeletes).to(haveCount(2)); + expect(queuedMenuAdds).to(haveCount(4)); + + expect(mockConnectionManager.receivedRequests).to(haveCount(6)); + }); + }); + + context(@"dynamic updates on", ^{ + beforeEach(^{ + testManager.dynamicMenuUpdatesMode = SDLDynamicMenuUpdatesModeForceOn; + OCMStub([mockFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg invokeBlock]]); + testManager.menuCells = testCurrentMenuCells; + }); + + it(@"should save the menu cells that are queued and send them when the current menu finishes uploading", ^{ + testManager.inProgressUpdate = @[]; + testManager.menuCells = testQueuedMenuCells; + + expect(testManager.hasQueuedUpdate).to(beTrue()); + expect(testManager.queuedDeleteMenuCells).to(haveCount(1)); + expect(testManager.queuedDeleteMenuCells).to(contain(textAndImageCell)); + + expect(testManager.queuedAddMenuCells).to(haveCount(1)); + expect(testManager.queuedAddMenuCells).to(contain(textOnlyCell2)); + + expect(mockConnectionManager.receivedRequests).to(haveCount(2)); + NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass:%@", [SDLDeleteCommand class]]; + NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate]; + NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass:%@", [SDLAddCommand class]]; + NSArray *adds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate]; + expect(deletes).to(haveCount(0)); + expect(adds).to(haveCount(2)); + + // When the current menu finishes uploading it should send the queued menu + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + + expect(testManager.inProgressUpdate).to(beNil()); + expect(testManager.hasQueuedUpdate).to(beFalse()); + expect(testManager.queuedDeleteMenuCells).to(haveCount(0)); + expect(testManager.queuedAddMenuCells).to(haveCount(0)); + + // Respond to the delete and add commands sent for the queued menu - (2 total) + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES]; + + NSArray *queuedMenuDeletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate]; + NSArray *queuedMenuAdds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate]; + expect(queuedMenuDeletes).to(haveCount(1)); + expect(queuedMenuAdds).to(haveCount(3)); + + expect(mockConnectionManager.receivedRequests).to(haveCount(4)); + }); + }); + }); }); describe(@"running menu cell handlers", ^{ From a5ee8b08de52722e65c86e171971d39f060b3333 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 7 Apr 2021 09:31:02 -0400 Subject: [PATCH 3/4] Added newline Signed-off-by: NicoleYarroch --- SmartDeviceLink/private/SDLMenuManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SmartDeviceLink/private/SDLMenuManager.m b/SmartDeviceLink/private/SDLMenuManager.m index 2e917c79d..974215502 100644 --- a/SmartDeviceLink/private/SDLMenuManager.m +++ b/SmartDeviceLink/private/SDLMenuManager.m @@ -407,6 +407,7 @@ - (void)sdl_updateMenuWithCellsToDelete:(NSArray *)deleteCells ce self.queuedDeleteMenuCells = deleteCells; return; } + __weak typeof(self) weakself = self; [self sdl_sendDeleteCurrentMenu:deleteCells withCompletionHandler:^(NSError * _Nullable error) { [weakself sdl_sendUpdatedMenu:addCells usingMenu:weakself.menuCells withCompletionHandler:^(NSError * _Nullable error) { From e34c41f1a797b1a73af0a89dcc222ab4a6189956 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 7 Apr 2021 09:51:50 -0400 Subject: [PATCH 4/4] Cleaned up queued updates on stop Signed-off-by: NicoleYarroch --- SmartDeviceLink/private/SDLMenuManager.m | 2 ++ SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/SmartDeviceLink/private/SDLMenuManager.m b/SmartDeviceLink/private/SDLMenuManager.m index 974215502..455674f94 100644 --- a/SmartDeviceLink/private/SDLMenuManager.m +++ b/SmartDeviceLink/private/SDLMenuManager.m @@ -123,6 +123,8 @@ - (void)stop { _hasQueuedUpdate = NO; _waitingOnHMIUpdate = NO; _waitingUpdateMenuCells = @[]; + _queuedAddMenuCells = @[]; + _queuedDeleteMenuCells = @[]; } #pragma mark - Setters diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m index 797201b89..eb638b0e1 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m @@ -115,6 +115,8 @@ - (void)sdl_displayCapabilityDidUpdate; expect(testManager.oldMenuCells).to(beEmpty()); expect(testManager.waitingUpdateMenuCells).to(beNil()); expect(testManager.menuConfiguration).toNot(beNil()); + expect(testManager.queuedAddMenuCells).to(beNil()); + expect(testManager.queuedDeleteMenuCells).to(beNil()); }); describe(@"updating menu cells before HMI is ready", ^{ @@ -855,6 +857,8 @@ - (void)sdl_displayCapabilityDidUpdate; expect(testManager.oldMenuCells).to(beEmpty()); expect(testManager.waitingUpdateMenuCells).to(beEmpty()); expect(testManager.menuConfiguration).toNot(beNil()); + expect(testManager.queuedAddMenuCells).to(beEmpty()); + expect(testManager.queuedDeleteMenuCells).to(beEmpty()); }); });