Skip to content

Commit 03d84d2

Browse files
author
Vitaliy
authored
Merge pull request #159 from konarshankar07/schema-graphql-resolver-inspection--task-35
#35 :- Inspection. GraphQL resolver should implement Resolver interface
2 parents 8e0c566 + e15af0c commit 03d84d2

File tree

19 files changed

+290
-44
lines changed

19 files changed

+290
-44
lines changed

resources/META-INF/withJsGraphQl.xml

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
<!--
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
-->
7+
18
<idea-plugin>
29
<extensions defaultExtensionNs="com.intellij">
310
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.graphql.GraphQlResolverIndex" />
@@ -9,5 +16,11 @@
916
enabledByDefault="true"
1017
level="ERROR"
1118
implementationClass="com.magento.idea.magento2plugin.inspections.php.GraphQlResolverInspection"/>
19+
<localInspection language="GraphQL" groupPath="GraphQL"
20+
shortName="SchemaResolverInspection" displayName="Schema Resolver must implements ResolverInterface"
21+
groupName="Magento 2"
22+
enabledByDefault="true"
23+
level="ERROR"
24+
implementationClass="com.magento.idea.magento2plugin.inspections.graphqls.SchemaResolverInspection"/>
1225
</extensions>
1326
</idea-plugin>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
-->
7+
<html>
8+
<body>
9+
<p>
10+
This inspection detects the invalid resolver interface in schema.graphqls files
11+
</p>
12+
</body>
13+
</html>

resources/magento2/inspection.properties

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
inspection.class.hierarchyImplementationCheck=Class must implement {0}
2-
inspection.class.hierarchyExtendingCheck=Class must extend {0}
31
inspection.plugin.duplicateInSameFile=The plugin name already used in this file. For more details see Inspection Description.
42
inspection.plugin.duplicateInOtherPlaces=The plugin name "{0}" for targeted "{1}" class is already used in the module "{2}" ({3} scope). For more details see Inspection Description.
53
inspection.graphql.resolver.mustImplement=Class must implements any of the following interfaces: \\Magento\\Framework\\GraphQl\\Query\\ResolverInterface, \\Magento\\Framework\\GraphQl\\Query\\Resolver\\BatchResolverInterface, \\Magento\\Framework\\GraphQl\\Query\\Resolver\\BatchServiceContractResolverInterface
4+
inspection.graphql.resolver.notExist=Resolver class do not exist
65
inspection.graphql.resolver.fix.family=Implement Resolver interface
76
inspection.graphql.resolver.fix.title=Select one of the following interface
87
inspection.plugin.error.nonPublicMethod=You can't declare a plugin for a not public method.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.inspections.graphqls;
7+
8+
import com.intellij.codeInspection.LocalInspectionTool;
9+
import com.intellij.codeInspection.ProblemHighlightType;
10+
import com.intellij.codeInspection.ProblemsHolder;
11+
import com.intellij.lang.jsgraphql.psi.GraphQLValue;
12+
import com.intellij.lang.jsgraphql.psi.GraphQLVisitor;
13+
import com.jetbrains.php.lang.psi.elements.PhpClass;
14+
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
15+
import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
16+
import com.magento.idea.magento2plugin.util.magento.graphql.GraphQlUtil;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
public class SchemaResolverInspection extends LocalInspectionTool {
20+
21+
private final InspectionBundle inspectionBundle = new InspectionBundle();
22+
23+
@NotNull
24+
@Override
25+
public GraphQLVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
26+
return new GraphQLVisitor() {
27+
@Override
28+
public void visitValue(@NotNull GraphQLValue element) {
29+
String getVisitedElementValue = element.getText();
30+
if (getVisitedElementValue == null) {
31+
return;
32+
}
33+
34+
String resolverFQN = GraphQlUtil.resolverStringToPhpFQN(getVisitedElementValue);
35+
GetPhpClassByFQN getPhpClassByFQN = GetPhpClassByFQN.getInstance(holder.getProject());
36+
PhpClass resolverClass = getPhpClassByFQN.execute(resolverFQN);
37+
if (resolverClass == null) {
38+
holder.registerProblem(element,
39+
inspectionBundle.message(
40+
"inspection.graphql.resolver.notExist"
41+
),
42+
ProblemHighlightType.ERROR);
43+
return;
44+
}
45+
if (!GraphQlUtil.isResolver(resolverClass)) {
46+
holder.registerProblem(element,
47+
inspectionBundle.message(
48+
"inspection.graphql.resolver.mustImplement"
49+
),
50+
ProblemHighlightType.ERROR);
51+
}
52+
}
53+
};
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
package com.magento.idea.magento2plugin.magento.files;
6+
7+
public class GraphQLSchema {
8+
public static String FILE_NAME = "schema.graphqls";
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Query {
5+
test(input: test!): test @resolver(class: "\\Magento\\Backend\\Model\\Source\\YesNo") @doc(description: "Test")
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Query {
5+
test(input: test!): test @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\ImplementsBatchResolverInterface") @doc(description: "Test")
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Query {
5+
test(input: test!): test @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\ImplementsBatchServiceContractResolverInterface") @doc(description: "Test")
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright © Magento, Inc. All rights reserved.
2+
# See COPYING.txt for license details.
3+
4+
type Query {
5+
test(input: test!): test @resolver(class: "\\Magento\\CatalogGraphQl\\Model\\Resolver\\ImplementsResolverInterface") @doc(description: "Test")
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Query\Resolver\BatchResolverInterface;
11+
12+
class ImplementsBatchResolverInterface implements BatchResolverInterface
13+
{
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Query\Resolver\BatchServiceContractResolverInterface;
11+
12+
class ImplementsBatchServiceContractResolverInterface implements BatchServiceContractResolverInterface
13+
{
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Query\ResolverInterface;
11+
12+
class ImplementsResolverInterface implements ResolverInterface
13+
{
14+
}

tests/com/magento/idea/magento2plugin/BaseProjectTestCase.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
99
import com.magento.idea.magento2plugin.indexes.IndexManager;
1010
import com.magento.idea.magento2plugin.project.Settings;
11-
import com.magento.idea.magento2plugin.project.util.GetProjectBasePath;
1211
import com.magento.idea.magento2plugin.magento.packages.File;
1312

1413
/**
@@ -65,4 +64,5 @@ protected String prepareFixturePath(String fileName, String fixturesFolderPath)
6564
private String name() {
6665
return StringUtil.trimEnd(getTestName(true), "Test");
6766
}
67+
6868
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
package com.magento.idea.magento2plugin.inspections;
6+
7+
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
8+
import com.magento.idea.magento2plugin.BaseProjectTestCase;
9+
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
10+
import java.util.List;
11+
12+
/**
13+
* Configure test environment with Magento 2 project
14+
*/
15+
abstract public class BaseInspectionsTestCase extends BaseProjectTestCase {
16+
protected final InspectionBundle inspectionBundle = new InspectionBundle();
17+
18+
protected void assertHasHighlighting(String message) {
19+
String highlightingNotFound = "Failed that documents contains highlighting with the description `%s`";
20+
21+
List<HighlightInfo> highlightingList = myFixture.doHighlighting();
22+
if (highlightingList.isEmpty()) {
23+
fail(String.format(highlightingNotFound, message));
24+
}
25+
26+
for (HighlightInfo highlighting :
27+
highlightingList) {
28+
if (highlighting.getDescription() == null) continue;
29+
if (highlighting.getDescription().equals(message)) {
30+
return;
31+
}
32+
}
33+
fail(String.format(highlightingNotFound, message));
34+
}
35+
36+
protected void assertHasNoHighlighting(String message) {
37+
String highlightingNotFound = "Failed that documents not contains highlighting with the description `%s`";
38+
39+
List<HighlightInfo> highlightingList = myFixture.doHighlighting();
40+
if (highlightingList.isEmpty()) {
41+
return;
42+
}
43+
44+
for (HighlightInfo highlighting :
45+
highlightingList) {
46+
if (highlighting.getDescription() == null) continue;
47+
if (highlighting.getDescription().equals(message)) {
48+
fail(String.format(highlightingNotFound, message));
49+
}
50+
}
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.inspections.graphqls;
7+
8+
import com.magento.idea.magento2plugin.inspections.BaseInspectionsTestCase;
9+
import com.magento.idea.magento2plugin.magento.packages.File;
10+
11+
abstract public class InspectionGraphqlsFixtureTestCase extends BaseInspectionsTestCase {
12+
13+
private static final String testDataFolderPath = "testData" + File.separator + "inspections" + File.separator;
14+
private static final String fixturesFolderPath = "graphqls" + File.separator;
15+
16+
@Override
17+
protected void setUp() throws Exception {
18+
super.setUp();
19+
myFixture.setTestDataPath(testDataFolderPath);
20+
}
21+
22+
@Override
23+
protected boolean isWriteActionRequired() {
24+
return false;
25+
}
26+
27+
protected String getFixturePath(String fileName) {
28+
return prepareFixturePath(fileName, fixturesFolderPath);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
package com.magento.idea.magento2plugin.inspections.graphqls;
6+
7+
import com.magento.idea.magento2plugin.magento.files.GraphQLSchema;
8+
9+
public class SchemaResolverInspectionTest extends InspectionGraphqlsFixtureTestCase {
10+
11+
private final String errorMessage = inspectionBundle.message(
12+
"inspection.graphql.resolver.mustImplement"
13+
);
14+
15+
@Override
16+
public void setUp() throws Exception {
17+
super.setUp();
18+
myFixture.enableInspections(SchemaResolverInspection.class);
19+
}
20+
21+
protected boolean isWriteActionRequired() {
22+
return false;
23+
}
24+
25+
public void testWithValidSchemaResolverInterface() throws Exception {
26+
myFixture.configureByFile(getFixturePath(GraphQLSchema.FILE_NAME));
27+
assertHasNoHighlighting(errorMessage);
28+
}
29+
30+
public void testWithInvalidSchemaResolverInterface() throws Exception {
31+
myFixture.configureByFile(getFixturePath(GraphQLSchema.FILE_NAME));
32+
assertHasHighlighting(errorMessage);
33+
}
34+
35+
public void testWithValidBatchResolverInterface() throws Exception {
36+
myFixture.configureByFile(getFixturePath(GraphQLSchema.FILE_NAME));
37+
38+
assertHasNoHighlighting(errorMessage);
39+
}
40+
41+
public void testWithValidBatchServiceContractResolverInterface() throws Exception {
42+
myFixture.configureByFile(getFixturePath(GraphQLSchema.FILE_NAME));
43+
44+
assertHasNoHighlighting(errorMessage);
45+
}
46+
}

tests/com/magento/idea/magento2plugin/inspections/php/GraphQlResolverInspectionTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
public class GraphQlResolverInspectionTest extends InspectionPhpFixtureTestCase {
1010

11-
private final InspectionBundle inspectionBundle = new InspectionBundle();
1211
private final String errorMessage = inspectionBundle.message(
1312
"inspection.graphql.resolver.mustImplement"
1413
);

tests/com/magento/idea/magento2plugin/inspections/php/InspectionPhpFixtureTestCase.java

+2-37
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
*/
55
package com.magento.idea.magento2plugin.inspections.php;
66

7-
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
8-
import com.magento.idea.magento2plugin.BaseProjectTestCase;
7+
import com.magento.idea.magento2plugin.inspections.BaseInspectionsTestCase;
98
import com.magento.idea.magento2plugin.magento.packages.File;
10-
import java.util.List;
119

12-
abstract public class InspectionPhpFixtureTestCase extends BaseProjectTestCase {
10+
abstract public class InspectionPhpFixtureTestCase extends BaseInspectionsTestCase {
1311

1412
private static final String testDataFolderPath = "testData" + File.separator + "inspections" + File.separator;
1513
private static final String fixturesFolderPath = "php" + File.separator;
@@ -28,37 +26,4 @@ protected boolean isWriteActionRequired() {
2826
protected String getFixturePath(String fileName) {
2927
return prepareFixturePath(fileName, fixturesFolderPath);
3028
}
31-
32-
protected void assertHasHighlighting(String message) {
33-
String highlightingNotFound = "Failed that documents contains highlighting with the description `%s`";
34-
35-
List<HighlightInfo> highlightingList = myFixture.doHighlighting();
36-
if (highlightingList.isEmpty()) {
37-
fail(String.format(highlightingNotFound, message));
38-
}
39-
40-
for (HighlightInfo highlighting :
41-
highlightingList) {
42-
if (highlighting.getDescription().equals(message)) {
43-
return;
44-
}
45-
}
46-
fail(String.format(highlightingNotFound, message));
47-
}
48-
49-
protected void assertHasNoHighlighting(String message) {
50-
String highlightingFound = "Failed that documents not contains highlighting with the description `%s`";
51-
52-
List<HighlightInfo> highlightingList = myFixture.doHighlighting();
53-
if (highlightingList.isEmpty()) {
54-
return;
55-
}
56-
57-
for (HighlightInfo highlighting :
58-
highlightingList) {
59-
if (highlighting.getDescription().equals(message)) {
60-
fail(String.format(highlightingFound, message));
61-
}
62-
}
63-
}
6429
}

0 commit comments

Comments
 (0)