/*
 * Copyright (C) 2014-2021 CZ.NIC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#if defined(__APPLE__) || defined(__clang__)
#  define __USE_C99_MATH
#  define _Bool bool
#else /* !__APPLE__ */
#  include <cstdbool>
#endif /* __APPLE__ */

#include <libdatovka/isds.h>
#include <QDate>
#include <QString>
#include <QtTest/QtTest>

#include "src/datovka_shared/isds/box_interface.h"
#include "src/datovka_shared/log/log.h"
#include "src/isds/box_conversion.h"
#include "src/isds/initialisation.h"
#include "tests/test_isds_box_interface.h"

class TestIsdsBoxInterface : public QObject {
	Q_OBJECT

public:
	TestIsdsBoxInterface(void);

private slots:
	void initTestCase(void);

	void cleanupTestCase(void);

	void address(void);

	void addressCompare(void);

	void addressCopy(void);

	void addressConversion(void);

	void birthInfo(void);

	void birthInfoCompare(void);

	void birthInfoCopy(void);

	void birthInfoConversion(void);

	void personName(void);

	void personNameCompare(void);

	void personNameCopy(void);

	void personNameConversion(void);

	void dbOwnerInfo(void);

	void dbOwnerInfoCompare(void);

	void dbOwnerInfoCopy(void);

	void dbOwnerInfoConversion(void);

	void dbUserInfo(void);

	void dbUserInfoCompare(void);

	void dbUserInfoCopy(void);

	void dbUserInfoConversion(void);

	void credentialsDelivery(void);

	void credentialsDeliveryCompare(void);

	void credentialsDeliveryCopy(void);

	void credentialsDeliveryConversion(void);
};

TestIsdsBoxInterface::TestIsdsBoxInterface(void)
{
}

void TestIsdsBoxInterface::initTestCase(void)
{
	QVERIFY(GlobInstcs::logPtr == Q_NULLPTR);
}

void TestIsdsBoxInterface::cleanupTestCase(void)
{
}

void TestIsdsBoxInterface::address(void)
{
	Isds::Address addr1, addr2;
	const QString city("adCity");
	const QString street("adStreet");
	const QString numberInStreet("adNumberInStreet");
	const QString numberInMunicipality("adNumberInMunicipality");
	const QString zipCode("adZipCode");
	const QString state("adState");

	/* Must be null. */
	QVERIFY(addr1.city().isNull());
	QVERIFY(addr1.street().isNull());
	QVERIFY(addr1.numberInStreet().isNull());
	QVERIFY(addr1.numberInMunicipality().isNull());
	QVERIFY(addr1.zipCode().isNull());
	QVERIFY(addr1.state().isNull());
	QVERIFY(addr2.city().isNull());
	QVERIFY(addr2.street().isNull());
	QVERIFY(addr2.numberInStreet().isNull());
	QVERIFY(addr2.numberInMunicipality().isNull());
	QVERIFY(addr2.zipCode().isNull());
	QVERIFY(addr2.state().isNull());

	QVERIFY(addr1.isNull());
	QVERIFY(addr2.isNull());
	QVERIFY(addr1 == addr2);

	/* Check whether values are not cross-linked. */
	addr1.setCity(city);
	addr1.setStreet(street);
	addr1.setNumberInStreet(numberInStreet);
	addr1.setNumberInMunicipality(numberInMunicipality);
	addr1.setZipCode(zipCode);
	addr1.setState(state);

	QVERIFY(addr1.city() == city);
	QVERIFY(addr1.street() == street);
	QVERIFY(addr1.numberInStreet() == numberInStreet);
	QVERIFY(addr1.numberInMunicipality() == numberInMunicipality);
	QVERIFY(addr1.zipCode() == zipCode);
	QVERIFY(addr1.state() == state);

	QVERIFY(!addr1.isNull());
	QVERIFY(addr2.isNull());
	QVERIFY(addr1 != addr2);

	/* Check value copying. */
	addr2 = addr1;

	QVERIFY(addr2.city() == city);
	QVERIFY(addr2.street() == street);
	QVERIFY(addr2.numberInStreet() == numberInStreet);
	QVERIFY(addr2.numberInMunicipality() == numberInMunicipality);
	QVERIFY(addr2.zipCode() == zipCode);
	QVERIFY(addr2.state() == state);

	QVERIFY(!addr1.isNull());
	QVERIFY(!addr2.isNull());
	QVERIFY(addr1 == addr2);

	/* Clear value. */
	addr1 = Isds::Address();

	QVERIFY(addr1.city().isNull());
	QVERIFY(addr1.street().isNull());
	QVERIFY(addr1.numberInStreet().isNull());
	QVERIFY(addr1.numberInMunicipality().isNull());
	QVERIFY(addr1.zipCode().isNull());
	QVERIFY(addr1.state().isNull());
	QVERIFY(addr2.city() == city);
	QVERIFY(addr2.street() == street);
	QVERIFY(addr2.numberInStreet() == numberInStreet);
	QVERIFY(addr2.numberInMunicipality() == numberInMunicipality);
	QVERIFY(addr2.zipCode() == zipCode);
	QVERIFY(addr2.state() == state);

	QVERIFY(addr1.isNull());
	QVERIFY(!addr2.isNull());
	QVERIFY(addr1 != addr2);
}

void TestIsdsBoxInterface::addressCompare(void)
{
	Isds::Address addr1, addr2;
	const QString city("adCity");
	const QString street("adStreet");
	const QString numberInStreet("adNumberInStreet");
	const QString numberInMunicipality("adNumberInMunicipality");
	const QString zipCode("adZipCode");
	const QString state("adState");

	addr1.setCity(city);
	addr1.setStreet(street);
	addr1.setNumberInStreet(numberInStreet);
	addr1.setNumberInMunicipality(numberInMunicipality);
	addr1.setZipCode(zipCode);
	addr1.setState(state);
	addr2.setCity(city);
	addr2.setStreet(street);
	addr2.setNumberInStreet(numberInStreet);
	addr2.setNumberInMunicipality(numberInMunicipality);
	addr2.setZipCode(zipCode);
	addr2.setState(state);

	QVERIFY(addr1 == addr2);

	addr2.setCity("");
	QVERIFY(addr1 != addr2);
	addr2.setCity(city);
	QVERIFY(addr1 == addr2);

	addr2.setStreet("");
	QVERIFY(addr1 != addr2);
	addr2.setStreet(street);
	QVERIFY(addr1 == addr2);

	addr2.setNumberInStreet("");
	QVERIFY(addr1 != addr2);
	addr2.setNumberInStreet(numberInStreet);
	QVERIFY(addr1 == addr2);

	addr2.setNumberInMunicipality("");
	QVERIFY(addr1 != addr2);
	addr2.setNumberInMunicipality(numberInMunicipality);
	QVERIFY(addr1 == addr2);

	addr2.setZipCode("");
	QVERIFY(addr1 != addr2);
	addr2.setZipCode(zipCode);
	QVERIFY(addr1 == addr2);

	addr2.setState("");
	QVERIFY(addr1 != addr2);
	addr2.setState(state);
	QVERIFY(addr1 == addr2);
}

