From 60c14575a15aab4d983824f32b14957d7aba6fe7 Mon Sep 17 00:00:00 2001 From: Dzianis Lisiankou Date: Fri, 15 Mar 2024 11:10:09 +0100 Subject: [PATCH] IJMP-1537: move tasks from 2.0.0 to 1.2.0 --- .../common/SettingsPropertyManager.kt | 31 ++ .../dataops/operations/TsoOperationRunner.kt | 57 ++- .../explorer/actions/AllocateActionBase.kt | 69 ++-- .../explorer/ui/AllocationDialog.kt | 5 + .../ui/build/TerminalCommandReceiver.kt | 37 +- .../ui/build/tso/TSOWindowFactory.kt | 2 +- .../ui/build/tso/ui/TSOConsoleView.kt | 55 ++- .../resources/messages/FMBundle.properties | 4 +- src/main/resources/settings.properties | 1 + .../formainframe/common/CommonTestSpec.kt | 52 ++- .../formainframe/editor/EditorTestSpec.kt | 19 +- .../actions/AllocateDatasetActionTestSpec.kt | 336 ++++-------------- .../actions/AllocateLikeActionTestSpec.kt | 204 +++-------- .../ui/ChangeEncodingDialogTestSpec.kt | 7 +- .../utils/EncodingUtilsTestSpec.kt | 7 +- 15 files changed, 398 insertions(+), 488 deletions(-) create mode 100644 src/main/kotlin/eu/ibagroup/formainframe/common/SettingsPropertyManager.kt create mode 100644 src/main/resources/settings.properties diff --git a/src/main/kotlin/eu/ibagroup/formainframe/common/SettingsPropertyManager.kt b/src/main/kotlin/eu/ibagroup/formainframe/common/SettingsPropertyManager.kt new file mode 100644 index 000000000..9aced3e81 --- /dev/null +++ b/src/main/kotlin/eu/ibagroup/formainframe/common/SettingsPropertyManager.kt @@ -0,0 +1,31 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright IBA Group 2020 + */ + +package eu.ibagroup.formainframe.common + +import java.util.* + +class SettingsPropertyManager + +/** + * Properties from the settings.properties file + */ +internal val settingsProperties by lazy { + Properties().apply { + load(SettingsPropertyManager::class.java.classLoader.getResourceAsStream("settings.properties")) + } +} + +/** + * Check if the debug mode is enabled + */ +fun isDebugModeEnabled(): Boolean { + return settingsProperties.getProperty("debug.mode")?.toBoolean() ?: false +} \ No newline at end of file diff --git a/src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/TsoOperationRunner.kt b/src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/TsoOperationRunner.kt index 8c5c64edd..b6a7d8803 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/TsoOperationRunner.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/TsoOperationRunner.kt @@ -19,14 +19,13 @@ import eu.ibagroup.formainframe.ui.build.tso.config.TSOConfigWrapper import eu.ibagroup.formainframe.ui.build.tso.ui.TSOSessionParams import eu.ibagroup.formainframe.utils.cancelByIndicator import eu.ibagroup.formainframe.utils.log +import eu.ibagroup.formainframe.dataops.operations.MessageType as MessageTypeEnum import org.zowe.kotlinsdk.MessageType import org.zowe.kotlinsdk.TsoApi import org.zowe.kotlinsdk.TsoData import org.zowe.kotlinsdk.TsoResponse import io.ktor.util.* import retrofit2.Response -import java.nio.charset.Charset -import java.util.* /** * Factory class which represents a TSO operation runner. Defined in plugin.xml @@ -85,12 +84,7 @@ class TsoOperationRunner : OperationRunner { response = api(state.getConnectionConfig()) .sendMessageToTso( state.getConnectionConfig().authToken, - body = TsoData( - tsoResponse = MessageType( - version = "0100", - data = operation.message - ) - ), + body = createTsoData(operation), servletKey = servletKey ) .cancelByIndicator(progressIndicator) @@ -140,4 +134,51 @@ class TsoOperationRunner : OperationRunner { return response?.body() ?: throw Exception("Cannot retrieve response from server.") } + /** + * Create TsoData object depending on the specified message type + * @throws Exception if message type not specified + */ + private fun createTsoData(operation: TsoOperation): TsoData { + return when (operation.messageType) { + MessageTypeEnum.TSO_MESSAGE -> TsoData( + tsoMessage = createMessageType(operation) + ) + + MessageTypeEnum.TSO_PROMPT -> TsoData( + tsoPrompt = createMessageType(operation) + ) + + MessageTypeEnum.TSO_RESPONSE -> TsoData( + tsoResponse = createMessageType(operation) + ) + + null -> throw Exception("Message type not specified") + } + } + + /** + * Create MessageType object depending on the specified message data + * @throws Exception if message data not specified + */ + private fun createMessageType(operation: TsoOperation): MessageType { + return when (operation.messageData) { + MessageData.DATA_DATA -> MessageType( + version = "0100", + data = operation.message + ) + + MessageData.DATA_HIDDEN -> MessageType( + version = "0100", + hidden = operation.message + ) + + MessageData.DATA_ACTION -> MessageType( + version = "0100", + action = operation.message + ) + + null -> throw Exception("Message data not specified") + } + } + } diff --git a/src/main/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateActionBase.kt b/src/main/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateActionBase.kt index 79fd503c7..5697ecf3c 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateActionBase.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateActionBase.kt @@ -10,12 +10,14 @@ package eu.ibagroup.formainframe.explorer.actions +import com.intellij.notification.Notification +import com.intellij.notification.NotificationAction +import com.intellij.notification.NotificationType +import com.intellij.notification.Notifications import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.application.runInEdt import com.intellij.openapi.components.service import com.intellij.openapi.progress.runModalTask -import com.intellij.openapi.ui.showOkNoDialog import eu.ibagroup.formainframe.analytics.AnalyticsService import eu.ibagroup.formainframe.analytics.events.FileAction import eu.ibagroup.formainframe.analytics.events.FileEvent @@ -28,6 +30,7 @@ import eu.ibagroup.formainframe.config.ws.FilesWorkingSetConfig import eu.ibagroup.formainframe.dataops.DataOpsManager import eu.ibagroup.formainframe.dataops.operations.DatasetAllocationOperation import eu.ibagroup.formainframe.dataops.operations.DatasetAllocationParams +import eu.ibagroup.formainframe.explorer.ExplorerUnit import eu.ibagroup.formainframe.explorer.FilesWorkingSet import eu.ibagroup.formainframe.explorer.ui.AllocationDialog import eu.ibagroup.formainframe.explorer.ui.DSMaskNode @@ -44,6 +47,8 @@ import org.zowe.kotlinsdk.Dataset import org.zowe.kotlinsdk.DatasetOrganization import org.zowe.kotlinsdk.DsnameType +const val ALLOCATE_ACTION_NOTIFICATION_GROUP_ID = "eu.ibagroup.formainframe.explorer.AllocateActionNotificationGroup" + abstract class AllocateActionBase : AnAction() { /** @@ -140,34 +145,10 @@ abstract class AllocateActionBase : AnAction() { } val nodeToClean = parentProbablyDSMaskNode?.castOrNull>() nodeToClean?.let { cleanInvalidateOnExpand(nodeToClean, view) } - - var nodeCleaned = false - runInEdt { - if ( - showOkNoDialog( - title = "Dataset ${state.datasetName} Has Been Created", - message = "Would you like to add mask \"${state.datasetName}\" to ${workingSet.name}", - project = e.project, - okText = "Yes", - noText = "No" - ) - ) { - val filesWorkingSetConfig = - configCrudable.getByUniqueKey(workingSet.uuid)?.clone() - if (filesWorkingSetConfig != null) { - nodeToClean?.cleanCache(recursively = false, cleanBatchedQuery = true, sendTopic = false) - nodeCleaned = true - - filesWorkingSetConfig.dsMasks.add(DSMask().apply { mask = state.datasetName }) - configCrudable.update(filesWorkingSetConfig) - } - } - - if (!nodeCleaned) { - nodeToClean?.cleanCache(recursively = false, cleanBatchedQuery = true) - } - } + nodeToClean?.cleanCache(recursively = false, cleanBatchedQuery = true) initialState.errorMessage = "" + + showNotification(state, workingSet) } .onFailure { t -> explorer.reportThrowable(t, e.project) @@ -187,4 +168,34 @@ abstract class AllocateActionBase : AnAction() { override fun isDumbAware(): Boolean { return true } + + /** + * Shows a notification about successful allocation and suggest adding a mask to the working set + */ + private fun showNotification( + state: DatasetAllocationParams, + workingSet: ExplorerUnit<*> + ) { + val notification = Notification( + ALLOCATE_ACTION_NOTIFICATION_GROUP_ID, + "Dataset ${state.datasetName} has been created", + "Would you like to add mask \"${state.datasetName}\" to ${workingSet.name}?", + NotificationType.INFORMATION + ) + notification.addActions( + setOf( + NotificationAction.createSimpleExpiring("Add mask") { + val filesWorkingSetConfig = + configCrudable.getByUniqueKey(workingSet.uuid)?.clone() + if (filesWorkingSetConfig != null) { + filesWorkingSetConfig.dsMasks.add(DSMask().apply { mask = state.datasetName }) + configCrudable.update(filesWorkingSetConfig) + } + }, + NotificationAction.createSimpleExpiring("Skip") { } + ) + ) + notification.setSuggestionType(true) + Notifications.Bus.notify(notification) + } } diff --git a/src/main/kotlin/eu/ibagroup/formainframe/explorer/ui/AllocationDialog.kt b/src/main/kotlin/eu/ibagroup/formainframe/explorer/ui/AllocationDialog.kt index 48d428048..052d3e028 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/explorer/ui/AllocationDialog.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/explorer/ui/AllocationDialog.kt @@ -22,6 +22,7 @@ import com.intellij.ui.dsl.builder.panel import com.intellij.ui.dsl.builder.toNullableProperty import com.intellij.ui.dsl.gridLayout.HorizontalAlign import com.intellij.ui.layout.selectedValueMatches +import eu.ibagroup.formainframe.common.message import eu.ibagroup.formainframe.common.ui.StatefulDialog import eu.ibagroup.formainframe.config.connect.ConnectionConfig import eu.ibagroup.formainframe.config.connect.getUsername @@ -133,6 +134,10 @@ class AllocationDialog(project: Project?, config: ConnectionConfig, override var .bindItem(state.allocationParameters::allocationUnit.toNullableProperty()) .also { spaceUnitBox = it.component } .widthGroup(sameWidthComboBoxGroup) + contextHelp( + description = message("allocation.dialog.unit.size.hint.description"), + title = message("allocation.dialog.unit.size.hint.title") + ) } row { label("Primary allocation: ") diff --git a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/TerminalCommandReceiver.kt b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/TerminalCommandReceiver.kt index 3d44aea58..de07b5b9d 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/TerminalCommandReceiver.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/TerminalCommandReceiver.kt @@ -13,6 +13,7 @@ package eu.ibagroup.formainframe.ui.build import com.intellij.execution.process.NopProcessHandler import com.intellij.execution.process.ProcessHandler import com.intellij.execution.process.ProcessOutputType +import com.intellij.openapi.util.Key import com.intellij.terminal.TerminalExecutionConsole import com.jediterm.terminal.TerminalKeyEncoder import eu.ibagroup.formainframe.ui.build.tso.utils.InputRecognizer @@ -33,6 +34,7 @@ class TerminalCommandReceiver(terminalConsole: TerminalExecutionConsole) { private var needToWaitForCommandInput = false private var commandsInQueue: Queue = LinkedList() private var expectParameters = false + private var prevCommandEndsWithReady = false var initialized = false private var onCommandEntered: (String) -> Unit = {} @@ -146,15 +148,34 @@ class TerminalCommandReceiver(terminalConsole: TerminalExecutionConsole) { override fun getProcessInput(): OutputStream { return this@TerminalCommandReceiver.processInput } + + /** + * Override notifyTextAvailable() method to check what the command ends with + */ + override fun notifyTextAvailable(text: String, outputType: Key<*>) { + if (text != "\n" && text.endsWith("\n")) { + prevCommandEndsWithReady = isTextEndsWithReady(text) + } + super.notifyTextAvailable(text, outputType) + } } terminalConsole.withConvertLfToCrlfForNonPtyProcess(true) terminalConsole.attachToProcess(processHandler) } + /** + * Check if the text ends with "READY" - successful completion of TSO command + */ + private fun isTextEndsWithReady(text: String): Boolean { + val successfulEnding = "READY" + val trimmedText = text.trimEnd() + return trimmedText.endsWith(successfulEnding, true) + } + /** * Called when command is submitted. Clean up the entered command for follow up user input */ - private fun cleanCommand() { + fun cleanCommand() { this.typedCommand = "" this.textAfterCursor = "" this.cursorPosition = 0 @@ -193,6 +214,20 @@ class TerminalCommandReceiver(terminalConsole: TerminalExecutionConsole) { } } + /** + * Return true if console is waiting for command input or else otherwise + */ + fun isNeedToWaitForCommandInput(): Boolean { + return needToWaitForCommandInput + } + + /** + * Return true if previous command ends with "READY" or else otherwise + */ + fun isPrevCommandEndsWithReady(): Boolean { + return prevCommandEndsWithReady + } + /** * Called when user finished typing the command and pressed Enter */ diff --git a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/TSOWindowFactory.kt b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/TSOWindowFactory.kt index d7d07aea6..18aa36a9b 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/TSOWindowFactory.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/TSOWindowFactory.kt @@ -350,7 +350,7 @@ class TSOWindowFactory : ToolWindowFactory { try { sendTopic(SESSION_RECONNECT_TOPIC, project).reconnect(project, console, session) processHandler.notifyTextAvailable( - "Successfully reconnected to the TSO session.\n", + "Successfully reconnected to the TSO session.\nREADY\n", ProcessOutputType.STDOUT ) } catch (e: Exception) { diff --git a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/ui/TSOConsoleView.kt b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/ui/TSOConsoleView.kt index 8a6818105..3bbdd5b79 100644 --- a/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/ui/TSOConsoleView.kt +++ b/src/main/kotlin/eu/ibagroup/formainframe/ui/build/tso/ui/TSOConsoleView.kt @@ -11,15 +11,21 @@ package eu.ibagroup.formainframe.ui.build.tso.ui //import com.intellij.ui.layout.cellPanel +import com.intellij.execution.process.ProcessEvent import com.intellij.execution.process.ProcessHandler +import com.intellij.execution.process.ProcessListener import com.intellij.execution.ui.ExecutionConsole import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.ComboBox import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.Key import com.intellij.terminal.TerminalExecutionConsole import com.intellij.ui.CollectionComboBoxModel import com.intellij.ui.SimpleListCellRenderer import com.intellij.ui.components.JBPanel import com.intellij.ui.dsl.builder.panel +import com.intellij.util.ui.JBEmptyBorder +import eu.ibagroup.formainframe.common.isDebugModeEnabled import eu.ibagroup.formainframe.dataops.operations.MessageData import eu.ibagroup.formainframe.dataops.operations.MessageType import eu.ibagroup.formainframe.ui.build.TerminalCommandReceiver @@ -29,7 +35,7 @@ import eu.ibagroup.formainframe.ui.build.tso.utils.InputRecognizer import eu.ibagroup.formainframe.utils.log import eu.ibagroup.formainframe.utils.sendTopic import java.awt.BorderLayout -import javax.swing.JComboBox +import javax.swing.JButton import javax.swing.JComponent /** @@ -42,12 +48,13 @@ class TSOConsoleView( private var tsoSession: TSOConfigWrapper ) : ExecutionConsole, JBPanel() { - private lateinit var tsoMessageType: JComboBox - private lateinit var tsoDataType: JComboBox + private lateinit var tsoMessageTypeBox: ComboBox + private lateinit var tsoDataTypeBox: ComboBox + private lateinit var cancelCommandButton: JButton private val tsoWidthGroup: String = "TSO_WIDTH_GROUP" private val tsoMessageTypes: List = - listOf(MessageType.TSO_MESSAGE, MessageType.TSO_PROMPT, MessageType.TSO_RESPONSE) + listOf(MessageType.TSO_RESPONSE, MessageType.TSO_MESSAGE, MessageType.TSO_PROMPT) private val tsoDataTypes: List = listOf(MessageData.DATA_DATA, MessageData.DATA_HIDDEN, MessageData.DATA_ACTION) @@ -61,6 +68,8 @@ class TSOConsoleView( private val log = log() + private val debugMode = isDebugModeEnabled() + /** * UI panel which contains 2 combo boxes of TSO message type and message data type */ @@ -73,18 +82,35 @@ class TSOConsoleView( model = tsoMessageTypeComboBoxModel, renderer = SimpleListCellRenderer.create("") { it.type } ).also { - tsoMessageType = it.component + tsoMessageTypeBox = it.component } - } + }.visible(debugMode) row { label("TSO data type").widthGroup(tsoWidthGroup) comboBox( model = tsoDataTypeComboBoxModel, renderer = SimpleListCellRenderer.create("") { it.data } ).also { - tsoDataType = it.component + tsoDataTypeBox = it.component + } + }.visible(debugMode) + row { + button("Cancel Command (PA1)") { + log.info("CANCEL COMMAND (PA1)") + val prevTsoMessageType = tsoMessageTypeBox.item + val prevTsoDataType = tsoDataTypeBox.item + tsoMessageTypeBox.item = MessageType.TSO_RESPONSE + tsoDataTypeBox.item = MessageData.DATA_ACTION + terminalCommandReceiver.cleanCommand() + processHandler.processInput?.write(("\r").toByteArray()) + tsoMessageTypeBox.item = prevTsoMessageType + tsoDataTypeBox.item = prevTsoDataType + }.also { + cancelCommandButton = it.component } } + }.also { + it.border = JBEmptyBorder(10, 15, 10, 15) } } @@ -102,8 +128,8 @@ class TSOConsoleView( this, tsoSession, enteredCommand.trim(), - tsoMessageType.selectedItem as MessageType, - tsoDataType.selectedItem as MessageData, + tsoMessageTypeBox.item, + tsoDataTypeBox.item, processHandler ) terminalCommandReceiver.waitForCommandInput() @@ -111,6 +137,17 @@ class TSOConsoleView( terminalCommandReceiver.initialized = true + processHandler.addProcessListener(object : ProcessListener { + override fun startNotified(event: ProcessEvent) {} + + override fun processTerminated(event: ProcessEvent) {} + + override fun onTextAvailable(event: ProcessEvent, outputType: Key<*>) { + cancelCommandButton.isEnabled = + !terminalCommandReceiver.isPrevCommandEndsWithReady() && terminalCommandReceiver.isNeedToWaitForCommandInput() + } + }) + Disposer.register(this, consoleView) layout = BorderLayout() add(this.component, BorderLayout.WEST) diff --git a/src/main/resources/messages/FMBundle.properties b/src/main/resources/messages/FMBundle.properties index 521c2c349..85709ae3e 100755 --- a/src/main/resources/messages/FMBundle.properties +++ b/src/main/resources/messages/FMBundle.properties @@ -25,4 +25,6 @@ encoding.reload.or.convert.dialog.title={0}: Reload or Convert to {1} encoding.reload.or.convert.dialog.message=The encoding you'''ve chosen ('{1}') may change the contents of '{0}'.
Do you want to
1. Reload the file from remote in the new encoding '{1}' and overwrite contents (may not display correctly) or
2. Convert the text and overwrite file in the new encoding?
encoding.reload.dialog.title={0}: Reload to {1} encoding.reload.dialog.message=The encoding you'''ve chosen ('{1}') may change the contents of '{0}'.
Do you want to Reload the file from remote in the new encoding '{1}' and overwrite contents (may not display correctly).
-encoding.convert.button.error.tooltip=Encoding conversion is not available because more than one project is open \ No newline at end of file +encoding.convert.button.error.tooltip=Encoding conversion is not available because more than one project is open +allocation.dialog.unit.size.hint.description=For IBM 3390 direct access storage device:
1 CYLINDER = 15 TRACKS
1 TRACK = 56664 BYTES +allocation.dialog.unit.size.hint.title=Allocation unit Size \ No newline at end of file diff --git a/src/main/resources/settings.properties b/src/main/resources/settings.properties new file mode 100644 index 000000000..ccee7c8ba --- /dev/null +++ b/src/main/resources/settings.properties @@ -0,0 +1 @@ +debug.mode=false \ No newline at end of file diff --git a/src/test/kotlin/eu/ibagroup/formainframe/common/CommonTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/common/CommonTestSpec.kt index 07b14dc46..5985c97ec 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/common/CommonTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/common/CommonTestSpec.kt @@ -10,9 +10,16 @@ package eu.ibagroup.formainframe.common -import io.kotest.core.spec.style.ShouldSpec +import eu.ibagroup.formainframe.testutils.WithApplicationShouldSpec +import io.kotest.assertions.assertSoftly +import io.kotest.matchers.shouldBe +import io.mockk.* +import java.util.Properties -class CommonTestSpec : ShouldSpec({ +class CommonTestSpec : WithApplicationShouldSpec({ + afterSpec { + clearAllMocks() + } context("common module: ui") { // ValidatingCellRenderer.getTableCellRendererComponent should("get table cell renderer") {} @@ -26,4 +33,45 @@ class CommonTestSpec : ShouldSpec({ // StatefulDialog.showUntilDone should("show dialog until it is fulfilled") {} } + context("common module: SettingsPropertyManager") { + val propertyName = "debug.mode" + + mockkConstructor(Properties::class) + + // isDebugModeEnabled + should("debug mode enabled") { + every { anyConstructed().getProperty(propertyName) } returns "true" + val debugMode = isDebugModeEnabled() + + assertSoftly { + debugMode shouldBe true + } + } + should("debug mode disabled") { + every { anyConstructed().getProperty(propertyName) } returns "false" + val debugMode = isDebugModeEnabled() + + assertSoftly { + debugMode shouldBe false + } + } + should("debug mode property not found") { + every { anyConstructed().getProperty(propertyName) } returns null + val debugMode = isDebugModeEnabled() + + assertSoftly { + debugMode shouldBe false + } + } + should("debug mode property contains a non-boolean value") { + every { anyConstructed().getProperty(propertyName) } returns "123" + val debugMode = isDebugModeEnabled() + + assertSoftly { + debugMode shouldBe false + } + } + + unmockkAll() + } }) diff --git a/src/test/kotlin/eu/ibagroup/formainframe/editor/EditorTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/editor/EditorTestSpec.kt index ea57efb22..e149e5120 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/editor/EditorTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/editor/EditorTestSpec.kt @@ -75,7 +75,6 @@ import java.nio.charset.CoderResult import javax.swing.JComponent import javax.swing.SwingUtilities import kotlin.reflect.KFunction -import kotlin.reflect.full.declaredFunctions class EditorTestSpec : WithApplicationShouldSpec({ afterSpec { @@ -300,10 +299,8 @@ class EditorTestSpec : WithApplicationShouldSpec({ val decoderResultMock = mockk() every { decoderResultMock.length() } returns 1 - val getLastItemRef = ContainerUtil::class.declaredFunctions - .filter { it.name == "getLastItem" } - .first { it.parameters.size == 2 } - mockkStatic(getLastItemRef) + val getLastItemRef: (MutableList) -> Any = ContainerUtil::getLastItem + mockkStatic(getLastItemRef as KFunction<*>) every { ContainerUtil.getLastItem(any>()) } answers { val descriptors = firstArg>() if (descriptors.isNotEmpty()) descriptors.last() else null @@ -502,10 +499,8 @@ class EditorTestSpec : WithApplicationShouldSpec({ decoderResultMock } - val commonPrefixLengthRef = StringUtil::class.declaredFunctions - .filter { it.name == "commonPrefixLength" } - .first { it.parameters.size == 2 } - mockkStatic(commonPrefixLengthRef) + val commonPrefixLengthRef: (CharSequence, CharSequence) -> Int = StringUtil::commonPrefixLength + mockkStatic(commonPrefixLengthRef as KFunction<*>) every { StringUtil.commonPrefixLength(any(), any()) } returns text.length val descriptors = lossyEncodingInspection.checkFile(psiFileMock, inspectionManagerMock, isOnTheFly) @@ -621,10 +616,8 @@ class EditorTestSpec : WithApplicationShouldSpec({ decoderResultMock } - val commonPrefixLengthRef = StringUtil::class.declaredFunctions - .filter { it.name == "commonPrefixLength" } - .first { it.parameters.size == 2 } - mockkStatic(commonPrefixLengthRef) + val commonPrefixLengthRef: (CharSequence, CharSequence) -> Int = StringUtil::commonPrefixLength + mockkStatic(commonPrefixLengthRef as KFunction<*>) every { StringUtil.commonPrefixLength(any(), any()) } returns text.length - 1 val descriptors = lossyEncodingInspection.checkFile(psiFileMock, inspectionManagerMock, isOnTheFly) diff --git a/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateDatasetActionTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateDatasetActionTestSpec.kt index 061d4a19b..0504a7335 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateDatasetActionTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateDatasetActionTestSpec.kt @@ -10,13 +10,15 @@ package eu.ibagroup.formainframe.explorer.actions +import com.intellij.notification.Notification +import com.intellij.notification.Notifications +import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.Presentation import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.ComponentManager import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.project.Project -import com.intellij.openapi.ui.showOkNoDialog import eu.ibagroup.formainframe.analytics.AnalyticsService import eu.ibagroup.formainframe.analytics.events.AnalyticsEvent import eu.ibagroup.formainframe.common.ui.StatefulDialog @@ -44,12 +46,10 @@ import io.mockk.mockk import io.mockk.mockkObject import io.mockk.mockkStatic import io.mockk.unmockkAll -import org.junit.jupiter.api.fail import org.zowe.kotlinsdk.DatasetOrganization import org.zowe.kotlinsdk.DsnameType import java.util.* import javax.swing.Icon -import javax.swing.SwingUtilities import kotlin.reflect.KFunction class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ @@ -69,6 +69,7 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ val dataOpsManagerMock = mockk() val componentManagerMock = mockk() val explorerMock = mockk>() + lateinit var addMaskActionInst: AnAction val analyticsService = ApplicationManager.getApplication().service() as TestAnalyticsServiceImpl @@ -109,6 +110,15 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ } answers { isCleanInvalidateOnExpandTriggered = true } + + val notifyRef: (Notification) -> Unit = Notifications.Bus::notify + mockkStatic(notifyRef as KFunction<*>) + mockkStatic(Notification::get) + every { Notifications.Bus.notify(any()) } answers { + val notification = firstArg() + every { Notification.get(any()) } returns notification + addMaskActionInst = notification.actions.first { it.templateText == "Add mask" } + } } afterEach { @@ -124,7 +134,6 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isUpdateOnConfigCrudableCalled = false var isShowUntilDoneSucceeded = false @@ -153,15 +162,7 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (isSendTopic) { - fail("cleanCache should not send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -180,34 +181,17 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ Optional.of(mockk()) } - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - true - } - allocateDsActionInst.actionPerformed(anActionEventMock) + addMaskActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isUpdateOnConfigCrudableCalled shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("perform allocate PS dataset action creating a new dataset mask") { @@ -218,7 +202,6 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isUpdateOnConfigCrudableCalled = false var isShowUntilDoneSucceeded = false @@ -254,15 +237,7 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (isSendTopic) { - fail("cleanCache should not send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -281,35 +256,18 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ Optional.of(mockk()) } - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - true - } - allocateDsActionInst.actionPerformed(anActionEventMock) + addMaskActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } - assertSoftly { initState.allocationParameters.directoryBlocks shouldBe null } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isUpdateOnConfigCrudableCalled shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" + initState.allocationParameters.directoryBlocks shouldBe null } } should("perform allocate PO-E dataset action creating a new dataset mask") { @@ -320,7 +278,6 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isUpdateOnConfigCrudableCalled = false var isShowUntilDoneSucceeded = false @@ -353,15 +310,7 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (isSendTopic) { - fail("cleanCache should not send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -380,36 +329,19 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ Optional.of(mockk()) } - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - true - } - allocateDsActionInst.actionPerformed(anActionEventMock) + addMaskActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } - assertSoftly { initState.allocationParameters.datasetOrganization shouldBe DatasetOrganization.PO } - assertSoftly { initState.allocationParameters.dsnType shouldBe DsnameType.LIBRARY } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isUpdateOnConfigCrudableCalled shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" + initState.allocationParameters.datasetOrganization shouldBe DatasetOrganization.PO + initState.allocationParameters.dsnType shouldBe DsnameType.LIBRARY } } should("perform allocate dataset action without creating a new dataset mask") { @@ -420,7 +352,6 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isUpdateOnConfigCrudableCalled = false var isShowUntilDoneSucceeded = false @@ -449,15 +380,7 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (!isSendTopic) { - fail("cleanCache should send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -476,119 +399,19 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ Optional.of(mockk()) } - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - false - } - allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe false } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } - } - } - should("perform allocate dataset action without refreshing dataset mask as the selected node is a working set") { - val workingSetMock = mockk() - val nodeMock = mockk() - val nodeDataMock = NodeData(nodeMock, null, null) - val selectedNodesData = listOf(nodeDataMock) - lateinit var initState: DatasetAllocationParams - var isOperationPerformed = false - var isUpdateOnConfigCrudableCalled = false - var isShowUntilDoneSucceeded = false - - val showUntilDoneMockk: ( - DatasetAllocationParams, - (DatasetAllocationParams) -> StatefulDialog, - (DatasetAllocationParams) -> Boolean - ) -> DatasetAllocationParams? = ::showUntilDone - mockkStatic(showUntilDoneMockk as KFunction<*>) - every { - hint(DatasetAllocationParams::class) - showUntilDoneMockk( - any(), - any<(DatasetAllocationParams) -> StatefulDialog>(), - any<(DatasetAllocationParams) -> Boolean>() - ) - } answers { - initState = firstArg() - val thirdBlockResult = thirdArg<(DatasetAllocationParams) -> Boolean>() - isShowUntilDoneSucceeded = thirdBlockResult(initState) - initState - } - - mockkObject(configCrudable) - every { - configCrudable.getByUniqueKey(any(), any()) - } returns Optional.of(filesWorkingSetConfigMock) - - every { nodeMock.parent } returns null - every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock - every { viewMock.mySelectedNodesData } returns selectedNodesData - every { workingSetMock.name } returns "test" - every { workingSetMock.uuid } returns "test" - every { workingSetMock.hint(ConnectionConfig::class).connectionConfig } returns mockk() - every { - dataOpsManagerMock.hint(Boolean::class).performOperation(any>(), any()) - } answers { - isOperationPerformed = true - true - } - every { workingSetMock.explorer } returns explorerMock - every { configCrudable.update(any(), any()) } answers { - isUpdateOnConfigCrudableCalled = true - Optional.of(mockk()) - } - - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - true - } - - allocateDsActionInst.actionPerformed(anActionEventMock) - - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe false } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isUpdateOnConfigCrudableCalled shouldBe false + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } - should("perform allocate dataset action creating new dataset mask without refreshing the existing on as the connection config is not found") { + should("perform allocate dataset action creating new dataset mask without adding as the connection config is not found") { val workingSetMock = mockk() val nodeMock = mockk() val nodeDataMock = NodeData(nodeMock, null, null) @@ -641,33 +464,17 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ Optional.of(mockk()) } - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - true - } - allocateDsActionInst.actionPerformed(anActionEventMock) + addMaskActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe false } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isUpdateOnConfigCrudableCalled shouldBe false } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe false + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isUpdateOnConfigCrudableCalled shouldBe false + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("perform allocate dataset action with failure on operation performing") { @@ -711,13 +518,12 @@ class AllocateDatasetActionTestSpec : WithApplicationShouldSpec({ allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe false } - assertSoftly { isShowUntilDoneSucceeded shouldBe false } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isThrowableReported shouldBe true } - assertSoftly { initState.errorMessage shouldBe exceptionMsg } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe false + isShowUntilDoneSucceeded shouldBe false + isAnalitycsTracked shouldBe true + isThrowableReported shouldBe true + initState.errorMessage shouldBe exceptionMsg } } } diff --git a/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateLikeActionTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateLikeActionTestSpec.kt index a92bb88d5..c0bc04312 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateLikeActionTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/explorer/actions/AllocateLikeActionTestSpec.kt @@ -10,6 +10,9 @@ package eu.ibagroup.formainframe.explorer.actions +import com.intellij.notification.Notification +import com.intellij.notification.Notifications +import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.Presentation import com.intellij.openapi.application.ApplicationManager @@ -17,7 +20,6 @@ import com.intellij.openapi.components.ComponentManager import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.project.Project import com.intellij.openapi.ui.Messages.showWarningDialog -import com.intellij.openapi.ui.showOkNoDialog import eu.ibagroup.formainframe.analytics.AnalyticsService import eu.ibagroup.formainframe.analytics.events.AnalyticsEvent import eu.ibagroup.formainframe.common.ui.StatefulDialog @@ -54,14 +56,12 @@ import io.mockk.mockk import io.mockk.mockkObject import io.mockk.mockkStatic import io.mockk.unmockkAll -import org.junit.jupiter.api.fail import org.zowe.kotlinsdk.Dataset import org.zowe.kotlinsdk.DatasetOrganization import org.zowe.kotlinsdk.RecordFormat import org.zowe.kotlinsdk.SpaceUnits import java.util.* import javax.swing.Icon -import javax.swing.SwingUtilities import kotlin.reflect.KFunction class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ @@ -80,6 +80,7 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ val dataOpsManagerMock = mockk() val componentManagerMock = mockk() val explorerMock = mockk>() + lateinit var addMaskActionInst: AnAction val analyticsService = ApplicationManager.getApplication().service() as TestAnalyticsServiceImpl @@ -119,6 +120,15 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ } answers { isCleanInvalidateOnExpandTriggered = true } + + val notifyRef: (Notification) -> Unit = Notifications.Bus::notify + mockkStatic(notifyRef as KFunction<*>) + mockkStatic(Notification::get) + every { Notifications.Bus.notify(any()) } answers { + val notification = firstArg() + every { Notification.get(any()) } returns notification + addMaskActionInst = notification.actions.first { it.templateText == "Add mask" } + } } afterEach { @@ -137,7 +147,6 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isShowUntilDoneSucceeded = false every { anActionEventMock.getExplorerView() } returns viewMock @@ -168,15 +177,7 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (!isSendTopic) { - fail("cleanCache should send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -191,33 +192,16 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ } every { workingSetMock.explorer } returns explorerMock - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - false - } - allocateDsActionInst.actionPerformed(anActionEventMock) - - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + addMaskActionInst.actionPerformed(anActionEventMock) + + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("perform allocate PDS dataset with TRACKS action without creating a new dataset mask") { @@ -236,7 +220,6 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isShowUntilDoneSucceeded = false every { anActionEventMock.getExplorerView() } returns viewMock @@ -267,15 +250,7 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (!isSendTopic) { - fail("cleanCache should send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -290,33 +265,15 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ } every { workingSetMock.explorer } returns explorerMock - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - false - } - allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("perform allocate PDS/E dataset with CYLINDERS action without creating a new dataset mask") { @@ -335,7 +292,6 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isShowUntilDoneSucceeded = false every { anActionEventMock.getExplorerView() } returns viewMock @@ -366,15 +322,7 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (!isSendTopic) { - fail("cleanCache should send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -389,33 +337,15 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ } every { workingSetMock.explorer } returns explorerMock - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - false - } - allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("perform allocate PS dataset with BLOCKS action without creating a new dataset mask, changing BLOCKS to TRACKS") { @@ -429,7 +359,6 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ val dsMaskNodeMock = mockk() lateinit var initState: DatasetAllocationParams var isOperationPerformed = false - var isCleanCacheTriggered = false var isShowUntilDoneSucceeded = false var isBlocksChangedToTracks = false @@ -470,15 +399,7 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ configCrudable.getByUniqueKey(any(), any()) } returns Optional.of(filesWorkingSetConfigMock) - every { - dsMaskNodeMock.cleanCache(any(), any(), any(), any()) - } answers { - isCleanCacheTriggered = true - val isSendTopic = lastArg() - if (!isSendTopic) { - fail("cleanCache should send topic in this testcase") - } - } + every { dsMaskNodeMock.cleanCache(any(), any(), any(), any()) } returns Unit every { nodeMock.parent } returns dsMaskNodeMock every { nodeMock.hint(FilesWorkingSet::class).unit } returns workingSetMock every { viewMock.mySelectedNodesData } returns selectedNodesData @@ -493,34 +414,16 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ } every { workingSetMock.explorer } returns explorerMock - val showOkNoDialogMock: ( - String, - String, - Project?, - String, - String, - Icon? - ) -> Boolean = ::showOkNoDialog - mockkStatic(showOkNoDialogMock as KFunction<*>) - every { - hint(Boolean::class) - showOkNoDialogMock(any(), any(), any(), any(), any(), any()) - } answers { - false - } - allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe true } - assertSoftly { isShowUntilDoneSucceeded shouldBe true } - assertSoftly { isAnalitycsTracked shouldBe true } - assertSoftly { isOperationPerformed shouldBe true } - assertSoftly { isCleanCacheTriggered shouldBe true } - assertSoftly { isBlocksChangedToTracks shouldBe true } - assertSoftly { isThrowableReported shouldBe false } - assertSoftly { initState.errorMessage shouldBe "" } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe true + isShowUntilDoneSucceeded shouldBe true + isAnalitycsTracked shouldBe true + isOperationPerformed shouldBe true + isBlocksChangedToTracks shouldBe true + isThrowableReported shouldBe false + initState.errorMessage shouldBe "" } } should("not perform 'allocate like' action as the file explorer view is not found") { @@ -537,12 +440,11 @@ class AllocateLikeActionTestSpec : WithApplicationShouldSpec({ allocateDsActionInst.actionPerformed(anActionEventMock) - // Pause to wait until all EDT events are finished - SwingUtilities.invokeAndWait { - assertSoftly { isCleanInvalidateOnExpandTriggered shouldBe false } - assertSoftly { isAnalitycsTracked shouldBe false } - assertSoftly { isOperationPerformed shouldBe false } - assertSoftly { isThrowableReported shouldBe false } + assertSoftly { + isCleanInvalidateOnExpandTriggered shouldBe false + isAnalitycsTracked shouldBe false + isOperationPerformed shouldBe false + isThrowableReported shouldBe false } } } diff --git a/src/test/kotlin/eu/ibagroup/formainframe/explorer/ui/ChangeEncodingDialogTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/explorer/ui/ChangeEncodingDialogTestSpec.kt index 1989d4ca1..91c27687f 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/explorer/ui/ChangeEncodingDialogTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/explorer/ui/ChangeEncodingDialogTestSpec.kt @@ -49,7 +49,7 @@ import java.awt.event.ActionEvent import java.nio.charset.Charset import javax.swing.Action import javax.swing.Icon -import kotlin.reflect.full.declaredFunctions +import kotlin.reflect.KFunction class ChangeEncodingDialogTestSpec : WithApplicationShouldSpec({ afterSpec { @@ -95,9 +95,8 @@ class ChangeEncodingDialogTestSpec : WithApplicationShouldSpec({ val actionEventMock = mockk() - val showDialogRef = Messages::class.declaredFunctions - .first { it.name == "showDialog" && it.parameters.size == 5 } - mockkStatic(showDialogRef) + val showDialogRef: (String, String, Array, Int, Icon) -> Int = Messages::showDialog + mockkStatic(showDialogRef as KFunction<*>) every { contentSynchronizerMock.synchronizeWithRemote(any()) } returns Unit diff --git a/src/test/kotlin/eu/ibagroup/formainframe/utils/EncodingUtilsTestSpec.kt b/src/test/kotlin/eu/ibagroup/formainframe/utils/EncodingUtilsTestSpec.kt index 0a2131b37..5f86f3397 100644 --- a/src/test/kotlin/eu/ibagroup/formainframe/utils/EncodingUtilsTestSpec.kt +++ b/src/test/kotlin/eu/ibagroup/formainframe/utils/EncodingUtilsTestSpec.kt @@ -52,7 +52,7 @@ import java.nio.charset.CharsetDecoder import java.nio.charset.CharsetEncoder import java.nio.charset.UnsupportedCharsetException import javax.swing.Icon -import kotlin.reflect.full.declaredFunctions +import kotlin.reflect.KFunction class EncodingUtilsTestSpec : WithApplicationShouldSpec({ context("utils module: encodingUtils") { @@ -139,9 +139,8 @@ class EncodingUtilsTestSpec : WithApplicationShouldSpec({ mockkStatic(InspectionEngine::runInspectionOnFile) - val showDialogRef = Messages::class.declaredFunctions - .first { it.name == "showDialog" && it.parameters.size == 5 } - mockkStatic(showDialogRef) + val showDialogRef: (String, String, Array, Int, Icon) -> Int = Messages::showDialog + mockkStatic(showDialogRef as KFunction<*>) beforeEach { dataOpsManagerService.testInstance = object : TestDataOpsManagerImpl(explorerMock.componentManager) {