Skip to content

Commit f212fe7

Browse files
committed
Additional tests for better coverage
1 parent babdc8e commit f212fe7

File tree

3 files changed

+206
-2
lines changed

3 files changed

+206
-2
lines changed

libs/SalesforceSDKCore/SalesforceSDKCore.xcodeproj/project.pbxproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
4F2410B1282DCA4B00E5EFE3 /* SFSDKCollectionResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F2410B0282DCA4B00E5EFE3 /* SFSDKCollectionResponse.m */; };
8181
4F3139652331C5A1007B3705 /* SFSDKAuthRootController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F3139642331C5A1007B3705 /* SFSDKAuthRootController.m */; };
8282
4F3139682331C5C7007B3705 /* SFSDKAuthRootController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F3139672331C5B9007B3705 /* SFSDKAuthRootController.h */; };
83+
4F3ECD8A2EBBD150005020A6 /* SFOAuthCoordinatorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F3ECD892EBBD150005020A6 /* SFOAuthCoordinatorTests.m */; };
84+
4F3ECD8C2EBBD182005020A6 /* SFOAuthInfoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F3ECD8B2EBBD182005020A6 /* SFOAuthInfoTests.m */; };
8385
4F5727E327F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F5727DC27F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
8486
4F5727E427F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F5727E227F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.m */; };
8587
4F5A49502E98711600C89DDD /* ScopeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5A494F2E98711600C89DDD /* ScopeParser.swift */; };
@@ -600,6 +602,8 @@
600602
4F2410B0282DCA4B00E5EFE3 /* SFSDKCollectionResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSDKCollectionResponse.m; sourceTree = "<group>"; };
601603
4F3139642331C5A1007B3705 /* SFSDKAuthRootController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSDKAuthRootController.m; sourceTree = "<group>"; };
602604
4F3139672331C5B9007B3705 /* SFSDKAuthRootController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSDKAuthRootController.h; sourceTree = "<group>"; };
605+
4F3ECD892EBBD150005020A6 /* SFOAuthCoordinatorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFOAuthCoordinatorTests.m; sourceTree = "<group>"; };
606+
4F3ECD8B2EBBD182005020A6 /* SFOAuthInfoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFOAuthInfoTests.m; sourceTree = "<group>"; };
603607
4F5727DC27F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFSDKPrimingRecordsResponse.h; sourceTree = "<group>"; };
604608
4F5727E227F27F1A0008CDA4 /* SFSDKPrimingRecordsResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SFSDKPrimingRecordsResponse.m; sourceTree = "<group>"; };
605609
4F5A494F2E98711600C89DDD /* ScopeParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScopeParser.swift; sourceTree = "<group>"; };
@@ -1046,6 +1050,8 @@
10461050
4F7EB3F61BFFC84700768720 /* SalesforceSDKCoreTests */ = {
10471051
isa = PBXGroup;
10481052
children = (
1053+
4F3ECD8B2EBBD182005020A6 /* SFOAuthInfoTests.m */,
1054+
4F3ECD892EBBD150005020A6 /* SFOAuthCoordinatorTests.m */,
10491055
4F5A49572E98B0F800C89DDD /* ScopeParserTests.swift */,
10501056
23F200AB2E551C890091C5F5 /* ActionTypeTests.swift */,
10511057
23F200AD2E551C890091C5F5 /* BootconfigTests.swift */,
@@ -1132,8 +1138,7 @@
11321138
6990CBBF29F5AF56004A5F8D /* SFSDKIDPAuthCodeLoginRequestCommandTest.m */,
11331139
23CAB0F82DCBE51F00B8929B /* Mocks */,
11341140
);
1135-
name = SalesforceSDKCoreTests;
1136-
path = SalesforceSDKCore;
1141+
path = SalesforceSDKCoreTests;
11371142
sourceTree = "<group>";
11381143
};
11391144
4F7EB4571BFFC9D900768720 /* Supporting Files */ = {
@@ -2244,6 +2249,7 @@
22442249
23D96B762E145B400004B06A /* DomainDiscoveryCoordinatorTests.swift in Sources */,
22452250
B7A4AE4922E8CA780060E737 /* SFSDKAuthUtilTests.swift in Sources */,
22462251
69DFE06C2B969C25000906E4 /* PushNotificationDecryptionTests.swift in Sources */,
2252+
4F3ECD8C2EBBD182005020A6 /* SFOAuthInfoTests.m in Sources */,
22472253
4F7EB4161BFFC8D700768720 /* SDKCommonNSDataTests.m in Sources */,
22482254
CE81A9C81E9C26F900F3D0AD /* SFUserAccountManagerNotificationsTests.m in Sources */,
22492255
23F200AC2E551C890091C5F5 /* ActionTypeTests.swift in Sources */,
@@ -2268,6 +2274,7 @@
22682274
69CEBC7E22F368CF00F16218 /* SFNetworkTests.m in Sources */,
22692275
4F7EB41B1BFFC8D700768720 /* SFSDKCryptoUtilsTests.m in Sources */,
22702276
69848CB82364035300893E57 /* SFSDKEncryptedPushNotificationTests.m in Sources */,
2277+
4F3ECD8A2EBBD150005020A6 /* SFOAuthCoordinatorTests.m in Sources */,
22712278
4F9E05322DD6A08000548985 /* SFSDKOAuthTokenEndpointResponseTests.m in Sources */,
22722279
4F06AF8D1C49A18E00F70798 /* SalesforceSDKManagerTests.m in Sources */,
22732280
237C186C2E44FCAE0008015C /* EncryptStreamTests.swift in Sources */,
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
Copyright (c) 2025-present, salesforce.com, inc. All rights reserved.
3+
4+
Redistribution and use of this software in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright notice, this list of conditions
7+
and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright notice, this list of
9+
conditions and the following disclaimer in the documentation and/or other materials provided
10+
with the distribution.
11+
* Neither the name of salesforce.com, inc. nor the names of its contributors may be used to
12+
endorse or promote products derived from this software without specific prior written
13+
permission of salesforce.com, inc.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
22+
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
*/
24+
25+
#import <XCTest/XCTest.h>
26+
#import <SalesforceSDKCore/SalesforceSDKCore.h>
27+
#import "SFOAuthCoordinator+Internal.h"
28+
#import "SFUserAccount+Internal.h"
29+
#import "SFOAuthCredentials+Internal.h"
30+
#import "SFSDKAuthSession.h"
31+
#import "SFSDKAuthRequest.h"
32+
33+
@interface SFOAuthCoordinatorTests : XCTestCase
34+
35+
@end
36+
37+
@implementation SFOAuthCoordinatorTests
38+
39+
- (void)testMigrateRefreshTokenSetup {
40+
// Create test credentials
41+
SFOAuthCredentials *credentials = [[SFOAuthCredentials alloc] initWithIdentifier:@"testIdentifier" clientId:@"testClientId" encrypted:NO];
42+
credentials.redirectUri = @"testapp://callback";
43+
credentials.domain = @"test.salesforce.com";
44+
credentials.accessToken = @"testAccessToken";
45+
credentials.refreshToken = @"testRefreshToken";
46+
credentials.instanceUrl = [NSURL URLWithString:@"https://test.salesforce.com"];
47+
48+
// Create a test user account (not fully logged in to avoid actual API calls)
49+
SFUserAccount *userAccount = [[SFUserAccount alloc] initWithCredentials:credentials];
50+
51+
// Create auth request and session
52+
SFSDKAuthRequest *authRequest = [[SFSDKAuthRequest alloc] init];
53+
authRequest.oauthClientId = @"newClientId";
54+
authRequest.oauthCompletionUrl = @"newapp://callback";
55+
authRequest.loginHost = @"login.salesforce.com";
56+
57+
SFSDKAuthSession *authSession = [[SFSDKAuthSession alloc] initWith:authRequest credentials:nil];
58+
59+
// Track whether callbacks are invoked
60+
__block BOOL failureCallbackInvoked = NO;
61+
__block SFOAuthInfo *capturedAuthInfo = nil;
62+
__block NSError *capturedError = nil;
63+
64+
authSession.authFailureCallback = ^(SFOAuthInfo *authInfo, NSError *error) {
65+
failureCallbackInvoked = YES;
66+
capturedAuthInfo = authInfo;
67+
capturedError = error;
68+
};
69+
70+
// Create coordinator
71+
SFOAuthCoordinator *coordinator = [[SFOAuthCoordinator alloc] initWithAuthSession:authSession];
72+
coordinator.credentials = credentials;
73+
74+
// Verify initial state
75+
XCTAssertNotNil(coordinator.credentials);
76+
XCTAssertEqualObjects(coordinator.credentials.clientId, @"testClientId");
77+
78+
// Call migrateRefreshToken - this will attempt to make a REST API call
79+
// which will fail because the user is not properly logged in
80+
[coordinator migrateRefreshToken:userAccount];
81+
82+
// Wait a bit for the async failure callback
83+
XCTestExpectation *expectation = [self expectationWithDescription:@"Wait for failure callback"];
84+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
85+
[expectation fulfill];
86+
});
87+
[self waitForExpectations:@[expectation] timeout:2.0];
88+
89+
// Verify that the auth info was set to the correct type
90+
// This happens synchronously before the REST call
91+
XCTAssertNotNil(coordinator.authInfo, @"Auth info should be set");
92+
XCTAssertEqual(coordinator.authInfo.authType, SFOAuthTypeRefreshTokenMigration, @"Auth type should be refresh token migration");
93+
94+
// Verify initialRequestLoaded was set to false
95+
XCTAssertFalse(coordinator.initialRequestLoaded, @"Initial request loaded should be false");
96+
97+
// Verify the failure callback was invoked (because the user isn't logged in properly)
98+
XCTAssertTrue(failureCallbackInvoked, @"Failure callback should be invoked when REST API fails");
99+
XCTAssertNotNil(capturedError, @"Should have captured an error");
100+
XCTAssertEqual(capturedAuthInfo.authType, SFOAuthTypeRefreshTokenMigration, @"AuthInfo type should be refresh token migration");
101+
}
102+
103+
@end
104+
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
Copyright (c) 2025-present, salesforce.com, inc. All rights reserved.
3+
4+
Redistribution and use of this software in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright notice, this list of conditions
7+
and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright notice, this list of
9+
conditions and the following disclaimer in the documentation and/or other materials provided
10+
with the distribution.
11+
* Neither the name of salesforce.com, inc. nor the names of its contributors may be used to
12+
endorse or promote products derived from this software without specific prior written
13+
permission of salesforce.com, inc.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
22+
WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
*/
24+
25+
#import <XCTest/XCTest.h>
26+
#import <SalesforceSDKCore/SalesforceSDKCore.h>
27+
28+
@interface SFOAuthInfoTests : XCTestCase
29+
30+
@end
31+
32+
@implementation SFOAuthInfoTests
33+
34+
- (void)testAuthTypeDescription {
35+
// Test SFOAuthTypeUnknown
36+
SFOAuthInfo *unknownInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeUnknown];
37+
XCTAssertEqualObjects(unknownInfo.authTypeDescription, @"SFOAuthTypeUnknown", @"Unknown auth type should return correct description");
38+
XCTAssertEqual(unknownInfo.authType, SFOAuthTypeUnknown, @"Auth type should be Unknown");
39+
40+
// Test SFOAuthTypeUserAgent
41+
SFOAuthInfo *userAgentInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeUserAgent];
42+
XCTAssertEqualObjects(userAgentInfo.authTypeDescription, @"SFOAuthTypeUserAgent", @"UserAgent auth type should return correct description");
43+
XCTAssertEqual(userAgentInfo.authType, SFOAuthTypeUserAgent, @"Auth type should be UserAgent");
44+
45+
// Test SFOAuthTypeWebServer
46+
SFOAuthInfo *webServerInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeWebServer];
47+
XCTAssertEqualObjects(webServerInfo.authTypeDescription, @"SFOAuthTypeWebServer", @"WebServer auth type should return correct description");
48+
XCTAssertEqual(webServerInfo.authType, SFOAuthTypeWebServer, @"Auth type should be WebServer");
49+
50+
// Test SFOAuthTypeRefresh
51+
SFOAuthInfo *refreshInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeRefresh];
52+
XCTAssertEqualObjects(refreshInfo.authTypeDescription, @"SFOAuthTypeRefresh", @"Refresh auth type should return correct description");
53+
XCTAssertEqual(refreshInfo.authType, SFOAuthTypeRefresh, @"Auth type should be Refresh");
54+
55+
// Test SFOAuthTypeAdvancedBrowser
56+
SFOAuthInfo *advancedBrowserInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeAdvancedBrowser];
57+
XCTAssertEqualObjects(advancedBrowserInfo.authTypeDescription, @"SFOAuthTypeAdvancedBrowser", @"AdvancedBrowser auth type should return correct description");
58+
XCTAssertEqual(advancedBrowserInfo.authType, SFOAuthTypeAdvancedBrowser, @"Auth type should be AdvancedBrowser");
59+
60+
// Test SFOAuthTypeJwtTokenExchange
61+
SFOAuthInfo *jwtInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeJwtTokenExchange];
62+
XCTAssertEqualObjects(jwtInfo.authTypeDescription, @"SFOAuthTypeJwtTokenExchange", @"JwtTokenExchange auth type should return correct description");
63+
XCTAssertEqual(jwtInfo.authType, SFOAuthTypeJwtTokenExchange, @"Auth type should be JwtTokenExchange");
64+
65+
// Test SFOAuthTypeIDP
66+
SFOAuthInfo *idpInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeIDP];
67+
XCTAssertEqualObjects(idpInfo.authTypeDescription, @"SFOAuthTypeIDP", @"IDP auth type should return correct description");
68+
XCTAssertEqual(idpInfo.authType, SFOAuthTypeIDP, @"Auth type should be IDP");
69+
70+
// Test SFOAuthTypeNative
71+
SFOAuthInfo *nativeInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeNative];
72+
XCTAssertEqualObjects(nativeInfo.authTypeDescription, @"SFOAuthTypeNative", @"Native auth type should return correct description");
73+
XCTAssertEqual(nativeInfo.authType, SFOAuthTypeNative, @"Auth type should be Native");
74+
75+
// Test SFOAuthTypeRefreshTokenMigration
76+
SFOAuthInfo *migrationInfo = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeRefreshTokenMigration];
77+
XCTAssertEqualObjects(migrationInfo.authTypeDescription, @"SFOAuthTypeRefreshTokenMigration", @"RefreshTokenMigration auth type should return correct description");
78+
XCTAssertEqual(migrationInfo.authType, SFOAuthTypeRefreshTokenMigration, @"Auth type should be RefreshTokenMigration");
79+
}
80+
81+
- (void)testDescription {
82+
// Test that description includes authTypeDescription
83+
SFOAuthInfo *info = [[SFOAuthInfo alloc] initWithAuthType:SFOAuthTypeRefresh];
84+
NSString *description = [info description];
85+
86+
XCTAssertNotNil(description, @"Description should not be nil");
87+
XCTAssertTrue([description containsString:@"SFOAuthInfo"], @"Description should contain class name");
88+
XCTAssertTrue([description containsString:@"authType="], @"Description should contain authType label");
89+
XCTAssertTrue([description containsString:@"SFOAuthTypeRefresh"], @"Description should contain auth type description");
90+
}
91+
92+
@end
93+

0 commit comments

Comments
 (0)