Skip to content

Instantly share code, notes, and snippets.

@binshuohu
Created December 8, 2015 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save binshuohu/256525d05b8262e9f466 to your computer and use it in GitHub Desktop.
Save binshuohu/256525d05b8262e9f466 to your computer and use it in GitHub Desktop.
refactor a function
import spray.http._
object Foo {
def collectQueryParameters(query: Uri.Query, headers: List[HttpHeader]) = {
val contentType = headers.filter(_.name == "Content-Type")
val referrer = headers.filter(_.name == "Referrer")
(contentType.isEmpty, referrer.isEmpty) match {
case (false, false) => {
val cookie = headers.filter(_.name == "Cookie")
val contentTypeHead = contentType.head
val referrerHead = referrer.head
val parameters = collection.mutable.Map[String, String]()
query.toMap.map(item => parameters.update(item._1, item._2))
parameters.update(contentTypeHead.name, contentTypeHead.value)
if (!cookie.isEmpty) {
val cookieValue = cookie.head.value
val cookieMap = cookieValue.split(";").filter(_.contains("Agent-List"))
if (!cookieMap.isEmpty) {
val cookieAgentList = cookieMap.apply(0).split("=")
parameters.update(cookieAgentList.apply(0), cookieAgentList.apply(1))
}
}
parameters.update(referrerHead.name, referrerHead.value)
Some(parameters)
}
case _ => {
None
}
}
}
//this is what a *function* should be like.
def collectQueryParametersV2(query: Uri.Query, headers: List[HttpHeader]) = {
def agentList: Option[(String, String)] = for {
cookie <- headers find (_.name == "Cookie")
pattern = ".*?( ?Agent-List)=([^;]+)+.*".r
m <- pattern findFirstMatchIn cookie.value
} yield (m group 1, m group 2)
for {
contentType <- headers find (_.name == "Content-Type")
referrer <- headers find (_.name == "Referrer")
parameters = (query.toMap ++ agentList)
.updated(contentType.name, contentType.value)
.updated(referrer.name, referrer.value)
} yield parameters
}
}
import org.scalatest._
import spray.http._
import spray.http.HttpHeaders._
import spray.http.ContentTypes._
import Foo._
class CollectParamsSpec extends FlatSpec with Matchers {
val agent = "bazinga"
val cookie = HttpHeaders.Cookie(
HttpCookie("Agent-List", agent),
HttpCookie("Humpty", "Dumpty"))
val query = Uri.Query(Map[String, String](
"abc" -> "ABC",
"xyz" -> "XYZ")
)
val contentType = `Content-Type`(`application/json`)
val referrer = HttpHeaders.RawHeader("Referrer", "www.hooli.xyz")
"An empty header" should "return Nothing" in {
collectQueryParameters(query, List()) shouldBe None
collectQueryParametersV2(query, List()) shouldBe None
}
"headers with content-type and referrer" should "get tangible params" in {
collectQueryParametersV2(query, List(contentType, referrer)) shouldBe
collectQueryParameters(query, List(contentType, referrer))
}
"headers with agent list in cookie" should "inlude agent list" in {
collectQueryParametersV2(query, List(contentType, referrer, cookie)) shouldBe
collectQueryParameters(query, List(contentType, referrer, cookie))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment