Skip to content

Commit

Permalink
Add integration tests for GraphQL tool
Browse files Browse the repository at this point in the history
  • Loading branch information
DimuthuMadushan committed Sep 11, 2023
1 parent d0de77e commit 1328082
Show file tree
Hide file tree
Showing 15 changed files with 665 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com) All Rights Reserved.
*
* WSO2 LLC. 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.ballerinalang.distribution.test;

import org.ballerinalang.distribution.utils.TestUtils;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;

import static org.ballerinalang.distribution.utils.TestUtils.*;

public class GraphqlToolTest {

@BeforeClass
public void setupDistributions() throws IOException {
TestUtils.cleanDistribution();
TestUtils.prepareDistribution(DISTRIBUTIONS_DIR.resolve(DISTRIBUTION_FILE_NAME + ".zip"));
}

@Test(description = "Check GraphQL client generation")
public void testGraphqlClientGenerationUsingEndpoint() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/client-gen/project_1");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("graphql_endpoint.config.yaml");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("client.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("types.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("config_types.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("utils.bal")));
TestUtils.deleteGeneratedFiles("client.bal", GRAPHQL_CMD);
}

@Test(description = "Check GraphQL client generation")
public void testGraphqlClientGenerationUsingSchemaFile() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/client-gen/project_2");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("graphql_schema.config.yaml");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("client.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("types.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("config_types.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("utils.bal")));
TestUtils.deleteGeneratedFiles("client.bal", GRAPHQL_CMD);
}

@Test(description = "Check GraphQL schema generation")
public void testGraphqlSchemaGeneration() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/schema-gen");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("service.bal");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("schema_graphql.graphql")));
TestUtils.deleteGeneratedFiles("schema_graphql.graphql", GRAPHQL_CMD);
}

@Test(description = "Check GraphQL schema generation")
public void testGraphqlSchemaGenerationWithServicePathFlag() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/schema-gen/project_1");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("main.bal");
buildArgs.add("-s");
buildArgs.add("/gql");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("schema_gql.graphql")));
TestUtils.deleteGeneratedFiles("schema_gql.graphql", GRAPHQL_CMD);
}

@Test(description = "Check GraphQL service generation")
public void testGraphqlServiceGeneration() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/service-gen");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("schema_starwars.graphql");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("service.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("types.bal")));
TestUtils.deleteGeneratedFiles("service.bal", GRAPHQL_CMD);
}

@Test(description = "Check GraphQL service generation")
public void testGraphqlServiceGenerationWithRecordFlag() throws IOException, InterruptedException {
Path testResource = Paths.get("/graphql/service-gen");
List<String> buildArgs = new LinkedList<>();
buildArgs.add("-i");
buildArgs.add("schema_book.graphql");
buildArgs.add("-r");
boolean successful = TestUtils.executeGraphql(DISTRIBUTION_FILE_NAME, TestUtils.getResource(testResource),
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("service.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("types.bal")));
TestUtils.deleteGeneratedFiles("service.bal", GRAPHQL_CMD);
}

@AfterClass
public void cleanUp() throws IOException {
TestUtils.cleanDistribution();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void buildOpenAPIToBallerinaTest() throws IOException, InterruptedExcepti
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("petstore_service.bal")));
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("client.bal")));
TestUtils.deleteGeneratedFiles("petstore");
TestUtils.deleteGeneratedFiles("petstore", OPENAPI_CMD);
}

@Test(description = "Check openapi to ballerina generator command with service file only.")
Expand All @@ -78,7 +78,7 @@ public void buildOpenAPIToBallerinaServiceFileGenerationTest() throws IOExceptio
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("petstore_service.bal")));
TestUtils.deleteGeneratedFiles("petstore");
TestUtils.deleteGeneratedFiles("petstore", OPENAPI_CMD);
}

@Test(description = "Check openapi to ballerina generator command for given tags")
Expand Down Expand Up @@ -114,7 +114,7 @@ public void buildOpenAPIToBallerinaWithFilterTagsTest() throws IOException,
Assert.fail("Expected content and actual generated content is mismatched for: petstoreTags.yaml");
}
//Clean the generated files
TestUtils.deleteGeneratedFiles("petstoretags");
TestUtils.deleteGeneratedFiles("petstoretags", OPENAPI_CMD);
}
}

Expand Down Expand Up @@ -149,7 +149,7 @@ public void buildOpenAPIToBallerinaClientGenerationTests() throws IOException,
Assert.assertEquals(expectedTypes, generatedTypes);
Assert.assertEquals(expectedUtils, generatedUtils);

TestUtils.deleteGeneratedFiles("client.bal");
TestUtils.deleteGeneratedFiles("client.bal", OPENAPI_CMD);
} else {
Assert.fail("Client generation failed");
}
Expand All @@ -165,7 +165,7 @@ public void buildBallerinaToOpenAPITest() throws IOException, InterruptedExcepti
buildArgs);
Assert.assertTrue(successful);
Assert.assertTrue(Files.exists(TestUtils.getResource(testResource).resolve("hello_openapi.yaml")));
TestUtils.deleteGeneratedFiles("hello_openapi.yaml");
TestUtils.deleteGeneratedFiles("hello_openapi.yaml", OPENAPI_CMD);
}

