<commit_before>package org.sagebionetworks.bridge.sdk.integration;

import static org.junit.Assert.fail;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sagebionetworks.bridge.rest.ClientManager;
import org.sagebionetworks.bridge.rest.api.ForAdminsApi;
import org.sagebionetworks.bridge.rest.api.ForResearchersApi;
import org.sagebionetworks.bridge.rest.api.SubstudiesApi;
import org.sagebionetworks.bridge.rest.exceptions.EntityNotFoundException;
import org.sagebionetworks.bridge.rest.model.AccountSummary;
import org.sagebionetworks.bridge.rest.model.AccountSummaryList;
import org.sagebionetworks.bridge.rest.model.Role;
import org.sagebionetworks.bridge.rest.model.SignIn;
import org.sagebionetworks.bridge.rest.model.SignUp;
import org.sagebionetworks.bridge.rest.model.Substudy;
import org.sagebionetworks.bridge.user.TestUserHelper;
import org.sagebionetworks.bridge.user.TestUserHelper.TestUser;
import org.sagebionetworks.bridge.util.IntegTestUtils;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class SubstudyFilteringTest {
    public static class UserInfo {
        private final String userId;
        private final SignIn signIn;
        public UserInfo(String userId, String email) {
            this.userId = userId;
            this.signIn = new SignIn().email(email).password(<PASSWORD>).study(IntegTestUtils.STUDY_ID);
        }
        public String getUserId() { return userId; }
        public SignIn getSignIn() { return signIn; }
    }

    private TestUser admin;
    private SubstudiesApi substudiesApi;
    private Set<String> substudyIdsToDelete;
    private Set<String> userIdsToDelete;
    
    @Before
    public void before() { 
        admin = TestUserHelper.getSignedInAdmin();
        substudiesApi = admin.getClient(SubstudiesApi.class);
        
        substudyIdsToDelete = new HashSet<>();
        userIdsToDelete = new HashSet<>();
    }

    @After
    public void after() {
        ForAdminsApi adminsApi = admin.getClient(ForAdminsApi.class);
        for (String userId : userIdsToDelete) {
            try {
                adminsApi.deleteUser(userId).execute();    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        for (String substudyId : substudyIdsToDelete) {
            try {
                adminsApi.deleteSubstudy(substudyId, true).execute();    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void test() throws Exception { 
        // Create two substudies
        String idA = createSubstudy();
        String idB = createSubstudy();
        
        // Create a researcher in substudy A
        SignIn researcherA = createUser(Role.RESEARCHER, idA).getSignIn();
        SignIn researcherB = createUser(Role.RESEARCHER, idB).getSignIn();
        
        // Create three accounts, one A, one B, one AB, one with nothing
        String userIdA = createUser(null, idA).getUserId();
        String userIdB = createUser(null, idB).getUserId();
        String userIdAB = createUser(null, idA, idB).getUserId();
        
        // researcherA
        ClientManager manager = new ClientManager.Builder().withSignIn(researcherA).build();
        ForResearchersApi researcherApi = manager.getClient(ForResearchersApi.class);
        
        // This researcher sees A substudy users only
        AccountSummaryList list = researcherApi.getParticipants(null, null, null, null, null, null).execute().body();
        assertAccountHasSubstudies(ImmutableSet.of(idA), list.getItems());
        assertAccountHasSubstudies(ImmutableSet.of(idA, idB), list.getItems());
        
        // researcherB
        manager = new ClientManager.Builder().withSignIn(researcherB).build();
        researcherApi = manager.getClient(ForResearchersApi.class);
        
        // This researcher sees B substudy users only
        list = researcherApi.getParticipants(null, null, null, null, null, null).execute().body();
        assertAccountHasSubstudies(ImmutableSet.of(idB), list.getItems());
        assertAccountHasSubstudies(ImmutableSet.of(idA, idB), list.getItems());
        
        // Researcher B should not be able to get a substudy A account
        try {
            researcherApi.getParticipantById(userIdA, false).execute();
            fail("Should have thrown exception");
        } catch(EntityNotFoundException e) {
        }
        // Researcher B should be able to get only substudy B accounts (even if mixed)
        researcherApi.getParticipantById(userIdB, false).execute().body();
        researcherApi.getParticipantById(userIdAB, false).execute().body();
        
        // This should apply to any call involving user in another substudy, try one (fully tested in 
        // the unit tests)
        try {
            researcherApi.getActivityEvents(userIdA).execute();
            fail("Should have thrown exception");
        } catch(EntityNotFoundException e) {
        }
    }
    
    private void assertAccountHasSubstudies(Set<String> substudies, List<AccountSummary> summaries) {
        for (AccountSummary summary : summaries) {
            Set<String> summaryIds = ImmutableSet.copyOf(summary.getSubstudyIds());
            if (summaryIds.equals(substudies)) {
                return;
            }
        }
        fail("Did not find account with substudies: " + Joiner.on(", ").join(substudies));
    }
    
    private String createSubstudy() throws Exception {
        String id = Tests.randomIdentifier(SubstudyTest.class);
        Substudy substudyA = new Substudy().id(id).name("Substudy Filtering Test");
        substudiesApi.createSubstudy(substudyA).execute();
        substudyIdsToDelete.add(id);
        return id;
    }
    
    private UserInfo createUser(Role role, String... substudyIds) throws Exception {
        String email = IntegTestUtils.makeEmail(SubstudyTest.class);<commit_msg>Change in test reflecting new permissions to change account-substudy associations.<commit_after>package org.sagebionetworks.bridge.sdk.integration;

import static org.junit.Assert.fail;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sagebionetworks.bridge.rest.ClientManager;
import org.sagebionetworks.bridge.rest.api.ForAdminsApi;
import org.sagebionetworks.bridge.rest.api.ForResearchersApi;
import org.sagebionetworks.bridge.rest.api.SubstudiesApi;
import org.sagebionetworks.bridge.rest.exceptions.EntityNotFoundException;
import org.sagebionetworks.bridge.rest.model.AccountSummary;
import org.sagebionetworks.bridge.rest.model.AccountSummaryList;
import org.sagebionetworks.bridge.rest.model.Role;
import org.sagebionetworks.bridge.rest.model.SignIn;
import org.sagebionetworks.bridge.rest.model.SignUp;
import org.sagebionetworks.bridge.rest.model.StudyParticipant;
import org.sagebionetworks.bridge.rest.model.Substudy;
import org.sagebionetworks.bridge.user.TestUserHelper;
import org.sagebionetworks.bridge.user.TestUserHelper.TestUser;
import org.sagebionetworks.bridge.util.IntegTestUtils;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class SubstudyFilteringTest {
    public static class UserInfo {
        private final String userId;
        private final SignIn signIn;
        public UserInfo(String userId, String email) {
            this.userId = userId;
            this.signIn = new SignIn().email(email).password(<PASSWORD>).study(IntegTestUtils.STUDY_ID);
        }
        public String getUserId() { return userId; }
        public SignIn getSignIn() { return signIn; }
    }

    private TestUser admin;
    private SubstudiesApi substudiesApi;
    private Set<String> substudyIdsToDelete;
    private Set<String> userIdsToDelete;
    
    @Before
    public void before() { 
        admin = TestUserHelper.getSignedInAdmin();
        substudiesApi = admin.getClient(SubstudiesApi.class);
        
        substudyIdsToDelete = new HashSet<>();
        userIdsToDelete = new HashSet<>();
    }

    @After
    public void after() {
        ForAdminsApi adminsApi = admin.getClient(ForAdminsApi.class);
        for (String userId : userIdsToDelete) {
            try {
                adminsApi.deleteUser(userId).execute();    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
        for (String substudyId : substudyIdsToDelete) {
            try {
                adminsApi.deleteSubstudy(substudyId, true).execute();    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void test() throws Exception { 
        // Create two substudies
        String idA = createSubstudy();
        String idB = createSubstudy();
        
        // Create a researcher in substudy A
        SignIn researcherA = createUser(Role.RESEARCHER, idA).getSignIn();
        SignIn researcherB = createUser(Role.RESEARCHER, idB).getSignIn();
        
        // Create three accounts, one A, one B, one AB, one with nothing
        String userIdA = createUser(null, idA).getUserId();
        String userIdB = createUser(null, idB).getUserId();
        String userIdAB = createUser(null, idA, idB).getUserId();
        
        // researcherA
        ClientManager manager = new ClientManager.Builder().withSignIn(researcherA).build();
        ForResearchersApi researcherApi = manager.getClient(ForResearchersApi.class);
        
        // This researcher sees A substudy users only
        AccountSummaryList list = researcherApi.getParticipants(null, null, null, null, null, null).execute().body();
        assertListContainsAccount(list.getItems(), userIdA);
        assertListContainsAccount(list.getItems(), userIdAB);
        
        // researcherB
        manager = new ClientManager.Builder().withSignIn(researcherB).build();
        researcherApi = manager.getClient(ForResearchersApi.class);
        
        // This researcher sees B substudy users only
        list = researcherApi.getParticipants(null, null, null, null, null, null).execute().body();
        assertListContainsAccount(list.getItems(), userIdB);
        assertListContainsAccount(list.getItems(), userIdAB);
        
        // Researcher B should not be able to get a substudy A account
        try {
            researcherApi.getParticipantById(userIdA, false).execute();
            fail("Should have thrown exception");
        } catch(EntityNotFoundException e) {
        }
        // Researcher B should be able to get only substudy B accounts (even if mixed)
        researcherApi.getParticipantById(userIdB, false).execute().body();
        researcherApi.getParticipantById(userIdAB, false).execute().body();
        
        // This should apply to any call involving user in another substudy, try one (fully tested in 
        // the unit tests)
        try {
            researcherApi.getActivityEvents(userIdA).execute();
            fail("Should have thrown exception");
        } catch(EntityNotFoundException e) {
        }
        
        // Researcher A should not be able to save and destroy the mapping to substudy B
        StudyParticipant participant = researcherApi.getParticipantById(userIdAB, false).execute().body();
        researcherApi.updateParticipant(userIdAB, participant);
        
        participant = researcherApi.getParticipantById(userIdAB, false).execute().body();
        participant.getSubstudyIds().contains(idB); // this wasn't wiped out by the update.
    }
    
    private void assertListContainsAccount(List<AccountSummary> summaries, String userId) {
        for (AccountSummary summary : summaries) {
            if (summary.getId().equals(userId)) {
                return;
            }
        }
        fail("Did not find account with ID: " + userId);
    }
    
    private String createSubstudy() throws Exception {
        String id = Tests.randomIdentifier(SubstudyTest.class);
        Substudy substudyA = new Substudy().id(id).name("Substudy Filtering Test");
        substudiesApi.createSubstudy(substudyA).execute();
        substudyIdsToDelete.add(id);
        return id;
    }
    
    private UserInfo createUser(Role role, String... substudyIds) throws Exception {
        String email = IntegTestUtils.makeEmail(SubstudyTest.class);
{'fraction_non_alphanumeric': 0.09771064432381402, 'fraction_numerical': 0.0, 'mean_word_length': 2.8791577662496186, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2374539', 'n_tokens_mistral': 3650, 'n_tokens_neox': 3569, 'n_words': 768}