From 0d7e7cfaeb573c83fbcf6abd8ad76793d9a996d8 Mon Sep 17 00:00:00 2001 From: Katsiaryna Tsytsenia Date: Wed, 9 Oct 2024 13:14:20 +0300 Subject: [PATCH] IJMP-1841 Fixid updating config file if connection was deleted. Signed-off-by: Katsiaryna Tsytsenia --- .../ui/zosmf/ZOSMFConnectionConfigurable.kt | 6 + .../zosmf/ZOSMFConnectionConfigurableTest.kt | 123 +++++++++++++++++- .../testutils/WithApplicationShouldSpec.kt | 7 +- 3 files changed, 133 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt index 007498e4..27d6d58b 100644 --- a/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt +++ b/src/main/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurable.kt @@ -151,6 +151,12 @@ class ZOSMFConnectionConfigurable : BoundSearchableConfigurable("z/OSMF Connecti /** Delete selected connections from Connections table */ private fun removeSelectedConnections() { val indices = connectionsTable?.selectedRows + val connToRemove = + indices?.map { connectionsTableModel?.get(it) }?.toSet() + connToRemove?.forEach { + if (it?.zoweConfigPath != null && zoweConfigStates.contains(it.connectionName)) + zoweConfigStates.remove(it.connectionName) + } indices?.forEachIndexed { i, idx -> connectionsTableModel?.removeRow(idx - i) } diff --git a/src/test/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurableTest.kt b/src/test/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurableTest.kt index b2c4d531..a0ccff45 100644 --- a/src/test/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurableTest.kt +++ b/src/test/kotlin/org/zowe/explorer/config/connect/ui/zosmf/ZOSMFConnectionConfigurableTest.kt @@ -18,24 +18,34 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.showOkCancelDialog +import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain import io.mockk.* +import org.zowe.explorer.common.ui.DialogMode +import org.zowe.explorer.common.ui.ValidatingTableView +import org.zowe.explorer.config.ConfigStateV2 +import org.zowe.explorer.config.connect.ConnectionConfig +import org.zowe.explorer.config.makeCrudableWithoutListeners import org.zowe.explorer.testutils.WithApplicationShouldSpec +import org.zowe.kotlinsdk.annotations.ZVersion import org.zowe.kotlinsdk.zowe.config.DefaultKeytarWrapper import org.zowe.kotlinsdk.zowe.config.KeytarWrapper import org.zowe.kotlinsdk.zowe.config.ZoweConfig +import java.lang.reflect.Modifier import java.nio.file.Path +import java.util.stream.Stream import javax.swing.Icon import kotlin.reflect.KFunction import kotlin.reflect.full.declaredMemberFunctions +import kotlin.reflect.full.declaredMemberProperties import kotlin.reflect.jvm.isAccessible class ZOSMFConnectionConfigurableTest : WithApplicationShouldSpec({ - val zOSMFConnectionConfigurableMock = spyk() + val zOSMFConnectionConfigurableMock = spyk(ZOSMFConnectionConfigurable(), recordPrivateCalls = true) var isShowOkCancelDialogCalled = false var isFindFileByNioPathCalled = false var isInputStreamCalled = false @@ -246,6 +256,115 @@ class ZOSMFConnectionConfigurableTest : WithApplicationShouldSpec({ } } + fun Any.mockPrivateFields(name: String, mocks: Any?): Any? { + javaClass.declaredFields + .filter { it.modifiers.and(Modifier.PRIVATE) > 0 || it.modifiers.and(Modifier.PROTECTED) > 0 } + .firstOrNull { it.name == name } + ?.also { it.isAccessible = true } + ?.set(this, mocks) + return this + } + + val connectionConfig = ConnectionConfig( + uuid = "0000", + name = "zowe-local-zosmf/testProj", + url = "https://url.com", + isAllowSelfSigned = true, + zVersion = ZVersion.ZOS_2_1, + zoweConfigPath = "zowe/config/path", + owner = "owner" + ) + state.connectionUrl = "https://testhost.com" + state.username = "testuser" + state.password = "testpass" + state.owner = "owner" + state.zoweConfigPath = "zowe/config/path" + state.mode = DialogMode.UPDATE + var crud = spyk(makeCrudableWithoutListeners(false) { ConfigStateV2() }) + every { crud.getAll(ConnectionConfig::class.java) } returns Stream.of(connectionConfig) + every { crud.find(ConnectionConfig::class.java, any()) } returns Stream.of(connectionConfig) + var connTModel = ConnectionsTableModel(crud) + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTableModel", connTModel) + var valTView = spyk(ValidatingTableView(connTModel, Disposer.newDisposable())) + every { valTView.selectedRow } returns 0 + every { valTView.selectedRows } returns intArrayOf(0) + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTable", valTView) + every { zOSMFConnectionConfigurableMock["showAndTestConnection"](any()) } returns state + + should("editConnection/removeSelectedConnections") { + zOSMFConnectionConfigurableMock::class.declaredMemberFunctions.find { it.name == "editConnection" } + ?.let { + it.isAccessible = true + it.call(zOSMFConnectionConfigurableMock) + } + zOSMFConnectionConfigurableMock::class.declaredMemberProperties.find { it.name == "zoweConfigStates" } + ?.let { + it.isAccessible = true + (it.getter.call(zOSMFConnectionConfigurableMock) as HashMap<*, *>).size shouldBe 1 + } + crud = spyk(makeCrudableWithoutListeners(false) { ConfigStateV2() }) + every { crud.getAll(ConnectionConfig::class.java) } returns Stream.of(connectionConfig) + every { crud.find(ConnectionConfig::class.java, any()) } returns Stream.of(connectionConfig) + connTModel = ConnectionsTableModel(crud) + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTableModel", connTModel) + zOSMFConnectionConfigurableMock::class.declaredMemberFunctions.find { it.name == "removeSelectedConnections" } + ?.let { + it.isAccessible = true + it.call(zOSMFConnectionConfigurableMock) + } + zOSMFConnectionConfigurableMock::class.declaredMemberProperties.find { it.name == "zoweConfigStates" } + ?.let { + it.isAccessible = true + (it.getter.call(zOSMFConnectionConfigurableMock) as HashMap<*, *>).size shouldBe 0 + } + } + + should("removeSelectedConnections null selectedRows") { + every { valTView.selectedRows } returns null + zOSMFConnectionConfigurableMock::class.declaredMemberFunctions.find { it.name == "removeSelectedConnections" } + ?.let { + it.isAccessible = true + it.call(zOSMFConnectionConfigurableMock) + } + zOSMFConnectionConfigurableMock::class.declaredMemberProperties.find { it.name == "zoweConfigStates" } + ?.let { + it.isAccessible = true + (it.getter.call(zOSMFConnectionConfigurableMock) as HashMap<*, *>).size shouldBe 0 + } + } + + should("removeSelectedConnections null connectionsTable") { + every { valTView.selectedRows } returns intArrayOf(0) + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTable", null) + zOSMFConnectionConfigurableMock::class.declaredMemberFunctions.find { it.name == "removeSelectedConnections" } + ?.let { + it.isAccessible = true + it.call(zOSMFConnectionConfigurableMock) + } + zOSMFConnectionConfigurableMock::class.declaredMemberProperties.find { it.name == "zoweConfigStates" } + ?.let { + it.isAccessible = true + (it.getter.call(zOSMFConnectionConfigurableMock) as HashMap<*, *>).size shouldBe 0 + } + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTable", valTView) + } + + should("removeSelectedConnections null connectionsTableModel") { + every { valTView.selectedRows } returns intArrayOf(0) + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTableModel", null) + zOSMFConnectionConfigurableMock::class.declaredMemberFunctions.find { it.name == "removeSelectedConnections" } + ?.let { + it.isAccessible = true + it.call(zOSMFConnectionConfigurableMock) + } + zOSMFConnectionConfigurableMock::class.declaredMemberProperties.find { it.name == "zoweConfigStates" } + ?.let { + it.isAccessible = true + (it.getter.call(zOSMFConnectionConfigurableMock) as HashMap<*, *>).size shouldBe 0 + } + zOSMFConnectionConfigurableMock.mockPrivateFields("connectionsTableModel", connTModel) + } + } } -) \ No newline at end of file +) diff --git a/src/test/kotlin/org/zowe/explorer/testutils/WithApplicationShouldSpec.kt b/src/test/kotlin/org/zowe/explorer/testutils/WithApplicationShouldSpec.kt index 9e23d288..5961be9f 100644 --- a/src/test/kotlin/org/zowe/explorer/testutils/WithApplicationShouldSpec.kt +++ b/src/test/kotlin/org/zowe/explorer/testutils/WithApplicationShouldSpec.kt @@ -28,7 +28,9 @@ import org.zowe.explorer.telemetry.NotificationsService import org.zowe.explorer.testutils.testServiceImpl.* import io.kotest.core.spec.Spec import io.kotest.core.spec.style.ShouldSpec -import io.mockk.clearMocks +import io.mockk.* +import org.zowe.explorer.zowe.ZoweStartupActivity +import org.zowe.kotlinsdk.zowe.config.DefaultKeytarWrapper private var appFixture: CodeInsightTestFixture? = null @@ -74,5 +76,8 @@ abstract class WithApplicationShouldSpec(body: ShouldSpec.() -> Unit = {}) : Sho init { body() + // TODO: rework + mockkConstructor(ZoweStartupActivity::class) + every { anyConstructed().runActivity(any()) } just Runs } }