Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support categories #152

Merged
merged 6 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
build:
runs-on: macos-latest
runs-on: macos-12
steps:
- name: Checkout project
uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ui-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
build:
runs-on: macos-latest
runs-on: macos-12
steps:
- name: Checkout project
uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion AffirmSDK/AffirmClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ + (nullable AffirmResponse *)parseError:(NSData *)data
NSString *message = [responseObject valueForKey:@"message"];
NSNumber *statusCode = [responseObject valueForKey:@"status_code"];
NSString *type = [responseObject valueForKey:@"type"];

return [[AffirmErrorResponse alloc] initWithMessage:message code:code field:field type:type statusCode:statusCode];
}

Expand Down
88 changes: 86 additions & 2 deletions AffirmSDK/AffirmItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@

NS_ASSUME_NONNULL_BEGIN

/**
An AffirmCategory object represents the details of categories.
*/
@interface AffirmCategory : NSObject <NSCopying>

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

/**
The name of the categories. Optional.
*/
@property (nonatomic, copy, readonly, nullable) NSString *name;

/**
The sub categories. Required.
*/
@property (nonatomic, copy, readonly) NSArray<NSString *> *subCategories;

/**
Initializer. See properties for more details.

@param name Categories name.
@param subCategories All of sub categories.
@return The initialized category.
*/
- (instancetype)initWithName:(NSString *)name
subCategories:(NSArray<NSString *> *)subCategories
NS_SWIFT_NAME(init(name:subCategories:));

/**
Convenience constructor. See properties for more details.

@param name Item name.
@param subCategories All of sub categories.
@return The newly created category.
*/
+ (AffirmCategory *)categoryWithName:(NSString *)name
subCategories:(NSArray<NSString *> *)subCategories;

@end

/**
An AffirmItem object represents an item that is purchased.
*/
Expand Down Expand Up @@ -50,8 +91,13 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, copy, readonly) NSURL *imageURL;

/**
Convenience constructor. See properties for more details.
An array of lists that indicate the various categories that apply to this product, and the hierarchy of those category definitions. Each list in the array contains one or more comma-separated strings, with the first string being the highest-level (widest) category. Optional.
*/
@property(nonatomic, copy, readonly, nullable) NSArray<AffirmCategory *> *categories;

/**
Convenience constructor. See properties for more details.

@param name Item name.
@param SKU Item SKU.
@param unitPrice Price per item.
Expand All @@ -67,8 +113,27 @@ NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(item(name:sku:unitPrice:quantity:url:));

/**
Initializer. See properties for more details.
Convenience constructor. See properties for more details.

@param name Item name.
@param SKU Item SKU.
@param unitPrice Price per item.
@param quantity Number of items purchased.
@param URL URL of the item.
@param categories An array of lists that indicate the various categories that apply to this product, and the hierarchy of those category definitions.
@return The newly created item.
*/
+ (AffirmItem *)itemWithName:(NSString *)name
SKU:(NSString *)SKU
unitPrice:(NSDecimalNumber *)unitPrice
quantity:(NSInteger)quantity
URL:(NSURL *)URL
categories:(nullable NSArray<AffirmCategory *> *)categories
NS_SWIFT_NAME(item(name:sku:unitPrice:quantity:url:categories:));

/**
Initializer. See properties for more details.

@param name Item name.
@param SKU Item SKU.
@param unitPrice Price per item.
Expand All @@ -83,6 +148,25 @@ NS_SWIFT_NAME(item(name:sku:unitPrice:quantity:url:));
URL:(NSURL *)URL
NS_SWIFT_NAME(init(name:sku:unitPrice:quantity:url:));

/**
Initializer. See properties for more details.

@param name Item name.
@param SKU Item SKU.
@param unitPrice Price per item.
@param quantity Number of items purchased.
@param URL URL of the item.
@param categories An array of lists that indicate the various categories that apply to this product, and the hierarchy of those category definitions.
@return The initialized item.
*/
- (instancetype)initWithName:(NSString *)name
SKU:(NSString *)SKU
unitPrice:(NSDecimalNumber *)unitPrice
quantity:(NSInteger)quantity
URL:(NSURL *)URL
categories:(nullable NSArray<AffirmCategory *> *)categories
NS_SWIFT_NAME(init(name:sku:unitPrice:quantity:url:categories:));

@end

