diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/invitation/invitation.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/invitation/invitation.lib.ftl new file mode 100644 index 0000000000..fd31738fff --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/invitation/invitation.lib.ftl @@ -0,0 +1,23 @@ +<#-- renders an invitation object which can be either a MODERATED or NOMINATED invitation--> +<#macro invitationJSON invitation> +<#escape x as jsonUtils.encodeJSONString(x)> +{ + "inviteId": "${invitation.inviteId}", + "inviteeUserName": "${invitation.inviteeUserName}", + <#if invitation.roleName??>"roleName": "${invitation.roleName}", + <#-- Moderated invitation properties --> + <#if invitation.inviteeComments??>"inviteeComments": "${invitation.inviteeComments}", + <#-- Nominated invitation properties --> + <#if invitation.acceptURL??>"acceptURL": "${invitation.acceptURL}", + <#if invitation.acceptURL??>"rejectURL": "${invitation.rejectURL}", + <#if invitation.sentInviteDateAsISO8601??>"sentInviteDate" : { "iso8601" : "${invitation.sentInviteDateAsISO8601}" }, + <#if invitation.inviteeFirstName??>"inviteeFirstName": "${invitation.inviteeFirstName}", + <#if invitation.inviteeLastName??>"inviteeLastName": "${invitation.inviteeLastName}", + <#if invitation.inviteeEmail??>"inviteeEmail": "${invitation.inviteeEmail}", + <#-- put a mandatory property at the end to deal cleanly with training commas --> + "resourceType": "${invitation.resourceType}", + "resourceName": "${invitation.resourceName}", + "invitationType": "${invitation.invitationType}" +} + + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.desc.xml new file mode 100644 index 0000000000..372b7e3278 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.desc.xml @@ -0,0 +1,20 @@ + + Cancel invitation + + Canceling an invitation immediatly stops the invitation, it is different to rejecting an + invitation which will result in the invitation workflow continuing to a normal but rejected conclusion. + In particular the approver or invitee are not notified if an invitation is canceled. +
+ Only a site manager may cancel an invitation. +
+ Returns 200, STATUS_OK on success. + ]]> +
+ /api/sites/{shortname}/invitations/{invitationId} + + draft_public_api + user + required +
\ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.js new file mode 100644 index 0000000000..590ac6215d --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.js @@ -0,0 +1,33 @@ +// Cancel invitation for a web site + +function main() +{ + // Get the url values + var urlElements = url.extension.split("/"); + var shortName = urlElements[0]; + var inviteId = urlElements[2]; + + // Get the site + var site = siteService.getSite(shortName); + if (site == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist."); + return; + } + + + // Need to cancel an invitation here + var invitation = site.getInvitation(inviteId); + if (invitation == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The invitation :" + inviteId + " for web site :" + shortName + ", does not exist."); + return; + } + + // Cancel the invitation + invitation.cancel(); +} + +main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.json.ftl new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.delete.json.ftl @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.desc.xml new file mode 100644 index 0000000000..26ad829f38 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.desc.xml @@ -0,0 +1,12 @@ + + Get Invitation + + + /api/sites/{shortname}/invitations/{inviteId} + + draft_public_api + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.js new file mode 100644 index 0000000000..4e0847db39 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.js @@ -0,0 +1,34 @@ +/** + * Get Invitation web script + */ +function main() +{ + + // Get the site id + var urlElements = url.extension.split("/"); + var shortName = urlElements[0]; + var inviteId = urlElements[2]; + + var site = siteService.getSite(shortName); + if (site == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist."); + return; + } + + var invitation = site.getInvitation(inviteId); + if (invitation == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The invitation :" + inviteId + " for web site :" + shortName + ", does not exist."); + return; + } + + // Pass the model to the template + model.invitation = invitation; + model.site = site; +} + +main(); + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.json.ftl new file mode 100644 index 0000000000..748a2d2025 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.get.json.ftl @@ -0,0 +1,5 @@ +<#-- Get Invitation --> +<#import "../../invitation/invitation.lib.ftl" as invitationLib/> +{ + "data":<@invitationLib.invitationJSON invitation=invitation /> +} diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.desc.xml new file mode 100644 index 0000000000..baf8c1d3a8 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.desc.xml @@ -0,0 +1,44 @@ + + Create invitation for web site + + For a Nominated Invitation, where an existing site member nominates someone else who is possibly not yet an alfresco user to become a member of this web site. + +
+ For an existing user, the invitee is identified by inviteeUserName. + For a user who does not have a userName a new account will be generated based upon + inviteeFirstName, inviteeLastName and inviteeEmail +
if inviteeUserName is specified then inviteeFirstName, inviteeLastName and inviteeEmail are ignored. + +
+
invitationType
mandatory - "NOMINATED"
+
inviteeFirstName
optional,
+
inviteeLastName
optional,
+
inviteeEmail
optional,
+
inviteeUserName
optional
+
serverPath
+
acceptURL
+
rejectURL
+
inviteeRoleName
mandatory what role to be given on this web site
+
+ +
+ For a Moderated Invitation, where an existing user wants to be made a member of a moderated web site. +
+
invitationType
mandatory - "MODERATED"
+
inviteeUserName
optional who wants to be invited to this web site?
+
inviteeComments
mandatory (but can be blank) why do they want membership to this site ?
+
inviteeRoleName
mandatory what role to be given on this web site
+
+
+ + Returns HTTPStatus.Created (201) if an invitation is created. + + ]]>
+ /api/sites/{shortname}/invitations + + draft_public_api + user + required +
\ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.ftl new file mode 100644 index 0000000000..247d463fe8 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.ftl @@ -0,0 +1,5 @@ +<#-- Create / Post / Invitation --> +<#import "../../invitation/invitation.lib.ftl" as invitationLib/> +{ + "data":<@invitationLib.invitationJSON invitation=invitation /> +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.js new file mode 100644 index 0000000000..bb36aba23f --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitation.post.json.js @@ -0,0 +1,139 @@ +/** + * Create / Post / Invitation + */ +function main() +{ + + var invitation = null; + + // Get the web site site + var shortName = url.extension.split("/")[0]; + var site = siteService.getSite(shortName); + if (site == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist."); + return; + } + + if(!json.has("invitationType")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The invitationType has not been set."); + return; + } + + // Get the role + var invitationType = json.get("invitationType"); + if (invitationType == null || invitationType.length == 0) + { + status.setCode(status.STATUS_BAD_REQUEST, "The invitationType is null or empty."); + return; + } + + if(!invitationType.match("[MODERATED]|[NOMINATED]")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The invitationType has does not have a correct value."); + return; + } + + if(invitationType == "MODERATED") + { + // Check mandatory parameters + if(!json.has("inviteeRoleName")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeRoleName has not been set."); + return; + } + + if(!json.has("inviteeUserName")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeUserName has not been set."); + return; + } + + // Get the role + var inviteeRoleName = json.get("inviteeRoleName"); + if (inviteeRoleName == null || inviteeRoleName == "") + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeRoleName has not been set."); + return; + } + + var inviteeComments = json.get("inviteeComments"); + if (inviteeComments == null) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeComments has not been set."); + return; + } + + var inviteeUserName = json.get("inviteeUserName"); + if (inviteeUserName == null || inviteeUserName == "") + { + status.setCode(status.STATUS_BAD_REQUEST, "The userName has not been set."); + return; + } + + invitation = site.inviteModerated(inviteeComments, inviteeUserName, inviteeRoleName); + } + + if(invitationType == "NOMINATED") + { + + // Get Mandatory properties + if(!json.has("inviteeRoleName")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeRoleName has not been set."); + return; + } + var inviteeRoleName = json.get("inviteeRoleName"); + if (inviteeRoleName == null || inviteeRoleName == "" ) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeRoleName is null or empty."); + return; + } + var serverPath = json.get("serverPath"); + var acceptUrl = json.get("acceptURL"); + var rejectUrl = json.get("rejectURL"); + + /** + * Get the optional properties + */ + if(json.has("inviteeUserName")) + { + var inviteeUserName = json.get("inviteeUserName"); + invitation = site.inviteNominated(inviteeUserName, inviteeRoleName, serverPath, acceptUrl, rejectUrl); + } + else + { + // Get Mandatory properties + if(!json.has("inviteeFirstName")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeFirstName has not been set."); + return; + } + if(!json.has("inviteeLastName")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeLastName has not been set."); + return; + } + if(!json.has("inviteeEmail")) + { + status.setCode(status.STATUS_BAD_REQUEST, "The inviteeEmail has not been set."); + return; + } + + var inviteeFirstName = json.get("inviteeFirstName") ; + var inviteeLastName = json.get("inviteeLastName") ; + var inviteeEmail = json.get("inviteeEmail") ; + invitation = site.inviteNominated(inviteeFirstName, inviteeLastName, inviteeEmail, inviteeRoleName, serverPath, acceptUrl, rejectUrl); + } + } + + // Pass the model to the results template + model.site = site; + model.invitation = invitation; + + status.code = status.STATUS_CREATED; +} + +main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.desc.xml new file mode 100644 index 0000000000..ef685ae199 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.desc.xml @@ -0,0 +1,22 @@ + + List Invitations + + With no parameters, returns all open invitations for this web site. +
+ With inviteeUserName, returns all open invitations for this web site and invitee. +
+ With invitationType, returns all open invitations of the specified type (Either NOMINATED or MODERATED). + +
+ +
+ ]]> +
+ /api/sites/{shortname}/invitations?inviteeUserName={inviteeUserName?}&invitationType={invitationType?} + + draft_public_api + user + required +
\ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.js new file mode 100644 index 0000000000..dc2b300c66 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.js @@ -0,0 +1,40 @@ +/** + * List invitations implementation + */ + +function main () +{ + // Get the site id + var urlElements = url.extension.split("/"); + var shortName = urlElements[0]; + + // Get the args + var inviteeUserName = args["inviteeUserName"]; + var invitationType = args["invitationType"]; + + var site = siteService.getSite(shortName); + if (site == null) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The site " + shortName + " does not exist."); + return; + } + + var props = {}; + + if(inviteeUserName != null) + { + props.inviteeUserName = inviteeUserName + } + if(invitationType != null) + { + props.invitationType = invitationType + } + + var invitations = site.listInvitations(props); + + // Pass the information to the template + model.invitations = invitations; +} + +main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.json.ftl new file mode 100644 index 0000000000..b5a0a68050 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/site/invitation/invitations.get.json.ftl @@ -0,0 +1,9 @@ +<#-- list / search / invitations --> + +<#import "../../invitation/invitation.lib.ftl" as invitationLib/> +"data": [ + <#list invitations as invitation> + <@invitationLib.invitationJSON invitation=invitation /> + <#if invitation_has_next>, + + ] diff --git a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java index f16f30f761..86f2a388ba 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java @@ -625,7 +625,7 @@ public class Invite extends DeclarativeWebScript workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_GEN_PASSWORD, inviteePassword); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TYPE, Invitation.ResourceType.WEB_SITE); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME, siteShortName); - workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_SITE_ROLE, inviteeSiteRole); + workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_ROLE, inviteeSiteRole); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_SERVER_PATH, serverPath); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_ACCEPT_URL, acceptUrl); workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_REJECT_URL, rejectUrl); diff --git a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java index 2c981da481..1981fd2c4a 100644 --- a/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java +++ b/source/java/org/alfresco/repo/web/scripts/site/SiteServiceTest.java @@ -44,6 +44,7 @@ import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.namespace.QName; import org.alfresco.util.GUID; import org.alfresco.util.PropertyMap; +import org.alfresco.web.scripts.Status; import org.alfresco.web.scripts.TestWebScriptServer.DeleteRequest; import org.alfresco.web.scripts.TestWebScriptServer.GetRequest; import org.alfresco.web.scripts.TestWebScriptServer.PostRequest; @@ -54,7 +55,7 @@ import org.json.JSONArray; import org.json.JSONObject; /** - * Unit test to test site Web Script API + * Unit test to test site Web Script API of the Site Object. * * @author Roy Wetherall */ @@ -195,12 +196,12 @@ public class SiteServiceTest extends BaseWebScriptTest public void testGetSite() throws Exception { // Get a site that doesn't exist - Response response = sendRequest(new GetRequest(URL_SITES + "/" + "somerandomshortname"), 404); + sendRequest(new GetRequest(URL_SITES + "/" + "somerandomshortname"), 404); // Create a site and get it String shortName = GUID.generate(); JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); - response = sendRequest(new GetRequest(URL_SITES + "/" + shortName), 200); + Response response = sendRequest(new GetRequest(URL_SITES + "/" + shortName), 200); } @@ -456,4 +457,305 @@ public class SiteServiceTest extends BaseWebScriptTest assertEquals("Additional Site Information", addInfo.get("title")); } + + /** + * End to end sanity check of web site invitation. + * + * Nominated and Moderated invitations. + * + * @throws Exception + */ + public void testInvitationSanityCheck() throws Exception + { + String shortName = GUID.generate(); + createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); + + String inviteComments = "Please sir, let me in"; + String userName = USER_TWO; + String roleName = SiteModel.SITE_CONSUMER; + + String inviteeFirstName = "Buffy"; + String inviteeLastName = "Summers"; + String inviteeEmail = "buffy@sunnydale"; + String inviteeUserName = userName; + String serverPath = "http://localhost:8081/share/"; + String acceptURL = "page/accept-invite"; + String rejectURL = "page/reject-invite"; + + // Create a nominated invitation + String nominatedId = createNominatedInvitation(shortName, inviteeFirstName, inviteeLastName, inviteeEmail, inviteeUserName, roleName, serverPath, acceptURL, rejectURL); + + // Get the nominated invitation + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/" + nominatedId), 200); + + //Create a new moderated invitation + String moderatedId = createModeratedInvitation(shortName, inviteComments, userName, roleName); + + // Get the moderated invitation + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/" + moderatedId), 200); + + // search for the moderated invitation + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations?inviteeUserName=" + userName), 200); + + // Search for all invitations on this site + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations"), 200); + + // cancel the nominated invitation + sendRequest(new DeleteRequest(URL_SITES + "/" + shortName + "/invitations/" + nominatedId), 200); + + // cancel the moderated invitation + sendRequest(new DeleteRequest(URL_SITES + "/" + shortName + "/invitations/" + moderatedId), 200); + } + + /** + * Detailed Test of Get Invitation Web Script + * @throws Exception + */ + public void testGetInvitation() throws Exception + { + String shortName = GUID.generate(); + createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); + + /* + * Create a new moderated invitation + */ + String inviteeComments = "Please sir, let $* me in"; + String userName = USER_TWO; + String roleName = SiteModel.SITE_CONSUMER; + String inviteId = createModeratedInvitation(shortName, inviteeComments, userName, roleName); + + /* + * Negative test - site does not exist + */ + sendRequest(new GetRequest(URL_SITES + "/rubbish/invitations/" + inviteId), 404); + + /* + * Negative test - site does exist but invitation doesn't + */ + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/jbpm$8787487"), 404); + + /* + * Negative test - site does exist but invitation engine is wrong + */ + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/trash$123"), 404); + + /* + * Negative test - site does exist but invitation doesn't no $ in inviteId + */ + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/trash123"), 404); + + /* + * Positive test - get the invitation and validate that it is correct + */ + { + Response response = sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/" + inviteId), 200); + JSONObject top = new JSONObject(response.getContentAsString()); + //System.out.println(response.getContentAsString()); + JSONObject data = top.getJSONObject("data"); + assertNotNull("data is null", data); + assertEquals("inviteId is not set", data.getString("inviteId"), inviteId); + assertEquals("invitationType", "MODERATED", data.getString("invitationType")); + assertEquals("inviteeUserName is not set", userName, data.getString("inviteeUserName")); + assertEquals("resourceName is not correct", shortName, data.getString("resourceName")); + assertEquals("resourceType is not correct", "WEB_SITE", data.getString("resourceType")); + // Moderated specific properties + assertEquals("inviteeComments", inviteeComments, data.getString("inviteeComments")); + assertEquals("roleName is not set", roleName, data.getString("roleName")); + + } + + /* + * Cancel the invitation + */ + sendRequest(new DeleteRequest(URL_SITES + "/" + shortName + "/invitations/" + inviteId), 200); + + /* + * Verify that the invitation is no longer open + */ + sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/" + inviteId), 404); + + /** + * Create a nominated invitation + */ + String inviteeFirstName = "Buffy"; + String inviteeLastName = "Summers"; + String inviteeEmail = "FirstName123.LastName123@email.com"; + String inviteeUserName = null; + String serverPath = "http://localhost:8081/share/"; + String acceptURL = "page/accept-invite"; + String rejectURL = "page/reject-invite"; + inviteId = createNominatedInvitation(shortName, inviteeFirstName, inviteeLastName, inviteeEmail, inviteeUserName, roleName, serverPath, acceptURL, rejectURL); + + /* + * Positive test - get the invitation and validate that it is correct + * inviteId and inviteeUserName will be generated. + */ + { + Response response = sendRequest(new GetRequest(URL_SITES + "/" + shortName + "/invitations/" + inviteId), 200); + JSONObject top = new JSONObject(response.getContentAsString()); + //System.out.println(response.getContentAsString()); + JSONObject data = top.getJSONObject("data"); + assertNotNull("data is null", data); + assertEquals("inviteId is not set", data.getString("inviteId"), inviteId); + assertEquals("invitationType", "NOMINATED", data.getString("invitationType")); + assertEquals("resourceName is not correct", shortName, data.getString("resourceName")); + assertEquals("resourceType is not correct", "WEB_SITE", data.getString("resourceType")); + + // Nominated specific attributes + assertEquals("roleName is not set", roleName, data.getString("roleName")); + // Generated user name + assertNotNull("inviteeUserName is not set", data.getString("inviteeUserName")); + + } + + /* + * Cancel the nominated invitation + */ + sendRequest(new DeleteRequest(URL_SITES + "/" + shortName + "/invitations/" + inviteId), 200); + + } + + /** + * Detailed Test of List Invitation Web Script. + * @throws Exception + */ + public void testListInvitation() throws Exception + { + String shortName = GUID.generate(); + createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); + + + + } + + /** + * Detailed test of Create Invitation Web Script + * + * Create Nominated Invitation + * + * Create Moderated Invitation + * + * @throws Exception + */ + public void testCreateInvitation() throws Exception + { + String shortName = GUID.generate(); + createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200); + + + String inviteComments = "Please sir, let me in"; + String userName = USER_TWO; + String roleName = SiteModel.SITE_CONSUMER; + String inviteId = null; + + /* + * Negative test - wrong invitation type + */ + { + JSONObject newInvitation = new JSONObject(); + newInvitation.put("invitationType", "Grundge"); + newInvitation.put("inviteeRoleName", roleName); + newInvitation.put("inviteeComments", inviteComments); + newInvitation.put("inviteeUserName", userName); + sendRequest(new PostRequest(URL_SITES + "/" + shortName + "/invitations", newInvitation.toString(), "application/json"), Status.STATUS_BAD_REQUEST); + } + + /* + * Negative test - missing Invitation type + */ + { + JSONObject newInvitation = new JSONObject(); + newInvitation.put("inviteeRoleName", roleName); + newInvitation.put("inviteeComments", inviteComments); + newInvitation.put("inviteeUserName", userName); + sendRequest(new PostRequest(URL_SITES + "/" + shortName + "/invitations", newInvitation.toString(), "application/json"), Status.STATUS_BAD_REQUEST); + } + + /* + * Negative test - blank RoleName + */ + { + JSONObject newInvitation = new JSONObject(); + newInvitation.put("invitationType", "MODERATED"); + newInvitation.put("inviteeRoleName", ""); + newInvitation.put("inviteeComments", inviteComments); + newInvitation.put("inviteeUserName", userName); + sendRequest(new PostRequest(URL_SITES + "/" + shortName + "/invitations", newInvitation.toString(), "application/json"), Status.STATUS_BAD_REQUEST); + } + + /* + * Create a new moderated invitation + */ + JSONObject newInvitation = new JSONObject(); + { + newInvitation.put("invitationType", "MODERATED"); + newInvitation.put("inviteeRoleName", roleName); + newInvitation.put("inviteeComments", inviteComments); + newInvitation.put("inviteeUserName", userName); + Response response = sendRequest(new PostRequest(URL_SITES + "/" + shortName + "/invitations", newInvitation.toString(), "application/json"), Status.STATUS_CREATED); + JSONObject top = new JSONObject(response.getContentAsString()); + JSONObject data = top.getJSONObject("data"); + inviteId = data.getString("inviteId"); + assertEquals("invitationType", "MODERATED", data.getString("invitationType")); + assertEquals("inviteeUserName is not set", userName, data.getString("inviteeUserName")); + assertEquals("resourceName is not correct", shortName, data.getString("resourceName")); + assertEquals("resourceType is not correct", "WEB_SITE", data.getString("resourceType")); + + } + assertNotNull("inviteId is null", inviteId); + assertTrue("inviteId is too small", inviteId.length() > 0); + + } + + private String createNominatedInvitation(String siteName, String inviteeFirstName, String inviteeLastName, String inviteeEmail, String inviteeUserName, String inviteeRoleName, String serverPath, String acceptURL, String rejectURL) throws Exception + { + /* + * Create a new nominated invitation + */ + JSONObject newInvitation = new JSONObject(); + + newInvitation.put("invitationType", "NOMINATED"); + newInvitation.put("inviteeRoleName", inviteeRoleName); + if(inviteeUserName != null) + { + // nominate an existing user + newInvitation.put("inviteeUserName", inviteeUserName); + } + else + { + // nominate someone else + newInvitation.put("inviteeFirstName", inviteeFirstName); + newInvitation.put("inviteeLastName", inviteeLastName); + newInvitation.put("inviteeEmail", inviteeEmail); + } + newInvitation.put("serverPath", serverPath); + newInvitation.put("acceptURL", acceptURL); + newInvitation.put("rejectURL", rejectURL); + + Response response = sendRequest(new PostRequest(URL_SITES + "/" + siteName + "/invitations", newInvitation.toString(), "application/json"), 201); + JSONObject top = new JSONObject(response.getContentAsString()); + JSONObject data = top.getJSONObject("data"); + String inviteId = data.getString("inviteId"); + + return inviteId; + } + + private String createModeratedInvitation(String siteName, String inviteeComments, String inviteeUserName, String inviteeRoleName) throws Exception + { + /* + * Create a new moderated invitation + */ + JSONObject newInvitation = new JSONObject(); + + newInvitation.put("invitationType", "MODERATED"); + newInvitation.put("inviteeRoleName", inviteeRoleName); + newInvitation.put("inviteeComments", inviteeComments); + newInvitation.put("inviteeUserName", inviteeUserName); + Response response = sendRequest(new PostRequest(URL_SITES + "/" + siteName + "/invitations", newInvitation.toString(), "application/json"), 201); + JSONObject top = new JSONObject(response.getContentAsString()); + JSONObject data = top.getJSONObject("data"); + String inviteId = data.getString("inviteId"); + + return inviteId; + } }