Improve test coverage for public models

Add a bunch of test coverage for our public models so that we’re closer
to having a 1:1 correspondence between the implementation and tests

This also shuffles some internal interface definitions into
`*+Private.h` headers so that they’re accessible from tests.
This commit is contained in:
Joey Dong 2017-06-27 10:29:31 -07:00
parent 576a1b6844
commit 9a8799e898
32 changed files with 1050 additions and 191 deletions

View File

@ -338,6 +338,9 @@
8B429ADC1EF9E18400F95F34 /* STPBankAccount+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */; };
8B429ADE1EF9EFF900F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; };
8B429ADF1EF9EFFA00F95F34 /* STPFile+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */; };
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 */; };
8B8DDBB31EF887A4004B141F /* STPBankAccountParamsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */; };
8BD87B881EFB131700269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; };
8BD87B891EFB131800269C2B /* STPSourceCardDetails+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */; };
@ -967,6 +970,9 @@
8B429AD71EF9D4A300F95F34 /* STPBankAccountParams+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccountParams+Private.h"; sourceTree = "<group>"; };
8B429ADA1EF9E15900F95F34 /* STPBankAccount+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPBankAccount+Private.h"; sourceTree = "<group>"; };
8B429ADD1EF9EFF600F95F34 /* STPFile+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPFile+Private.h"; sourceTree = "<group>"; };
8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceOwnerTest.m; sourceTree = "<group>"; };
8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceReceiverTest.m; sourceTree = "<group>"; };
8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceSEPADebitDetailsTest.m; sourceTree = "<group>"; };
8B8DDBB21EF887A4004B141F /* STPBankAccountParamsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPBankAccountParamsTest.m; sourceTree = "<group>"; };
8BD87B871EFB131400269C2B /* STPSourceCardDetails+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "STPSourceCardDetails+Private.h"; sourceTree = "<group>"; };
8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPSourceCardDetailsTest.m; sourceTree = "<group>"; };
@ -1499,8 +1505,11 @@
C1FEE5981CBFF24000A7632B /* STPPostalCodeValidatorTest.m */,
F152321A1EA92F9D00D65C67 /* STPRedirectContextTest.m */,
8BD87B8A1EFB136F00269C2B /* STPSourceCardDetailsTest.m */,
8B5B4B431EFDD925005CF475 /* STPSourceOwnerTest.m */,
C1BD9B1E1E390A2700CEE925 /* STPSourceParamsTest.m */,
8B6DC9741F0171D20025E811 /* STPSourceReceiverTest.m */,
8BD87B8F1EFB17AA00269C2B /* STPSourceRedirectTest.m */,
8B6DC9761F0172640025E811 /* STPSourceSEPADebitDetailsTest.m */,
C17D24ED1E37DBAC005CB188 /* STPSourceTest.m */,
8BD87B941EFB1CB100269C2B /* STPSourceVerificationTest.m */,
F1D777BF1D81DD520076FA19 /* STPStringUtilsTest.m */,
@ -2611,12 +2620,15 @@
04415C681A6605B5001225ED /* STPFormEncoderTest.m in Sources */,
C1CFCB751ED5E12400BE45DF /* STPFileTest.m in Sources */,
C11810991CC6D46D0022FB55 /* NSDecimalNumber+StripeTest.m in Sources */,
8B5B4B441EFDD925005CF475 /* STPSourceOwnerTest.m in Sources */,
C1EEDCC81CA2172700A54582 /* NSString+StripeTest.m in Sources */,
8BD87B901EFB17AA00269C2B /* STPSourceRedirectTest.m in Sources */,
04415C6A1A6605B5001225ED /* STPApplePayFunctionalTest.m in Sources */,
8BE5AE8B1EF8905B0081A33C /* STPCardParamsTest.m in Sources */,
F1D3A25F1EB015B30095BFA9 /* UIImage+StripeTests.m in Sources */,
04415C6B1A6605B5001225ED /* STPBankAccountFunctionalTest.m in Sources */,
8B6DC9751F0171D20025E811 /* STPSourceReceiverTest.m in Sources */,
8B6DC9771F0172640025E811 /* STPSourceSEPADebitDetailsTest.m in Sources */,
04415C6C1A6605B5001225ED /* STPBankAccountTest.m in Sources */,
C19D09931EAEAE5E00A4AB3E /* STPTelemetryClientTest.m in Sources */,
F152321B1EA92F9D00D65C67 /* STPRedirectContextTest.m in Sources */,

View File

