Skip to content

Commit 8c57824

Browse files
@W-20798759: [MSDK] Add ability to programmatically update servers list (#2841)
1 parent c783226 commit 8c57824

2 files changed

Lines changed: 214 additions & 3 deletions

File tree

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

Lines changed: 92 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,94 @@ 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 firstCustomLoginServerIndex = -1;
355+
for (int i = servers.size() - 1; i >= 0; i--) {
356+
if (servers.get(i).isCustom) {
357+
firstCustomLoginServerIndex = i;
358+
}
359+
}
360+
361+
// Adjust the re-ordered custom login server index to be within bounds.
362+
if (updatedIndex <= firstCustomLoginServerIndex) {
363+
updatedIndex = firstCustomLoginServerIndex;
364+
} else if (updatedIndex >= servers.size()) {
365+
updatedIndex = servers.size() - 1;
366+
}
367+
368+
// Update the login server list.
369+
loginServers.remove(originalIndex);
370+
loginServers.add(updatedIndex, originalLoginServer);
371+
372+
// Edit each login server indexed after the updated index.
373+
final Editor editor = settings.edit();
374+
for (int i = updatedIndex; i < loginServers.size(); i++) {
375+
final LoginServer loginServer = loginServers.get(i);
376+
editor.remove(format(US, SERVER_NAME, i))
377+
.remove(format(US, SERVER_URL, i))
378+
.remove(format(US, IS_CUSTOM, i))
379+
.putString(format(US, SERVER_NAME, i), loginServer.name)
380+
.putString(format(US, SERVER_URL, i), loginServer.url)
381+
.putBoolean(format(US, IS_CUSTOM, i), loginServer.isCustom);
382+
}
383+
editor.apply();
384+
}
385+
386+
/**
387+
* Replaces one custom login server with another.
388+
*
389+
* @param originalCustomLoginServer The original custom login server. If this is not a custom
390+
* login server or doesn't match an existing login server this
391+
* method will do nothing.
392+
* @param updatedCustomLoginServer The updated custom login server. If this is not a custom
393+
* login server this method will do nothing.
394+
*/
395+
@SuppressWarnings("unused")
396+
public void replaceCustomLoginServer(
397+
final LoginServer originalCustomLoginServer,
398+
final LoginServer updatedCustomLoginServer
399+
) {
400+
// Guard against replacing a non-custom login server.
401+
if (!originalCustomLoginServer.isCustom || !updatedCustomLoginServer.isCustom) {
402+
return;
403+
}
404+
405+
final int originalIndex = getLoginServers().indexOf(originalCustomLoginServer);
406+
407+
// Guard against an original login server that doesn't exist.
408+
if (originalIndex == -1) {
409+
return;
410+
}
411+
412+
removeServer(originalCustomLoginServer);
413+
addCustomLoginServer(updatedCustomLoginServer.name, updatedCustomLoginServer.url);
414+
reorderCustomLoginServer(getLoginServers().size() - 1, originalIndex);
415+
}
416+
326417
/**
327418
* Returns production and sandbox as the login servers
328419
* (only called when servers.xml is missing).

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

Lines changed: 122 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,126 @@ public void testAddingDuplicateServers() {
347347
loginServerManager.getLoginServers().size());
348348
}
349349

350+
/**
351+
* Test both replace and re-order custom login 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+
391+
// Add the original and other custom login server.
392+
loginServerManager.addCustomLoginServer(originalName, originalUrl);
393+
loginServerManager.addCustomLoginServer(otherName, otherUrl);
394+
395+
// Verify the original and other custom login servers were added.
396+
Assert.assertEquals(originalCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
397+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
398+
399+
400+
// Prepare for negative tests.
401+
final LoginServer production = new LoginServer("Production", "https://login.salesforce.com", false);
402+
final LoginServer productionMismatch = new LoginServer("Production?", "https://login.salesforce.com", true);
403+
final LoginServer productionReplacement = new LoginServer("Production Replaced", "https://login.salesforce.com", false);
404+
final LoginServer productionReplacementMismatch = new LoginServer("Production Replaced?", "https://login.salesforce.com", true);
405+
406+
// Attempt the prohibited replacement of a non-custom login server where the original matches.
407+
loginServerManager.replaceCustomLoginServer(production, productionReplacement);
408+
Assert.assertTrue(loginServerManager.getLoginServers().contains(production));
409+
Assert.assertFalse(loginServerManager.getLoginServers().contains(productionReplacement));
410+
411+
412+
// Attempt the prohibited replacement of a non-custom login server where the original doesn't exit.
413+
loginServerManager.replaceCustomLoginServer(productionMismatch, productionReplacementMismatch);
414+
Assert.assertTrue(loginServerManager.getLoginServers().contains(production));
415+
Assert.assertFalse(loginServerManager.getLoginServers().contains(productionReplacement));
416+
417+
418+
// Attempt the prohibited reordering of a non-custom login server.
419+
loginServerManager.reorderCustomLoginServer(0, 1);
420+
Assert.assertEquals(loginServerManager.getLoginServers().get(0), production);
421+
422+
423+
// Replace the original custom login server with a non-custom server.
424+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, nonCustomLoginServer);
425+
426+
// Verify the original and other custom login servers weren't changed.
427+
Assert.assertFalse(loginServerManager.getLoginServers().contains(nonCustomLoginServer));
428+
Assert.assertEquals(originalCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
429+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
430+
431+
432+
// Replace the original custom login server.
433+
loginServerManager.replaceCustomLoginServer(originalCustomLoginServer, updatedCustomLoginServer);
434+
435+
// Verify the original custom login server is not present.
436+
Assert.assertFalse(loginServerManager.getLoginServers().contains(originalCustomLoginServer));
437+
438+
// Verify the updated and other custom login servers are present.
439+
Assert.assertEquals(updatedCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 2));
440+
Assert.assertEquals(otherCustomLoginServer, loginServerManager.getLoginServers().get(loginServerManager.getLoginServers().size() - 1));
441+
442+
// Attempt to move the updated custom login server above the non-custom login servers.
443+
loginServerManager.reorderCustomLoginServer(loginServerManager.getLoginServers().indexOf(updatedCustomLoginServer), 0);
444+
445+
// Verify the updated custom login server is actually immediately following the last non-custom login server.
446+
final List<LoginServer> loginServers = loginServerManager.getLoginServers();
447+
int lastNonCustomIndex = -1;
448+
for (int i = 0; i < loginServers.size(); i++) {
449+
final LoginServer loginServer = loginServers.get(i);
450+
if (!loginServer.isCustom) {
451+
lastNonCustomIndex = i;
452+
}
453+
}
454+
Assert.assertEquals(loginServers.get(lastNonCustomIndex + 1), updatedCustomLoginServer);
455+
456+
457+
// Attempt to move the updated custom login server one greater than the upper bounds of the login servers list.
458+
loginServerManager.reorderCustomLoginServer(loginServerManager.getLoginServers().indexOf(updatedCustomLoginServer), loginServerManager.getLoginServers().size());
459+
460+
// Attempt to move the updated custom login server more than one greater than the upper bounds of the login servers list.
461+
loginServerManager.reorderCustomLoginServer(loginServerManager.getLoginServers().indexOf(updatedCustomLoginServer), loginServerManager.getLoginServers().size() + 1);
462+
463+
// Attempt to move the updated custom login server more than one less than the upper bounds of the login servers list.
464+
loginServerManager.reorderCustomLoginServer(loginServerManager.getLoginServers().indexOf(updatedCustomLoginServer), loginServerManager.getLoginServers().size() - 1);
465+
466+
// Verify the updated custom login server is now the last login server in the list.
467+
Assert.assertEquals(loginServerManager.getLoginServers().getLast(), updatedCustomLoginServer);
468+
}
469+
350470
private void assertProduction(LoginServer server) {
351471
Assert.assertEquals("Expected production's name", "Production", server.name);
352472
Assert.assertEquals("Expected production's url", PRODUCTION_URL, server.url);

0 commit comments

Comments
 (0)