summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2020-12-09 15:00:39 -0500
committerGitHub <noreply@github.com>2020-12-09 15:00:39 -0500
commitc3dded18f53910caf5d8f07fe00a4ce89ec3c80b (patch)
treee87233eebce81b59a3b00e807798c41b48068a22
parent039cf18f1632684117be59cba312630112bd9bd6 (diff)
parent8cad3b235e84ffa9ea75f23f8d4c45da27455e0b (diff)
downloadsdl_ios-c3dded18f53910caf5d8f07fe00a4ce89ec3c80b.tar.gz
Merge pull request #1853 from smartdevicelink/bugfix/issue-1117-Setting-a-SDLArtwork-overwrite-property-to-true-does-not-work-with-screen-manager
Fix for overwriting SDLArtwork
-rw-r--r--SmartDeviceLink/private/SDLMenuManager.m17
-rw-r--r--SmartDeviceLink/private/SDLPreloadChoicesOperation.m8
-rw-r--r--SmartDeviceLink/private/SDLSoftButtonReplaceOperation.m10
-rw-r--r--SmartDeviceLink/private/SDLTextAndGraphicUpdateOperation.m24
-rw-r--r--SmartDeviceLink/public/SDLFileManager.h12
-rw-r--r--SmartDeviceLink/public/SDLFileManager.m12
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m60
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m27
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPreloadChoicesOperationSpec.m22
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicUpdateOperationSpec.m29
-rw-r--r--SmartDeviceLinkTests/SDLSoftButtonReplaceOperationSpec.m30
11 files changed, 218 insertions, 33 deletions
diff --git a/SmartDeviceLink/private/SDLMenuManager.m b/SmartDeviceLink/private/SDLMenuManager.m
index af91dc3a1..b78f8ee99 100644
--- a/SmartDeviceLink/private/SDLMenuManager.m
+++ b/SmartDeviceLink/private/SDLMenuManager.m
@@ -472,7 +472,7 @@ UInt32 const MenuCellIdMin = 1;
NSArray<SDLRPCRequest *> *mainMenuCommands = nil;
NSArray<SDLRPCRequest *> *subMenuCommands = nil;
- if ([self sdl_findAllArtworksToBeUploadedFromCells:self.menuCells].count > 0 || ![self.windowCapability hasImageFieldOfName:SDLImageFieldNameCommandIcon]) {
+ if (![self sdl_shouldRPCsIncludeImages:self.menuCells] || ![self.windowCapability hasImageFieldOfName:SDLImageFieldNameCommandIcon]) {
// Send artwork-less menu
mainMenuCommands = [self sdl_mainMenuCommandsForCells:updatedMenu withArtwork:NO usingIndexesFrom:menu];
subMenuCommands = [self sdl_subMenuCommandsForCells:updatedMenu withArtwork:NO];
@@ -539,7 +539,7 @@ UInt32 const MenuCellIdMin = 1;
NSMutableSet<SDLArtwork *> *mutableArtworks = [NSMutableSet set];
for (SDLMenuCell *cell in cells) {
- if ([self sdl_artworkNeedsUpload:cell.icon]) {
+ if ([self.fileManager fileNeedsUpload:cell.icon]) {
[mutableArtworks addObject:cell.icon];
}
@@ -551,8 +551,17 @@ UInt32 const MenuCellIdMin = 1;
return [mutableArtworks allObjects];
}
-- (BOOL)sdl_artworkNeedsUpload:(SDLArtwork *)artwork {
- return (artwork != nil && ![self.fileManager hasUploadedFile:artwork] && !artwork.isStaticIcon);
+- (BOOL)sdl_shouldRPCsIncludeImages:(NSArray<SDLMenuCell *> *)cells {
+ for (SDLMenuCell *cell in cells) {
+ SDLArtwork *artwork = cell.icon;
+ if (artwork != nil && !artwork.isStaticIcon && ![self.fileManager hasUploadedFile:artwork]) {
+ return NO;
+ } else if (cell.subCells.count > 0) {
+ return [self sdl_shouldRPCsIncludeImages:cell.subCells];
+ }
+ }
+
+ return YES;
}
#pragma mark IDs
diff --git a/SmartDeviceLink/private/SDLPreloadChoicesOperation.m b/SmartDeviceLink/private/SDLPreloadChoicesOperation.m
index 82f7435ff..b52a82f70 100644
--- a/SmartDeviceLink/private/SDLPreloadChoicesOperation.m
+++ b/SmartDeviceLink/private/SDLPreloadChoicesOperation.m
@@ -87,10 +87,10 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableArray<SDLArtwork *> *artworksToUpload = [NSMutableArray arrayWithCapacity:self.cellsToUpload.count];
for (SDLChoiceCell *cell in self.cellsToUpload) {
- if ([self sdl_shouldSendChoicePrimaryImage] && [self sdl_artworkNeedsUpload:cell.artwork]) {
+ if ([self sdl_shouldSendChoicePrimaryImage] && [self.fileManager fileNeedsUpload:cell.artwork]) {
[artworksToUpload addObject:cell.artwork];
}
- if ([self sdl_shouldSendChoiceSecondaryImage] && [self sdl_artworkNeedsUpload:cell.secondaryArtwork]) {
+ if ([self sdl_shouldSendChoiceSecondaryImage] && [self.fileManager fileNeedsUpload:cell.secondaryArtwork]) {
[artworksToUpload addObject:cell.secondaryArtwork];
}
}
@@ -113,10 +113,6 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
-- (BOOL)sdl_artworkNeedsUpload:(SDLArtwork *)artwork {
- return (artwork != nil && ![self.fileManager hasUploadedFile:artwork] && !artwork.isStaticIcon);
-}
-
- (void)sdl_preloadCells {
_currentState = SDLPreloadChoicesOperationStatePreloadingChoices;
diff --git a/SmartDeviceLink/private/SDLSoftButtonReplaceOperation.m b/SmartDeviceLink/private/SDLSoftButtonReplaceOperation.m
index d3a68735c..65285f830 100644
--- a/SmartDeviceLink/private/SDLSoftButtonReplaceOperation.m
+++ b/SmartDeviceLink/private/SDLSoftButtonReplaceOperation.m
@@ -103,7 +103,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_uploadInitialStateImagesWithCompletionHandler:(void (^)(void))handler {
NSMutableArray<SDLArtwork *> *initialStatesToBeUploaded = [NSMutableArray array];
for (SDLSoftButtonObject *object in self.softButtonObjects) {
- if ([self sdl_artworkNeedsUpload:object.currentState.artwork]) {
+ if ([self.fileManager fileNeedsUpload:object.currentState.artwork]) {
[initialStatesToBeUploaded addObject:object.currentState.artwork];
}
}
@@ -118,7 +118,7 @@ NS_ASSUME_NONNULL_BEGIN
for (SDLSoftButtonObject *object in self.softButtonObjects) {
for (SDLSoftButtonState *state in object.states) {
if ([state.name isEqualToString:object.currentState.name]) { continue; }
- if ([self sdl_artworkNeedsUpload:state.artwork]) {
+ if ([self.fileManager fileNeedsUpload:state.artwork]) {
[otherStatesToBeUploaded addObject:state.artwork];
}
}
@@ -227,17 +227,13 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Images
-- (BOOL)sdl_artworkNeedsUpload:(SDLArtwork *)artwork {
- return (artwork != nil && ![self.fileManager hasUploadedFile:artwork] && self.softButtonCapabilities.imageSupported.boolValue && !artwork.isStaticIcon);
-}
-
/// Checks all the button states for images that need to be uploaded.
/// @return True if all images have been uploaded; false at least one image needs to be uploaded
- (BOOL)sdl_allStateImagesAreUploaded {
for (SDLSoftButtonObject *button in self.softButtonObjects) {
for (SDLSoftButtonState *state in button.states) {
SDLArtwork *artwork = state.artwork;
- if (![self sdl_artworkNeedsUpload:artwork]) { continue; }
+ if (![self.fileManager fileNeedsUpload:artwork]) { continue; }
return NO;
}
}
diff --git a/SmartDeviceLink/private/SDLTextAndGraphicUpdateOperation.m b/SmartDeviceLink/private/SDLTextAndGraphicUpdateOperation.m
index 990df13f2..cd47531e2 100644
--- a/SmartDeviceLink/private/SDLTextAndGraphicUpdateOperation.m
+++ b/SmartDeviceLink/private/SDLTextAndGraphicUpdateOperation.m
@@ -111,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
}
[strongSelf finishOperation];
}];
- } else if (![self sdl_artworkNeedsUpload:self.updatedState.primaryGraphic] && ![self sdl_artworkNeedsUpload:self.updatedState.secondaryGraphic]) {
+ } else if (![self.fileManager fileNeedsUpload:self.updatedState.primaryGraphic] && ![self.fileManager fileNeedsUpload:self.updatedState.secondaryGraphic]) {
SDLLogV(@"Images already uploaded, sending full update");
// The files to be updated are already uploaded, send the full show immediately
[self sdl_sendShow:show withHandler:^(NSError * _Nullable error) {
@@ -263,8 +263,8 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable SDLShow *)sdl_createImageOnlyShowWithPrimaryArtwork:(nullable SDLArtwork *)primaryArtwork secondaryArtwork:(nullable SDLArtwork *)secondaryArtwork {
SDLShow *newShow = [[SDLShow alloc] init];
- newShow.graphic = ![self sdl_artworkNeedsUpload:primaryArtwork] ? primaryArtwork.imageRPC : nil;
- newShow.secondaryGraphic = ![self sdl_artworkNeedsUpload:secondaryArtwork] ? secondaryArtwork.imageRPC : nil;
+ newShow.graphic = [self sdl_shouldRPCIncludeImage:primaryArtwork] ? primaryArtwork.imageRPC : nil;
+ newShow.secondaryGraphic = [self sdl_shouldRPCIncludeImage:secondaryArtwork] ? secondaryArtwork.imageRPC : nil;
if (newShow.graphic == nil && newShow.secondaryGraphic == nil) {
SDLLogV(@"No graphics to upload");
@@ -515,30 +515,34 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Should Update
-- (BOOL)sdl_artworkNeedsUpload:(SDLArtwork *)artwork {
- return (artwork != nil && ![self.fileManager hasUploadedFile:artwork] && !artwork.isStaticIcon);
+- (BOOL)sdl_shouldRPCIncludeImage:(nullable SDLArtwork *)artwork {
+ if (artwork == nil) { return NO; }
+
+ return (artwork.isStaticIcon || [self.fileManager hasUploadedFile:artwork]);
}
- (BOOL)sdl_shouldUpdatePrimaryImage {
// If the template is updating, we don't yet know it's capabilities. Just assume the template supports the primary image.
BOOL templateSupportsPrimaryArtwork = [self.currentCapabilities hasImageFieldOfName:SDLImageFieldNameGraphic] || [self sdl_shouldUpdateTemplateConfig];
- BOOL graphicMatchesExisting = [self.currentScreenData.primaryGraphic.name isEqualToString:self.updatedState.primaryGraphic.name];
+ BOOL graphicNameMatchesExisting = [self.currentScreenData.primaryGraphic.name isEqualToString:self.updatedState.primaryGraphic.name];
+ BOOL shouldOverwriteGraphic = self.updatedState.primaryGraphic.overwrite;
BOOL graphicExists = (self.updatedState.primaryGraphic != nil);
- return (templateSupportsPrimaryArtwork && !graphicMatchesExisting && graphicExists);
+ return (templateSupportsPrimaryArtwork && (shouldOverwriteGraphic || !graphicNameMatchesExisting) && graphicExists);
}
- (BOOL)sdl_shouldUpdateSecondaryImage {
// If the template is updating, we don't yet know it's capabilities. Just assume the template supports the secondary image.
BOOL templateSupportsSecondaryArtwork = [self.currentCapabilities hasImageFieldOfName:SDLImageFieldNameSecondaryGraphic] || [self sdl_shouldUpdateTemplateConfig];
- BOOL graphicMatchesExisting = [self.currentScreenData.secondaryGraphic.name isEqualToString:self.updatedState.secondaryGraphic.name];
+ BOOL graphicNameMatchesExisting = [self.currentScreenData.secondaryGraphic.name isEqualToString:self.updatedState.secondaryGraphic.name];
+ BOOL shouldOverwriteGraphic = self.updatedState.secondaryGraphic != nil && self.updatedState.secondaryGraphic.overwrite;
BOOL graphicExists = (self.updatedState.secondaryGraphic != nil);
// Cannot detect if there is a secondary image below v5.0, so we'll just try to detect if the primary image is allowed and allow the secondary image if it is.
if ([[SDLGlobals sharedGlobals].rpcVersion isGreaterThanOrEqualToVersion:[SDLVersion versionWithMajor:5 minor:0 patch:0]]) {
- return (templateSupportsSecondaryArtwork && !graphicMatchesExisting && graphicExists);
+ return (templateSupportsSecondaryArtwork && (shouldOverwriteGraphic || !graphicNameMatchesExisting) && graphicExists);
} else {
- return ([self.currentCapabilities hasImageFieldOfName:SDLImageFieldNameGraphic] && !graphicMatchesExisting && graphicExists);
+ return ([self.currentCapabilities hasImageFieldOfName:SDLImageFieldNameGraphic] && (shouldOverwriteGraphic || !graphicNameMatchesExisting) && graphicExists);
}
}
diff --git a/SmartDeviceLink/public/SDLFileManager.h b/SmartDeviceLink/public/SDLFileManager.h
index 24b589a2a..5010b89e4 100644
--- a/SmartDeviceLink/public/SDLFileManager.h
+++ b/SmartDeviceLink/public/SDLFileManager.h
@@ -137,6 +137,18 @@ typedef void (^SDLFileManagerStartupCompletionHandler)(BOOL success, NSError *__
- (void)uploadFiles:(NSArray<SDLFile *> *)files completionHandler:(nullable SDLFileManagerMultiUploadCompletionHandler)completionHandler NS_SWIFT_NAME(upload(files:completionHandler:));
/**
+ * Check if an SDLFile needs to be uploaded to Core or not. This method differs from hasUploadedFile() because it takes the `isStaticIcon` and `overwrite` properties into consideration.
+ *
+ * For example, if the file is static icon, the method always returns false.
+ *
+ * If the file is dynamic, it returns true in one of these situations: 1) the file has the overwrite property set to true, 2) the file hasn't been uploaded to Core before.
+ *
+ * @param file the SDLFile that needs to be checked
+ * @return BOOL that tells whether file needs to be uploaded to Core or not
+ */
+- (BOOL)fileNeedsUpload:(SDLFile *)file;
+
+/**
* Uploads an artwork file to the remote file system and returns the name of the uploaded artwork once completed. If an artwork with the same name is already on the remote system, the artwork is not uploaded and the artwork name is simply returned.
*
* @param artwork A SDLArwork containing an image to be sent
diff --git a/SmartDeviceLink/public/SDLFileManager.m b/SmartDeviceLink/public/SDLFileManager.m
index 9bade2752..58ed6a547 100644
--- a/SmartDeviceLink/public/SDLFileManager.m
+++ b/SmartDeviceLink/public/SDLFileManager.m
@@ -285,13 +285,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
// HAX: [#827](https://github.com/smartdevicelink/sdl_ios/issues/827) Older versions of Core had a bug where list files would cache incorrectly.
if (file.persistent && [self.remoteFileNames containsObject:file.name]) {
// If it's a persistant file, the bug won't present itself; just check if it's on the remote system
- return true;
+ return YES;
} else if (!file.persistent && [self.remoteFileNames containsObject:file.name] && [self.uploadedEphemeralFileNames containsObject:file.name]) {
// If it's an ephemeral file, the bug will present itself; check that it's a remote file AND that we've uploaded it this session
- return true;
+ return YES;
}
- return false;
+ return NO;
}
- (void)uploadFiles:(NSArray<SDLFile *> *)files completionHandler:(nullable SDLFileManagerMultiUploadCompletionHandler)completionHandler {
@@ -427,6 +427,12 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
#pragma mark Artworks
+- (BOOL)fileNeedsUpload:(SDLFile *)file {
+ if (file == nil || file.isStaticIcon) { return NO; }
+
+ return (file.overwrite || ![self hasUploadedFile:file]);
+}
+
- (void)uploadArtwork:(SDLArtwork *)artwork completionHandler:(nullable SDLFileManagerUploadArtworkCompletionHandler)completion {
__weak typeof(self) weakself = self;
[self uploadFile:artwork completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
index af5f443a7..f7ea93fc8 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
@@ -466,6 +466,66 @@ describe(@"uploading / deleting single files with the file manager", ^{
expect(testFileManager.pendingTransactions.count).to(equal(1));
});
});
+
+ describe(@"checking if files and artworks needs upload", ^{
+ __block UIImage *testUIImage = nil;
+ __block NSString *expectedArtworkName = nil;
+ __block SDLArtwork *artwork = nil;
+
+ context(@"when artwork is nil", ^{
+ it(@"should not allow file to be uploaded", ^{
+ expect(artwork).to(beNil());
+ BOOL testFileNeedsUpload = [testFileManager fileNeedsUpload:artwork];
+ expect(testFileNeedsUpload).to(beFalse());
+ });
+ });
+
+ context(@"when artwork is static", ^{
+ it(@"should not allow file to be uploaded", ^{
+ artwork = [[SDLArtwork alloc] initWithStaticIcon:SDLStaticIconNameKey];
+
+ BOOL testFileNeedsUpload = [testFileManager fileNeedsUpload:artwork];
+ expect(testFileNeedsUpload).to(beFalse());
+ });
+ });
+
+ context(@"when artwork is dynamic", ^{
+ beforeEach(^{
+ testUIImage = [FileManagerSpecHelper imagesForCount:1].firstObject;
+ expectedArtworkName = testInitialFileNames.firstObject;
+ artwork = [SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG];
+ });
+
+ context(@"when uploading artwork for the first time", ^{
+ it(@"should allow file to be uploaded", ^{
+ BOOL testFileNeedsUpload = [testFileManager fileNeedsUpload:artwork];
+ expect(testFileNeedsUpload).to(beTrue());
+ });
+ });
+
+ context(@"when artwork is previously uploaded", ^{
+ beforeEach(^{
+ testFileManager.uploadedEphemeralFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
+
+ it(@"should not allow file to be uploaded when overwrite is set to false", ^{
+ artwork.overwrite = NO;
+
+ BOOL testFileNeedsUpload = [testFileManager fileNeedsUpload:artwork];
+ expect(testFileNeedsUpload).to(beFalse());
+ });
+
+ it(@"should allow file to be uploaded when overwrite is set to true", ^{
+ artwork.overwrite = YES;
+
+ BOOL testFileNeedsUpload = [testFileManager fileNeedsUpload:artwork];
+ expect(testFileNeedsUpload).to(beTrue());
+ });
+ });
+ });
+ });
});
describe(@"uploading/deleting multiple files in the file manager", ^{
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
index ff9c4e7bb..9bde38ac7 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
@@ -35,6 +35,8 @@
@property (assign, nonatomic) UInt32 lastMenuId;
@property (copy, nonatomic) NSArray<SDLMenuCell *> *oldMenuCells;
+- (BOOL)sdl_shouldRPCsIncludeImages:(NSArray<SDLMenuCell *> *)cells;
+
@end
QuickSpecBegin(SDLMenuManagerSpec)
@@ -46,6 +48,7 @@ describe(@"menu manager", ^{
__block SDLSystemCapabilityManager *mockSystemCapabilityManager = nil;
__block SDLArtwork *testArtwork = nil;
__block SDLArtwork *testArtwork2 = nil;
+ __block SDLArtwork *testArtwork3 = nil;
__block SDLMenuCell *textOnlyCell = nil;
__block SDLMenuCell *textOnlyCell2 = nil;
@@ -58,6 +61,8 @@ describe(@"menu manager", ^{
beforeEach(^{
testArtwork = [[SDLArtwork alloc] initWithData:[@"Test data" dataUsingEncoding:NSUTF8StringEncoding] name:@"some artwork name" fileExtension:@"png" persistent:NO];
testArtwork2 = [[SDLArtwork alloc] initWithData:[@"Test data 2" dataUsingEncoding:NSUTF8StringEncoding] name:@"some artwork name 2" fileExtension:@"png" persistent:NO];
+ testArtwork3 = [[SDLArtwork alloc] initWithData:[@"Test data 3" dataUsingEncoding:NSUTF8StringEncoding] name:@"some artwork name" fileExtension:@"png" persistent:NO];
+ testArtwork3.overwrite = YES;
textOnlyCell = [[SDLMenuCell alloc] initWithTitle:@"Test 1" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
textAndImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 2" icon:testArtwork voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
@@ -180,6 +185,13 @@ describe(@"menu manager", ^{
});
});
+ it(@"should check if all artworks are uploaded and return NO", ^{
+ textAndImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 2" icon:testArtwork3 voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+ testManager.menuCells = @[textAndImageCell, textOnlyCell];
+ OCMVerify([testManager sdl_shouldRPCsIncludeImages:testManager.menuCells]);
+ expect([testManager sdl_shouldRPCsIncludeImages:testManager.menuCells]).to(beFalse());
+ });
+
it(@"should properly update a text cell", ^{
testManager.menuCells = @[textOnlyCell];
@@ -213,6 +225,13 @@ describe(@"menu manager", ^{
OCMStub([mockFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(YES);
});
+ it(@"should check if all artworks are uploaded", ^{
+ textAndImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 2" icon:testArtwork3 voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+ testManager.menuCells = @[textAndImageCell, textOnlyCell];
+ OCMVerify([testManager sdl_shouldRPCsIncludeImages:testManager.menuCells]);
+ expect([testManager sdl_shouldRPCsIncludeImages:testManager.menuCells]).to(beTrue());
+ });
+
it(@"should properly update an image cell", ^{
testManager.menuCells = @[textAndImageCell, submenuImageCell];
@@ -228,6 +247,14 @@ describe(@"menu manager", ^{
expect(submenu).to(haveCount(1));
expect(sentCommand.cmdIcon.value).to(equal(testArtwork.name));
expect(sentSubmenu.menuIcon.value).to(equal(testArtwork2.name));
+ OCMReject([mockFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]);
+ });
+
+ it(@"should properly overwrite an image cell", ^{
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
+ textAndImageCell = [[SDLMenuCell alloc] initWithTitle:@"Test 2" icon:testArtwork3 voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+ testManager.menuCells = @[textAndImageCell, submenuImageCell];
+ OCMVerify([mockFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]);
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPreloadChoicesOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPreloadChoicesOperationSpec.m
index c36e574fe..144f54e3d 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPreloadChoicesOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPreloadChoicesOperationSpec.m
@@ -25,6 +25,7 @@ describe(@"a preload choices operation", ^{
__block NSString *testDisplayName = @"SDL_GENERIC";
__block NSData *cellArtData = [@"testart" dataUsingEncoding:NSUTF8StringEncoding];
+ __block NSData *cellArtData2 = [@"testart2" dataUsingEncoding:NSUTF8StringEncoding];
__block BOOL hasCalledOperationCompletionHandler = NO;
__block NSError *resultError = nil;
@@ -53,6 +54,7 @@ describe(@"a preload choices operation", ^{
windowCapability.textFields = @[primaryTextField];
OCMStub([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg invokeBlock]]);
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
});
context(@"with artworks", ^{
@@ -60,6 +62,7 @@ describe(@"a preload choices operation", ^{
__block NSSet<SDLChoiceCell *> *cellsWithStaticIcon = nil;
__block NSString *art1Name = @"Art1Name";
__block NSString *art2Name = @"Art2Name";
+ __block SDLArtwork *cell1Art2 = [[SDLArtwork alloc] initWithData:cellArtData2 name:art1Name fileExtension:@"png" persistent:NO];
beforeEach(^{
SDLArtwork *cell1Art = [[SDLArtwork alloc] initWithData:cellArtData name:art1Name fileExtension:@"png" persistent:NO];
@@ -145,6 +148,25 @@ describe(@"a preload choices operation", ^{
}] completionHandler:[OCMArg any]]);
expect(@(testOp.currentState)).to(equal(SDLPreloadChoicesOperationStatePreloadingChoices));
});
+
+ it(@"should properly overwrite artwork", ^{
+ cell1Art2.overwrite = YES;
+ SDLChoiceCell *cell1WithArt = [[SDLChoiceCell alloc] initWithText:@"Cell1" artwork:cell1Art2 voiceCommands:nil];
+
+ SDLArtwork *cell2Art = [[SDLArtwork alloc] initWithData:cellArtData name:art2Name fileExtension:@"png" persistent:NO];
+ SDLChoiceCell *cell2WithArtAndSecondary = [[SDLChoiceCell alloc] initWithText:@"Cell2" secondaryText:nil tertiaryText:nil voiceCommands:nil artwork:cell2Art secondaryArtwork:cell2Art];
+
+ SDLArtwork *staticIconArt = [SDLArtwork artworkWithStaticIcon:SDLStaticIconNameDate];
+ SDLChoiceCell *cellWithStaticIcon = [[SDLChoiceCell alloc] initWithText:@"Static Icon" secondaryText:nil tertiaryText:nil voiceCommands:nil artwork:staticIconArt secondaryArtwork:nil];
+
+ cellsWithArtwork = [NSSet setWithArray:@[cell1WithArt, cell2WithArtAndSecondary]];
+ cellsWithStaticIcon = [NSSet setWithArray:@[cellWithStaticIcon]];
+ testOp = [[SDLPreloadChoicesOperation alloc] initWithConnectionManager:testConnectionManager fileManager:testFileManager displayName:testDisplayName windowCapability:windowCapability isVROptional:NO cellsToPreload:cellsWithArtwork];
+ [testOp start];
+
+ OCMExpect([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]);
+ OCMVerify([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]);
+ });
});
context(@"when artworks are static icons", ^{
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicUpdateOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicUpdateOperationSpec.m
index 77760bb07..b03252c25 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicUpdateOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicUpdateOperationSpec.m
@@ -820,18 +820,37 @@ describe(@"the text and graphic operation", ^{
updatedState.textField1 = field1String;
updatedState.primaryGraphic = testArtwork;
updatedState.secondaryGraphic = testArtwork2;
+ });
+ it(@"should send a show and not upload any artworks", ^{
testOp = [[SDLTextAndGraphicUpdateOperation alloc] initWithConnectionManager:testConnectionManager fileManager:mockFileManager currentCapabilities:windowCapability currentScreenData:emptyCurrentData newState:updatedState currentScreenDataUpdatedHandler:^(SDLTextAndGraphicState * _Nullable newScreenData, NSError * _Nullable error) {} updateCompletionHandler:nil];
[testOp start];
- });
- it(@"should send a show and not upload any artworks", ^{
expect(testConnectionManager.receivedRequests).to(haveCount(1));
SDLShow *firstSentRequest = testConnectionManager.receivedRequests[0];
expect(firstSentRequest.mainField1).to(equal(field1String));
expect(firstSentRequest.mainField2).to(beEmpty());
expect(firstSentRequest.graphic).toNot(beNil());
expect(firstSentRequest.secondaryGraphic).to(beNil());
+ OCMReject([mockFileManager uploadArtworks:[OCMArg any] progressHandler:[OCMArg any] completionHandler:[OCMArg any]]);
+ });
+
+ it(@"should properly overwrite artwork", ^{
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
+ SDLArtwork *testArtwork3 = [[SDLArtwork alloc] initWithData:[@"Test data 3" dataUsingEncoding:NSUTF8StringEncoding] name:testArtworkName fileExtension:@"png" persistent:NO];
+ testArtwork3.overwrite = YES;
+
+ SDLTextAndGraphicState *updatedState2 = [[SDLTextAndGraphicState alloc] init];
+ updatedState2.textField1 = field1String;
+ updatedState2.primaryGraphic = testArtwork3;
+ updatedState2.secondaryGraphic = testArtwork2;
+
+ SDLTextAndGraphicUpdateOperation *testOp2 = [[SDLTextAndGraphicUpdateOperation alloc] initWithConnectionManager:testConnectionManager fileManager:mockFileManager currentCapabilities:windowCapability currentScreenData:updatedState newState:updatedState2 currentScreenDataUpdatedHandler:^(SDLTextAndGraphicState * _Nullable newScreenData, NSError * _Nullable error) {} updateCompletionHandler:nil];
+ [testOp2 start];
+
+ [testConnectionManager respondToLastRequestWithResponse:successShowResponse];
+
+ OCMVerify([mockFileManager uploadArtworks:[OCMArg any] progressHandler:[OCMArg any] completionHandler:[OCMArg any]]);
});
});
@@ -868,6 +887,7 @@ describe(@"the text and graphic operation", ^{
// when there is text to update as well
context(@"when there is text to update as well", ^{
beforeEach(^{
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
updatedState = [[SDLTextAndGraphicState alloc] init];
updatedState.textField1 = field1String;
updatedState.primaryGraphic = testArtwork;
@@ -943,6 +963,7 @@ describe(@"the text and graphic operation", ^{
// when there is no text to update
context(@"when there is no text to update", ^{
beforeEach(^{
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
updatedState = [[SDLTextAndGraphicState alloc] init];
updatedState.primaryGraphic = testArtwork;
@@ -972,6 +993,7 @@ describe(@"the text and graphic operation", ^{
// when the image is a static icon
context(@"when the image is a static icon", ^{
beforeEach(^{
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(NO);
updatedState = [[SDLTextAndGraphicState alloc] init];
updatedState.primaryGraphic = testStaticIcon;
@@ -998,6 +1020,7 @@ describe(@"the text and graphic operation", ^{
context(@"if the images for the primary and secondary graphics fail the upload process", ^{
beforeEach(^{
OCMStub([mockFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(NO);
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
NSArray<NSString *> *testSuccessfulArtworks = @[];
NSError *testError = [NSError errorWithDomain:@"errorDomain"
code:9
@@ -1030,6 +1053,7 @@ describe(@"the text and graphic operation", ^{
NSArray<NSString *> *testSuccessfulArtworks = @[testArtwork.name];
NSError *testError = [NSError errorWithDomain:@"errorDomain" code:9 userInfo:@{testArtwork2.name:@"error 2"}];
OCMStub([mockFileManager uploadArtworks:[OCMArg isNotNil] progressHandler:[OCMArg isNotNil] completionHandler:([OCMArg invokeBlockWithArgs:testSuccessfulArtworks, testError, nil])]);
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
updatedState = [[SDLTextAndGraphicState alloc] init];
updatedState.textField1 = field1String;
updatedState.primaryGraphic = testArtwork;
@@ -1058,6 +1082,7 @@ describe(@"the text and graphic operation", ^{
NSArray<NSString *> *testSuccessfulArtworks = @[testArtwork2.name];
NSError *testError = [NSError errorWithDomain:@"errorDomain" code:9 userInfo:@{testArtwork.name:@"error 2"}];
OCMStub([mockFileManager uploadArtworks:[OCMArg isNotNil] progressHandler:[OCMArg isNotNil] completionHandler:([OCMArg invokeBlockWithArgs:testSuccessfulArtworks, testError, nil])]);
+ OCMStub([mockFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
updatedState = [[SDLTextAndGraphicState alloc] init];
updatedState.textField1 = field1String;
updatedState.primaryGraphic = testArtwork;
diff --git a/SmartDeviceLinkTests/SDLSoftButtonReplaceOperationSpec.m b/SmartDeviceLinkTests/SDLSoftButtonReplaceOperationSpec.m
index 623ec427c..3b4669d78 100644
--- a/SmartDeviceLinkTests/SDLSoftButtonReplaceOperationSpec.m
+++ b/SmartDeviceLinkTests/SDLSoftButtonReplaceOperationSpec.m
@@ -44,6 +44,7 @@ describe(@"a soft button replace operation", ^{
__block NSString *object2State2ArtworkName = @"O2S2 Artwork";
__block SDLArtwork *object2State1Art = nil;
__block SDLArtwork *object2State2Art = nil;
+ __block SDLArtwork *object2State11Art = nil;
__block SDLSoftButtonState *object2State1 = nil;
__block SDLSoftButtonState *object2State2 = nil;
__block SDLSoftButtonObject *buttonWithTextAndImage = nil;
@@ -97,6 +98,8 @@ describe(@"a soft button replace operation", ^{
object2State1Art = [[SDLArtwork alloc] initWithData:[@"TestData" dataUsingEncoding:NSUTF8StringEncoding] name:object2State1ArtworkName fileExtension:@"png" persistent:YES];
object2State2Art = [[SDLArtwork alloc] initWithData:[@"TestData2" dataUsingEncoding:NSUTF8StringEncoding] name:object2State2ArtworkName fileExtension:@"png" persistent:YES];
+ object2State11Art = [[SDLArtwork alloc] initWithData:[@"TestData11" dataUsingEncoding:NSUTF8StringEncoding] name:object2State1ArtworkName fileExtension:@"png" persistent:YES];
+ object2State11Art.overwrite = YES;
object2State1 = [[SDLSoftButtonState alloc] initWithStateName:object2State1Name text:object2State1Text artwork:object2State1Art];
object2State2 = [[SDLSoftButtonState alloc] initWithStateName:object2State2Name text:object2State2Text artwork:object2State2Art];
buttonWithTextAndImage = [[SDLSoftButtonObject alloc] initWithName:object2Name states:@[object2State1, object2State2] initialStateName:object2State1.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {}];
@@ -162,6 +165,7 @@ describe(@"a soft button replace operation", ^{
context(@"When a response is received to the upload", ^{
beforeEach(^{
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg any]]);
[testOp start];
});
@@ -278,7 +282,7 @@ describe(@"a soft button replace operation", ^{
it(@"should not upload artworks", ^{
OCMReject([testFileManager uploadArtworks:[OCMArg any] progressHandler:nil completionHandler:nil]);
-
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg any]]).andReturn(NO);
[testOp start];
OCMVerifyAllWithDelay(testFileManager, 0.5);
@@ -296,8 +300,22 @@ describe(@"a soft button replace operation", ^{
expect(sentRequests.firstObject.softButtons.lastObject.type).to(equal(SDLSoftButtonTypeBoth));
});
+ it(@"should properly overwrite artwork", ^{
+ OCMExpect([testFileManager uploadArtworks:[OCMArg any] progressHandler:[OCMArg any] completionHandler:[OCMArg any]]);
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg any]]);
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
+ object2State1 = [[SDLSoftButtonState alloc] initWithStateName:object2State1Name text:object2State1Text artwork:object2State11Art];
+ buttonWithTextAndImage = [[SDLSoftButtonObject alloc] initWithName:object2Name states:@[object2State1, object2State2] initialStateName:object2State1.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {}];
+ testSoftButtonObjects = @[buttonWithText, buttonWithTextAndImage];
+ testOp = [[SDLSoftButtonReplaceOperation alloc] initWithConnectionManager:testConnectionManager fileManager:testFileManager capabilities:capabilities softButtonObjects:testSoftButtonObjects mainField1:testMainField1];
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg any]]);
+ [testOp start];
+ OCMVerify([testFileManager uploadArtworks:[OCMArg any] progressHandler:[OCMArg any] completionHandler:[OCMArg any]]);
+ });
+
context(@"When a response is received to the upload", ^{
beforeEach(^{
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg any]]).andReturn(NO);
[testOp start];
});
@@ -324,6 +342,7 @@ describe(@"a soft button replace operation", ^{
context(@"when artworks are static icons", ^{
beforeEach(^{
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(NO);
testSoftButtonObjects = @[buttonWithTextAndStaticImage];
testOp = [[SDLSoftButtonReplaceOperation alloc] initWithConnectionManager:testConnectionManager fileManager:testFileManager capabilities:capabilities softButtonObjects:testSoftButtonObjects mainField1:testMainField1];
@@ -371,8 +390,11 @@ describe(@"a soft button replace operation", ^{
it(@"should upload all artworks", ^{
// Check that the artworks in the initial button states are uploaded
OCMExpect([testFileManager uploadArtworks:@[buttonWithTextAndImage.states[0].artwork] progressHandler:[OCMArg invokeBlock] completionHandler:[OCMArg invokeBlock]]);
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg any]]);
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
testSoftButtonObjects = @[buttonWithText, buttonWithTextAndImage];
testOp = [[SDLSoftButtonReplaceOperation alloc] initWithConnectionManager:testConnectionManager fileManager:testFileManager capabilities:capabilities softButtonObjects:testSoftButtonObjects mainField1:testMainField1];
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg any]]);
[testOp start];
OCMVerifyAllWithDelay(testFileManager, 0.5);
@@ -407,14 +429,19 @@ describe(@"a soft button replace operation", ^{
it(@"should upload all artworks even if the initial state does not have artworks", ^{
OCMReject([testFileManager uploadFiles:[OCMArg any] progressHandler:[OCMArg invokeBlock] completionHandler:[OCMArg invokeBlock]]);
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(NO);
+ OCMExpect([testFileManager fileNeedsUpload:[OCMArg isNil]]).andReturn(NO);
// buttonWithTextAndImage2 has text in the first state and an text and image in the second & third states
testSoftButtonObjects = @[buttonWithTextAndStaticImage, buttonWithTextAndImage2];
testOp = [[SDLSoftButtonReplaceOperation alloc] initWithConnectionManager:testConnectionManager fileManager:testFileManager capabilities:capabilities softButtonObjects:testSoftButtonObjects mainField1:testMainField1];
+
[testOp start];
OCMVerifyAllWithDelay(testFileManager, 0.5);
NSArray<SDLArtwork *> *testArtworkUploads = @[buttonWithTextAndImage2.states[1].artwork, buttonWithTextAndImage2.states[2].artwork];
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
OCMExpect([testFileManager uploadArtworks:testArtworkUploads progressHandler:[OCMArg invokeBlock] completionHandler:[OCMArg invokeBlock]]);
[testConnectionManager respondToLastRequestWithResponse:successResponse];
OCMVerifyAllWithDelay(testFileManager, 0.5);
@@ -445,6 +472,7 @@ describe(@"a soft button replace operation", ^{
context(@"When a response is received to the upload", ^{
beforeEach(^{
+ OCMStub([testFileManager fileNeedsUpload:[OCMArg isNotNil]]).andReturn(YES);
OCMExpect([testFileManager uploadArtworks:[OCMArg isNotNil] progressHandler:[OCMArg invokeBlock] completionHandler:[OCMArg invokeBlock]]);
testSoftButtonObjects = @[buttonWithTextAndImage];