Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
A simple gradle project to test a subset of GitHub API using REST requests
## Summary

A simple Gradle project for testing a subset of the GitHub API using REST requests. It is implemented in Java and uses Rest-assured.
implemented in Java and Rest-assured. The test results will be in Allure format.

### Local setup

- Add `github-pat`=<your-github-pat> to `src/test/resources/test.properties`
- Run `gradlew test` to execute the tests
110 changes: 75 additions & 35 deletions app/src/test/java/com/github/hoangqt/GitHubApiTest.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package com.github.hoangqt;

import io.restassured.http.ContentType;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import static org.assertj.core.api.Assertions.assertThat;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GitHubApiTest {
private static Properties properties;
private static String token;
private static GitHub github;

private static final String GITHUB_PAT_KEY = "github-pat";
private static final String TEST_REPO = "ansible";
private static final String TEST_OWNER = "hoangqt";

private static String issueNumber;

@BeforeAll
public static void setup() throws IOException {
properties = new Properties();
Expand All @@ -24,8 +32,8 @@ public static void setup() throws IOException {
e.printStackTrace();
}

if (properties.getProperty("github-pat") != null) {
token = properties.getProperty("github-pat");
if (properties.getProperty(GITHUB_PAT_KEY) != null) {
Comment on lines 34 to +35
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low: The check !githubToken.trim().isEmpty() is redundant because githubToken != null already ensures the string is not null. You can simplify this condition.

Suggested change
if (properties.getProperty("github-pat") != null) {
token = properties.getProperty("github-pat");
if (properties.getProperty(GITHUB_PAT_KEY) != null) {
if (githubToken != null) {

token = properties.getProperty(GITHUB_PAT_KEY);
} else {
String githubToken = System.getenv("GITHUB_PAT");
if (githubToken != null || !githubToken.trim().isEmpty()) {
Expand All @@ -37,41 +45,18 @@ public static void setup() throws IOException {

@Test
public void testGetRepository() {
var json = github.getRepository("ansible")
var json = github.getRepository(TEST_REPO)
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.extract()
.jsonPath();
assertThat(json.getString("name")).isEqualTo("ansible");
assertThat(json.getString("owner.login")).isEqualTo("hoangqt");
}


@Test
public void testGetIssues() {
var json = github.getRepositoryIssues("ansible")
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.extract()
.jsonPath();
assertThat(json.getList("title", String.class)).contains("Test");
assertThat(json.getList("number", Integer.class)).contains(5);
}

@Test
public void testGetCommits() {
var json = github.getRepositoryCommits("ansible")
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.extract()
.jsonPath();
assertThat(json.getList("committer.login", String.class)).contains("hoangqt");
assertThat(json.getString("name")).isEqualTo(TEST_REPO);
assertThat(json.getString("owner.login")).isEqualTo(TEST_OWNER);
}

@Test
@Order(1)
public void testCreateIssue() {
var body = """
{
Expand All @@ -81,7 +66,7 @@ public void testCreateIssue() {
"labels": ["bug"]
}""";

var json = github.createIssue("ansible", body)
var json = github.createIssue(TEST_REPO, body)
.then()
.statusCode(201)
.contentType(ContentType.JSON)
Expand All @@ -91,9 +76,55 @@ public void testCreateIssue() {
assertThat(json.getString("title")).isEqualTo("Found a bug");
assertThat(json.getString("body")).isEqualTo("This is a test issue created by automation");
assertThat(json.getString("state")).isEqualTo("open");

issueNumber = String.valueOf(json.getInt("number"));
}

@Test
@Order(2)
public void testGetIssues() throws InterruptedException {
// Poll for the issue to appear due to eventual consistency
long timeoutMillis = 15_000L;
long pollIntervalMillis = 500L;
long deadline = System.currentTimeMillis() + timeoutMillis;

boolean found = false;
while (System.currentTimeMillis() < deadline) {
var json = github.getRepositoryIssues(TEST_REPO)
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.extract()
.jsonPath();

var titles = json.getList("title", String.class);
if (titles != null && titles.contains("Found a bug")) {
found = true;
Comment on lines +101 to +102
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low: Consider making the polling timeout and interval configurable instead of hardcoding them. This could be done via system properties or a configuration file, making the tests more flexible for different environments.

Suggested change
if (titles != null && titles.contains("Found a bug")) {
found = true;
long timeoutMillis = Long.getLong("test.poll.timeout", 15_000L);
long pollIntervalMillis = Long.getLong("test.poll.interval", 500L);


// If issueNumber wasn't set in testCreateIssue (e.g., rerun), set it now
if (issueNumber == null) {
List<Map<String, Object>> issues = json.getList("$");
for (Map<String, Object> issue : issues) {
if ("Found a bug".equals(issue.get("title"))) {
Object number = issue.get("number");
if (number != null) {
issueNumber = String.valueOf(number);
}
break;
}
}
}
break;
}
Thread.sleep(pollIntervalMillis);
}

assertThat(found).as("Issue titled 'Found a bug' should appear within the polling timeout").isTrue();
assertThat(issueNumber).as("Issue number for title 'Found a bug' should be found").isNotNull();
}

@Test
@Order(3)
public void testUpdateIssue() {
var body = """
{
Expand All @@ -103,9 +134,7 @@ public void testUpdateIssue() {
"labels": ["bug", "invalid"]
}""";

var issueNumber = "8";

var json = github.updateIssue("ansible", body, issueNumber)
var json = github.updateIssue(TEST_REPO, body, issueNumber)
.then()
.statusCode(200)
.contentType(ContentType.JSON)
Expand All @@ -114,4 +143,15 @@ public void testUpdateIssue() {

assertThat(json.getString("labels")).containsAnyOf("bug", "invalid");
}

@Test
public void testGetCommits() {
var json = github.getRepositoryCommits(TEST_REPO)
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.extract()
.jsonPath();
assertThat(json.getList("committer.login", String.class)).contains(TEST_OWNER);
}
}