You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/03/06 09:37:48 UTC

git commit: ISIS-233: more action testing

Updated Branches:
  refs/heads/dan/ISIS-233-ro b4dc94caa -> 3c2564f1e


ISIS-233: more action testing

... and discovered that will need a different way to pass querystring
if using the JBoss RestEasy client framework

... have invented a new 'x-isis-querystring' for this.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/3c2564f1
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/3c2564f1
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/3c2564f1

Branch: refs/heads/dan/ISIS-233-ro
Commit: 3c2564f1e5846d9a864364c41dc4ee8dd5df6414
Parents: b4dc94c
Author: Dan Haywood <da...@apache.org>
Authored: Wed Mar 6 08:36:10 2013 +0000
Committer: Dan Haywood <da...@apache.org>
Committed: Wed Mar 6 08:36:10 2013 +0000

----------------------------------------------------------------------
 .../domainobjects/DomainServiceResource.java       |   10 +-
 .../applib/util/UrlEncodingUtils.java              |    7 +-
 .../resources/DomainServiceResourceServerside.java |    8 +-
 .../tck/src/main/webapp/WEB-INF/isis.properties    |    6 +-
 .../restfulobjects/tck/RepresentationMatchers.java |   15 ++
 .../invoke/DomainServiceTest_action_invoke.java    |   98 ------------
 .../invoke/DomainServiceTest_safe_noarg_list.java  |  106 +++++++++++++
 .../DomainServiceTest_safe_simplearg_list.java     |  123 +++++++++++++++
 .../core/tck/dom/AbstractEntityRepository.java     |    4 +-
 .../isis/core/tck/dom/actions/ActionsEntity.java   |   76 +++++++++
 .../tck/dom/actions/ActionsEntityRepository.java   |   62 ++++++++
 .../tck/fixture/actions/ActionsEntityFixture.java  |   52 ++++++
 .../fixture/busrules/BusRulesEntityFixture.java    |    2 +-
 13 files changed, 462 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
index 29de6cd..627ef4a 100644
--- a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
+++ b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
@@ -75,11 +76,18 @@ public interface DomainServiceResource {
     // domain service action invoke
     // //////////////////////////////////////////////////////////
 
+    /**
+     * Because it isn't possible with the RestEasy client-side framework to specify a query string nor to pass arbitrary query params; instead 
+     * we provide an additional syntax of passing an Isis-defined query param <tt>x-isis-querystring</tt>.
+     * 
+     * <p>
+     * The content of this is taken to be the URL encoded map of arguments.
+     */
     @GET
     @Path("/{serviceId}/actions/{actionId}/invoke")
     @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
     @ClientResponseType(entityType = String.class)
-    public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+    public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, @QueryParam("x-isis-querystring") final String xIsisQueryString);
 
     @PUT
     @Path("/{serviceId}/actions/{actionId}/invoke")

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/UrlEncodingUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/UrlEncodingUtils.java b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/UrlEncodingUtils.java
index c21fb2a..63e73c7 100644
--- a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/UrlEncodingUtils.java
+++ b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/UrlEncodingUtils.java
@@ -24,6 +24,7 @@ import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.codehaus.jackson.JsonNode;
 
 import com.google.common.base.Charsets;
@@ -61,7 +62,11 @@ public final class UrlEncodingUtils {
     }
 
     public static String urlEncode(final JsonNode jsonNode) {
-        return UrlEncodingUtils.urlEncode(jsonNode.toString());
+        return urlEncode(jsonNode.toString());
+    }
+
+    public static String urlEncode(final JsonRepresentation jsonRepresentation ) {
+        return urlEncode(jsonRepresentation.toString());
     }
 
     public static String urlEncode(final String str) {

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
index 86156ef..da3254a 100644
--- a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
+++ b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
@@ -26,6 +26,7 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
@@ -125,11 +126,12 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
     @GET
     @Path("/{serviceId}/actions/{actionId}/invoke")
     @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
-    public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId) {
+    public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, @QueryParam("x-isis-querystring") final String xIsisQueryString) {
         init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES);
 