@ -8,8 +8,8 @@
#import <Foundation/Foundation.h>
#import "STPAPIResponseDecodable.h"
#import "STPBankAccountParams.h"
#import "STPAPIResponseDecodable.h"
typedef NS_ENUM(NSInteger, STPBankAccountStatus) {
STPBankAccountStatusNew,
@ -19,7 +19,9 @@ typedef NS_ENUM(NSInteger, STPBankAccountStatus) {
};
/**
* Representation of a user's bank account details that have been tokenized with the Stripe API. @see https://stripe.com/docs/api#cards
* Representation of a user's bank account details that have been tokenized with the Stripe API
*
* @see https://stripe.com/docs/api#bank_accounts
*/
@interface STPBankAccount : STPBankAccountParams<STPAPIResponseDecodable>

View File

@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
#import "STPFormEncodable.h"
typedef NS_ENUM(NSInteger, STPBankAccountHolderType) {
@ -16,7 +17,9 @@ typedef NS_ENUM(NSInteger, STPBankAccountHolderType) {
/**
* Representation of a user's bank account details. You can assemble these with information that your user enters and
* then create Stripe tokens with them using an STPAPIClient. @see https://stripe.com/docs/api#create_bank_account_token
* then create Stripe tokens with them using an STPAPIClient.
*
* @see https://stripe.com/docs/api#create_bank_account_token
*/
@interface STPBankAccountParams : NSObject<STPFormEncodable>

View File

@ -27,7 +27,9 @@ typedef NS_ENUM(NSInteger, STPCardFundingType) {
};
/**
* Representation of a user's credit card details that have been tokenized with the Stripe API. @see https://stripe.com/docs/api#cards
* Representation of a user's credit card details that have been tokenized with the Stripe API
*
* @see https://stripe.com/docs/api#cards
*/
@interface STPCard : STPCardParams<STPAPIResponseDecodable, STPPaymentMethod, STPSourceProtocol>

View File

@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
#import "STPFormEncodable.h"
#if TARGET_OS_IPHONE
#import "STPAddress.h"
@ -14,7 +15,9 @@
/**
* Representation of a user's credit card details. You can assemble these with information that your user enters and
* then create Stripe tokens with them using an STPAPIClient. @see https://stripe.com/docs/api#cards
* then create Stripe tokens with them using an STPAPIClient.
*
* @see https://stripe.com/docs/api#cards
*/
@interface STPCardParams : NSObject<STPFormEncodable>

View File

@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@ -34,4 +35,5 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readwrite, copy)NSDictionary *additionalAPIParameters;
@end
NS_ASSUME_NONNULL_END

View File

@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
#import "STPAPIResponseDecodable.h"
@class STPAddress;

View File

@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPBankAccount ()
@property (nonatomic, readwrite) NSString *last4;
+ (STPBankAccountStatus)statusFromString:(NSString *)string;
+ (NSString *)stringFromStatus:(STPBankAccountStatus)status;

View File

@ -15,12 +15,13 @@
@interface STPBankAccount ()
@property (nonatomic, readwrite) NSString *bankAccountId;
@property (nonatomic, readwrite) NSString *last4;
@property (nonatomic, readwrite) NSString *bankName;
@property (nonatomic, readwrite) NSString *fingerprint;
@property (nonatomic) STPBankAccountStatus status;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPBankAccount+Private.h
@end
@implementation STPBankAccount

View File

@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (STPBankAccountHolderType)accountHolderTypeFromString:(NSString *)string;
+ (NSString *)stringFromAccountHolderType:(STPBankAccountHolderType)accountHolderType;
- (instancetype)init;
- (NSString *)accountHolderTypeString;
@end

View File

@ -13,7 +13,7 @@
@interface STPBankAccountParams ()
@property (nonatomic, readonly) NSString *accountHolderTypeString;
// See STPBankAccountParams+Private.h
@end

View File

@ -13,8 +13,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface STPCard () <STPInternalAPIResponseDecodable>
@property (nonatomic, readwrite) NSString *last4;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
+ (STPCardFundingType)fundingFromString:(NSString *)string;
+ (nullable NSString *)stringFromFunding:(STPCardFundingType)funding;
- (instancetype)init;
- (nullable STPAddress *)address;
@end

View File

@ -16,12 +16,12 @@
@interface STPCard ()
@property (nonatomic, readwrite) NSString *cardId;
@property (nonatomic, readwrite) NSString *last4;
@property (nonatomic, readwrite) NSString *dynamicLast4;
@property (nonatomic, readwrite) STPCardBrand brand;
@property (nonatomic, readwrite) STPCardFundingType funding;
@property (nonatomic, readwrite) NSString *country;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPCard+Private.h
@end

View File

@ -22,6 +22,8 @@
- (BOOL)isEqualToFile:(STPFile *)file;
// See STPFile+Private.h
@end
@implementation STPFile

View File

@ -39,6 +39,8 @@
@property (nonatomic, nullable) STPSourceSEPADebitDetails *sepaDebitDetails;
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPSource+Private.h
@end
@implementation STPSource

View File

@ -16,6 +16,8 @@
@property (nonatomic, readwrite, nonnull, copy) NSDictionary *allResponseFields;
// See STPSourceCardDetails+Private.h
@end
@implementation STPSourceCardDetails

View File

@ -6,9 +6,10 @@
// Copyright © 2017 Stripe, Inc. All rights reserved.
//
#import "STPSourceOwner.h"
#import "NSDictionary+Stripe.h"
#import "STPAddress.h"
#import "STPSourceOwner.h"
@interface STPSourceOwner ()

View File

@ -8,8 +8,16 @@
#import <Stripe/Stripe.h>
NS_ASSUME_NONNULL_BEGIN
@interface STPSourceParams ()
@property (nonatomic, nullable, strong) NSString *redirectMerchantName;
- (instancetype)init;
- (NSString *)flowString;
- (NSString *)usageString;
@end
NS_ASSUME_NONNULL_END

View File

@ -13,6 +13,12 @@
#import "STPFormEncoder.h"
#import "STPSource+Private.h"
@interface STPSourceParams ()
// See STPSourceParams+Private.h
@end
@implementation STPSourceParams
@synthesize additionalAPIParameters = _additionalAPIParameters;
@ -33,7 +39,6 @@
}
- (void)setType:(STPSourceType)type {
// If setting unknown and we're already unknown, don't want to override raw value
if (type != self.type) {
self.rawTypeString = [STPSource stringFromType:type];
@ -243,8 +248,7 @@
return params;
}
#pragma mark - Redirect url
#pragma mark - Redirect Dictionary
/**
Private setter allows for setting the name of the app in the returnURL so
@ -294,7 +298,6 @@
}
#pragma mark - STPFormEncodable
+ (NSString *)rootObjectName {

View File

@ -82,14 +82,8 @@
#pragma mark - Description Tests
- (void)testDescriptionWorks {
- (void)testDescription {
STPBankAccountParams *bankAccountParams = [[STPBankAccountParams alloc] init];
bankAccountParams.accountNumber = @"000123456789";
bankAccountParams.routingNumber = @"123456789";
bankAccountParams.country = @"US";
bankAccountParams.currency = @"usd";
bankAccountParams.accountHolderName = @"John Doe";
bankAccountParams.accountHolderType = STPBankAccountHolderTypeCompany;
XCTAssert(bankAccountParams.description);
}
@ -105,6 +99,7 @@
NSDictionary *mapping = [STPBankAccountParams propertyNamesToFormFieldNamesMapping];
for (NSString *propertyName in [mapping allKeys]) {
XCTAssertFalse([propertyName containsString:@":"]);
XCTAssert([bankAccountParams respondsToSelector:NSSelectorFromString(propertyName)]);
}

View File

@ -8,13 +8,12 @@
@import XCTest;
#import "STPFormEncoder.h"
#import "STPBankAccount.h"
#import "STPBankAccount+Private.h"
@interface STPBankAccountTest : XCTestCase
#import "STPFormEncoder.h"
@property (nonatomic) STPBankAccount *bankAccount;
@interface STPBankAccountTest : XCTestCase
@end
@ -22,7 +21,7 @@
- (void)setUp {
[super setUp];
_bankAccount = [[STPBankAccount alloc] init];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
@ -80,18 +79,36 @@
#pragma mark -
- (void)testSetAccountNumber {
STPBankAccount *bankAccount = [[STPBankAccount alloc] init];
XCTAssertNil(bankAccount.accountNumber);
bankAccount.accountNumber = @"000123456789";
XCTAssertEqualObjects(bankAccount.accountNumber, @"000123456789");
}
- (void)testLast4ReturnsAccountNumberLast4WhenNotSet {
self.bankAccount.accountNumber = @"000123456789";
XCTAssertEqualObjects(self.bankAccount.last4, @"6789", @"last4 correctly returns the last 4 digits of the bank account number");
STPBankAccount *bankAccount = [[STPBankAccount alloc] init];
bankAccount.accountNumber = @"000123456789";
XCTAssertEqualObjects(bankAccount.last4, @"6789");
}
- (void)testLast4ReturnsNullWhenNoAccountNumberSet {
XCTAssertEqualObjects(nil, self.bankAccount.last4, @"last4 returns nil when nothing is set");
- (void)testLast4ReturnsNilWhenNoAccountNumberSet {
STPBankAccount *bankAccount = [[STPBankAccount alloc] init];
XCTAssertNil(bankAccount.last4);
}
- (void)testLast4ReturnsNullWhenAccountNumberIsLessThanLength4 {
self.bankAccount.accountNumber = @"123";
XCTAssertEqualObjects(nil, self.bankAccount.last4, @"last4 returns nil when number length is < 4");
- (void)testLast4ReturnsNilWhenAccountNumberIsLessThanLength4 {
STPBankAccount *bankAccount = [[STPBankAccount alloc] init];
bankAccount.accountNumber = @"123";
XCTAssertNil(bankAccount.last4);
}
- (void)testLast4ReturnsValueOverAccountNumberDerivation {
STPBankAccount *bankAccount = [[STPBankAccount alloc] init];
bankAccount.accountNumber = nil;
bankAccount.last4 = @"1234";
XCTAssertEqualObjects(bankAccount.last4, @"1234");
}
#pragma mark - Equality Tests
@ -100,53 +117,82 @@
STPBankAccount *bankAccount1 = [STPBankAccount decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
STPBankAccount *bankAccount2 = [STPBankAccount decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(bankAccount1, bankAccount1, @"bank account should equal itself");
XCTAssertEqualObjects(bankAccount1, bankAccount2, @"bank account with equal data should be equal");
XCTAssertNotEqual(bankAccount1, bankAccount2);
XCTAssertEqualObjects(bankAccount1, bankAccount1);
XCTAssertEqualObjects(bankAccount1, bankAccount2);
XCTAssertEqual(bankAccount1.hash, bankAccount1.hash);
XCTAssertEqual(bankAccount1.hash, bankAccount2.hash);
}
#pragma mark - Description Tests
- (void)testDescriptionWorks {
- (void)testDescription {
STPBankAccount *bankAccount = [STPBankAccount decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
bankAccount.routingNumber = @"123456789";
XCTAssert(bankAccount.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#customer_bank_account_object
return @{
@"id": @"something",
@"last4": @"6789",
@"id": @"ba_1AXvnKEOD54MuFwSotKc6xq0",
@"object": @"bank_account",
@"account": @"acct_1AHMhqEOD54MuFwS",
@"account_holder_name": @"Jane Austen",
@"account_holder_type": @"individual",
@"bank_name": @"STRIPE TEST BANK",
@"country": @"US",
@"fingerprint": @"something",
@"currency": @"usd",
@"default_for_currency": @(NO),
@"fingerprint": @"C5fW7AwE3of8bHvV",
@"last4": @"6789",
@"metadata": @{},
@"routing_number": @"110000000",
@"status": @"new",
@"account_holder_name": @"John Doe",
@"account_holder_type": @"company",
@"customer": @"cus_AtMGi1QH6GlMP4",
};
}
- (void)testInitializingBankAccountWithAttributeDictionary {
NSMutableDictionary *apiResponse = [[self completeAttributeDictionary] mutableCopy];
apiResponse[@"foo"] = @"bar";
STPBankAccount *bankAccountWithAttributes = [STPBankAccount decodedObjectFromAPIResponse:apiResponse];
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"id",
@"last4",
@"bank_name",
@"country",
@"currency",
@"status",
];
XCTAssertEqualObjects([bankAccountWithAttributes bankAccountId], @"something", @"bankAccountId is set correctly");
XCTAssertEqualObjects([bankAccountWithAttributes last4], @"6789", @"last4 is set correctly");
XCTAssertEqualObjects([bankAccountWithAttributes bankName], @"STRIPE TEST BANK", @"bankName is set correctly");
XCTAssertEqualObjects([bankAccountWithAttributes country], @"US", @"country is set correctly");
XCTAssertEqualObjects([bankAccountWithAttributes fingerprint], @"something", @"fingerprint is set correctly");
XCTAssertEqualObjects([bankAccountWithAttributes currency], @"usd", @"currency is set correctly");
XCTAssertEqual([bankAccountWithAttributes status], STPBankAccountStatusNew);
XCTAssertEqualObjects([bankAccountWithAttributes accountHolderName], @"John Doe");
XCTAssertEqual([bankAccountWithAttributes accountHolderType], STPBankAccountHolderTypeCompany);
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
NSDictionary *allResponseFields = bankAccountWithAttributes.allResponseFields;
XCTAssertEqual(allResponseFields[@"foo"], @"bar");
XCTAssertEqual(allResponseFields[@"last4"], @"6789");
XCTAssertNil(allResponseFields[@"baz"]);
XCTAssertNil([STPBankAccount decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPBankAccount decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPBankAccount *bankAccount = [STPBankAccount decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(bankAccount.bankAccountId, @"ba_1AXvnKEOD54MuFwSotKc6xq0");
XCTAssertEqualObjects(bankAccount.accountHolderName, @"Jane Austen");
XCTAssertEqual(bankAccount.accountHolderType, STPBankAccountHolderTypeIndividual);
XCTAssertEqualObjects(bankAccount.bankName, @"STRIPE TEST BANK");
XCTAssertEqualObjects(bankAccount.country, @"US");
XCTAssertEqualObjects(bankAccount.currency, @"usd");
XCTAssertEqualObjects(bankAccount.fingerprint, @"C5fW7AwE3of8bHvV");
XCTAssertEqualObjects(bankAccount.last4, @"6789");
XCTAssertNil(bankAccount.routingNumber);
XCTAssertEqual(bankAccount.status, STPBankAccountStatusNew);
XCTAssertNotEqual(bankAccount.allResponseFields, response);
XCTAssertEqualObjects(bankAccount.allResponseFields, response);
}
@end

View File

@ -90,20 +90,8 @@
#pragma mark - Description Tests
- (void)testDescriptionWorks {
- (void)testDescription {
STPCardParams *cardParams = [[STPCardParams alloc] init];
cardParams.number = @"4242424242424242";
cardParams.expMonth = 6;
cardParams.expYear = 2020;
cardParams.cvc = @"123";
cardParams.name = @"John Smith";
cardParams.addressLine1 = @"55 John St";
cardParams.addressLine2 = @"#3B";
cardParams.addressCity = @"New York";
cardParams.addressState = @"NY";
cardParams.addressZip = @"10002";
cardParams.addressCountry = @"US";
cardParams.currency = @"usd";
XCTAssert(cardParams.description);
}
@ -119,6 +107,7 @@
NSDictionary *mapping = [STPCardParams propertyNamesToFormFieldNamesMapping];
for (NSString *propertyName in [mapping allKeys]) {
XCTAssertFalse([propertyName containsString:@":"]);
XCTAssert([cardParams respondsToSelector:NSSelectorFromString(propertyName)]);
}

View File

@ -13,15 +13,13 @@
@interface STPCardTest : XCTestCase
@property (nonatomic) STPCard *card;
@end
@implementation STPCardTest
- (void)setUp {
[super setUp];
_card = [[STPCard alloc] init];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
@ -151,38 +149,86 @@
#pragma mark -
- (void)testInitWithIDBrandLast4ExpMonthExpYearFunding {
STPCard *card = [[STPCard alloc] initWithID:@"card_1AVRojEOD54MuFwSxr93QJSx"
brand:STPCardBrandVisa
last4:@"5556"
expMonth:12
expYear:2034
funding:STPCardFundingTypeDebit];
XCTAssertEqualObjects(card.cardId, @"card_1AVRojEOD54MuFwSxr93QJSx");
XCTAssertEqual(card.brand, STPCardBrandVisa);
XCTAssertEqualObjects(card.last4, @"5556");
XCTAssertEqual(card.expMonth, (NSUInteger)12);
XCTAssertEqual(card.expYear, (NSUInteger)2034);
XCTAssertEqual(card.funding, STPCardFundingTypeDebit);
}
- (void)testInit {
STPCard *card = [[STPCard alloc] init];
XCTAssertEqual(card.brand, STPCardBrandUnknown);
XCTAssertEqual(card.funding, STPCardFundingTypeOther);
}
- (void)testLast4ReturnsCardNumberLast4WhenNotSet {
self.card.number = @"4242424242424242";
XCTAssertEqualObjects(self.card.last4, @"4242", @"last4 correctly returns the last 4 digits of the card number");
STPCard *card = [[STPCard alloc] init];
card.number = @"4242424242424242";
XCTAssertEqualObjects(card.last4, @"4242");
}
- (void)testLast4ReturnsNullWhenNoCardNumberSet {
XCTAssertEqualObjects(nil, self.card.last4, @"last4 returns nil when nothing is set");
- (void)testLast4ReturnsNilWhenNoCardNumberSet {
STPCard *card = [[STPCard alloc] init];
XCTAssertNil(card.last4);
}
- (void)testLast4ReturnsNullWhenCardNumberIsLessThanLength4 {
self.card.number = @"123";
XCTAssertEqualObjects(nil, self.card.last4, @"last4 returns nil when number length is < 3");
- (void)testLast4ReturnsNilWhenCardNumberIsLessThanLength4 {
STPCard *card = [[STPCard alloc] init];
card.number = @"123";
XCTAssertNil(card.last4);
}
- (void)testAddress {
NSMutableDictionary *apiResponse = [[self completeAttributeDictionary] mutableCopy];
STPCard *card = [STPCard decodedObjectFromAPIResponse:apiResponse];
STPAddress *address = [card address];
XCTAssertEqualObjects(address.name, @"Smerlock Smolmes");
XCTAssertEqualObjects(address.line1, @"221A Baker Street");
XCTAssertEqualObjects(address.city, @"New York");
XCTAssertEqualObjects(address.state, @"NY");
XCTAssertEqualObjects(address.postalCode, @"12345");
XCTAssertEqualObjects(address.country, @"USA");
apiResponse[@"name"] = nil;
apiResponse[@"address_line1"] = nil;
apiResponse[@"address_city"] = nil;
apiResponse[@"address_state"] = nil;
apiResponse[@"address_zip"] = nil;
apiResponse[@"address_country"] = nil;
STPCard *noAddressCard = [STPCard decodedObjectFromAPIResponse:apiResponse];
XCTAssertNil([noAddressCard address]);
- (void)testLast4ReturnsValueOverCardNumberDerivation {
STPCard *card = [[STPCard alloc] init];
card.number = nil;
card.last4 = @"1234";
XCTAssertEqualObjects(card.last4, @"1234");
}
- (void)testIsApplePayCard {
STPCard *card = [[STPCard alloc] init];
card.allResponseFields = @{};
XCTAssertFalse(card.isApplePayCard);
card.allResponseFields = @{@"tokenization_method": @"android_pay"};
XCTAssertFalse(card.isApplePayCard);
card.allResponseFields = @{@"tokenization_method": @"apple_pay"};
XCTAssert(card.isApplePayCard);
card.allResponseFields = @{@"tokenization_method": @"garbage"};
XCTAssertFalse(card.isApplePayCard);
card.allResponseFields = @{@"tokenization_method": @""};
XCTAssertFalse(card.isApplePayCard);
// See: https://stripe.com/docs/api#card_object-tokenization_method
}
- (void)testAddressPopulated {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(card.address.name, @"Jane Austen");
XCTAssertEqualObjects(card.address.line1, @"123 Fake St");
XCTAssertEqualObjects(card.address.line2, @"Apt 1");
XCTAssertEqualObjects(card.address.city, @"Pittsburgh");
XCTAssertEqualObjects(card.address.state, @"PA");
XCTAssertEqualObjects(card.address.postalCode, @"19219");
XCTAssertEqualObjects(card.address.country, @"US");
}
- (void)testAddressEmpty {
STPCard *card = [[STPCard alloc] init];
XCTAssertNil(card.address);
}
#pragma mark - Equality Tests
@ -191,13 +237,18 @@
STPCard *card1 = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
STPCard *card2 = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(card1, card1, @"card should equal itself");
XCTAssertEqualObjects(card1, card2, @"cards with equal data should be equal");
XCTAssertNotEqual(card1, card2);
XCTAssertEqualObjects(card1, card1);
XCTAssertEqualObjects(card1, card2);
XCTAssertEqual(card1.hash, card1.hash);
XCTAssertEqual(card1.hash, card2.hash);
}
#pragma mark - Description Tests
- (void)testDescriptionWorks {
- (void)testDescription {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(card.description);
}
@ -205,52 +256,99 @@
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#card_object
return @{
@"id": @"1",
@"exp_month": @"12",
@"exp_year": @"2013",
@"funding": @"debit",
@"name": @"Smerlock Smolmes",
@"address_line1": @"221A Baker Street",
@"address_city": @"New York",
@"address_state": @"NY",
@"address_zip": @"12345",
@"address_country": @"USA",
@"last4": @"1234",
@"dynamic_last4": @"5678",
@"brand": @"MasterCard",
@"country": @"Japan",
@"id": @"card_1AVRojEOD54MuFwSxr93QJSx",
@"object": @"card",
@"address_city": @"Pittsburgh",
@"address_country": @"US",
@"address_line1": @"123 Fake St",
@"address_line1_check": @"pass",
@"address_line2": @"Apt 1",
@"address_state": @"PA",
@"address_zip": @"19219",
@"address_zip_check": @"pass",
@"brand": @"Visa",
@"country": @"US",
@"currency": @"usd",
@"customer": @"cus_Apzu98qCHnHJNJ",
@"cvc_check": @"pass",
@"dynamic_last4": @"5678",
@"exp_month": @(12),
@"exp_year": @(2034),
@"fingerprint": @"A7041YccE8Z6m5Cm",
@"funding": @"debit",
@"last4": @"5556",
@"metadata": @{},
@"name": @"Jane Austen",
@"tokenization_method": @"apple_pay",
};
}
- (void)testInitializingCardWithAttributeDictionary {
NSMutableDictionary *apiResponse = [[self completeAttributeDictionary] mutableCopy];
apiResponse[@"foo"] = @"bar";
apiResponse[@"nested"] = @{@"baz": @"bang"};
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"id",
@"last4",
@"brand",
@"exp_month",
@"exp_year",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
STPCard *cardWithAttributes = [STPCard decodedObjectFromAPIResponse:apiResponse];
XCTAssertTrue([cardWithAttributes expMonth] == 12, @"expMonth is set correctly");
XCTAssertTrue([cardWithAttributes expYear] == 2013, @"expYear is set correctly");
XCTAssertEqual([cardWithAttributes funding], STPCardFundingTypeDebit);
XCTAssertEqualObjects([cardWithAttributes name], @"Smerlock Smolmes", @"name is set correctly");
XCTAssertEqualObjects([cardWithAttributes addressLine1], @"221A Baker Street", @"addressLine1 is set correctly");
XCTAssertEqualObjects([cardWithAttributes addressCity], @"New York", @"addressCity is set correctly");
XCTAssertEqualObjects([cardWithAttributes addressState], @"NY", @"addressState is set correctly");
XCTAssertEqualObjects([cardWithAttributes addressZip], @"12345", @"addressZip is set correctly");
XCTAssertEqualObjects([cardWithAttributes addressCountry], @"USA", @"addressCountry is set correctly");
XCTAssertEqualObjects([cardWithAttributes last4], @"1234", @"last4 is set correctly");
XCTAssertEqualObjects([cardWithAttributes dynamicLast4], @"5678", @"last4 is set correctly");
XCTAssertEqual([cardWithAttributes brand], STPCardBrandMasterCard, @"type is set correctly");
XCTAssertEqualObjects([cardWithAttributes country], @"Japan", @"country is set correctly");
XCTAssertEqualObjects([cardWithAttributes currency], @"usd", @"currency is set correctly");
XCTAssertNil([STPCard decodedObjectFromAPIResponse:response]);
}
NSDictionary *allResponseFields = cardWithAttributes.allResponseFields;
XCTAssertEqual(allResponseFields[@"foo"], @"bar");
XCTAssertEqual(allResponseFields[@"last4"], @"1234");
XCTAssertEqualObjects(allResponseFields[@"nested"], @{@"baz": @"bang"});
XCTAssertNil(allResponseFields[@"baz"]);
XCTAssert([STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPCard *card = [STPCard decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(card.cardId, @"card_1AVRojEOD54MuFwSxr93QJSx");
XCTAssertEqualObjects(card.addressCity, @"Pittsburgh");
XCTAssertEqualObjects(card.addressCountry, @"US");
XCTAssertEqualObjects(card.addressLine1, @"123 Fake St");
XCTAssertEqualObjects(card.addressLine2, @"Apt 1");
XCTAssertEqualObjects(card.addressState, @"PA");
XCTAssertEqualObjects(card.addressZip, @"19219");
XCTAssertEqual(card.brand, STPCardBrandVisa);
XCTAssertEqualObjects(card.country, @"US");
XCTAssertEqualObjects(card.currency, @"usd");
XCTAssertEqualObjects(card.dynamicLast4, @"5678");
XCTAssertEqual(card.expMonth, (NSUInteger)12);
XCTAssertEqual(card.expYear, (NSUInteger)2034);
XCTAssertEqual(card.funding, STPCardFundingTypeDebit);
XCTAssertEqualObjects(card.last4, @"5556");
XCTAssertEqualObjects(card.name, @"Jane Austen");
XCTAssertNotEqual(card.allResponseFields, response);
XCTAssertEqualObjects(card.allResponseFields, response);
}
#pragma mark - STPSourceProtocol Tests
- (void)testStripeID {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(card.stripeID, @"card_1AVRojEOD54MuFwSxr93QJSx");
}
- (void)testLabel {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(card.label, @"Visa 5556");
}
- (void)testImage {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(card.image);
}
- (void)testTemplateImage {
STPCard *card = [STPCard decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(card.templateImage);
}
@end

View File

@ -13,14 +13,18 @@
@interface STPFileTest : XCTestCase
@property (nonatomic) STPFile *file;
@end
@implementation STPFileTest
- (void)setUp {
_file = [[STPFile alloc] init];
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#pragma mark - STPFilePurpose Tests
@ -70,46 +74,61 @@
STPFile *file1 = [STPFile decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
STPFile *file2 = [STPFile decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertEqualObjects(file1, file1, @"file should equal itself");
XCTAssertEqualObjects(file1, file2, @"file with equal data should be equal");
XCTAssertNotEqual(file1, file2);
XCTAssertEqualObjects(file1, file1);
XCTAssertEqualObjects(file1, file2);
XCTAssertEqual(file1.hash, file1.hash);
XCTAssertEqual(file1.hash, file2.hash);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#file_upload_object
return @{
@"id": @"file_something",
@"created": @1483888528,
@"size": @322035,
@"id": @"file_1AXyapEOD54MuFwSnhlqqvsX",
@"object": @"file_upload",
@"created": @(1498250487),
@"purpose": @"dispute_evidence",
@"size": @9863,
@"type": @"png",
@"purpose": @"identity_document",
@"url": @"https://stripe-upload-api.s3.amazonaws.com/uploads/file_1AXyapEOD54MuFwSnhlqqvsX?AWSAccessKeyId=KEY_ID&Expires=TIMESTAMP&Signature=SIGNATURE"
};
}
- (void)testInitializingFileWithAttributeDictionary {
NSMutableDictionary *apiResponse = [[self completeAttributeDictionary] mutableCopy];
apiResponse[@"foo"] = @"bar";
apiResponse[@"nested"] = @{@"baz": @"bang"};
STPFile *fileWithAttributes = [STPFile decodedObjectFromAPIResponse:apiResponse];
XCTAssertEqualObjects([fileWithAttributes fileId], @"file_something", @"fileId is set correctly");
XCTAssertEqualObjects([fileWithAttributes created], [NSDate dateWithTimeIntervalSince1970:1483888528], @"created is set correctly");
XCTAssertEqualObjects([fileWithAttributes size], @322035, @"size is set correctly");
XCTAssertEqualObjects([fileWithAttributes type], @"png", @"type is set correctly");
XCTAssertEqual(fileWithAttributes.purpose, STPFilePurposeIdentityDocument);
NSDictionary *allResponseFields = fileWithAttributes.allResponseFields;
XCTAssertEqual(allResponseFields[@"foo"], @"bar");
XCTAssertEqual(allResponseFields[@"id"], @"file_something");
XCTAssertEqualObjects(allResponseFields[@"nested"], @{@"baz": @"bang"});
XCTAssertNil(allResponseFields[@"baz"]);
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"id",
@"created",
@"size",
@"purpose",
@"type",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPFile decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPFile decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testInitializingFileFailsWhenMissingRequiredParam {
NSMutableDictionary *apiResponse = [[self completeAttributeDictionary] mutableCopy];
apiResponse[@"id"] = nil;
STPFile *fileWithAttributes = [STPFile decodedObjectFromAPIResponse:apiResponse];
XCTAssertNil(fileWithAttributes);
- (void)testInitializingFileWithAttributeDictionary {
NSDictionary *response = [self completeAttributeDictionary];
STPFile *file = [STPFile decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(file.fileId, @"file_1AXyapEOD54MuFwSnhlqqvsX");
XCTAssertEqualObjects(file.created, [NSDate dateWithTimeIntervalSince1970:1498250487]);
XCTAssertEqual(file.purpose, STPFilePurposeDisputeEvidence);
XCTAssertEqualObjects(file.size, @9863);
XCTAssertEqualObjects(file.type, @"png");
XCTAssertNotEqual(file.allResponseFields, response);
XCTAssertEqualObjects(file.allResponseFields, response);
}
@end

View File

@ -27,7 +27,6 @@
[super tearDown];
}
#pragma mark - STPSourceCard3DSecureStatus Tests
- (void)testThreeDSecureStatusFromString {
@ -76,4 +75,54 @@
}
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceCardDetails *cardDetails = [STPSourceCardDetails decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(cardDetails.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
return @{
@"brand": @"Visa",
@"country": @"US",
@"exp_month": @(12),
@"exp_year": @(2034),
@"funding": @"debit",
@"last4": @"5556",
@"three_d_secure": @"not_supported",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceCardDetails decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceCardDetails decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceCardDetails *cardDetails = [STPSourceCardDetails decodedObjectFromAPIResponse:response];
XCTAssertEqual(cardDetails.brand, STPCardBrandVisa);
XCTAssertEqualObjects(cardDetails.country, @"US");
XCTAssertEqual(cardDetails.expMonth, (NSUInteger)12);
XCTAssertEqual(cardDetails.expYear, (NSUInteger)2034);
XCTAssertEqual(cardDetails.funding, STPCardFundingTypeDebit);
XCTAssertEqualObjects(cardDetails.last4, @"5556");
XCTAssertEqual(cardDetails.threeDSecure, STPSourceCard3DSecureStatusNotSupported);
XCTAssertNotEqual(cardDetails.allResponseFields, response);
XCTAssertEqualObjects(cardDetails.allResponseFields, response);
}
@end

View File

@ -0,0 +1,100 @@
//
// STPSourceOwnerTest.m
// Stripe
//
// Created by Joey Dong on 6/23/17.
// Copyright © 2017 Stripe, Inc. All rights reserved.
//
@import XCTest;
#import "STPSourceOwner.h"
#import "STPAddress.h"
@interface STPSourceOwnerTest : XCTestCase
@end
@implementation STPSourceOwnerTest
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#source_object
return @{
@"address": @{
@"city": @"Pittsburgh",
@"country": @"US",
@"line1": @"123 Fake St",
@"line2": @"Apt 1",
@"postal_code": @"19219",
@"state": @"PA",
},
@"email": @"jenny.rosen@example.com",
@"name": @"Jenny Rosen",
@"phone": @"555-867-5309",
@"verified_address": @{
@"city": @"Pittsburgh",
@"country": @"US",
@"line1": @"123 Fake St",
@"line2": @"Apt 1",
@"postal_code": @"19219",
@"state": @"PA",
},
@"verified_email": @"jenny.rosen@example.com",
@"verified_name": @"Jenny Rosen",
@"verified_phone": @"555-867-5309",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceOwner decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceOwner decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceOwner *owner = [STPSourceOwner decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(owner.address.city, @"Pittsburgh");
XCTAssertEqualObjects(owner.address.country, @"US");
XCTAssertEqualObjects(owner.address.line1, @"123 Fake St");
XCTAssertEqualObjects(owner.address.line2, @"Apt 1");
XCTAssertEqualObjects(owner.address.postalCode, @"19219");
XCTAssertEqualObjects(owner.address.state, @"PA");
XCTAssertEqualObjects(owner.email, @"jenny.rosen@example.com");
XCTAssertEqualObjects(owner.name, @"Jenny Rosen");
XCTAssertEqualObjects(owner.phone, @"555-867-5309");
XCTAssertEqualObjects(owner.verifiedAddress.city, @"Pittsburgh");
XCTAssertEqualObjects(owner.verifiedAddress.country, @"US");
XCTAssertEqualObjects(owner.verifiedAddress.line1, @"123 Fake St");
XCTAssertEqualObjects(owner.verifiedAddress.line2, @"Apt 1");
XCTAssertEqualObjects(owner.verifiedAddress.postalCode, @"19219");
XCTAssertEqualObjects(owner.verifiedAddress.state, @"PA");
XCTAssertEqualObjects(owner.verifiedEmail, @"jenny.rosen@example.com");
XCTAssertEqualObjects(owner.verifiedName, @"Jenny Rosen");
XCTAssertEqualObjects(owner.verifiedPhone, @"555-867-5309");
XCTAssertNotEqual(owner.allResponseFields, response);
XCTAssertEqualObjects(owner.allResponseFields, response);
}
@end

View File

@ -6,12 +6,13 @@
// Copyright © 2017 Stripe, Inc. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "Stripe.h"
#import "STPFormEncoder.h"
@import XCTest;
#import "STPSource+Private.h"
#import "STPSourceParams+Private.h"
#import "Stripe.h"
#import "STPFormEncoder.h"
@interface STPSourceParamsTest : XCTestCase
@ -19,6 +20,149 @@
@implementation STPSourceParamsTest
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#pragma mark -
- (void)testInit {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
XCTAssertEqualObjects(sourceParams.rawTypeString, @"");
XCTAssertEqual(sourceParams.flow, STPSourceFlowUnknown);
XCTAssertEqual(sourceParams.usage, STPSourceUsageUnknown);
XCTAssertEqualObjects(sourceParams.additionalAPIParameters, @{});
}
- (void)testType {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
sourceParams.rawTypeString = @"bancontact";
XCTAssertEqual(sourceParams.type, STPSourceTypeBancontact);
sourceParams.rawTypeString = @"bitcoin";
XCTAssertEqual(sourceParams.type, STPSourceTypeBitcoin);
sourceParams.rawTypeString = @"card";
XCTAssertEqual(sourceParams.type, STPSourceTypeCard);
sourceParams.rawTypeString = @"giropay";
XCTAssertEqual(sourceParams.type, STPSourceTypeGiropay);
sourceParams.rawTypeString = @"ideal";
XCTAssertEqual(sourceParams.type, STPSourceTypeIDEAL);
sourceParams.rawTypeString = @"sepa_debit";
XCTAssertEqual(sourceParams.type, STPSourceTypeSEPADebit);
sourceParams.rawTypeString = @"sofort";
XCTAssertEqual(sourceParams.type, STPSourceTypeSofort);
sourceParams.rawTypeString = @"three_d_secure";
XCTAssertEqual(sourceParams.type, STPSourceTypeThreeDSecure);
sourceParams.rawTypeString = @"unknown";
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
sourceParams.rawTypeString = @"garbage";
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
}
- (void)testSetType {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
sourceParams.type = STPSourceTypeBancontact;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"bancontact");
sourceParams.type = STPSourceTypeBitcoin;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"bitcoin");
sourceParams.type = STPSourceTypeCard;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"card");
sourceParams.type = STPSourceTypeGiropay;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"giropay");
sourceParams.type = STPSourceTypeIDEAL;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"ideal");
sourceParams.type = STPSourceTypeSEPADebit;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"sepa_debit");
sourceParams.type = STPSourceTypeSofort;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"sofort");
sourceParams.type = STPSourceTypeThreeDSecure;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"three_d_secure");
sourceParams.type = STPSourceTypeUnknown;
XCTAssertNil(sourceParams.rawTypeString);
}
- (void)testSetTypePreserveUnknownRawTypeString {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
sourceParams.rawTypeString = @"money";
sourceParams.type = STPSourceTypeUnknown;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"money");
}
- (void)testRawTypeString {
STPSourceParams *sourceParams = [STPSourceParams new];
// Check defaults to unknown
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
// Check changing type sets rawTypeString
sourceParams.type = STPSourceTypeCard;
XCTAssertEqualObjects(sourceParams.rawTypeString, [STPSource stringFromType:STPSourceTypeCard]);
// Check changing to unknown raw string sets type to unknown
sourceParams.rawTypeString = @"new_source_type";
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
// Check once unknown that setting type to unknown doesnt clobber string
sourceParams.type = STPSourceTypeUnknown;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"new_source_type");
// Check setting string to known type sets type correctly
sourceParams.rawTypeString = [STPSource stringFromType:STPSourceTypeIDEAL];
XCTAssertEqual(sourceParams.type, STPSourceTypeIDEAL);
}
- (void)testFlowString {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
XCTAssertNil(sourceParams.flowString);
sourceParams.flow = STPSourceFlowRedirect;
XCTAssertEqualObjects(sourceParams.flowString, @"redirect");
sourceParams.flow = STPSourceFlowReceiver;
XCTAssertEqualObjects(sourceParams.flowString, @"receiver");
sourceParams.flow = STPSourceFlowCodeVerification;
XCTAssertEqualObjects(sourceParams.flowString, @"code_verification");
sourceParams.flow = STPSourceFlowNone;
XCTAssertEqualObjects(sourceParams.flowString, @"none");
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
XCTAssert(sourceParams.description);
}
#pragma mark - Constructors Tests
- (void)testCardParamsWithCard {
STPCardParams *card = [STPCardParams new];
card.number = @"4242 4242 4242 4242";
@ -50,6 +194,8 @@
XCTAssertEqualObjects(sourceAddress[@"country"], card.addressCountry);
}
#pragma mark - Redirect Dictionary Tests
- (NSString *)redirectMerchantNameQueryItemValueFromURLString:(NSString *)urlString {
NSURLComponents *components = [NSURLComponents componentsWithString:urlString];
for (NSURLQueryItem *item in components.queryItems) {
@ -85,27 +231,28 @@
}
- (void)testRawTypeString {
STPSourceParams *sourceParams = [STPSourceParams new];
#pragma mark - STPFormEncodable Tests
// Check defaults to unknown
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
- (void)testRootObjectName {
XCTAssertNil([STPSourceParams rootObjectName]);
}
// Check changing type sets rawTypeString
sourceParams.type = STPSourceTypeCard;
XCTAssertEqualObjects(sourceParams.rawTypeString, [STPSource stringFromType:STPSourceTypeCard]);
- (void)testPropertyNamesToFormFieldNamesMapping {
STPSourceParams *sourceParams = [[STPSourceParams alloc] init];
// Check changing to unknown raw string sets type to unknown
sourceParams.rawTypeString = @"new_source_type";
XCTAssertEqual(sourceParams.type, STPSourceTypeUnknown);
NSDictionary *mapping = [STPSourceParams propertyNamesToFormFieldNamesMapping];
// Check once unknown that setting type to unknown doesnt clobber string
sourceParams.type = STPSourceTypeUnknown;
XCTAssertEqualObjects(sourceParams.rawTypeString, @"new_source_type");
for (NSString *propertyName in [mapping allKeys]) {
XCTAssertFalse([propertyName containsString:@":"]);
XCTAssert([sourceParams respondsToSelector:NSSelectorFromString(propertyName)]);
}
// Check setting string to known type sets type correctly
sourceParams.rawTypeString = [STPSource stringFromType:STPSourceTypeIDEAL];
XCTAssertEqual(sourceParams.type, STPSourceTypeIDEAL);
for (NSString *formFieldName in [mapping allValues]) {
XCTAssert([formFieldName isKindOfClass:[NSString class]]);
XCTAssert([formFieldName length] > 0);
}
XCTAssertEqual([[mapping allValues] count], [[NSSet setWithArray:[mapping allValues]] count]);
}
@end

View File

@ -0,0 +1,78 @@
//
// STPSourceReceiverTest.m
// Stripe
//
// Created by Joey Dong on 6/26/17.
// Copyright © 2017 Stripe, Inc. All rights reserved.
//
@import XCTest;
#import "STPSourceReceiver.h"
@interface STPSourceReceiverTest : XCTestCase
@end
@implementation STPSourceReceiverTest
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceReceiver *receiver = [STPSourceReceiver decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(receiver.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#source_object
return @{
@"address": @"test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N",
@"amount_charged": @(300),
@"amount_received": @(200),
@"amount_returned": @(100),
@"refund_attributes_method": @"email",
@"refund_attributes_status": @"missing",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"address",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceReceiver decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceReceiver decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceReceiver *receiver = [STPSourceReceiver decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(receiver.address, @"test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N");
XCTAssertEqualObjects(receiver.amountCharged, @(300));
XCTAssertEqualObjects(receiver.amountReceived, @(200));
XCTAssertEqualObjects(receiver.amountReturned, @(100));
XCTAssertNotEqual(receiver.allResponseFields, response);
XCTAssertEqualObjects(receiver.allResponseFields, response);
}
@end

View File

@ -75,4 +75,51 @@
}
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceRedirect *redirect = [STPSourceRedirect decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(redirect.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/sources/three-d-secure
return @{
@"return_url": @"https://shop.example.com/crtA6B28E1",
@"status": @"pending",
@"url": @"https://hooks.stripe.com/redirect/authenticate/src_19YlvWAHEMiOZZp1QQlOD79v?client_secret=src_client_secret_kBwCSm6Xz5MQETiJ43hUH8qv",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"return_url",
@"status",
@"url",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceRedirect decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceRedirect decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceRedirect *redirect = [STPSourceRedirect decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(redirect.returnURL, [NSURL URLWithString:@"https://shop.example.com/crtA6B28E1"]);
XCTAssertEqual(redirect.status, STPSourceRedirectStatusPending);
XCTAssertEqualObjects(redirect.url, [NSURL URLWithString:@"https://hooks.stripe.com/redirect/authenticate/src_19YlvWAHEMiOZZp1QQlOD79v?client_secret=src_client_secret_kBwCSm6Xz5MQETiJ43hUH8qv"]);
XCTAssertNotEqual(redirect.allResponseFields, response);
XCTAssertEqualObjects(redirect.allResponseFields, response);
}
@end

View File

@ -0,0 +1,78 @@
//
// STPSourceSEPADebitDetails.m
// Stripe
//
// Created by Joey Dong on 6/26/17.
// Copyright © 2017 Stripe, Inc. All rights reserved.
//
@import XCTest;
#import "STPSourceSEPADebitDetails.h"
@interface STPSourceSEPADebitDetailsTest : XCTestCase
@end
@implementation STPSourceSEPADebitDetailsTest
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceSEPADebitDetails *sepaDebitDetails = [STPSourceSEPADebitDetails decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(sepaDebitDetails.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/sources/sepa-debit
return @{
@"bank_code": @"37040044",
@"country": @"DE",
@"fingerprint": @"NxdSyRegc9PsMkWy",
@"last4": @"3001",
@"mandate_reference": @"NXDSYREGC9PSMKWY",
@"mandate_url": @"https://hooks.stripe.com/adapter/sepa_debit/file/src_18HgGjHNCLa1Vra6Y9TIP6tU/src_client_secret_XcBmS94nTg5o0xc9MSliSlDW",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceSEPADebitDetails decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceSEPADebitDetails decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceSEPADebitDetails *sepaDebitDetails = [STPSourceSEPADebitDetails decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(sepaDebitDetails.bankCode, @"37040044");
XCTAssertEqualObjects(sepaDebitDetails.country, @"DE");
XCTAssertEqualObjects(sepaDebitDetails.fingerprint, @"NxdSyRegc9PsMkWy");
XCTAssertEqualObjects(sepaDebitDetails.last4, @"3001");
XCTAssertEqualObjects(sepaDebitDetails.mandateReference, @"NXDSYREGC9PSMKWY");
XCTAssertEqualObjects(sepaDebitDetails.mandateURL, [NSURL URLWithString:@"https://hooks.stripe.com/adapter/sepa_debit/file/src_18HgGjHNCLa1Vra6Y9TIP6tU/src_client_secret_XcBmS94nTg5o0xc9MSliSlDW"]);
XCTAssertNotEqual(sepaDebitDetails.allResponseFields, response);
XCTAssertEqualObjects(sepaDebitDetails.allResponseFields, response);
}
@end

View File

@ -259,9 +259,126 @@
}
}
#pragma mark - Equality Tests
- (void)testSourceEquals {
STPSource *source1 = [STPSource decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
STPSource *source2 = [STPSource decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssertNotEqual(source1, source2);
XCTAssertEqualObjects(source1, source1);
XCTAssertEqualObjects(source1, source2);
XCTAssertEqual(source1.hash, source1.hash);
XCTAssertEqual(source1.hash, source2.hash);
}
#pragma mark - Description Tests
- (void)testDescription {
STPSource *source = [STPSource decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(source.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/api#source_object
return @{
@"id": @"src_1AXyapEOD54MuFwSGpIHn8NM",
@"object": @"source",
@"amount": @(1000),
@"client_secret": @"src_client_secret_Eh47vJB9AUNENJi0pfObKtCM",
@"created": @(1498250487),
@"currency": @"usd",
@"flow": @"receiver",
@"livemode": @NO,
@"metadata": @{},
@"owner": @{
@"address": [NSNull null],
@"email": @"jenny.rosen@example.com",
@"name": [NSNull null],
@"phone": [NSNull null],
@"verified_address": [NSNull null],
@"verified_email": [NSNull null],
@"verified_name": [NSNull null],
@"verified_phone": [NSNull null],
},
@"receiver": @{
@"address": @"test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N",
@"amount_charged": @(0),
@"amount_received": @(0),
@"amount_returned": @(0),
@"refund_attributes_method": @"email",
@"refund_attributes_status": @"missing",
},
@"status": @"pending",
@"type": @"bitcoin",
@"usage": @"single_use",
@"bitcoin": @{
@"address": @"test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N",
@"amount": @(2371000),
@"amount_charged": @(0),
@"amount_received": @(0),
@"amount_returned": @(0),
@"uri": @"bitcoin:test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N?amount=0.02371000",
},
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"id",
@"livemode",
@"status",
@"type",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSource decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSource decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSource *source = [STPSource decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(source.stripeID, @"src_1AXyapEOD54MuFwSGpIHn8NM");
XCTAssertEqualObjects(source.amount, @(1000));
XCTAssertEqualObjects(source.clientSecret, @"src_client_secret_Eh47vJB9AUNENJi0pfObKtCM");
XCTAssertEqualObjects(source.created, [NSDate dateWithTimeIntervalSince1970:1498250487]);
XCTAssertEqualObjects(source.currency, @"usd");
XCTAssertEqual(source.flow, STPSourceFlowReceiver);
XCTAssertFalse(source.livemode);
XCTAssertNil(source.owner.address);
XCTAssertEqualObjects(source.owner.email, @"jenny.rosen@example.com");
XCTAssertNil(source.owner.name);
XCTAssertNil(source.owner.phone);
XCTAssertNil(source.owner.verifiedAddress);
XCTAssertNil(source.owner.verifiedEmail);
XCTAssertNil(source.owner.verifiedName);
XCTAssertNil(source.owner.verifiedPhone);
XCTAssertEqualObjects(source.receiver.address, @"test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N");
XCTAssertEqualObjects(source.receiver.amountCharged, @(0));
XCTAssertEqualObjects(source.receiver.amountReceived, @(0));
XCTAssertEqualObjects(source.receiver.amountReturned, @(0));
XCTAssertEqual(source.status, STPSourceStatusPending);
XCTAssertEqual(source.type, STPSourceTypeBitcoin);
XCTAssertEqual(source.usage, STPSourceUsageSingleUse);
XCTAssertEqualObjects(source.details, response[@"bitcoin"]);
XCTAssertNotEqual(source.allResponseFields, response);
XCTAssertEqualObjects(source.allResponseFields, response);
}
- (NSDictionary *)buildTestResponse_ideal {
// Source: https://stripe.com/docs/sources/ideal
NSDictionary *dict = @{
@"id": @"src_123",
@"object": @"source",
@ -297,6 +414,7 @@
}
- (NSDictionary *)buildTestResponse_sepa_debit {
// Source: https://stripe.com/docs/sources/sepa-debit
NSDictionary *dict = @{
@"id": @"src_123",
@"object": @"source",

View File

@ -75,4 +75,47 @@
}
}
#pragma mark - Description Tests
- (void)testDescription {
STPSourceVerification *verification = [STPSourceVerification decodedObjectFromAPIResponse:[self completeAttributeDictionary]];
XCTAssert(verification.description);
}
#pragma mark - STPAPIResponseDecodable Tests
- (NSDictionary *)completeAttributeDictionary {
// Source: https://stripe.com/docs/sources/sepa-debit
return @{
@"attempts_remaining": @(5),
@"status": @"pending",
};
}
- (void)testDecodedObjectFromAPIResponseRequiredFields {
NSArray<NSString *> *requiredFields = @[
@"status",
];
for (NSString *field in requiredFields) {
NSMutableDictionary *response = [[self completeAttributeDictionary] mutableCopy];
[response removeObjectForKey:field];
XCTAssertNil([STPSourceVerification decodedObjectFromAPIResponse:response]);
}
XCTAssert([STPSourceVerification decodedObjectFromAPIResponse:[self completeAttributeDictionary]]);
}
- (void)testDecodedObjectFromAPIResponseMapping {
NSDictionary *response = [self completeAttributeDictionary];
STPSourceVerification *verification = [STPSourceVerification decodedObjectFromAPIResponse:response];
XCTAssertEqualObjects(verification.attemptsRemaining, @5);
XCTAssertEqual(verification.status, STPSourceVerificationStatusPending);
XCTAssertNotEqual(verification.allResponseFields, response);
XCTAssertEqualObjects(verification.allResponseFields, response);
}
@end