Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/8 implement methods #27

Merged
merged 33 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ca67acc
#17 - Assertion rename and simplification
miroslavpojer Aug 22, 2023
b1e3ade
Merge branch 'master' into feature/17_assertion_rename_and_simplifica…
miroslavpojer Aug 22, 2023
9d89dc1
#17 - Assertion rename and simplification
miroslavpojer Aug 22, 2023
0b5a476
#18 - Refactoring of ResponseAction to dynamic
miroslavpojer Aug 22, 2023
2e68674
#18 - Refactoring of ResponseAction to dynamic
miroslavpojer Aug 22, 2023
4d5a6bc
* Repairs of unit tests.
miroslavpojer Aug 22, 2023
f14b81f
#8 - Implement method ideas
miroslavpojer Aug 23, 2023
104415f
* Implemented methods for Assertion 'ResponseAction' - status-code-..…
miroslavpojer Aug 23, 2023
2559bb2
* Implemented methods for Assertion 'ResponseAction' - response-time-…
miroslavpojer Aug 24, 2023
643a68a
* Implemented methods for Assertion 'ResponseAction' - cookie-... part
miroslavpojer Aug 24, 2023
e0ac15d
Merge branch 'master' into feature/8-implement_methods
miroslavpojer Aug 26, 2023
6032a64
* Fix multiline strings review note.
miroslavpojer Sep 7, 2023
c203ab6
* Fix - multiline strings review note.
miroslavpojer Sep 21, 2023
2e251ae
* Fix - replace Assert type of response actions by enum.
miroslavpojer Sep 21, 2023
3dc366b
* Fix - Update of javaDoc after migration from boolean to Try[Unit] r…
miroslavpojer Oct 3, 2023
02a2447
* Fix - replaced tuple by new CookieValue class.
miroslavpojer Oct 6, 2023
11293dc
* Fix - add missed class file.
miroslavpojer Oct 6, 2023
0227000
* Fix - review of code warnings.
miroslavpojer Oct 6, 2023
8b4c12e
* Fix - Removed no more used class and object TestResults.scala.
miroslavpojer Oct 9, 2023
1aa261b
* Fix - moved Factory classes to dedicated package.
miroslavpojer Oct 13, 2023
d51747d
* Fix - rename Suite to TestSet.
miroslavpojer Oct 13, 2023
0f82356
* Fix - removed only keyword.
miroslavpojer Oct 13, 2023
2f579ac
* Change: set jacoco-report debug to find source of logic failing.
miroslavpojer Oct 13, 2023
f353d54
* Change: set jacoco-report debug to find source of logic failing.
miroslavpojer Oct 13, 2023
aca8587
* Fix - expected change to fix jacoco report issue and better package…
miroslavpojer Oct 13, 2023
1d2c8ab
* Fix - expected change to fix jacoco report issue and better package…
miroslavpojer Oct 13, 2023
e2fec8f
* Fix - log action methods returns Unit.
miroslavpojer Nov 1, 2023
470efbf
* Fix - Improved usage of resultType enums.
miroslavpojer Nov 1, 2023
a15a420
* Fix - Removed usage of Success from Action implementations.
miroslavpojer Nov 1, 2023
5ec5a73
* Fix - Renamed and moved Type to String implicit conversion as they …
miroslavpojer Nov 1, 2023
e4ce58a
* Fix - correct usage clue calls in assert (not assertEquals) method.
miroslavpojer Nov 2, 2023
236cbae
* Fix - removed used only keyword from test name.
miroslavpojer Nov 2, 2023
4e0d029
* Fix - Applied Scala CamelCase to enumaration contants.
miroslavpojer Nov 2, 2023
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
1 change: 1 addition & 0 deletions .github/workflows/ci-check-jacoco.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
min-coverage-changed-files: 80.0
title: JaCoCo code coverage report - ScAPI
update-comment: true
debug-mode: true
- name: Get the Coverage info
run: |
echo "Total coverage ${{ steps.jacoco.outputs.coverage-overall }}"
Expand Down
2 changes: 2 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ object Dependencies {
private val commonsIoVersion = "2.13.0"
private val requestsVersion = "0.8.0"
private val loggerVersion = "2.14.1"
private val scalaXmlVersion = "1.3.0"

def getScalaDependency(scalaVersion: String): ModuleID = "org.scala-lang" % "scala-library" % scalaVersion

Expand All @@ -40,6 +41,7 @@ object Dependencies {
"com.lihaoyi" %% "requests" % requestsVersion,
"org.apache.logging.log4j" % "log4j-core" % loggerVersion,
"org.apache.logging.log4j" % "log4j-api" % loggerVersion,
"org.scala-lang.modules" %% "scala-xml" % scalaXmlVersion,

// test
"org.scalameta" %% "munit" % munitVersion % Test
Expand Down
2 changes: 1 addition & 1 deletion testApi/src/main/resources/schema/after.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"properties": {
"method": {
"type": "string",
"enum": ["assert.status-code", "assert.body-contains", "log.info", "extractJson.string-from-list"],
"enum": ["assert.response-time-is-below", "assert.response-time-is-above", "assert.status-code-equals", "assert.status-code-is-success", "assert.status-code-is-client-error", "assert.status-code-is-server-error", "assert.header-exists", "assert.header-value-equals", "assert.content-type-is-json", "assert.content-type-is-xml", "assert.content-type-is-html", "assert.cookie-exists", "assert.cookie-value-equals", "assert.cookie-is-secured", "assert.cookie-is-not-secured", "assert.body-contains-text", "log.error", "log.warn", "log.info", "log.debug", "extractJson.string-from-list"],
"description": "The method to be used for the response action. Restricted to specific values."
}
},
Expand Down
2 changes: 1 addition & 1 deletion testApi/src/main/resources/schema/before.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
"properties": {
"method": {
"type": "string",
"enum": ["assert.status-code", "assert.body-contains", "log.info", "extractJson.string-from-list"],
"enum": ["assert.response-time-is-below", "assert.response-time-is-above", "assert.status-code-equals", "assert.status-code-is-success", "assert.status-code-is-client-error", "assert.status-code-is-server-error", "assert.header-exists", "assert.header-value-equals", "assert.content-type-is-json", "assert.content-type-is-xml", "assert.content-type-is-html", "assert.cookie-exists", "assert.cookie-value-equals", "assert.cookie-is-secured", "assert.cookie-is-not-secured", "assert.body-contains-text", "log.error", "log.warn", "log.info", "log.debug", "extractJson.string-from-list"],
"description": "The method to be used for the response action."
}
},
Expand Down
12 changes: 6 additions & 6 deletions testApi/src/main/resources/schema/suite.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"type": "object",
"additionalProperties": true,
"properties": {
"endpoint": {
"name": {
"type": "string",
"description": "The user endpoint name which suite cover by tests."
"description": "The suite name."
},
"tests": {
"type": "array",
Expand All @@ -20,7 +20,7 @@
}
},
"required": [
"endpoint",
"name",
"tests"
],
"title": "suite",
Expand Down Expand Up @@ -133,7 +133,7 @@
"properties": {
"method": {
"type": "string",
"enum": ["assert.status-code", "assert.body-contains", "log.info", "extractJson.string-from-list"],
"enum": ["assert.response-time-is-below", "assert.response-time-is-above", "assert.status-code-equals", "assert.status-code-is-success", "assert.status-code-is-client-error", "assert.status-code-is-server-error", "assert.header-exists", "assert.header-value-equals", "assert.content-type-is-json", "assert.content-type-is-xml", "assert.content-type-is-html", "assert.cookie-exists", "assert.cookie-value-equals", "assert.cookie-is-secured", "assert.cookie-is-not-secured", "assert.body-contains-text", "log.error", "log.warn", "log.info", "log.debug", "extractJson.string-from-list"],
"description": "The method to be used for the response action."
}
},
Expand All @@ -156,7 +156,7 @@
{
"properties": {
"method": {
"const": "assert.status-code"
"const": "assert.status-code-equals"
}
},
"required": ["code"]
Expand Down Expand Up @@ -190,7 +190,7 @@
{
"properties": {
"method": {
"const": "assert.status-code"
"const": "assert.status-code-equals"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,30 @@ import com.networknt.schema.ValidationMessage

import scala.collection.mutable

case class UndefinedConstantsInProperties(undefinedConstants: Set[String], source: String)
case class UndefinedConstantsInPropertiesException(undefinedConstants: Set[String], source: String)
extends Exception(s"Undefined constant(s): '${undefinedConstants.mkString(", ")}' in '$source'.")

case class PropertyNotFound(property: String) extends Exception(s"Property not found: '$property'.")
case class PropertyNotFoundException(property: String) extends Exception(s"Property not found: '$property'.")

case class JsonInvalidSchema(filePath: String, messages: mutable.Set[ValidationMessage])
case class JsonInvalidSchemaException(filePath: String, messages: mutable.Set[ValidationMessage])
extends Exception(s"Json file '$filePath' not valid to defined json schema. " + messages.mkString("\n"))

case class ProjectLoadFailed() extends Exception("Problems during project loading.")
case class ProjectLoadFailedException() extends Exception("Problems during project loading.")

case class SuiteLoadFailed(detail: String) extends Exception(s"Problems during project loading. Details: $detail")
case class SuiteLoadFailedException(detail: String)
extends Exception(s"Problems during project loading. Details: $detail")

case class UndefinedHeaderType(undefinedType: String)
case class SuiteBeforeFailedException(detail: String)
extends Exception(s"Problems during running before suite logic. Details: $detail")

case class UndefinedHeaderTypeException(undefinedType: String)
extends Exception(s"Undefined Header content type: '$undefinedType'")

case class UndefinedResponseActionType(undefinedType: String)
case class UndefinedResponseActionTypeException(undefinedType: String)
extends Exception(s"Undefined response action content type: '$undefinedType'")

case class ContentValidationFailed(value: String, message: String)
case class ContentValidationFailedException(value: String, message: String)
extends Exception(s"Content validation failed for value: '$value': $message")

case class AssertionException(message: String)
extends Exception(s"Assertion failed: $message")
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
package africa.absa.testing.scapi

import africa.absa.testing.scapi.config.ScAPIRunnerConfig
import africa.absa.testing.scapi.json.{Environment, EnvironmentFactory, SuiteFactory}
import africa.absa.testing.scapi.json.factory.{EnvironmentFactory, SuiteFactory}
import africa.absa.testing.scapi.json.Environment
import africa.absa.testing.scapi.logging.Logger
import africa.absa.testing.scapi.model.{SuiteBundle, SuiteResults}
import africa.absa.testing.scapi.model.suite.{Suite, SuiteResult}
import africa.absa.testing.scapi.reporter.StdOutReporter
import africa.absa.testing.scapi.rest.RestClient
import africa.absa.testing.scapi.rest.request.sender.ScAPIRequestSender
Expand Down Expand Up @@ -47,20 +48,20 @@ object ScAPIRunner {
Logger.setLevel(if (cmd.debug) Level.DEBUG else Level.INFO)
cmd.logConfigInfo()

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

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

// run tests and result reporting - use categories for test filtering
if (cmd.validateOnly) {
Logger.info("Validate only => end run.")
} else {
Logger.info("Running tests")
val testResults: List[SuiteResults] = SuiteRunner.runSuites(suiteBundles, environment, () => new RestClient(ScAPIRequestSender))
StdOutReporter.printReport(testResults)
val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suiteBundles, environment, () => new RestClient(ScAPIRequestSender))
StdOutReporter.printReport(suiteResults)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,23 @@ object ScAPIRunnerConfig {
opt[String]("filter")
.optional()
.action((value, config) => { config.copy(filter = value) })
.text(s"Filter rule to select test definitions file (recursive) to include into test suite. Default is all '${DefaultFilter}'")
.text(s"Filter rule to select test definitions file (recursive) to include into test suite. Default is all '$DefaultFilter'")

opt[Seq[String]]("categories")
.optional()
.valueName("<v1>,<v2>")
.action((value, config) => { config.copy(categories = value.toSet) })
.text(s"Select which test categories will be included into test suite. Default is all '${DefaultCategories}'")
.text(s"Select which test categories will be included into test suite. Default is all '$DefaultCategories'")

opt[Int]("thread-count")
.optional()
.action((value, config) => { config.copy(threadCount = value) })
.text(s"Maximum count of thread used to run test suite. Default is '${DefaultThreadCount}'")
.text(s"Maximum count of thread used to run test suite. Default is '$DefaultThreadCount'")

opt[String]("file-format")
.optional()
.action((value, config) => { config.copy(fileFormat = value) })
.text(s"Format of definition files. Default is all '${DefaultFileFormat}'")
.text(s"Format of definition files. Default is all '$DefaultFileFormat'")

opt[String]("report")
.optional()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

package africa.absa.testing.scapi.json

import africa.absa.testing.scapi.rest.response.action.types.ResponseActionGroupType.ResponseActionGroupType
import africa.absa.testing.scapi.utils.cache.RuntimeCache
import africa.absa.testing.scapi.{PropertyNotFound, UndefinedConstantsInProperties}
import africa.absa.testing.scapi.{PropertyNotFoundException, UndefinedConstantsInPropertiesException}

import scala.util.matching.Regex

Expand Down Expand Up @@ -56,10 +57,10 @@ sealed protected trait ReferenceResolver {
* If there are any unresolved references, it throws an exception.
*
* @param notResolvedReferences A set of unresolved reference keys.
* @throws UndefinedConstantsInProperties If there are any unresolved references.
* @throws UndefinedConstantsInPropertiesException If there are any unresolved references.
*/
private def notResolved(notResolvedReferences: Set[String]): Unit =
if (notResolvedReferences.nonEmpty) throw UndefinedConstantsInProperties(notResolvedReferences, s"'${getClass.getSimpleName}' action.")
if (notResolvedReferences.nonEmpty) throw UndefinedConstantsInPropertiesException(notResolvedReferences, s"'${getClass.getSimpleName}' action.")

/**
* Resolve a map of references to their actual values. It iteratively updates the map with resolved values.
Expand Down Expand Up @@ -114,7 +115,7 @@ case class Environment private(constants: Map[String, String], properties: Map[S
* @param key The key to retrieve the value for.
* @return The value corresponding to the key.
*/
def apply(key: String): String = properties.getOrElse(key, constants.getOrElse(key, throw PropertyNotFound(key)))
def apply(key: String): String = properties.getOrElse(key, constants.getOrElse(key, throw PropertyNotFoundException(key)))

/**
* Method to resolve all the references in the environment's properties.
Expand Down Expand Up @@ -198,23 +199,20 @@ case class Action private(methodName: String, url: String, body: Option[String]
}

/**
* Case class that represents ResponseAction.
* This class is used to hold test response action.
* It implements the `ReferenceResolver` trait to support resolution of reference constants.
* Represents a `ResponseAction` case class.
*
* <p>This class encapsulates the details of a test response action and provides
* functionality to resolve reference constants through the `ReferenceResolver` trait.</p>
*
* @constructor create a new ResponseAction with a name and value.
* @param method the "group and name" of the response action.
* @param params the map containing the parameters of the response action. Each key-value pair in the map
* represents a parameter name and its corresponding value.
* @param group The type of the response action group.
* @param name The name that identifies the response action.
* @param params A map containing the parameters of the response action. Each entry in the map
* corresponds to a parameter name and its associated value.
*/
case class ResponseAction private(method: String,
case class ResponseAction private(group: ResponseActionGroupType,
name: String,
params: Map[String, String]) extends ReferenceResolver {

private def splitter: Seq[String] = method.split("\\.").toSeq

def group : String = splitter.head
def name : String = splitter.tail.head

/**
* Method to resolve references.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ package africa.absa.testing.scapi.json
trait Requestable {
def name: String

def headers: Set[Header]
def headers: Seq[Header]

def actions: Set[Action]
def actions: Seq[Action]

def responseActions: Set[ResponseAction]
def responseActions: Seq[ResponseAction]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
* limitations under the License.
*/

package africa.absa.testing.scapi.json
package africa.absa.testing.scapi.json.factory

import africa.absa.testing.scapi.json.Environment
import africa.absa.testing.scapi.json.schema.{JsonSchemaValidator, ScAPIJsonSchema}
import africa.absa.testing.scapi.utils.file.JsonUtils
import spray.json._
Expand Down
Loading
Loading