-        final JsonRepresentation arguments = getResourceContext().getQueryStringAsJsonRepr();
-
+        final JsonRepresentation arguments = DomainResourceHelper.readQueryStringAsMap(
+                xIsisQueryString != null? xIsisQueryString : getResourceContext().getQueryString());
+        
         final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
         final DomainResourceHelper helper = new DomainResourceHelper(getResourceContext(), serviceAdapter).using(new DomainServiceLinkTo());
 

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/tck/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/main/webapp/WEB-INF/isis.properties b/component/viewer/restfulobjects/tck/src/main/webapp/WEB-INF/isis.properties
index 03b05ca..0734bb7 100644
--- a/component/viewer/restfulobjects/tck/src/main/webapp/WEB-INF/isis.properties
+++ b/component/viewer/restfulobjects/tck/src/main/webapp/WEB-INF/isis.properties
@@ -39,7 +39,8 @@ isis.services =\
     refs.UnidirReferencingEntityRepository,\
     defaults.WithDefaultsEntityRepository,\
     defaults.HiddenRepository,\
-    busrules.BusRulesEntityRepository
+    busrules.BusRulesEntityRepository,\
+    actions.ActionsEntityRepository
 
 
 isis.fixtures.prefix= org.apache.isis.core.tck.fixture
@@ -51,6 +52,7 @@ isis.fixtures=\
     scalars.WrapperValuedEntityFixture,\
     refs.ParentEntitiesFixture,\
     defaults.WithDefaultsEntityFixture,\
-    busrules.BusRulesEntityFixture
+    busrules.BusRulesEntityFixture,\
+    actions.ActionsEntityFixture
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/RepresentationMatchers.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/RepresentationMatchers.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/RepresentationMatchers.java
index 6b1957d..b9cc167 100644
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/RepresentationMatchers.java
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/RepresentationMatchers.java
@@ -509,4 +509,19 @@ public class RepresentationMatchers {
         };
     }
 
