diff --git a/src/test/java/school/redrover/api/APIFreestyleProjectTest.java b/src/test/java/school/redrover/api/APIFreestyleProjectTest.java
deleted file mode 100644
index 17d43f8e4..000000000
--- a/src/test/java/school/redrover/api/APIFreestyleProjectTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package school.redrover.api;
-
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-import io.restassured.response.Response;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-import school.redrover.common.APIBaseTest;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static school.redrover.common.TestUtils.requestSpec;
-import static school.redrover.common.TestUtils.responseSpec;
-
-public class APIFreestyleProjectTest extends APIBaseTest {
-
- private static final String PROJECT_NAME = "FreestyleProject";
- private static final String NEW_PROJECT_NAME = "NewFreestyleProject";
-
- private static final String bodyXML = """
-
- false
-
-
- false
- false
- false
- false
-
- false
-
-
-
-
- """;
-
- @Test
- public void testCreateWithValidName() {
- Map projectName = new HashMap<>();
- projectName.put("name", PROJECT_NAME);
-
- RestAssured.given()
- .spec(requestSpec())
- .contentType(ContentType.XML)
- .queryParams(projectName)
- .body(bodyXML)
- .when()
- .post("/createItem")
- .then()
- .spec(responseSpec(200, 1500L));
-
- Response response = RestAssured.given()
- .spec(requestSpec())
- .when()
- .get("job/%s/api/json".formatted(projectName.get("name")))
- .then()
- .spec(responseSpec(200, 1500L))
- .extract().response();
-
- String actualProjectName = response.jsonPath().getString("name");
- Assert.assertEquals(actualProjectName, projectName.get("name"));
- }
-
- @Test
- public void testRenameProject() {
- Map projectName = new HashMap<>();
- projectName.put("name", PROJECT_NAME);
-
- RestAssured.given()
- .spec(requestSpec())
- .contentType(ContentType.XML)
- .queryParams(projectName)
- .body(bodyXML)
- .when()
- .post("/createItem")
- .then()
- .spec(responseSpec(200, 1500L));
-
- RestAssured.given()
- .spec(requestSpec())
- .contentType("application/x-www-form-urlencoded")
- .queryParam("newName", NEW_PROJECT_NAME)
- .when()
- .post("job/%s/confirmRename".formatted(projectName.get("name")))
- .then()
- .spec(responseSpec(302, 1500L));
-
- Response response = RestAssured.given()
- .spec(requestSpec())
- .when()
- .get("job/%s/api/json".formatted(NEW_PROJECT_NAME))
- .then()
- .spec(responseSpec(200, 1500L))
- .extract().response();
-
- String actualProjectName = response.jsonPath().getString("name");
- Assert.assertEquals(actualProjectName, NEW_PROJECT_NAME);
- }
-}
diff --git a/src/test/java/school/redrover/api/FreestyleProjectTest.java b/src/test/java/school/redrover/api/FreestyleProjectTest.java
new file mode 100644
index 000000000..da900456a
--- /dev/null
+++ b/src/test/java/school/redrover/api/FreestyleProjectTest.java
@@ -0,0 +1,66 @@
+package school.redrover.api;
+
+import io.restassured.response.Response;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import school.redrover.api.testdata.ProjectType;
+import school.redrover.common.APIBaseTest;
+import school.redrover.api.testdata.ProjectDataProvider;
+
+import static school.redrover.api.endpoint.ProjectEndpoints.*;
+import static school.redrover.common.TestUtils.getPayload;
+
+public class FreestyleProjectTest extends APIBaseTest {
+ private static final String PROJECT_NAME = "FreestyleProject";
+
+ @Test(dataProvider = "projectNameList", dataProviderClass = ProjectDataProvider.class)
+ public void testCreateWithValidName(String projectName) {
+ Response createProjectResponse = createProjectWithXML(projectName,
+ getPayload("create-empty-freestyle-project.xml"));
+ Response getProjectResponse = getProjectByName(projectName);
+
+ String actualProjectName = getProjectResponse.jsonPath().getString("name");
+
+ softAssert.assertEquals(createProjectResponse.getStatusCode(), 200);
+
+ softAssert.assertEquals(actualProjectName, projectName);
+ softAssert.assertEquals(getProjectResponse.getStatusCode(), 200);
+ softAssert.assertTrue(getProjectResponse.time() <= 1500);
+ }
+
+ @Test(dataProvider = "renameProjectNameList", dataProviderClass = ProjectDataProvider.class)
+ public void testRenameProject(String oldName, String newName) {
+ createProjectWithXML(oldName, getPayload("create-empty-freestyle-project.xml"));
+
+ renameProject(oldName, newName);
+
+ Response getProjectResponse = getProjectByName(newName);
+
+ String actualProjectName = getProjectResponse.jsonPath().getString("name");
+ softAssert.assertEquals(actualProjectName, newName);
+ softAssert.assertEquals(getProjectResponse.statusCode(), 200);
+ softAssert.assertTrue(getProjectResponse.time() <= 1500);
+ }
+
+ @Test
+ public void testDeleteProject() {
+ createProject(PROJECT_NAME, ProjectType.FREESTYLE_PROJECT);
+
+ deleteProject(PROJECT_NAME);
+
+ Response afterDeletedResponse = getProjectByName(PROJECT_NAME);
+ Assert.assertEquals(afterDeletedResponse.statusCode(), 404, "Not found");
+ }
+
+ @Test(dataProvider = "providerUnsafeCharacters", dataProviderClass = ProjectDataProvider.class)
+ public void testCreateWithUnsafeCharacter(String unsafeCharacter) {
+ Response response = createProject(unsafeCharacter, ProjectType.FREESTYLE_PROJECT);
+
+ softAssert.assertEquals(response.statusCode(), 400);
+ softAssert.assertTrue(response.time() <= 1500);
+ softAssert.assertEquals(
+ response.getHeaders().getValue("X-Error"),
+ "%s is an unsafe character".formatted(unsafeCharacter));
+ }
+
+}
diff --git a/src/test/java/school/redrover/api/MultibranchPipelineTest.java b/src/test/java/school/redrover/api/MultibranchPipelineTest.java
index 6b716904f..4872f46c8 100644
--- a/src/test/java/school/redrover/api/MultibranchPipelineTest.java
+++ b/src/test/java/school/redrover/api/MultibranchPipelineTest.java
@@ -3,7 +3,7 @@
import org.testng.Assert;
import org.testng.annotations.Test;
import school.redrover.common.APIBaseTest;
-import school.redrover.api.endpoint.ProjectType;
+import school.redrover.api.testdata.ProjectType;
import static school.redrover.api.endpoint.ProjectEndpoints.*;
diff --git a/src/test/java/school/redrover/api/endpoint/ProjectEndpoints.java b/src/test/java/school/redrover/api/endpoint/ProjectEndpoints.java
index 64046dd9f..c1c09da1e 100644
--- a/src/test/java/school/redrover/api/endpoint/ProjectEndpoints.java
+++ b/src/test/java/school/redrover/api/endpoint/ProjectEndpoints.java
@@ -4,13 +4,13 @@
import io.restassured.http.ContentType;
import io.restassured.response.Response;
+import school.redrover.api.testdata.ProjectType;
import static school.redrover.common.TestUtils.requestSpec;
import static school.redrover.common.TestUtils.responseSpec;
public class ProjectEndpoints {
-
public static Response createProject(String projectName, ProjectType projectType) {
return RestAssured.given()
.spec(requestSpec())
@@ -55,6 +55,7 @@ public static Response getProjectByName(String projectName) {
.when()
.get("job/%s/api/json".formatted(projectName))
.then()
+ .spec(responseSpec())
.extract().response();
}
diff --git a/src/test/java/school/redrover/api/testdata/ProjectDataProvider.java b/src/test/java/school/redrover/api/testdata/ProjectDataProvider.java
new file mode 100644
index 000000000..4c1676265
--- /dev/null
+++ b/src/test/java/school/redrover/api/testdata/ProjectDataProvider.java
@@ -0,0 +1,35 @@
+package school.redrover.api.testdata;
+
+import org.testng.annotations.DataProvider;
+
+public class ProjectDataProvider {
+
+ private static final String maxProjectName = "A".repeat(255);
+
+ @DataProvider
+ public Object[][] projectNameList() {
+ return new Object[][]{
+ {"ValidProject"},
+ {"A"},
+ {maxProjectName}
+ };
+ }
+
+ @DataProvider
+ public static Object[][] renameProjectNameList() {
+ return new Object[][]{
+ {"ValidProject", "B".repeat(255)},
+ {"A", "B"},
+ {maxProjectName, "NewValidProject"}
+ };
+ }
+
+ @DataProvider
+ public Object[][] providerUnsafeCharacters() {
+ return new Object[][]{
+ {"\\"}, {"]"}, {":"}, {"#"}, {"&"}, {"?"}, {"!"}, {"@"},
+ {"$"}, {"%"}, {"^"}, {"*"}, {"|"}, {"/"}, {"<"}, {">"},
+ {"["}, {";"}
+ };
+ }
+}
diff --git a/src/test/java/school/redrover/api/endpoint/ProjectType.java b/src/test/java/school/redrover/api/testdata/ProjectType.java
similarity index 93%
rename from src/test/java/school/redrover/api/endpoint/ProjectType.java
rename to src/test/java/school/redrover/api/testdata/ProjectType.java
index 9401fea9f..05a680ba8 100644
--- a/src/test/java/school/redrover/api/endpoint/ProjectType.java
+++ b/src/test/java/school/redrover/api/testdata/ProjectType.java
@@ -1,4 +1,4 @@
-package school.redrover.api.endpoint;
+package school.redrover.api.testdata;
public enum ProjectType {
diff --git a/src/test/java/school/redrover/common/APIBaseTest.java b/src/test/java/school/redrover/common/APIBaseTest.java
index 2c7c10928..8ca3689c6 100644
--- a/src/test/java/school/redrover/common/APIBaseTest.java
+++ b/src/test/java/school/redrover/common/APIBaseTest.java
@@ -4,6 +4,7 @@
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
+import org.testng.asserts.SoftAssert;
import school.redrover.common.logging.Log;
import school.redrover.common.logging.RestAssuredLogFilter;
@@ -16,6 +17,7 @@ public abstract class APIBaseTest {
protected String apiToken;
protected String tokenUuid;
protected String userName = ProjectUtils.getUserName();
+ protected SoftAssert softAssert;
@BeforeClass
protected void setUpApi() {
@@ -32,11 +34,13 @@ protected void beforeMethod(Method method) {
Log.info("Clear data");
Log.info("Run %s.%s", this.getClass().getName(), method.getName());
JenkinsUtils.clearData();
+ softAssert = new SoftAssert();
}
@AfterClass
protected void tearDownApi() {
Log.info("Delete API token");
JenkinsUtils.deleteApiTokenByUuid(jenkinsUrl, tokenUuid, apiToken);
+ softAssert.assertAll();
}
}
\ No newline at end of file
diff --git a/src/test/java/school/redrover/common/TestUtils.java b/src/test/java/school/redrover/common/TestUtils.java
index 7f782b34b..a1d36a2f0 100644
--- a/src/test/java/school/redrover/common/TestUtils.java
+++ b/src/test/java/school/redrover/common/TestUtils.java
@@ -5,12 +5,31 @@
import io.restassured.filter.log.LogDetail;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
+import school.redrover.common.logging.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import static io.restassured.RestAssured.preemptive;
import static org.hamcrest.Matchers.lessThan;
public class TestUtils {
+ private static final String PAYLOAD = "payload";
+
+ private static String readFileFromResources(String folder, String name) {
+ try (InputStream inputStream = TestUtils.class.getClassLoader().getResourceAsStream("%s/%s".formatted(folder, name))) {
+ if (inputStream == null) {
+ throw new IOException("File not found in resources");
+ }
+ return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ Log.error("File not found");
+ throw new RuntimeException(e);
+ }
+ }
+
public static RequestSpecification requestSpec() {
return new RequestSpecBuilder()
.setAuth(preemptive().basic(ProjectUtils.getUserName(), JenkinsUtils.getApiTokenValue()))
@@ -32,4 +51,8 @@ public static ResponseSpecification responseSpec() {
.log(LogDetail.ALL)
.build();
}
+
+ public static String getPayload(String fileName) {
+ return readFileFromResources(PAYLOAD, fileName);
+ }
}
diff --git a/src/test/resources/payload/create-empty-freestyle-project.xml b/src/test/resources/payload/create-empty-freestyle-project.xml
new file mode 100644
index 000000000..2de97091c
--- /dev/null
+++ b/src/test/resources/payload/create-empty-freestyle-project.xml
@@ -0,0 +1,14 @@
+
+ false
+
+
+ false
+ false
+ false
+ false
+
+ false
+
+
+
+
\ No newline at end of file