/******************************************************************************* * 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.ide.ext.java.client.refactoring.rename; import com.google.common.base.Optional; import com.google.web.bindery.event.shared.EventBus; 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.ide.api.editor.EditorInput; import org.eclipse.che.ide.api.editor.EditorWithAutoSave; import org.eclipse.che.ide.api.event.FileEvent; import org.eclipse.che.ide.api.event.ng.ClientServerEventService; import org.eclipse.che.ide.api.notification.NotificationManager; import org.eclipse.che.ide.api.resources.Container; import org.eclipse.che.ide.api.resources.File; import org.eclipse.che.ide.api.resources.Project; import org.eclipse.che.ide.api.resources.Resource; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.ext.java.client.JavaLocalizationConstant; import org.eclipse.che.ide.ext.java.client.refactoring.RefactoringUpdater; import org.eclipse.che.ide.ext.java.client.refactoring.rename.wizard.RenamePresenter; import org.eclipse.che.ide.ext.java.client.refactoring.service.RefactoringServiceClient; import org.eclipse.che.ide.ext.java.client.resource.SourceFolderMarker; import org.eclipse.che.ide.ext.java.shared.dto.LinkedModeModel; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.ChangeInfo; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.LinkedRenameRefactoringApply; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringResult; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatusEntry; import org.eclipse.che.ide.ext.java.shared.dto.refactoring.RenameRefactoringSession; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.api.editor.document.Document; import org.eclipse.che.ide.api.editor.link.HasLinkedMode; import org.eclipse.che.ide.api.editor.link.LinkedMode; import org.eclipse.che.ide.api.editor.link.LinkedModel; import org.eclipse.che.ide.api.editor.texteditor.TextEditor; import org.eclipse.che.ide.api.dialogs.CancelCallback; import org.eclipse.che.ide.api.dialogs.ConfirmCallback; import org.eclipse.che.ide.api.dialogs.DialogFactory; import org.eclipse.che.ide.api.dialogs.ConfirmDialog; import org.eclipse.che.ide.api.dialogs.MessageDialog; 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.Mockito; import org.mockito.runners.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.eclipse.che.ide.api.event.FileEvent.FileOperation.CLOSE; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.CreateRenameRefactoring.RenameType.JAVA_ELEMENT; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.ERROR; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.FATAL; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.INFO; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.OK; import static org.eclipse.che.ide.ext.java.shared.dto.refactoring.RefactoringStatus.WARNING; import static org.junit.Assert.assertFalse; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyList; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * @author Alexander Andrinko * @author Vlad Zhukovskyi */ @RunWith(MockitoJUnitRunner.class) public class JavaRefactoringRenameTest { private static final String NEW_JAVA_CLASS_NAME = "NewJavaTest.java"; private static final String SESSION_ID = "some session id"; private static final int CURSOR_OFFSET = 10; //variables for constructor @Mock private RenamePresenter renamePresenter; @Mock private JavaLocalizationConstant locale; @Mock private DialogFactory dialogFactory; @Mock private RefactoringServiceClient refactoringServiceClient; @Mock private DtoFactory dtoFactory; @Mock private RefactoringUpdater refactoringUpdater; @Mock private NotificationManager notificationManager; @Mock private ClientServerEventService clientServerEventService; @Mock private CreateRenameRefactoring createRenameRefactoringDto; @Mock private LinkedRenameRefactoringApply linkedRenameRefactoringApplyDto; @Mock(extraInterfaces = {HasLinkedMode.class, EditorWithAutoSave.class}) private TextEditor textEditor; @Mock private EditorInput editorInput; @Mock private File file; @Mock private Container srcFolder; @Mock private Project relatedProject; @Mock private Promise<RenameRefactoringSession> createRenamePromise; @Mock private RenameRefactoringSession session; @Mock private LinkedModeModel linkedModel; @Mock private Promise<RefactoringResult> applyModelPromise; @Mock private RefactoringResult result; @Mock private FileEvent fileEvent; @Mock private RefactoringStatusEntry entry; @Mock private LinkedMode linkedMode; @Mock private LinkedModel editorLinkedModel; @Mock private EventBus eventBus; @Mock private Document document; @Mock private Promise<Void> updateAfterRefactoringPromise; @Mock private Promise<Void> fileTrackingSuspendEventPromise; @Mock private Promise<Void> handleMovingFilesPromise; @Captor private ArgumentCaptor<Operation<RenameRefactoringSession>> renameRefCaptor; @Captor private ArgumentCaptor<LinkedMode.LinkedModeListener> inputArgumentCaptor; @Captor private ArgumentCaptor<Operation<RefactoringResult>> refactoringStatusCaptor; @Captor private ArgumentCaptor<Operation<PromiseError>> refactoringErrorCaptor; @Captor private ArgumentCaptor<Operation<Void>> clientServerSuspendOperation; @Captor private ArgumentCaptor<Operation<Void>> updateAfterRefactoringOperation; @InjectMocks private JavaRefactoringRename refactoringRename; @Before public void setUp() { when(dtoFactory.createDto(CreateRenameRefactoring.class)).thenReturn(createRenameRefactoringDto); when(dtoFactory.createDto(LinkedRenameRefactoringApply.class)).thenReturn(linkedRenameRefactoringApplyDto); when(textEditor.getEditorInput()).thenReturn(editorInput); when(editorInput.getFile()).thenReturn(file); when(file.getName()).thenReturn("A.java"); when(file.getExtension()).thenReturn("java"); when(file.getParentWithMarker(eq(SourceFolderMarker.ID))).thenReturn(Optional.of(srcFolder)); when(file.getLocation()).thenReturn(Path.valueOf("/project/src/a/b/c/A.java")); when(file.getResourceType()).thenReturn(Resource.FILE); when(srcFolder.getLocation()).thenReturn(Path.valueOf("/project/src")); when(file.getRelatedProject()).thenReturn(Optional.of(relatedProject)); when(relatedProject.getLocation()).thenReturn(Path.valueOf("/project")); when(refactoringServiceClient.createRenameRefactoring(createRenameRefactoringDto)).thenReturn(createRenamePromise); when(createRenamePromise.then((Operation<RenameRefactoringSession>)any())).thenReturn(createRenamePromise); when(applyModelPromise.then((Operation<RefactoringResult>)any())).thenReturn(applyModelPromise); when(session.getLinkedModeModel()).thenReturn(linkedModel); when(refactoringServiceClient.applyLinkedModeRename(linkedRenameRefactoringApplyDto)).thenReturn(applyModelPromise); when(textEditor.getCursorOffset()).thenReturn(CURSOR_OFFSET); when(document.getContentRange(anyInt(), anyInt())).thenReturn(NEW_JAVA_CLASS_NAME); when(((HasLinkedMode)textEditor).getLinkedMode()).thenReturn(linkedMode); when(((HasLinkedMode)textEditor).createLinkedModel()).thenReturn(editorLinkedModel); when(textEditor.getDocument()).thenReturn(document); when(document.getFile()).thenReturn(file); when(result.getEntries()).thenReturn(Collections.singletonList(entry)); when(clientServerEventService.sendFileTrackingSuspendEvent()).thenReturn(fileTrackingSuspendEventPromise); when(refactoringUpdater.handleMovingFiles(anyList())).thenReturn(handleMovingFilesPromise); when(refactoringUpdater.updateAfterRefactoring(anyList())).thenReturn(updateAfterRefactoringPromise); } @Test public void renameRefactoringShouldBeAppliedSuccess() throws OperationException { when(result.getSeverity()).thenReturn(OK); List<ChangeInfo> changes = new ArrayList<>(); when(result.getChanges()).thenReturn(changes); refactoringRename.refactor(textEditor); mainCheckRenameRefactoring(); verify(refactoringUpdater).updateAfterRefactoring(Matchers.<List<ChangeInfo>>any()); verify(eventBus).addHandler(FileEvent.TYPE, refactoringRename); verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); updateAfterRefactoringOperation.getValue().apply(null); verify(refactoringUpdater).handleMovingFiles(anyList()); verify(clientServerEventService).sendFileTrackingResumeEvent(); } @Test public void turnOffLinkedEditorModeWhenEditorIsClosed() throws Exception { when(fileEvent.getOperationType()).thenReturn(CLOSE); when(fileEvent.getFile()).thenReturn(file); refactoringRename.refactor(textEditor); refactoringRename.onFileOperation(fileEvent); assertFalse(refactoringRename.isActiveLinkedEditor()); } @Test public void renameRefactoringShouldBeAppliedSuccessAndShowWizard() throws OperationException { when(result.getSeverity()).thenReturn(OK); refactoringRename.refactor(textEditor); refactoringRename.refactor(textEditor); verify(refactoringServiceClient, times(2)).createRenameRefactoring(createRenameRefactoringDto); verify(createRenamePromise, times(2)).then(renameRefCaptor.capture()); renameRefCaptor.getValue().apply(session); verify(renamePresenter).show(session); } @Test public void renameRefactoringShouldBeShowErrorWindow() throws OperationException { PromiseError arg = Mockito.mock(PromiseError.class); MessageDialog dialog = Mockito.mock(MessageDialog.class); when(result.getSeverity()).thenReturn(OK); when(locale.renameRename()).thenReturn("renameTitle"); when(locale.renameOperationUnavailable()).thenReturn("renameBody"); when(dialogFactory.createMessageDialog(anyString(), anyString(), anyObject())).thenReturn(dialog); refactoringRename.refactor(textEditor); verify(createRenamePromise).then(renameRefCaptor.capture()); renameRefCaptor.getValue().apply(session); verify(createRenamePromise).catchError(refactoringErrorCaptor.capture()); refactoringErrorCaptor.getValue().apply(arg); verify(dialogFactory).createMessageDialog("renameTitle", "renameBody", null); verify(dialog).show(); } @Test public void renameRefactoringShouldBeFailedByFatalError() throws OperationException { when(result.getSeverity()).thenReturn(FATAL); refactoringRename.refactor(textEditor); mainCheckRenameRefactoring(); verify(result, times(1)).getSeverity(); verify(clientServerEventService).sendFileTrackingResumeEvent(); } @Test public void renameRefactoringShouldBeFailedByError() throws OperationException { ConfirmDialog confirmDialog = mock(ConfirmDialog.class); when(result.getSeverity()).thenReturn(ERROR); when(dialogFactory.createConfirmDialog(anyString(), anyString(), anyString(), anyString(), Matchers.<ConfirmCallback>anyObject(), Matchers.<CancelCallback>anyObject())).thenReturn(confirmDialog); refactoringRename.refactor(textEditor); verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); verify(createRenamePromise).then(renameRefCaptor.capture()); renameRefCaptor.getValue().apply(session); verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); clientServerSuspendOperation.getValue().apply(null); verify(linkedMode).addListener(inputArgumentCaptor.capture()); inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); verify(applyModelPromise).then(refactoringStatusCaptor.capture()); refactoringStatusCaptor.getValue().apply(result); verify(locale).warningOperationTitle(); verify(locale).renameWithWarnings(); verify(locale).showRenameWizard(); verify(locale).buttonCancel(); verify(dialogFactory).createConfirmDialog(anyString(), anyString(), anyString(), anyString(), Matchers.<ConfirmCallback>anyObject(), Matchers.<CancelCallback>anyObject()); verify(confirmDialog).show(); } @Test public void renameRefactoringShouldBeWithWarningOrErrorStatus() throws OperationException { ConfirmDialog confirmDialog = mock(ConfirmDialog.class); when(result.getSeverity()).thenReturn(WARNING); when(dialogFactory.createConfirmDialog(anyString(), anyString(), anyString(), anyString(), Matchers.<ConfirmCallback>anyObject(), Matchers.<CancelCallback>anyObject())).thenReturn(confirmDialog); refactoringRename.refactor(textEditor); verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); verify(createRenamePromise).then(renameRefCaptor.capture()); renameRefCaptor.getValue().apply(session); verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); clientServerSuspendOperation.getValue().apply(null); verify(linkedMode).addListener(inputArgumentCaptor.capture()); inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); verify(applyModelPromise).then(refactoringStatusCaptor.capture()); refactoringStatusCaptor.getValue().apply(result); verify(locale).warningOperationTitle(); verify(locale).renameWithWarnings(); verify(locale).showRenameWizard(); verify(locale).buttonCancel(); verify(dialogFactory).createConfirmDialog(anyString(), anyString(), anyString(), anyString(), Matchers.<ConfirmCallback>anyObject(), Matchers.<CancelCallback>anyObject()); verify(confirmDialog).show(); } @Test public void renameRefactoringShouldBeWithINFO() throws OperationException { when(result.getSeverity()).thenReturn(INFO); refactoringRename.refactor(textEditor); mainCheckRenameRefactoring(); verify(result).getSeverity(); verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); updateAfterRefactoringOperation.getValue().apply(null); verify(refactoringUpdater).handleMovingFiles(anyList()); verify(clientServerEventService).sendFileTrackingResumeEvent(); } @Test public void renameRefactoringShouldBeWithOK() throws OperationException { when(result.getSeverity()).thenReturn(OK); refactoringRename.refactor(textEditor); mainCheckRenameRefactoring(); verify(result).getSeverity(); verify(updateAfterRefactoringPromise).then(updateAfterRefactoringOperation.capture()); updateAfterRefactoringOperation.getValue().apply(null); verify(refactoringUpdater).handleMovingFiles(anyList()); verify(clientServerEventService).sendFileTrackingResumeEvent(); } private void mainCheckRenameRefactoring() throws OperationException { verify(dtoFactory).createDto(CreateRenameRefactoring.class); verify(textEditor).getCursorOffset(); verify(createRenameRefactoringDto).setOffset(CURSOR_OFFSET); verify(createRenameRefactoringDto).setRefactorLightweight(true); verify(textEditor).getEditorInput(); verify(editorInput).getFile(); verify(createRenameRefactoringDto).setPath(eq("a.b.c.A")); verify(createRenameRefactoringDto).setProjectPath(eq("/project")); verify(createRenameRefactoringDto).setProjectPath(eq("/project")); verify(createRenameRefactoringDto).setType(JAVA_ELEMENT); verify(refactoringServiceClient).createRenameRefactoring(createRenameRefactoringDto); verify(createRenamePromise).then(renameRefCaptor.capture()); renameRefCaptor.getValue().apply(session); verify(fileTrackingSuspendEventPromise).then(clientServerSuspendOperation.capture()); clientServerSuspendOperation.getValue().apply(null); verify(session).getLinkedModeModel(); verify(linkedMode).addListener(inputArgumentCaptor.capture()); inputArgumentCaptor.getValue().onLinkedModeExited(true, 0, 1); verify(dtoFactory).createDto(LinkedRenameRefactoringApply.class); linkedRenameRefactoringApplyDto.setNewName(NEW_JAVA_CLASS_NAME); linkedRenameRefactoringApplyDto.setSessionId(SESSION_ID); verify(refactoringServiceClient).applyLinkedModeRename(linkedRenameRefactoringApplyDto); verify(applyModelPromise).then(refactoringStatusCaptor.capture()); refactoringStatusCaptor.getValue().apply(result); } }