Skip to content

Commit

Permalink
Feature/44 small improvements from mvp (#45)
Browse files Browse the repository at this point in the history
* Logic reading suites files is now using suites folder as root dir.
* Synced name of Action attribute to 'method'. Now it is used on same way across project.
* Improved error handling and error message when no json string provided in Action body.
  • Loading branch information
miroslavpojer authored Dec 1, 2023
1 parent 048f44b commit 67736f0
Show file tree
Hide file tree
Showing 18 changed files with 40 additions and 34 deletions.
4 changes: 2 additions & 2 deletions testApi/src/main/resources/schema/after.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"methodName": {
"method": {
"type": "string",
"enum": ["get", "post", "put", "delete"],
"description": "The HTTP method name for the action. Restricted to specific values."
Expand All @@ -109,7 +109,7 @@
}
},
"required": [
"methodName",
"method",
"url"
],
"title": "Action",
Expand Down
4 changes: 2 additions & 2 deletions testApi/src/main/resources/schema/before.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"methodName": {
"method": {
"type": "string",
"description": "The HTTP method name for the action."
},
Expand All @@ -107,7 +107,7 @@
}
},
"required": [
"methodName",
"method",
"url"
],
"title": "Action",
Expand Down
4 changes: 2 additions & 2 deletions testApi/src/main/resources/schema/suite.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"methodName": {
"method": {
"type": "string",
"description": "The HTTP method name for the action."
},
Expand All @@ -119,7 +119,7 @@
}
},
"required": [
"methodName",
"method",
"url"
],
"title": "Action",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ object ScAPIRunner {
}
cmd.logConfigInfo()

if (!Files.exists(Paths.get(cmd.testRootPath, "suites"))) throw SuiteLoadFailedException("'suites' directory have to exist in project root.")
val suitesPath = Paths.get(cmd.testRootPath, "suites")
if (!Files.exists(suitesPath)) throw SuiteLoadFailedException("'suites' directory have to exist in project root.")

// jsons to objects
val environment: Environment = EnvironmentFactory.fromFile(cmd.envPath)
val suiteBundles: Set[Suite] = SuiteFactory.fromFiles(environment, cmd.testRootPath, cmd.filter, cmd.fileFormat)
val suiteBundles: Set[Suite] = SuiteFactory.fromFiles(environment, suitesPath, cmd.filter, cmd.fileFormat)
SuiteFactory.validateSuiteContent(suiteBundles)

