diff --git a/ear/.gitignore b/ear/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d --- /dev/null +++ b/ear/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/ear/pom.xml b/ear/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ae65dca33ab5011e657eddccfbfa0a8466e8a0ec --- /dev/null +++ b/ear/pom.xml @@ -0,0 +1,52 @@ + + 4.0.0 + + es.uvigo.esei.xcs + sample + 0.0.1-SNAPSHOT + + ear + ear + + EAR + XCS Sample - EAR + + + + es.uvigo.esei.xcs + domain + + + es.uvigo.esei.xcs + service + ${project.version} + ejb + + + es.uvigo.esei.xcs + rest + ${project.version} + war + + + es.uvigo.esei.xcs + jsf + ${project.version} + war + + + + + + + org.apache.maven.plugins + maven-ear-plugin + + lib/ + true + + + + + diff --git a/jsf/.gitignore b/jsf/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d --- /dev/null +++ b/jsf/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/jsf/pom.xml b/jsf/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..c6ebde49aaab56b87d9b50e324bf75bebd01cef7 --- /dev/null +++ b/jsf/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + es.uvigo.esei.xcs + sample + 0.0.1-SNAPSHOT + + jsf + war + + JSF + XCS Sample - JSF + + + + + javax + javaee-api + provided + + + es.uvigo.esei.xcs + service + provided + + + + + es.uvigo.esei.xcs + tests + test + + + junit + junit + test + + + org.hamcrest + java-hamcrest + test + + + org.easymock + easymock + test + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + org.jboss.arquillian.extension + arquillian-persistence-dbunit + test + + + org.jboss.arquillian.graphene + graphene-webdriver + pom + test + + + \ No newline at end of file diff --git a/jsf/scripts/deploy-mysql-ds.cli b/jsf/scripts/deploy-mysql-ds.cli new file mode 100644 index 0000000000000000000000000000000000000000..e6d975e3dc150962701057230181955fbcf60554 --- /dev/null +++ b/jsf/scripts/deploy-mysql-ds.cli @@ -0,0 +1,15 @@ +# Connect to Wildfly instance +connect + +# Create Oracle JDBC Driver Module +# If the module already exists, Wildfly will output a message saying that the module already exists and the script exits. +module add \ + --name=org.postgre \ + --resources=${settings.localRepository}/org/postgresql/postgresql/9.3-1102-jdbc41/postgresql-9.3-1102-jdbc41.jar \ + --dependencies=javax.api,javax.transaction.api + +# Add Driver Properties +/subsystem=datasources/jdbc-driver=postgre: \ + add( \ + driver-name="postgre", \ + driver-module-name="org.postgre") \ No newline at end of file diff --git a/jsf/src/main/java/es/uvigo/esei/xcs/jsf/LoginManagedBean.java b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/LoginManagedBean.java new file mode 100644 index 0000000000000000000000000000000000000000..34a00007d4a0f00ad747b59369d0cbb97fb109f3 --- /dev/null +++ b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/LoginManagedBean.java @@ -0,0 +1,103 @@ +package es.uvigo.esei.xcs.jsf; + +import java.security.Principal; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.RequestScoped; +import javax.faces.context.FacesContext; +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +@ManagedBean(name = "login") +@RequestScoped +public class LoginManagedBean { + @Inject + private Principal currentUserPrincipal; + + @Inject + private HttpServletRequest request; + + private String login; + private String password; + + private boolean error = false; + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isError() { + return error; + } + + public String doLogin() { + try { + request.login(this.getLogin(), this.getPassword()); + this.error = false; + + if (this.isAdmin()) { + return redirectTo(this.getAdminViewId()); + } else if (this.isOwner()) { + return redirectTo(this.getOwnerViewId()); + } else { + return redirectTo(this.getViewId()); + } + } catch (ServletException e) { + this.error = true; + + return this.getViewId(); + } + } + + public String doLogout() throws ServletException { + request.logout(); + + return redirectTo("/index.xhtml"); + } + + public Principal getCurrentUser() { + return this.currentUserPrincipal; + } + + private String redirectTo(String url) { + return url + "?faces-redirect=true"; + } + + private String getViewId() { + return FacesContext.getCurrentInstance().getViewRoot().getViewId(); + } + + private String getOwnerViewId() { + return "/owner/pets.xhtml"; + } + + private String getAdminViewId() { + return "/admin/owners.xhtml"; + } + + private boolean isAdmin() { + return this.isUserInRole("ADMIN"); + } + + private boolean isOwner() { + return this.isUserInRole("OWNER"); + } + + private boolean isUserInRole(String role) { + return FacesContext.getCurrentInstance().getExternalContext() + .isUserInRole(role); + } +} \ No newline at end of file diff --git a/jsf/src/main/java/es/uvigo/esei/xcs/jsf/OwnerManagerdBean.java b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/OwnerManagerdBean.java new file mode 100644 index 0000000000000000000000000000000000000000..0fbe39e5af5eaf863a44363aa8071ae6502cd1db --- /dev/null +++ b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/OwnerManagerdBean.java @@ -0,0 +1,120 @@ +package es.uvigo.esei.xcs.jsf; + +import static java.util.stream.Collectors.joining; + +import java.util.List; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.SessionScoped; +import javax.faces.context.FacesContext; +import javax.inject.Inject; + +import es.uvigo.esei.xcs.domain.entities.Owner; +import es.uvigo.esei.xcs.domain.entities.Pet; +import es.uvigo.esei.xcs.service.OwnerService; + +@ManagedBean(name = "owner") +@SessionScoped +public class OwnerManagerdBean { + @Inject + private OwnerService service; + + private String login; + private String password; + + private Owner currentOwner; + + private String errorMessage; + + public String getLogin() { + return login; + } + + public void setLogin(String name) { + this.login = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getErrorMessage() { + return errorMessage; + } + + public boolean isError() { + return this.errorMessage != null; + } + + public boolean isEditing() { + return this.currentOwner != null; + } + + public List getOwners() { + return this.service.list(); + } + + public String getPetNames(String login) { + return this.service.getPets(login).stream() + .map(Pet::getName) + .collect(joining(", ")); + } + + public String edit(Owner owner) { + this.currentOwner = owner; + this.login = this.currentOwner.getLogin(); + + return this.getViewId(); + } + + public String cancelEditing() { + this.clear(); + + return this.getViewId(); + } + + public String remove(String login) { + this.service.remove(login); + + return redirectTo(this.getViewId()); + } + + public String store() { + try { + if (this.isEditing()) { + this.currentOwner.changePassword(this.password); + + this.service.update(this.currentOwner); + } else { + this.service.create(new Owner(login, password)); + } + + this.clear(); + + return redirectTo(this.getViewId()); + } catch (Throwable t) { + this.errorMessage = t.getMessage(); + + return this.getViewId(); + } + } + + private void clear() { + this.login = null; + this.password = null; + this.errorMessage = null; + this.currentOwner = null; + } + + private String redirectTo(String url) { + return url + "?faces-redirect=true"; + } + + private String getViewId() { + return FacesContext.getCurrentInstance().getViewRoot().getViewId(); + } +} diff --git a/jsf/src/main/java/es/uvigo/esei/xcs/jsf/PetManagedBean.java b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/PetManagedBean.java new file mode 100644 index 0000000000000000000000000000000000000000..ae2760db853a17db17d37f8fcdf5cbcab1fffb78 --- /dev/null +++ b/jsf/src/main/java/es/uvigo/esei/xcs/jsf/PetManagedBean.java @@ -0,0 +1,130 @@ +package es.uvigo.esei.xcs.jsf; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.SessionScoped; +import javax.faces.context.FacesContext; +import javax.inject.Inject; + +import es.uvigo.esei.xcs.domain.entities.AnimalType; +import es.uvigo.esei.xcs.domain.entities.Pet; +import es.uvigo.esei.xcs.service.PetService; + +@ManagedBean(name = "pet") +@SessionScoped +public class PetManagedBean { + @Inject + private PetService service; + + private String name; + private Date birth; + private AnimalType animal; + + private Pet currentPet; + + private String errorMessage; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getBirth() { + return birth; + } + + public void setBirth(Date birth) { + this.birth = birth; + } + + public String getAnimal() { + return Optional.ofNullable(this.animal) + .map(AnimalType::name) + .orElse(null); + } + + public void setAnimal(String animal) { + this.animal = AnimalType.valueOf(animal); + } + + public String getErrorMessage() { + return errorMessage; + } + + public boolean isError() { + return this.errorMessage != null; + } + + public boolean isEditing() { + return this.currentPet != null; + } + + public List getPets() { + return this.service.list(); + } + + public String edit(Pet pet) { + this.currentPet = pet; + this.name = this.currentPet.getName(); + this.birth = this.currentPet.getBirth(); + this.animal = this.currentPet.getAnimal(); + + return this.getViewId(); + } + + public String cancelEditing() { + this.clear(); + + return this.getViewId(); + } + + public String remove(int id) { + this.service.remove(id); + + return redirectTo(this.getViewId()); + } + + public String store() { + try { + if (this.isEditing()) { + this.currentPet.setName(this.name); + this.currentPet.setBirth(this.birth); + this.currentPet.setAnimal(this.animal); + + this.service.update(this.currentPet); + } else { + this.service.create(new Pet(name, animal, birth)); + } + + this.clear(); + + return redirectTo(this.getViewId()); + } catch (Throwable t) { + this.errorMessage = t.getMessage(); + + return this.getViewId(); + } + } + + private void clear() { + this.currentPet = null; + this.name = null; + this.birth = null; + this.animal = null; + this.errorMessage = null; + } + + private String redirectTo(String url) { + return url + "?faces-redirect=true"; + } + + private String getViewId() { + return FacesContext.getCurrentInstance().getViewRoot().getViewId(); + } +} diff --git a/jsf/src/main/resources/META-INF/persistence.xml b/jsf/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f685f214faaa522c69be999f4de0320b14a29b2 --- /dev/null +++ b/jsf/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,20 @@ + + + + java:jboss/datasources/xcs + + es.uvigo.esei.xcs.domain.entities.Owner + es.uvigo.esei.xcs.domain.entities.Pet + es.uvigo.esei.xcs.domain.entities.Administrator + false + + + + + + + \ No newline at end of file diff --git a/jsf/src/main/webapp/WEB-INF/beans.xml b/jsf/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000000000000000000000000000000000..2777559c2045ceee8c62d5f3c9dce7c25608eb39 --- /dev/null +++ b/jsf/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + diff --git a/jsf/src/main/webapp/WEB-INF/jboss-web.xml b/jsf/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 0000000000000000000000000000000000000000..68c92827d5a6f787d0e89d9f7f445097bd1ad261 --- /dev/null +++ b/jsf/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,4 @@ + + + xcs-sample-security-domain + \ No newline at end of file diff --git a/jsf/src/main/webapp/WEB-INF/template.xhtml b/jsf/src/main/webapp/WEB-INF/template.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..8e53092ef6ca08592f08562eb9f70366431de779 --- /dev/null +++ b/jsf/src/main/webapp/WEB-INF/template.xhtml @@ -0,0 +1,47 @@ + + + Pet Store + + + + +
+ + +
+ +
+ +
+ +
+
+ + + +
+ \ No newline at end of file diff --git a/jsf/src/main/webapp/WEB-INF/web.xml b/jsf/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..b71dc7fe07b7865e2eba53eee3d00aab01dc7e5f --- /dev/null +++ b/jsf/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,50 @@ + + Pet Store JSF + + + /faces/index.xhtml + + + + + + admin + /faces/admin/* + POST + GET + PUT + DELETE + + + ADMIN + + + + + + owner + /faces/owner/* + POST + GET + PUT + DELETE + + + OWNER + + + + + + + ADMIN + + + + OWNER + + + \ No newline at end of file diff --git a/jsf/src/main/webapp/admin/owners.xhtml b/jsf/src/main/webapp/admin/owners.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..f5c3f738a0feb98e8a443b9a8b56a36c8aad47b6 --- /dev/null +++ b/jsf/src/main/webapp/admin/owners.xhtml @@ -0,0 +1,60 @@ + + + + + Pet Store - Owners + + + + +

Owner

+ + + Name + + Password + + + + + +
+ + + Error: #{owner.errorMessage} + +
+
+ + + + Login + #{c.login} + + + Password + #{c.password} + + + Pets + #{owner.getPetNames(c.login)} + + + + + + + + + +
+ + \ No newline at end of file diff --git a/jsf/src/main/webapp/index.xhtml b/jsf/src/main/webapp/index.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..d8d9f5c175eba17db1bc017b86f6a3dab6ccdc52 --- /dev/null +++ b/jsf/src/main/webapp/index.xhtml @@ -0,0 +1,19 @@ + + + + + Pet Store - Index + + + + +

Welcome!

+
This is the Pet Store web page, where you can manage your pets. Please, login to continue.
+
+
+ + \ No newline at end of file diff --git a/jsf/src/main/webapp/owner/pets.xhtml b/jsf/src/main/webapp/owner/pets.xhtml new file mode 100644 index 0000000000000000000000000000000000000000..ecdb845e3627f3c8383c4aa824792d7cc81e4e26 --- /dev/null +++ b/jsf/src/main/webapp/owner/pets.xhtml @@ -0,0 +1,63 @@ + + + + + Pet Store - Pets + + + + +

New Pet

+ + + + + + + + + + + + + + + +
+ + + Error: #{pet.errorMessage} + +
+
+ + + + Name + #{p.name} + + + Birth + + + + + + Type + #{p.animal} + + + + + + + + + +
+ + \ No newline at end of file diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/OwnerJsfTest.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/OwnerJsfTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a3212e9f04f0e25e12756467b833a2650c439ed6 --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/OwnerJsfTest.java @@ -0,0 +1,341 @@ +package es.uvigo.esei.xcs.jsf; + +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentLogin; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.existentOwner; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerLogin; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerPassword; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.newOwnerWithoutPets; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.ownerWithPets; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.ownerWithoutPets; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.owners; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.ownersAnd; +import static es.uvigo.esei.xcs.domain.entities.OwnersDataset.ownersWithout; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.page.InitialPage; +import org.jboss.arquillian.graphene.page.Page; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.junit.InSequence; +import org.jboss.arquillian.persistence.Cleanup; +import org.jboss.arquillian.persistence.CleanupUsingScript; +import org.jboss.arquillian.persistence.ShouldMatchDataSet; +import org.jboss.arquillian.persistence.TestExecutionPhase; +import org.jboss.arquillian.persistence.UsingDataSet; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.WebDriver; + +import es.uvigo.esei.xcs.domain.entities.Owner; +import es.uvigo.esei.xcs.jsf.pages.LoginPage; +import es.uvigo.esei.xcs.jsf.pages.OwnersPage; +import es.uvigo.esei.xcs.service.OwnerService; + +@RunWith(Arquillian.class) +public class OwnerJsfTest { + private static final Path WEBAPP = Paths.get("src/main/webapp"); + + @Drone + private WebDriver browser; + + @Page + private OwnersPage ownersPage; + + @Deployment + public static Archive createDeployment() { + return ShrinkWrap.create(WebArchive.class, "test.war") + .addPackage(LoginManagedBean.class.getPackage()) + .addPackage(OwnerService.class.getPackage()) + .addPackage(Owner.class.getPackage()) + .addPackage(WebDriver.class.getPackage()) + .addPackage(LoginPage.class.getPackage()) + .addAsWebResource(WEBAPP.resolve("index.xhtml").toFile()) + .addAsWebResource(WEBAPP.resolve("admin/owners.xhtml").toFile(), "admin/owners.xhtml") + .addAsResource("test-persistence.xml", "META-INF/persistence.xml") + .addAsWebInfResource(WEBAPP.resolve("WEB-INF/template.xhtml").toFile()) + .addAsWebInfResource("jboss-web.xml") + .addAsWebInfResource("web.xml") + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); + } + + @Before + public void setUp() { + if (this.browser != null) + this.browser.manage().deleteAllCookies(); + } + + @Test @InSequence(1) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeLoginFail() {} + + @Test @InSequence(2) + @RunAsClient + public void testLoginFail(@InitialPage LoginPage loginPage) { + loginPage.login("bad", "userpass"); + + loginPage.assertOnLoginPage(); + + loginAsAdmin(loginPage); + } + + @Test @InSequence(3) + @ShouldMatchDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterLoginFail() {} + + + + @Test @InSequence(10) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeList() {} + + @Test @InSequence(11) + @RunAsClient + public void testList(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertThat(ownersPage.areOwnersInTable(owners()), is(true)); + } + + @Test @InSequence(12) + @ShouldMatchDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterGet() {} + + + + @Test @InSequence(21) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeCreate() {} + + @Test @InSequence(22) + @RunAsClient + public void testCreate(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + ownersPage.createOwner(newOwnerLogin(), newOwnerPassword()); + + ownersPage.assertOnOwnersPage(); + + final Owner[] expectedOwners = ownersAnd(newOwnerWithoutPets()); + + assertThat(ownersPage.areOwnersInTable(expectedOwners), is(true)); + } + + @Test @InSequence(23) + @ShouldMatchDataSet({ "owners.xml", "owners-create-without-pets.xml" }) + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterCreate() {} + + + + @Test @InSequence(24) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeCreateExistingOwner() {} + + @Test @InSequence(25) + @RunAsClient + public void testCreateExistingOwner(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertThat(ownersPage.isErrorMessageVisible(), is(false)); + + final String existentLogin = existentLogin(); + ownersPage.createOwner(existentLogin, "anypassword"); + + ownersPage.assertOnOwnersPage(); + + assertThat(ownersPage.isErrorMessageVisible(), is(true)); + } + + @Test @InSequence(26) + @ShouldMatchDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterCreateExistingOwner() {} + + + + @Test @InSequence(27) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeCreateShortPassword() {} + + @Test @InSequence(28) + @RunAsClient + public void testCreateShortPassword(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertThat(ownersPage.isErrorMessageVisible(), is(false)); + + ownersPage.createOwner(newOwnerLogin(), "short"); + + ownersPage.assertOnOwnersPage(); + + assertThat(ownersPage.isErrorMessageVisible(), is(true)); + } + + @Test @InSequence(29) + @ShouldMatchDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterCreateShortPassword() {} + + + + @Test @InSequence(31) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeDeleteOwnerWithoutPets() {} + + @Test @InSequence(32) + @RunAsClient + public void testDeleteOwnerWithoutPets(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertDeleteOwner(ownerWithoutPets()); + } + + @Test @InSequence(33) + @ShouldMatchDataSet("owners-remove-without-pets.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterDeleteOwnerWithoutPets() {} + + + + @Test @InSequence(34) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeDeleteOwnerWithPets() {} + + @Test @InSequence(35) + @RunAsClient + public void testDeleteOwnerWithPets(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertDeleteOwner(ownerWithPets()); + } + + + + @Test @InSequence(36) + @ShouldMatchDataSet("owners-remove-with-pets.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterDeleteOwnerWithPets() {} + + private void assertDeleteOwner(Owner ownerToDelete) { + ownersPage.removeOwner(ownerToDelete); + + ownersPage.assertOnOwnersPage(); + + final Owner[] expectedOwners = ownersWithout(ownerToDelete); + + assertThat(ownersPage.areOwnersInTable(expectedOwners), is(true)); + } + + @Test @InSequence(41) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeEdit() {} + + @Test @InSequence(42) + @RunAsClient + public void testEdit(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + final Owner owner = existentOwner(); + ownersPage.editOwner(owner); + + assertThat(ownersPage.isEditing(), is(true)); + + ownersPage.changePassword("newpassword"); + + ownersPage.assertOnOwnersPage(); + assertThat(ownersPage.isEditing(), is(false)); + } + + @Test @InSequence(43) + @ShouldMatchDataSet("owners-update-password.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterEdit() {} + + + + @Test @InSequence(44) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeEditShortPassword() {} + + @Test @InSequence(45) + @RunAsClient + public void testEditShortPassword(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + assertThat(ownersPage.isErrorMessageVisible(), is(false)); + + final Owner owner = existentOwner(); + ownersPage.editOwner(owner); + + assertThat(ownersPage.isEditing(), is(true)); + + ownersPage.changePassword("short"); + + ownersPage.assertOnOwnersPage(); + + assertThat(ownersPage.isErrorMessageVisible(), is(true)); + assertThat(ownersPage.isEditing(), is(true)); + } + + @Test @InSequence(46) + @UsingDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterEditShortPassword() {} + + + + @Test @InSequence(47) + @UsingDataSet("owners.xml") + @Cleanup(phase = TestExecutionPhase.NONE) + public void beforeCancelEdit() {} + + @Test @InSequence(48) + @RunAsClient + public void testCancelEdit(@InitialPage LoginPage loginPage) { + loginAsAdmin(loginPage); + + final Owner owner = existentOwner(); + ownersPage.editOwner(owner); + + assertThat(ownersPage.isEditing(), is(true)); + + ownersPage.cancelEdit(); + + assertThat(ownersPage.isEditing(), is(false)); + } + + @Test @InSequence(49) + @UsingDataSet("owners.xml") + @CleanupUsingScript({ "cleanup.sql", "cleanup-autoincrement.sql" }) + public void afterCancelEdit() {} + + + + private void loginAsAdmin(LoginPage loginPage) { + loginPage.login("jose", "josepass"); + + ownersPage.assertOnOwnersPage(); + } +} diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginForm.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginForm.java new file mode 100644 index 0000000000000000000000000000000000000000..83130eb62563e5464082968b0b628965a64f501d --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginForm.java @@ -0,0 +1,27 @@ +package es.uvigo.esei.xcs.jsf.pages; + +import static org.jboss.arquillian.graphene.Graphene.guardHttp; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +public class LoginForm { + @FindBy(id = "login-form:login-field") + private WebElement inputLogin; + + @FindBy(id = "login-form:password-field") + private WebElement inputPassword; + + @FindBy(id = "login-form:submit") + private WebElement buttonSubmit; + + public void login(String login, String password) { + inputLogin.clear(); + inputPassword.clear(); + + inputLogin.sendKeys(login); + inputPassword.sendKeys(password); + + guardHttp(buttonSubmit).click(); + } +} diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginPage.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginPage.java new file mode 100644 index 0000000000000000000000000000000000000000..06a02117200c6de124ec68a803751bd82211a3fb --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/LoginPage.java @@ -0,0 +1,26 @@ +package es.uvigo.esei.xcs.jsf.pages; + +import static org.hamcrest.core.StringContains.containsString; +import static org.junit.Assert.assertThat; + +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.page.Location; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +@Location("faces/index.xhtml") +public class LoginPage { + @Drone + private WebDriver browser; + + @FindBy(id = "login-form") + private LoginForm loginForm; + + public void login(String login, String password) { + this.loginForm.login(login, password); + } + + public void assertOnLoginPage() { + assertThat(browser.getCurrentUrl(), containsString("/faces/index.xhtml")); + } +} diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnerForm.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnerForm.java new file mode 100644 index 0000000000000000000000000000000000000000..1b4051473bde0386444427b70adcf88dcb1bc4a6 --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnerForm.java @@ -0,0 +1,46 @@ +package es.uvigo.esei.xcs.jsf.pages; + +import static org.jboss.arquillian.graphene.Graphene.guardHttp; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +public class OwnerForm { + @FindBy(id = "owner-form:name-field") + private WebElement fieldName; + @FindBy(id = "owner-form:password-field") + private WebElement fieldPassword; + @FindBy(id = "owner-form:submit-button") + private WebElement buttonSubmit; + @FindBy(id = "owner-form:cancel-button") + private WebElement buttonCancel; + + + public void setName(String name) { + this.fieldName.sendKeys(name); + } + + public void setPassword(String password) { + this.fieldPassword.sendKeys(password); + } + + public String getName() { + return this.fieldName.getText(); + } + + public String getPassword() { + return this.fieldPassword.getText(); + } + + public void submit() { + guardHttp(this.buttonSubmit).click(); + } + + public void cancel() { + guardHttp(this.buttonCancel).click(); + } + + public boolean isEditing() { + return this.fieldName.getAttribute("readonly") != null; + } +} diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersPage.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersPage.java new file mode 100644 index 0000000000000000000000000000000000000000..a298e33593ce9955be3797980bb4c637e4fd6d4d --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersPage.java @@ -0,0 +1,74 @@ +package es.uvigo.esei.xcs.jsf.pages; + +import static org.hamcrest.core.StringContains.containsString; +import static org.junit.Assert.assertThat; + +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.GrapheneElement; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.FindBy; + +import es.uvigo.esei.xcs.domain.entities.Owner; + +public class OwnersPage { + @Drone + private WebDriver browser; + + @FindBy(id = "owner-form") + private OwnerForm formOwner; + + @FindBy(id = "owners-table") + private OwnersTable tableOwners; + + // GrapheneElement adds "isPresent()" to WebElement. + @FindBy(id = "store-error") + private GrapheneElement storeError; + + public void assertOnOwnersPage() { + assertThat(browser.getCurrentUrl(), containsString("/faces/admin/owners.xhtml")); + } + + public boolean areOwnersInTable(Owner ... owners) { + for (Owner owner : owners) { + if (!this.isOwnerInTable(owner)) + return false; + } + + return true; + } + + public boolean isOwnerInTable(Owner owner) { + return this.tableOwners.hasOwner(owner); + } + + public void createOwner(String login, String password) { + this.formOwner.setName(login); + this.formOwner.setPassword(password); + this.formOwner.submit(); + } + + public void removeOwner(Owner owner) { + this.tableOwners.remove(owner); + } + + public void editOwner(Owner owner) { + this.tableOwners.edit(owner); + } + + public void changePassword(String password) { + this.formOwner.setPassword(password); + this.formOwner.submit(); + } + + public boolean isErrorMessageVisible() { + return storeError.isPresent(); + } + + public boolean isEditing() { + return this.formOwner.isEditing(); + } + + public void cancelEdit() { + this.formOwner.cancel(); + } +} diff --git a/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersTable.java b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersTable.java new file mode 100644 index 0000000000000000000000000000000000000000..4ee14f42be6c74bb50348a57900c5cf14cf0005a --- /dev/null +++ b/jsf/src/test/java/es/uvigo/esei/xcs/jsf/pages/OwnersTable.java @@ -0,0 +1,93 @@ +package es.uvigo.esei.xcs.jsf.pages; + +import static org.jboss.arquillian.graphene.Graphene.guardHttp; + +import java.util.Collection; +import java.util.List; + +import org.jboss.arquillian.graphene.findby.FindByJQuery; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +import es.uvigo.esei.xcs.domain.entities.Owner; +import es.uvigo.esei.xcs.domain.entities.Pet; + +public class OwnersTable { + @FindByJQuery("tbody tr") + private List trOwner; + + public boolean hasOwner(Owner owner) { + for (OwnerRow row : trOwner) { + if (row.hasOwner(owner)) + return true; + } + + return false; + } + + public OwnerRow getOwnerRow(Owner owner) { + for (OwnerRow row : trOwner) { + if (row.hasOwner(owner)) + return row; + } + + throw new IllegalArgumentException("No row for owner: " + owner.getLogin()); + } + + public void remove(Owner owner) { + guardHttp(this.getOwnerRow(owner).getButtonRemove()).click(); + } + + public void edit(Owner owner) { + guardHttp(this.getOwnerRow(owner).getButtonEdit()).click(); + } + + public static class OwnerRow { + @FindBy(className = "owners-table-login") + private WebElement tdLogin; + + @FindBy(className = "owners-table-password") + private WebElement tdPassword; + + @FindBy(className = "owners-table-pets") + private WebElement tdPets; + + @FindBy(className = "owners-table-remove") + private WebElement buttonRemove; + + @FindBy(className = "owners-table-edit") + private WebElement buttonEdit; + + public boolean hasOwner(Owner owner) { + return this.getLoginText().equals(owner.getLogin()) + && this.getPasswordText().equals(owner.getPassword()) + && arePetNamesInTest(owner.getPets(), this.getPetsText()); + } + + private String getLoginText() { + return this.tdLogin.getText().trim(); + } + + private String getPasswordText() { + return this.tdPassword.getText().trim(); + } + + private String getPetsText() { + return this.tdPets.getText().trim(); + } + + public WebElement getButtonRemove() { + return this.buttonRemove; + } + + public WebElement getButtonEdit() { + return this.buttonEdit; + } + + private static boolean arePetNamesInTest(Collection pets, String text) { + return pets.stream() + .map(Pet::getName) + .allMatch(text::contains); + } + } +} diff --git a/jsf/src/test/resources-wildfly-embedded-h2/beans.xml b/jsf/src/test/resources-wildfly-embedded-h2/beans.xml new file mode 100644 index 0000000000000000000000000000000000000000..01d52d1a567d583d8353fdb98e65e827ff09ebac --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/beans.xml @@ -0,0 +1,11 @@ + + + + es.uvigo.esei.xcs.service.util.security.TestPrincipal + + + diff --git a/jsf/src/test/resources-wildfly-embedded-h2/cleanup-autoincrement.sql b/jsf/src/test/resources-wildfly-embedded-h2/cleanup-autoincrement.sql new file mode 100644 index 0000000000000000000000000000000000000000..245049ca05efb8bd0cb20c838880162d9623d3e7 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/cleanup-autoincrement.sql @@ -0,0 +1 @@ +ALTER TABLE Pet ALTER COLUMN id RESTART WITH 1; \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-h2/jboss-web.xml b/jsf/src/test/resources-wildfly-embedded-h2/jboss-web.xml new file mode 100644 index 0000000000000000000000000000000000000000..68c92827d5a6f787d0e89d9f7f445097bd1ad261 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/jboss-web.xml @@ -0,0 +1,4 @@ + + + xcs-sample-security-domain + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-h2/standalone.xml b/jsf/src/test/resources-wildfly-embedded-h2/standalone.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd979b90f80cf7c8973b9e3615c217f8177f7f25 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/standalone.xml @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsf/src/test/resources-wildfly-embedded-h2/test-persistence.xml b/jsf/src/test/resources-wildfly-embedded-h2/test-persistence.xml new file mode 100644 index 0000000000000000000000000000000000000000..ae6b5d32518772eaccca0143292dd26d1324aabf --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/test-persistence.xml @@ -0,0 +1,17 @@ + + + + java:jboss/datasources/ExampleDS + + false + + + + + + + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-h2/web.xml b/jsf/src/test/resources-wildfly-embedded-h2/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..f54a4841d9831a7d5a2861c2fc82a365541e7e86 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-h2/web.xml @@ -0,0 +1,44 @@ + + Pet Store JSF + + + /faces/index.xhtml + + + + + + admin + /api/owner/* + OPTIONS + + + ADMIN + + + + + + owner + /api/pet/* + OPTIONS + + + OWNER + + + + + + + ADMIN + + + + OWNER + + + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/beans.xml b/jsf/src/test/resources-wildfly-embedded-mysql/beans.xml new file mode 100644 index 0000000000000000000000000000000000000000..01d52d1a567d583d8353fdb98e65e827ff09ebac --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/beans.xml @@ -0,0 +1,11 @@ + + + + es.uvigo.esei.xcs.service.util.security.TestPrincipal + + + diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/cleanup-autoincrement.sql b/jsf/src/test/resources-wildfly-embedded-mysql/cleanup-autoincrement.sql new file mode 100644 index 0000000000000000000000000000000000000000..a51d23be2cbb2664431732170bda027e04dda9d5 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/cleanup-autoincrement.sql @@ -0,0 +1 @@ +ALTER TABLE Pet AUTO_INCREMENT = 1; \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/jboss-web.xml b/jsf/src/test/resources-wildfly-embedded-mysql/jboss-web.xml new file mode 100644 index 0000000000000000000000000000000000000000..68c92827d5a6f787d0e89d9f7f445097bd1ad261 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/jboss-web.xml @@ -0,0 +1,4 @@ + + + xcs-sample-security-domain + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/mysql-ds.xml b/jsf/src/test/resources-wildfly-embedded-mysql/mysql-ds.xml new file mode 100644 index 0000000000000000000000000000000000000000..e35c79b61bcb83eaddf8d22303e1eff0e3bbf450 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/mysql-ds.xml @@ -0,0 +1,17 @@ + + + + jdbc:mysql://localhost:3306/xcs + mysql-connector-java-${mysql.version}.jar + + 30 + + + xcs + xcs + + + + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/standalone.xml b/jsf/src/test/resources-wildfly-embedded-mysql/standalone.xml new file mode 100644 index 0000000000000000000000000000000000000000..28088fde0c74abbb7ec04a1862e685f4ddf4e029 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/standalone.xml @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/test-persistence.xml b/jsf/src/test/resources-wildfly-embedded-mysql/test-persistence.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d6b2be6a710d0acf94eacf057af32d6b8849452 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/test-persistence.xml @@ -0,0 +1,17 @@ + + + + java:jboss/datasources/xcs + + false + + + + + + + \ No newline at end of file diff --git a/jsf/src/test/resources-wildfly-embedded-mysql/web.xml b/jsf/src/test/resources-wildfly-embedded-mysql/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..f54a4841d9831a7d5a2861c2fc82a365541e7e86 --- /dev/null +++ b/jsf/src/test/resources-wildfly-embedded-mysql/web.xml @@ -0,0 +1,44 @@ + + Pet Store JSF + + + /faces/index.xhtml + + + + + + admin + /api/owner/* + OPTIONS + + + ADMIN + + + + + + owner + /api/pet/* + OPTIONS + + + OWNER + + + + + + + ADMIN + + + + OWNER + + + \ No newline at end of file diff --git a/jsf/src/test/resources/arquillian.xml b/jsf/src/test/resources/arquillian.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd1edb85bb198089d0520d1404925b153f509638 --- /dev/null +++ b/jsf/src/test/resources/arquillian.xml @@ -0,0 +1,25 @@ + + + + + CLEAN_INSERT + + + + + target/wildfly-${wildfly.version} + target/wildfly-${wildfly.version}/modules + + + + + + target/wildfly-${wildfly.version} + target/wildfly-${wildfly.version}/modules + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f3223c75c32ee3c4d507f951bf5d109db085310c..84bcdb0687e3adcebf1ad4b650c668b0e37b33c9 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,8 @@ tests service rest + jsf + ear @@ -22,17 +24,17 @@ UTF-8 UTF-8 false - + 7.0 1.1.9.Final 1.0.0.Alpha3 - 2.47.1 - + 2.48.2 + 8.2.1.Final 3.4 - + 4.12 2.0.0.0 @@ -41,13 +43,14 @@ 1.5.10 3.4 3.0.13.Final - 2.1.0.Alpha2 - + 2.1.0.Alpha3 + - 1.1.0.Alpha1 + 1.1.0.Alpha4 2.10 2.18.1 2.7 + 2.10.1 @@ -72,7 +75,7 @@ pom import - + ${project.groupId} @@ -89,20 +92,25 @@ rest ${project.version} + + ${project.groupId} + jsf + ${project.version} + ${project.groupId} tests ${project.version} test - + org.apache.commons commons-lang3 ${commons.lang3.version} - + junit @@ -197,7 +205,13 @@ wildfly-maven-plugin ${wildfly.maven.plugin.version} - + + org.apache.maven.plugins + maven-ear-plugin + ${maven.ear.plugin} + + org.eclipse.m2e lifecycle-mapping @@ -335,7 +349,7 @@ - + wildfly-embedded-mysql diff --git a/rest/pom.xml b/rest/pom.xml index 001dee5c2ce9e1aa749412d85147ee6ab0e6c8ba..51fbe203b7036f6c9d0cafc2e31e7a572d91cf5b 100644 --- a/rest/pom.xml +++ b/rest/pom.xml @@ -22,6 +22,7 @@ es.uvigo.esei.xcs service + provided diff --git a/tests/src/main/java/es/uvigo/esei/xcs/domain/entities/OwnersDataset.java b/tests/src/main/java/es/uvigo/esei/xcs/domain/entities/OwnersDataset.java index 8677f35c7df744dc7e56d81839994246d676be65..5c1d0277a585a4f2434eab5dbf4799518a2c9c59 100644 --- a/tests/src/main/java/es/uvigo/esei/xcs/domain/entities/OwnersDataset.java +++ b/tests/src/main/java/es/uvigo/esei/xcs/domain/entities/OwnersDataset.java @@ -1,11 +1,13 @@ package es.uvigo.esei.xcs.domain.entities; +import static java.util.Arrays.asList; import static java.util.Arrays.stream; import static java.util.stream.Collectors.toSet; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -47,6 +49,33 @@ public class OwnersDataset { }; } + public static Owner[] ownersAnd(Owner ... additionalOwners) { + final Owner[] owners = owners(); + final Owner[] ownersWithNewOwner = new Owner[owners.length + additionalOwners.length]; + + System.arraycopy(owners, 0, ownersWithNewOwner, 0, owners.length); + System.arraycopy(additionalOwners, 0, ownersWithNewOwner, owners.length, additionalOwners.length); + + return ownersWithNewOwner; + } + + public static Owner[] ownersWithout(Owner ... removeOwners) { + final List owners = new ArrayList<>(asList(owners())); + + for (Owner owner : removeOwners) { + final Iterator itOwner = owners.iterator(); + + while (itOwner.hasNext()) { + if (itOwner.next().getLogin().equals(owner.getLogin())) { + itOwner.remove(); + break; + } + } + } + + return owners.toArray(new Owner[owners.size()]); + } + public static String petNameWithMultipleOwners() { return "Max"; }