You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2020/06/02 15:14:42 UTC

[sling-org-apache-sling-graphql-core] branch master updated: SLING-9479 - add SchemaDescriptionsTest

This is an automated email from the ASF dual-hosted git repository.

bdelacretaz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-graphql-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 218d8da  SLING-9479 - add SchemaDescriptionsTest
218d8da is described below

commit 218d8da1a0cb9ccb4d14dde3280030618d9bcde0
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Tue Jun 2 17:12:39 2020 +0200

    SLING-9479 - add SchemaDescriptionsTest
---
 .../core/schema/SchemaDescriptionsTest.java        | 139 +++++++++++++++++++++
 src/test/resources/test-schema.txt                 |  17 ++-
 2 files changed, 153 insertions(+), 3 deletions(-)

diff --git a/src/test/java/org/apache/sling/graphql/core/schema/SchemaDescriptionsTest.java b/src/test/java/org/apache/sling/graphql/core/schema/SchemaDescriptionsTest.java
new file mode 100644
index 0000000..3b25042
--- /dev/null
+++ b/src/test/java/org/apache/sling/graphql/core/schema/SchemaDescriptionsTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.sling.graphql.core.schema;
+
+import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.UUID;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.graphql.api.SchemaProvider;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.hamcrest.CustomMatcher;
+import org.hamcrest.Matcher;
+import org.apache.sling.graphql.core.engine.GraphQLResourceQuery;
+import org.apache.sling.graphql.core.json.JsonSerializer;
+import org.apache.sling.graphql.core.mocks.MockSchemaProvider;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import graphql.ExecutionResult;
+import net.minidev.json.JSONArray;
+
+/**
+ * Test the fields descriptions which are part of the schema as per
+ * http://spec.graphql.org/June2018/#sec-Descriptions
+ * 
+ * Created for SLING-9479, to verify that our fetch: schema annotations
+ * are ignored if separated from their types or fields by a comment line
+ * containing just a hash character.
+ */
+public class SchemaDescriptionsTest {
+    private SchemaProvider schemaProvider = new MockSchemaProvider("test-schema");
+    private DataFetcherSelector dataFetchersSelector;
+    private Resource resource;
+    private String schemaJson;
+
+    private static final String SCHEMA_QUERY = "{ __schema { types { name description fields { name description }}}}";
+
+    @Rule
+    public final OsgiContext context = new OsgiContext();
+
+    /** Haven't been able to get rid of the JSONArray in selected paths */
+    static class DescriptionMatcher extends CustomMatcher<String> {
+
+        private String toMatch;
+
+        DescriptionMatcher(String toMatch) {
+            super(toMatch);
+            this.toMatch = stripSpace(toMatch);
+        }
+
+        static String stripSpace(String str) {
+            return str.replaceAll("\\s+", " ").trim();
+        }
+
+        @Override
+        public boolean matches(Object item) {
+            String itemStr = null;
+            if(item instanceof JSONArray) {
+                itemStr = String.valueOf(((JSONArray)item).get(0));
+            } else {
+                itemStr = String.valueOf(item);
+            }
+            return toMatch.equals(stripSpace(itemStr));
+        }
+    }
+
+    static Matcher<String> descriptionEquals(String str) {
+        return new DescriptionMatcher(str);
+    }
+    
+    @Before
+    public void setup()  throws Exception {
+        final String resourceType = "RT-" + UUID.randomUUID();
+        final String path = "/some/path/" + UUID.randomUUID();
+        resource = Mockito.mock(Resource.class);
+        Mockito.when(resource.getPath()).thenReturn(path);
+        Mockito.when(resource.getResourceType()).thenReturn(resourceType);
+        dataFetchersSelector = new DataFetcherSelector(context.bundleContext());
+        schemaJson = queryJSON(SCHEMA_QUERY);
+    }
+
+    private String queryJSON(String stmt) throws Exception {
+        final ExecutionResult result = new GraphQLResourceQuery().executeQuery(schemaProvider,
+            dataFetchersSelector, resource, null, stmt, null);
+        assertTrue("Expecting no errors: " + result.getErrors(), result.getErrors().isEmpty());
+        return new JsonSerializer().toJSON(result);
+    }
+
+    private void assertTypeDescription(String typeName, String expected) {
+        final String path = String.format("$.data.__schema.types[?(@.name=='%s')].description", typeName);
+        assertThat(schemaJson, hasJsonPath(path, descriptionEquals(expected)));
+    }
+
+    private void assertFieldDescription(String typeName, String fieldName, String expected) {
+        final String path = String.format(
+            "$.data.__schema.types[?(@.name=='%s')].fields[?(@.name=='%s')].description", 
+            typeName,
+            fieldName);
+        assertThat(schemaJson, hasJsonPath(path, descriptionEquals(expected)));
+    }
+
+    @Test
+    public void verifyTypesDescriptions() {
+        assertTypeDescription("Query", " A blank line without leading hash does NOT dissociate the comments from the type that follows. GraphQL Schema used for our tests annotated with our fetch: definitions");
+        assertTypeDescription("SlingResource", "SlingResource, for our tests");
+        assertTypeDescription("Test", "null");
+    }
+
+    @Test
+    public void verifyFieldDescriptions() {
+        assertFieldDescription("Query", "staticContent", "Test some static values");
+        assertFieldDescription("SlingResource", "pathMD5", "null");
+        assertFieldDescription("SlingResource", "pathSHA256", "SHA256 digest of the path");
+        assertFieldDescription("SlingResource", "failure", "# fetch:failure/fail Failure message - the above fetch: statement is included in the description as it's not separated by an empty comment.");
+        assertFieldDescription("Test", "test", "null");
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/test-schema.txt b/src/test/resources/test-schema.txt
index 5959e1a..0821e3f 100644
--- a/src/test/resources/test-schema.txt
+++ b/src/test/resources/test-schema.txt
@@ -15,9 +15,16 @@
 # * specific language governing permissions and limitations
 # * under the License.
 
+# Note the use of empty comment lines, like the one that follows
+# this, to dissociate comments from the types or fields
+# that follow.
+#
+
+# A blank line without leading hash does NOT dissociate the comments
+# from the type that follows.
+
 # GraphQL Schema used for our tests
 # annotated with our fetch: definitions
-
 type Query {
     ## fetch:echoNS/echo
     #
@@ -25,9 +32,13 @@ type Query {
 
     ## fetch:test/static
     #
+    # Test some static values
     staticContent: Test
 }
 
+# This should be omitted from the SlingResource type description
+#
+# SlingResource, for our tests
 type SlingResource { 
     path: String
     resourceType: String
@@ -51,8 +62,8 @@ type SlingResource {
     nullValue: String
 
     ## fetch:failure/fail
-    #
-    # Failure message
+    # Failure message - the above fetch: statement is included in the
+    # description as it's not separated by an empty comment.
     failure: String
 }