Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
37780 amit 1
package com.spice.profitmandi.service.cs;
2
 
3
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
4
import com.spice.profitmandi.common.model.CustomRetailer;
5
import com.spice.profitmandi.dao.entity.cs.DemoPartnerAccess;
6
import com.spice.profitmandi.dao.repository.cs.CsService;
7
import com.spice.profitmandi.dao.repository.cs.DemoPartnerAccessRepository;
8
import com.spice.profitmandi.dao.repository.cs.DemoPartnerAccessService;
9
import com.spice.profitmandi.service.AdminUser;
10
import com.spice.profitmandi.service.user.RetailerService;
11
import com.spice.profitmandi.web.config.AppConfig;
12
import org.hibernate.Session;
13
import org.hibernate.SessionFactory;
14
import org.junit.Assert;
15
import org.junit.Test;
16
import org.junit.runner.RunWith;
17
import org.springframework.beans.factory.annotation.Autowired;
18
import org.springframework.test.annotation.Rollback;
19
import org.springframework.test.context.ContextConfiguration;
20
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
21
import org.springframework.test.context.web.WebAppConfiguration;
22
import org.springframework.transaction.annotation.Transactional;
23
 
24
import java.util.Arrays;
25
import java.util.Collections;
26
import java.util.List;
27
import java.util.Map;
28
 
29
/**
30
 * Local-database integration tests (rolled back) for demo partner access: a grant opens the partner
31
 * for the sales person without ever entering the shared position mapping.
32
 */
33
@RunWith(SpringJUnit4ClassRunner.class)
34
@WebAppConfiguration
35
@ContextConfiguration(classes = {AppConfig.class})
36
@Transactional
37
public class DemoPartnerAccessTest {
38
 
39
    private static final int GRANTOR = 1;
40
 
41
    @Autowired private DemoPartnerAccessService demoPartnerAccessService;
42
    @Autowired private DemoPartnerAccessRepository demoPartnerAccessRepository;
43
    @Autowired private CsService csService;
44
    @Autowired private RetailerService retailerService;
45
    @Autowired private SessionFactory sessionFactory;
46
 
47
    @Test
48
    @Rollback
49
    public void grantAllowsPartnerWithoutTouchingPositionMapping() throws Exception {
50
        int salesUser = this.anySalesUser();
51
        int fofoId = this.anyActiveStoreNotMappedTo(salesUser);
52
        Assert.assertFalse(demoPartnerAccessService.isAllowed(salesUser, fofoId));
53
 
54
        Map<String, Object> result = demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));
55
        this.session().flush();
56
 
57
        Assert.assertEquals(1, result.get("granted"));
58
        Assert.assertTrue(demoPartnerAccessService.isAllowed(salesUser, fofoId));
59
        Assert.assertTrue(demoPartnerAccessService.getDemoFofoIds(salesUser).contains(fofoId));
60
        List<Integer> positionFofoIds = csService.getAuthUserIdPartnerIdMapping().get(salesUser);
61
        Assert.assertTrue("demo partner must not leak into the position mapping",
62
                positionFofoIds == null || !positionFofoIds.contains(fofoId));
63
 
64
        CustomRetailer retailer = retailerService.getFofoRetailer(fofoId);
65
        Assert.assertTrue(demoPartnerAccessService.getDemoPartnerEmails(salesUser).contains(retailer.getEmail()));
66
 
67
        DemoPartnerAccess grant = demoPartnerAccessRepository.selectActive(salesUser, fofoId);
68
        demoPartnerAccessService.revoke(GRANTOR, grant.getId());
69
        this.session().flush();
70
 
71
        Assert.assertFalse(demoPartnerAccessService.isAllowed(salesUser, fofoId));
72
        Assert.assertNull(demoPartnerAccessRepository.selectActive(salesUser, fofoId));
73
    }
74
 
75
    @Test
76
    @Rollback
77
    public void grantSkipsDuplicateAndPositionMappedPartners() throws Exception {
78
        int salesUser = this.anySalesUser();
79
        int fofoId = this.anyActiveStoreNotMappedTo(salesUser);
80
        demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));
