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}",#if>
+ <#-- Moderated invitation properties -->
+ <#if invitation.inviteeComments??>"inviteeComments": "${invitation.inviteeComments}",#if>
+ <#-- Nominated invitation properties -->
+ <#if invitation.acceptURL??>"acceptURL": "${invitation.acceptURL}",#if>
+ <#if invitation.acceptURL??>"rejectURL": "${invitation.rejectURL}",#if>
+ <#if invitation.sentInviteDateAsISO8601??>"sentInviteDate" : { "iso8601" : "${invitation.sentInviteDateAsISO8601}" }, #if>
+ <#if invitation.inviteeFirstName??>"inviteeFirstName": "${invitation.inviteeFirstName}",#if>
+ <#if invitation.inviteeLastName??>"inviteeLastName": "${invitation.inviteeLastName}",#if>
+ <#if invitation.inviteeEmail??>"inviteeEmail": "${invitation.inviteeEmail}",#if>
+ <#-- put a mandatory property at the end to deal cleanly with training commas -->
+ "resourceType": "${invitation.resourceType}",
+ "resourceName": "${invitation.resourceName}",
+ "invitationType": "${invitation.invitationType}"
+}
+#escape>
+#macro>
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>,#if>
+ #list>
+ ]
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;
+ }
}