Skip to content

Commit

Permalink
pact-foundation#12: add cookie verification functionality. Peng & Jinwen
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhang Jinwen committed Mar 27, 2014
1 parent 428bb9b commit 211967e
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ object Matching {
s"Header Mismatch(\n\texpected: $expected\n\tactual: $actual)"
}
}
case class CookieMismatch(expected: List[String], actual: List[String]) extends MatchResult {
override def toString: String = {
s"Header 'Cookie' Mismatch(\n\texpected: $expected\n\tactual: $actual)"
}
}

case class BodyContentMismatch(diff: Diff) extends MatchResult {

override def toString: String = {
Expand Down Expand Up @@ -85,6 +91,15 @@ object Matching {
}
}

def matchCookie(expected: Option[List[String]], actual: Option[List[String]], reverseCookies: Boolean = false): MatchResult = {
def compareCookies(e: List[String], a: List[String]) = {
if (e == e.intersect(a)) MatchFound else CookieMismatch(e, a)
}
val e = expected.getOrElse(List.empty)
val a = actual.getOrElse(List.empty)
if (reverseCookies) compareCookies(a, e) else compareCookies(e, a)
}

def matchMethod(expected: String, actual: String): MatchResult = {
if(expected.equalsIgnoreCase(actual)) {
MatchFound
Expand Down
11 changes: 11 additions & 0 deletions pact-jvm-model/src/main/scala/au/com/dius/pact/model/Pact.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ case class Request(method: String,
body: Option[JValue]) {
def bodyString:Option[String] = body.map{ b => compact(render(b))}

def cookie: Option[List[String]] = cookieHeader.map(_._2.split(";").map(_.trim).toList)

def headersWithoutCookie: Option[Map[String, String]] = cookieHeader match {
case Some(cookie) => headers.map(_ - cookie._1)
case _ => headers
}

private def cookieHeader = findHeaderByCaseInsensitiveKey("cookie")

private def findHeaderByCaseInsensitiveKey(key: String): Option[(String, String)] = headers.flatMap(_.find(_._1.toLowerCase == key.toLowerCase))

override def toString: String = {
s"\tmethod: $method\n\tpath: $path\n\theaders: $headers\n\tbody:\n${body.map{b => pretty(render(b))}}"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ case class RequestMatching(interactions: Iterable[Interaction], reverseHeaders:

val result = matchMethod(request.method, actual.method) and
matchPath(request.path, actual.path) and
matchHeaders(request.headers, actual.headers, reverseHeaders) and
matchCookie(request.cookie, actual.cookie, reverseHeaders) and
matchHeaders(request.headersWithoutCookie, actual.headersWithoutCookie, reverseHeaders) and
matchBodies(request.body, actual.body, diffConfig)

// if(result != MatchFound) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package au.com.dius.pact.model
import org.specs2.mutable.Specification
import Fixtures._
import org.json4s.JsonDSL._
import au.com.dius.pact.model.HttpMethod._
import scala.Some

class RequestMatchingSpec extends Specification {

"request matching" should {
def test(r:Request):Option[Response] = RequestMatching(pact.interactions).findResponse(r)

def test(r: Request): Option[Response] = RequestMatching(pact.interactions).findResponse(r)

"match the valid request" in {
test(request) must beSome(response)
Expand Down Expand Up @@ -41,5 +45,56 @@ class RequestMatchingSpec extends Specification {
val extraHeaderRequest = request.copy(headers = request.headers.map(_.+("additonal" -> "header")))
test(extraHeaderRequest) must beSome(response)
}

}

"request with cookie" should {

val request = Request(Get, "/", Map("Cookie" -> "key1=value1;key2=value2"), "")
val interactions = List(interaction.copy(request = request))

def test(r: Request, reverseHeaders: Boolean = false): Option[Response] = RequestMatching(interactions, reverseHeaders).findResponse(r)

"match if actual cookie exactly matches the expected" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key1=value1;key2=value2"), "")
test(cookieRequest) must beSome(response)
}

"mismatch if actual cookie contains less data than expected cookie" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key2=value2"), "")
test(cookieRequest) must beNone
}

"match if actual cookie contains more data than expected one" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key2=value2;key1=value1;key3=value3"), "")
test(cookieRequest) must beSome(response)
}

"mismatch if actual cookie has no intersection with expected request" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key5=value5"), "")
test(cookieRequest) must beNone
}

"match when cookie field is different from cases" in {
val cookieRequest = Request(Get, "/", Map("cOoKie" -> "key1=value1;key2=value2"), "")
test(cookieRequest) must beSome(response)
}

"match when there are spaces between cookie items" in {
val cookieRequest = Request(Get, "/", Map("cookie" -> "key1=value1; key2=value2"), "")
test(cookieRequest) must beSome(response)
}

"mismatch if actual cookie contains more data than expected request when reverseHeaders option is true" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key2=value2;key1=value1;key3=value3"), "")
test(cookieRequest, reverseHeaders = true) must beNone
}

"match if actual cookie contains less data than expected request when reverseHeaders option is true" in {
val cookieRequest = Request(Get, "/", Map("Cookie" -> "key2=value2"), "")
test(cookieRequest, reverseHeaders =true) must beSome(response)
}

}

}

0 comments on commit 211967e

Please sign in to comment.