/*
 * Copyright 2015-2016 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package whisk.core.controller.test

import scala.language.postfixOps

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import spray.http.StatusCodes._
import spray.httpx.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._
import spray.json._
import whisk.core.controller.WhiskRulesApi
import whisk.core.entity._
import whisk.core.entity.test.OldWhiskTrigger
import whisk.http.ErrorResponse
import scala.language.postfixOps
import whisk.core.entity.test.OldWhiskRule
import whisk.http.Messages

/**
 * Tests Rules API.
 *
 * Unit tests of the controller service as a standalone component.
 * These tests exercise a fresh instance of the service object in memory -- these
 * tests do NOT communication with a whisk deployment.
 *
 *
 * @Idioglossia
 * "using Specification DSL to write unit tests, as in should, must, not, be"
 * "using Specs2RouteTest DSL to chain HTTP requests for unit testing, as in ~>"
 */
@RunWith(classOf[JUnitRunner])
class RulesApiTests extends ControllerTestCommon with WhiskRulesApi {

    /** Rules API tests */
    behavior of "Rules API"

    val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
    val namespace = EntityPath(creds.subject())
    def aname() = MakeName.next("rules_tests")
    def afullname(namespace: EntityPath, name: String) = FullyQualifiedEntityName(namespace, EntityName(name))
    val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
    val activeStatus = s"""{"status":"${Status.ACTIVE}"}""".parseJson.asJsObject
    val inactiveStatus = s"""{"status":"${Status.INACTIVE}"}""".parseJson.asJsObject
    val entityTooBigRejectionMessage = "request entity too large"
    val parametersLimit = Parameters.sizeLimit

