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