diff --git a/src/main/kotlin/org/zowe/explorer/zowe/ZoweStartupActivity.kt b/src/main/kotlin/org/zowe/explorer/zowe/ZoweStartupActivity.kt index 0663ee44b..57349ddb7 100644 --- a/src/main/kotlin/org/zowe/explorer/zowe/ZoweStartupActivity.kt +++ b/src/main/kotlin/org/zowe/explorer/zowe/ZoweStartupActivity.kt @@ -76,8 +76,7 @@ fun showDialogForDeleteZoweConfigIfNeeded(project: Project) { "Delete Connection", "Keep Connection" ), 0, - AllIcons.General.QuestionDialog, - null + AllIcons.General.QuestionDialog ) if (choice == 0) { zoweConfigService.deleteZoweConfig() diff --git a/src/main/kotlin/org/zowe/explorer/zowe/service/ZoweConfigServiceImpl.kt b/src/main/kotlin/org/zowe/explorer/zowe/service/ZoweConfigServiceImpl.kt index b5e655820..055a909d3 100644 --- a/src/main/kotlin/org/zowe/explorer/zowe/service/ZoweConfigServiceImpl.kt +++ b/src/main/kotlin/org/zowe/explorer/zowe/service/ZoweConfigServiceImpl.kt @@ -70,20 +70,12 @@ const val ZOWE_PROJECT_PREFIX = "zowe-" class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService { companion object { - + /** + * This function is required for testing purposes + */ private fun getResourceUrl(strPath: String): URL? { - return ReflectionUtil.getGrandCallerClass()?.classLoader?.getResource(strPath) - } - - private fun getResourceContent(strPath: String, cs: Charset): String { - val url = getResourceUrl(strPath) - val array = url.toString().split("!") - val fs: FileSystem = FileSystems.newFileSystem(URI.create(array[0]), HashMap()) - val content = String(Files.readAllBytes(fs.getPath(array[1])), cs) - fs.close() - return content + return ZoweConfigServiceImpl::class.java.classLoader?.getResource(strPath) } - } private val configCrudable = ConfigService.instance.crudable @@ -288,6 +280,7 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService val jsonFileName = "${myProject.basePath}/${ZOWE_CONFIG_NAME}" val charset: Charset = StandardCharsets.UTF_8 + val pathSourceConfig = getResourceUrl("files/${ZOWE_CONFIG_NAME}") val pathSourceSchema = getResourceUrl("files/zowe.schema.json") val f: File = File(schemaFileName) @@ -307,7 +300,10 @@ class ZoweConfigServiceImpl(override val myProject: Project) : ZoweConfigService port = matcher.group(4).substring(1) } - var content = getResourceContent("files/$ZOWE_CONFIG_NAME", charset) + val array = pathSourceConfig.toString().split("!") + val fs: FileSystem = FileSystems.newFileSystem(URI.create(array[0]), HashMap()) + var content = String(Files.readAllBytes(fs.getPath(array[1])), charset) + fs.close() content = content.replace("".toRegex(), port) content = content.replace("".toRegex(), "\"$host\"") content = content.replace("".toRegex(), (!state.isAllowSsl).toString()) diff --git a/src/test/kotlin/org/zowe/explorer/config/ZoweConfigTestSpec.kt b/src/test/kotlin/org/zowe/explorer/config/ZoweConfigTestSpec.kt index 1286e2bea..91d4f0d11 100644 --- a/src/test/kotlin/org/zowe/explorer/config/ZoweConfigTestSpec.kt +++ b/src/test/kotlin/org/zowe/explorer/config/ZoweConfigTestSpec.kt @@ -2,6 +2,7 @@ package org.zowe.explorer.config import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages import com.intellij.openapi.vfs.VirtualFileManager import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.shouldBe @@ -18,16 +19,16 @@ import org.zowe.explorer.zowe.service.ZoweConfigState import org.zowe.kotlinsdk.zowe.config.KeytarWrapper import org.zowe.kotlinsdk.zowe.config.ZoweConfig import java.io.File +import java.net.URI import java.net.URL -import java.nio.charset.Charset -import java.nio.file.Files -import java.nio.file.Paths +import java.nio.file.* +import javax.swing.Icon import kotlin.reflect.KFunction class ZoweConfigTestSpec : WithApplicationShouldSpec({ - - val baseProjPath = System.getProperty("java.io.tmpdir") - val tmpZoweConfFile = baseProjPath + File.separator + ZOWE_CONFIG_NAME + val baseProjPath = Path.of(System.getProperty("java.io.tmpdir")).toRealPath().toString().replace("\\", "/") + val tmpZoweConfFile = "$baseProjPath/$ZOWE_CONFIG_NAME" + val winTmpZoweConfFile = tmpZoweConfFile.split("/").toTypedArray().joinToString(File.separator) val connectionDialogState = ConnectionDialogState( connectionName = "a", connectionUrl = "https://111.111.111.111:555", @@ -38,11 +39,12 @@ class ZoweConfigTestSpec : WithApplicationShouldSpec({ afterSpec { clearAllMocks() + unmockkAll() } context("config module: zowe config file") { - val mockedProject = mockk() + val mockedProject = mockk(relaxed = true) every { mockedProject.basePath } returns baseProjPath every { mockedProject.name } returns "testProj" @@ -54,42 +56,67 @@ class ZoweConfigTestSpec : WithApplicationShouldSpec({ copyURLToFileMock(any() as URL, any() as File) } just Runs + val fs = mockk(relaxed = true) + val newFileSystemMock: ( + URI?, Map + ) -> FileSystem? = FileSystems::newFileSystem + mockkStatic(newFileSystemMock as KFunction<*>) + every { + newFileSystemMock(any() as URI, any() as Map) + } returns fs + every { + fs.getPath(any() as String) + } answers { + (Paths.get(firstArg())) + } + every { + fs.close() + } just Runs + + val pathsGet: ( + String, Array + ) -> Path = Paths::get + mockkStatic(pathsGet as KFunction<*>) + every { + pathsGet(match { it.startsWith("/") && System.getProperty("os.name").contains("Windows") }, arrayOf()) + } answers { + if (System.getProperty("os.name") + .contains("Windows") && firstArg().startsWith("/") + ) Path.of(URI("file:" + firstArg())) + else Path.of(URI(firstArg())) + } + mockkObject(ZoweConfigServiceImpl(mockedProject)) { every { ZoweConfigService.getInstance(mockedProject) } returns ZoweConfigServiceImpl(mockedProject) } mockkObject(ZoweConfigServiceImpl) - every { ZoweConfigServiceImpl.Companion["getResourceContent"](any() as String, any() as Charset) } answers { - String( - Files.readAllBytes( - Paths.get( - this::class.java.classLoader?.getResource(firstArg())?.path.toString() - ) - ), secondArg() - ) + every { ZoweConfigServiceImpl.Companion["getResourceUrl"](any() as String) } answers { + val p = ZoweConfigTestSpec::class.java.classLoader?.getResource(firstArg())?.path + if (firstArg().contains(ZOWE_CONFIG_NAME)) { + URL("jar:file:/path/to/jar!" + p.toString()) + } else { + URL("file:" + p) + } + } var checkFilePath = false var checkUser = false var checkPass = false fun checkSaveNewSecProp( - filePath: String, - configCredentialsMap: MutableMap + filePath: String, configCredentialsMap: MutableMap ) { - if (filePath == tmpZoweConfFile) - checkFilePath = true + if (filePath == tmpZoweConfFile) checkFilePath = true configCredentialsMap.forEach { - if (it.key == "profiles.base.properties.user" && it.value == "testUser") - checkUser = true - if (it.key == "profiles.base.properties.password" && it.value == "testPass") - checkPass = true + if (it.key == "profiles.base.properties.user" && it.value == "testUser") checkUser = true + if (it.key == "profiles.base.properties.password" && it.value == "testPass") checkPass = true } } mockkObject(ZoweConfig) every { ZoweConfig.saveNewSecureProperties( - any() as String, - any() as MutableMap, any() + any() as String, any() as MutableMap, any() ) } answers { checkSaveNewSecProp(firstArg(), secondArg>()) @@ -99,14 +126,28 @@ class ZoweConfigTestSpec : WithApplicationShouldSpec({ val configCredentialsMap = mutableMapOf() configCredentialsMap["profiles.base.properties.user"] = "testUser" configCredentialsMap["profiles.base.properties.password"] = "testPass" - confMap[tmpZoweConfFile] = configCredentialsMap + confMap[winTmpZoweConfFile] = configCredentialsMap every { ZoweConfig.Companion["readZoweCredentialsFromStorage"](any() as KeytarWrapper) } returns confMap val zoweConnConf = connectionDialogState.connectionConfig - zoweConnConf.zoweConfigPath = tmpZoweConfFile + zoweConnConf.zoweConfigPath = tmpZoweConfFile.replace("\\", "/") zoweConnConf.name = "zowe-testProj" + val zoweConfigService = ZoweConfigService.getInstance(mockedProject) + val crudableInst = ConfigService.instance.crudable + + var isDeleteMessageInDialogCalled = false + val showDialogSpecificMock: ( + Project?, String, String, Array, Int, Icon? + ) -> Int = Messages::showDialog + mockkStatic(showDialogSpecificMock as KFunction<*>) + every { + showDialogSpecificMock(any(), any(), any(), any>(), any(), any()) + } answers { + isDeleteMessageInDialogCalled = true + 1 + } should("add zowe team config file") { @@ -117,18 +158,15 @@ class ZoweConfigTestSpec : WithApplicationShouldSpec({ var isSslAdded = false ApplicationManager.getApplication().invokeAndWait { - ZoweConfigService.getInstance(mockedProject).addZoweConfigFile(connectionDialogState) + zoweConfigService.addZoweConfigFile(connectionDialogState) VirtualFileManager.getInstance().syncRefresh() } val read = Files.readAllLines(Paths.get(tmpZoweConfFile)) for (listItem in read) { - if (listItem.contains("\"port\": 555")) - isPortAdded = true - if (listItem.contains("\"host\": \"111.111.111.111\"")) - isHostAdded = true - if (listItem.contains("\"rejectUnauthorized\": false")) - isSslAdded = true + if (listItem.contains("\"port\": 555")) isPortAdded = true + if (listItem.contains("\"host\": \"111.111.111.111\"")) isHostAdded = true + if (listItem.contains("\"rejectUnauthorized\": false")) isSslAdded = true } isPortAdded shouldBe true @@ -142,57 +180,72 @@ class ZoweConfigTestSpec : WithApplicationShouldSpec({ should("get zowe team config state") { - val run1 = ZoweConfigService.getInstance(mockedProject).getZoweConfigState(false) + val run1 = zoweConfigService.getZoweConfigState(false) run1 shouldBeEqual ZoweConfigState.NOT_EXISTS - val run2 = ZoweConfigService.getInstance(mockedProject).getZoweConfigState() + val run2 = zoweConfigService.getZoweConfigState() run2 shouldBeEqual ZoweConfigState.NEED_TO_ADD - ConfigService.instance.crudable.addOrUpdate(zoweConnConf) + crudableInst.addOrUpdate(zoweConnConf) - val run3 = ZoweConfigService.getInstance(mockedProject).getZoweConfigState() + val run3 = zoweConfigService.getZoweConfigState() run3 shouldBeEqual ZoweConfigState.NEED_TO_UPDATE - confMap[tmpZoweConfFile]?.set("profiles.base.properties.password", "testPassword") + confMap[winTmpZoweConfFile]?.set("profiles.base.properties.password", "testPassword") - val run4 = ZoweConfigService.getInstance(mockedProject).getZoweConfigState() + val run4 = zoweConfigService.getZoweConfigState() run4 shouldBeEqual ZoweConfigState.SYNCHRONIZED } + val zoweConfig = zoweConfigService.zoweConfig + val host = zoweConfig?.host + val port = zoweConfig?.port should("add or update zowe team config connection") { zoweConnConf.url = "222.222.222.222:666" - ConfigService.instance.crudable.addOrUpdate(zoweConnConf) - ConfigService.instance.crudable.getAll().toList() + crudableInst.addOrUpdate(zoweConnConf) + crudableInst.getAll().toList() .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual zoweConnConf.url - ZoweConfigService.getInstance(mockedProject).addOrUpdateZoweConfig(scanProject = true, checkConnection = false) - - ConfigService.instance.crudable.getAll().toList() - .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual "https://${ - ZoweConfigService.getInstance( - mockedProject - ).zoweConfig?.host - }:${ZoweConfigService.getInstance(mockedProject).zoweConfig?.port}" + zoweConfigService.addOrUpdateZoweConfig(scanProject = true, checkConnection = false) + crudableInst.getAll().toList() + .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual "https://$host:$port" } should("delete zowe team config connection") { - Files.deleteIfExists(Paths.get(tmpZoweConfFile)) + crudableInst.getAll().toList() + .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual "https://$host:$port" + + zoweConfigService.deleteZoweConfig() + + crudableInst.getAll().toList().filter { it.name == zoweConnConf.name }.size shouldBeEqual 0 + + } + + should("delete zowe team config file") { - ConfigService.instance.crudable.getAll().toList() - .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual "https://${ - ZoweConfigService.getInstance( - mockedProject - ).zoweConfig?.host - }:${ZoweConfigService.getInstance(mockedProject).zoweConfig?.port}" + zoweConnConf.name = "zowe-zowe-explorer" + crudableInst.addOrUpdate(zoweConnConf) + + crudableInst.getAll().toList() + .filter { it.name == zoweConnConf.name }[0].url shouldBeEqual zoweConnConf.url - ZoweConfigService.getInstance(mockedProject).deleteZoweConfig() + ApplicationManager.getApplication().invokeAndWait { + Files.deleteIfExists(Paths.get(tmpZoweConfFile)) + VirtualFileManager.getInstance().syncRefresh() + } + var t = 0 + while (!isDeleteMessageInDialogCalled && t < 5000) { + Thread.sleep(100) + t += 100 + } - ConfigService.instance.crudable.getAll().toList() - .filter { it.name == zoweConnConf.name }.size shouldBeEqual 0 + File(tmpZoweConfFile).exists() shouldBe false + isDeleteMessageInDialogCalled shouldBe true + crudableInst.getAll().toList()[0].name shouldBeEqual "zowe-zowe-explorer1" }