/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.ssh.key.client.manage;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwtmockito.GwtMockitoTestRunner;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.api.promises.client.js.JsPromiseError;
import org.eclipse.che.api.ssh.shared.dto.SshPairDto;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.dialogs.CancelCallback;
import org.eclipse.che.ide.api.dialogs.ConfirmCallback;
import org.eclipse.che.ide.api.dialogs.ConfirmDialog;
import org.eclipse.che.ide.api.dialogs.DialogFactory;
import org.eclipse.che.ide.api.dialogs.InputCallback;
import org.eclipse.che.ide.api.dialogs.InputDialog;
import org.eclipse.che.ide.api.dialogs.InputValidator;
import org.eclipse.che.ide.api.dialogs.InputValidator.Violation;
import org.eclipse.che.ide.api.dialogs.MessageDialog;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode;
import org.eclipse.che.ide.api.ssh.SshServiceClient;
import org.eclipse.che.ide.rest.DtoUnmarshallerFactory;
import org.eclipse.che.plugin.ssh.key.client.SshKeyLocalizationConstant;
import org.eclipse.che.plugin.ssh.key.client.SshResources;
import org.eclipse.che.plugin.ssh.key.client.upload.UploadSshKeyPresenter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.List;
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_DEFAULTS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Testing {@link SshKeyManagerPresenter} functionality.
*
* @author Roman Nikitenko
*/
@RunWith(GwtMockitoTestRunner.class)
public class SshKeyManagerPresenterTest {
public static final String GITHUB_HOST = "github.com";
@Captor
private ArgumentCaptor<AsyncCallback<Void>> asyncCallbackCaptor;
@Captor
private ArgumentCaptor<ConfirmCallback> confirmCallbackCaptor;
@Captor
private ArgumentCaptor<CancelCallback> cancelCallbackCaptor;
@Captor
private ArgumentCaptor<InputCallback> inputCallbackCaptor;
@Captor
private ArgumentCaptor<Operation<Void>> operationVoidCapture;
@Captor
private ArgumentCaptor<Operation<List<SshPairDto>>> operationSshPairDTOsCapture;
@Captor
private ArgumentCaptor<Operation<SshPairDto>> operationSshPairDTOCapture;
@Captor
private ArgumentCaptor<Operation<PromiseError>> operationErrorCapture;
private Promise<Void> voidPromise;
private Promise<SshPairDto> sshPairDTOPromise;
private Promise<List<SshPairDto>> sshPairDTOsPromise;
@Mock
private AppContext appContext;
@Mock
private DtoUnmarshallerFactory dtoUnmarshallerFactory;
@Mock
private DialogFactory dialogFactory;
@Mock
private SshKeyManagerView view;
@Mock
private SshServiceClient service;
@Mock
private ShowSshKeyView showSshKeyView;
@Mock
private SshKeyLocalizationConstant constant;
@Mock
private SshResources resources;
@Mock
private UploadSshKeyPresenter uploadSshKeyPresenter;
@Mock
private NotificationManager notificationManager;
@Mock
private InputDialog inputDialog;
@InjectMocks
private SshKeyManagerPresenter presenter;
@Mock
SshPairDto sshPairDto;
@Before
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
voidPromise = createPromiseMock();
sshPairDTOsPromise = createPromiseMock();
sshPairDTOPromise = createPromiseMock();
when(service.getPairs(anyString())).thenReturn(sshPairDTOsPromise);
when(service.deletePair(anyString(), anyString())).thenReturn(voidPromise);
when(service.generatePair(anyString(), anyString())).thenReturn(sshPairDTOPromise);
when(inputDialog.withValidator(any(InputValidator.class))).thenReturn(inputDialog);
}
private Promise createPromiseMock() {
return mock(Promise.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
if (invocation.getMethod().getReturnType().isInstance(invocation.getMock())) {
return invocation.getMock();
}
return RETURNS_DEFAULTS.answer(invocation);
}
});
}
@Test
public void testGo() {
AcceptsOneWidget container = mock(AcceptsOneWidget.class);
presenter.go(container);
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(container).setWidget(eq(view));
}
@Test
public void testOnViewClickedWhenGetPublicKeyIsSuccess() {
when(sshPairDto.getPublicKey()).thenReturn("publicKey");
when(sshPairDto.getName()).thenReturn("name");
MessageDialog messageDialog = mock(MessageDialog.class);
when(dialogFactory.createMessageDialog(anyString(), anyString(), (ConfirmCallback)anyObject())).thenReturn(messageDialog);
presenter.onViewClicked(sshPairDto);
verify(showSshKeyView).show("name", "publicKey");
}
@Test
public void testOnDeleteClickedWhenDeleteKeyConfirmed() {
when(sshPairDto.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
when(sshPairDto.getName()).thenReturn(GITHUB_HOST);
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), confirmCallbackCaptor.capture(), (CancelCallback)anyObject());
ConfirmCallback confirmCallback = confirmCallbackCaptor.getValue();
confirmCallback.accepted();
verify(confirmDialog).show();
verify(service).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
}
@Test
public void testOnDeleteClickedWhenDeleteKeyCanceled() {
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), cancelCallbackCaptor.capture());
CancelCallback cancelCallback = cancelCallbackCaptor.getValue();
cancelCallback.cancelled();
verify(confirmDialog).show();
verify(service, never()).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), anyString());
}
@Test
public void testOnDeleteClickedWhenDeleteKeyIsSuccess() throws OperationException {
when(sshPairDto.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
when(sshPairDto.getName()).thenReturn(GITHUB_HOST);
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), confirmCallbackCaptor.capture(), (CancelCallback)anyObject());
ConfirmCallback confirmCallback = confirmCallbackCaptor.getValue();
confirmCallback.accepted();
verify(voidPromise).then(operationVoidCapture.capture());
operationVoidCapture.getValue().apply(null);
verify(confirmDialog).show();
verify(service).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
}
@Test
public void testOnDeleteClickedWhenDeleteKeyIsFailure() throws OperationException {
when(sshPairDto.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
when(sshPairDto.getName()).thenReturn(GITHUB_HOST);
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), confirmCallbackCaptor.capture(), (CancelCallback)anyObject());
ConfirmCallback confirmCallback = confirmCallbackCaptor.getValue();
confirmCallback.accepted();
verify(voidPromise).catchError(operationErrorCapture.capture());
operationErrorCapture.getValue().apply(JsPromiseError.create(""));
verify(confirmDialog).show();
verify(service).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), anyString());
verify(notificationManager).notify(anyString(), eq(StatusNotification.Status.FAIL), eq(FLOAT_MODE));
verify(service, never()).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
}
@Test
public void testShouldRefreshKeysAfterSuccessfulDeleteKey() throws OperationException {
when(sshPairDto.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
when(sshPairDto.getName()).thenReturn(GITHUB_HOST);
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
List<SshPairDto> sshPairDtoArray = new ArrayList<>();
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), confirmCallbackCaptor.capture(), (CancelCallback)anyObject());
ConfirmCallback confirmCallback = confirmCallbackCaptor.getValue();
confirmCallback.accepted();
verify(voidPromise).then(operationVoidCapture.capture());
operationVoidCapture.getValue().apply(null);
verify(sshPairDTOsPromise).then(operationSshPairDTOsCapture.capture());
operationSshPairDTOsCapture.getValue().apply(sshPairDtoArray);
verify(confirmDialog).show();
verify(service).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view).setPairs(eq(sshPairDtoArray));
}
@Test
public void testFailedRefreshKeysAfterSuccessfulDeleteKey() throws OperationException {
when(sshPairDto.getService()).thenReturn(SshKeyManagerPresenter.VCS_SSH_SERVICE);
when(sshPairDto.getName()).thenReturn(GITHUB_HOST);
SafeHtml safeHtml = mock(SafeHtml.class);
ConfirmDialog confirmDialog = mock(ConfirmDialog.class);
List<SshPairDto> sshPairDtoArray = new ArrayList<>();
when(constant.deleteSshKeyQuestion(anyString())).thenReturn(safeHtml);
when(safeHtml.asString()).thenReturn("");
when(dialogFactory.createConfirmDialog(anyString(), anyString(), (ConfirmCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(confirmDialog);
presenter.onDeleteClicked(sshPairDto);
verify(dialogFactory).createConfirmDialog(anyString(), anyString(), confirmCallbackCaptor.capture(), (CancelCallback)anyObject());
ConfirmCallback confirmCallback = confirmCallbackCaptor.getValue();
confirmCallback.accepted();
verify(voidPromise).then(operationVoidCapture.capture());
operationVoidCapture.getValue().apply(null);
verify(sshPairDTOsPromise).catchError(operationErrorCapture.capture());
operationErrorCapture.getValue().apply(JsPromiseError.create(""));
verify(confirmDialog).show();
verify(service).deletePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view, never()).setPairs(eq(sshPairDtoArray));
verify(notificationManager).notify(anyString(), any(StatusNotification.Status.class), (DisplayMode)anyObject());
}
@Test
public void testShouldRefreshKeysAfterSuccessfulUploadKey() throws OperationException {
List<SshPairDto> sshPairDtoArray = new ArrayList<>();
presenter.onUploadClicked();
verify(uploadSshKeyPresenter).showDialog(asyncCallbackCaptor.capture());
AsyncCallback<Void> asyncCallback = asyncCallbackCaptor.getValue();
asyncCallback.onSuccess(null);
verify(sshPairDTOsPromise).then(operationSshPairDTOsCapture.capture());
operationSshPairDTOsCapture.getValue().apply(sshPairDtoArray);
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view).setPairs(eq(sshPairDtoArray));
}
@Test
public void testFailedRefreshKeysAfterSuccessfulUploadKey() throws OperationException {
List<SshPairDto> sshPairDtoArray = new ArrayList<>();
presenter.onUploadClicked();
verify(uploadSshKeyPresenter).showDialog(asyncCallbackCaptor.capture());
AsyncCallback<Void> asyncCallback = asyncCallbackCaptor.getValue();
asyncCallback.onSuccess(null);
verify(sshPairDTOsPromise).catchError(operationErrorCapture.capture());
operationErrorCapture.getValue().apply(JsPromiseError.create(""));
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view, never()).setPairs(eq(sshPairDtoArray));
}
@Test
public void testOnGenerateClickedWhenUserConfirmGenerateKey() {
when(dialogFactory.createInputDialog(anyString(), anyString(), (InputCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(inputDialog);
presenter.onGenerateClicked();
verify(dialogFactory).createInputDialog(anyString(), anyString(), inputCallbackCaptor.capture(), (CancelCallback)anyObject());
InputCallback inputCallback = inputCallbackCaptor.getValue();
inputCallback.accepted(GITHUB_HOST);
verify(service).generatePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
}
@Test
public void testOnGenerateClickedWhenUserCancelGenerateKey() {
when(dialogFactory.createInputDialog(anyString(), anyString(), (InputCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(inputDialog);
presenter.onGenerateClicked();
verify(dialogFactory).createInputDialog(anyString(), anyString(), (InputCallback)anyObject(), cancelCallbackCaptor.capture());
CancelCallback cancelCallback = cancelCallbackCaptor.getValue();
cancelCallback.cancelled();
verify(service, never()).generatePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
}
@Test
public void testOnGenerateClickedWhenGenerateKeyIsFailed() throws OperationException {
when(dialogFactory.createInputDialog(anyString(), anyString(), (InputCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(inputDialog);
presenter.onGenerateClicked();
verify(dialogFactory).createInputDialog(anyString(), anyString(),
inputCallbackCaptor.capture(), cancelCallbackCaptor.capture());
InputCallback inputCallback = inputCallbackCaptor.getValue();
inputCallback.accepted(GITHUB_HOST);
verify(sshPairDTOPromise).catchError(operationErrorCapture.capture());
operationErrorCapture.getValue().apply(JsPromiseError.create(""));
verify(service).generatePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
verify(service, never()).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view, never()).setPairs((List<SshPairDto>)anyObject());
verify(notificationManager).notify(anyString(), anyString(), any(StatusNotification.Status.class), (DisplayMode)anyObject());
}
@Test
public void testShouldRefreshKeysAfterSuccessfulGenerateKey() throws OperationException {
List<SshPairDto> sshPairDtoArray = new ArrayList<>();
when(dialogFactory.createInputDialog(anyString(), anyString(), (InputCallback)anyObject(), (CancelCallback)anyObject()))
.thenReturn(inputDialog);
presenter.onGenerateClicked();
verify(dialogFactory).createInputDialog(anyString(), anyString(),
inputCallbackCaptor.capture(), cancelCallbackCaptor.capture());
InputCallback inputCallback = inputCallbackCaptor.getValue();
inputCallback.accepted(GITHUB_HOST);
verify(sshPairDTOPromise).then(operationSshPairDTOCapture.capture());
operationSshPairDTOCapture.getValue().apply(null);
verify(sshPairDTOsPromise).then(operationSshPairDTOsCapture.capture());
operationSshPairDTOsCapture.getValue().apply(sshPairDtoArray);
verify(service).generatePair(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE), eq(GITHUB_HOST));
verify(service).getPairs(Matchers.eq(SshKeyManagerPresenter.VCS_SSH_SERVICE));
verify(view).setPairs(eq(sshPairDtoArray));
}
@Test
public void shouldReturnErrorOnHostNameWithHttpProtocolValidation() throws OperationException {
String invalidHostname = "http://host.xz";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameWithHttpsProtocolValidation() throws OperationException {
String invalidHostname = "https://host.xz";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameWithPortValidation() throws OperationException {
String invalidHostname = "host:5005";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameThatStartsWithDotValidation() throws OperationException {
String invalidHostname = ".host.com";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameThatStartsWithDashValidation() throws OperationException {
String invalidHostname = "-host.com";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameThatEndsOnDotValidation() throws OperationException {
String invalidHostname = "host.com.";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameThatEndsOnDashValidation() throws OperationException {
String invalidHostname = "host.com-";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnErrorOnHostNameWithDotAndDashTogetherValidation() throws OperationException {
String invalidHostname = "host.-com";
when(constant.invalidHostName()).thenReturn("ErrorMessage");
String errorMessage = ((InputValidator)presenter.hostNameValidator).validate(invalidHostname).getMessage();
assertEquals("ErrorMessage", errorMessage);
}
@Test
public void shouldReturnNullOnValidHostNameValidation() throws OperationException {
String validHostname = "hostname.com";
Violation violation = ((InputValidator)presenter.hostNameValidator).validate(validHostname);
assertNull(violation);
}
@Test
public void shouldReturnNullOnHostNameWithDotAndDashValidation() throws OperationException {
String validHostname = "host-name.com";
Violation violation = ((InputValidator)presenter.hostNameValidator).validate(validHostname);
assertNull(violation);
}
@Test
public void shouldReturnNullOnHostNameWithSeveralDotsAndDashesValidation() throws OperationException {
String validHostname = "ho-st.na-me.com";
Violation violation = ((InputValidator)presenter.hostNameValidator).validate(validHostname);
assertNull(violation);
}
}