diff --git a/catroid/src/androidTest/java/org/catrobat/catroid/uiespresso/ui/fragment/AddFromLocalProjectsTest.kt b/catroid/src/androidTest/java/org/catrobat/catroid/uiespresso/ui/fragment/AddFromLocalProjectsTest.kt new file mode 100644 index 00000000000..17cc4d047c1 --- /dev/null +++ b/catroid/src/androidTest/java/org/catrobat/catroid/uiespresso/ui/fragment/AddFromLocalProjectsTest.kt @@ -0,0 +1,177 @@ +/* + * Catroid: An on-device visual programming system for Android devices + * Copyright (C) 2010-2025 The Catrobat Team + * () + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * An additional term exception under section 7 of the GNU Affero + * General Public License, version 3, is available at + * http://developer.catrobat.org/license_additional_term + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.catrobat.catroid.uiespresso.ui.fragment + +import androidx.appcompat.widget.SwitchCompat +import androidx.test.core.app.ApplicationProvider.getApplicationContext +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.catrobat.catroid.ProjectManager +import org.catrobat.catroid.R +import org.catrobat.catroid.common.BrickValues +import org.catrobat.catroid.content.Project +import org.catrobat.catroid.content.Script +import org.catrobat.catroid.content.Sprite +import org.catrobat.catroid.content.StartScript +import org.catrobat.catroid.content.bricks.ChangeXByNBrick +import org.catrobat.catroid.content.bricks.IfLogicBeginBrick +import org.catrobat.catroid.content.bricks.SetXBrick +import org.catrobat.catroid.formulaeditor.Formula +import org.catrobat.catroid.io.XstreamSerializer +import org.catrobat.catroid.test.utils.TestUtils +import org.catrobat.catroid.testsuites.annotations.Cat.AppUi +import org.catrobat.catroid.testsuites.annotations.Level.Smoke +import org.catrobat.catroid.ui.ProjectActivity +import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.setLanguageSharedPreference +import org.catrobat.catroid.uiespresso.content.brick.utils.BrickDataInteractionWrapper +import org.catrobat.catroid.uiespresso.util.UiTestUtils +import org.catrobat.catroid.uiespresso.util.rules.FragmentActivityTestRule +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.experimental.categories.Category +import org.junit.runner.RunWith +import org.koin.java.KoinJavaComponent.inject + +@Category(AppUi::class, Smoke::class) +@RunWith(AndroidJUnit4::class) +class AddFromLocalProjectsTest { + private val projectManager by inject(ProjectManager::class.java) + private val projectName1 = "project1" + private val projectName2 = "project2" + private val spriteName1 = "sprite1" + private val spriteName2 = "sprite2" + + @get:Rule + var baseActivityTestRule = FragmentActivityTestRule( + ProjectActivity::class.java, ProjectActivity.EXTRA_FRAGMENT_POSITION, + ProjectActivity.FRAGMENT_SPRITES + ) + + @Before + fun setUp() { + setLanguageSharedPreference(getApplicationContext(), "en") + createProject1() + createProject2() + baseActivityTestRule.launchActivity() + } + + @After + fun tearDown() { + setLanguageSharedPreference(getApplicationContext(), "en") + TestUtils.deleteProjects(projectName1) + TestUtils.deleteProjects(projectName2) + baseActivityTestRule.finishActivity() + } + + @Test + fun testAddActorFromLocalProject() { + onView(withId(R.id.button_add)) + .perform(click()) + + onView(withId(R.id.dialog_new_look_from_local)) + .perform(click()) + + onView(withText(projectName2)) + .perform(click()) + + turnSwitchOff(R.id.place_visually_sprite_switch) + + onView(withText("OK")) + .perform(click()) + + onView(withText(spriteName1)) + .check(matches(isDisplayed())) + + onView(withText(spriteName2)) + .check(matches(isDisplayed())) + } + + @Test + fun testAddScriptFromLocalProject() { + UiTestUtils.openSpriteActionMenu(spriteName1, false) + + onView(withText(R.string.from_local)) + .perform(click()) + + onView(withText(projectName2)) + .perform(click()) + + onView(withText(spriteName1)) + .perform(click()) + + BrickDataInteractionWrapper.onBrickAtPosition(1) + .checkShowsText(R.string.brick_set_x) + + BrickDataInteractionWrapper.onBrickAtPosition(4) + .checkShowsText(R.string.brick_if_begin) + .checkShowsText(R.string.brick_if_begin_second_part) + } + + private fun createProject1() { + val project = Project(getApplicationContext(), projectName1) + val sprite = Sprite(spriteName1) + + val script: Script = StartScript() + script.addBrick(SetXBrick(Formula(BrickValues.X_POSITION))) + script.addBrick(SetXBrick(Formula(BrickValues.X_POSITION))) + sprite.addScript(script) + + project.defaultScene.addSprite(sprite) + projectManager.currentProject = project + + XstreamSerializer.getInstance().saveProject(project) + } + + private fun createProject2() { + val project = Project(getApplicationContext(), projectName2) + val sprite = Sprite(spriteName2) + + val startScript = StartScript() + val ifBrick = IfLogicBeginBrick() + ifBrick.addBrickToIfBranch(SetXBrick()) + ifBrick.addBrickToElseBranch(ChangeXByNBrick()) + startScript.addBrick(ifBrick) + startScript.setParents() + + sprite.addScript(startScript) + project.defaultScene.addSprite(sprite) + + XstreamSerializer.getInstance().saveProject(project) + } + + private fun turnSwitchOff(switchId: Int) { + onView(withId(switchId)).check { view, _ -> + if (view is SwitchCompat && view.isChecked) { + view.performClick() + } + } + } +} diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.kt b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.kt index 1d867f486f2..bfb5e9fae3a 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.kt +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.kt @@ -38,6 +38,7 @@ import android.view.MenuItem import android.view.View import androidx.annotation.PluralsRes import androidx.annotation.RequiresApi +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -75,7 +76,9 @@ import java.io.IOException import java.util.concurrent.locks.ReentrantLock @SuppressLint("NotifyDataSetChanged") -class ProjectListFragment : RecyclerViewFragment(), ProjectLoadListener { +class ProjectListFragment( + private val mainDispatcher: CoroutineDispatcher = Dispatchers.Main +) : RecyclerViewFragment(), ProjectLoadListener { private var items: MutableList = ArrayList() private var filesForUnzipAndImportTask: ArrayList? = null @@ -95,7 +98,9 @@ class ProjectListFragment : RecyclerViewFragment(), ProjectLoadLis importProject(requireArguments().getParcelable("intent")) } if (requireActivity().intent?.hasExtra(ProjectListActivity.IMPORT_LOCAL_INTENT) == true) { - adapter.showSettings = false + if (adapter != null) { + adapter.showSettings = false + } actionModeType = IMPORT_LOCAL } } @@ -559,7 +564,7 @@ class ProjectListFragment : RecyclerViewFragment(), ProjectLoadLis items = newItems lock.unlock() - withContext(Dispatchers.Main) { + withContext(mainDispatcher) { callback.onProjectsLoaded() } } diff --git a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/SpriteListFragment.kt b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/SpriteListFragment.kt index ccb492c7819..a6ded3895db 100644 --- a/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/SpriteListFragment.kt +++ b/catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/SpriteListFragment.kt @@ -375,7 +375,6 @@ class SpriteListFragment : RecyclerViewFragment() { } if (item !is GroupSprite) { popupMenu.menu.findItem(R.id.backpack).setTitle(R.string.pack) - popupMenu.menu.removeItem(R.id.from_local) } popupMenu.show() }