NS_ASSUME_NONNULL_END
78 changes: 77 additions & 1 deletion AffirmSDK/AffirmItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,34 @@
#import "AffirmItem.h"
#import "AffirmUtils.h"

@implementation AffirmCategory

- (instancetype)initWithName:(NSString *)name
subCategories:(NSArray<NSString *> *)subCategories
{
[AffirmValidationUtils checkNotNil:subCategories name:@"subCategories"];

if (self = [super init]) {
_name = [name copy];
_subCategories = [subCategories copy];
}
return self;
}

+ (AffirmCategory *)categoryWithName:(NSString *)name
subCategories:(NSArray<NSString *> *)subCategories
{
return [[self alloc] initWithName:name subCategories:subCategories];
}

- (id)copyWithZone:(NSZone *)zone
{
return [[self class] categoryWithName:self.name
subCategories:self.subCategories];
}

@end

@implementation AffirmItem

- (instancetype)initWithName:(NSString *)name
Expand All @@ -23,13 +51,38 @@ - (instancetype)initWithName:(NSString *)name
[AffirmValidationUtils checkNotNegative:unitPrice name:@"unitPrice"];
[AffirmValidationUtils checkNotNegative:[NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:quantity] decimalValue]] name:@"quantity"];
[AffirmValidationUtils checkNotNil:URL name:@"URL"];

if (self = [super init]) {
_name = [name copy];
_SKU = [SKU copy];
_unitPrice = [unitPrice copy];
_quantity = quantity;
_URL = [URL copy];
}
return self;
}

- (instancetype)initWithName:(NSString *)name
SKU:(NSString *)SKU
unitPrice:(NSDecimalNumber *)unitPrice
quantity:(NSInteger)quantity
URL:(NSURL *)URL
categories:(nullable NSArray<AffirmCategory *> *)categories
{
[AffirmValidationUtils checkNotNil:name name:@"name"];
[AffirmValidationUtils checkNotNil:SKU name:@"SKU"];
[AffirmValidationUtils checkNotNil:unitPrice name:@"unitPrice"];
[AffirmValidationUtils checkNotNegative:unitPrice name:@"unitPrice"];
[AffirmValidationUtils checkNotNegative:[NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:quantity] decimalValue]] name:@"quantity"];
[AffirmValidationUtils checkNotNil:URL name:@"URL"];

if (self = [super init]) {
_name = [name copy];
_SKU = [SKU copy];
_unitPrice = [unitPrice copy];
_quantity = quantity;
_URL = [URL copy];
_categories = [categories copy];
}
return self;
}
Expand All @@ -47,6 +100,21 @@ + (AffirmItem *)itemWithName:(NSString *)name
URL:URL];
}

+ (AffirmItem *)itemWithName:(NSString *)name
SKU:(NSString *)SKU
unitPrice:(NSDecimalNumber *)unitPrice
quantity:(NSInteger)quantity
URL:(NSURL *)URL
categories:(nullable NSArray<AffirmCategory *> *)categories
{
return [[self alloc] initWithName:name
SKU:SKU
unitPrice:unitPrice
quantity:quantity
URL:URL
categories:categories];
}

- (NSDictionary *)toJSONDictionary
{
NSMutableDictionary *json = [@{
Expand All @@ -58,6 +126,13 @@ - (NSDictionary *)toJSONDictionary
if (![self.URL isFileURL] && ([self.URL.scheme isEqualToString:@"http"] || [self.URL.scheme isEqualToString:@"https"] || [self.URL.scheme length] == 0)) {
json[@"item_url"] = [self.URL absoluteString];
}
if (self.categories) {
NSMutableArray *allSubcategories = [NSMutableArray array];
for (AffirmCategory *category in self.categories) {
[allSubcategories addObject:category.subCategories];
}
json[@"categories"] = allSubcategories;
}
return json;
}

Expand All @@ -67,7 +142,8 @@ - (id)copyWithZone:(NSZone *)zone
SKU:self.SKU
unitPrice:self.unitPrice
quantity:self.quantity
URL:self.URL];
URL:self.URL
categories:self.categories];
}

