forked from oppia/oppia-android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from JishnuGoyal/profiles-cant-have-internation…
…alised-names Profiles cant have internationalised names
- Loading branch information
Showing
12 changed files
with
241 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
utility/src/main/java/org/oppia/android/util/profile/ProfileNameValidator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package org.oppia.android.util.profile | ||
|
||
import javax.inject.Inject | ||
|
||
/** Utility to validate that profile names are correctly formatted. */ | ||
class ProfileNameValidator @Inject constructor() { | ||
private val noRepeatedAllowedSymbolsRegex by lazy { Regex("[.'-]{2}") } | ||
|
||
/** | ||
* Validates a profile name to ensure that it isn't confusingly formatted or contains invalid | ||
* characters (e.g. non-letter characters, per the Unicode standard for letter categories, plus | ||
* apostrophes and dashes).. | ||
* | ||
* @param name name of the profile | ||
* @return whether the profile name whether is a valid, acceptable name | ||
*/ | ||
fun isNameValid(name: String): Boolean { | ||
return containsOnlyLettersAndAllowedSymbols(name) && containsNoRepeatedUseOfAllowedSymbols(name) | ||
} | ||
|
||
/** Validates if the character in the name is an alphabet or an allowed symbol or not. */ | ||
private fun containsOnlyLettersAndAllowedSymbols(name: String): Boolean { | ||
name.forEach { | ||
if (!(it.isAlphabetic() || isAllowedSymbol(it))) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
private fun containsNoRepeatedUseOfAllowedSymbols(name: String): Boolean { | ||
return !name.contains(noRepeatedAllowedSymbolsRegex) | ||
} | ||
|
||
private fun isAllowedSymbol(symbol: Char): Boolean { | ||
return symbol == '.' || symbol == '-' || symbol == '\'' | ||
} | ||
|
||
private fun Char.isAlphabetic(): Boolean { | ||
/* | ||
The following categories are based on Kotlin's Char.isLetter() and Character.isAlphabetic(). | ||
It also adds spacing marks which can be safely ignored since they modify other Unicode | ||
characters (which are then being verified as being letters). Note also that 'LETTER_NUMBER' | ||
is included for roman numerals and other number-like letters since these can sometimes show | ||
up in names. | ||
*/ | ||
return when (category) { | ||
CharCategory.UPPERCASE_LETTER, CharCategory.LOWERCASE_LETTER, CharCategory.TITLECASE_LETTER, | ||
CharCategory.MODIFIER_LETTER, CharCategory.OTHER_LETTER, CharCategory.LETTER_NUMBER, | ||
CharCategory.COMBINING_SPACING_MARK, CharCategory.NON_SPACING_MARK -> true | ||
else -> false | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
utility/src/test/java/org/oppia/android/util/profile/BUILD.bazel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
""" | ||
Tests for profile utilities. | ||
""" | ||
|
||
load("@dagger//:workspace_defs.bzl", "dagger_rules") | ||
load("//:oppia_android_test.bzl", "oppia_android_test") | ||
|
||
oppia_android_test( | ||
name = "ProfileNameValidatorTest", | ||
srcs = ["ProfileNameValidatorTest.kt"], | ||
custom_package = "org.oppia.android.util.profile", | ||
test_class = "org.oppia.android.util.profile.ProfileNameValidatorTest", | ||
test_manifest = "//utility:test_manifest", | ||
deps = [ | ||
":dagger", | ||
"//testing/src/main/java/org/oppia/android/testing/junit:oppia_parameterized_test_runner", | ||
"//testing/src/main/java/org/oppia/android/testing/junit:parameterized_robolectric_test_runner", | ||
"//testing/src/main/java/org/oppia/android/testing/robolectric:test_module", | ||
"//testing/src/main/java/org/oppia/android/testing/threading:test_module", | ||
"//testing/src/main/java/org/oppia/android/testing/time:test_module", | ||
"//third_party:androidx_test_ext_junit", | ||
"//third_party:com_google_truth_truth", | ||
"//third_party:junit_junit", | ||
"//third_party:org_robolectric_robolectric", | ||
"//third_party:robolectric_android-all", | ||
"//utility/src/main/java/org/oppia/android/util/locale:prod_module", | ||
"//utility/src/main/java/org/oppia/android/util/logging:prod_module", | ||
"//utility/src/main/java/org/oppia/android/util/profile:profile_name_validator", | ||
], | ||
) | ||
|
||
dagger_rules() |
119 changes: 119 additions & 0 deletions
119
utility/src/test/java/org/oppia/android/util/profile/ProfileNameValidatorTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package org.oppia.android.util.profile | ||
|
||
import android.app.Application | ||
import androidx.test.core.app.ApplicationProvider | ||
import com.google.common.truth.Truth.assertThat | ||
import dagger.BindsInstance | ||
import dagger.Component | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner | ||
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Iteration | ||
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.Parameter | ||
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.RunParameterized | ||
import org.oppia.android.testing.junit.OppiaParameterizedTestRunner.SelectRunnerPlatform | ||
import org.oppia.android.testing.junit.ParameterizedRobolectricTestRunner | ||
import org.oppia.android.testing.robolectric.RobolectricModule | ||
import org.robolectric.annotation.Config | ||
import org.robolectric.annotation.LooperMode | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Suppress("FunctionName") | ||
@RunWith(OppiaParameterizedTestRunner::class) | ||
@SelectRunnerPlatform(ParameterizedRobolectricTestRunner::class) | ||
@LooperMode(LooperMode.Mode.PAUSED) | ||
@Config(manifest = Config.NONE) | ||
class ProfileNameValidatorTest { | ||
@Inject | ||
lateinit var profileNameValidator: ProfileNameValidator | ||
|
||
@Parameter | ||
lateinit var name: String | ||
|
||
@Before | ||
fun setup() { | ||
setUpTestApplicationComponent() | ||
} | ||
|
||
@Test | ||
fun testIsNameValid_nameWithSpaces_returnsFalse() { | ||
val nameWithSpaces = "Ben Henning" | ||
assertThat(profileNameValidator.isNameValid(nameWithSpaces)).isFalse() | ||
} | ||
|
||
@Test | ||
fun testIsNameValid_nameWithNumber_returnsFalse() { | ||
val nameWithNumber = "Jishnu7" | ||
assertThat(profileNameValidator.isNameValid(nameWithNumber)).isFalse() | ||
} | ||
|
||
@Test | ||
@RunParameterized( | ||
Iteration("Ben#Henning", "name=Ben#Henning"), | ||
Iteration("Rajay@T", "name=Rajay@T"), | ||
Iteration("جيشنو^&&", "name=جيشنو^&&"), | ||
Iteration("_Jishnu", "name=_Jishnu") | ||
) | ||
fun testIsNameValid_nameWithDisallowedSymbol_returnsFalse() { | ||
assertThat(profileNameValidator.isNameValid(name)).isFalse() | ||
} | ||
|
||
@Test | ||
@RunParameterized( | ||
Iteration("Ben-Henning", "name=Ben-Henning"), | ||
Iteration("Rajat.T", "name=Rajat.T"), | ||
Iteration("G'Jishnu", "name=G'Jishnu") | ||
) | ||
fun testIsNameValid_nameWithAllowedSymbols_returnsTrue() { | ||
assertThat(profileNameValidator.isNameValid(name)).isTrue() | ||
} | ||
|
||
@Test | ||
@RunParameterized( | ||
Iteration("Ben-.Henning", "name=Ben-.Henning"), | ||
Iteration("Rajat..T", "name=Rajat..T") | ||
) | ||
fun testIsNameValid_nameWithRepeatedAllowedSymbols_returnsFalse() { | ||
assertThat(profileNameValidator.isNameValid(name)).isFalse() | ||
} | ||
|
||
@Test | ||
fun testIsNameValid_nameWithEnglishLetters_returnsTrue() { | ||
val nameWithEnglishLetters = "Jerry" | ||
assertThat(profileNameValidator.isNameValid(nameWithEnglishLetters)).isTrue() | ||
} | ||
|
||
@Test | ||
fun testIsNameValid_nameWithHindiLetters_returnsTrue() { | ||
val nameWithHindiLetters = "जिष्णु" | ||
assertThat(profileNameValidator.isNameValid(nameWithHindiLetters)).isTrue() | ||
} | ||
|
||
@Test | ||
fun testIsNameValid_nameWithArabicLetters_returnsTrue() { | ||
val nameWithArabicLetters = "جيشنو" | ||
assertThat(profileNameValidator.isNameValid(nameWithArabicLetters)).isTrue() | ||
} | ||
|
||
private fun setUpTestApplicationComponent() { | ||
DaggerProfileNameValidatorTest_TestApplicationComponent | ||
.builder() | ||
.setApplication(ApplicationProvider.getApplicationContext()).build().inject(this) | ||
} | ||
|
||
@Singleton | ||
@Component(modules = [RobolectricModule::class]) | ||
interface TestApplicationComponent { | ||
@Component.Builder | ||
interface Builder { | ||
@BindsInstance | ||
fun setApplication(application: Application): Builder | ||
|
||
fun build(): TestApplicationComponent | ||
} | ||
|
||
fun inject(test: ProfileNameValidatorTest) | ||
} | ||
} |