@Test
  public void shouldCloseTerminal() throws Exception {
    TerminalPresenter terminal = mock(TerminalPresenter.class);
    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    ProcessTreeNode terminalNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);
    presenter.terminals.put(PROCESS_ID, terminal);

    when(terminalNode.getId()).thenReturn(PROCESS_ID);
    when(view.getNodeIndex(anyString())).thenReturn(0);
    when(machineNode.getChildren()).thenReturn(children);
    when(terminalNode.getParent()).thenReturn(machineNode);

    presenter.onCloseTerminal(terminalNode);

    verify(terminal).stopTerminal();
    verify(terminalNode, times(2)).getId();
    verify(terminalNode).getParent();
    verify(view).getNodeIndex(eq(PROCESS_ID));
    verify(view).hideProcessOutput(eq(PROCESS_ID));
    verify(view).removeProcessNode(eq(terminalNode));
    verify(view).setProcessesData(anyObject());
  }
  @Test
  public void shouldStopProcessWithoutCloseCommanOutput() throws Exception {
    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    ProcessTreeNode commandNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    when(outputConsole.isFinished()).thenReturn(false);
    presenter.consoles.put(PROCESS_ID, outputConsole);
    //noinspection ConstantConditions
    machineNode.getChildren().add(commandNode);

    when(commandNode.getId()).thenReturn(PROCESS_ID);
    when(view.getNodeIndex(anyString())).thenReturn(0);
    when(machineNode.getChildren()).thenReturn(children);
    when(commandNode.getParent()).thenReturn(machineNode);

    presenter.onStopCommandProcess(commandNode);

    verify(outputConsole).stop();
    verify(view, never()).hideProcessOutput(eq(PROCESS_ID));
    verify(view, never()).removeProcessNode(eq(commandNode));
  }
  @Test
  public void shouldHideStopProcessButtonAtAddingCommand() throws Exception {
    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    ProcessTreeNode selectedCommandNode =
        new ProcessTreeNode(COMMAND_NODE, null, PROCESS_NAME, null, children);
    children.add(selectedCommandNode);

    when(outputConsole.isFinished()).thenReturn(true);

    presenter.consoles.clear();

    presenter.addCommandOutput(MACHINE_ID, outputConsole);

    verify(view).addProcessNode(anyObject());
    verify(view, never()).hideProcessOutput(anyString());

    verify(outputConsole).go(acceptsOneWidgetCaptor.capture());
    IsWidget widget = mock(IsWidget.class);
    acceptsOneWidgetCaptor.getValue().setWidget(widget);

    verify(view).addProcessWidget(anyString(), eq(widget));
    verify(view, times(2)).selectNode(anyObject());
    verify(view).setProcessesData(anyObject());
    verify(view).getNodeById(anyString());
    verify(view).setProcessRunning(anyString(), eq(false));
  }
  @Test
  public void shouldCloseCommanOutputWhenCommandHasFinished() throws Exception {
    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    ProcessTreeNode commandNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    when(outputConsole.isFinished()).thenReturn(true);
    presenter.consoles.put(PROCESS_ID, outputConsole);
    machineNode.getChildren().add(commandNode);

    when(commandNode.getId()).thenReturn(PROCESS_ID);
    when(view.getNodeIndex(anyString())).thenReturn(0);
    when(machineNode.getChildren()).thenReturn(children);
    when(commandNode.getParent()).thenReturn(machineNode);

    presenter.onCloseCommandOutputClick(commandNode);

    verify(commandNode, times(2)).getId();
    verify(commandNode).getParent();
    verify(view).getNodeIndex(eq(PROCESS_ID));
    verify(view).hideProcessOutput(eq(PROCESS_ID));
    verify(view).removeProcessNode(eq(commandNode));
    verify(view).setProcessesData(anyObject());
  }
  @Test
  public void shouldShowErrorWhenMachineNodeIsNull() throws Exception {
    List<ProcessTreeNode> children = new ArrayList<>();
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    OutputConsole outputConsole = mock(OutputConsole.class);

    presenter.addCommandOutput(MACHINE_ID, outputConsole);
    verify(notificationManager)
        .notify(anyString(), anyString(), any(StatusNotification.Status.class), anyBoolean());
    verify(localizationConstant, times(2)).machineNotFound(eq(MACHINE_ID));
  }
  @Test
  public void testGo() throws Exception {
    AcceptsOneWidget container = mock(AcceptsOneWidget.class);

    presenter.go(container);

    verify(container).setWidget(eq(view));
  }
  @Test
  public void stopButtonShouldBeHiddenWhenProcessFinished() {
    when(outputConsole.isFinished()).thenReturn(true);
    presenter.consoles.put(PROCESS_ID, outputConsole);

    presenter.onProcessFinished(new ProcessFinishedEvent(null));

    verify(view).setProcessRunning(PROCESS_ID, false);
  }
  @Test
  public void shouldShowTerminalWhenTerminalNodeSelected() throws Exception {
    TerminalPresenter terminal = mock(TerminalPresenter.class);
    presenter.terminals.put(PROCESS_ID, terminal);

    ProcessTreeNode terminalNode = mock(ProcessTreeNode.class);
    when(terminalNode.getId()).thenReturn(PROCESS_ID);
    presenter.onTreeNodeSelected(terminalNode);

    verify(view).showProcessOutput(eq(PROCESS_ID));
    verify(view, never()).setProcessRunning(PROCESS_ID, true);
  }
  @Test
  public void stopButtonStateShouldBeRefreshedWhenConsoleHasRunningProcess() {
    ProcessTreeNode commandNode = mock(ProcessTreeNode.class);
    when(commandNode.getId()).thenReturn(PROCESS_ID);

    when(outputConsole.isFinished()).thenReturn(false);
    presenter.consoles.put(PROCESS_ID, outputConsole);

    presenter.onTreeNodeSelected(commandNode);

    verify(view).setProcessRunning(PROCESS_ID, true);
  }
  @Test
  public void shouldShowCommanOutputWhenCommandSelected() throws Exception {
    ProcessTreeNode commandNode = mock(ProcessTreeNode.class);
    when(commandNode.getId()).thenReturn(PROCESS_ID);

    presenter.consoles.put(PROCESS_ID, outputConsole);

    presenter.onTreeNodeSelected(commandNode);

    verify(view).showProcessOutput(eq(PROCESS_ID));
    verify(view).setProcessRunning(anyString(), eq(true));
  }
  @Test
  public void shouldShowStopProcessButtonAtAddingTerminal() throws Exception {
    MachineDto machineDto = mock(MachineDto.class);
    MachineConfigDto machineConfigDto = mock(MachineConfigDto.class);
    when(machineDto.getConfig()).thenReturn(machineConfigDto);
    when(machineConfigDto.isDev()).thenReturn(true);
    when(machineDto.getStatus()).thenReturn(MachineStatus.RUNNING);

    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    Machine machine = mock(Machine.class);
    when(entityFactory.createMachine(anyObject())).thenReturn(machine);
    TerminalPresenter terminal = mock(TerminalPresenter.class);
    when(terminalFactory.create(machine)).thenReturn(terminal);
    IsWidget terminalWidget = mock(IsWidget.class);
    when(terminal.getView()).thenReturn(terminalWidget);

    presenter.addCommandOutput(MACHINE_ID, outputConsole);
    presenter.onAddTerminal(MACHINE_ID);

    verify(machinePromise).then(machineCaptor.capture());
    machineCaptor.getValue().apply(machineDto);

    verify(entityFactory).createMachine(anyObject());
    verify(terminalFactory).create(eq(machine));
    verify(terminal).getView();
    verify(view, times(2)).setProcessesData(anyObject());
    verify(view, times(2)).selectNode(anyObject());
    verify(view).addProcessWidget(anyString(), eq(terminalWidget));
    verify(view, times(2)).addProcessNode(anyObject());
    verify(terminal).setVisible(eq(true));
    verify(terminal).connect();
    verify(terminal).setListener(anyObject());
    verify(view).setProcessRunning(anyString(), eq(true));
  }
  @Test
  public void shouldAddCommand() throws Exception {
    ProcessTreeNode machineNode = mock(ProcessTreeNode.class);
    when(machineNode.getId()).thenReturn(MACHINE_ID);
    List<ProcessTreeNode> children = new ArrayList<>();
    children.add(machineNode);
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);

    presenter.addCommandOutput(MACHINE_ID, outputConsole);

    verify(view).addProcessNode(anyObject());
    verify(view, never()).hideProcessOutput(anyString());

    verify(outputConsole).go(acceptsOneWidgetCaptor.capture());
    IsWidget widget = mock(IsWidget.class);
    acceptsOneWidgetCaptor.getValue().setWidget(widget);

    verify(view).addProcessWidget(anyString(), eq(widget));
    verify(view, times(2)).selectNode(anyObject());
    verify(view).setProcessesData(anyObject());
    verify(view).getNodeById(anyString());
    verify(view).setProcessRunning(anyString(), anyBoolean());
  }
  @Test
  public void shouldReplaceCommandOutput() throws Exception {
    MachineDto machineDto = mock(MachineDto.class);
    when(machineDto.getId()).thenReturn(MACHINE_ID);
    MachineConfigDto machineConfigDto = mock(MachineConfigDto.class);
    when(machineDto.getConfig()).thenReturn(machineConfigDto);

    List<ProcessTreeNode> children = new ArrayList<>();
    ProcessTreeNode commandNode =
        new ProcessTreeNode(COMMAND_NODE, null, PROCESS_NAME, null, children);
    children.add(commandNode);
    ProcessTreeNode machineNode =
        new ProcessTreeNode(MACHINE_NODE, null, machineDto, null, children);
    children.add(machineNode);
    when(machineNode.getId()).thenReturn(MACHINE_ID);

    String commandId = commandNode.getId();
    presenter.rootNode = new ProcessTreeNode(ROOT_NODE, null, null, null, children);
    presenter.consoles.put(commandId, outputConsole);

    when(outputConsole.isFinished()).thenReturn(true);
    when(outputConsole.getTitle()).thenReturn(PROCESS_NAME);

    presenter.addCommandOutput(MACHINE_ID, outputConsole);

    verify(view, never()).addProcessNode(anyObject());
    verify(view, never()).setProcessesData(anyObject());

    verify(outputConsole).go(acceptsOneWidgetCaptor.capture());
    IsWidget widget = mock(IsWidget.class);
    acceptsOneWidgetCaptor.getValue().setWidget(widget);

    verify(view).hideProcessOutput(eq(commandId));
    verify(view).addProcessWidget(eq(commandId), eq(widget));
    verify(view).selectNode(anyObject());
    verify(view).getNodeById(eq(commandId));
  }
  @Test
  public void shouldShowConfirmDialogWhenCommandHasNotFinished() throws Exception {
    ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
    ProcessTreeNode commandNode = mock(ProcessTreeNode.class);

    when(outputConsole.isFinished()).thenReturn(false);
    presenter.consoles.put(PROCESS_ID, outputConsole);

    when(commandNode.getId()).thenReturn(PROCESS_ID);
    when(dialogFactory.createConfirmDialog(anyString(), anyString(), anyObject(), anyObject()))
        .thenReturn(confirmDialog);

    presenter.onCloseCommandOutputClick(commandNode);

    verify(commandNode).getId();
    verify(view, never()).hideProcessOutput(anyString());
    verify(view, never()).removeProcessNode(anyObject());
    verify(dialogFactory).createConfirmDialog(anyString(), anyString(), anyObject(), anyObject());
    verify(confirmDialog).show();
  }
  @Test
  public void shouldReturnTitleSVGImage() {
    presenter.getTitleSVGImage();

    verify(resources).terminal();
  }
  @Test
  public void shouldSetViewVisible() throws Exception {
    presenter.setVisible(true);

    verify(view).setVisible(eq(true));
  }
  @Test
  public void shouldReturnTitleToolTip() throws Exception {
    presenter.getTitleToolTip();

    verify(localizationConstant).viewProcessesTooltip();
  }
  @Test
  public void shouldReturnTitle() throws Exception {
    presenter.getTitle();

    verify(localizationConstant, times(2)).viewConsolesTitle();
  }