001    package org.hackystat.sensorbase.resource.projects;
002    
003    import static org.junit.Assert.assertEquals;
004    import static org.junit.Assert.assertFalse;
005    import static org.junit.Assert.assertTrue;
006    import static org.hackystat.sensorbase.client.SensorBaseClient.InvitationReply.ACCEPT;
007    import static org.hackystat.sensorbase.client.SensorBaseClient.InvitationReply.DECLINE;
008    
009    import javax.xml.datatype.XMLGregorianCalendar;
010    
011    import org.hackystat.sensorbase.client.SensorBaseClient;
012    import org.hackystat.sensorbase.resource.projects.jaxb.Invitations;
013    import org.hackystat.sensorbase.resource.projects.jaxb.Project;
014    import org.hackystat.sensorbase.resource.projects.jaxb.UriPatterns;
015    import org.hackystat.sensorbase.resource.sensordata.jaxb.Properties;
016    import org.hackystat.sensorbase.resource.sensordata.jaxb.Property;
017    import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;
018    import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataIndex;
019    import org.hackystat.sensorbase.test.SensorBaseRestApiHelper;
020    import org.hackystat.utilities.tstamp.Tstamp;
021    import org.junit.BeforeClass;
022    import org.junit.Test;
023    
024    /**
025     * Tests the SensorBase REST API for Project membership processing.
026     * 
027     * @author Philip M. Johnson
028     */
029    public class TestProjectMembershipRestApi extends SensorBaseRestApiHelper {
030    
031      private static String testUser1 = "TestProjectMembershipUser1@hackystat.org";
032      private static String testUser2 = "TestProjectMembershipUser2@hackystat.org";
033      private static String testProject1 = "TestInvitationProject1";
034      private static SensorBaseClient client1;
035      private static SensorBaseClient client2;
036      
037      /**
038       * Starts the server going for these tests, and makes sure our test user is registered.
039       * 
040       * @throws Exception If problems occur setting up the server.
041       */
042      @BeforeClass
043      public static void setupMembership() throws Exception {
044        SensorBaseClient.registerUser(getHostName(), testUser1);
045        SensorBaseClient.registerUser(getHostName(), testUser2);
046        client1 = new SensorBaseClient(getHostName(), testUser1, testUser1);
047        client2 = new SensorBaseClient(getHostName(), testUser2, testUser2);
048        client1.deleteProject(testUser1, testProject1);
049      }
050      
051    
052      /**
053       * Tests a "normal" invitation acceptance use case:
054       * <ul>
055       * <li> testUser1 creates a new project called TestProject1, and puts testUser2 on the 
056       * invitation list.
057       * <li> testUser2 retrieves the project description.
058       * <li> testUser2 accepts the invitation.
059       * <li> testUser1 retrieves the project and confirms that testUser2 is a member.
060       * <li> testUser1 then deletes the Project.
061       * </ul>
062       * @throws Exception If problems occur.
063       */
064      @Test
065      public void testInvitation1() throws Exception {
066        // First, check that testUser1 has only one defined project (the default).
067        assertEquals("Size is 1", 1, client1.getProjectIndex(testUser1).getProjectRef().size());
068        // Construct the project representation that is owned by testUser1.
069        Project project = makeProject(testProject1);
070        project.getInvitations().getInvitation().add(testUser2);
071        // PUT it to the server.
072        client1.putProject(project);
073        // Ensure that now there are two projects for testUser1 and for testUser2
074        assertEquals("Size is 2", 2, client1.getProjectIndex(testUser1).getProjectRef().size());
075        assertEquals("Size is 2a", 2, client2.getProjectIndex(testUser2).getProjectRef().size());
076        // Ensure that testUser2 can retrieve it.
077        project = client2.getProject(testUser1, testProject1);
078        // Make sure that testUser2 is invited.
079        assertTrue("Checking invite 1", project.getInvitations().getInvitation().contains(testUser2));
080        // Accept the invitation.
081        client2.reply(testUser1, testProject1, ACCEPT);
082        // Now check to see that testUser2 is a member.
083        project = client2.getProject(testUser1, testProject1);
084        assertTrue("Checking member 1", project.getMembers().getMember().contains(testUser2));
085        // Now delete the Project.
086        client1.deleteProject(testUser1, testProject1);
087      }
088      
089      /**
090       * Just like testNormalInvitation1, but we use the invite() method to invite testUser2
091       * after the project has already been defined.
092       * @throws Exception If problems occur.
093       */
094      @Test
095      public void testInvitation2() throws Exception {
096        // Construct the project representation that is owned by testUser1.
097        Project project = makeProject(testProject1);
098        // PUT it to the server.
099        client1.putProject(project);
100        // Now invite testUser2.
101        client1.invite(testUser2, testProject1);
102        // Ensure that testUser2 can retrieve it.
103        project = client2.getProject(testUser1, testProject1);
104        // Make sure that testUser2 is invited.
105        assertTrue("Checking invite 2", project.getInvitations().getInvitation().contains(testUser2));
106        // Accept the invitation.
107        client2.reply(testUser1, testProject1, ACCEPT);
108        // Now check to see that testUser2 is a member.
109        project = client2.getProject(testUser1, testProject1);
110        assertTrue("Checking members 2", project.getMembers().getMember().contains(testUser2));
111        // Now delete the Project.
112        client1.deleteProject(testUser1, testProject1);
113      }
114      
115      /**
116       * We now test that if testUser2 declines the invitation, the project representation no 
117       * longer contains testUser2.
118       * @throws Exception If problems occur.
119       */
120      @Test
121      public void testInvitation3() throws Exception {
122        // Construct the project representation that is owned by testUser1.
123        Project project = makeProject(testProject1);
124        // PUT it to the server.
125        client1.putProject(project);
126        // Now invite testUser2.
127        client1.invite(testUser2, testProject1);
128        // Ensure that testUser2 can retrieve it.
129        project = client2.getProject(testUser1, testProject1);
130        // Make sure that testUser2 is invited.
131        assertTrue("Checking invitation", project.getInvitations().getInvitation().contains(testUser2));
132        // Decline the invitation.
133        client2.reply(testUser1, testProject1, DECLINE);
134        // Check that they only have one project now.
135        assertEquals("Size is 1a", 1, client2.getProjectIndex(testUser2).getProjectRef().size());
136        // Now check to see that testUser2 is not a member nor on invitees list.
137        project = client1.getProject(testUser1, testProject1);
138        assertFalse("Checking members 3", project.getMembers().getMember().contains(testUser2));
139        assertFalse("Checking invites 3", project.getInvitations().getInvitation().contains(testUser2));
140        // Now delete the Project.
141        client1.deleteProject(testUser1, testProject1);
142      }
143      
144      /**
145       * Tests that we can send data from two different users and retrieve it as part of a joint 
146       * project.
147       * @throws Exception If problems occur.
148       */
149      @Test
150      public void testMultiProjectMemberDataAccess() throws Exception {
151        // Make the project and a member.
152        Project project = makeProject(testProject1);
153        client1.putProject(project);
154        client1.invite(testUser2, testProject1);
155        client2.reply(testUser1, testProject1, ACCEPT);
156        // Delete all preexisting sensor data from these test users. 
157        client1.deleteSensorData(testUser1);
158        client2.deleteSensorData(testUser2);
159        // Now have each client send some data.
160        client1.putSensorData(makeSensorData(testUser1));
161        client2.putSensorData(makeSensorData(testUser2));
162        // Now check to see that there are two sensor data instances associated with this project.
163        SensorDataIndex index1 = client1.getProjectSensorData(testUser1, testProject1);
164        assertEquals("Checking index1", 2, index1.getSensorDataRef().size());
165        SensorDataIndex index2 = client2.getProjectSensorData(testUser1, testProject1);
166        assertEquals("Checking index2", 2, index2.getSensorDataRef().size());
167      }
168      
169      
170      /**
171       * Create a project with the passed name.
172       * The project start time is now, and the end time is one day from now.
173       * @param projectName The name of the Project.
174       * @return The newly created Project representation.
175       */
176      private Project makeProject(String projectName) {
177        String owner = testUser1;
178        Project project = new Project();
179        project.setOwner(owner);
180        project.setName(projectName);
181        project.setDescription("Test Project Invitation");
182        XMLGregorianCalendar tstamp = Tstamp.makeTimestamp();
183        project.setStartTime(tstamp);
184        project.setEndTime(Tstamp.incrementDays(tstamp, 1));
185        UriPatterns uris = new UriPatterns();
186        uris.getUriPattern().add("**/test/**");
187        project.setUriPatterns(uris);
188        Invitations invitations = new Invitations();
189        project.setInvitations(invitations);
190        return project;
191      }
192      
193      /**
194       * Creates a sample SensorData instance given a timestamp and a user. 
195       * @param user The user.
196       * @return The new SensorData instance. 
197       */
198      private SensorData makeSensorData(String user) {
199        String sdt = "TestSdt";
200        SensorData data = new SensorData();
201        String tool = "Subversion";
202        data.setTool(tool);
203        data.setOwner(user);
204        data.setSensorDataType(sdt);
205        data.setTimestamp(Tstamp.makeTimestamp());
206        data.setResource("file://foo/bar/test/baz.txt");
207        data.setRuntime(Tstamp.makeTimestamp());
208        Property property = new Property();
209        property.setKey("SampleField");
210        property.setValue("The test value for Sample Field");
211        Properties properties = new Properties();
212        properties.getProperty().add(property);
213        data.setProperties(properties);
214        return data;
215      }
216    
217     
218    }