+    public static Matcher<? super JsonRepresentation> mapHas(final String key) {
+        return new TypeSafeMatcher<JsonRepresentation>() {
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("is a map with key '" + key + "'");
+            }
+
+            @Override
+            protected boolean matchesSafely(JsonRepresentation item) {
+                return item.mapHas(key);
+            }
+        };
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_action_invoke.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_action_invoke.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_action_invoke.java
deleted file mode 100644
index f7ce101..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_action_invoke.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.viewer.restfulobjects.tck.domainservice.serviceId.action.invoke;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.Rel;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ListRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
-import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
-import org.apache.isis.viewer.restfulobjects.tck.Util;
-
-import static org.apache.isis.viewer.restfulobjects.tck.RepresentationMatchers.*;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-public class DomainServiceTest_action_invoke {
-
-    @Rule
-    public IsisWebServerRule webServerRule = new IsisWebServerRule();
-
-    private RestfulClient client;
-
-    @SuppressWarnings("unused")
-    private DomainServiceResource resource;
-
-    @Before
-    public void setUp() throws Exception {
-        client = webServerRule.getClient();
-
-        resource = client.getDomainServiceResource();
-    }
-
-    @Test
-    public void invokeQueryOnly_noArg_usingClientFollow_returning_list() throws Exception {
-
-        // given
-        final JsonRepresentation givenAction = Util.givenAction(client, "ParentEntities", "list");
-        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
-
-        // when
-        final LinkRepresentation invokeLink = actionRepr.getInvoke();
-
-        // then
-        assertThat(invokeLink, isLink(client)
-                                    .rel(Rel.INVOKE)
-                                    .httpMethod(RestfulHttpMethod.GET)
-                                    .href(Matchers.endsWith(":39393/services/ParentEntities/actions/list/invoke"))
-                                    .arguments(JsonRepresentation.newMap())
-                                    .build());
-        
-        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink);
-        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
-        
-        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
-        
-        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
-
-        assertThat(listRepr.getValue().size(), is(5));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_noarg_list.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_noarg_list.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_noarg_list.java
new file mode 100644
index 0000000..ff07257
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_noarg_list.java
@@ -0,0 +1,106 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.restfulobjects.tck.domainservice.serviceId.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RepresentationMatchers.isLink;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ListRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DomainServiceTest_safe_noarg_list {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void invokeQueryOnly_noArg_usingClientFollow_returning_list() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "list");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+
+        assertThat(invokeLink, isLink(client)
+                                    .rel(Rel.INVOKE)
+                                    .httpMethod(RestfulHttpMethod.GET)
+                                    .href(Matchers.endsWith(":39393/services/ActionsEntities/actions/list/invoke"))
+                                    .arguments(JsonRepresentation.newMap())
+                                    .build());
+        
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink);
+        
+        // then
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
+        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
+        assertThat(listRepr.getValue().size(), is(5));
+    }
+
+    
+    @Test
+    public void invokeQueryOnly_noArg_usingResourceProxy_returning_list() throws Exception {
+
+        // given, when
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "list", null);
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        // then
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
+        
+        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
+
+        assertThat(listRepr.getValue().size(), is(5));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_simplearg_list.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_simplearg_list.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_simplearg_list.java
new file mode 100644
index 0000000..2de1f28
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainservice/serviceId/action/invoke/DomainServiceTest_safe_simplearg_list.java
@@ -0,0 +1,123 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.restfulobjects.tck.domainservice.serviceId.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RepresentationMatchers.isLink;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ListRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.RepresentationMatchers;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DomainServiceTest_safe_simplearg_list {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void invokeQueryOnly_noArg_usingClientFollow_returning_list() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "subList");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+
+        assertThat(invokeLink, isLink(client)
+                                    .rel(Rel.INVOKE)
+                                    .httpMethod(RestfulHttpMethod.GET)
+                                    .href(Matchers.endsWith(":39393/services/ActionsEntities/actions/subList/invoke"))
+                                    .build());
+        
+        JsonRepresentation args =invokeLink.getArguments();
+        assertThat(args.size(), is(2));
+        assertThat(args, RepresentationMatchers.mapHas("from"));
+        assertThat(args, RepresentationMatchers.mapHas("to"));
+        
+        // when
+        args.mapPut("from", 1);
+        args.mapPut("to", 3);
+
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
+        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
+        assertThat(listRepr.getValue().size(), is(2));
+    }
+
+
+    @Ignore("up to here...")
+    @Test
+    public void invokeQueryOnly_noArg_usingResourceProxy_returning_list() throws Exception {
+
+        // given, when
+        JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("from", 1);
+        args.mapPut("to", 3);
+        String xIsisQueryString = UrlEncodingUtils.urlEncode(args);
+        
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "subList", xIsisQueryString);
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        // then
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
+        
+        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
+
+        assertThat(listRepr.getValue().size(), is(2));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/AbstractEntityRepository.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/AbstractEntityRepository.java b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/AbstractEntityRepository.java
index 92792fd..d6b6a24 100644
--- a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/AbstractEntityRepository.java
+++ b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/AbstractEntityRepository.java
@@ -23,9 +23,11 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.ActionSemantics;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.QueryOnly;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.query.QueryDefault;
 
@@ -44,7 +46,7 @@ public abstract class AbstractEntityRepository<T> extends AbstractFactoryAndRepo
         return serviceId;
     }
 
