Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* [iOS] updated action test

* [iOS] Added vertical constraint to public API and mocks for unit testing

* [iOS] added title width constraint to public api
  • Loading branch information
jwoo-msft authored and michaelfarnsworth committed Nov 9, 2022
1 parent 4d0356f commit 2ed5ff7
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -338,26 +338,26 @@
6B182B9925DF5FB700629A39 /* resources */ = {
isa = PBXGroup;
children = (
6B182BD225E5D7D400629A39 /* bg_image.png */,
6B182BCE25E5AD3500629A39 /* image_3.png */,
6B182B9A25DF5FB700629A39 /* Gray_Dot.png */,
6B182B9B25DF5FB700629A39 /* SeaTacMap.png */,
6B182B9D25DF5FB700629A39 /* LocationRed_C.png */,
6B182B9E25DF5FB700629A39 /* person_w2.png */,
6B182B9F25DF5FB700629A39 /* LocationBlue_B.png */,
6B182BA025DF5FB700629A39 /* SmallVerticalLineGray.png */,
6B182BA725DF5FB700629A39 /* Action.Scrolling.json */,
6B182BA125DF5FB700629A39 /* filebrowserHostConfig.json */,
6B182BA225DF5FB700629A39 /* person_w1.png */,
6B182BA325DF5FB700629A39 /* person_m1.png */,
6B182BA425DF5FB700629A39 /* location_gray.png */,
6B182BA525DF5FB700629A39 /* sample.json */,
6B182BD225E5D7D400629A39 /* bg_image.png */,
6B182BA625DF5FB700629A39 /* car.png */,
6B182BA725DF5FB700629A39 /* Action.Scrolling.json */,
6B182BA825DF5FB700629A39 /* power_point.png */,
6B182BAC25DF5FB700629A39 /* CircleBlue_flight.png */,
6B182BAB25DF5FB700629A39 /* CircleGreen_coffee.png */,
6B182BA925DF5FB700629A39 /* Conflict.png */,
6B182B9A25DF5FB700629A39 /* Gray_Dot.png */,
6B182BCE25E5AD3500629A39 /* image_3.png */,
6B182BA425DF5FB700629A39 /* location_gray.png */,
6B182B9F25DF5FB700629A39 /* LocationBlue_B.png */,
6B182BAA25DF5FB700629A39 /* LocationGreen_A.png */,
6B182BAB25DF5FB700629A39 /* CircleGreen_coffee.png */,
6B182BAC25DF5FB700629A39 /* CircleBlue_flight.png */,
6B182B9D25DF5FB700629A39 /* LocationRed_C.png */,
6B182BA325DF5FB700629A39 /* person_m1.png */,
6B182BA225DF5FB700629A39 /* person_w1.png */,
6B182B9E25DF5FB700629A39 /* person_w2.png */,
6B182BA825DF5FB700629A39 /* power_point.png */,
6B182B9B25DF5FB700629A39 /* SeaTacMap.png */,
6B182BA025DF5FB700629A39 /* SmallVerticalLineGray.png */,
);
path = resources;
sourceTree = "<group>";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
6B1147D11F32E53A008846EC /* ACRActionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B1147D01F32E53A008846EC /* ACRActionDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
6B1147D81F32F922008846EC /* ACRShowCardTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B1147D61F32F922008846EC /* ACRShowCardTarget.h */; settings = {ATTRIBUTES = (Public, ); }; };
6B1147D91F32F922008846EC /* ACRShowCardTarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B1147D71F32F922008846EC /* ACRShowCardTarget.mm */; };
6B124C8C26B4AA07007E9641 /* AdaptiveCardsActionsTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B124C8B26B4AA07007E9641 /* AdaptiveCardsActionsTest.mm */; };
6B124C8E26B4B3CD007E9641 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B124C8D26B4B3CD007E9641 /* UIKit.framework */; };
6B124C9026B8AC37007E9641 /* MockACRView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B124C8F26B8AC37007E9641 /* MockACRView.mm */; };
6B124C9526B8AE72007E9641 /* MockContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B124C9426B8AE72007E9641 /* MockContext.mm */; };
6B22425D21E80647000ACDA1 /* ACOParseContextPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B22425A21E80647000ACDA1 /* ACOParseContextPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
6B22425E21E80647000ACDA1 /* ACOParseContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B22425B21E80647000ACDA1 /* ACOParseContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
6B22425F21E80647000ACDA1 /* ACOParseContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B22425C21E80647000ACDA1 /* ACOParseContext.mm */; };
Expand Down Expand Up @@ -454,6 +458,12 @@
6B1147D01F32E53A008846EC /* ACRActionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRActionDelegate.h; sourceTree = "<group>"; };
6B1147D61F32F922008846EC /* ACRShowCardTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACRShowCardTarget.h; sourceTree = "<group>"; };
6B1147D71F32F922008846EC /* ACRShowCardTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACRShowCardTarget.mm; sourceTree = "<group>"; };
6B124C8B26B4AA07007E9641 /* AdaptiveCardsActionsTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AdaptiveCardsActionsTest.mm; sourceTree = "<group>"; };
6B124C8D26B4B3CD007E9641 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/System/iOSSupport/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
6B124C8F26B8AC37007E9641 /* MockACRView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockACRView.mm; sourceTree = "<group>"; };
6B124C9126B8AC58007E9641 /* MockACRView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockACRView.h; sourceTree = "<group>"; };
6B124C9326B8AE59007E9641 /* MockContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockContext.h; sourceTree = "<group>"; };
6B124C9426B8AE72007E9641 /* MockContext.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockContext.mm; sourceTree = "<group>"; };
6B22425A21E80647000ACDA1 /* ACOParseContextPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACOParseContextPrivate.h; sourceTree = "<group>"; };
6B22425B21E80647000ACDA1 /* ACOParseContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ACOParseContext.h; sourceTree = "<group>"; };
6B22425C21E80647000ACDA1 /* ACOParseContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ACOParseContext.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -846,13 +856,25 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6B124C8E26B4B3CD007E9641 /* UIKit.framework in Frameworks */,
F423C0BF1EE1FBAA00905679 /* AdaptiveCards.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
6B124C9226B8AE3B007E9641 /* Mocks */ = {
isa = PBXGroup;
children = (
6B124C8F26B8AC37007E9641 /* MockACRView.mm */,
6B124C9126B8AC58007E9641 /* MockACRView.h */,
6B124C9326B8AE59007E9641 /* MockContext.h */,
6B124C9426B8AE72007E9641 /* MockContext.mm */,
);
path = Mocks;
sourceTree = "<group>";
};
6B70ABA425797B720095D925 /* InputRenderers */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1082,8 +1104,10 @@
F423C0C21EE1FBAA00905679 /* AdaptiveCardsTests */ = {
isa = PBXGroup;
children = (
6B124C8B26B4AA07007E9641 /* AdaptiveCardsActionsTest.mm */,
30D56DEE2682AB9C00D6E418 /* AdaptiveCardsTextBlockTests.mm */,
30D56DE8268298B300D6E418 /* AdaptiveCardsTests.mm */,
6B124C9226B8AE3B007E9641 /* Mocks */,
);
path = AdaptiveCardsTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -1384,6 +1408,7 @@
F45A07191EF4BC44007C6503 /* Frameworks */ = {
isa = PBXGroup;
children = (
6B124C8D26B4B3CD007E9641 /* UIKit.framework */,
6BB2121721001596009EA1BA /* AVFoundation.framework */,
6BB2120F210013AA009EA1BA /* AVKit.framework */,
F4CA74A320181B52002041DF /* QuartzCore.framework */,
Expand Down Expand Up @@ -1916,8 +1941,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6B124C8C26B4AA07007E9641 /* AdaptiveCardsActionsTest.mm in Sources */,
30D56DEF2682AB9C00D6E418 /* AdaptiveCardsTextBlockTests.mm in Sources */,
6B124C9526B8AE72007E9641 /* MockContext.mm in Sources */,
30D56DE9268298B300D6E418 /* AdaptiveCardsTests.mm in Sources */,
6B124C9026B8AC37007E9641 /* MockACRView.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
@property ACRIconPlacement iconPlacement;
@property ACRActionType actionType;
@property __weak UIImageView *iconView;
@property NSLayoutConstraint *heightConstraint;
@property NSLayoutConstraint *titleWidthConstraint;

+ (UIButton *)rootView:(ACRView *)rootView
baseActionElement:(ACOBaseActionElement *)acoAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,14 @@ - (void)setImageView:(UIImage *)image withConfig:(ACOHostConfig *)config

[NSLayoutConstraint constraintWithItem:_iconView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES;
CGFloat offset = -(self.contentEdgeInsets.left + self.contentEdgeInsets.right);
[self.titleLabel.widthAnchor constraintLessThanOrEqualToAnchor:self.widthAnchor constant:offset].active = YES;

self.titleWidthConstraint = [self.titleLabel.widthAnchor constraintLessThanOrEqualToAnchor:self.widthAnchor constant:offset];
self.titleWidthConstraint.active = YES;

[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.centerXAnchor constant:(widthOffset / 2)].active = YES;
[self.heightAnchor constraintGreaterThanOrEqualToAnchor:self.titleLabel.heightAnchor constant:self.contentEdgeInsets.top + self.contentEdgeInsets.bottom].active = YES;

self.heightConstraint = [self.heightAnchor constraintGreaterThanOrEqualToAnchor:self.titleLabel.heightAnchor constant:self.contentEdgeInsets.top + self.contentEdgeInsets.bottom];
self.heightConstraint.active = YES;
}
}

Expand Down Expand Up @@ -150,7 +155,8 @@ + (UIButton *)rootView:(ACRView *)rootView
}
}
} else {
[button.heightAnchor constraintGreaterThanOrEqualToAnchor:button.titleLabel.heightAnchor constant:button.contentEdgeInsets.top + button.contentEdgeInsets.bottom].active = YES;
button.heightConstraint = [button.heightAnchor constraintGreaterThanOrEqualToAnchor:button.titleLabel.heightAnchor constant:button.contentEdgeInsets.top + button.contentEdgeInsets.bottom];
button.heightConstraint.active = YES;
}

return button;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -872,4 +872,11 @@ - (void)registerImageFromUIImageView:(UIImageView *)imageView key:(NSString *)ke
}
}

- (void)setContext:(ACORenderContext *)context
{
if (context) {
_context = context;
}
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,7 @@ typedef void (^ObserverActionBlockForBaseAction)(NSObject<ACOIResourceResolver>
- (ACOInputResults *)dispatchAndValidateInput:(ACRColumnView *)parent;

- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)path onObject:(NSObject *)object;

- (void)setContext:(ACORenderContext *)context;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// AdaptiveCardsActionsTest.mm
// AdaptiveCardsActionsTest
//
// Copyright © 2021 Microsoft. All rights reserved.
//

#import "ACOBaseActionElementPrivate.h"
#import "ACOHostConfigPrivate.h"
#import "ACRButton.h"
#import "ACRViewPrivate.h"
#import "BaseActionElement.h"
#import "Mocks/MockACRView.h"
#import "Mocks/MockContext.h"
#import "OpenUrlAction.h"
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>

@interface AdaptiveCardsActionsTest : XCTestCase

@end

using namespace AdaptiveCards;

@implementation AdaptiveCardsActionsTest {
MockACRView *_rootView;
}

- (void)setUp
{
// Put setup code here. This method is called before the invocation of each test method in the class.
_rootView = [[MockACRView alloc] initWithFrame:CGRectMake(0, 0, 20, 30)];
}

- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

- (ACOBaseActionElement *)buildSimpleAction
{
std::shared_ptr<OpenUrlAction> action = std::make_shared<OpenUrlAction>();
action->SetTitle("Hello");
action->SetUrl("https://www.bing.com");
ACOBaseActionElement *acoAction = [ACOBaseActionElement getACOActionElementFromAdaptiveElement:action];
return acoAction;
}

- (ACRButton *)buildAButton:(ACOBaseActionElement *)acoAction
{
ACOHostConfig *acoConfig = [[ACOHostConfig alloc] init];
return (ACRButton *)[ACRButton rootView:_rootView baseActionElement:acoAction title:acoAction.title andHostConfig:acoConfig];
}

- (void)testACRButtonPublicConstraints
{
ACRButton *button = [self buildAButton:[self buildSimpleAction]];
XCTAssertNotNil(button);
XCTAssertNotNil(button.heightConstraint);
XCTAssertNil(button.titleWidthConstraint);
}

- (void)testACRButtonPublicConstraintsWithImageView
{
std::string iconURL = "https://adaptivecards.io/content/cats/1.png";
NSString *iconURLObjc = [NSString stringWithCString:iconURL.c_str() encoding:NSUTF8StringEncoding];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:iconURLObjc]]];
ACOBaseActionElement *action = [self buildSimpleAction];
action.element->SetIconUrl(iconURL);
NSString *key = iconURLObjc;
[_rootView getImageMap][key] = image;
ACRButton *button = [self buildAButton:action];
XCTAssertNotNil(button.heightConstraint);
XCTAssertNotNil(button.titleWidthConstraint);
}

- (void)testACRButtonPublicConstraintsWithImageViewWithKey
{
std::string iconURL = "https://adaptivecards.io/content/cats/1.png";
NSString *iconURLObjc = [NSString stringWithCString:iconURL.c_str() encoding:NSUTF8StringEncoding];

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:iconURLObjc]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
ACOBaseActionElement *acoAction = [self buildSimpleAction];
acoAction.element->SetIconUrl(iconURL);
NSNumber *number = [NSNumber numberWithUnsignedLongLong:(unsigned long long)acoAction.element.get()];
NSString *key = [number stringValue];
[_rootView setImageView:key view:imageView];
ACRButton *button = [self buildAButton:acoAction];
XCTAssertNotNil(button.heightConstraint);
XCTAssertNotNil(button.titleWidthConstraint);
}

- (void)testACRButtonPublicConstraintsWithIconPlacements
{
std::string iconURL = "https://adaptivecards.io/content/cats/1.png";
NSString *iconURLObjc = [NSString stringWithCString:iconURL.c_str() encoding:NSUTF8StringEncoding];

UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:iconURLObjc]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
ACOBaseActionElement *acoAction = [self buildSimpleAction];
acoAction.element->SetIconUrl(iconURL);
NSNumber *number = [NSNumber numberWithUnsignedLongLong:(unsigned long long)acoAction.element.get()];
NSString *key = [number stringValue];
_rootView.mockContext = [[MockContext alloc] init];
[_rootView setImageView:key view:imageView];
[_rootView.mockContext setMockValueForAllHasActionIcons:YES];
ACRButton *button = [self buildAButton:acoAction];
XCTAssertNil(button.heightConstraint);
XCTAssertNil(button.titleWidthConstraint);
}

@end

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// MockACRView.h
// AdaptiveCardsTests
//
// Copyright © 2021 Microsoft. All rights reserved.
//

#import "ACRViewPrivate.h"
#import "MockContext.h"

@interface MockACRView : ACRView

@property MockContext *mockContext;

@end

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// MockACRView.m
// AdaptiveCardsTests
//
// Copyright © 2021 Microsoft. All rights reserved.
//

#import "MockACRView.h"
#import "MockContext.h"
#import <Foundation/Foundation.h>

@implementation MockACRView

- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
return self;
}

- (void)setMockContext:(MockContext *)context
{
if (context) {
[self setContext:context];
_mockContext = context;
}
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// MockContext.h
// AdaptiveCards
//
// Copyright © 2021 Microsoft. All rights reserved.
//

#import "ACORenderContext.h"

@interface MockContext : ACORenderContext

- (void)setMockValueForAllHasActionIcons:(BOOL)value;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// MockContext.m
// AdaptiveCardsTests
//
// Copyright © 2021 Microsoft. All rights reserved.
//

#import "MockContext.h"

@implementation MockContext {
BOOL _mockValueForAllHasActionIcons;
}

- (void)setMockValueForAllHasActionIcons:(BOOL)value
{
_mockValueForAllHasActionIcons = value;
}

- (BOOL)allHasActionIcons
{
return _mockValueForAllHasActionIcons;
}

@end

0 comments on commit 2ed5ff7

Please sign in to comment.