From 94a518cdfac4139a82f94541c93e4f180342059d Mon Sep 17 00:00:00 2001 From: Ralfmal Date: Sat, 28 Jun 2025 16:45:21 +0000 Subject: [PATCH 01/12] Start draft PR From f94c6b5829a510ab8141b31dc2b6d9e9f180a354 Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:45:31 +0000 Subject: [PATCH 02/12] Start draft PR From 98d23bb8a926a3e861ebf1ee74dc8c8b4004b845 Mon Sep 17 00:00:00 2001 From: Ralfmal Date: Sat, 28 Jun 2025 16:45:39 +0000 Subject: [PATCH 03/12] Add comprehensive .gitignore for Android Kotlin project --- .gitignore | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe30152 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Android Studio +*.iml +.gradle +/local.properties +/.idea/ +.DS_Store +/build +/captures +.externalNativeBuild +.cxx + +# Kotlin and Java +*.class +*.log +*.ctxt +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# Dependency directories +node_modules/ +kotlin-js-store/ + +# Gradle +.gradle/ +build/ + +# Miscellaneous +.env +__pycache__/ \ No newline at end of file From 184ee17600a582e27358f0976d552436d40b3a2f Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:45:47 +0000 Subject: [PATCH 04/12] Add .gitignore for Android/Kotlin project --- .gitignore | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6199bb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Android Studio +.idea/ +*.iml +.gradle/ +build/ +captures/ + +# Kotlin +*.class +*.kotlin_module + +# Gradle +local.properties +/out/ + +# Logs +*.log + +# Virtual Machine +.DS_Store + +# Dependency directories +/node_modules/ + +# Compiled class files +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs +hs_err_pid* \ No newline at end of file From 9ddd4b84a574507e477ca6333687728260187292 Mon Sep 17 00:00:00 2001 From: Ralfmal Date: Sat, 28 Jun 2025 16:45:51 +0000 Subject: [PATCH 05/12] Implement navigation logic for CreateTodoItemActivity --- .../todoapp/ui/CreateTodoItemActivity.kt | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 app/src/main/java/com/example/todoapp/ui/CreateTodoItemActivity.kt diff --git a/app/src/main/java/com/example/todoapp/ui/CreateTodoItemActivity.kt b/app/src/main/java/com/example/todoapp/ui/CreateTodoItemActivity.kt new file mode 100644 index 0000000..237d1bc --- /dev/null +++ b/app/src/main/java/com/example/todoapp/ui/CreateTodoItemActivity.kt @@ -0,0 +1,71 @@ +package com.example.todoapp.ui + +import android.content.Intent +import android.os.Bundle +import android.widget.Button +import android.widget.EditText +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import com.example.todoapp.R +import com.example.todoapp.data.TodoItem +import com.example.todoapp.data.TodoRepository +import kotlinx.coroutines.launch + +class CreateTodoItemActivity : AppCompatActivity() { + + private lateinit var titleEditText: EditText + private lateinit var descriptionEditText: EditText + private lateinit var saveButton: Button + private lateinit var todoRepository: TodoRepository + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_create_todo_item) + + // Initialize views + titleEditText = findViewById(R.id.edit_text_todo_title) + descriptionEditText = findViewById(R.id.edit_text_todo_description) + saveButton = findViewById(R.id.button_save_todo) + + // Initialize repository (assumes dependency injection or manual initialization) + todoRepository = TodoRepository(application) + + saveButton.setOnClickListener { + saveTodoItem() + } + } + + private fun saveTodoItem() { + val title = titleEditText.text.toString().trim() + val description = descriptionEditText.text.toString().trim() + + // Basic validation + if (title.isEmpty()) { + titleEditText.error = "Title cannot be empty" + return + } + + // Create todo item + val todoItem = TodoItem( + title = title, + description = description, + isCompleted = false + ) + + // Save todo item using coroutines + lifecycleScope.launch { + todoRepository.insert(todoItem) + // Navigate back to main activity + navigateToMainActivity() + } + } + + private fun navigateToMainActivity() { + val intent = Intent(this, MainActivity::class.java) + // Clear the back stack so user can't navigate back to create todo screen + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(intent) + // Finish current activity + finish() + } +} \ No newline at end of file From 672d612c898711500b1002ee7db48a63d449bc1e Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:45:56 +0000 Subject: [PATCH 06/12] Add TodoValidation class with title validation logic --- .../com/todoapp/validation/TodoValidation.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/kotlin/com/todoapp/validation/TodoValidation.kt diff --git a/src/main/kotlin/com/todoapp/validation/TodoValidation.kt b/src/main/kotlin/com/todoapp/validation/TodoValidation.kt new file mode 100644 index 0000000..bbcd126 --- /dev/null +++ b/src/main/kotlin/com/todoapp/validation/TodoValidation.kt @@ -0,0 +1,27 @@ +package com.todoapp.validation + +/** + * Provides validation methods for Todo items + */ +object TodoValidation { + /** + * Validates the title of a todo item + * + * @param title The title to validate + * @return Boolean indicating if the title is valid + */ + fun isValidTitle(title: String?): Boolean { + // Check if title is null or empty after trimming whitespace + return !title.isNullOrBlank() + } + + /** + * Throws an exception if the title is invalid + * + * @param title The title to validate + * @throws IllegalArgumentException if title is invalid + */ + fun validateTitle(title: String?) { + require(isValidTitle(title)) { "Todo item title cannot be empty" } + } +} \ No newline at end of file From 4d2306b3e81e619b8301df4305520eba805ecb5b Mon Sep 17 00:00:00 2001 From: Ralfmal Date: Sat, 28 Jun 2025 16:46:01 +0000 Subject: [PATCH 07/12] Add test for CreateTodoItemActivity navigation logic --- .../todoapp/CreateTodoItemActivityTest.kt | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 app/src/test/java/com/example/todoapp/CreateTodoItemActivityTest.kt diff --git a/app/src/test/java/com/example/todoapp/CreateTodoItemActivityTest.kt b/app/src/test/java/com/example/todoapp/CreateTodoItemActivityTest.kt new file mode 100644 index 0000000..cf792ed --- /dev/null +++ b/app/src/test/java/com/example/todoapp/CreateTodoItemActivityTest.kt @@ -0,0 +1,44 @@ +package com.example.todoapp + +import android.content.Intent +import androidx.test.core.app.ActivityScenario +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.example.todoapp.ui.CreateTodoItemActivity +import com.example.todoapp.ui.MainActivity +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.Robolectric +import org.robolectric.Shadows.shadowOf + +@RunWith(AndroidJUnit4::class) +class CreateTodoItemActivityTest { + + @Test + fun `test navigation to main activity after saving todo item`() { + // Create an activity scenario + val scenario = ActivityScenario.launch(CreateTodoItemActivity::class.java) + + scenario.onActivity { activity -> + // Mock saving a todo item by directly calling private method + val method = activity.javaClass.getDeclaredMethod("navigateToMainActivity") + method.isAccessible = true + method.invoke(activity) + + // Get the next started intent + val shadowActivity = Robolectric.shadowOf(activity) + val startedIntent = shadowActivity.nextStartedActivity + + // Verify intent navigation + assertEquals(MainActivity::class.java.name, + startedIntent.component?.className) + + // Verify intent flags + assertEquals( + Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK, + startedIntent.flags + ) + } + } +} \ No newline at end of file From d07f218baf984708835c86b87aa5badabe621180 Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:46:07 +0000 Subject: [PATCH 08/12] Add comprehensive tests for TodoValidation --- .../todoapp/validation/TodoValidationTest.kt | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/test/kotlin/com/todoapp/validation/TodoValidationTest.kt diff --git a/src/test/kotlin/com/todoapp/validation/TodoValidationTest.kt b/src/test/kotlin/com/todoapp/validation/TodoValidationTest.kt new file mode 100644 index 0000000..698061d --- /dev/null +++ b/src/test/kotlin/com/todoapp/validation/TodoValidationTest.kt @@ -0,0 +1,67 @@ +package com.todoapp.validation + +import org.junit.Assert.* +import org.junit.Test + +class TodoValidationTest { + @Test + fun `test valid title returns true`() { + // Arrange + val validTitle = "Buy groceries" + + // Act + val result = TodoValidation.isValidTitle(validTitle) + + // Assert + assertTrue("Valid title should return true", result) + } + + @Test + fun `test empty title returns false`() { + // Arrange + val emptyTitle = "" + + // Act + val result = TodoValidation.isValidTitle(emptyTitle) + + // Assert + assertFalse("Empty title should return false", result) + } + + @Test + fun `test null title returns false`() { + // Arrange + val nullTitle: String? = null + + // Act + val result = TodoValidation.isValidTitle(nullTitle) + + // Assert + assertFalse("Null title should return false", result) + } + + @Test + fun `test whitespace-only title returns false`() { + // Arrange + val whitespaceTitle = " " + + // Act + val result = TodoValidation.isValidTitle(whitespaceTitle) + + // Assert + assertFalse("Whitespace-only title should return false", result) + } + + @Test(expected = IllegalArgumentException::class) + fun `test validateTitle throws exception for invalid title`() { + // Act + TodoValidation.validateTitle("") + } + + @Test + fun `test validateTitle does not throw for valid title`() { + // Act + TodoValidation.validateTitle("Valid Title") + // Assert (no exception thrown) + } +} \ No newline at end of file From 47755c153db5cdf41fb2dcdd7f5ef9546c6fa318 Mon Sep 17 00:00:00 2001 From: Ralfmal Date: Sat, 28 Jun 2025 16:46:14 +0000 Subject: [PATCH 09/12] Configure build.gradle with project dependencies --- app/build.gradle | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 app/build.gradle diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..6708cf9 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' + id 'kotlin-kapt' +} + +dependencies { + // Kotlin standard library + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.0" + + // AndroidX + implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' + + // Room Database + implementation 'androidx.room:room-runtime:2.5.2' + implementation 'androidx.room:room-ktx:2.5.2' + kapt 'androidx.room:room-compiler:2.5.2' + + // Test dependencies + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.robolectric:robolectric:4.10.3' + testImplementation 'androidx.test:core:1.5.0' + testImplementation 'androidx.test.ext:junit:1.1.5' +} \ No newline at end of file From 14ad2cce56674e65b8650e775b7e0a7bce62e2f2 Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:46:16 +0000 Subject: [PATCH 10/12] Add build configuration with JUnit dependencies --- build.gradle.kts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..f809b70 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + kotlin("jvm") version "1.9.0" +} + +dependencies { + testImplementation("junit:junit:4.13.2") + testImplementation(kotlin("test")) +} + +repositories { + mavenCentral() +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file From 6bd9b4fd5294c79b986ab832c69d5b30cb7e6cfd Mon Sep 17 00:00:00 2001 From: Vuk7912 Date: Sat, 28 Jun 2025 16:46:25 +0000 Subject: [PATCH 11/12] Create Gradle build file for Kotlin project with JUnit --- build.gradle | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 build.gradle diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..919b394 --- /dev/null +++ b/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.9.0' +} + +dependencies { + testImplementation 'junit:junit:4.13.2' + testImplementation "org.jetbrains.kotlin:kotlin-test-junit" +} + +repositories { + mavenCentral() +} + +test { + useJUnit() +} \ No newline at end of file From 2d0b8d7266511f70cce9fa75525240ed2ac7a490 Mon Sep 17 00:00:00 2001 From: hubbahubba11x Date: Sat, 5 Jul 2025 09:42:19 +0000 Subject: [PATCH 12/12] Start draft PR