/* ****************************************************************************
*
* render - 
*/
TEST(ContextRegistrationAttributeVector, render)
{
  ContextRegistrationAttributeVector crav;
  ContextRegistrationAttribute       cra("name", "type", "false");
  ContextRegistrationAttribute       cra2("name2", "type2", "true");
  std::string                        out;  
  const char*                        outfile1 = "ngsi.contextRegistrationAttributeVector.render1.middle.json";
  const char*                        outfile2 = "ngsi.contextRegistrationAttributeVector.render2.middle.json";

  utInit();

  out = crav.render("");
  EXPECT_STREQ("", out.c_str());

  out = crav.render("");
  EXPECT_STREQ("", out.c_str());

  crav.push_back(&cra);
  out = crav.render("");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  crav.push_back(&cra2);
  out = crav.render("");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* render - 
*/
TEST(MetadataVector, render)
{
  Metadata        m("Name", "Type", "Value");
  Metadata        m2("Name2", "Type2", "Value2");
  MetadataVector  mV("registrationMetadata");
  const char*     outfile1 = "ngsi.metadataVector.render1.middle.json";
  const char*     outfile2 = "ngsi.metadataVector.render3.middle.json";
  std::string     out;

  utInit();

  mV.push_back(&m);

  out = mV.render("");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  mV.keyNameSet("metadata");

  mV.push_back(&m2); 
  out = mV.render("");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* xml_ok - 
*/
TEST(NotifyContextRequest, xml_ok)
{
  ParseData              reqData;
  ConnectionInfo         ci("", "POST", "1.1");
  std::string            rendered;
  const char*            infile   = "ngsi10.notifyContextRequest.ok.valid.xml";
  const char*            outfile  = "ngsi10.notifyContextResponse.ok.valid.xml";
  NotifyContextRequest*  ncrP     = &reqData.ncr.res;

  utInit();
  
  ci.outFormat = XML;

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";

  lmTraceLevelSet(LmtDump, true);
  std::string result = xmlTreat(testBuf, &ci, &reqData, NotifyContext, "notifyContextRequest", NULL);
  EXPECT_EQ("OK", result);
  lmTraceLevelSet(LmtDump, false);

  ncrP->present("");

  rendered = ncrP->render(&ci, NotifyContext, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  EXPECT_STREQ(expectedBuf, rendered.c_str());

  ncrP->present("");
  ncrP->release();

  utExit();
}
/* ****************************************************************************
*
* ok - 
*/
TEST(AttributeDomainName, ok)
{
  AttributeDomainName adn;
  std::string         out;
  const char*         outfile1 = "ngsi10.attributeDomainName.ok.middle.xml";
  const char*         outfile2 = "ngsi10.attributeDomainName.ok.middle.json";

  utInit();

  EXPECT_TRUE(adn.isEmpty());
  
  adn.set("ADN");
  EXPECT_FALSE(adn.isEmpty());
  EXPECT_STREQ("ADN", adn.get().c_str());
  EXPECT_STREQ("ADN", adn.c_str());

  out = adn.render(XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = adn.render(JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  // Just to exercise the code
  adn.present("");
  adn.set("");
  adn.present("");
  out = adn.render(JSON, "");
  EXPECT_STREQ("", out.c_str());

  utExit();
}
/* ****************************************************************************
*
* ok_json - 
*/
TEST(NotifyContextAvailabilityRequest, ok_json)
{
  ParseData       parseData;
  const char*     fileName = "ngsi9.notifyContextAvailabilityRequest.ok2.valid.json";
  ConnectionInfo  ci("", "POST", "1.1");
  std::string     out;

  utInit();

  ci.inFormat  = JSON;
  ci.outFormat = JSON;

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), fileName)) << "Error getting test data from '" << fileName << "'";

  lmTraceLevelSet(LmtDump, true);
  out = jsonTreat(testBuf, &ci, &parseData, NotifyContextAvailability, "notifyContextAvailabilityRequest", NULL);
  EXPECT_EQ("OK", out);
  lmTraceLevelSet(LmtDump, false);

  NotifyContextAvailabilityRequest* ncarP = &parseData.ncar.res;

  const char*     outfile = "ngsi9.notifyContextAvailabilityRequest.ok.valid.json";

  out = ncarP->render(NotifyContext, JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  ncarP->release();
  
  utExit();
}
/* ****************************************************************************
*
* ok - 
*/
TEST(ConditionValueList, ok)
{
  ConditionValueList cvList;
  std::string        out;
  const char*        outfile1 = "ngsi.conditionValueList.ok2.middle.json";
  const char*        outfile2 = "ngsi.conditionValueList.ok3.middle.json";

  out = cvList.render("", false);
  EXPECT_STREQ("", out.c_str());

  cvList.push_back("cv1");

  out = cvList.render("", false);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  cvList.push_back("cv2");
  out = cvList.render("", false);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = cvList.check(SubscribeContext, "", "", 0);
  EXPECT_STREQ("OK", out.c_str());

  cvList.push_back("");
  out = cvList.check(SubscribeContext, "", "", 0);
  EXPECT_STREQ("empty condValue name", out.c_str());

  // Just to exercise the code
  cvList.present("");

  cvList.release();
  EXPECT_EQ(0, cvList.size());
}
/* ****************************************************************************
*
* constructorsAndCheck -
*
* FIXME P5 #1862: _json countepart?
*/
TEST(UnsubscribeContextAvailabilityRequest, DISABLED_constructorAndCheck)
{
  UnsubscribeContextAvailabilityRequest ucar1;
  SubscriptionId                        subId("012345678901234567890123");
  UnsubscribeContextAvailabilityRequest ucar2(subId);

  utInit();

  EXPECT_EQ("", ucar1.subscriptionId.get());
  EXPECT_EQ("012345678901234567890123", ucar2.subscriptionId.get());

  std::string   out;
  const char*   outfile1 = "ngsi9.unsubscribeContextAvailabilityResponse.forcedError.valid.xml";
  const char*   outfile2 = "ngsi9.unsubscribeContextAvailabilityResponse.invalidSubscriptionId.valid.xml";

  out = ucar1.check(UnsubscribeContextAvailability, "", "Forced Error", 0);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  ucar1.subscriptionId.set("1");
  out = ucar1.check(UnsubscribeContextAvailability, "", "", 0);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = ucar2.check(UnsubscribeContextAvailability, "", "", 0);
  EXPECT_EQ("OK", out);

  utExit();
}
/* ****************************************************************************
*
* jsonRender - 
*
*/
TEST(UnsubscribeContextAvailabilityResponse, jsonRender)
{
  const char*                              filename1  = "ngsi9.unsubscribeContextAvailabilityResponse.jsonRender1.valid.json";
  const char*                              filename2  = "ngsi9.unsubscribeContextAvailabilityResponse.jsonRender2.valid.json";
  UnsubscribeContextAvailabilityResponse*  ucasP;
  std::string                              out;

  utInit();

  // Preparations
  ucasP = new UnsubscribeContextAvailabilityResponse();
  ucasP->subscriptionId.set("012345678901234567890123");

  // 1. short and ok statusCode
  ucasP->statusCode.fill(SccOk);

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), filename1)) << "Error getting test data from '" << filename1 << "'";
  out = ucasP->render(UpdateContextAvailabilitySubscription, JSON, "");
  EXPECT_STREQ(expectedBuf, out.c_str());

  
  // 2. Long and !OK statusCode
  ucasP->statusCode.fill(SccBadRequest, "no details");

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), filename2)) << "Error getting test data from '" << filename2 << "'";
  out = ucasP->render(UpdateContextAvailabilitySubscription, JSON, "");
  EXPECT_STREQ(expectedBuf, out.c_str());

  free(ucasP);

  utExit();
}
/* ****************************************************************************
*
* error - 
*/
TEST(exitTreat, error)
{
  ConnectionInfo ci1("/exit",  "GET", "1.1");
  ConnectionInfo ci2("/exit/nadadenada",  "GET", "1.1");
  ConnectionInfo ci3("/exit/harakiri",  "GET", "1.1");
  const char*    outfile1 = "orion.exit.error1.valid.xml";
  const char*    outfile2 = "orion.exit.error2.valid.xml";
  const char*    outfile3 = "orion.exit.error3.valid.xml";
  std::string    out;

  utInit();

  harakiri = true;

  out = restService(&ci1, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = restService(&ci2, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  harakiri = false;
  out = restService(&ci3, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  harakiri = true;
  out = restService(&ci3, rs);
  EXPECT_STREQ("DIE", out.c_str());
  harakiri = false;

  utExit();
}
/* ****************************************************************************
*
* ok_xml - 
*/
TEST(QueryContextRequest, ok_xml)
{
  ParseData       reqData;
  ConnectionInfo  ci("", "POST", "1.1");
  const char*     infile = "ngsi10.queryContextRequest.ok.valid.xml";

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";

  lmTraceLevelSet(LmtDump, true);
  std::string out = xmlTreat(testBuf, &ci, &reqData, QueryContext, "queryContextRequest", NULL);
  lmTraceLevelSet(LmtDump, false);

  EXPECT_EQ("OK", out) << "this test should be OK";

  //
  // With the data obtained, render, present and release methods are exercised
  //
  QueryContextRequest*  qcrP = &reqData.qcr.res;
  const char*  outfile = "ngsi10.queryContextRequest.ok2.valid.xml";
  
  qcrP->present(""); // No output

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  out = qcrP->render(QueryContext, XML, "");
  EXPECT_STREQ(expectedBuf, out.c_str());

  qcrP->release();

  utExit();
}
/* ****************************************************************************
*
* badSubscriptionId_json - 
*/
TEST(UnsubscribeContextAvailabilityRequest, badSubscriptionId_json)
{
  ParseData       reqData;
  ConnectionInfo  ci("", "POST", "1.1");
  const char*     infile  = "ngsi9.unsubscribeContextAvailabilityRequest.badSubscriptionId.invalid.json";
  const char*     outfile = "ngsi9.unsubscribeContextAvailabilityResponse.badSubscriptionId.valid.json";

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  
  ci.inFormat  = JSON;
  ci.outFormat = JSON;
  lmTraceLevelSet(LmtDump, true);
  std::string out = jsonTreat(testBuf, &ci, &reqData, UnsubscribeContextAvailability, "unsubscribeContextAvailabilityRequest", NULL);
  EXPECT_STREQ(expectedBuf, out.c_str());

  lmTraceLevelSet(LmtDump, false);

  UnsubscribeContextAvailabilityRequest*  ucarP = &reqData.ucar.res;

  ucarP->release();

  utExit();
}
/* ****************************************************************************
*
* render
*/
TEST(SubscriptionId, render)
{
  SubscriptionId  sId;
  std::string     out;
  const char*     outfile1 = "ngsi.subscriptionId.render1.middle.xml";
  const char*     outfile2 = "ngsi.subscriptionId.render2.middle.xml";
  const char*     outfile3 = "ngsi.subscriptionId.render2.middle.json";

  utInit();

  sId.set("");
  out = sId.render(UnsubscribeContext, XML, ""); // subscriptionId is MANDATORY for RegisterContext 
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  sId.set("012345012345012345012345");
  out = sId.render(UnsubscribeContext, XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());
  
  out = sId.render(UnsubscribeContext, JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  sId.release(); // just to exercise the code

  utExit();
}
/* ****************************************************************************
*
* ok_json - 
*/
TEST(SubscribeContextRequest, ok_json)
{
  ParseData       parseData;
  ConnectionInfo  ci("", "POST", "1.1");
  const char*     infile = "ngsi10.subscribeContextRequest.ok.valid.json";

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";

  ci.inFormat  = JSON;
  ci.outFormat = JSON;

  lmTraceLevelSet(LmtDump, true);
  std::string result = jsonTreat(testBuf, &ci, &parseData, SubscribeContext, "subscribeContextRequest", NULL);
  EXPECT_EQ("OK", result);
  lmTraceLevelSet(LmtDump, false);


  //
  // With the data obtained, render, present and release methods are exercised
  //
  SubscribeContextRequest*  scrP    = &parseData.scr.res;
  const char*               outfile = "ngsi10.subscribeContextRequest_ok.expected.valid.json";
  
  scrP->present(""); // No output

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  std::string out = scrP->render(SubscribeContext, JSON, "");
  EXPECT_STREQ(expectedBuf, out.c_str());

  scrP->release();

  utExit();
}
/* ****************************************************************************
*
* render -
*/
TEST(ContextRegistrationResponse, render)
{
    ContextRegistrationResponse  crr;
    std::string                  rendered;
    const char*                  outfile1 = "ngsi.contextRegistrationResponse.renderOk.middle.xml";
    const char*                  outfile2 = "ngsi.contextRegistrationResponse.renderOk.middle.json";
    const char*                  outfile3 = "ngsi.contextRegistrationResponse.renderError.middle.xml";
    const char*                  outfile4 = "ngsi.contextRegistrationResponse.renderError.middle.json";

    utInit();

    crr.errorCode.fill(SccNone);
    rendered = crr.render(XML, "");
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
    EXPECT_STREQ(expectedBuf, rendered.c_str());
    rendered = crr.render(JSON, "");
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
    EXPECT_STREQ(expectedBuf, rendered.c_str());

    crr.errorCode.fill(SccBadRequest);
    rendered = crr.render(XML, "");
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
    EXPECT_STREQ(expectedBuf, rendered.c_str());
    rendered = crr.render(JSON, "");
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile4)) << "Error getting test data from '" << outfile4 << "'";
    EXPECT_STREQ(expectedBuf, rendered.c_str());

    utExit();
}
/* ****************************************************************************
*
* ok - 
*
* FIXME P5 #1862: _json counterpart?
*/
TEST(postContextEntityTypeAttribute, DISABLED_ok)
{
  utInit();

  // Avoid forwarding of messages
  extern int fwdPort;
  int saved = fwdPort;
  fwdPort = 0;

  ConnectionInfo ci("/ngsi9/contextEntityTypes/TYPE_123/attributes/temperature",  "POST", "1.1");
  const char*    infile     = "ngsi9.registerProviderRequest.noRegistrationId.postponed.xml";
  const char*    outfile    = "ngsi9.registerContextResponse.noRegistrationId.middle.xml";
  std::string    out;

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";

  ci.outFormat    = JSON;
  ci.inFormat     = JSON;
  ci.payload      = testBuf;
  ci.payloadSize  = strlen(testBuf);
  out             = restService(&ci, rs);

  char* outStart  = (char*) out.c_str();

  // Remove last char in expectedBuf
  expectedBuf[strlen(expectedBuf) - 1] = 0;

  // Shorten 'out' to be of same length as expectedBuf
  outStart[strlen(expectedBuf)]    = 0;
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
  fwdPort = saved;
}
/* ****************************************************************************
*
* render_json - 
*/
TEST(AppendContextElementResponse, render_json)
{
  AppendContextElementResponse  acer;
  ContextAttributeResponse      car;
  std::string                   out;
  const char*                   outfile1 = "ngsi10.appendContextElementResponse.empty.valid.json";
  const char*                   outfile2 = "ngsi10.appendContextElementResponse.badRequest.valid.json";
  ConnectionInfo                ci;

  utInit();

  // 1. empty acer
  ci.outMimeType = JSON;
  out = acer.render(&ci, AppendContextElement, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  // 2. errorCode 'active'
  acer.errorCode.fill(SccBadRequest, "very bad request");
  out = acer.render(&ci, AppendContextElement, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}   
/* ****************************************************************************
*
* check_json - 
*/
TEST(AppendContextElementResponse, check_json)
{
  AppendContextElementResponse  acer;
  ContextAttributeResponse      car;
  ContextAttribute              ca("", "TYPE", "VALUE"); // empty name, thus provoking error
  std::string                   out;
  const char*                   outfile1 = "ngsi10.appendContextElementRequest.check1.postponed.json";
  const char*                   outfile2 = "ngsi10.appendContextElementRequest.check2.postponed.json";
  ConnectionInfo                ci;

  utInit();

  // 1. predetected error
  ci.outMimeType = JSON;
  out = acer.check(&ci, IndividualContextEntity, "", "PRE ERR", 0);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  // 2. bad contextAttributeResponseVector
  car.contextAttributeVector.push_back(&ca);
  acer.contextAttributeResponseVector.push_back(&car);
  out = acer.check(&ci, IndividualContextEntity, "", "", 0);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  // 3. OK
  ca.name = "NAME";
  out = acer.check(&ci, IndividualContextEntity, "", "", 0);
  EXPECT_EQ("OK", out);

  utExit();
}  
/* ****************************************************************************
*
* shortPath - 
*/
TEST(Convenience, shortPath)
{
  ConnectionInfo  ci1("ngsi9", "GET", "1.1");
  ConnectionInfo  ci2("ngsi10", "GET", "1.1");
  ConnectionInfo  ci3("ngsi8", "GET", "1.1");
  ConnectionInfo  ci4("ngsi10/nada", "GET", "1.1");
  std::string     out;
  const char*     outfile1 = "ngsi.convenience.shortPath.postponed.xml";
  const char*     outfile2 = "ngsi.convenience.shortPath2.postponed.xml";
  const char*     outfile3 = "ngsi.convenience.shortPath3.postponed.xml";
  const char*     outfile4 = "ngsi.convenience.shortPath4.postponed.xml";

  utInit();

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  out = restService(&ci1, restServiceV);
  EXPECT_STREQ(expectedBuf, out.c_str());

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  out = restService(&ci2, restServiceV);
  EXPECT_STREQ(expectedBuf, out.c_str());

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  out = restService(&ci3, restServiceV);
  EXPECT_STREQ(expectedBuf, out.c_str());

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile4)) << "Error getting test data from '" << outfile4 << "'";
  out = restService(&ci4, restServiceV);
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* ok - 
*
* FIXME P5 #1862: _json countepart?
*/
TEST(postSubscribeContextAvailability, DISABLED_ok)
{
  ConnectionInfo ci("/ngsi9/subscribeContextAvailability",  "POST", "1.1");
  const char*    infile   = "ngsi9.subscribeContextAvailabilityRequest.ok2.valid.xml";
  const char*    outfile  = "ngsi9.subscribeContextAvailabilityResponse.ok2.middle.xml";
  std::string    out;

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";

  ci.outFormat    = JSON;
  ci.inFormat     = JSON;
  ci.payload      = testBuf;
  ci.payloadSize  = strlen(testBuf);
  out             = restService(&ci, rs);

  char* outStart  = (char*) out.c_str();

  // Remove last char in expectedBuf
  expectedBuf[strlen(expectedBuf) - 1] = 0;

  // Shorten'out' to be of same length as expectedBuf
  outStart[strlen(expectedBuf)]    = 0;
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* found - 
*/
TEST(getAttributeValueInstance, found)
{
  ConnectionInfo ci1("/ngsi10/contextEntities/E1/attributes",          "POST", "1.1");
  ConnectionInfo ci2("/ngsi10/contextEntities/E1/attributes/A1/left",  "GET", "1.1");
  const char*    outfile1  = "ngsi10.appendContextElementResponse.ok1.valid.xml";
  const char*    outfile2  = "ngsi10.appendContextElementResponse.ok2.valid.xml";
  const char*    infile    = "ngsi10.IndividualContextEntityAttributes.A1-left.postponed.xml";
  std::string    out;

  utInit();

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";

  ci1.outFormat    = XML;
  ci1.inFormat     = XML;
  ci1.payload      = testBuf;
  ci1.payloadSize  = strlen(testBuf);
  out              = restService(&ci1, rs);
  EXPECT_STREQ(expectedBuf, out.c_str());

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  ci2.outFormat    = XML;
  out              = restService(&ci2, rs);
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* render - 
*/
TEST(StatusCode, render)
{
  StatusCode    sc1;
  StatusCode    sc2(SccOk, "");
  StatusCode    sc3(SccOk, "DETAILS");
  StatusCode    sc4(SccOk, "DETAILS");
  std::string   out;
  const char*   outfile1  = "ngsi.statusCode.render1.valid.xml";
  const char*   outfile2  = "ngsi.statusCode.render2.valid.xml";
  const char*   outfile3  = "ngsi.statusCode.render3.valid.xml";
  const char*   outfile4  = "ngsi.statusCode.render4.middle.json";

  utInit();

  out = sc1.render(XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = sc2.render(XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = sc3.render(XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = sc4.render(JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile4)) << "Error getting test data from '" << outfile4 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  sc1.release(); // just to exercise the code ...

  utExit();
}
/* ****************************************************************************
*
* render - 
*/
TEST(SubscribeError, render)
{
  SubscribeError  se;
  std::string     out;
  const char*     outfile1 = "ngsi.subscribeError.render1.middle.xml";
  const char*     outfile2 = "ngsi.subscribeError.render1.middle.json";
  const char*     outfile3 = "ngsi.subscribeError.render2.middle.xml";
  const char*     outfile4 = "ngsi.subscribeError.render2.middle.json";

  utInit();

  se.subscriptionId.set("SUB_123");
  se.errorCode.fill(SccBadRequest, "detail");

  out = se.render(RegisterContext, XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = se.render(RegisterContext, JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());


  out = se.render(SubscribeContext, XML, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = se.render(SubscribeContext, JSON, "");
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile4)) << "Error getting test data from '" << outfile4 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* Check - 
*/
TEST(ContextElement, Check)
{
  ContextElement ce;

  utInit();

  ce.entityId.id = "";
  EXPECT_EQ(ce.check(UpdateContext, XML, "", "", 0), "empty entityId:id");

  ce.entityId.id = "id";
  EXPECT_EQ(ce.check(UpdateContext, XML, "", "", 0), "OK");

  ContextAttribute a;
  a.name  = "";
  a.value = "V";
  ce.contextAttributeVector.push_back(&a);
  EXPECT_EQ(ce.check(UpdateContext, XML, "", "", 0), "missing attribute name");
  a.name = "name";
  
  Metadata m;
  m.name  = "";
  m.value = "V";
  ce.domainMetadataVector.push_back(&m);
  EXPECT_EQ(ce.check(UpdateContext, XML, "", "", 0), "missing metadata name");
  m.name = "NAME";
  EXPECT_EQ(ce.check(UpdateContext, XML, "", "", 0), "OK");

  ContextElement ce2;
  ce2.entityId.id = "id";

  ContextElementVector ceVector;

  EXPECT_EQ(ceVector.check(UpdateContext, XML, "", "", 0), "No context elements");

  ceVector.push_back(&ce);
  ceVector.push_back(&ce2);
  EXPECT_EQ(ceVector.check(UpdateContext, XML, "", "", 0), "OK");

  // render
  const char*  outfile1 = "ngsi.contextelement.check.middle.xml";
  const char*  outfile2 = "ngsi.contextelement.check.middle.json";
  std::string  out;

  out = ce2.render(UpdateContextElement, XML, "", false);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  out = ce2.render(UpdateContextElement, JSON, "", false);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  // present
  ce2.present("", -1);
  ce2.present("", 1);

  m.name  = "";
  EXPECT_EQ("missing metadata name", ceVector.check(UpdateContext, XML, "", "", 0));

  utExit();
}
/* ****************************************************************************
*
* json_ok -
*/
TEST(NotifyContextRequest, json_ok)
{
  ParseData              reqData;
  ConnectionInfo         ci("", "POST", "1.1");
  NotifyContextRequest*  ncrP      = &reqData.ncr.res;
  const char*            infile    = "notifyContextRequest_ok.json";
  const char*            outfile   = "ngsi10.notifyContextRequest_ok.expected1.valid.json";
  std::string            rendered;

  utInit();

  ci.outMimeType = JSON;

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";

  ci.inMimeType  = JSON;
  ci.outMimeType = JSON;

  lmTraceLevelSet(LmtDump, true);
  std::string result = jsonTreat(testBuf, &ci, &reqData, NotifyContext, NULL);
  EXPECT_EQ("OK", result);
  lmTraceLevelSet(LmtDump, false);

  //
  // With the data obtained, render, present and release methods are exercised
  //
  std::vector<std::string> emptyV;
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile)) << "Error getting test data from '" << outfile << "'";
  rendered = ncrP->toJsonV1(false, emptyV, false, emptyV);
  EXPECT_STREQ(expectedBuf, rendered.c_str());

  ncrP->release();

  utExit();
}
/* ****************************************************************************
*
* check_json -
*/
TEST(ContextAttributeResponseVector, check_json)
{
    ContextAttributeResponseVector  carV;
    ContextAttribute                ca("caName", "caType", "caValue");
    ContextAttributeResponse        car;
    std::string                     out;
    const char*                     outfile1 = "ngsi10.contextAttributeResponse.check1.valid.json";
    const char*                     outfile2 = "ngsi10.contextAttributeResponse.check2.valid.json";
    ConnectionInfo                  ci(JSON);

    // 1. ok
    car.contextAttributeVector.push_back(&ca);
    carV.push_back(&car);
    out = carV.check(&ci, UpdateContextAttribute, "", "", 0);
    EXPECT_STREQ("OK", out.c_str());

    // 2. Predetected Error
    out = carV.check(&ci, UpdateContextAttribute, "", "PRE ERROR", 0);
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
    EXPECT_STREQ(expectedBuf, out.c_str());


    // 3. Bad ContextAttribute
    ContextAttribute  ca2("", "caType", "caValue");

    car.contextAttributeVector.push_back(&ca2);
    out = carV.check(&ci, UpdateContextAttribute, "", "", 0);
    EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
    EXPECT_STREQ(expectedBuf, out.c_str());
}
/* ****************************************************************************
*
* put - 
*/
TEST(logTraceTreat, put)
{
  ConnectionInfo  ci1("/log/traceLevel/0-19,21-200",  "PUT", "1.1");
  ConnectionInfo  ci2("/log/traceLevel/aaa",  "PUT", "1.1");
  ConnectionInfo  ci3("/log/traceLevel",  "GET", "1.1");
  const char*     outfile1 = "orion.logTrace.spanOfLevels.valid.xml";
  const char*     outfile2 = "orion.logTrace.invalidLevels.valid.xml";
  const char*     outfile3 = "orion.logTrace.get.valid.xml";
  std::string     out;

  utInit();

  ci1.outFormat = XML;
  out          = restService(&ci1, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  ci2.outFormat = XML;
  out          = restService(&ci2, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  ci3.outFormat = XML;
  out          = restService(&ci3, rs);
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  EXPECT_STREQ(expectedBuf, out.c_str());

  utExit();
}
/* ****************************************************************************
*
* ok_xml - 
*/
TEST(NotifyContextAvailabilityRequest, ok_xml)
{
  ParseData       parseData;
  const char*     inFile  = "ngsi9.notifyContextAvailabilityRequest.ok.valid.xml";
  const char*     outFile = "ngsi9.notifyContextAvailabilityRequestRendered.ok.valid.xml";
  ConnectionInfo  ci("", "POST", "1.1");
  std::string     rendered;

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), inFile)) << "Error getting test data from '" << inFile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outFile)) << "Error getting test data from '" << outFile << "'";

  lmTraceLevelSet(LmtDump, true);
  std::string result = xmlTreat(testBuf, &ci, &parseData, NotifyContextAvailability, "notifyContextAvailabilityRequest", NULL);
  EXPECT_EQ("OK", result);
  lmTraceLevelSet(LmtDump, false);

  NotifyContextAvailabilityRequest* ncarP = &parseData.ncar.res;

  rendered = ncarP->render(NotifyContext, XML, "");
  EXPECT_STREQ(expectedBuf, rendered.c_str());

  ncarP->release();
  
  utExit();
}
/* ****************************************************************************
*
* json_render - 
*/
TEST(NotifyContextAvailabilityRequest, json_render)
{
  const char*                          filename1  = "ngsi10.notifyContextAvailabilityRequest.jsonRender1.valid.json";
  const char*                          filename2  = "ngsi10.notifyContextAvailabilityRequest.jsonRender2.valid.json";
  NotifyContextAvailabilityRequest*    ncarP;
  std::string                          rendered;
  ContextRegistrationResponse*         crrP;
  EntityId*                            eidP  = new EntityId("E01", "EType", "false");

  utInit();

  //
  // Both subscriptionId and contextRegistrationResponseVector are MANDATORY.
  // Just two tests here:
  //  1. contextRegistrationResponseVector with ONE contextRegistrationResponse instance
  //  2. contextRegistrationResponseVector with TWO contextRegistrationResponse instances
  //



  // Preparation
  ncarP = new NotifyContextAvailabilityRequest();
  ncarP->subscriptionId.set("012345678901234567890123");

  crrP = new ContextRegistrationResponse();
  ncarP->contextRegistrationResponseVector.push_back(crrP);
  crrP->contextRegistration.entityIdVector.push_back(eidP);
  crrP->contextRegistration.providingApplication.set("http://www.tid.es/NotifyContextAvailabilityRequestTest");

  // Test 1. contextRegistrationResponseVector with ONE contextRegistrationResponse instance
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), filename1)) << "Error getting test data from '" << filename1 << "'";
  rendered = ncarP->render(QueryContext, JSON, "");
  EXPECT_STREQ(expectedBuf, rendered.c_str());
  

  
  // Test 2. contextRegistrationResponseVector with TWO contextRegistrationResponse instances
  Metadata*                     mdP   = new Metadata("M01", "MType", "123");
  ContextRegistrationAttribute* craP  = new ContextRegistrationAttribute("CRA1", "CType", "false");

  eidP->fill("E02", "EType", "false");
  crrP = new ContextRegistrationResponse();
  ncarP->contextRegistrationResponseVector.push_back(crrP);

  crrP->contextRegistration.entityIdVector.push_back(eidP);
  crrP->contextRegistration.entityIdVectorPresent = true;
  crrP->contextRegistration.contextRegistrationAttributeVector.push_back(craP);
  crrP->contextRegistration.registrationMetadataVector.push_back(mdP);

  crrP->contextRegistration.providingApplication.set("http://www.tid.es/NotifyContextAvailabilityRequestTest2");
  
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), filename2)) << "Error getting test data from '" << filename2 << "'";
  rendered = ncarP->render(QueryContext, JSON, "");
  EXPECT_STREQ(expectedBuf, rendered.c_str());
  
  utExit();
}
/* ****************************************************************************
*
* put - 
*/
TEST(putSubscriptionConvOp, put)
{
  ConnectionInfo ci1("/ngsi10/contextSubscriptions/012345678901234567890123",  "DELETE", "1.1");
  ConnectionInfo ci2("/ngsi10/contextSubscriptions/111222333444555666777888",  "PUT",    "1.1");
  ConnectionInfo ci3("/ngsi10/contextSubscriptions/111222333444555666777881",  "PUT",    "1.1");
  ConnectionInfo ci4("/ngsi10/contextSubscriptions/012345678901234567890123",  "XVERB",  "1.1");
  const char*    infile       = "ngsi10.updateContextSubscriptionRequest.subscriptionNotFound.valid.xml";
  const char*    outfile1     = "ngsi10.unsubscribeContextResponse.putSubscriptionConvOp.notFound.valid.xml";
  const char*    outfile2     = "ngsi10.updateContextSubscriptionResponse.putSubscriptionConvOp.notFound.valid.xml";
  const char*    outfile3     = "ngsi10.updateContextSubscriptionResponse.putSubscriptionConvOp.unmatchingSubscriptionId.valid.xml";
  std::string    out;

  utInit();

  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
  ci1.outFormat    = XML;
  ci1.inFormat     = XML;
  ci1.payload      = NULL;
  ci1.payloadSize  = 0;
  out              = restService(&ci1, rs);
  EXPECT_STREQ(expectedBuf, out.c_str());
  

  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";
  ci2.outFormat    = XML;
  ci2.inFormat     = XML;
  ci2.payload      = testBuf;
  ci2.payloadSize  = strlen(testBuf);
  out              = restService(&ci2, rs);
  EXPECT_STREQ(expectedBuf, out.c_str());


  EXPECT_EQ("OK", testDataFromFile(testBuf, sizeof(testBuf), infile)) << "Error getting test data from '" << infile << "'";
  EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";
  ci3.outFormat    = XML;
  ci3.inFormat     = XML;
  ci3.payload      = testBuf;
  ci3.payloadSize  = strlen(testBuf);
  out              = restService(&ci3, rs);
  EXPECT_STREQ(expectedBuf, out.c_str());


  ci4.outFormat    = XML;
  ci4.inFormat     = XML;
  ci4.payload      = NULL;
  ci4.payloadSize  = 0;
  out              = restService(&ci4, rs);
  EXPECT_EQ("", out);
  EXPECT_EQ("Allow",       ci4.httpHeader[0]);
  EXPECT_EQ("PUT, DELETE", ci4.httpHeaderValue[0]);

  utExit();
}
/* ****************************************************************************
*
* check_json - 
*/
TEST(AppendContextElementRequest, check_json)
{
   AppendContextElementRequest  acer;
   std::string                  out;
   ContextAttribute             ca("caName", "caType", "121");
   Metadata                     md("mdName", "mdType", "122");
   const char*                  outfile1 = "ngsi10.appendContextElementResponse.predetectedError.valid.json";
   const char*                  outfile2 = "ngsi10.appendContextElementResponse.missingAttributeName.valid.json";
   const char*                  outfile3 = "ngsi10.appendContextElementResponse.missingMetadataName.valid.json";
   ConnectionInfo               ci;

   utInit();

   acer.attributeDomainName.set("ADN");
   acer.contextAttributeVector.push_back(&ca);
   acer.domainMetadataVector.push_back(&md);

   // 1. ok
   ci.outMimeType = JSON;
   out = acer.check(&ci, AppendContextElement, "", "", 0);
   EXPECT_STREQ("OK", out.c_str());


   // 2. Predetected error 
   EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile1)) << "Error getting test data from '" << outfile1 << "'";
   out = acer.check(&ci, AppendContextElement, "", "Error is predetected", 0);
   EXPECT_STREQ(expectedBuf, out.c_str());
   

   // 3. bad ContextAttribute
   ContextAttribute  ca2("", "caType", "121");

   acer.contextAttributeVector.push_back(&ca2);
   out = acer.check(&ci, AppendContextElement, "", "", 0);
   EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile2)) << "Error getting test data from '" << outfile2 << "'";   
   EXPECT_STREQ(expectedBuf, out.c_str());
   ca2.name = "ca2Name";


   // 4. Bad domainMetadata
   Metadata  md2("", "mdType", "122");

   acer.domainMetadataVector.push_back(&md2);
   out = acer.check(&ci, AppendContextElement, "", "", 0);
   EXPECT_EQ("OK", testDataFromFile(expectedBuf, sizeof(expectedBuf), outfile3)) << "Error getting test data from '" << outfile3 << "'";   
   EXPECT_STREQ(expectedBuf, out.c_str());


   // 5. Bad attributeDomainName
   // FIXME P3: AttributeDomainName::check always returns "OK"

   utExit();
}