Skip to content

Commit 62e6be4

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

2 files changed

Lines changed: 156 additions & 3 deletions

File tree

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

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@
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;
3235
import android.content.res.XmlResourceParser;
3336
import android.os.Looper;
37+
import android.util.Log;
3438

3539
import androidx.annotation.NonNull;
3640
import androidx.lifecycle.MutableLiveData;
@@ -130,7 +134,7 @@ public LoginServer getSelectedLoginServer() {
130134
if (name != null && url != null) {
131135
LoginServer server = new LoginServer(name, url, isCustom);
132136

133-
// Only notify livedata consumers if the value has changed.
137+
// Only notify live data consumers if the value has changed.
134138
if (!server.equals(selectedServer.getValue())) {
135139
selectedServer.postValue(server);
136140
}
@@ -323,6 +327,88 @@ public List<LoginServer> getLoginServersFromPreferences() {
323327
return getLoginServersFromPreferences(settings);
324328
}
325329

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

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

Lines changed: 69 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,73 @@ 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+
// Replace the original custom login server with a non-custom server.
399+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, nonCustomLoginServer);
400+
401+
// Verify the original and other custom login servers weren't changed.
402+
Assert.assertFalse(loginServerManager.getLoginServers().contains(nonCustomLoginServer));
403+
Assert.assertEquals(originalCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
404+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
405+
406+
// Replace the original custom login server.
407+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, updatedCustomLoginServer);
408+
409+
// Verify the original custom login server is not present.
410+
Assert.assertFalse(loginServerManager.getLoginServers().contains(originalCustomLoginServer));
411+
412+
// Verify the updated and other custom login servers are present.
413+
Assert.assertEquals(updatedCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
414+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
415+
}
416+
350417
private void assertProduction(LoginServer server) {
351418
Assert.assertEquals("Expected production's name", "Production", server.name);
352419
Assert.assertEquals("Expected production's url", PRODUCTION_URL, server.url);

0 commit comments

Comments
 (0)