// run tests and result reporting - use categories for test filtering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ case class Header private(name: String, value: String) extends ReferenceResolver
* It implements the `ReferenceResolver` trait to support resolution of reference constants.
*
* @constructor create a new Action with a name and value.
* @param methodName the name of the action.
* @param method the name of the action.
* @param url the value of the action.
* @param body the body of the action - optional.
*/
case class Action private(methodName: String, url: String, body: Option[String] = None, params: Option[Set[Param]] = None) extends ReferenceResolver {
case class Action private(method: String, url: String, body: Option[String] = None, params: Option[Set[Param]] = None) extends ReferenceResolver {

/**
* Method to resolve references.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object SuiteFactory {
* @param format The format of suite JSON files.
* @return Set of Suite instances.
*/
def fromFiles(environment: Environment, testRootPath: String, filter: String, format: String): Set[Suite] = {
def fromFiles(environment: Environment, testRootPath: Path, filter: String, format: String): Set[Suite] = {
// NOTE: format not used as json is only supported format in time od development

val suiteLoadingResults: Map[String, Try[Suite]] = {
Expand Down Expand Up @@ -120,7 +120,7 @@ object SuiteFactory {
* @param filter The filter string to be used for finding suite JSON files.
* @return Set of paths to suite JSON files.
*/
private def findSuiteJsonFiles(path: String, filter: String): Set[String] = FileUtils.findMatchingFiles(path, filter + "\\.suite\\.json")
private def findSuiteJsonFiles(path: Path, filter: String): Set[String] = FileUtils.findMatchingFiles(path, filter + "\\.suite\\.json")

/**
* Method to load a SuiteBundle instance from the given suite JSON file path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package africa.absa.testing.scapi.rest.request

import africa.absa.testing.scapi.ContentValidationFailedException
import africa.absa.testing.scapi.utils.cache.RuntimeCache
import spray.json.JsonParser.ParsingException
import spray.json._

import scala.util.{Failure, Try}
Expand All @@ -37,7 +38,13 @@ object RequestBody {
*/
def buildBody(jsonBody: Option[String] = None): String = {
jsonBody match {
case Some(body) if body.trim.nonEmpty => RuntimeCache.resolve(body.parseJson.toString())
case Some(body) if body.trim.nonEmpty =>
try {
val jsonAst = body.parseJson // Attempt to parse the JSON
RuntimeCache.resolve(jsonAst.toString()) // If successful, resolve
} catch {
case e: ParsingException => throw new IllegalArgumentException("Invalid JSON string provided in Action body.")
}
case _ => "{}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ object SuiteRunner {
val resolvedAction = requestable.action.resolveByRuntimeCache()

restClientCreator().sendRequest(
method = resolvedAction.methodName,
method = resolvedAction.method,
url = RuntimeCache.resolve(resolvedAction.url),
headers = RequestHeaders.buildHeaders(requestable.headers.map(header => header.resolveByRuntimeCache())),
body = RequestBody.buildBody(resolvedAction.body),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object FileUtils {
* @param pattern A regex pattern to match file names. The default value is "(.*)" which matches all files.
* @return Set<String> A set of file paths as strings that match the provided pattern.
*/
def findMatchingFiles(path: String, pattern: String = "(.*)"): Set[String] = {
def findMatchingFiles(path: Path, pattern: String = "(.*)"): Set[String] = {
def findFilesRecursive(directory: File): Set[File] = {
val files = directory.listFiles.toSet
val matchingFiles = files.filter(_.isFile).filter(_.getName.matches(pattern))
Expand All @@ -40,9 +40,7 @@ object FileUtils {
matchingFiles ++ subDirectories.flatMap(findFilesRecursive)
}

val rootDirectory = new File(path)
val matchingFiles = findFilesRecursive(rootDirectory)

val matchingFiles = findFilesRecursive(path.toFile)
matchingFiles.map(_.getPath)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}
],
"action": {
"methodName": "get",
"method": "get",
"url": "{{ env.url }}/AULGUI/user"
},
"responseActions": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
],
"action": {
"methodName": "get",
"method": "get",
"url": "{{ env.url }}/api/owners"
},
"responseActions": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
],
"action": {
"methodName": "get",
"method": "get",
"url": "{{ env.url }}/api/owners"
},
"responseActions": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"categories": ["SMOKE"],
"headers" : [],
"action": {
"methodName": "get",
"method": "get",
"url": "{{ env.url }}/api/owner/999"
},
"responseActions": [
Expand All @@ -24,7 +24,7 @@
"categories": ["SMOKE"],
"headers" : [],
"action": {
"methodName": "get",
"method": "get",
"url": "{{ env.url }}/api/owners/5"
},
"responseActions": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import munit.FunSuite
class ReferenceResolverTest extends FunSuite {

val action: Action = Action(
methodName = "get",
method = "get",
url = "nice/{{ cache.urlValue }}",
body = Option("body {{ cache.surpriseValue }}"),
params = Option(Set(Param("message", "value nr.: {{ cache.numberValue }}")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package africa.absa.testing.scapi.json
import africa.absa.testing.scapi.ContentValidationFailedException
import africa.absa.testing.scapi.rest.request.RequestBody
import munit.FunSuite
import spray.json.JsonParser.ParsingException

class RequestBodyTest extends FunSuite {

Expand All @@ -36,7 +35,7 @@ class RequestBodyTest extends FunSuite {
test("buildBody - throw exception when non json string received") {
val jsonBody = Some("""not json string""")

interceptMessage[ParsingException]("Unexpected character 'o' at input index 0 (line 1, position 1), expected JSON Value:\nnot json string\n^\n") {
interceptMessage[IllegalArgumentException]("Invalid JSON string provided in Action body.") {
RequestBody.buildBody(jsonBody)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package africa.absa.testing.scapi.json

import africa.absa.testing.scapi.json.factory.SuiteFactory
import africa.absa.testing.scapi.model.suite.{TestSet, Suite, SuiteTestScenario}
import africa.absa.testing.scapi.model.suite.{Suite, SuiteTestScenario, TestSet}
import africa.absa.testing.scapi.{ProjectLoadFailedException, UndefinedConstantsInPropertiesException}
import munit.FunSuite
import org.apache.logging.log4j.LogManager
Expand All @@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.appender.OutputStreamAppender
import org.apache.logging.log4j.core.layout.PatternLayout

import java.io.ByteArrayOutputStream
import java.nio.file.Paths

class SuiteFactoryTest extends FunSuite {

Expand Down Expand Up @@ -62,7 +63,7 @@ class SuiteFactoryTest extends FunSuite {
val constants: Map[String, String] = Map.empty
val properties: Map[String, String] = Map.empty
val environment: Environment = Environment(constants, properties)
val testRootPath: String = getClass.getResource("/project_with_issues").getPath
val testRootPath = Paths.get(getClass.getResource("/project_with_issues").getPath)

initTestLogger()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import org.apache.logging.log4j.Level
class SuiteRunnerTest extends FunSuite {

val header: Header = Header(name = RequestHeaders.AUTHORIZATION, value = "Basic abcdefg")
val action: Action = Action(methodName = "get", url = "nice url")
val actionNotSupported: Action = Action(methodName = "wrong", url = "nice url")
val action: Action = Action(method = "get", url = "nice url")
val actionNotSupported: Action = Action(method = "wrong", url = "nice url")
val responseAction: ResponseAction = ResponseAction(group = ResponseActionGroupType.Assert, name = AssertResponseActionType.StatusCodeEquals.toString, Map("code" -> "200"))
val method: Method = Method(name = "test", headers = Seq(header), action = action, responseActions = Seq(responseAction))
val methodNotSupported: Method = Method(name = "test", headers = Seq(header), action = actionNotSupported, responseActions = Seq(responseAction))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class FileUtilsTest extends FunSuite {
test("find matching files") {
val (tmpDir, expectedFiles): (Path, Set[String]) = prepareTestData

val matchingFiles = FileUtils.findMatchingFiles(tmpDir.toString)
val matchingFiles = FileUtils.findMatchingFiles(tmpDir)

assert(clue(expectedFiles) == clue(matchingFiles))
}
Expand All @@ -52,7 +52,7 @@ class FileUtilsTest extends FunSuite {
val (tmpDir, files) = prepareTestData
val expectedFiles = files.filter(file => file.endsWith(".json"))

val matchingFiles = FileUtils.findMatchingFiles(tmpDir.toString, "(.*).json")
val matchingFiles = FileUtils.findMatchingFiles(tmpDir, "(.*).json")

assert(clue(expectedFiles) == clue(matchingFiles))
}
Expand All @@ -61,7 +61,7 @@ class FileUtilsTest extends FunSuite {
val (tmpDir, files) = prepareTestData
val expectedFiles = Set.empty[String]

val matchingFiles = FileUtils.findMatchingFiles(tmpDir.toString, "(.*).nonsense")
val matchingFiles = FileUtils.findMatchingFiles(tmpDir, "(.*).nonsense")

assert(clue(expectedFiles) == clue(matchingFiles))
}
Expand All @@ -70,7 +70,7 @@ class FileUtilsTest extends FunSuite {
val (tmpDir, files) = prepareTestData
val expectedFiles = files.filter(file => file.endsWith(".xml"))

val matchingFiles = FileUtils.findMatchingFiles(tmpDir.toString, "(.*).xml")
val matchingFiles = FileUtils.findMatchingFiles(tmpDir, "(.*).xml")

assert(clue(expectedFiles) == clue(matchingFiles))
}
Expand Down

0 comments on commit 67736f0

Please sign in to comment.