81
        this.session().flush();
82
 
83
        List<Integer> positionFofoIds = csService.getAuthUserIdPartnerIdMapping().get(salesUser);
84
        List<Integer> request = positionFofoIds == null || positionFofoIds.isEmpty()
85
                ? Collections.singletonList(fofoId) : Arrays.asList(fofoId, positionFofoIds.get(0));
86
        Map<String, Object> result = demoPartnerAccessService.grant(GRANTOR, salesUser, request);
87
 
88
        Assert.assertEquals(0, result.get("granted"));
89
        Assert.assertEquals(request.size(), ((List<?>) result.get("skipped")).size());
90
    }
91
 
92
    @Test(expected = ProfitMandiBusinessException.class)
93
    @Rollback
94
    public void grantRejectsNonSalesUser() throws Exception {
95
        int nonSales = ((Number) this.session().createNativeQuery(
96
                "SELECT u.id FROM auth.auth_user u WHERE u.active = 1 AND u.id NOT IN "
97
                        + "(SELECT auth_user_id FROM cs.position WHERE category_id = 4) LIMIT 1").getSingleResult()).intValue();
98
        demoPartnerAccessService.grant(GRANTOR, nonSales, Collections.singletonList(this.anyActiveStoreNotMappedTo(nonSales)));
99
    }
100
 
101
    @Test
102
    @Rollback
103
    public void salesUserCannotManageGrants() {
104
        Assert.assertFalse(demoPartnerAccessService.canManage(this.anySalesUser()));
105
    }
106
 
107
    @Test
108
    @Rollback
109
    public void revokingTwiceFails() throws Exception {
110
        int salesUser = this.anySalesUser();
111
        int fofoId = this.anyActiveStoreNotMappedTo(salesUser);
112
        demoPartnerAccessService.grant(GRANTOR, salesUser, Collections.singletonList(fofoId));
113
        this.session().flush();
114
        int id = demoPartnerAccessRepository.selectActive(salesUser, fofoId).getId();
115
        demoPartnerAccessService.revoke(GRANTOR, id);
116
        this.session().flush();
117
        try {
118
            demoPartnerAccessService.revoke(GRANTOR, id);
119
            Assert.fail("second revoke must fail");
120
        } catch (ProfitMandiBusinessException expected) {
121
        }
122
    }
123
 
124
    // Active Sales user who cannot see every menu (no L5 position, not an all-menu email, not Business Intelligence).
125
    private int anySalesUser() {
126
        return ((Number) this.session().createNativeQuery(
127
                "SELECT p.auth_user_id FROM cs.position p JOIN auth.auth_user u ON u.id = p.auth_user_id "
128
                        + "WHERE p.category_id = 4 AND u.active = 1 AND u.email_id NOT IN (:emails) AND p.auth_user_id NOT IN "
129
                        + "(SELECT auth_user_id FROM cs.position WHERE escalation_type = 'L5' OR category_id = 19) "
130
                        + "ORDER BY p.auth_user_id LIMIT 1")
131
                .setParameter("emails", AdminUser.ALL_MENU_EMAILS).getSingleResult()).intValue();
132
    }
133
 
134
    private int anyActiveStoreNotMappedTo(int authUserId) throws Exception {
135
        List<Integer> mapped = csService.getAuthUserIdPartnerIdMapping().get(authUserId);
136
        List<?> ids = this.session().createNativeQuery(
137
                "SELECT fs.id FROM fofo.fofo_store fs WHERE fs.active = 1 AND fs.internal = 0 ORDER BY fs.id").getResultList();
138
        for (Object id : ids) {
139
            int fofoId = ((Number) id).intValue();
140
            if (mapped == null || !mapped.contains(fofoId)) {
141
                return fofoId;
142
            }
143
        }
144
        throw new IllegalStateException("No unmapped active store");
145
    }
146
 
147
    private Session session() {
148
        return sessionFactory.getCurrentSession();
149
    }
150
}