///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General // Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.fibu; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.Serializable; import java.util.Calendar; import java.util.Random; import org.junit.Test; import org.projectforge.access.AccessException; import org.projectforge.common.DateHolder; import org.projectforge.core.UserException; import org.projectforge.test.TestBase; import org.projectforge.user.GroupDO; import org.projectforge.user.GroupDao; import org.projectforge.user.PFUserDO; import org.projectforge.user.UserRightDO; import org.projectforge.user.UserRightDao; import org.projectforge.user.UserRightId; import org.projectforge.user.UserRightValue; public class AuftragDaoTest extends TestBase { private static int dbNumber = AuftragDao.START_NUMBER; private AuftragDao auftragDao; private ProjektDao projektDao; private GroupDao groupDao; private UserRightDao userRightDao; private final Random random = new Random(); @Test public void getNextNumber() { logon(TEST_FINANCE_USER); AuftragDO auftrag = new AuftragDO(); auftrag.setNummer(auftragDao.getNextNumber(auftrag)); auftrag.addPosition(new AuftragsPositionDO()); auftragDao.save(auftrag); assertEquals(dbNumber++, auftrag.getNummer().intValue()); auftrag = new AuftragDO(); auftrag.setNummer(auftragDao.getNextNumber(auftrag)); auftrag.addPosition(new AuftragsPositionDO()); auftragDao.save(auftrag); assertEquals(dbNumber++, auftrag.getNummer().intValue()); } @Test public void checkAccess() { logon(TEST_FINANCE_USER); AuftragDO auftrag1 = new AuftragDO(); auftrag1.setNummer(auftragDao.getNextNumber(auftrag1)); auftragDao.setContactPerson(auftrag1, getUserId(TEST_FINANCE_USER)); Serializable id1 = null; try { id1 = auftragDao.save(auftrag1); fail("UserException expected: Order should have positions."); } catch (final UserException ex) { assertEquals("fibu.auftrag.error.auftragHatKeinePositionen", ex.getI18nKey()); } auftrag1.addPosition(new AuftragsPositionDO()); id1 = auftragDao.save(auftrag1); dbNumber++; // Needed for getNextNumber test; auftrag1 = auftragDao.getById(id1); AuftragDO auftrag2 = new AuftragDO(); auftrag2.setNummer(auftragDao.getNextNumber(auftrag2)); auftragDao.setContactPerson(auftrag2, getUserId(TEST_PROJECT_MANAGER_USER)); auftrag2.addPosition(new AuftragsPositionDO()); final Serializable id2 = auftragDao.save(auftrag2); dbNumber++; // Needed for getNextNumber test; auftrag2 = auftragDao.getById(id2); AuftragDO auftrag3 = new AuftragDO(); auftrag3.setNummer(auftragDao.getNextNumber(auftrag3)); auftragDao.setContactPerson(auftrag3, getUserId(TEST_PROJECT_MANAGER_USER)); final DateHolder date = new DateHolder(); date.add(Calendar.YEAR, -6); // 6 years old. auftrag3.setAngebotsDatum(date.getSQLDate()); auftrag3.setAuftragsStatus(AuftragsStatus.ABGESCHLOSSEN); final AuftragsPositionDO position = new AuftragsPositionDO(); position.setVollstaendigFakturiert(true); position.setStatus(AuftragsPositionsStatus.ABGESCHLOSSEN); auftrag3.addPosition(position); final Serializable id3 = auftragDao.save(auftrag3); dbNumber++; // Needed for getNextNumber test; auftrag3 = auftragDao.getById(id3); logon(TEST_PROJECT_MANAGER_USER); try { auftragDao.getById(id1); fail("AccessException expected: Projectmanager should not have access to foreign orders."); } catch (final AccessException ex) { // OK } auftragDao.getById(id2); try { auftragDao.getById(id3); fail("AccessException expected: Projectmanager should not have access to 2 years old orders."); } catch (final AccessException ex) { // OK } logon(TEST_CONTROLLING_USER); auftrag1 = auftragDao.getById(id1); checkNoWriteAccess(id1, auftrag1, "Controller"); logon(TEST_USER); checkNoAccess(id1, auftrag1, "Other"); logon(TEST_ADMIN_USER); checkNoAccess(id1, auftrag1, "Admin "); } @Test public void checkAccess2() { logon(TEST_FINANCE_USER); final GroupDO group1 = initTestDB.addGroup("AuftragDaoTest.ProjectManagers1", TEST_PROJECT_ASSISTANT_USER); final GroupDO group2 = initTestDB.addGroup("AuftragDaoTest.ProjectManagers2", TEST_PROJECT_MANAGER_USER); ProjektDO projekt1 = new ProjektDO(); projekt1.setName("ACME - Webportal 1"); projekt1.setProjektManagerGroup(group1); Serializable id = projektDao.save(projekt1); projekt1 = projektDao.getById(id); AuftragDO auftrag1 = new AuftragDO(); auftrag1.setNummer(auftragDao.getNextNumber(auftrag1)); auftrag1.setProjekt(projekt1); auftrag1.addPosition(new AuftragsPositionDO()); id = auftragDao.save(auftrag1); dbNumber++; // Needed for getNextNumber test; auftrag1 = auftragDao.getById(id); ProjektDO projekt2 = new ProjektDO(); projekt2.setName("ACME - Webportal 2"); projekt2.setProjektManagerGroup(group2); id = projektDao.save(projekt2); projekt2 = projektDao.getById(id); AuftragDO auftrag2 = new AuftragDO(); auftrag2.setNummer(auftragDao.getNextNumber(auftrag2)); auftrag2.setProjekt(projekt2); auftrag2.addPosition(new AuftragsPositionDO()); id = auftragDao.save(auftrag2); dbNumber++; // Needed for getNextNumber test; auftrag2 = auftragDao.getById(id); logon(TEST_CONTROLLING_USER); checkNoWriteAccess(id, auftrag1, "Controlling"); logon(TEST_USER); checkNoAccess(id, auftrag1, "Other"); logon(TEST_PROJECT_MANAGER_USER); projektDao.getList(new ProjektFilter()); checkNoAccess(auftrag1.getId(), "Project manager"); checkNoWriteAccess(auftrag1.getId(), auftrag1, "Project manager"); checkHasUpdateAccess(auftrag2.getId()); logon(TEST_PROJECT_ASSISTANT_USER); projektDao.getList(new ProjektFilter()); checkHasUpdateAccess(auftrag1.getId()); checkNoAccess(auftrag2.getId(), "Project assistant"); checkNoWriteAccess(auftrag2.getId(), auftrag2, "Project assistant"); logon(TEST_ADMIN_USER); checkNoAccess(id, auftrag1, "Admin "); } @Test public void checkPartlyReadwriteAccess() { logon(TEST_ADMIN_USER); final PFUserDO user = initTestDB.addUser("AuftragDaoCheckPartlyReadWriteAccess"); final GroupDO financeGroup = getGroup(FINANCE_GROUP); financeGroup.getSafeAssignedUsers().add(user); groupDao.update(financeGroup); final GroupDO projectAssistants = getGroup(PROJECT_ASSISTANT); projectAssistants.getSafeAssignedUsers().add(user); groupDao.update(projectAssistants); final GroupDO group = initTestDB.addGroup("AuftragDaoTest.checkPartlyReadwriteAccess"); logon(TEST_FINANCE_USER); ProjektDO projekt = new ProjektDO(); projekt.setName("ACME - Webportal checkPartlyReadwriteAccess"); projekt.setProjektManagerGroup(group); Serializable id = projektDao.save(projekt); projekt = projektDao.getById(id); AuftragDO auftrag = new AuftragDO(); auftrag.setNummer(auftragDao.getNextNumber(auftrag)); auftrag.setProjekt(projekt); auftrag.addPosition(new AuftragsPositionDO()); id = auftragDao.save(auftrag); dbNumber++; // Needed for getNextNumber test; auftrag = auftragDao.getById(id); logon(user); try { auftrag = auftragDao.getById(id); fail("Access exception expected."); } catch (final AccessException ex) { assertEquals("access.exception.userHasNotRight", ex.getI18nKey()); } logon(TEST_ADMIN_USER); user.addRight(new UserRightDO(UserRightId.PM_ORDER_BOOK, UserRightValue.PARTLYREADWRITE)); // userDao.update(user); logon(user); try { auftrag = auftragDao.getById(id); fail("Access exception expected."); } catch (final AccessException ex) { assertEquals("access.exception.userHasNotRight", ex.getI18nKey()); } logon(TEST_ADMIN_USER); final UserRightDO right = user.getRight(UserRightId.PM_ORDER_BOOK); right.setValue(UserRightValue.READWRITE); // Full access userRightDao.update(right); logon(user); auftrag = auftragDao.getById(id); logon(TEST_ADMIN_USER); right.setValue(UserRightValue.PARTLYREADWRITE); userRightDao.update(right); group.getAssignedUsers().add(user); groupDao.update(group); // User is now in project manager group. logon(user); auftrag = auftragDao.getById(id); } private void checkHasUpdateAccess(final Serializable auftragsId) { AuftragDO auftrag = auftragDao.getById(auftragsId); final String value = String.valueOf(random.nextLong()); auftrag.setBemerkung(value); auftragDao.update(auftrag); auftrag = auftragDao.getById(auftragsId); assertEquals(value, auftrag.getBemerkung()); } private void checkNoAccess(final String who) { try { final AuftragFilter filter = new AuftragFilter(); auftragDao.getList(filter); fail("AccessException expected: " + who + " users should not have select list access to orders."); } catch (final AccessException ex) { // OK } } private void checkNoAccess(final Serializable auftragsId, final String who) { try { auftragDao.getById(auftragsId); fail("AccessException expected: " + who + " users should not have select access to orders."); } catch (final AccessException ex) { // OK } } private void checkNoAccess(final Serializable id, final AuftragDO auftrag, final String who) { checkNoAccess(who); checkNoAccess(id, who); checkNoWriteAccess(id, auftrag, who); } private void checkNoWriteAccess(final Serializable id, final AuftragDO auftrag, final String who) { try { final AuftragDO auf = new AuftragDO(); final int number = auftragDao.getNextNumber(auf); auf.setNummer(number); auftragDao.save(auf); fail("AccessException expected: " + who + " users should not have save access to orders."); } catch (final AccessException ex) { // OK } try { auftrag.setBemerkung(who); auftragDao.update(auftrag); fail("AccessException expected: " + who + " users should not have update access to orders."); } catch (final AccessException ex) { // OK } } @Test public void checkVollstaendigFakturiert() { logon(TEST_FINANCE_USER); AuftragDO auftrag1 = new AuftragDO(); auftrag1.setNummer(auftragDao.getNextNumber(auftrag1)); auftragDao.setContactPerson(auftrag1, getUserId(TEST_PROJECT_MANAGER_USER)); auftrag1.addPosition(new AuftragsPositionDO()); final Serializable id1 = auftragDao.save(auftrag1); dbNumber++; // Needed for getNextNumber test; auftrag1 = auftragDao.getById(id1); AuftragsPositionDO position = auftrag1.getPositionen().get(0); position.setVollstaendigFakturiert(true); try { auftragDao.update(auftrag1); fail("UserException expected: Only orders with state ABGESCHLOSSEN should be set as fully invoiced."); } catch (final UserException ex) { assertEquals("fibu.auftrag.error.nurAbgeschlosseneAuftragsPositionenKoennenVollstaendigFakturiertSein", ex.getI18nKey()); } auftrag1 = auftragDao.getById(id1); auftrag1.setAuftragsStatus(AuftragsStatus.ABGESCHLOSSEN); auftragDao.update(auftrag1); auftrag1 = auftragDao.getById(id1); logon(TEST_PROJECT_MANAGER_USER); position = auftrag1.getPositionen().get(0); position.setStatus(AuftragsPositionsStatus.ABGESCHLOSSEN); position.setVollstaendigFakturiert(true); try { auftragDao.update(auftrag1); fail("AccessException expected: Projectmanager should not able to set order as fully invoiced."); } catch (final AccessException ex) { // OK assertEquals("fibu.auftrag.error.vollstaendigFakturiertProtection", ex.getI18nKey()); } logon(TEST_FINANCE_USER); position = auftrag1.getPositionen().get(0); position.setStatus(AuftragsPositionsStatus.ABGESCHLOSSEN); position.setVollstaendigFakturiert(true); auftragDao.update(auftrag1); } @Test public void checkEmptyAuftragsPositionen() { logon(TEST_FINANCE_USER); AuftragDO auftrag = new AuftragDO(); auftrag.setNummer(auftragDao.getNextNumber(auftrag)); auftrag.addPosition(new AuftragsPositionDO()); auftrag.addPosition(new AuftragsPositionDO()); auftrag.addPosition(new AuftragsPositionDO()); auftrag.addPosition(new AuftragsPositionDO()); Serializable id = auftragDao.save(auftrag); dbNumber++; // Needed for getNextNumber test; auftrag = auftragDao.getById(id); assertEquals(1, auftrag.getPositionen().size()); auftrag = new AuftragDO(); auftrag.setNummer(auftragDao.getNextNumber(auftrag)); auftrag.addPosition(new AuftragsPositionDO()); auftrag.addPosition(new AuftragsPositionDO()); final AuftragsPositionDO position = new AuftragsPositionDO(); position.setTitel("Hurzel"); auftrag.addPosition(position); auftrag.addPosition(new AuftragsPositionDO()); id = auftragDao.save(auftrag); dbNumber++; // Needed for getNextNumber test; auftrag = auftragDao.getById(id); assertEquals(3, auftrag.getPositionen().size()); auftrag.getPositionen().get(2).setTitel(null); auftragDao.update(auftrag); auftrag = auftragDao.getById(id); assertEquals(3, auftrag.getPositionen().size()); } public void setAuftragDao(final AuftragDao auftragDao) { this.auftragDao = auftragDao; } public void setGroupDao(final GroupDao groupDao) { this.groupDao = groupDao; } public void setProjektDao(final ProjektDao projektDao) { this.projektDao = projektDao; } public void setUserRightDao(final UserRightDao userRightDao) { this.userRightDao = userRightDao; } }