Skip to content

Commit 6e696d3

Browse files
committed
feat: allow renaming profiles
- test: unit test for renaming method
1 parent b9ab20d commit 6e696d3

2 files changed

Lines changed: 96 additions & 0 deletions

File tree

AnkiDroid/src/main/java/com/ichi2/anki/multiprofile/ProfileManager.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,40 @@ class ProfileManager private constructor(
224224
return ProfileRestrictedDirectory(directoryFile)
225225
}
226226

227+
/**
228+
* Renames an existing profile by updating its display name in
229+
* the registry.
230+
*
231+
* All other metadata fields (version, creation timestamp) are
232+
* preserved. The change is persisted immediately.
233+
*
234+
* @param profileId The [ProfileId] of the profile to rename.
235+
* @param newDisplayName The new user-facing name.
236+
*
237+
* @throws IllegalArgumentException if [profileId] does not
238+
* exist in the registry.
239+
*/
240+
fun renameProfile(
241+
profileId: ProfileId,
242+
newDisplayName: String,
243+
) {
244+
Timber.d("ProfileManager::renameProfile called for $profileId")
245+
246+
val existing =
247+
profileRegistry.getProfileMetadata(profileId)
248+
?: throw IllegalArgumentException("Profile $profileId not found")
249+
250+
if (existing.displayName == newDisplayName) {
251+
Timber.d("Rename skipped: New name matches existing name for $profileId")
252+
return
253+
}
254+
255+
val updated = existing.copy(displayName = newDisplayName)
256+
profileRegistry.saveProfile(profileId, updated)
257+
258+
Timber.d("Renamed profile $profileId to '$newDisplayName'")
259+
}
260+
227261
private fun triggerAppRestart() {
228262
Timber.w("Restarting app to apply profile switch")
229263
// TODO: Implement process restart logic (e.g. ProcessPhoenix)

AnkiDroid/src/test/java/com/ichi2/anki/multiprofile/ProfileManagerTest.kt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import org.junit.Assert.assertEquals
3939
import org.junit.Assert.assertTrue
4040
import org.junit.Before
4141
import org.junit.Test
42+
import org.junit.jupiter.api.Assertions.assertThrows
4243
import org.junit.runner.RunWith
4344
import org.robolectric.annotation.Config
4445
import java.io.File
@@ -200,4 +201,65 @@ class ProfileManagerTest {
200201
assertEquals(1, allProfiles.size)
201202
assertTrue(allProfiles.containsKey(ProfileId.DEFAULT))
202203
}
204+
205+
fun `renameProfile updates displayName in registry`() {
206+
val manager = ProfileManager.create(context)
207+
val profileId = manager.createNewProfile("Original Name")
208+
val newName = "Updated Name"
209+
210+
manager.renameProfile(profileId, newName)
211+
212+
val json = prefs.getString(profileId.value, null)
213+
val metadata = ProfileManager.ProfileMetadata.fromJson(json!!)
214+
215+
assertEquals(newName, metadata.displayName)
216+
}
217+
218+
@Test
219+
fun `renameProfile preserves version and createdTimestamp`() {
220+
val manager = ProfileManager.create(context)
221+
val profileId = manager.createNewProfile("Original Name")
222+
223+
val originalJson = prefs.getString(profileId.value, null)
224+
val originalMetadata = ProfileManager.ProfileMetadata.fromJson(originalJson!!)
225+
226+
manager.renameProfile(profileId, "New Name")
227+
228+
val updatedJson = prefs.getString(profileId.value, null)
229+
val updatedMetadata = ProfileManager.ProfileMetadata.fromJson(updatedJson!!)
230+
231+
assertEquals("Version must be preserved", originalMetadata.version, updatedMetadata.version)
232+
assertEquals(
233+
"Timestamp must be preserved",
234+
originalMetadata.createdTimestamp,
235+
updatedMetadata.createdTimestamp,
236+
)
237+
}
238+
239+
@Test
240+
fun `renameProfile does not write to disk if name is identical`() {
241+
val manager = ProfileManager.create(context)
242+
val name = "No Change"
243+
val profileId = manager.createNewProfile(name)
244+
245+
val originalJson = prefs.getString(profileId.value, null)
246+
247+
manager.renameProfile(profileId, name)
248+
249+
val currentJson = prefs.getString(profileId.value, null)
250+
assertEquals("No disk write should occur for identical names", originalJson, currentJson)
251+
}
252+
253+
@Test
254+
fun `renameProfile throws IllegalArgumentException for missing profile`() {
255+
val manager = ProfileManager.create(context)
256+
val fakeId = ProfileId("p_ghost")
257+
258+
val exception =
259+
assertThrows(IllegalArgumentException::class.java) {
260+
manager.renameProfile(fakeId, "New Name")
261+
}
262+
263+
assertTrue(exception.message!!.contains("not found"))
264+
}
203265
}

0 commit comments

Comments
 (0)