    //// GET /rules
    it should "list rules by default/explicit namespace" in {
        implicit val tid = transid()

        val rules = (1 to 2).map { i =>
            WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), afullname(namespace, "bogus action"))
        }.toList
        rules foreach { put(entityStore, _) }
        waitOnView(entityStore, WhiskRule, namespace, 2)
        Get(s"$collectionPath") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[List[JsObject]]
            rules.length should be(response.length)
            rules forall { r => response contains r.summaryAsJson } should be(true)
        }

        // it should "list trirulesggers with explicit namespace owned by subject" in {
        Get(s"/$namespace/${collection.path}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[List[JsObject]]
            rules.length should be(response.length)
            rules forall { r => response contains r.summaryAsJson } should be(true)
        }

        // it should "reject list rules with explicit namespace not owned by subject" in {
        val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
        Get(s"/$namespace/${collection.path}") ~> sealRoute(routes(auser)) ~> check {
            status should be(Forbidden)
        }
    }

    //?docs disabled
    ignore should "list rules by default namespace with full docs" in {
        implicit val tid = transid()

        val rules = (1 to 2).map { i =>
            WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), afullname(namespace, "bogus action"))
        }.toList
        rules foreach { put(entityStore, _) }
        waitOnView(entityStore, WhiskRule, namespace, 2)
        Get(s"$collectionPath?docs=true") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[List[WhiskRule]]
            rules.length should be(response.length)
            rules forall { r => response contains r } should be(true)
        }
    }

    //// GET /rule/name
    it should "get rule by name in default/explicit namespace" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), afullname(namespace, "bogus action"))
        put(entityStore, rule)
        Get(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }

        // it should "get trigger by name in explicit namespace owned by subject" in
        Get(s"/$namespace/${collection.path}/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }

        // it should "reject get trigger by name in explicit namespace not owned by subject" in
        val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
        Get(s"/$namespace/${collection.path}/${rule.name}") ~> sealRoute(routes(auser)) ~> check {
            status should be(Forbidden)
        }
    }

    it should "reject get of non existent rule" in {
        implicit val tid = transid()

        Get(s"$collectionPath/xxx") ~> sealRoute(routes(creds)) ~> check {
            status should be(NotFound)
        }
    }

    it should "get rule with active state in trigger" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, EntityName("get_active_rule"), afullname(namespace, "get_active_rule trigger"), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.ACTIVE))
        })

        put(entityStore, trigger)
        put(entityStore, rule)

        Get(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
        }
    }

    it should "get rule with no rule-entries in trigger" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, EntityName("get_rule_with_empty_trigger trigger"))
        val rule = WhiskRule(namespace, EntityName("get_rule_with_empty_trigger"), trigger.fullyQualifiedName(false), afullname(namespace, "an action"))

        put(entityStore, trigger)
        put(entityStore, rule)

        Get(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }
    }

    it should "report Conflict if the name was of a different type" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())

        put(entityStore, trigger)

        Get(s"/$namespace/${collection.path}/${trigger.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(Conflict)
        }
    }

    // DEL /rules/name
    it should "reject delete rule in state active" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, EntityName("reject_delete_rule_active"), FullyQualifiedEntityName(namespace, aname()), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.ACTIVE))
        })

        put(entityStore, trigger)
        put(entityStore, rule)

        Delete(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(Conflict)
            val response = responseAs[ErrorResponse]
            response.error should be(s"rule status is '${Status.ACTIVE}', must be '${Status.INACTIVE}' to delete")
            response.code() should be >= 1L
        }
    }

    it should "delete rule in state inactive" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), FullyQualifiedEntityName(namespace, aname()))
        val triggerLink = ReducedRule(rule.action, Status.INACTIVE)
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name, rules = Some(Map(rule.fullyQualifiedName(false) -> triggerLink)))

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Delete(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(OK)
            t.rules.get.get(rule.fullyQualifiedName(false)) shouldBe None
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }
    }

    it should "delete rule in state inactive even if the trigger has been deleted" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, EntityName("delete_rule_inactive"), afullname(namespace, "a trigger"), afullname(namespace, "an action"))

        put(entityStore, rule)

        Delete(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }
    }

    it should "delete rule in state inactive even if the trigger has no reference to the rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name)

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Delete(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            deleteTrigger(trigger.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.INACTIVE))
        }
    }

    //// PUT /rules/name
    it should "create rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), FullyQualifiedEntityName(namespace, aname()))
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name)
        val action = WhiskAction(rule.action.path, rule.action.name, Exec.js("??"))
        val content = WhiskRulePut(Some(rule.trigger), Some(rule.action))

        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
            t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
        }
    }

    it should "create rule without fully qualifying name" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), FullyQualifiedEntityName(namespace, aname()))
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name)
        val action = WhiskAction(rule.action.path, rule.action.name, Exec.js("??"))
        val content = JsObject("trigger" -> JsString(s"/_/${trigger.name()}"), "action" -> JsString(s"/_/${action.name()}"))

        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
            t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
        }
    }

    it should "reject create rule without namespace in referenced entities" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), FullyQualifiedEntityName(namespace, aname()))
        val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name)
        val action = WhiskAction(rule.action.path, rule.action.name, Exec.js("??"))
        val contentT = JsObject("trigger" -> trigger.name.toJson, "action" -> action.fullyQualifiedName(false).toDocId.toJson)
        val contentA = JsObject("action" -> action.name.toJson, "trigger" -> trigger.fullyQualifiedName(false).toDocId.toJson)

        Put(s"$collectionPath/${rule.name}", contentT) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] shouldBe s"The request content was malformed:\nrequirement failed: ${Messages.malformedFullyQualifiedEntityName}"
        }

        Put(s"$collectionPath/${rule.name}", contentA) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] shouldBe s"The request content was malformed:\nrequirement failed: ${Messages.malformedFullyQualifiedEntityName}"
        }
    }

    it should "create rule with an action in a package" in {
        implicit val tid = transid()

        val provider = WhiskPackage(namespace, aname(), publish = true)
        val action = WhiskAction(provider.fullPath, aname(), Exec.js("??"))
        val trigger = WhiskTrigger(namespace, aname())
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), action.fullyQualifiedName(false))
        val content = WhiskRulePut(Some(rule.trigger), Some(rule.action))

        put(entityStore, provider)
        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
            t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
        }
    }

    it should "create rule with an action in a binding" in {
        implicit val tid = transid()

        val provider = WhiskPackage(namespace, aname(), publish = true)
        val reference = WhiskPackage(namespace, aname(), provider.bind)
        val action = WhiskAction(provider.fullPath, aname(), Exec.js("??"))
        val trigger = WhiskTrigger(namespace, aname())
        val actionReference = reference.binding.map(b => b.namespace.addPath(b.name)).get
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), FullyQualifiedEntityName(actionReference, action.name))
        val content = WhiskRulePut(Some(rule.trigger), Some(rule.action))

        put(entityStore, provider)
        put(entityStore, reference)
        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
            t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
        }
    }

    it should "reject create rule with annotations which are too big" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))

        val keys: List[Long] = List.range(Math.pow(10, 9) toLong, (Parameters.sizeLimit.toBytes / 2 / 20 + Math.pow(10, 9) + 2) toLong)
        val parameters = keys map { key =>
            Parameters(key.toString, "a" * 10)
        } reduce (_ ++ _)
        val content = s"""{"trigger":"${trigger.name}","action":"${action.name}","annotations":$parameters}""".parseJson.asJsObject

        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${aname()}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(RequestEntityTooLarge)
            response.entity.toString should include(entityTooBigRejectionMessage)
        }
    }

    it should "reject update rule with annotations which are too big" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), action.fullyQualifiedName(false))

        val keys: List[Long] = List.range(Math.pow(10, 9) toLong, (Parameters.sizeLimit.toBytes / 2 / 20 + Math.pow(10, 9) + 2) toLong)
        val parameters = keys map { key =>
            Parameters(key.toString, "a" * 10)
        } reduce (_ ++ _)
        val content = s"""{"trigger":"${trigger.name}","action":"${action.name}","annotations":$parameters}""".parseJson.asJsObject

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(RequestEntityTooLarge)
            response.entity.toString should include(entityTooBigRejectionMessage)
        }
    }

    it should "reject rule if action does not exist" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val content = WhiskRulePut(Some(trigger.fullyQualifiedName(false)), Some(afullname(namespace, "bogus action")))

        put(entityStore, trigger)

        Put(s"$collectionPath/xxx", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] === s"${content.action.get.qualifiedNameWithLeadingSlash} does not exist"
        }
    }

    it should "reject rule if trigger does not exist" in {
        implicit val tid = transid()

        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val content = WhiskRulePut(Some(afullname(namespace, "bogus trigger")), Some(action.fullyQualifiedName(false)))

        put(entityStore, action)

        Put(s"$collectionPath/xxx", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] === s"${content.trigger.get.qualifiedNameWithLeadingSlash} does not exist"
        }
    }

    it should "reject rule if neither action or trigger do not exist" in {
        implicit val tid = transid()

        val content = WhiskRulePut(Some(afullname(namespace, "bogus trigger")), Some(afullname(namespace, "bogus action")))

        Put(s"$collectionPath/xxx", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String].contains("does not exist") should be(true)
        }
    }

    it should "update rule updating trigger and action at once" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), afullname(namespace, "bogus action"))
        val content = WhiskRulePut(Some(trigger.fullyQualifiedName(false)), Some(action.fullyQualifiedName(false)))

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule, false)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)

            t.rules.get(rule.fullyQualifiedName(false)).action should be(action.fullyQualifiedName(false))
            val response = responseAs[WhiskRuleResponse]
            response should be(WhiskRuleResponse(namespace, rule.name, Status.ACTIVE, trigger.fullyQualifiedName(false), action.fullyQualifiedName(false), version = SemVer().upPatch))
        }
    }

    it should "update rule with a new action while passing the same trigger" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), afullname(namespace, "bogus action"))
        val content = WhiskRulePut(Some(trigger.fullyQualifiedName(false)), Some(action.fullyQualifiedName(false)))

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule, false)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            t.rules.get(rule.fullyQualifiedName(false)).action should be(action.fullyQualifiedName(false))
            val response = responseAs[WhiskRuleResponse]
            response should be(WhiskRuleResponse(namespace, rule.name, Status.ACTIVE, trigger.fullyQualifiedName(false), action.fullyQualifiedName(false), version = SemVer().upPatch))
        }
    }

    it should "update rule with just a new action" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), afullname(namespace, "bogus action"))
        val content = WhiskRulePut(action = Some(action.fullyQualifiedName(false)))

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule, false)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            t.rules.get(rule.fullyQualifiedName(false)).action should be(action.fullyQualifiedName(false))
            val response = responseAs[WhiskRuleResponse]
            response should be(WhiskRuleResponse(namespace, rule.name, Status.ACTIVE, trigger.fullyQualifiedName(false), action.fullyQualifiedName(false), version = SemVer().upPatch))
        }
    }

    it should "update rule with just a new trigger" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), action.fullyQualifiedName(false))
        val content = WhiskRulePut(trigger = Some(trigger.fullyQualifiedName(false)))

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule, false)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            t.rules.get.get(rule.fullyQualifiedName(false)) shouldBe a[Some[_]]
            val response = responseAs[WhiskRuleResponse]
            response should be(WhiskRuleResponse(namespace, rule.name, Status.ACTIVE, trigger.fullyQualifiedName(false), action.fullyQualifiedName(false), version = SemVer().upPatch))
        }
    }

    it should "update rule when no new content is provided" in {
        implicit val tid = transid()
        val trigger = WhiskTrigger(namespace, aname())
        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), action.fullyQualifiedName(false))
        val content = WhiskRulePut(None, None, None, None, None)

        put(entityStore, trigger, false)
        put(entityStore, action)
        put(entityStore, rule, false)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            deleteTrigger(trigger.docid)
            deleteRule(rule.docid)

            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(WhiskRuleResponse(namespace, rule.name, Status.ACTIVE, trigger.fullyQualifiedName(false), action.fullyQualifiedName(false), version = SemVer().upPatch))
        }
    }

    it should "reject update rule if trigger does not exist" in {
        implicit val tid = transid()

        val action = WhiskAction(namespace, aname(), Exec.js("??"))
        val rule = WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), action.fullyQualifiedName(false))
        val content = WhiskRulePut(action = Some(action.fullyQualifiedName(false)))

        put(entityStore, action)
        put(entityStore, rule)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] === s"${rule.trigger.qualifiedNameWithLeadingSlash} does not exist"
        }
    }

    it should "reject update rule if action does not exist" in {
        implicit val tid = transid()

        val trigger = WhiskTrigger(namespace, aname())
        val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), afullname(namespace, "bogus action"))
        val content = WhiskRulePut(trigger = Some(trigger.fullyQualifiedName(false)))

        put(entityStore, trigger)
        put(entityStore, rule)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] === s"${rule.action.qualifiedNameWithLeadingSlash} does not exist"
        }
    }

    it should "reject update rule if neither trigger or action exist" in {
        implicit val tid = transid()
        val rule = WhiskRule(namespace, aname(), afullname(namespace, "bogus trigger"), afullname(namespace, "bogus action"))
        val content = WhiskRulePut(None, None, None, None, None)

        put(entityStore, rule)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[String] should {
                include(s"${rule.action.qualifiedNameWithLeadingSlash} does not exist") or
                    include(s"${rule.trigger.qualifiedNameWithLeadingSlash} does not exist")
            }
        }
    }

    it should "reject update rule in state active" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, "a trigger"), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.ACTIVE))
        })
        val content = WhiskRulePut(publish = Some(!rule.publish))

        put(entityStore, trigger)
        put(entityStore, rule)

        Put(s"$collectionPath/${rule.name}?overwrite=true", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(Conflict)
        }
    }

    //// POST /rules/name
    it should "do nothing to disable already disabled rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, "a trigger"), afullname(namespace, "an action"))

        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", inactiveStatus) ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
        }
    }

    it should "do nothing to enable already enabled rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.ACTIVE))
        })

        put(entityStore, trigger)
        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", activeStatus) ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
        }
    }

    it should "reject post with status undefined" in {
        implicit val tid = transid()

        Post(s"$collectionPath/xyz") ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
        }
    }

    it should "reject post with invalid status" in {
        implicit val tid = transid()

        val badStatus = s"""{"status":"xxx"}""".parseJson.asJsObject

        Post(s"$collectionPath/xyz", badStatus) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
        }
    }

    it should "activate rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.INACTIVE))
        })

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", activeStatus) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(OK)

            t.rules.get(rule.fullyQualifiedName(false)).status should be(Status.ACTIVE)
        }
    }

    it should "activate rule without rule in trigger" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name)

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", activeStatus) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(OK)
            t.rules.get(rule.fullyQualifiedName(false)).status should be(Status.ACTIVE)
        }
    }

    it should "reject rule activation, if the trigger is absent" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, "an action"))

        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", activeStatus) ~> sealRoute(routes(creds)) ~> check {
            status should be(NotFound)
        }
    }

    it should "deactivate rule" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, "an action"))
        val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
            Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action, Status.ACTIVE))
        })

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", inactiveStatus) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(OK)
            t.rules.get(rule.fullyQualifiedName(false)).status should be(Status.INACTIVE)
        }
    }

    // invalid resource
    it should "reject invalid resource" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, "a trigger"), afullname(namespace, "an action"))

        put(entityStore, rule)

        Get(s"$collectionPath/${rule.name}/bar") ~> sealRoute(routes(creds)) ~> check {
            status should be(NotFound)
        }
    }

    // migration path
    it should "handle a rule with the old schema gracefully" in {
        implicit val tid = transid()

        val rule = OldWhiskRule(namespace, aname(), EntityName("a trigger"), EntityName("an action"), Status.ACTIVE)

        put(entityStore, rule)

        Get(s"$collectionPath/${rule.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(OK)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.toWhiskRule.withStatus(Status.INACTIVE))
        }
    }

    it should "create rule even if the attached trigger has the old schema" in {
        implicit val tid = transid()

        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, aname().name))
        val trigger = OldWhiskTrigger(namespace, rule.trigger.name)

        val action = WhiskAction(namespace, rule.action.name, Exec.js("??"))
        val content = WhiskRulePut(Some(rule.trigger), Some(rule.action))

        put(entityStore, trigger, false)
        put(entityStore, action)

        Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)
            deleteRule(rule.docid)

            status should be(OK)
            t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
            val response = responseAs[WhiskRuleResponse]
            response should be(rule.withStatus(Status.ACTIVE))
        }
    }

    it should "activate rule even if it is still in the old schema" in {
        implicit val tid = transid()

        val ruleNameQualified = FullyQualifiedEntityName(namespace, aname())
        val triggerName = aname()
        val actionName = FullyQualifiedEntityName(namespace, aname())
        val rule = OldWhiskRule(namespace, ruleNameQualified.name, triggerName, actionName.name, Status.ACTIVE)
        val trigger = WhiskTrigger(namespace, triggerName, rules = Some(Map(ruleNameQualified -> ReducedRule(actionName, Status.INACTIVE))))

        put(entityStore, trigger, false)
        put(entityStore, rule)

        Post(s"$collectionPath/${rule.name}", activeStatus) ~> sealRoute(routes(creds)) ~> check {
            val t = get(entityStore, trigger.docid, WhiskTrigger)
            deleteTrigger(t.docid)

            status should be(OK)

            t.rules.get(ruleNameQualified).status should be(Status.ACTIVE)
        }
    }

    it should "report proper error when record is corrupted on delete" in {
        implicit val tid = transid()
        val entity = BadEntity(namespace, aname())
        put(entityStore, entity)

        Delete(s"$collectionPath/${entity.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(InternalServerError)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }
    }

    it should "report proper error when record is corrupted on get" in {
        implicit val tid = transid()
        val entity = BadEntity(namespace, aname())
        put(entityStore, entity)

        Get(s"$collectionPath/${entity.name}") ~> sealRoute(routes(creds)) ~> check {
            status should be(InternalServerError)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }
    }

    it should "report proper error when record is corrupted on put" in {
        implicit val tid = transid()
        val entity = BadEntity(namespace, aname())
        put(entityStore, entity)

        val content = WhiskRulePut()
        Put(s"$collectionPath/${entity.name}", content) ~> sealRoute(routes(creds)) ~> check {
            status should be(InternalServerError)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }
    }

    it should "report proper error when action record is corrupted on put" in {
        implicit val tid = transid()
        val tentity = BadEntity(namespace, aname())
        val aentity = BadEntity(namespace, aname())
        val rule = WhiskRule(namespace, aname(), afullname(namespace, aname().name), afullname(namespace, aname().name))
        val trigger = WhiskTrigger(namespace, rule.trigger.name)
        val action = WhiskAction(namespace, rule.action.name, Exec.js("??"))

        val contenta = WhiskRulePut(Some(tentity.fullyQualifiedName(false)), Some(aentity.fullyQualifiedName(false)))
        val contentb = WhiskRulePut(Some(trigger.fullyQualifiedName(false)), Some(aentity.fullyQualifiedName(false)))
        val contentc = WhiskRulePut(Some(tentity.fullyQualifiedName(false)), Some(action.fullyQualifiedName(false)))

        put(entityStore, tentity)
        put(entityStore, aentity)
        put(entityStore, trigger)
        put(entityStore, action)

        Put(s"$collectionPath/${aname()}", contenta) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }

        Put(s"$collectionPath/${aname()}", contentb) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }

        Put(s"$collectionPath/${aname()}", contentc) ~> sealRoute(routes(creds)) ~> check {
            status should be(BadRequest)
            responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
        }
    }
}