@end
7 changes: 4 additions & 3 deletions AffirmSDKTests/AffirmPromoMsgTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ - (void)setUp
- (void)testCalculatePrice
{
XCTestExpectation *expectation = [self expectationWithDescription:@"start calculate price 500"];
AffirmPromoRequest *request = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"promo_set_ios" amount:[NSDecimalNumber decimalNumberWithString:@"500"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
AffirmPromoRequest *request = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"" amount:[NSDecimalNumber decimalNumberWithString:@"500"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
NSLog(@"%@", request.parameters);
[AffirmPromoClient send:request handler:^(AffirmResponse * _Nullable response, NSError * _Nonnull error) {
XCTAssertNil(error);
XCTAssertTrue([response isKindOfClass:[AffirmPromoResponse class]]);
Expand All @@ -35,7 +36,7 @@ - (void)testCalculatePrice
[self waitForExpectationsWithTimeout:10 handler:nil];

XCTestExpectation *expectation2 = [self expectationWithDescription:@"start calculate price 100"];
AffirmPromoRequest *request2 = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"promo_set_ios" amount:[NSDecimalNumber decimalNumberWithString:@"100"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
AffirmPromoRequest *request2 = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"" amount:[NSDecimalNumber decimalNumberWithString:@"100"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
[AffirmPromoClient send:request2 handler:^(AffirmResponse * _Nullable response, NSError * _Nonnull error) {
XCTAssertNil(error);
XCTAssertTrue([response isKindOfClass:[AffirmPromoResponse class]]);
Expand All @@ -48,7 +49,7 @@ - (void)testCalculatePrice
- (void)testRequestPromoFailed
{
XCTestExpectation *expectation = [self expectationWithDescription:@"start calculate price 50000"];
AffirmPromoRequest *request = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"promo_set_ios" amount:[NSDecimalNumber decimalNumberWithString:@"50000"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
AffirmPromoRequest *request = [[AffirmPromoRequest alloc] initWithPublicKey:[AffirmConfiguration sharedInstance].publicKey promoId:@"" amount:[NSDecimalNumber decimalNumberWithString:@"50000"] showCTA:YES pageType:nil logoType:@"text" logoColor:@"blue"];
[AffirmPromoClient send:request handler:^(AffirmResponse * _Nullable response, NSError * _Nonnull error) {
XCTAssertNil(error);
XCTAssertNotNil(response);
Expand Down
10 changes: 8 additions & 2 deletions Examples/Examples/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ - (IBAction)checkout:(id)sender
SKU:@"test_item"
unitPrice:dollarPrice
quantity:1
URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]];
URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]
categories:@[[AffirmCategory categoryWithName:@"Category 1" subCategories:@[@"Apparel", @"Pants"]],
[AffirmCategory categoryWithName:@"Category 2" subCategories:@[@"Mens", @"Apparel", @"Pants"]]]];

AffirmShippingDetail *shipping = [AffirmShippingDetail shippingDetailWithName:@"Chester Cheetah"
addressWithLine1:@"633 Folsom Street"
line2:@""
Expand Down Expand Up @@ -148,7 +151,9 @@ - (IBAction)showFailedCheckout:(id)sender
SKU:@"test_item"
unitPrice:dollarPrice
quantity:1
URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]];
URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]
categories:@[[AffirmCategory categoryWithName:@"Category 1" subCategories:@[@"Apparel", @"Pants"]],
[AffirmCategory categoryWithName:@"Category 2" subCategories:@[@"Mens", @"Apparel", @"Pants"]]]];
AffirmShippingDetail *shipping = [AffirmShippingDetail shippingDetailWithName:@"Test Tester"
email:@"testtester@test.com"
phoneNumber:@"1111111111"
Expand Down Expand Up @@ -337,6 +342,7 @@ - (void)configurPromotionalMessage
quantity:1
URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]];


NSURL *fontURL = [NSURL URLWithString:@"https://fonts.googleapis.com/css?family=Saira+Stencil+One&display=swap"];
NSURL *cssURL = [[NSBundle mainBundle] URLForResource:@"css_promo_sample" withExtension:@"css"];

Expand Down
2 changes: 1 addition & 1 deletion Examples/ExamplesUITests/ExamplesUITests.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ - (void)testBuyWithAffirm
[self.app.buttons[@"OK"] tap];
} else {
XCUIElement *phoneElement = [self.app.textFields softMatchingWithSubstring:@"Mobile number"];
[self waitForElement:phoneElement duration:10];
[self waitForElement:phoneElement duration:15];
XCTAssertTrue(phoneElement.exists);
}
}
Expand Down
Loading