Check headers based on its availability

Hi there,

We have a API that will return list of json items in an array in the below format:
[
{…},
{…}
]

So, when the items have been more than 100, it will return 100 items in one response and provide “nextPage” in the headers.
When it has less than 100 items, it won’t provide “nextPage” headers.

As per the API behaviour, I have the below httprequestbuilder and scenario builder:

  val getActivationsOfMemberByFields: HttpRequestBuilder = getActivationOfMember("member_GetActivationsOfMemberByFields","?fields=full")
   .check(header("nextPage").optional.saveAs("fieldNextPage"))
  val getActivationsOfMemberByFieldsAndNextPage: HttpRequestBuilder = getActivationOfMember("member_GetActivationsOfMemberByFieldsAndNextPage","?fields=full&lastEvaluatedKey=${fieldNextPage}")
    .check(header("nextPage").optional.saveAs("fieldNextPage"))
exec(getActivationsOfMemberByFields)
                .asLongAs(session => session("fieldNextPage").asOption[String].isDefined) {
                  exec(getActivationsOfMemberByFieldsAndNextPage)
                    .exec(session => {
                      if (session("fieldNextPage").asOption[String].isEmpty) {
                        session.set("fieldNextPage", null)
                      } else {
                        session
                      }
                    })
                }

But also observe that, if nextPage is not available in response header, optional in check won’t affect “fieldNextPage” value it seems.

So, how we can approach this situation?

Please read carefully:

Main issue in your example:

Session instances are immutable, meaning that methods such as set return a new instance and leave the original instance unmodified!

// wrong usage: result from Session#set is discarded
exec { session =>
  session.set("foo", "bar")
  session
}

// correct usage
exec { session =>
  val newSession = session.set("foo", "bar")
  newSession
}

Hi @Zuhair,

You’re right about the current behavior. .optional does not remove the previously saved value.
(TBH I’m not sure if it is the desired behavior, but I can imagine of use cases for that too)

Anyway, you can empty the value in the beginning of your loop.

exec(getActivationsOfMemberByFields)
  .asLongAs(session => session("fieldNextPage").asOption[String].isDefined) {
    exec(session => session.remove("fieldNextPage"))
      .exec(getActivationsOfMemberByFieldsAndNextPage)
  }

Does that help?

Cheers!

Hi @GeMi, understood but in my code snippet I haven’t written the empty session after set the value for “fieldNextPage”. I am returning session.set(“fieldNextPage”, null) if “fieldNextPage” is found empty. So that set won’t discarded. Is that correct?

Hi @sbrevet , empty the value will impact in calling HTTP request “getActivationsOfMemberByFieldsAndNextPage” as we are passing the session value of “fieldNextPage” in queryparams.

You should have two distinct values, then. One for param and one for check.

val getActivationsOfMemberByFieldsAndNextPage: HttpRequestBuilder =
  getActivationOfMember(
    "member_GetActivationsOfMemberByFieldsAndNextPage",
    "?fields=full&lastEvaluatedKey=#{paramNextPage}"  // <- note the change here
    ).check(header("nextPage").optional.saveAs("fieldNextPage"))

exec(getActivationsOfMemberByFields)
  .asLongAs(session => session("fieldNextPage").asOption[String].isDefined) {
    exec(session => session.set("paramNextPage", session("fieldNextPage").as[String]).remove("fieldNextPage"))
      .exec(getActivationsOfMemberByFieldsAndNextPage)
  }

Thank you @sbrevet. The above code snippet helps to solve the test case.