Skip to content

Commit e1c9208

Browse files
committed
IDE-289 Fix import actor from local project
1 parent 6dc83b6 commit e1c9208

File tree

3 files changed

+186
-4
lines changed

3 files changed

+186
-4
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Catroid: An on-device visual programming system for Android devices
3+
* Copyright (C) 2010-2025 The Catrobat Team
4+
* (<http://developer.catrobat.org/credits>)
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* An additional term exception under section 7 of the GNU Affero
12+
* General Public License, version 3, is available at
13+
* http://developer.catrobat.org/license_additional_term
14+
*
15+
* This program is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
* GNU Affero General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Affero General Public License
21+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
*/
23+
24+
package org.catrobat.catroid.uiespresso.ui.fragment
25+
26+
import androidx.appcompat.widget.SwitchCompat
27+
import androidx.test.core.app.ApplicationProvider.getApplicationContext
28+
import androidx.test.espresso.Espresso.onView
29+
import androidx.test.espresso.action.ViewActions.click
30+
import androidx.test.espresso.assertion.ViewAssertions.matches
31+
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
32+
import androidx.test.espresso.matcher.ViewMatchers.withId
33+
import androidx.test.espresso.matcher.ViewMatchers.withText
34+
import androidx.test.ext.junit.runners.AndroidJUnit4
35+
import org.catrobat.catroid.ProjectManager
36+
import org.catrobat.catroid.R
37+
import org.catrobat.catroid.common.BrickValues
38+
import org.catrobat.catroid.content.Project
39+
import org.catrobat.catroid.content.Script
40+
import org.catrobat.catroid.content.Sprite
41+
import org.catrobat.catroid.content.StartScript
42+
import org.catrobat.catroid.content.bricks.ChangeXByNBrick
43+
import org.catrobat.catroid.content.bricks.IfLogicBeginBrick
44+
import org.catrobat.catroid.content.bricks.SetXBrick
45+
import org.catrobat.catroid.formulaeditor.Formula
46+
import org.catrobat.catroid.io.XstreamSerializer
47+
import org.catrobat.catroid.test.utils.TestUtils
48+
import org.catrobat.catroid.testsuites.annotations.Cat.AppUi
49+
import org.catrobat.catroid.testsuites.annotations.Level.Smoke
50+
import org.catrobat.catroid.ui.ProjectActivity
51+
import org.catrobat.catroid.ui.settingsfragments.SettingsFragment.setLanguageSharedPreference
52+
import org.catrobat.catroid.uiespresso.content.brick.utils.BrickDataInteractionWrapper
53+
import org.catrobat.catroid.uiespresso.util.UiTestUtils
54+
import org.catrobat.catroid.uiespresso.util.rules.FragmentActivityTestRule
55+
import org.junit.After
56+
import org.junit.Before
57+
import org.junit.Rule
58+
import org.junit.Test
59+
import org.junit.experimental.categories.Category
60+
import org.junit.runner.RunWith
61+
import org.koin.java.KoinJavaComponent.inject
62+
63+
@Category(AppUi::class, Smoke::class)
64+
@RunWith(AndroidJUnit4::class)
65+
class AddFromLocalProjectsTest {
66+
private val projectManager by inject(ProjectManager::class.java)
67+
private val projectName1 = "project1"
68+
private val projectName2 = "project2"
69+
private val spriteName1 = "sprite1"
70+
private val spriteName2 = "sprite2"
71+
72+
@get:Rule
73+
var baseActivityTestRule = FragmentActivityTestRule(
74+
ProjectActivity::class.java, ProjectActivity.EXTRA_FRAGMENT_POSITION,
75+
ProjectActivity.FRAGMENT_SPRITES
76+
)
77+
78+
@Before
79+
fun setUp() {
80+
setLanguageSharedPreference(getApplicationContext(), "en")
81+
createProject1()
82+
createProject2()
83+
baseActivityTestRule.launchActivity()
84+
}
85+
86+
@After
87+
fun tearDown() {
88+
setLanguageSharedPreference(getApplicationContext(), "en")
89+
TestUtils.deleteProjects(projectName1)
90+
TestUtils.deleteProjects(projectName2)
91+
baseActivityTestRule.finishActivity()
92+
}
93+
94+
@Test
95+
fun testAddActorFromLocalProject() {
96+
onView(withId(R.id.button_add))
97+
.perform(click())
98+
99+
onView(withId(R.id.dialog_new_look_from_local))
100+
.perform(click())
101+
102+
onView(withText(projectName2))
103+
.perform(click())
104+
105+
turnSwitchOff(R.id.place_visually_sprite_switch)
106+
107+
onView(withText("OK"))
108+
.perform(click())
109+
110+
onView(withText(spriteName1))
111+
.check(matches(isDisplayed()))
112+
113+
onView(withText(spriteName2))
114+
.check(matches(isDisplayed()))
115+
}
116+
117+
@Test
118+
fun testAddScriptFromLocalProject() {
119+
UiTestUtils.openSpriteActionMenu(spriteName1, false)
120+
121+
onView(withText(R.string.from_local))
122+
.perform(click())
123+
124+
onView(withText(projectName2))
125+
.perform(click())
126+
127+
onView(withText(spriteName1))
128+
.perform(click())
129+
130+
BrickDataInteractionWrapper.onBrickAtPosition(1)
131+
.checkShowsText(R.string.brick_set_x)
132+
133+
BrickDataInteractionWrapper.onBrickAtPosition(4)
134+
.checkShowsText(R.string.brick_if_begin)
135+
.checkShowsText(R.string.brick_if_begin_second_part)
136+
}
137+
138+
private fun createProject1() {
139+
val project = Project(getApplicationContext(), projectName1)
140+
val sprite = Sprite(spriteName1)
141+
142+
val script: Script = StartScript()
143+
script.addBrick(SetXBrick(Formula(BrickValues.X_POSITION)))
144+
script.addBrick(SetXBrick(Formula(BrickValues.X_POSITION)))
145+
sprite.addScript(script)
146+
147+
project.defaultScene.addSprite(sprite)
148+
projectManager.currentProject = project
149+
150+
XstreamSerializer.getInstance().saveProject(project)
151+
}
152+
153+
private fun createProject2() {
154+
val project = Project(getApplicationContext(), projectName2)
155+
val sprite = Sprite(spriteName2)
156+
157+
val startScript = StartScript()
158+
val ifBrick = IfLogicBeginBrick()
159+
ifBrick.addBrickToIfBranch(SetXBrick())
160+
ifBrick.addBrickToElseBranch(ChangeXByNBrick())
161+
startScript.addBrick(ifBrick)
162+
startScript.setParents()
163+
164+
sprite.addScript(startScript)
165+
project.defaultScene.addSprite(sprite)
166+
167+
XstreamSerializer.getInstance().saveProject(project)
168+
}
169+
170+
private fun turnSwitchOff(switchId: Int) {
171+
onView(withId(switchId)).check { view, _ ->
172+
if (view is SwitchCompat && view.isChecked) {
173+
view.performClick()
174+
}
175+
}
176+
}
177+
}

catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/ProjectListFragment.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import android.view.MenuItem
3838
import android.view.View
3939
import androidx.annotation.PluralsRes
4040
import androidx.annotation.RequiresApi
41+
import kotlinx.coroutines.CoroutineDispatcher
4142
import kotlinx.coroutines.CoroutineScope
4243
import kotlinx.coroutines.Dispatchers
4344
import kotlinx.coroutines.launch
@@ -75,14 +76,17 @@ import java.io.IOException
7576
import java.util.concurrent.locks.ReentrantLock
7677

7778
@SuppressLint("NotifyDataSetChanged")
78-
class ProjectListFragment : RecyclerViewFragment<ProjectData?>(), ProjectLoadListener {
79+
class ProjectListFragment(
80+
private val mainDispatcher: CoroutineDispatcher = Dispatchers.Main
81+
) : RecyclerViewFragment<ProjectData?>(), ProjectLoadListener {
7982
private var items: MutableList<ProjectData> = ArrayList()
8083

8184
private var filesForUnzipAndImportTask: ArrayList<File>? = null
8285
private var hasUnzipAndImportTaskFinished = false
8386

8487
private val coroutineScope = CoroutineScope(Dispatchers.IO)
8588

89+
8690
private val projectManager: ProjectManager by inject()
8791

8892
private val lock = ReentrantLock()
@@ -95,7 +99,9 @@ class ProjectListFragment : RecyclerViewFragment<ProjectData?>(), ProjectLoadLis
9599
importProject(requireArguments().getParcelable("intent"))
96100
}
97101
if (requireActivity().intent?.hasExtra(ProjectListActivity.IMPORT_LOCAL_INTENT) == true) {
98-
adapter.showSettings = false
102+
if (adapter != null) {
103+
adapter.showSettings = false
104+
}
99105
actionModeType = IMPORT_LOCAL
100106
}
101107
}
@@ -559,7 +565,7 @@ class ProjectListFragment : RecyclerViewFragment<ProjectData?>(), ProjectLoadLis
559565
items = newItems
560566
lock.unlock()
561567

562-
withContext(Dispatchers.Main) {
568+
withContext(mainDispatcher) {
563569
callback.onProjectsLoaded()
564570
}
565571
}

catroid/src/main/java/org/catrobat/catroid/ui/recyclerview/fragment/SpriteListFragment.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ class SpriteListFragment : RecyclerViewFragment<Sprite?>() {
375375
}
376376
if (item !is GroupSprite) {
377377
popupMenu.menu.findItem(R.id.backpack).setTitle(R.string.pack)
378-
popupMenu.menu.removeItem(R.id.from_local)
379378
}
380379
popupMenu.show()
381380
}

0 commit comments

Comments
 (0)