-    @QueryOnly
+    @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence = "1")
     public List<T> list() {
         return allInstances(entityClass);

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntity.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntity.java b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntity.java
new file mode 100644
index 0000000..2f4ed64
--- /dev/null
+++ b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntity.java
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.tck.dom.actions;
+
+import org.apache.isis.applib.AbstractDomainObject;
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.Disabled;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.ObjectType;
+
+@javax.jdo.annotations.PersistenceCapable
+@javax.jdo.annotations.Discriminator("RTNE")
+@ObjectType("RTNE")
+public class ActionsEntity extends AbstractDomainObject {
+
+    // {{ Id (Integer)
+    private Integer id;
+
+    @javax.jdo.annotations.PrimaryKey // must be on the getter.
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(final Integer id) {
+        this.id = id;
+    }
+    // }}
+
+    // {{ Title
+    public String title() {
+        return null;
+    }
+    // }}
+
+
+
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity visibleAndInvokableAction() {
+        return this;
+    }
+
+    @Disabled
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity visibleButUninvokableAction() {
+        return this;
+    }
+
+    @Hidden
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity invisibleAction() {
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
new file mode 100644
index 0000000..88c2b9a
--- /dev/null
+++ b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.tck.dom.actions;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.ObjectType;
+import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.core.tck.dom.AbstractEntityRepository;
+
+@Named("ActionsEntities")
+@ObjectType("ActionsEntities")
+public class ActionsEntityRepository extends AbstractEntityRepository<ActionsEntity> {
+
+    public ActionsEntityRepository() {
+        super(ActionsEntity.class, "ActionsEntities");
+    }
+
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity findById(int id) {
+        final Query<ActionsEntity> query = 
+                new QueryDefault<ActionsEntity>(ActionsEntity.class, ActionsEntity.class.getName() + "#pk", "id", id);
+        return this.firstMatch(query);
+    }
+
+
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public List<ActionsEntity> subList(@Named("from") int from, @Named("to") int to) {
+        List<ActionsEntity> list = list();
+        int toChecked = Math.min(to, list.size());
+        int fromChecked = Math.min(from, toChecked);
+        return list.subList(fromChecked, toChecked);
+    }
+
+
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/actions/ActionsEntityFixture.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/actions/ActionsEntityFixture.java b/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/actions/ActionsEntityFixture.java
new file mode 100644
index 0000000..2a5e6ad
--- /dev/null
+++ b/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/actions/ActionsEntityFixture.java
@@ -0,0 +1,52 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.tck.fixture.actions;
+
+import org.apache.isis.applib.fixtures.AbstractFixture;
+import org.apache.isis.core.tck.dom.actions.ActionsEntity;
+import org.apache.isis.core.tck.dom.actions.ActionsEntityRepository;
+import org.apache.isis.core.tck.dom.busrules.BusRulesEntity;
+import org.apache.isis.core.tck.dom.busrules.BusRulesEntityRepository;
+
+public class ActionsEntityFixture extends AbstractFixture {
+
+    @Override
+    public void install() {
+        createEntity(1);
+        createEntity(2);
+        createEntity(3);
+        createEntity(4);
+        createEntity(5);
+    }
+
+    private ActionsEntity createEntity(Integer id) {
+        final ActionsEntity entity = repository.newEntity();
+        entity.setId(id);
+        return entity;
+    }
+
+    // {{ injected: ActionSemanticsEntityRepository
+    private ActionsEntityRepository repository;
+
+    public void setActionSemanticsEntityRepository(final ActionsEntityRepository repository) {
+        this.repository = repository;
+    }
+    // }}
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/3c2564f1/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/busrules/BusRulesEntityFixture.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/busrules/BusRulesEntityFixture.java b/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/busrules/BusRulesEntityFixture.java
index e31578e..39a84c4 100644
--- a/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/busrules/BusRulesEntityFixture.java
+++ b/core/tck/tck-fixture/src/main/java/org/apache/isis/core/tck/fixture/busrules/BusRulesEntityFixture.java
@@ -39,7 +39,7 @@ public class BusRulesEntityFixture extends AbstractFixture {
         return entity;
     }
 
-    // {{ injected: WithDefaultsEntityRepository
+    // {{ injected: BusRulesEntityRepository
     private BusRulesEntityRepository repository;
 
     public void setBusRulesEntityRepository(final BusRulesEntityRepository repository) {