blob: f552625d0bafb4ce34bff9ab8ee874995e979636 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2018 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Lucas Koehler - initial API and implementation
******************************************************************************/
package org.eclipse.emfforms.internal.core.services.datatemplate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecp.view.test.common.swt.spi.SWTTestUtil;
import org.eclipse.emfforms.common.Optional;
import org.eclipse.emfforms.core.services.datatemplate.test.model.audit.AuditPackage;
import org.eclipse.emfforms.datatemplate.DataTemplateFactory;
import org.eclipse.emfforms.datatemplate.Template;
import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.osgi.framework.Bundle;
/**
* Plugin tests for the {@link SelectSubclassAndTemplateWizard}.
* <p>
* <strong>Note:</strong> The wizard itself would be unit testable but the used selection composites use the
* LocalizationServiceHelper which only works in a Plugin execution context.
*
* @author Lucas Koehler
*
*/
public class SelectSubclassAndTemplateWizard_PTest {
private EMFFormsLocalizationService localizationService;
private Shell shell;
/**
* @throws SWTException if the Shell cannot be instantiated
*/
@Before
public void setUp() throws SWTException {
localizationService = mock(EMFFormsLocalizationService.class);
when(localizationService.getString(any(Class.class), any(String.class))).thenReturn(""); //$NON-NLS-1$
when(localizationService.getString(any(Bundle.class), any(String.class))).thenAnswer(
new Answer<String>() {
@SuppressWarnings("nls")
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
final String key = (String) invocation.getArguments()[1];
if ("_UI_AbstractSubUser_type".equals(key)) {
return "Abstract Sub User";
}
if ("_UI_AdminUser_type".equals(key)) {
return "Admin User";
}
if ("_UI_GuestUser_type".equals(key)) {
return "Guest User";
}
if ("_UI_PrivilegedUser_type".equals(key)) {
return "Privileged User";
}
if ("_UI_RegisteredUser_type".equals(key)) {
return "Registered User";
}
if ("_UI_UserGroup_type".equals(key)) {
return "User Group";
}
if ("_UI_User_type".equals(key)) {
return "User";
}
return "";
}
});
shell = new Shell();
}
@After
public void tearDown() {
shell.dispose();
}
/**
* Tests the standard use case: first selecting an EClass and then a template on the next page.
*/
@Test
public void testSubClassAndTemplateSelection() {
// Add selectable EClasses
final LinkedHashSet<EClass> subClasses = new LinkedHashSet<EClass>();
subClasses.add(AuditPackage.eINSTANCE.getAdminUser());
subClasses.add(AuditPackage.eINSTANCE.getRegisteredUser());
// Configure templates
final Template template1 = createTemplate("AdminTemplate1", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template template2 = createTemplate("RegisteredUserTemplate1", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final Template template3 = createTemplate("RegisteredUserTemplate2", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final LinkedHashSet<Template> templates = new LinkedHashSet<Template>();
templates.add(template1);
templates.add(template2);
templates.add(template3);
// Create and open wizard
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("Wizard", subClasses, //$NON-NLS-1$
templates, localizationService);
final WizardDialog wizardDialog = openWizardDialog(wizard);
// Get the wizard dialog's shell from our parent shell
final Shell wizardShell = shell.getShells()[0];
final Composite dialogComposite = (Composite) Composite.class.cast(wizardShell.getChildren()[0])
.getChildren()[0];
// Get wizard buttons
final Composite buttonComposite = getButtonComposite(wizardDialog);
final Composite innerButtonComposite = (Composite) buttonComposite.getChildren()[0];
final Button backButton = (Button) innerButtonComposite.getChildren()[0];
final Button nextButton = (Button) innerButtonComposite.getChildren()[1];
final Button cancelButton = (Button) buttonComposite.getChildren()[1];
final Button finishButton = (Button) buttonComposite.getChildren()[2];
// Get the composites containing the wizard pages
final Composite pagesComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[0])
.getChildren()[1];
final Composite subClassPageComposite = (Composite) pagesComposite.getChildren()[0];
final Composite templateSelectionPageComposite = (Composite) pagesComposite.getChildren()[1];
final Tree subClassTable = (Tree) subClassPageComposite.getChildren()[2];
assertEquals(2, subClassTable.getItemCount());
// Select the registered user class
final TreeItem item = SWTTestUtil.selectTreeItem(subClassTable, 1);
SWTTestUtil.waitForUIThread();
assertEquals("RegisteredUser", item.getText()); //$NON-NLS-1$
// verify button enablement
assertFalse(backButton.isEnabled());
assertTrue(nextButton.isEnabled());
assertTrue(cancelButton.isEnabled());
assertFalse(finishButton.isEnabled());
// click next button and wait for next page
SWTTestUtil.clickButton(nextButton);
SWTTestUtil.waitForUIThread();
final Table templateTable = (Table) templateSelectionPageComposite.getChildren()[2];
// Next button must not be enabled on final page
assertFalse(nextButton.isEnabled());
// the two templates for the registered user
assertEquals(2, templateTable.getItemCount());
SWTTestUtil.selectTableItem(templateTable, 0);
SWTTestUtil.waitForUIThread();
// Finish
SWTTestUtil.clickButton(finishButton);
SWTTestUtil.waitForUIThread();
// Evaluate wizard result
assertEquals(Window.OK, wizardDialog.getReturnCode());
final Optional<Template> templateOptional = wizard.getSelectedTemplate();
assertTrue(templateOptional.isPresent());
assertEquals(template2, templateOptional.get());
}
/**
* Test that the sub class selection page is skipped if there is only one selectable {@link EClass}.
*/
@Test
public void testTemplateSelectionOnly() {
// Only add one sub class
final LinkedHashSet<EClass> subClasses = new LinkedHashSet<EClass>();
subClasses.add(AuditPackage.eINSTANCE.getRegisteredUser());
// Configure templates
final Template template1 = createTemplate("AdminTemplate1", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template template2 = createTemplate("RegisteredUserTemplate1", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final Template template3 = createTemplate("RegisteredUserTemplate2", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final LinkedHashSet<Template> templates = new LinkedHashSet<Template>();
templates.add(template1);
templates.add(template2);
templates.add(template3);
// Create and open wizard
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("Wizard", subClasses, //$NON-NLS-1$
templates, localizationService);
final WizardDialog wizardDialog = openWizardDialog(wizard);
// Get the wizard dialog's shell from our parent shell
final Shell wizardShell = shell.getShells()[0];
final Composite dialogComposite = (Composite) Composite.class.cast(wizardShell.getChildren()[0])
.getChildren()[0];
// Get wizard buttons
// final Composite buttonComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[1])
// .getChildren()[0];
final Composite buttonComposite = getButtonComposite(wizardDialog);
final Button cancelButton = (Button) buttonComposite.getChildren()[0];
final Button finishButton = (Button) buttonComposite.getChildren()[1];
// Get the composites containing the template selection page
final Composite pagesComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[0])
.getChildren()[1];
final Composite templateSelectionPageComposite = (Composite) pagesComposite.getChildren()[0];
// Verify that the wizard starts at the template selection page
assertTrue(wizardDialog.getCurrentPage() instanceof SelectSubclassAndTemplateWizard.TemplateSelectionPage);
SWTTestUtil.waitForUIThread();
assertTrue(cancelButton.isEnabled());
assertFalse(finishButton.isEnabled());
final Table templateTable = (Table) templateSelectionPageComposite.getChildren()[2];
assertEquals(2, templateTable.getItemCount());
SWTTestUtil.selectTableItem(templateTable, 0);
SWTTestUtil.waitForUIThread();
// Finish
assertTrue(finishButton.isEnabled());
SWTTestUtil.clickButton(finishButton);
SWTTestUtil.waitForUIThread();
// Evaluate wizard result
assertEquals(Window.OK, wizardDialog.getReturnCode());
final Optional<Template> templateOptional = wizard.getSelectedTemplate();
assertTrue(templateOptional.isPresent());
assertEquals(template2, templateOptional.get());
}
/**
* Tests that the template selection page is not shown if there is only one template for the selected EClass.
*/
@Test
public void testSubClassSelectionOnly() {
// Add selectable EClasses
final LinkedHashSet<EClass> subClasses = new LinkedHashSet<EClass>();
subClasses.add(AuditPackage.eINSTANCE.getAdminUser());
subClasses.add(AuditPackage.eINSTANCE.getGuestUser());
// Configure templates
final Template template1 = createTemplate("AdminTemplate1", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template template2 = createTemplate("GuestUserTemplate1", AuditPackage.eINSTANCE.getGuestUser()); //$NON-NLS-1$
final LinkedHashSet<Template> templates = new LinkedHashSet<Template>();
templates.add(template1);
templates.add(template2);
// Create and open wizard
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("Wizard", subClasses, //$NON-NLS-1$
templates, localizationService);
final WizardDialog wizardDialog = openWizardDialog(wizard);
SWTTestUtil.waitForUIThread();
// Get the wizard dialog's shell from our parent shell
final Shell wizardShell = shell.getShells()[0];
final Composite dialogComposite = (Composite) Composite.class.cast(wizardShell.getChildren()[0])
.getChildren()[0];
// Get wizard buttons
final Composite buttonComposite = getButtonComposite(wizardDialog);
final Composite innerButtonComposite = (Composite) buttonComposite.getChildren()[0];
final Button backButton = (Button) innerButtonComposite.getChildren()[0];
final Button nextButton = (Button) innerButtonComposite.getChildren()[1];
final Button cancelButton = (Button) buttonComposite.getChildren()[1];
final Button finishButton = (Button) buttonComposite.getChildren()[2];
// Get the composites containing the wizard pages
final Composite pagesComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[0])
.getChildren()[1];
final Composite subClassPageComposite = (Composite) pagesComposite.getChildren()[0];
final Tree subClassTree = (Tree) subClassPageComposite.getChildren()[2];
assertEquals(2, subClassTree.getItemCount());
// Select the guest user class
final TreeItem item = SWTTestUtil.selectTreeItem(subClassTree, 1);
SWTTestUtil.waitForUIThread();
assertEquals("GuestUser", item.getText()); //$NON-NLS-1$
// Because there is only one template for the guest user EClass the wizard should offer to finish directly but
// not to go to the template selection page
assertFalse(backButton.isEnabled());
assertFalse(nextButton.isEnabled());
assertTrue(cancelButton.isEnabled());
assertTrue(finishButton.isEnabled());
// Finish
SWTTestUtil.clickButton(finishButton);
SWTTestUtil.waitForUIThread();
// Evaluate wizard result
assertEquals(Window.OK, wizardDialog.getReturnCode());
final Optional<Template> templateOptional = wizard.getSelectedTemplate();
assertTrue(templateOptional.isPresent());
assertEquals(template2, templateOptional.get());
}
/**
* Tests that the template selection table gets updated correctly after the back functionality of the wizard was
* used.
*/
@Test
public void testBackButton() {
// Add selectable EClasses
final LinkedHashSet<EClass> subClasses = new LinkedHashSet<EClass>();
subClasses.add(AuditPackage.eINSTANCE.getAdminUser());
subClasses.add(AuditPackage.eINSTANCE.getGuestUser());
// Configure 2 templates for each EClass
final Template adminTemplate1 = createTemplate("AdminTemplate1", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template adminTemplate2 = createTemplate("AdminTemplate2", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template guestTemplate1 = createTemplate("GuestUserTemplate1", AuditPackage.eINSTANCE.getGuestUser()); //$NON-NLS-1$
final Template guestTemplate2 = createTemplate("GuestUserTemplate2", AuditPackage.eINSTANCE.getGuestUser()); //$NON-NLS-1$
final LinkedHashSet<Template> templates = new LinkedHashSet<Template>();
templates.add(adminTemplate1);
templates.add(adminTemplate2);
templates.add(guestTemplate1);
templates.add(guestTemplate2);
// Create and open wizard
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("Wizard", subClasses, //$NON-NLS-1$
templates, localizationService);
final WizardDialog wizardDialog = openWizardDialog(wizard);
// Get the wizard dialog's shell from our parent shell
final Shell wizardShell = shell.getShells()[0];
final Composite dialogComposite = (Composite) Composite.class.cast(wizardShell.getChildren()[0])
.getChildren()[0];
// Get wizard buttons
final Composite buttonComposite = getButtonComposite(wizardDialog);
final Composite innerButtonComposite = (Composite) buttonComposite.getChildren()[0];
final Button backButton = (Button) innerButtonComposite.getChildren()[0];
final Button nextButton = (Button) innerButtonComposite.getChildren()[1];
// final Button cancelButton = (Button) buttonComposite.getChildren()[1];
final Button finishButton = (Button) buttonComposite.getChildren()[2];
// Get the composites containing the wizard pages
final Composite pagesComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[0])
.getChildren()[1];
final Composite subClassPageComposite = (Composite) pagesComposite.getChildren()[0];
final Composite templateSelectionPageComposite = (Composite) pagesComposite.getChildren()[1];
final Tree subClassTable = (Tree) subClassPageComposite.getChildren()[2];
assertEquals(2, subClassTable.getItemCount());
// Select the admin user class
SWTTestUtil.selectTreeItem(subClassTable, 0);
SWTTestUtil.waitForUIThread();
// Next
SWTTestUtil.clickButton(nextButton);
SWTTestUtil.waitForUIThread();
final Table templateTable = (Table) templateSelectionPageComposite.getChildren()[2];
assertEquals(2, templateTable.getItemCount());
assertTrue(templateTable.getItem(0).getText().contains("AdminTemplate1")); //$NON-NLS-1$
assertTrue(templateTable.getItem(1).getText().contains("AdminTemplate2")); //$NON-NLS-1$
// Go back
SWTTestUtil.waitForUIThread();
SWTTestUtil.clickButton(backButton);
// Select guest user class and click next again
SWTTestUtil.selectTreeItem(subClassTable, 1);
SWTTestUtil.waitForUIThread();
assertTrue(nextButton.isEnabled());
SWTTestUtil.clickButton(nextButton);
SWTTestUtil.waitForUIThread();
// Verify that the template selection table was updated correctly
assertEquals(2, templateTable.getItemCount());
assertTrue(templateTable.getItem(0).getText().contains("GuestUserTemplate1")); //$NON-NLS-1$
assertTrue(templateTable.getItem(1).getText().contains("GuestUserTemplate2")); //$NON-NLS-1$
SWTTestUtil.selectTableItem(templateTable, 1);
SWTTestUtil.clickButton(finishButton);
SWTTestUtil.waitForUIThread();
// Evaluate wizard result
assertEquals(Window.OK, wizardDialog.getReturnCode());
final Optional<Template> templateOptional = wizard.getSelectedTemplate();
assertTrue(templateOptional.isPresent());
assertEquals(guestTemplate2, templateOptional.get());
}
/**
* If the wizard is cancelled it should return an empty Optional as a result even if a template was selected by the
* user.
*/
@Test
public void testCancel() {
// Only add one sub class
final LinkedHashSet<EClass> subClasses = new LinkedHashSet<EClass>();
subClasses.add(AuditPackage.eINSTANCE.getRegisteredUser());
// Configure templates
final Template template1 = createTemplate("AdminTemplate1", AuditPackage.eINSTANCE.getAdminUser()); //$NON-NLS-1$
final Template template2 = createTemplate("RegisteredUserTemplate1", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final Template template3 = createTemplate("RegisteredUserTemplate2", //$NON-NLS-1$
AuditPackage.eINSTANCE.getRegisteredUser());
final LinkedHashSet<Template> templates = new LinkedHashSet<Template>();
templates.add(template1);
templates.add(template2);
templates.add(template3);
// Create and open wizard
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("Wizard", subClasses, //$NON-NLS-1$
templates, localizationService);
final WizardDialog wizardDialog = openWizardDialog(wizard);
// Get the wizard dialog's shell from our parent shell
final Shell wizardShell = shell.getShells()[0];
final Composite dialogComposite = (Composite) Composite.class.cast(wizardShell.getChildren()[0])
.getChildren()[0];
// Get wizard buttons
final Composite buttonComposite = getButtonComposite(wizardDialog);
final Button cancelButton = (Button) buttonComposite.getChildren()[0];
final Button finishButton = (Button) buttonComposite.getChildren()[1];
// Get the composites containing the template selection page
final Composite pagesComposite = (Composite) Composite.class.cast(dialogComposite.getChildren()[0])
.getChildren()[1];
final Composite templateSelectionPageComposite = (Composite) pagesComposite.getChildren()[0];
// Verify that the wizard starts at the template selection page
assertTrue(wizardDialog.getCurrentPage() instanceof SelectSubclassAndTemplateWizard.TemplateSelectionPage);
assertTrue(cancelButton.isEnabled());
assertFalse(finishButton.isEnabled());
final Table templateTable = (Table) templateSelectionPageComposite.getChildren()[2];
// Select a template
assertEquals(2, templateTable.getItemCount());
SWTTestUtil.selectTableItem(templateTable, 0);
SWTTestUtil.waitForUIThread();
// Cancel after a template was selected
assertTrue(cancelButton.isEnabled());
SWTTestUtil.clickButton(cancelButton);
SWTTestUtil.waitForUIThread();
// Evaluate wizard result: the result Optional should be empty
assertEquals(Window.CANCEL, wizardDialog.getReturnCode());
final Optional<Template> templateOptional = wizard.getSelectedTemplate();
assertFalse(templateOptional.isPresent());
}
@Test
public void testGetAvailableTemplates() {
final Set<EClass> subClasses = Collections.emptySet();
final Set<Template> templates = new LinkedHashSet<Template>();
// corupt eclass
final Template templateInvalid = mock(Template.class);
final EObject templateInstanceInvalid = mock(EObject.class);
when(templateInvalid.getInstance()).thenReturn(templateInstanceInvalid);
when(templateInstanceInvalid.eClass()).thenThrow(new IllegalArgumentException());
templates.add(templateInvalid);
// valid template
final Template templateValid = mock(Template.class);
final EObject templateInstanceValid = mock(EObject.class);
when(templateValid.getInstance()).thenReturn(templateInstanceValid);
when(templateInstanceValid.eClass()).thenReturn(EcorePackage.eINSTANCE.getEAttribute());
templates.add(templateValid);
final SelectSubclassAndTemplateWizard wizard = new SelectSubclassAndTemplateWizard("", subClasses, templates, //$NON-NLS-1$
localizationService);
final Set<Template> filteredTemplates = wizard.getAvailableTemplates(EcorePackage.eINSTANCE.getEAttribute());
assertEquals(1, filteredTemplates.size());
assertEquals(templateValid, filteredTemplates.iterator().next());
}
/**
* Gets the button composite containing the cancel, finish, and sometimes the back and next buttons.
*
* @param wizardDialog The {@link WizardDialog} to get the button composite from
* @return The {@link Composite} containing the wizard's buttons
*/
private Composite getButtonComposite(final WizardDialog wizardDialog) {
final Composite buttonBar = (Composite) wizardDialog.buttonBar;
// take the second as the first is a toolbar with help entries
final Composite buttonComposite = (Composite) buttonBar.getChildren()[1];
return buttonComposite;
}
/**
* Open the wizard in a wizard dialog and wait for the UI to finish opening it.
*
* @param wizard The wizard to open
* @return The opened {@link WizardDialog}
*/
private WizardDialog openWizardDialog(final Wizard wizard) {
final WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizardDialog.setBlockOnOpen(false);
wizardDialog.open();
SWTTestUtil.waitForUIThread();
return wizardDialog;
}
/**
* Creates a new {@link Template} with the given name and an instance of the given {@link EClass}
*
* @param name The template's name
* @param instanceClass The instance's type
* @return The created {@link Template}
*/
private Template createTemplate(String name, EClass instanceClass) {
final Template template = DataTemplateFactory.eINSTANCE.createTemplate();
template.setName(name);
final EObject instance = instanceClass.getEPackage().getEFactoryInstance().create(instanceClass);
template.setInstance(instance);
return template;
}
}