Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class HistoryServiceTest {
val instance = Instance(
baseURI + i,
TranslatableString("displayName"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"NL",
Expand All @@ -100,6 +101,7 @@ class HistoryServiceTest {
Instance(
baseURI + i,
TranslatableString("displayName"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"NL",
Expand All @@ -124,6 +126,7 @@ class HistoryServiceTest {
val instance = Instance(
baseURI,
TranslatableString("displayName"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"HU",
Expand Down Expand Up @@ -154,6 +157,7 @@ class HistoryServiceTest {
val instance = Instance(
baseURI,
TranslatableString("displayName"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"HU",
Expand Down Expand Up @@ -188,6 +192,7 @@ class HistoryServiceTest {
val instance1 = Instance(
"http://example.com/",
TranslatableString("example.com"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"DK",
Expand All @@ -199,6 +204,7 @@ class HistoryServiceTest {
val instance2 = Instance(
"http://something.else/",
TranslatableString("something.else"),
TranslatableString("konijn"),
null,
AuthorizationType.Distributed,
"DK",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class PreferencesServiceTest {
val instance = Instance(
"http://example.com",
TranslatableString("Example"),
TranslatableString("konijn"),
"http://example.com/image.jpg",
AuthorizationType.Distributed,
"HU",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ public void testProfileSerialization() throws SerializerService.UnknownFormatExc

@Test
public void testInstanceSerialization() throws SerializerService.UnknownFormatException {
Instance instance = new Instance("baseUri", new TranslatableString("displayName"), "logoUri", AuthorizationType.Distributed, "HU", true, null, Arrays
.asList("mailto:user@test.example.com", "tel:+0011223344659898"));
Instance instance = new Instance("baseUri", new TranslatableString("displayName"), new TranslatableString("konijn"), "logoUri", AuthorizationType.Distributed, "HU", true, null, Arrays.asList("mailto:user@test.example.com", "tel:+0011223344659898"));
String serializedInstance = _serializerService.serializeInstance(instance);
Instance deserializedInstance = _serializerService.deserializeInstance(serializedInstance);
assertEquals(instance.getDisplayName(), deserializedInstance.getDisplayName());
Expand Down Expand Up @@ -144,13 +143,10 @@ public void testMessageListSerialization() throws SerializerService.UnknownForma
@SuppressWarnings("ConstantConditions")
@Test
public void testSavedTokenListSerialization() throws SerializerService.UnknownFormatException {
Instance instance1 = new Instance("baseUri1", new TranslatableString("displayName1"), null, AuthorizationType.Distributed, "DE", true, "https://example.com/template", Arrays
.asList("mailto:support@example.com", "tel:+00123456789"));
Instance instance2 = new Instance("baseUri2", new TranslatableString("displayName2"), null, AuthorizationType.Local, "FR", true, null, new ArrayList<>());
AuthState state1 = new AuthState(new AuthorizationServiceConfiguration(Uri.parse("http://eduvpn.org/auth"), Uri
.parse("http://eduvpn.org/token"), null));
AuthState state2 = new AuthState(new AuthorizationServiceConfiguration(Uri.parse("http://example.com/auth"), Uri
.parse("http://example.com/token"), null));
Instance instance1 = new Instance("baseUri1", new TranslatableString("displayName1"), new TranslatableString("konijn"), null, AuthorizationType.Distributed, "DE", true, "https://example.com/template", Arrays.asList("mailto:support@example.com", "tel:+00123456789"));
Instance instance2 = new Instance("baseUri2", new TranslatableString("displayName2"), new TranslatableString("konijn"), null, AuthorizationType.Local, "FR", true, null, new ArrayList<>());
AuthState state1 = new AuthState(new AuthorizationServiceConfiguration(Uri.parse("http://eduvpn.org/auth"), Uri.parse("http://eduvpn.org/token"), null));
AuthState state2 = new AuthState(new AuthorizationServiceConfiguration(Uri.parse("http://example.com/auth"), Uri.parse("http://example.com/token"), null));
SavedAuthState token1 = new SavedAuthState(instance1, state1, new Date());
SavedAuthState token2 = new SavedAuthState(instance2, state2, new Date());
List<SavedAuthState> list = Arrays.asList(token1, token2);
Expand All @@ -176,9 +172,8 @@ public void testSavedTokenListSerialization() throws SerializerService.UnknownFo

@Test
public void testSavedProfileListSerialization() throws SerializerService.UnknownFormatException {
Instance instance1 = new Instance("baseUri1", new TranslatableString("displayName1"), "logoUri1", AuthorizationType.Distributed, "SV", true, "https://example.com/template", Collections
.singletonList("mailto:support@example.com"));
Instance instance2 = new Instance("baseUri2", new TranslatableString("displayName2"), "logoUri2", AuthorizationType.Local, "CH", true, null, new ArrayList<>());
Instance instance1 = new Instance("baseUri1", new TranslatableString("displayName1"), new TranslatableString("konijn"), "logoUri1", AuthorizationType.Distributed, "SV", true, "https://example.com/template", Collections.singletonList("mailto:support@example.com"));
Instance instance2 = new Instance("baseUri2", new TranslatableString("displayName2"), new TranslatableString("konijn"), "logoUri2", AuthorizationType.Local, "CH", true, null, new ArrayList<>());
ProfileV2 profile1 = new ProfileV2(new TranslatableString("displayName1"), "profileId1");
ProfileV2 profile2 = new ProfileV2(new TranslatableString("displayName2"), "profileId2");
SavedProfile savedProfile1 = new SavedProfile(instance1, profile1, "profileUUID1");
Expand Down Expand Up @@ -226,11 +221,10 @@ public void testKeyPairSerialization() throws SerializerService.UnknownFormatExc
@Test
public void testSavedKeyPairListSerialization() throws SerializerService.UnknownFormatException {
KeyPair keyPair1 = new KeyPair(false, "cert1", "pk1");
Instance instance1 = new Instance("http://example.com/", new TranslatableString("example.com"), null, AuthorizationType.Distributed, "NL", false, "https://example.com/url_template", new ArrayList<>());
Instance instance1 = new Instance("http://example.com/", new TranslatableString("example.com"), new TranslatableString("konijn"), null, AuthorizationType.Distributed, "NL", false, "https://example.com/url_template", new ArrayList<>());
SavedKeyPair savedKeyPair1 = new SavedKeyPair(instance1, keyPair1);
KeyPair keyPair2 = new KeyPair(true, "example certificate", "example private key");
Instance instance2 = new Instance("http://something.else/", new TranslatableString("something.else"), "http://www.example.com/logo", AuthorizationType.Local, "HU", true, null, Collections
.emptyList());
Instance instance2 = new Instance("http://something.else/", new TranslatableString("something.else"), new TranslatableString("konijn"), "http://www.example.com/logo", AuthorizationType.Local, "HU", true, null, Collections.emptyList());
SavedKeyPair savedKeyPair2 = new SavedKeyPair(instance2, keyPair2);
List<SavedKeyPair> savedKeyPairList = Arrays.asList(savedKeyPair1, savedKeyPair2);
String serializedSavedKeyPairList = _serializerService.serializeSavedKeyPairList(savedKeyPairList);
Expand Down Expand Up @@ -289,7 +283,6 @@ public void testProfileListSerialization() throws SerializerService.UnknownForma
}
}


/**
* Removes the milliseconds from a date. Required because the parser does not care about milliseconds.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class ProviderSearchTest {
typeText("konijn"),
closeSoftKeyboard()
)
onView(withText("SURF (New)")).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) // For some reason isDisplayed() does not work
onView(withText("SURF BV")).check(matches(isDisplayed()))
onView(withText("SURF")).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) // For some reason isDisplayed() does not work
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/nl/eduvpn/app/entity/Instance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ data class Instance(
@Serializable(with = TranslatableStringSerializer::class)
val displayName: TranslatableString = TranslatableString(),

@SerialName("keyword_list")
@Serializable(with = TranslatableStringSerializer::class)
val keywords: TranslatableString? = TranslatableString(),

@SerialName("logo")
val logoUri: String? = null,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import nl.eduvpn.app.EduVPNApplication
import nl.eduvpn.app.MainActivity
import nl.eduvpn.app.R
Expand Down Expand Up @@ -104,6 +103,7 @@ class AddServerFragment : BaseFragment<FragmentAddServerBinding>() {
val customInstance = Instance(
customUrl,
TranslatableString(getString(R.string.custom_provider_display_name)),
TranslatableString(),
null,
AuthorizationType.Local,
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class OrganizationSelectionFragment : BaseFragment<FragmentOrganizationSelection
val customInstance = Instance(
customUrl,
TranslatableString(getString(R.string.custom_provider_display_name)),
TranslatableString(),
null,
AuthorizationType.Local,
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,18 @@ class OrganizationSelectionViewModel @Inject constructor(
organizations.value = emptyList()
servers.value = emptyList()
state.value = ConnectionState.Ready
parentAction.value = ParentAction.DisplayError(R.string.error_server_list_version_check_title, context.getString(R.string.error_server_list_version_check_message))
parentAction.value = ParentAction.DisplayError(
R.string.error_server_list_version_check_title,
context.getString(R.string.error_server_list_version_check_message)
)
} else if (organizationList.version > 0 && lastKnownOrganizationVersion != null && lastKnownOrganizationVersion > organizationList.version) {
organizations.value = emptyList()
servers.value = serverList.serverList
state.value = ConnectionState.Ready
parentAction.value = ParentAction.DisplayError(R.string.error_organization_list_version_check_title, context.getString(R.string.error_organization_list_version_check_message))
parentAction.value = ParentAction.DisplayError(
R.string.error_organization_list_version_check_title,
context.getString(R.string.error_organization_list_version_check_message)
)
}

if (organizationList.version > 0) {
Expand All @@ -127,48 +133,65 @@ class OrganizationSelectionViewModel @Inject constructor(
}
}

private fun matchesServer(
searchText: String,
displayName: TranslatableString,
keywords: TranslatableString?
): Boolean {
return searchText.isBlank() || displayName.translations.any { keyValue ->
keyValue.value.contains(searchText, ignoreCase = true)
} || (keywords != null && keywords.translations.any { keyValue ->
keyValue.value.contains(searchText, ignoreCase = true)
})
}

val adapterItems = Transformations.switchMap(organizations) { organizations ->
Transformations.switchMap(servers) { servers ->
Transformations.map(searchText) { searchText ->
val resultList = mutableListOf<OrganizationAdapter.OrganizationAdapterItem>()
// Search contains at least two dots
if (searchText.count { ".".contains(it) } > 1) {
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(R.drawable.ic_server, R.string.header_connect_your_own_server)
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(
R.drawable.ic_server,
R.string.header_connect_your_own_server
)
resultList += OrganizationAdapter.OrganizationAdapterItem.AddServer(searchText)
return@map resultList
}
val instituteAccessServers = servers.filter {
it.authorizationType == AuthorizationType.Local && (searchText.isNullOrBlank() || it.displayName.bestTranslation?.contains(
searchText,
ignoreCase = true
) == true)
it.authorizationType == AuthorizationType.Local
&& matchesServer(searchText, it.displayName, it.keywords)
}.sortedBy { it.displayName.bestTranslation }
.map { OrganizationAdapter.OrganizationAdapterItem.InstituteAccess(it) }
.map { OrganizationAdapter.OrganizationAdapterItem.InstituteAccess(it) }
val secureInternetServers = organizations.filter {
if (searchText.isNullOrBlank()) {
true
} else {
it.displayName.translations.any { keyValue -> keyValue.value.contains(searchText, ignoreCase = true) } ||
it.keywordList.translations.any { keyValue -> keyValue.value.contains(searchText, ignoreCase = true) }
}
matchesServer(searchText, it.displayName, it.keywordList)
}.mapNotNull { organization ->
val matchingServer = servers
.firstOrNull {
it.authorizationType == AuthorizationType.Distributed &&
it.baseURI == organization.secureInternetHome
}
.firstOrNull {
it.authorizationType == AuthorizationType.Distributed &&
it.baseURI == organization.secureInternetHome
}
if (matchingServer != null) {
OrganizationAdapter.OrganizationAdapterItem.SecureInternet(matchingServer, organization)
OrganizationAdapter.OrganizationAdapterItem.SecureInternet(
matchingServer,
organization
)
} else {
null
}
}
if (instituteAccessServers.isNotEmpty()) {
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(R.drawable.ic_institute, R.string.header_institute_access)
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(
R.drawable.ic_institute,
R.string.header_institute_access
)
resultList += instituteAccessServers
}
if (secureInternetServers.isNotEmpty()) {
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(R.drawable.ic_secure_internet, R.string.header_secure_internet)
resultList += OrganizationAdapter.OrganizationAdapterItem.Header(
R.drawable.ic_secure_internet,
R.string.header_secure_internet
)
resultList += secureInternetServers
}
resultList
Expand Down