package core.controllers.graphql.contact

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.StatusCodes.OK
import akka.http.scaladsl.testkit.RouteTestTimeout
import akka.testkit.TestDuration
import akka.util.ByteString
import core.controllers.graphql.TestHelper
import core.controllers.graphql.jsonProtocols.GraphQLMessage
import core.controllers.graphql.jsonProtocols.GraphQLMessageJsonProtocol._
import modules.common.FieldError
import modules.contact.models.ContactPayload
import spray.json._

import scala.concurrent.duration._

class QuerySpec extends TestHelper {

  "GraphQLController" must {

    implicit val contactPayloadJsonReader: ContactPayloadJsonReader.type = ContactPayloadJsonReader
    implicit val timeout: RouteTestTimeout = RouteTestTimeout(10.seconds.dilated)

    "send a mail" in {
      val mutation = "mutation contact($input: ContactInput!) { contact(input: $input) { errors { message } } }"
      val variables =
        """{"input":
          |{"name": "test_user",
          |"email": "test_user@gmail.com",
          |"content": "Test message"}}""".stripMargin.parseJson.asJsObject
      val graphQLMessage = ByteString(GraphQLMessage(mutation, None, Some(variables)).toJson.compactPrint)
      val entity = HttpEntity(`application/json`, graphQLMessage)
      Post(endpoint, entity) ~> routes ~> check {
        val contactPayload = responseAs[String].parseJson.convertTo[ContactPayload]

        status shouldBe OK
        contentType.mediaType shouldBe `application/json`

        contactPayload.errors should not be defined
      }
    }
  }
}

object ContactPayloadJsonReader extends JsonReader[ContactPayload] with DefaultJsonProtocol {
  override def read(json: JsValue): ContactPayload = {
    println(json)
    json.asJsObject.getFields("data", "errors") match {
      case Seq(_) => ContactPayload(None)
      case Seq(_, JsArray(errors)) =>
        val errorsList = errors.map {
          error =>
            FieldError("", error.asJsObject.fields.head._2.convertTo[String])
        }.toList
        ContactPayload(Some(errorsList))
      case _ => throw DeserializationException("")
    }
  }
}
Add querySpec for contact module
Add querySpec for contact module