//OpenAPI integration tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class TestUtils {
public static final String WHITESPACE_PATTERN = "\\s+";
private static String balFile = "bal";
public static final String DISTRIBUTION_FILE_NAME = "ballerina-" + MAVEN_VERSION + "-" + CODE_NAME;
public static final String OPENAPI_CMD = "openapi";
public static final String GRAPHQL_CMD = "graphql";

/**
* Log the output of an input stream.
Expand Down Expand Up @@ -149,7 +151,27 @@ public static InputStream executeGrpcCommand(String distributionName, Path sourc
*/
public static boolean executeOpenAPI(String distributionName, Path sourceDirectory, List<String> args) throws
IOException, InterruptedException {
args.add(0, "openapi");
args.add(0, OPENAPI_CMD);
Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);
int exitCode = process.waitFor();
logOutput(process.getInputStream());
logOutput(process.getErrorStream());
return exitCode == 0;
}

/**
* Execute ballerina graphql command.
*
* @param distributionName The name of the distribution.
* @param sourceDirectory The directory where the sources files are location.
* @param args The arguments to be passed to the build command.
* @return True if build is successful, else false.
* @throws IOException Error executing build command.
* @throws InterruptedException Interrupted error executing build command.
*/
public static boolean executeGraphql(String distributionName, Path sourceDirectory, List<String> args) throws
IOException, InterruptedException {
args.add(0, GRAPHQL_CMD);
Process process = getProcessBuilderResults(distributionName, sourceDirectory, args);
int exitCode = process.waitFor();
logOutput(process.getInputStream());
Expand Down Expand Up @@ -227,19 +249,20 @@ public static String findFileOrDirectory(Path dir, String dirName) {
}

/**
* Delete openapi generated files.
* Delete openapi and graphql generated files.
*
* @param generatedFileName file name that need to delete.
*/
public static void deleteGeneratedFiles(String generatedFileName) throws IOException {
Path resourcesPath = RESOURCES_PATH.resolve("openapi");
public static void deleteGeneratedFiles(String generatedFileName, String command) throws IOException {
Path resourcesPath = RESOURCES_PATH.resolve(command);
if (Files.exists(resourcesPath)) {
List<File> listFiles = Arrays.asList(
Objects.requireNonNull(new File(String.valueOf(resourcesPath)).listFiles()));
for (File existsFile: listFiles) {
String fileName = existsFile.getName();
if (fileName.equals(generatedFileName) || fileName.equals(generatedFileName + "_service.bal") ||
fileName.equals("client.bal") || fileName.equals("types.bal") || fileName.equals("utils.bal")) {
fileName.equals("client.bal") || fileName.equals("types.bal") || fileName.equals("utils.bal") ||
fileName.equals("config_types.bal")) {
existsFile.delete();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## The GraphQL schema. E.g., https://countries.trevorblades.com or ./schemas/country.graphql
schema: https://countries.trevorblades.com
## The GraphQL documents that have queries/mutations
documents:
- ./query_country.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
query countryByCode($code: ID!) {
country(code: $code) {
name
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## The GraphQL schema. E.g., https://countries.trevorblades.com or ./schemas/country.graphql
schema: ./schema_country.graphql
## The GraphQL documents that have queries/mutations
documents:
- ./queries/query_country.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
query countryByCode($code: ID!) {
country(code: $code) {
name
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
schema {
query: Query
}

"Directs the executor to include this field or fragment only when the `if` argument is true"
directive @include(
"Included when true."
if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"Directs the executor to skip this field or fragment when the `if`'argument is true."
directive @skip(
"Skipped when true."
if: Boolean!
) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

directive @cacheControl(maxAge: Int, scope: CacheControlScope) on OBJECT | FIELD_DEFINITION | INTERFACE

"Marks the field, argument, input field or enum value as deprecated"
directive @deprecated(
"The reason for the deprecation"
reason: String = "No longer supported"
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION

"Exposes a URL that specifies the behaviour of this scalar."
directive @specifiedBy(
"The URL that specifies the behaviour of this scalar."
url: String!
) on SCALAR

type Continent {
code: ID!
countries: [Country!]!
name: String!
}

type Country {
capital: String
code: ID!
continent: Continent!
currency: String
emoji: String!
emojiU: String!
languages: [Language!]!
name: String!
native: String!
phone: String!
states: [State!]!
}

type Language {
code: ID!
name: String
native: String
rtl: Boolean!
}

type Query {
continent(code: ID!): Continent
continents(filter: ContinentFilterInput): [Continent!]!
countries(filter: CountryFilterInput): [Country!]!
country(code: ID!): Country
language(code: ID!): Language
languages(filter: LanguageFilterInput): [Language!]!
}

type State {
code: String
country: Country!
name: String!
}

enum CacheControlScope {
PRIVATE
PUBLIC
}

"The `Upload` scalar type represents a file upload."
scalar Upload

input ContinentFilterInput {
code: StringQueryOperatorInput
}

input CountryFilterInput {
code: StringQueryOperatorInput
continent: StringQueryOperatorInput
currency: StringQueryOperatorInput
}

input LanguageFilterInput {
code: StringQueryOperatorInput
}

input StringQueryOperatorInput {
eq: String
in: [String!]
ne: String
nin: [String!]
regex: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "ballerina_sdl_file_generator_test"
name = "project_1"
version = "0.1.0"
Loading

0 comments on commit 1328082

Please sign in to comment.