Blame | Last modification | View Log | RSS feed
package com.spice.profitmandi.service.cs;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.CustomRetailer;import com.spice.profitmandi.dao.entity.cs.DemoPartnerAccess;import com.spice.profitmandi.dao.repository.cs.CsService;import com.spice.profitmandi.dao.repository.cs.DemoPartnerAccessRepository;import com.spice.profitmandi.dao.repository.cs.DemoPartnerAccessService;import com.spice.profitmandi.service.AdminUser;import com.spice.profitmandi.service.user.RetailerService;import com.spice.profitmandi.web.config.AppConfig;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.annotation.Rollback;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import org.springframework.test.context.web.WebAppConfiguration;import org.springframework.transaction.annotation.Transactional;import java.util.Arrays;import java.util.Collections;import java.util.List;import java.util.Map;/*** Local-database integration tests (rolled back) for demo partner access: a grant opens the partner* for the sales person without ever entering the shared position mapping.*/@RunWith(SpringJUnit4ClassRunner.class)@WebAppConfiguration@ContextConfiguration(classes = {AppConfig.class})@Transactionalpublic class DemoPartnerAccessTest {private static final int GRANTOR = 1;@Autowired private DemoPartnerAccessService demoPartnerAccessService;@Autowired private DemoPartnerAccessRepository demoPartnerAccessRepository;@Autowired private CsService csService;@Autowired private RetailerService retailerService;@Autowired private SessionFactory sessionFactory;@Test@Rollbackpublic void grantAllowsPartnerWithoutTouchingPositionMapping() throws Exception {int salesUser = this.anySalesUser();int fofoId = this.anyActiveStoreNotMappedTo(salesUser);Assert.assertFalse(demoPartnerAccessService.isAllowed(salesUser, fofoId));Map<String, Object> result = demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));this.session().flush();Assert.assertEquals(1, result.get("granted"));Assert.assertTrue(demoPartnerAccessService.isAllowed(salesUser, fofoId));Assert.assertTrue(demoPartnerAccessService.getDemoFofoIds(salesUser).contains(fofoId));List<Integer> positionFofoIds = csService.getAuthUserIdPartnerIdMapping().get(salesUser);Assert.assertTrue("demo partner must not leak into the position mapping",positionFofoIds == null || !positionFofoIds.contains(fofoId));CustomRetailer retailer = retailerService.getFofoRetailer(fofoId);Assert.assertTrue(demoPartnerAccessService.getDemoPartnerEmails(salesUser).contains(retailer.getEmail()));DemoPartnerAccess grant = demoPartnerAccessRepository.selectActive(salesUser, fofoId);demoPartnerAccessService.revoke(GRANTOR, grant.getId());this.session().flush();Assert.assertFalse(demoPartnerAccessService.isAllowed(salesUser, fofoId));Assert.assertNull(demoPartnerAccessRepository.selectActive(salesUser, fofoId));}@Test@Rollbackpublic void grantSkipsDuplicateAndPositionMappedPartners() throws Exception {int salesUser = this.anySalesUser();int fofoId = this.anyActiveStoreNotMappedTo(salesUser);demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));this.session().flush();List<Integer> positionFofoIds = csService.getAuthUserIdPartnerIdMapping().get(salesUser);List<Integer> request = positionFofoIds == null || positionFofoIds.isEmpty()? Collections.singletonList(fofoId) : Arrays.asList(fofoId, positionFofoIds.get(0));Map<String, Object> result = demoPartnerAccessService.grant(GRANTOR, salesUser, request);Assert.assertEquals(0, result.get("granted"));Assert.assertEquals(request.size(), ((List<?>) result.get("skipped")).size());}@Test(expected = ProfitMandiBusinessException.class)@Rollbackpublic void grantRejectsNonSalesUser() throws Exception {int nonSales = ((Number) this.session().createNativeQuery("SELECT u.id FROM auth.auth_user u WHERE u.active = 1 AND u.id NOT IN "+ "(SELECT auth_user_id FROM cs.position WHERE category_id = 4) LIMIT 1").getSingleResult()).intValue();demoPartnerAccessService.grant(GRANTOR, nonSales, Collections.singletonList(this.anyActiveStoreNotMappedTo(nonSales)));}@Test@Rollbackpublic void salesUserCannotManageGrants() {Assert.assertFalse(demoPartnerAccessService.canManage(this.anySalesUser()));}@Test@Rollbackpublic void revokingTwiceFails() throws Exception {int salesUser = this.anySalesUser();int fofoId = this.anyActiveStoreNotMappedTo(salesUser);demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));this.session().flush();int id = demoPartnerAccessRepository.selectActive(salesUser, fofoId).getId();demoPartnerAccessService.revoke(GRANTOR, id);this.session().flush();try {demoPartnerAccessService.revoke(GRANTOR, id);Assert.fail("second revoke must fail");} catch (ProfitMandiBusinessException expected) {}}// Active Sales user who cannot see every menu (no L5 position, not an all-menu email, not Business Intelligence).private int anySalesUser() {return ((Number) this.session().createNativeQuery("SELECT p.auth_user_id FROM cs.position p JOIN auth.auth_user u ON u.id = p.auth_user_id "+ "WHERE p.category_id = 4 AND u.active = 1 AND u.email_id NOT IN (:emails) AND p.auth_user_id NOT IN "+ "(SELECT auth_user_id FROM cs.position WHERE escalation_type = 'L5' OR category_id = 19) "+ "ORDER BY p.auth_user_id LIMIT 1").setParameter("emails", AdminUser.ALL_MENU_EMAILS).getSingleResult()).intValue();}private int anyActiveStoreNotMappedTo(int authUserId) throws Exception {List<Integer> mapped = csService.getAuthUserIdPartnerIdMapping().get(authUserId);List<?> ids = this.session().createNativeQuery("SELECT fs.id FROM fofo.fofo_store fs WHERE fs.active = 1 AND fs.internal = 0 ORDER BY fs.id").getResultList();for (Object id : ids) {int fofoId = ((Number) id).intValue();if (mapped == null || !mapped.contains(fofoId)) {return fofoId;}}throw new IllegalStateException("No unmapped active store");}private Session session() {return sessionFactory.getCurrentSession();}}