void TestIsdsBoxInterface::addressCopy(void)
{
	Isds::Address addr1;
	const QString city("adCity");
	const QString street("adStreet");
	const QString numberInStreet("adNumberInStreet");
	const QString numberInMunicipality("adNumberInMunicipality");
	const QString zipCode("adZipCode");
	const QString state("adState");

	addr1.setCity(city);
	addr1.setStreet(street);
	addr1.setNumberInStreet(numberInStreet);
	addr1.setNumberInMunicipality(numberInMunicipality);
	addr1.setZipCode(zipCode);
	addr1.setState(state);

	/* Constructor. */
	{
		Isds::Address addr2(addr1);

		QVERIFY(!addr1.isNull());
		QVERIFY(!addr2.isNull());
		QVERIFY(addr1 == addr2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::Address addr3(::std::move(addr2));

		QVERIFY(addr2.isNull());
		QVERIFY(addr1 != addr2);

		QVERIFY(!addr1.isNull());
		QVERIFY(!addr3.isNull());
		QVERIFY(addr1 == addr3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::Address addr2;

		QVERIFY(addr2.isNull());

		addr2 = addr1;

		QVERIFY(!addr1.isNull());
		QVERIFY(!addr2.isNull());
		QVERIFY(addr1 == addr2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::Address addr3;

		QVERIFY(addr3.isNull());

		addr3 = ::std::move(addr2);

		QVERIFY(addr2.isNull());
		QVERIFY(addr1 != addr2);

		QVERIFY(!addr1.isNull());
		QVERIFY(!addr3.isNull());
		QVERIFY(addr1 == addr3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::addressConversion(void)
{
	Isds::Address addr1, addr2;
	const QString city("adCity");
	const QString street("adStreet");
	const QString numberInStreet("adNumberInStreet");
	const QString numberInMunicipality("adNumberInMunicipality");
	const QString zipCode("adZipCode");
	const QString state("adState");

	bool iOk = false;
	struct isds_Address *iaddr = NULL;

	QVERIFY(addr1.isNull());
	QVERIFY(addr2.isNull());
	QVERIFY(addr1 == addr2);

	addr1.setCity(city);
	addr1.setStreet(street);
	addr1.setNumberInStreet(numberInStreet);
	addr1.setNumberInMunicipality(numberInMunicipality);
	addr1.setZipCode(zipCode);
	addr1.setState(state);

	QVERIFY(!addr1.isNull());
	QVERIFY(addr2.isNull());
	QVERIFY(addr1 != addr2);

	/* NULL pointer converts onto null object. */
	iOk = false;
	addr2 = Isds::libisds2address(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(addr2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	iaddr = Isds::address2libisds(addr2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(iaddr == NULL);

	iOk = false;
	iaddr = Isds::address2libisds(addr1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(iaddr != NULL);

	iOk = false;
	addr2 = Isds::libisds2address(iaddr, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!addr2.isNull());

	QVERIFY(addr2.city() == city);
	QVERIFY(addr2.street() == street);
	QVERIFY(addr2.numberInStreet() == numberInStreet);
	QVERIFY(addr2.numberInMunicipality() == numberInMunicipality);
	QVERIFY(addr2.zipCode() == zipCode);
	QVERIFY(addr2.state() == state);

	QVERIFY(!addr1.isNull());
	QVERIFY(!addr2.isNull());
	QVERIFY(addr1 == addr2);

	isds_Address_free(&iaddr);
	QVERIFY(iaddr == NULL);
}

void TestIsdsBoxInterface::birthInfo(void)
{
	Isds::BirthInfo bi1, bi2;
	const QDate date(2001, 2, 3);
	const QString city("biCity");
	const QString county("biCounty");
	const QString state("biState");

	/* Must be null. */
	QVERIFY(bi1.date().isNull());
	QVERIFY(bi1.city().isNull());
	QVERIFY(bi1.county().isNull());
	QVERIFY(bi1.state().isNull());
	QVERIFY(bi2.date().isNull());
	QVERIFY(bi2.city().isNull());
	QVERIFY(bi2.county().isNull());
	QVERIFY(bi2.state().isNull());

	QVERIFY(bi1.isNull());
	QVERIFY(bi2.isNull());
	QVERIFY(bi1 == bi2);

	/* Check whether values are not cross-linked. */
	bi1.setDate(date);
	bi1.setCity(city);
	bi1.setCounty(county);
	bi1.setState(state);

	QVERIFY(bi1.date() == date);
	QVERIFY(bi1.city() == city);
	QVERIFY(bi1.county() == county);
	QVERIFY(bi1.state() == state);

	QVERIFY(!bi1.isNull());
	QVERIFY(bi2.isNull());
	QVERIFY(bi1 != bi2);

	/* Check value copying. */
	bi2 = bi1;

	QVERIFY(bi2.date() == date);
	QVERIFY(bi2.city() == city);
	QVERIFY(bi2.county() == county);
	QVERIFY(bi2.state() == state);

	QVERIFY(!bi1.isNull());
	QVERIFY(!bi2.isNull());
	QVERIFY(bi1 == bi2);

	/* Clear value. */
	bi1 = Isds::BirthInfo();

	QVERIFY(bi1.date().isNull());
	QVERIFY(bi1.city().isNull());
	QVERIFY(bi1.county().isNull());
	QVERIFY(bi1.state().isNull());
	QVERIFY(bi2.date() == date);
	QVERIFY(bi2.city() == city);
	QVERIFY(bi2.county() == county);
	QVERIFY(bi2.state() == state);

	QVERIFY(bi1.isNull());
	QVERIFY(!bi2.isNull());
	QVERIFY(bi1 != bi2);
}

void TestIsdsBoxInterface::birthInfoCompare(void)
{
	Isds::BirthInfo bi1, bi2;
	const QDate date(2001, 2, 3);
	const QString city("biCity");
	const QString county("biCounty");
	const QString state("biState");

	bi1.setDate(date);
	bi1.setCity(city);
	bi1.setCounty(county);
	bi1.setState(state);
	bi2.setDate(date);
	bi2.setCity(city);
	bi2.setCounty(county);
	bi2.setState(state);

	QVERIFY(bi1 == bi2);

	bi2.setDate(QDate(2001, 2, 4));
	QVERIFY(bi1 != bi2);
	bi2.setDate(date);
	QVERIFY(bi1 == bi2);

	bi2.setCity("");
	QVERIFY(bi1 != bi2);
	bi2.setCity(city);
	QVERIFY(bi1 == bi2);

	bi2.setCounty("");
	QVERIFY(bi1 != bi2);
	bi2.setCounty(county);
	QVERIFY(bi1 == bi2);

	bi2.setState("");
	QVERIFY(bi1 != bi2);
	bi2.setState(state);
	QVERIFY(bi1 == bi2);
}

void TestIsdsBoxInterface::birthInfoCopy(void)
{
	Isds::BirthInfo bi1;
	const QDate date(2001, 2, 3);
	const QString city("biCity");
	const QString county("biCounty");
	const QString state("biState");

	bi1.setDate(date);
	bi1.setCity(city);
	bi1.setCounty(county);
	bi1.setState(state);

	/* Constructor. */
	{
		Isds::BirthInfo bi2(bi1);

		QVERIFY(!bi1.isNull());
		QVERIFY(!bi2.isNull());
		QVERIFY(bi1 == bi2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::BirthInfo bi3(::std::move(bi2));

		QVERIFY(bi2.isNull());
		QVERIFY(bi1 != bi2);

		QVERIFY(!bi1.isNull());
		QVERIFY(!bi3.isNull());
		QVERIFY(bi1 == bi3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::BirthInfo bi2;

		QVERIFY(bi2.isNull());

		bi2 = bi1;

		QVERIFY(!bi1.isNull());
		QVERIFY(!bi2.isNull());
		QVERIFY(bi1 == bi2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::BirthInfo bi3;

		QVERIFY(bi3.isNull());

		bi3 = ::std::move(bi2);

		QVERIFY(bi2.isNull());
		QVERIFY(bi1 != bi2);

		QVERIFY(!bi1.isNull());
		QVERIFY(!bi3.isNull());
		QVERIFY(bi1 == bi3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::birthInfoConversion(void)
{
	Isds::BirthInfo bi1, bi2;
	const QDate date(2001, 2, 3);
	const QString city("biCity");
	const QString county("biCounty");
	const QString state("biState");

	bool iOk = false;
	struct isds_BirthInfo *ibi = NULL;

	QVERIFY(bi1.isNull());
	QVERIFY(bi2.isNull());
	QVERIFY(bi1 == bi2);

	bi1.setDate(date);
	bi1.setCity(city);
	bi1.setCounty(county);
	bi1.setState(state);

	/* NULL pointer converts onto null object. */
	iOk = false;
	bi2 = Isds::libisds2birthInfo(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(bi2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	ibi = Isds::birthInfo2libisds(bi2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(ibi == NULL);

	iOk = false;
	ibi = Isds::birthInfo2libisds(bi1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(ibi != NULL);

	iOk = false;
	bi2 = Isds::libisds2birthInfo(ibi, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!bi2.isNull());

	QVERIFY(bi2.date() == date);
	QVERIFY(bi2.city() == city);
	QVERIFY(bi2.county() == county);
	QVERIFY(bi2.state() == state);

	QVERIFY(!bi1.isNull());
	QVERIFY(!bi2.isNull());
	QVERIFY(bi1 == bi2);

	isds_BirthInfo_free(&ibi);
	QVERIFY(ibi == NULL);
}

void TestIsdsBoxInterface::personName(void)
{
	Isds::PersonName pn1, pn2;
	const QString firstName("pnFirstName");
	const QString middleName("pnMiddleName");
	const QString lastName("pnLastName");
	const QString lastNameAtBirth("pnLastNameAtBirth");

	/* Must be null. */
	QVERIFY(pn1.firstName().isNull());
	QVERIFY(pn1.middleName().isNull());
	QVERIFY(pn1.lastName().isNull());
	QVERIFY(pn1.lastNameAtBirth().isNull());
	QVERIFY(pn2.firstName().isNull());
	QVERIFY(pn2.middleName().isNull());
	QVERIFY(pn2.lastName().isNull());
	QVERIFY(pn2.lastNameAtBirth().isNull());

	QVERIFY(pn1.isNull());
	QVERIFY(pn2.isNull());
	QVERIFY(pn1 == pn2);

	/* Check whether values are not cross-linked. */
	pn1.setFirstName(firstName);
	pn1.setMiddleName(middleName);
	pn1.setLastName(lastName);
	pn1.setLastNameAtBirth(lastNameAtBirth);

	QVERIFY(pn1.firstName() == firstName);
	QVERIFY(pn1.middleName() == middleName);
	QVERIFY(pn1.lastName() == lastName);
	QVERIFY(pn1.lastNameAtBirth() == lastNameAtBirth);

	QVERIFY(!pn1.isNull());
	QVERIFY(pn2.isNull());
	QVERIFY(pn1 != pn2);

	/* Check value copying. */
	pn2 = pn1;

	QVERIFY(pn2.firstName() == firstName);
	QVERIFY(pn2.middleName() == middleName);
	QVERIFY(pn2.lastName() == lastName);
	QVERIFY(pn2.lastNameAtBirth() == lastNameAtBirth);

	QVERIFY(!pn1.isNull());
	QVERIFY(!pn2.isNull());
	QVERIFY(pn1 == pn2);

	/* Clear value. */
	pn1 = Isds::PersonName();

	QVERIFY(pn1.firstName().isNull());
	QVERIFY(pn1.middleName().isNull());
	QVERIFY(pn1.lastName().isNull());
	QVERIFY(pn1.lastNameAtBirth().isNull());
	QVERIFY(pn2.firstName() == firstName);
	QVERIFY(pn2.middleName() == middleName);
	QVERIFY(pn2.lastName() == lastName);
	QVERIFY(pn2.lastNameAtBirth() == lastNameAtBirth);

	QVERIFY(pn1.isNull());
	QVERIFY(!pn2.isNull());
	QVERIFY(pn1 != pn2);
}

void TestIsdsBoxInterface::personNameCompare(void)
{
	Isds::PersonName pn1, pn2;
	const QString firstName("pnFirstName");
	const QString middleName("pnMiddleName");
	const QString lastName("pnLastName");
	const QString lastNameAtBirth("pnLastNameAtBirth");

	pn1.setFirstName(firstName);
	pn1.setMiddleName(middleName);
	pn1.setLastName(lastName);
	pn1.setLastNameAtBirth(lastNameAtBirth);
	pn2.setFirstName(firstName);
	pn2.setMiddleName(middleName);
	pn2.setLastName(lastName);
	pn2.setLastNameAtBirth(lastNameAtBirth);

	QVERIFY(pn1 == pn2);

	pn2.setFirstName("");
	QVERIFY(pn1 != pn2);
	pn2.setFirstName(firstName);
	QVERIFY(pn1 == pn2);

	pn2.setMiddleName("");
	QVERIFY(pn1 != pn2);
	pn2.setMiddleName(middleName);
	QVERIFY(pn1 == pn2);

	pn2.setLastName("");
	QVERIFY(pn1 != pn2);
	pn2.setLastName(lastName);
	QVERIFY(pn1 == pn2);

	pn2.setLastNameAtBirth("");
	QVERIFY(pn1 != pn2);
	pn2.setLastNameAtBirth(lastNameAtBirth);
	QVERIFY(pn1 == pn2);
}

void TestIsdsBoxInterface::personNameCopy(void)
{
	Isds::PersonName pn1;
	const QString firstName("pnFirstName");
	const QString middleName("pnMiddleName");
	const QString lastName("pnLastName");
	const QString lastNameAtBirth("pnLastNameAtBirth");

	pn1.setFirstName(firstName);
	pn1.setMiddleName(middleName);
	pn1.setLastName(lastName);
	pn1.setLastNameAtBirth(lastNameAtBirth);

	/* Constructor. */
	{
		Isds::PersonName pn2(pn1);

		QVERIFY(!pn1.isNull());
		QVERIFY(!pn2.isNull());
		QVERIFY(pn1 == pn2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::PersonName pn3(::std::move(pn2));

		QVERIFY(pn2.isNull());
		QVERIFY(pn1 != pn2);

		QVERIFY(!pn1.isNull());
		QVERIFY(!pn3.isNull());
		QVERIFY(pn1 == pn3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::PersonName pn2;

		QVERIFY(pn2.isNull());

		pn2 = pn1;

		QVERIFY(!pn1.isNull());
		QVERIFY(!pn2.isNull());
		QVERIFY(pn1 == pn2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::PersonName pn3;

		QVERIFY(pn3.isNull());

		pn3 = ::std::move(pn2);

		QVERIFY(pn2.isNull());
		QVERIFY(pn1 != pn2);

		QVERIFY(!pn1.isNull());
		QVERIFY(!pn3.isNull());
		QVERIFY(pn1 == pn3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::personNameConversion(void)
{
	Isds::PersonName pn1, pn2;
	const QString firstName("pnFirstName");
	const QString middleName("pnMiddleName");
	const QString lastName("pnLastName");
	const QString lastNameAtBirth("pnLastNameAtBirth");

	bool iOk = false;
	struct isds_PersonName *ipn = NULL;

	QVERIFY(pn1.isNull());
	QVERIFY(pn2.isNull());
	QVERIFY(pn1 == pn2);

	pn1.setFirstName(firstName);
	pn1.setMiddleName(middleName);
	pn1.setLastName(lastName);
	pn1.setLastNameAtBirth(lastNameAtBirth);

	QVERIFY(!pn1.isNull());
	QVERIFY(pn2.isNull());
	QVERIFY(pn1 != pn2);

	/* NULL pointer converts onto null object. */
	iOk = false;
	pn2 = Isds::libisds2personName(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(pn2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	ipn = Isds::personName2libisds(pn2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(ipn == NULL);

	iOk = false;
	ipn = Isds::personName2libisds(pn1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(ipn != NULL);

	iOk = false;
	pn2 = Isds::libisds2personName(ipn, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!pn2.isNull());

	QVERIFY(pn2.firstName() == firstName);
	QVERIFY(pn2.middleName() == middleName);
	QVERIFY(pn2.lastName() == lastName);
	QVERIFY(pn2.lastNameAtBirth() == lastNameAtBirth);

	QVERIFY(!pn1.isNull());
	QVERIFY(!pn2.isNull());
	QVERIFY(pn1 == pn2);

	isds_PersonName_free(&ipn);
	QVERIFY(ipn == NULL);
}

void TestIsdsBoxInterface::dbOwnerInfo(void)
{
	Isds::DbOwnerInfo doi1, doi2;
	const QString dbID("dbID");
	const enum Isds::Type::DbType dbType = Isds::Type::BT_OVM;
	const QString ic("ic");
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	const QString firmName("firmName");
	Isds::BirthInfo birthInfo;
	{
		birthInfo.setDate(QDate(2001, 2, 3));
		birthInfo.setCity("biCity");
		birthInfo.setCounty("biCounty");
		birthInfo.setState("biState");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QString nationality("nationality");
	const QString email("email");
	const QString telNumber("telNumber");
	const QString identifier("identifier");
	const QString registryCode("registryCode");
	const enum Isds::Type::DbState dbState = Isds::Type::BS_ACCESSIBLE;
	const enum Isds::Type::NilBool dbEffectiveOVM = Isds::Type::BOOL_FALSE;
	const enum Isds::Type::NilBool dbOpenAddressing = Isds::Type::BOOL_TRUE;

	/* Must be null. */
	QVERIFY(doi1.dbID().isNull());
	QVERIFY(doi1.dbType() == Isds::Type::BT_NULL);
	QVERIFY(doi1.ic().isNull());
	QVERIFY(doi1.personName().isNull());
	QVERIFY(doi1.firmName().isNull());
	QVERIFY(doi1.birthInfo().isNull());
	QVERIFY(doi1.address().isNull());
	QVERIFY(doi1.nationality().isNull());
	QVERIFY(doi1.email().isNull());
	QVERIFY(doi1.telNumber().isNull());
	QVERIFY(doi1.identifier().isNull());
	QVERIFY(doi1.registryCode().isNull());
	QVERIFY(doi1.dbState() == Isds::Type::BS_ERROR);
	QVERIFY(doi1.dbEffectiveOVM() == Isds::Type::BOOL_NULL);
	QVERIFY(doi1.dbOpenAddressing() == Isds::Type::BOOL_NULL);
	QVERIFY(doi2.dbID().isNull());
	QVERIFY(doi2.dbType() == Isds::Type::BT_NULL);
	QVERIFY(doi2.ic().isNull());
	QVERIFY(doi2.personName().isNull());
	QVERIFY(doi2.firmName().isNull());
	QVERIFY(doi2.birthInfo().isNull());
	QVERIFY(doi2.address().isNull());
	QVERIFY(doi2.nationality().isNull());
	QVERIFY(doi2.email().isNull());
	QVERIFY(doi2.telNumber().isNull());
	QVERIFY(doi2.identifier().isNull());
	QVERIFY(doi2.registryCode().isNull());
	QVERIFY(doi2.dbState() == Isds::Type::BS_ERROR);
	QVERIFY(doi2.dbEffectiveOVM() == Isds::Type::BOOL_NULL);
	QVERIFY(doi2.dbOpenAddressing() == Isds::Type::BOOL_NULL);

	QVERIFY(doi1.isNull());
	QVERIFY(doi2.isNull());
	QVERIFY(doi1 == doi2);

	/* Check whether values are not cross-linked. */
	doi1.setDbID(dbID);
	doi1.setDbType(dbType);
	doi1.setIc(ic);
	doi1.setPersonName(personName);
	doi1.setFirmName(firmName);
	doi1.setBirthInfo(birthInfo);
	doi1.setAddress(address);
	doi1.setNationality(nationality);
	doi1.setEmail(email);
	doi1.setTelNumber(telNumber);
	doi1.setIdentifier(identifier);
	doi1.setRegistryCode(registryCode);
	doi1.setDbState(dbState);
	doi1.setDbEffectiveOVM(dbEffectiveOVM);
	doi1.setDbOpenAddressing(dbOpenAddressing);

	QVERIFY(doi1.dbID() == dbID);
	QVERIFY(doi1.dbType() == dbType);
	QVERIFY(doi1.ic() == ic);
	QVERIFY(doi1.personName() == personName);
	QVERIFY(doi1.firmName() == firmName);
	QVERIFY(doi1.birthInfo() == birthInfo);
	QVERIFY(doi1.address() == address);
	QVERIFY(doi1.nationality() == nationality);
	QVERIFY(doi1.email() == email);
	QVERIFY(doi1.telNumber() == telNumber);
	QVERIFY(doi1.identifier() == identifier);
	QVERIFY(doi1.registryCode() == registryCode);
	QVERIFY(doi1.dbState() == dbState);
	QVERIFY(doi1.dbEffectiveOVM() == dbEffectiveOVM);
	QVERIFY(doi1.dbOpenAddressing() == dbOpenAddressing);

	QVERIFY(!doi1.isNull());
	QVERIFY(doi2.isNull());
	QVERIFY(doi1 != doi2);

	/* Check value copying. */
	doi2 = doi1;

	QVERIFY(doi2.dbID() == dbID);
	QVERIFY(doi2.dbType() == dbType);
	QVERIFY(doi2.ic() == ic);
	QVERIFY(doi2.personName() == personName);
	QVERIFY(doi2.firmName() == firmName);
	QVERIFY(doi2.birthInfo() == birthInfo);
	QVERIFY(doi2.address() == address);
	QVERIFY(doi2.nationality() == nationality);
	QVERIFY(doi2.email() == email);
	QVERIFY(doi2.telNumber() == telNumber);
	QVERIFY(doi2.identifier() == identifier);
	QVERIFY(doi2.registryCode() == registryCode);
	QVERIFY(doi2.dbState() == dbState);
	QVERIFY(doi2.dbEffectiveOVM() == dbEffectiveOVM);
	QVERIFY(doi2.dbOpenAddressing() == dbOpenAddressing);

	QVERIFY(!doi1.isNull());
	QVERIFY(!doi2.isNull());
	QVERIFY(doi1 == doi2);

	/* Clear value. */
	doi1 = Isds::DbOwnerInfo();

	QVERIFY(doi1.dbID().isNull());
	QVERIFY(doi1.dbType() == Isds::Type::BT_NULL);
	QVERIFY(doi1.ic().isNull());
	QVERIFY(doi1.personName().isNull());
	QVERIFY(doi1.firmName().isNull());
	QVERIFY(doi1.birthInfo().isNull());
	QVERIFY(doi1.address().isNull());
	QVERIFY(doi1.nationality().isNull());
	QVERIFY(doi1.email().isNull());
	QVERIFY(doi1.telNumber().isNull());
	QVERIFY(doi1.identifier().isNull());
	QVERIFY(doi1.registryCode().isNull());
	QVERIFY(doi1.dbState() == Isds::Type::BS_ERROR);
	QVERIFY(doi1.dbEffectiveOVM() == Isds::Type::BOOL_NULL);
	QVERIFY(doi1.dbOpenAddressing() == Isds::Type::BOOL_NULL);
	QVERIFY(doi2.dbID() == dbID);
	QVERIFY(doi2.dbType() == dbType);
	QVERIFY(doi2.ic() == ic);
	QVERIFY(doi2.personName() == personName);
	QVERIFY(doi2.firmName() == firmName);
	QVERIFY(doi2.birthInfo() == birthInfo);
	QVERIFY(doi2.address() == address);
	QVERIFY(doi2.nationality() == nationality);
	QVERIFY(doi2.email() == email);
	QVERIFY(doi2.telNumber() == telNumber);
	QVERIFY(doi2.identifier() == identifier);
	QVERIFY(doi2.registryCode() == registryCode);
	QVERIFY(doi2.dbState() == dbState);
	QVERIFY(doi2.dbEffectiveOVM() == dbEffectiveOVM);
	QVERIFY(doi2.dbOpenAddressing() == dbOpenAddressing);

	QVERIFY(doi1.isNull());
	QVERIFY(!doi2.isNull());
	QVERIFY(doi1 != doi2);
}

void TestIsdsBoxInterface::dbOwnerInfoCompare(void)
{
	Isds::DbOwnerInfo doi1, doi2;
	const QString dbID("dbID");
	const enum Isds::Type::DbType dbType = Isds::Type::BT_OVM;
	const QString ic("ic");
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	const QString firmName("firmName");
	Isds::BirthInfo birthInfo;
	{
		birthInfo.setDate(QDate(2001, 2, 3));
		birthInfo.setCity("biCity");
		birthInfo.setCounty("biCounty");
		birthInfo.setState("biState");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QString nationality("nationality");
	const QString email("email");
	const QString telNumber("telNumber");
	const QString identifier("identifier");
	const QString registryCode("registryCode");
	const enum Isds::Type::DbState dbState = Isds::Type::BS_ACCESSIBLE;
	const enum Isds::Type::NilBool dbEffectiveOVM = Isds::Type::BOOL_FALSE;
	const enum Isds::Type::NilBool dbOpenAddressing = Isds::Type::BOOL_TRUE;

	doi1.setDbID(dbID);
	doi1.setDbType(dbType);
	doi1.setIc(ic);
	doi1.setPersonName(personName);
	doi1.setFirmName(firmName);
	doi1.setBirthInfo(birthInfo);
	doi1.setAddress(address);
	doi1.setNationality(nationality);
	doi1.setEmail(email);
	doi1.setTelNumber(telNumber);
	doi1.setIdentifier(identifier);
	doi1.setRegistryCode(registryCode);
	doi1.setDbState(dbState);
	doi1.setDbEffectiveOVM(dbEffectiveOVM);
	doi1.setDbOpenAddressing(dbOpenAddressing);
	doi2.setDbID(dbID);
	doi2.setDbType(dbType);
	doi2.setIc(ic);
	doi2.setPersonName(personName);
	doi2.setFirmName(firmName);
	doi2.setBirthInfo(birthInfo);
	doi2.setAddress(address);
	doi2.setNationality(nationality);
	doi2.setEmail(email);
	doi2.setTelNumber(telNumber);
	doi2.setIdentifier(identifier);
	doi2.setRegistryCode(registryCode);
	doi2.setDbState(dbState);
	doi2.setDbEffectiveOVM(dbEffectiveOVM);
	doi2.setDbOpenAddressing(dbOpenAddressing);

	QVERIFY(doi1 == doi2);

	doi2.setDbID("");
	QVERIFY(doi1 != doi2);
	doi2.setDbID(dbID);
	QVERIFY(doi1 == doi2);

	doi2.setDbType(Isds::Type::BT_PO);
	QVERIFY(doi1 != doi2);
	doi2.setDbType(dbType);
	QVERIFY(doi1 == doi2);

	doi2.setIc("");
	QVERIFY(doi1 != doi2);
	doi2.setIc(ic);
	QVERIFY(doi1 == doi2);

	doi2.setPersonName(Isds::PersonName());
	QVERIFY(doi1 != doi2);
	doi2.setPersonName(personName);
	QVERIFY(doi1 == doi2);

	doi2.setFirmName("");
	QVERIFY(doi1 != doi2);
	doi2.setFirmName(firmName);
	QVERIFY(doi1 == doi2);

	doi2.setBirthInfo(Isds::BirthInfo());
	QVERIFY(doi1 != doi2);
	doi2.setBirthInfo(birthInfo);
	QVERIFY(doi1 == doi2);

	doi2.setAddress(Isds::Address());
	QVERIFY(doi1 != doi2);
	doi2.setAddress(address);
	QVERIFY(doi1 == doi2);

	doi2.setNationality("");
	QVERIFY(doi1 != doi2);
	doi2.setNationality(nationality);
	QVERIFY(doi1 == doi2);

	doi2.setEmail("");
	QVERIFY(doi1 != doi2);
	doi2.setEmail(email);
	QVERIFY(doi1 == doi2);

	doi2.setTelNumber("");
	QVERIFY(doi1 != doi2);
	doi2.setTelNumber(telNumber);
	QVERIFY(doi1 == doi2);

	doi2.setIdentifier("");
	QVERIFY(doi1 != doi2);
	doi2.setIdentifier(identifier);
	QVERIFY(doi1 == doi2);

	doi2.setRegistryCode("");
	QVERIFY(doi1 != doi2);
	doi2.setRegistryCode(registryCode);
	QVERIFY(doi1 == doi2);

	doi2.setDbState(Isds::Type::BS_TEMP_INACCESSIBLE);
	QVERIFY(doi1 != doi2);
	doi2.setDbState(dbState);
	QVERIFY(doi1 == doi2);

	doi2.setDbEffectiveOVM(Isds::Type::BOOL_TRUE);
	QVERIFY(doi1 != doi2);
	doi2.setDbEffectiveOVM(dbEffectiveOVM);
	QVERIFY(doi1 == doi2);

	doi2.setDbOpenAddressing(Isds::Type::BOOL_FALSE);
	QVERIFY(doi1 != doi2);
	doi2.setDbOpenAddressing(dbOpenAddressing);
	QVERIFY(doi1 == doi2);
}

void TestIsdsBoxInterface::dbOwnerInfoCopy(void)
{
	Isds::DbOwnerInfo doi1;
	const QString dbID("dbID");
	const enum Isds::Type::DbType dbType = Isds::Type::BT_OVM;
	const QString ic("ic");
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	const QString firmName("firmName");
	Isds::BirthInfo birthInfo;
	{
		birthInfo.setDate(QDate(2001, 2, 3));
		birthInfo.setCity("biCity");
		birthInfo.setCounty("biCounty");
		birthInfo.setState("biState");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QString nationality("nationality");
	const QString email("email");
	const QString telNumber("telNumber");
	const QString identifier("identifier");
	const QString registryCode("registryCode");
	const enum Isds::Type::DbState dbState = Isds::Type::BS_ACCESSIBLE;
	const enum Isds::Type::NilBool dbEffectiveOVM = Isds::Type::BOOL_FALSE;
	const enum Isds::Type::NilBool dbOpenAddressing = Isds::Type::BOOL_TRUE;

	doi1.setDbID(dbID);
	doi1.setDbType(dbType);
	doi1.setIc(ic);
	doi1.setPersonName(personName);
	doi1.setFirmName(firmName);
	doi1.setBirthInfo(birthInfo);
	doi1.setAddress(address);
	doi1.setNationality(nationality);
	doi1.setEmail(email);
	doi1.setTelNumber(telNumber);
	doi1.setIdentifier(identifier);
	doi1.setRegistryCode(registryCode);
	doi1.setDbState(dbState);
	doi1.setDbEffectiveOVM(dbEffectiveOVM);
	doi1.setDbOpenAddressing(dbOpenAddressing);

	/* Constructor. */
	{
		Isds::DbOwnerInfo doi2(doi1);

		QVERIFY(!doi1.isNull());
		QVERIFY(!doi2.isNull());
		QVERIFY(doi1 == doi2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::DbOwnerInfo doi3(::std::move(doi2));

		QVERIFY(doi2.isNull());
		QVERIFY(doi1 != doi2);

		QVERIFY(!doi1.isNull());
		QVERIFY(!doi3.isNull());
		QVERIFY(doi1 == doi3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::DbOwnerInfo doi2;

		QVERIFY(doi2.isNull());

		doi2 = doi1;

		QVERIFY(!doi1.isNull());
		QVERIFY(!doi2.isNull());
		QVERIFY(doi1 == doi2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::DbOwnerInfo doi3;

		QVERIFY(doi3.isNull());

		doi3 = ::std::move(doi2);

		QVERIFY(doi2.isNull());
		QVERIFY(doi1 != doi2);

		QVERIFY(!doi1.isNull());
		QVERIFY(!doi3.isNull());
		QVERIFY(doi1 == doi3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::dbOwnerInfoConversion(void)
{
	Isds::DbOwnerInfo doi1, doi2;
	const QString dbID("dbID");
	const enum Isds::Type::DbType dbType = Isds::Type::BT_OVM;
	const QString ic("ic");
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	const QString firmName("firmName");
	Isds::BirthInfo birthInfo;
	{
		birthInfo.setDate(QDate(2001, 2, 3));
		birthInfo.setCity("biCity");
		birthInfo.setCounty("biCounty");
		birthInfo.setState("biState");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QString nationality("nationality");
	const QString email("email");
	const QString telNumber("telNumber");
	const QString identifier("identifier");
	const QString registryCode("registryCode");
	const enum Isds::Type::DbState dbState = Isds::Type::BS_ACCESSIBLE;
	const enum Isds::Type::NilBool dbEffectiveOVM = Isds::Type::BOOL_FALSE;
	const enum Isds::Type::NilBool dbOpenAddressing = Isds::Type::BOOL_TRUE;

	bool iOk = false;
	struct isds_DbOwnerInfo *idoi = NULL;

	QVERIFY(doi1.isNull());
	QVERIFY(doi2.isNull());
	QVERIFY(doi1 == doi2);

	doi1.setDbID(dbID);
	doi1.setDbType(dbType);
	doi1.setIc(ic);
	doi1.setPersonName(personName);
	doi1.setFirmName(firmName);
	doi1.setBirthInfo(birthInfo);
	doi1.setAddress(address);
	doi1.setNationality(nationality);
	doi1.setEmail(email);
	doi1.setTelNumber(telNumber);
	doi1.setIdentifier(identifier);
	doi1.setRegistryCode(registryCode);
	doi1.setDbState(dbState);
	doi1.setDbEffectiveOVM(dbEffectiveOVM);
	doi1.setDbOpenAddressing(dbOpenAddressing);

	QVERIFY(!doi1.isNull());
	QVERIFY(doi2.isNull());
	QVERIFY(doi1 != doi2);

	/* NULL pointer converts onto null object. */
	iOk = false;
	doi2 = Isds::libisds2dbOwnerInfo(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(doi2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	idoi = Isds::dbOwnerInfo2libisds(doi2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(idoi == NULL);

	iOk = false;
	idoi = Isds::dbOwnerInfo2libisds(doi1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(idoi != NULL);

	iOk = false;
	doi2 = Isds::libisds2dbOwnerInfo(idoi, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!doi2.isNull());

	QVERIFY(doi2.dbID() == dbID);
	QVERIFY(doi2.dbType() == dbType);
	QVERIFY(doi2.ic() == ic);
	QVERIFY(doi2.personName() == personName);
	QVERIFY(doi2.firmName() == firmName);
	QVERIFY(doi2.birthInfo() == birthInfo);
	QVERIFY(doi2.address() == address);
	QVERIFY(doi2.nationality() == nationality);
	QVERIFY(doi2.email() == email);
	QVERIFY(doi2.telNumber() == telNumber);
	QVERIFY(doi2.identifier() == identifier);
	QVERIFY(doi2.registryCode() == registryCode);
	QVERIFY(doi2.dbState() == dbState);
	QVERIFY(doi2.dbEffectiveOVM() == dbEffectiveOVM);
	QVERIFY(doi2.dbOpenAddressing() == dbOpenAddressing);

	QVERIFY(!doi1.isNull());
	QVERIFY(!doi2.isNull());
	QVERIFY(doi1 == doi2);

	isds_DbOwnerInfo_free(&idoi);
	QVERIFY(idoi == NULL);
}

void TestIsdsBoxInterface::dbUserInfo(void)
{
	Isds::DbUserInfo dui1, dui2;
	const QString userID("userID");
	const enum Isds::Type::UserType userType = Isds::Type::UT_PRIMARY;
	const Isds::Type::Privileges userPrivils = Isds::Type::PRIVIL_READ_NON_PERSONAL;
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QDate biDate(2001, 2, 3);
	const QString ic("ic");
	const QString firmName("firmName");
	const QString caStreet("caStreet");
	const QString caCity("caCity");
	const QString caZipCode("caZipCode");
	const QString caState("caState");

	/* Must be null. */
	QVERIFY(dui1.userID().isNull());
	QVERIFY(dui1.userType() == Isds::Type::UT_NULL);
	QVERIFY(dui1.userPrivils() == Isds::Type::PRIVIL_NONE);
	QVERIFY(dui1.personName().isNull());
	QVERIFY(dui1.address().isNull());
	QVERIFY(dui1.biDate().isNull());
	QVERIFY(dui1.ic().isNull());
	QVERIFY(dui1.firmName().isNull());
	QVERIFY(dui1.caStreet().isNull());
	QVERIFY(dui1.caCity().isNull());
	QVERIFY(dui1.caZipCode().isNull());
	QVERIFY(dui1.caState().isNull());
	QVERIFY(dui2.userID().isNull());
	QVERIFY(dui2.userType() == Isds::Type::UT_NULL);
	QVERIFY(dui2.userPrivils() == Isds::Type::PRIVIL_NONE);
	QVERIFY(dui2.personName().isNull());
	QVERIFY(dui2.address().isNull());
	QVERIFY(dui2.biDate().isNull());
	QVERIFY(dui2.ic().isNull());
	QVERIFY(dui2.firmName().isNull());
	QVERIFY(dui2.caStreet().isNull());
	QVERIFY(dui2.caCity().isNull());
	QVERIFY(dui2.caZipCode().isNull());
	QVERIFY(dui2.caState().isNull());

	QVERIFY(dui1.isNull());
	QVERIFY(dui2.isNull());
	QVERIFY(dui1 == dui2);

	/* Check whether values are not cross-linked. */
	dui1.setUserID(userID);
	dui1.setUserType(userType);
	dui1.setUserPrivils(userPrivils);
	dui1.setPersonName(personName);
	dui1.setAddress(address);
	dui1.setBiDate(biDate);
	dui1.setIc(ic);
	dui1.setFirmName(firmName);
	dui1.setCaStreet(caStreet);
	dui1.setCaCity(caCity);
	dui1.setCaZipCode(caZipCode);
	dui1.setCaState(caState);

	QVERIFY(dui1.userID() == userID);
	QVERIFY(dui1.userType() == userType);
	QVERIFY(dui1.userPrivils() == userPrivils);
	QVERIFY(dui1.personName() == personName);
	QVERIFY(dui1.address() == address);
	QVERIFY(dui1.biDate() == biDate);
	QVERIFY(dui1.ic() == ic);
	QVERIFY(dui1.firmName() == firmName);
	QVERIFY(dui1.caStreet() == caStreet);
	QVERIFY(dui1.caCity() == caCity);
	QVERIFY(dui1.caZipCode() == caZipCode);
	QVERIFY(dui1.caState() == caState);

	QVERIFY(!dui1.isNull());
	QVERIFY(dui2.isNull());
	QVERIFY(dui1 != dui2);

	/* Check value copying. */
	dui2 = dui1;

	QVERIFY(dui2.userID() == userID);
	QVERIFY(dui2.userType() == userType);
	QVERIFY(dui2.userPrivils() == userPrivils);
	QVERIFY(dui2.personName() == personName);
	QVERIFY(dui2.address() == address);
	QVERIFY(dui2.biDate() == biDate);
	QVERIFY(dui2.ic() == ic);
	QVERIFY(dui2.firmName() == firmName);
	QVERIFY(dui2.caStreet() == caStreet);
	QVERIFY(dui2.caCity() == caCity);
	QVERIFY(dui2.caZipCode() == caZipCode);
	QVERIFY(dui2.caState() == caState);

	QVERIFY(!dui1.isNull());
	QVERIFY(!dui2.isNull());
	QVERIFY(dui1 == dui2);

	/* Clear value. */
	dui1 = Isds::DbUserInfo();

	QVERIFY(dui1.userID().isNull());
	QVERIFY(dui1.userType() == Isds::Type::UT_NULL);
	QVERIFY(dui1.userPrivils() == Isds::Type::PRIVIL_NONE);
	QVERIFY(dui1.personName().isNull());
	QVERIFY(dui1.address().isNull());
	QVERIFY(dui1.biDate().isNull());
	QVERIFY(dui1.ic().isNull());
	QVERIFY(dui1.firmName().isNull());
	QVERIFY(dui1.caStreet().isNull());
	QVERIFY(dui1.caCity().isNull());
	QVERIFY(dui1.caZipCode().isNull());
	QVERIFY(dui1.caState().isNull());
	QVERIFY(dui2.userID() == userID);
	QVERIFY(dui2.userType() == userType);
	QVERIFY(dui2.userPrivils() == userPrivils);
	QVERIFY(dui2.personName() == personName);
	QVERIFY(dui2.address() == address);
	QVERIFY(dui2.biDate() == biDate);
	QVERIFY(dui2.ic() == ic);
	QVERIFY(dui2.firmName() == firmName);
	QVERIFY(dui2.caStreet() == caStreet);
	QVERIFY(dui2.caCity() == caCity);
	QVERIFY(dui2.caZipCode() == caZipCode);
	QVERIFY(dui2.caState() == caState);

	QVERIFY(dui1.isNull());
	QVERIFY(!dui2.isNull());
	QVERIFY(dui1 != dui2);
}

void TestIsdsBoxInterface::dbUserInfoCompare(void)
{
	Isds::DbUserInfo dui1, dui2;
	const QString userID("userID");
	const enum Isds::Type::UserType userType = Isds::Type::UT_PRIMARY;
	const Isds::Type::Privileges userPrivils = Isds::Type::PRIVIL_READ_NON_PERSONAL;
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QDate biDate(2001, 2, 3);
	const QString ic("ic");
	const QString firmName("firmName");
	const QString caStreet("caStreet");
	const QString caCity("caCity");
	const QString caZipCode("caZipCode");
	const QString caState("caState");

	dui1.setUserID(userID);
	dui1.setUserType(userType);
	dui1.setUserPrivils(userPrivils);
	dui1.setPersonName(personName);
	dui1.setAddress(address);
	dui1.setBiDate(biDate);
	dui1.setIc(ic);
	dui1.setFirmName(firmName);
	dui1.setCaStreet(caStreet);
	dui1.setCaCity(caCity);
	dui1.setCaZipCode(caZipCode);
	dui1.setCaState(caState);
	dui2.setUserID(userID);
	dui2.setUserType(userType);
	dui2.setUserPrivils(userPrivils);
	dui2.setPersonName(personName);
	dui2.setAddress(address);
	dui2.setBiDate(biDate);
	dui2.setIc(ic);
	dui2.setFirmName(firmName);
	dui2.setCaStreet(caStreet);
	dui2.setCaCity(caCity);
	dui2.setCaZipCode(caZipCode);
	dui2.setCaState(caState);

	QVERIFY(dui1 == dui2);

	dui2.setUserID("");
	QVERIFY(dui1 != dui2);
	dui2.setUserID(userID);
	QVERIFY(dui1 == dui2);

	dui2.setUserType(Isds::Type::UT_ENTRUSTED);
	QVERIFY(dui1 != dui2);
	dui2.setUserType(userType);
	QVERIFY(dui1 == dui2);

	dui2.setUserPrivils(Isds::Type::PRIVIL_READ_ALL);
	QVERIFY(dui1 != dui2);
	dui2.setUserPrivils(userPrivils);
	QVERIFY(dui1 == dui2);

	dui2.setPersonName(Isds::PersonName());
	QVERIFY(dui1 != dui2);
	dui2.setPersonName(personName);
	QVERIFY(dui1 == dui2);

	dui2.setAddress(Isds::Address());
	QVERIFY(dui1 != dui2);
	dui2.setAddress(address);
	QVERIFY(dui1 == dui2);

	dui2.setBiDate(QDate(2001, 2, 4));
	QVERIFY(dui1 != dui2);
	dui2.setBiDate(biDate);
	QVERIFY(dui1 == dui2);

	dui2.setIc("");
	QVERIFY(dui1 != dui2);
	dui2.setIc(ic);
	QVERIFY(dui1 == dui2);

	dui2.setFirmName("");
	QVERIFY(dui1 != dui2);
	dui2.setFirmName(firmName);
	QVERIFY(dui1 == dui2);

	dui2.setCaStreet("");
	QVERIFY(dui1 != dui2);
	dui2.setCaStreet(caStreet);
	QVERIFY(dui1 == dui2);

	dui2.setCaCity("");
	QVERIFY(dui1 != dui2);
	dui2.setCaCity(caCity);
	QVERIFY(dui1 == dui2);

	dui2.setCaZipCode("");
	QVERIFY(dui1 != dui2);
	dui2.setCaZipCode(caZipCode);
	QVERIFY(dui1 == dui2);

	dui2.setCaState("");
	QVERIFY(dui1 != dui2);
	dui2.setCaState(caState);
	QVERIFY(dui1 == dui2);
}

void TestIsdsBoxInterface::dbUserInfoCopy(void)
{
	Isds::DbUserInfo dui1;
	const QString userID("userID");
	const enum Isds::Type::UserType userType = Isds::Type::UT_PRIMARY;
	const Isds::Type::Privileges userPrivils = Isds::Type::PRIVIL_READ_NON_PERSONAL;
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QDate biDate(2001, 2, 3);
	const QString ic("ic");
	const QString firmName("firmName");
	const QString caStreet("caStreet");
	const QString caCity("caCity");
	const QString caZipCode("caZipCode");
	const QString caState("caState");

	dui1.setUserID(userID);
	dui1.setUserType(userType);
	dui1.setUserPrivils(userPrivils);
	dui1.setPersonName(personName);
	dui1.setAddress(address);
	dui1.setBiDate(biDate);
	dui1.setIc(ic);
	dui1.setFirmName(firmName);
	dui1.setCaStreet(caStreet);
	dui1.setCaCity(caCity);
	dui1.setCaZipCode(caZipCode);
	dui1.setCaState(caState);

	/* Constructor. */
	{
		Isds::DbUserInfo dui2(dui1);

		QVERIFY(!dui1.isNull());
		QVERIFY(!dui2.isNull());
		QVERIFY(dui1 == dui2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::DbUserInfo dui3(::std::move(dui2));

		QVERIFY(dui2.isNull());
		QVERIFY(dui1 != dui2);

		QVERIFY(!dui1.isNull());
		QVERIFY(!dui3.isNull());
		QVERIFY(dui1 == dui3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::DbUserInfo dui2;

		QVERIFY(dui2.isNull());

		dui2 = dui1;

		QVERIFY(!dui1.isNull());
		QVERIFY(!dui2.isNull());
		QVERIFY(dui1 == dui2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::DbUserInfo dui3;

		QVERIFY(dui3.isNull());

		dui3 = ::std::move(dui2);

		QVERIFY(dui2.isNull());
		QVERIFY(dui1 != dui2);

		QVERIFY(!dui1.isNull());
		QVERIFY(!dui3.isNull());
		QVERIFY(dui1 == dui3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::dbUserInfoConversion(void)
{
	Isds::DbUserInfo dui1, dui2;
	const QString userID("userID");
	const enum Isds::Type::UserType userType = Isds::Type::UT_PRIMARY;
	const Isds::Type::Privileges userPrivils = Isds::Type::PRIVIL_READ_NON_PERSONAL;
	Isds::PersonName personName;
	{
		personName.setFirstName("pnFirstName");
		personName.setMiddleName("pnMiddleName");
		personName.setLastName("pnLastName");
		personName.setLastNameAtBirth("pnLastNameAtBirth");
	}
	Isds::Address address;
	{
		address.setCity("adCity");
		address.setStreet("adStreet");
		address.setNumberInStreet("adNumberInStreet");
		address.setNumberInMunicipality("adNumberInMunicipality");
		address.setZipCode("adZipCode");
		address.setState("adState");
	}
	const QDate biDate(2001, 2, 3);
	const QString ic("ic");
	const QString firmName("firmName");
	const QString caStreet("caStreet");
	const QString caCity("caCity");
	const QString caZipCode("caZipCode");
	const QString caState("caState");

	bool iOk = false;
	struct isds_DbUserInfo *idui = NULL;

	QVERIFY(dui1.isNull());
	QVERIFY(dui2.isNull());
	QVERIFY(dui1 == dui2);

	dui1.setUserID(userID);
	dui1.setUserType(userType);
	dui1.setUserPrivils(userPrivils);
	dui1.setPersonName(personName);
	dui1.setAddress(address);
	dui1.setBiDate(biDate);
	dui1.setIc(ic);
	dui1.setFirmName(firmName);
	dui1.setCaStreet(caStreet);
	dui1.setCaCity(caCity);
	dui1.setCaZipCode(caZipCode);
	dui1.setCaState(caState);

	QVERIFY(!dui1.isNull());
	QVERIFY(dui2.isNull());
	QVERIFY(dui1 != dui2);

	/* NULL pointer converts onto null object. */
	iOk = false;
	dui2 = Isds::libisds2dbUserInfo(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(dui2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	idui = Isds::dbUserInfo2libisds(dui2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(idui == NULL);

	iOk = false;
	idui = Isds::dbUserInfo2libisds(dui1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(idui != NULL);

	iOk = false;
	dui2 = Isds::libisds2dbUserInfo(idui, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!dui2.isNull());

	QVERIFY(dui2.userID() == userID);
	QVERIFY(dui2.userType() == userType);
	QVERIFY(dui2.userPrivils() == userPrivils);
	QVERIFY(dui2.personName() == personName);
	QVERIFY(dui2.address() == address);
	QVERIFY(dui2.biDate() == biDate);
	QVERIFY(dui2.ic() == ic);
	QVERIFY(dui2.firmName() == firmName);
	QVERIFY(dui2.caStreet() == caStreet);
	QVERIFY(dui2.caCity() == caCity);
	QVERIFY(dui2.caZipCode() == caZipCode);
	QVERIFY(dui2.caState() == caState);

	QVERIFY(!dui1.isNull());
	QVERIFY(!dui2.isNull());
	QVERIFY(dui1 == dui2);

	isds_DbUserInfo_free(&idui);
	QVERIFY(idui == NULL);
}

void TestIsdsBoxInterface::credentialsDelivery(void)
{
	Isds::CredentialsDelivery cd1, cd2;
	const QString email("email");
	const QString token("token");
	const QString username("username");

	/* Must be null. */
	QVERIFY(cd1.email().isNull());
	QVERIFY(cd1.token().isNull());
	QVERIFY(cd1.username().isNull());
	QVERIFY(cd2.email().isNull());
	QVERIFY(cd2.token().isNull());
	QVERIFY(cd2.username().isNull());

	QVERIFY(cd1.isNull());
	QVERIFY(cd2.isNull());
	QVERIFY(cd1 == cd2);

	/* Check whether values are not cross-linked. */
	cd1.setEmail(email);
	cd1.setToken(token);
	cd1.setUsername(username);

	QVERIFY(cd1.email() == email);
	QVERIFY(cd1.token() == token);
	QVERIFY(cd1.username() == username);

	QVERIFY(!cd1.isNull());
	QVERIFY(cd2.isNull());
	QVERIFY(cd1 != cd2);

	/* Check value copying. */
	cd2 = cd1;

	QVERIFY(cd2.email() == email);
	QVERIFY(cd2.token() == token);
	QVERIFY(cd2.username() == username);

	QVERIFY(!cd1.isNull());
	QVERIFY(!cd2.isNull());
	QVERIFY(cd1 == cd2);

	/* Clear value. */
	cd1 = Isds::CredentialsDelivery();

	QVERIFY(cd1.email().isNull());
	QVERIFY(cd1.token().isNull());
	QVERIFY(cd1.username().isNull());
	QVERIFY(cd2.email() == email);
	QVERIFY(cd2.token() == token);
	QVERIFY(cd2.username() == username);

	QVERIFY(cd1.isNull());
	QVERIFY(!cd2.isNull());
	QVERIFY(cd1 != cd2);
}

void TestIsdsBoxInterface::credentialsDeliveryCompare(void)
{
	Isds::CredentialsDelivery cd1, cd2;
	const QString email("email");
	const QString token("token");
	const QString username("username");

	cd1.setEmail(email);
	cd1.setToken(token);
	cd1.setUsername(username);
	cd2.setEmail(email);
	cd2.setToken(token);
	cd2.setUsername(username);

	QVERIFY(cd1 == cd2);

	cd2.setEmail("");
	QVERIFY(cd1 != cd2);
	cd2.setEmail(email);
	QVERIFY(cd1 == cd2);

	cd2.setToken("");
	QVERIFY(cd1 != cd2);
	cd2.setToken(token);
	QVERIFY(cd1 == cd2);

	cd2.setUsername("");
	QVERIFY(cd1 != cd2);
	cd2.setUsername(username);
	QVERIFY(cd1 == cd2);
}

void TestIsdsBoxInterface::credentialsDeliveryCopy(void)
{
	Isds::CredentialsDelivery cd1;
	const QString email("email");
	const QString token("token");
	const QString username("username");

	cd1.setEmail(email);
	cd1.setToken(token);
	cd1.setUsername(username);

	/* Constructor. */
	{
		Isds::CredentialsDelivery cd2(cd1);

		QVERIFY(!cd1.isNull());
		QVERIFY(!cd2.isNull());
		QVERIFY(cd1 == cd2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::CredentialsDelivery cd3(::std::move(cd2));

		QVERIFY(cd2.isNull());
		QVERIFY(cd1 != cd2);

		QVERIFY(!cd1.isNull());
		QVERIFY(!cd3.isNull());
		QVERIFY(cd1 == cd3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}


	/* Assignment operator. */
	{
		Isds::CredentialsDelivery cd2;

		QVERIFY(cd2.isNull());

		cd2 = cd1;

		QVERIFY(!cd1.isNull());
		QVERIFY(!cd2.isNull());
		QVERIFY(cd1 == cd2);

#ifdef Q_COMPILER_RVALUE_REFS
		/* Move. */
		Isds::CredentialsDelivery cd3;

		QVERIFY(cd3.isNull());

		cd3 = ::std::move(cd2);

		QVERIFY(cd2.isNull());
		QVERIFY(cd1 != cd2);

		QVERIFY(!cd1.isNull());
		QVERIFY(!cd3.isNull());
		QVERIFY(cd1 == cd3);
#endif /* Q_COMPILER_RVALUE_REFS */
	}
}

void TestIsdsBoxInterface::credentialsDeliveryConversion(void)
{
	Isds::CredentialsDelivery cd1, cd2;
	const QString email("email");
	const QString token("token");
	const QString username("username");

	bool iOk = false;
	struct isds_credentials_delivery *icd = NULL;

	QVERIFY(cd1.isNull());
	QVERIFY(cd2.isNull());
	QVERIFY(cd1 == cd2);

	cd1.setEmail(email);
	cd1.setToken(token);
	cd1.setUsername(username);

	QVERIFY(!cd1.isNull());
	QVERIFY(cd2.isNull());
	QVERIFY(cd1 != cd2);

	/* NULL pointer converts onto null object. */
	iOk = false;
	cd2 = Isds::libisds2credentialsDelivery(NULL, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(cd2.isNull());

	/* Null object converts onto NULL pointer. */
	iOk = false;
	icd = Isds::credentialsDelivery2libisds(cd2, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(icd == NULL);

	iOk = false;
	icd = Isds::credentialsDelivery2libisds(cd1, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(icd != NULL);

	iOk = false;
	cd2 = Isds::libisds2credentialsDelivery(icd, &iOk);
	QVERIFY(iOk == true);
	QVERIFY(!cd2.isNull());

	QVERIFY(cd2.email() == email);
	QVERIFY(cd2.token() == token);
	QVERIFY(cd2.username() == username);

	QVERIFY(!cd1.isNull());
	QVERIFY(!cd2.isNull());
	QVERIFY(cd1 == cd2);

	isds_credentials_delivery_free(&icd);
	QVERIFY(icd == NULL);
}

QObject *newTestIsdsBoxInterface(void)
{
	return new (::std::nothrow) TestIsdsBoxInterface();
}

//QTEST_MAIN(TestIsdsBoxInterface)
#include "test_isds_box_interface.moc"
