diff --git a/CHANGELOG b/CHANGELOG index 380ac5dfc0b..4734b76686a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ == X.Y.Z 2017-XX-YY +* Adds nullability annotations to `STPPaymentMethod` protocol * Improves the `[STPAPIResponseDecodable allResponseFields]` by removing all instances of `[NSNull null]` including ones that are nested. See MIGRATING.md. == 11.2.0 2017-07-27 diff --git a/Stripe.xcodeproj/project.pbxproj b/Stripe.xcodeproj/project.pbxproj index c3c70ede2e3..629020238e9 100644 --- a/Stripe.xcodeproj/project.pbxproj +++ b/Stripe.xcodeproj/project.pbxproj @@ -342,6 +342,7 @@ 8B5B4B441EFDD925005CF475 /* STPSourceOwnerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */; }; 8B6DC9751F0171D20025E811 /* STPSourceReceiverTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */; }; 8B6DC9771F0172640025E811 /* STPSourceSEPADebitDetailsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */; }; + 8B82C5CA1F2BC78F009639F7 /* STPApplePayPaymentMethodTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B82C5C91F2BC78F009639F7 /* STPApplePayPaymentMethodTest.m */; }; 8B8DDBB31EF887A4004B141F /* STPBankAccountParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */; }; 8BB97F081F26645B0095122A /* NSDictionary+StripeTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BB97F071F26645B0095122A /* NSDictionary+StripeTest.m */; }; 8BD213371F044B57007F6FD1 /* BankAccount.json in Resources */ = {isa = PBXBuildFile; fileRef = 8BD213361F044B57007F6FD1 /* BankAccount.json */; }; @@ -984,6 +985,7 @@ 8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceOwnerTest.m; sourceTree = ""; }; 8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceReceiverTest.m; sourceTree = ""; }; 8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceSEPADebitDetailsTest.m; sourceTree = ""; }; + 8B82C5C91F2BC78F009639F7 /* STPApplePayPaymentMethodTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPApplePayPaymentMethodTest.m; sourceTree = ""; }; 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPBankAccountParamsTest.m; sourceTree = ""; }; 8BB97F071F26645B0095122A /* NSDictionary+StripeTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+StripeTest.m"; sourceTree = ""; }; 8BD213361F044B57007F6FD1 /* BankAccount.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = BankAccount.json; sourceTree = ""; }; @@ -1551,6 +1553,7 @@ C15B02721EA176090026E606 /* StripeErrorTest.m */, F1D3A25E1EB015B30095BFA9 /* UIImage+StripeTests.m */, F1122A7D1DFB84E000A8B1AF /* UINavigationBar+StripeTest.m */, + 8B82C5C91F2BC78F009639F7 /* STPApplePayPaymentMethodTest.m */, ); name = Unit; sourceTree = ""; @@ -2662,6 +2665,7 @@ C1CFCB751ED5E12400BE45DF /* STPFileTest.m in Sources */, C11810991CC6D46D0022FB55 /* NSDecimalNumber+StripeTest.m in Sources */, 8B5B4B441EFDD925005CF475 /* STPSourceOwnerTest.m in Sources */, + 8B82C5CA1F2BC78F009639F7 /* STPApplePayPaymentMethodTest.m in Sources */, 8B013C891F1E784A00DD831B /* STPPaymentConfigurationTest.m in Sources */, C1EEDCC81CA2172700A54582 /* NSString+StripeTest.m in Sources */, 8BD87B901EFB17AA00269C2B /* STPSourceRedirectTest.m in Sources */, diff --git a/Stripe/PublicHeaders/STPApplePayPaymentMethod.h b/Stripe/PublicHeaders/STPApplePayPaymentMethod.h index c2e81c28c12..cc2019be77d 100644 --- a/Stripe/PublicHeaders/STPApplePayPaymentMethod.h +++ b/Stripe/PublicHeaders/STPApplePayPaymentMethod.h @@ -10,12 +10,15 @@ #import "STPPaymentMethod.h" /** - An empty class representing that the user wishes to pay via Apple Pay. This can be checked on an `STPPaymentContext`, e.g. - - `if ([paymentContext.selectedPaymentMethod isKindOfClass:[STPApplePayPaymentMethod class]]) { - // don't ask the user for their card number; they want to pay with apple pay. - }` - + An empty class representing that the user wishes to pay via Apple Pay. This can + be checked on an `STPPaymentContext`, e.g: + + ``` + if ([paymentContext.selectedPaymentMethod isKindOfClass:[STPApplePayPaymentMethod class]]) { + // Don't ask the user for their card number; they want to pay with apple pay. + } + ``` */ @interface STPApplePayPaymentMethod : NSObject + @end diff --git a/Stripe/PublicHeaders/STPPaymentMethod.h b/Stripe/PublicHeaders/STPPaymentMethod.h index 41ce3a5b9ee..8a94163ffb3 100644 --- a/Stripe/PublicHeaders/STPPaymentMethod.h +++ b/Stripe/PublicHeaders/STPPaymentMethod.h @@ -8,44 +8,57 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** - This represents all of the payment methods available to your user (in addition to card payments, which are always enabled) when configuring an `STPPaymentContext`. + This represents all of the payment methods available to your user when + configuring an `STPPaymentContext`. This is in addition to card payments, which + are always enabled. */ typedef NS_OPTIONS(NSUInteger, STPPaymentMethodType) { - /** - Don't use any payment methods except for cards. + Don't allow any payment methods except for cards. */ STPPaymentMethodTypeNone = 0, - + /** - The user is allowed to pay with Apple Pay (if it's configured and available on their device). + The user is allowed to pay with Apple Pay if it's configured and available + on their device. */ STPPaymentMethodTypeApplePay = 1 << 0, + /** - The user can use any available payment method to pay. + The user is allowed to use any available payment method to pay. */ STPPaymentMethodTypeAll = STPPaymentMethodTypeApplePay }; /** - This protocol represents a payment method that a user can select and use to pay. Currently the only classes that conform to it are `STPCard` (which represents that the user wants to pay with a specific card) and `STPApplePayPaymentMethod` (which represents that the user wants to pay with Apple Pay). + This protocol represents a payment method that a user can select and use to + pay. Currently the only classes that conform to it are `STPCard`, which + represents that the user wants to pay with a specific card, and + `STPApplePayPaymentMethod`, which represents that the user wants to pay with + Apple Pay. */ @protocol STPPaymentMethod /** - A small (32 x 20 points) logo image representing the payment method. For example, the Visa logo for a Visa card, or the Apple Pay logo. + A small (32 x 20 points) logo image representing the payment method. For + example, the Visa logo for a Visa card, or the Apple Pay logo. */ -@property (nonatomic, readonly) UIImage *image; +@property (nonatomic, strong, readonly) UIImage *image; /** - A small (32 x 20 points) logo image representing the payment method that can be used as template for tinted icons. + A small (32 x 20 points) logo image representing the payment method that can be + used as template for tinted icons. */ -@property (nonatomic, readonly) UIImage *templateImage; +@property (nonatomic, strong, readonly) UIImage *templateImage; /** A string describing the payment method, such as "Apple Pay" or "Visa 4242". */ -@property (nonatomic, readonly) NSString *label; +@property (nonatomic, strong, readonly) NSString *label; @end + +NS_ASSUME_NONNULL_END diff --git a/Stripe/STPApplePayPaymentMethod.m b/Stripe/STPApplePayPaymentMethod.m index 0fca9f7f148..05390e83372 100644 --- a/Stripe/STPApplePayPaymentMethod.m +++ b/Stripe/STPApplePayPaymentMethod.m @@ -8,12 +8,14 @@ #import "STPApplePayPaymentMethod.h" -#import "STPImageLibrary+Private.h" #import "STPImageLibrary.h" +#import "STPImageLibrary+Private.h" #import "STPLocalizationUtils.h" @implementation STPApplePayPaymentMethod +#pragma mark - STPPaymentMethod + - (UIImage *)image { return [STPImageLibrary applePayCardImage]; } @@ -27,6 +29,8 @@ - (NSString *)label { return STPLocalizedString(@"Apple Pay", @"Text for Apple Pay payment method"); } +#pragma mark - Equality + - (BOOL)isEqual:(id)object { return [object isKindOfClass:[STPApplePayPaymentMethod class]]; } diff --git a/Stripe/STPCard.m b/Stripe/STPCard.m index 7edae7b4194..fbef1d53778 100644 --- a/Stripe/STPCard.m +++ b/Stripe/STPCard.m @@ -248,10 +248,7 @@ - (NSString *)stripeID { return self.cardId; } -- (NSString *)label { - NSString *brand = [self.class stringFromBrand:self.brand]; - return [NSString stringWithFormat:@"%@ %@", brand, self.last4]; -} +#pragma mark - STPPaymentMethod - (UIImage *)image { return [STPImageLibrary brandImageForCardBrand:self.brand]; @@ -261,4 +258,9 @@ - (UIImage *)templateImage { return [STPImageLibrary templatedBrandImageForCardBrand:self.brand]; } +- (NSString *)label { + NSString *brand = [self.class stringFromBrand:self.brand]; + return [NSString stringWithFormat:@"%@ %@", brand, self.last4]; +} + @end diff --git a/Tests/Tests/STPApplePayPaymentMethodTest.m b/Tests/Tests/STPApplePayPaymentMethodTest.m new file mode 100644 index 00000000000..639a9f94f5a --- /dev/null +++ b/Tests/Tests/STPApplePayPaymentMethodTest.m @@ -0,0 +1,50 @@ +// +// STPApplePayPaymentMethodTest.m +// Stripe +// +// Created by Joey Dong on 7/28/17. +// Copyright © 2017 Stripe, Inc. All rights reserved. +// + +#import + +#import "STPApplePayPaymentMethod.h" + +@interface STPApplePayPaymentMethodTest : XCTestCase + +@end + +@implementation STPApplePayPaymentMethodTest + +#pragma mark - STPPaymentMethod Tests + +- (void)testImage { + STPApplePayPaymentMethod *applePay = [[STPApplePayPaymentMethod alloc] init]; + XCTAssert([applePay image]); +} + +- (void)testTemplateImage { + STPApplePayPaymentMethod *applePay = [[STPApplePayPaymentMethod alloc] init]; + XCTAssert([applePay templateImage]); +} + +- (void)testLabel { + STPApplePayPaymentMethod *applePay = [[STPApplePayPaymentMethod alloc] init]; + XCTAssertEqualObjects([applePay label], @"Apple Pay"); +} + +#pragma mark - Equality Tests + +- (void)testApplePayEquals { + STPApplePayPaymentMethod *applePay1 = [[STPApplePayPaymentMethod alloc] init]; + STPApplePayPaymentMethod *applePay2 = [[STPApplePayPaymentMethod alloc] init]; + + XCTAssertNotEqual(applePay1, applePay2); + + XCTAssertEqualObjects(applePay1, applePay1); + XCTAssertEqualObjects(applePay1, applePay2); + + XCTAssertEqual(applePay1.hash, applePay1.hash); + XCTAssertEqual(applePay1.hash, applePay2.hash); +} +@end diff --git a/Tests/Tests/STPCardTest.m b/Tests/Tests/STPCardTest.m index d9a0e74d6bb..5954d5869dd 100644 --- a/Tests/Tests/STPCardTest.m +++ b/Tests/Tests/STPCardTest.m @@ -16,6 +16,8 @@ @interface STPCard () +@property (nonatomic, assign, readwrite) STPCardBrand brand; + - (void)setLast4:(NSString *)last4; - (void)setAllResponseFields:(NSDictionary *)allResponseFields; @@ -56,18 +58,7 @@ - (void)testBrandFromString { } - (void)testStringFromBrand { - NSArray *values = @[ - @(STPCardBrandAmex), - @(STPCardBrandDinersClub), - @(STPCardBrandDiscover), - @(STPCardBrandJCB), - @(STPCardBrandMasterCard), - @(STPCardBrandVisa), - @(STPCardBrandUnknown), - ]; - - for (NSNumber *brandNumber in values) { - STPCardBrand brand = (STPCardBrand)[brandNumber integerValue]; + [self forEachBrand:^(STPCardBrand brand) { NSString *string = [STPCard stringFromBrand:brand]; switch (brand) { @@ -93,7 +84,7 @@ - (void)testStringFromBrand { XCTAssertEqualObjects(string, @"Unknown"); break; } - } + }]; } #pragma mark - STPCardFundingType Tests @@ -306,19 +297,47 @@ - (void)testStripeID { XCTAssertEqualObjects(card.stripeID, @"card_103kbR2eZvKYlo2CDczLmw4K"); } -- (void)testLabel { - STPCard *card = [STPCard decodedObjectFromAPIResponse:[STPTestUtils jsonNamed:@"Card"]]; - XCTAssertEqualObjects(card.label, @"Visa 4242"); -} +#pragma mark - STPPaymentMethod Tests - (void)testImage { - STPCard *card = [STPCard decodedObjectFromAPIResponse:[STPTestUtils jsonNamed:@"Card"]]; - XCTAssert(card.image); + [self forEachBrand:^(STPCardBrand brand) { + STPCard *card = [[STPCard alloc] init]; + card.brand = brand; + + XCTAssert([card image]); + }]; } - (void)testTemplateImage { + [self forEachBrand:^(STPCardBrand brand) { + STPCard *card = [[STPCard alloc] init]; + card.brand = brand; + + XCTAssert([card templateImage]); + }]; +} + +- (void)testLabel { STPCard *card = [STPCard decodedObjectFromAPIResponse:[STPTestUtils jsonNamed:@"Card"]]; - XCTAssert(card.templateImage); + XCTAssertEqualObjects(card.label, @"Visa 4242"); +} + +#pragma mark - + +- (void)forEachBrand:(void (^)(STPCardBrand brand))block { + NSArray *values = @[ + @(STPCardBrandAmex), + @(STPCardBrandDinersClub), + @(STPCardBrandDiscover), + @(STPCardBrandJCB), + @(STPCardBrandMasterCard), + @(STPCardBrandVisa), + @(STPCardBrandUnknown), + ]; + + for (NSNumber *brandNumber in values) { + block((STPCardBrand)[brandNumber integerValue]); + } } @end