/*******************************************************************************
* Copyright (c) 2012-2016 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.extension.machine.client.perspective.widgets.recipe;
import com.google.gwtmockito.GwtMockitoTestRunner;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.api.machine.gwt.client.RecipeServiceClient;
import org.eclipse.che.api.machine.shared.dto.recipe.NewRecipe;
import org.eclipse.che.api.machine.shared.dto.recipe.RecipeDescriptor;
import org.eclipse.che.api.machine.shared.dto.recipe.RecipeUpdate;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.event.ActivePartChangedEvent;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.notification.StatusNotification;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant;
import org.eclipse.che.ide.extension.machine.client.MachineResources;
import org.eclipse.che.ide.extension.machine.client.perspective.widgets.recipe.container.RecipesContainerPresenter;
import org.eclipse.che.ide.extension.machine.client.perspective.widgets.recipe.editor.RecipeEditorPanel;
import org.eclipse.che.ide.extension.machine.client.perspective.widgets.recipe.editor.RecipeEditorView;
import org.eclipse.che.ide.extension.machine.client.perspective.widgets.recipe.entry.RecipeWidget;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.vectomatic.dom.svg.OMSVGSVGElement;
import org.vectomatic.dom.svg.ui.SVGResource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
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 Valeriy Svydenko
*/
@RunWith(GwtMockitoTestRunner.class)
public class RecipePartPresenterTest {
private static final String RECIPE_TYPE = "docker";
//constructor mocks
@Mock
private RecipePartView recipePartView;
@Mock(answer = RETURNS_DEEP_STUBS)
private MachineResources machineResources;
@Mock
private EventBus eventBus;
@Mock
private NotificationManager notificationManager;
@Mock
private RecipeServiceClient service;
@Mock
private MachineLocalizationConstant locale;
@Mock
private RecipesContainerPresenter recipesContainerPresenter;
@Mock
private DtoFactory dtoFactory;
//additional mocks
@Mock
private RecipeDescriptor recipeDescriptor1;
@Mock
private RecipeDescriptor recipeDescriptor2;
@Mock
private RecipeWidget recipeWidget;
@Mock
private RecipeEditorPanel recipeEditorPanel;
@Mock
private OMSVGSVGElement omsvgsvgElement;
@Mock
private SVGResource svgResource;
@Mock
RecipeEditorPanel stubPanel;
@Mock
private MachineResources.Css css;
@Mock
private Promise<List<RecipeDescriptor>> recipePromises;
@Mock
private Promise<RecipeDescriptor> recipeDescriptorPromise;
@Mock
private Promise<RecipeDescriptor> savedRecipeDescriptorPromise;
@Mock
private Promise<Void> deletePromise;
@Captor
private ArgumentCaptor<Operation<List<RecipeDescriptor>>> operationListDescriptorCaptor;
@Captor
private ArgumentCaptor<Operation<RecipeDescriptor>> operationDescriptorCaptor;
@Captor
private ArgumentCaptor<Operation<RecipeDescriptor>> savedDescriptorCaptor;
@Captor
private ArgumentCaptor<Operation<PromiseError>> operationErrorArgumentCaptor;
@Captor
private ArgumentCaptor<Operation<Void>> deleteCaptor;
RecipePartPresenter recipePartPresenter;
@Before
public void setUp() throws Exception {
when(machineResources.projectPerspective()).thenReturn(svgResource);
when(svgResource.getSvg()).thenReturn(omsvgsvgElement);
when(machineResources.getCss()).thenReturn(css);
when(machineResources.recipeTemplate().getText()).thenReturn("script");
when(recipesContainerPresenter.getEditorStubPanel()).thenReturn(stubPanel);
when(stubPanel.getName()).thenReturn("name");
recipePartPresenter = new RecipePartPresenter(recipePartView,
machineResources,
eventBus,
notificationManager,
locale,
recipesContainerPresenter,
dtoFactory,
service);
}
@Test
public void constructorShouldBePerform() throws Exception {
verify(recipePartView).setDelegate(recipePartPresenter);
verify(eventBus).addHandler(ActivePartChangedEvent.TYPE, recipePartPresenter);
}
@Test
public void recipesShouldBeShowed() throws Exception {
when(service.getAllRecipes()).thenReturn(recipePromises);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
recipePartPresenter.showRecipes();
verify(service).getAllRecipes();
verify(recipePromises).then(operationListDescriptorCaptor.capture());
operationListDescriptorCaptor.getValue().apply(Arrays.asList(recipeDescriptor1, recipeDescriptor2));
verify(recipePartView).clear();
verify(recipePartView, times(2)).addRecipe(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter, times(2)).addRecipePanel(Matchers.<RecipeWidget>any());
}
@Test
public void stubPanelShouldBeShowed() throws Exception {
RecipeEditorView recipeEditorView = mock(RecipeEditorView.class);
when(service.getAllRecipes()).thenReturn(recipePromises);
when(recipesContainerPresenter.getEditorStubPanel()).thenReturn(recipeEditorPanel);
when(recipeEditorPanel.getView()).thenReturn(recipeEditorView);
recipePartPresenter.showRecipes();
verify(service).getAllRecipes();
verify(recipePromises).then(operationListDescriptorCaptor.capture());
operationListDescriptorCaptor.getValue().apply(Collections.<RecipeDescriptor>emptyList());
verify(recipePartView).clear();
verify(recipesContainerPresenter).getEditorStubPanel();
verify(recipeEditorPanel).setDelegate(recipePartPresenter);
verify(recipesContainerPresenter).showEditorStubPanel();
verify(recipeEditorView).setName("");
}
@Test
public void firstRecipeShouldBeCreated() throws Exception {
NewRecipe newRecipe = mock(NewRecipe.class);
when(dtoFactory.createDto(NewRecipe.class)).thenReturn(newRecipe);
when(newRecipe.withType(anyString())).thenReturn(newRecipe);
when(newRecipe.withScript(anyString())).thenReturn(newRecipe);
when(newRecipe.withName(anyString())).thenReturn(newRecipe);
when(newRecipe.withTags(Matchers.<List<String>>any())).thenReturn(newRecipe);
when(service.createRecipe(newRecipe)).thenReturn(recipeDescriptorPromise);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
when(recipeEditorPanel.getName()).thenReturn("name");
recipePartPresenter.onNewButtonClicked();
verify(service).createRecipe(newRecipe);
verify(newRecipe).withType(RECIPE_TYPE);
verify(newRecipe).withScript("script");
verify(newRecipe).withName("name");
verify(stubPanel,times(2)).getName();
verify(stubPanel).getTags();
assertTrue(newRecipe.getTags().isEmpty());
verify(recipeDescriptorPromise).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
verify(recipePartView).addRecipe(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).addRecipePanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).showEditorPanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).getEditorPanel(Matchers.<RecipeWidget>any());
verify(recipeEditorPanel).setDelegate(recipePartPresenter);
}
@Test
public void secondRecipeShouldBeCreated() throws Exception {
NewRecipe newRecipe = mock(NewRecipe.class);
when(dtoFactory.createDto(NewRecipe.class)).thenReturn(newRecipe);
when(newRecipe.withType(anyString())).thenReturn(newRecipe);
when(newRecipe.withScript(anyString())).thenReturn(newRecipe);
when(newRecipe.withName(anyString())).thenReturn(newRecipe);
when(newRecipe.withTags(Matchers.<List<String>>any())).thenReturn(newRecipe);
when(service.createRecipe(newRecipe)).thenReturn(recipeDescriptorPromise);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
when(recipesContainerPresenter.getEditorStubPanel()).thenReturn(stubPanel);
recipePartPresenter.onNewButtonClicked();
verify(recipeDescriptorPromise).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
when(recipeDescriptor1.getName()).thenReturn("name");
recipePartPresenter.onCloneButtonClicked();
verify(recipeDescriptor1).getType();
verify(recipeDescriptor1).getScript();
verify(recipeDescriptor1).getTags();
verify(newRecipe).withType(RECIPE_TYPE);
verify(newRecipe).withScript("script");
verify(newRecipe).withName("name");
assertTrue(newRecipe.getTags().isEmpty());
verify(service, times(2)).createRecipe(newRecipe);
verify(recipeDescriptorPromise, times(2)).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
verify(recipePartView, times(2)).addRecipe(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter, times(2)).addRecipePanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter, times(2)).showEditorPanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter, times(2)).getEditorPanel(Matchers.<RecipeWidget>any());
verify(recipeEditorPanel, times(2)).setDelegate(recipePartPresenter);
}
@Test
public void recipeShouldBeDeleted() throws Exception {
NewRecipe newRecipe = mock(NewRecipe.class);
when(dtoFactory.createDto(NewRecipe.class)).thenReturn(newRecipe);
when(newRecipe.withType(anyString())).thenReturn(newRecipe);
when(newRecipe.withScript(anyString())).thenReturn(newRecipe);
when(newRecipe.withName(anyString())).thenReturn(newRecipe);
when(newRecipe.withTags(Matchers.<List<String>>any())).thenReturn(newRecipe);
when(service.createRecipe(newRecipe)).thenReturn(recipeDescriptorPromise);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
when(recipeDescriptor1.getId()).thenReturn("id");
when(service.removeRecipe(anyString())).thenReturn(deletePromise);
recipePartPresenter.onNewButtonClicked();
verify(recipeDescriptorPromise).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
recipePartPresenter.onDeleteButtonClicked();
verify(deletePromise).then(deleteCaptor.capture());
}
@Test
public void recipeShouldBeSaved() throws Exception {
NewRecipe newRecipe = mock(NewRecipe.class);
List<String> tags = Collections.singletonList("tag");
when(dtoFactory.createDto(NewRecipe.class)).thenReturn(newRecipe);
when(newRecipe.withType(anyString())).thenReturn(newRecipe);
when(newRecipe.withScript(anyString())).thenReturn(newRecipe);
when(newRecipe.withName(anyString())).thenReturn(newRecipe);
when(newRecipe.withTags(Matchers.<List<String>>any())).thenReturn(newRecipe);
when(service.createRecipe(newRecipe)).thenReturn(recipeDescriptorPromise);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
RecipeUpdate recipeUpdate = mock(RecipeUpdate.class);
when(dtoFactory.createDto(RecipeUpdate.class)).thenReturn(recipeUpdate);
when(recipeUpdate.withType(anyString())).thenReturn(recipeUpdate);
when(recipeUpdate.withId(anyString())).thenReturn(recipeUpdate);
when(recipeUpdate.withScript(anyString())).thenReturn(recipeUpdate);
when(recipeUpdate.withName(anyString())).thenReturn(recipeUpdate);
when(recipeUpdate.withTags(Matchers.<List<String>>any())).thenReturn(recipeUpdate);
when(recipeDescriptor1.getId()).thenReturn("id");
when(recipeDescriptor1.getName()).thenReturn("name");
when(recipeDescriptor1.getScript()).thenReturn("script");
when(recipeDescriptor1.getTags()).thenReturn(tags);
when(service.updateRecipe(recipeUpdate)).thenReturn(savedRecipeDescriptorPromise);
when(recipeDescriptor1.getType()).thenReturn(RECIPE_TYPE);
when(recipeEditorPanel.getScript()).thenReturn("script");
when(recipeEditorPanel.getTags()).thenReturn(tags);
when(recipeEditorPanel.getName()).thenReturn("name");
recipePartPresenter.onNewButtonClicked();
verify(recipeDescriptorPromise).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
recipePartPresenter.onSaveButtonClicked();
verify(service).updateRecipe(recipeUpdate);
verify(savedRecipeDescriptorPromise).then(savedDescriptorCaptor.capture());
savedDescriptorCaptor.getValue().apply(recipeDescriptor1);
verify(recipeDescriptor1).setScript("script");
verify(recipeDescriptor1).setTags(recipeDescriptor1.getTags());
verify(notificationManager).notify(eq("Recipe \"name\" was saved."));
}
@Test
public void titleShouldBeReturned() throws Exception {
recipePartPresenter.getTitle();
verify(locale).viewRecipePanelTitle();
}
@Test
public void panelShouldBeHidden() throws Exception {
recipePartPresenter.setVisible(false);
verify(recipePartView).setVisible(false);
}
@Test
public void toolTipShouldBeShowed() throws Exception {
recipePartPresenter.getTitleToolTip();
verify(locale).viewRecipePanelTooltip();
}
@Test
public void panelShouldBeShowedWhenPartIsActivated() throws Exception {
ActivePartChangedEvent event = mock(ActivePartChangedEvent.class);
when(event.getActivePart()).thenReturn(recipePartPresenter);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
recipePartPresenter.onActivePartChanged(event);
verify(recipeEditorPanel).setDelegate(recipePartPresenter);
}
@Test
public void notificationShouldBeShowedWhenCreationIsFailed() throws Exception {
NewRecipe newRecipe = mock(NewRecipe.class);
when(dtoFactory.createDto(NewRecipe.class)).thenReturn(newRecipe);
when(newRecipe.withType(anyString())).thenReturn(newRecipe);
when(newRecipe.withScript(anyString())).thenReturn(newRecipe);
when(newRecipe.withName(anyString())).thenReturn(newRecipe);
when(newRecipe.withTags(Matchers.<List<String>>any())).thenReturn(newRecipe);
when(service.createRecipe(newRecipe)).thenReturn(recipeDescriptorPromise);
when(recipesContainerPresenter.getEditorPanel(Matchers.<RecipeWidget>any())).thenReturn(recipeEditorPanel);
when(recipeEditorPanel.getName()).thenReturn("name");
recipePartPresenter.onNewButtonClicked();
verify(service).createRecipe(newRecipe);
verify(newRecipe).withType(RECIPE_TYPE);
verify(newRecipe).withScript("script");
verify(newRecipe).withName("name");
verify(stubPanel,times(2)).getName();
verify(stubPanel).getTags();
assertTrue(newRecipe.getTags().isEmpty());
verify(recipeDescriptorPromise).then(operationDescriptorCaptor.capture());
operationDescriptorCaptor.getValue().apply(recipeDescriptor1);
verify(recipePartView).addRecipe(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).addRecipePanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).showEditorPanel(Matchers.<RecipeWidget>any());
verify(recipesContainerPresenter).getEditorPanel(Matchers.<RecipeWidget>any());
verify(recipeEditorPanel).setDelegate(recipePartPresenter);
PromiseError promiseError = mock(PromiseError.class);
when(promiseError.getMessage()).thenReturn("text");
verify(recipeDescriptorPromise).catchError(operationErrorArgumentCaptor.capture());
operationErrorArgumentCaptor.getValue().apply(promiseError);
verify(notificationManager).notify(anyString(), anyString(), any(StatusNotification.Status.class), anyBoolean());
}
}