Skip to content

Commit 2d4444f

Browse files
@W-20798759: [MSDK] Add ability to programmatically update servers list
1 parent c672dd5 commit 2d4444f

2 files changed

Lines changed: 178 additions & 3 deletions

File tree

libs/SalesforceSDK/src/com/salesforce/androidsdk/config/LoginServerManager.java

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
*/
2727
package com.salesforce.androidsdk.config;
2828

29+
import static java.lang.String.format;
30+
import static java.util.Locale.US;
31+
2932
import android.content.Context;
3033
import android.content.SharedPreferences;
3134
import android.content.SharedPreferences.Editor;
@@ -130,7 +133,7 @@ public LoginServer getSelectedLoginServer() {
130133
if (name != null && url != null) {
131134
LoginServer server = new LoginServer(name, url, isCustom);
132135

133-
// Only notify livedata consumers if the value has changed.
136+
// Only notify live data consumers if the value has changed.
134137
if (!server.equals(selectedServer.getValue())) {
135138
selectedServer.postValue(server);
136139
}
@@ -323,6 +326,92 @@ public List<LoginServer> getLoginServersFromPreferences() {
323326
return getLoginServersFromPreferences(settings);
324327
}
325328

329+
/**
330+
* Reorders a custom login server in the list of login servers.
331+
*
332+
* @param originalIndex The original index of the custom login server. If this is not the index
333+
* of a custom login server, this method will do nothing
334+
* @param updatedIndex The new index of the custom login server. This must be after the last
335+
* non-custom login server and within the updatable bounds of the list. If
336+
* it is not it will be automatically corrected
337+
*/
338+
@SuppressWarnings("unused")
339+
public void reorderCustomLoginServer(
340+
final int originalIndex,
341+
int updatedIndex
342+
) {
343+
// Get the login server at the original index.
344+
final List<LoginServer> loginServers = getLoginServers();
345+
final LoginServer originalLoginServer = loginServers.get(originalIndex);
346+
347+
// Guard against reordering a non-custom login server.
348+
if (!originalLoginServer.isCustom) {
349+
return;
350+
}
351+
352+
// Determine the last non-custom login server index.
353+
final List<LoginServer> servers = getLoginServers();
354+
int lastNonCustomIndex = -1;
355+
for (int i = servers.size() - 1; i >= 0; i--) {
356+
if (!servers.get(i).isCustom) {
357+
lastNonCustomIndex = i;
358+
break;
359+
}
360+
}
361+
362+
// Adjust the re-ordered custom login server index to be within bounds.
363+
if (updatedIndex <= lastNonCustomIndex) {
364+
updatedIndex = lastNonCustomIndex + 1;
365+
} else if (updatedIndex >= servers.size()) {
366+
updatedIndex = servers.size() - 1;
367+
}
368+
369+
// Update the login server list.
370+
loginServers.remove(originalIndex);
371+
loginServers.add(updatedIndex, originalLoginServer);
372+
373+
// Edit each login server indexed after the updated index.
374+
final Editor editor = settings.edit();
375+
for (int i = updatedIndex; i < loginServers.size(); i++) {
376+
final LoginServer loginServer = loginServers.get(i);
377+
editor.remove(format(US, SERVER_NAME, i))
378+
.remove(format(US, SERVER_URL, i))
379+
.remove(format(US, IS_CUSTOM, i))
380+
.putString(format(US, SERVER_NAME, i), loginServer.name)
381+
.putString(format(US, SERVER_URL, i), loginServer.url)
382+
.putBoolean(format(US, IS_CUSTOM, i), loginServer.isCustom);
383+
}
384+
editor.apply();
385+
}
386+
387+
/**
388+
* Replaces one custom login server with another.
389+
*
390+
* @param originalCustomLoginServer The original custom login server
391+
* @param updatedCustomLoginServer The updated custom login server
392+
*/
393+
@SuppressWarnings("unused")
394+
public void replaceCustomLoginServer(
395+
final LoginServer originalCustomLoginServer,
396+
final LoginServer updatedCustomLoginServer
397+
) {
398+
// Guard against replacing a non-custom login server.
399+
if (!originalCustomLoginServer.isCustom || !updatedCustomLoginServer.isCustom) {
400+
return;
401+
}
402+
403+
final int originalIndex = getLoginServers().indexOf(originalCustomLoginServer);
404+
405+
// Guard against an original login server that doesn't exist.
406+
if (originalIndex == -1) {
407+
return;
408+
}
409+
410+
removeServer(originalCustomLoginServer);
411+
addCustomLoginServer(updatedCustomLoginServer.name, updatedCustomLoginServer.url);
412+
reorderCustomLoginServer(getLoginServers().size() - 1, originalIndex);
413+
}
414+
326415
/**
327416
* Returns production and sandbox as the login servers
328417
* (only called when servers.xml is missing).

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/auth/LoginServerManagerTest.java

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
import android.content.Context;
3232

3333
import androidx.arch.core.executor.testing.InstantTaskExecutorRule;
34-
import androidx.test.platform.app.InstrumentationRegistry;
35-
import androidx.test.filters.SmallTest;
3634
import androidx.test.ext.junit.runners.AndroidJUnit4;
35+
import androidx.test.filters.SmallTest;
36+
import androidx.test.platform.app.InstrumentationRegistry;
3737

3838
import com.salesforce.androidsdk.TestForceApp;
3939
import com.salesforce.androidsdk.app.SalesforceSDKManager;
@@ -347,6 +347,92 @@ public void testAddingDuplicateServers() {
347347
loginServerManager.getLoginServers().size());
348348
}
349349

350+
/**
351+
* Test attempting to add a duplicate server default or custom server.
352+
*/
353+
@Test
354+
public void testReplaceAndReOrderCustomLoginServer() {
355+
356+
// Test data.
357+
final String originalName = "ORIGINAL_CUSTOM_LOGIN_SERVER_FOR_REPLACEMENT_TEST";
358+
final String originalUrl = "https://original.example.com";
359+
final LoginServer originalCustomLoginServer = new LoginServer(
360+
originalName,
361+
originalUrl,
362+
true
363+
);
364+
final String otherName = "OTHER_CUSTOM_LOGIN_SERVER_FOR_REPLACEMENT_TEST";
365+
final String otherUrl = "https://other.example.com";
366+
final LoginServer otherCustomLoginServer = new LoginServer(
367+
otherName,
368+
otherUrl,
369+
true
370+
);
371+
final String updatedName = "UPDATED_CUSTOM_LOGIN_SERVER_FOR_REPLACEMENT_TEST";
372+
final String updatedUrl = "https://updated.example.com";
373+
final LoginServer updatedCustomLoginServer = new LoginServer(
374+
updatedName,
375+
updatedUrl,
376+
true
377+
);
378+
final String nonCustomName = "NON_CUSTOM_LOGIN_SERVER_FOR_REPLACEMENT_TEST";
379+
final String nonCustomUrl = "https://non.custom.example.com";
380+
final LoginServer nonCustomLoginServer = new LoginServer(
381+
nonCustomName,
382+
nonCustomUrl,
383+
false
384+
);
385+
386+
// Verify the original and other custom login servers are not present.
387+
Assert.assertFalse(loginServerManager.getLoginServers().contains(originalCustomLoginServer));
388+
Assert.assertFalse(loginServerManager.getLoginServers().contains(otherCustomLoginServer));
389+
390+
// Add the original and other custom login server.
391+
loginServerManager.addCustomLoginServer(originalName, originalUrl);
392+
loginServerManager.addCustomLoginServer(otherName, otherUrl);
393+
394+
// Verify the original and other custom login servers were added.
395+
Assert.assertEquals(originalCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
396+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
397+
398+
// Prepare for negative tests.
399+
final LoginServer production = new LoginServer("Production", "https://login.salesforce.com", false);
400+
final LoginServer productionMismatch = new LoginServer("Production", "https://login.salesforce.com", true);
401+
final LoginServer productionReplacement = new LoginServer("Production Replaced", "https://login.salesforce.com", false);
402+
403+
// Attempt the prohibited replacement of a non-custom login server where the original matches.
404+
loginServerManager.replaceCustomLoginServer(production, productionReplacement);
405+
Assert.assertTrue(loginServerManager.getLoginServers().contains(production));
406+
Assert.assertFalse(loginServerManager.getLoginServers().contains(productionReplacement));
407+
408+
// Attempt the prohibited replacement of a non-custom login server where the original doesn't exit.
409+
loginServerManager.replaceCustomLoginServer(productionMismatch, productionReplacement);
410+
Assert.assertTrue(loginServerManager.getLoginServers().contains(production));
411+
Assert.assertFalse(loginServerManager.getLoginServers().contains(productionReplacement));
412+
413+
// Attempt the prohibited reordering of a non-custom login server.
414+
loginServerManager.reorderCustomLoginServer(0, 1);
415+
Assert.assertEquals(loginServerManager.getLoginServers().get(0), production);
416+
417+
// Replace the original custom login server with a non-custom server.
418+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, nonCustomLoginServer);
419+
420+
// Verify the original and other custom login servers weren't changed.
421+
Assert.assertFalse(loginServerManager.getLoginServers().contains(nonCustomLoginServer));
422+
Assert.assertEquals(originalCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
423+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
424+
425+
// Replace the original custom login server.
426+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, updatedCustomLoginServer);
427+
428+
// Verify the original custom login server is not present.
429+
Assert.assertFalse(loginServerManager.getLoginServers().contains(originalCustomLoginServer));
430+
431+
// Verify the updated and other custom login servers are present.
432+
Assert.assertEquals(updatedCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
433+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
434+
}
435+
350436
private void assertProduction(LoginServer server) {
351437
Assert.assertEquals("Expected production's name", "Production", server.name);
352438
Assert.assertEquals("Expected production's url", PRODUCTION_URL, server.url);

0 commit comments

Comments
 (0)