changeset 199:9ef01392a7f1

tests: make a database test fixture, closes #939 @4h Start PostgreSQL for each test in a clean directory and initialize a malikaniadb within. Only enable unix domain sockets to avoid collision with a system instance. While here, move out the init script into a dedicated file until we find a good solution for initializing databases and upgrading.
author David Demelier <markand@malikania.fr>
date Tue, 30 Oct 2018 13:21:55 +0100
parents bf17be3e20f2
children 0a285d62ace7
files CMakeLists.txt cmake/function/MalikaniaDefineLibrary.cmake libmlk-db-test/CMakeLists.txt libmlk-db-test/malikania/db/test/db_fixture.cpp libmlk-db-test/malikania/db/test/db_fixture.hpp libmlk-db/malikania/db/character.cpp libmlk-db/malikania/db/database.cpp libmlk-db/malikania/db/database.hpp libmlk-db/script/init.sql mlk-server/main.cpp tests/CMakeLists.txt tests/libmlk-db/CMakeLists.txt tests/libmlk-db/account/CMakeLists.txt tests/libmlk-db/account/main.cpp
diffstat 14 files changed, 415 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Tue Nov 27 21:07:00 2018 +0100
+++ b/CMakeLists.txt	Tue Oct 30 13:21:55 2018 +0100
@@ -59,6 +59,7 @@
 
 if (WITH_TESTS)
 	# Unit test libs.
+	add_subdirectory(libmlk-db-test)
 	add_subdirectory(libmlk-js-test)
 	add_subdirectory(libmlk-client-js-test)
 
--- a/cmake/function/MalikaniaDefineLibrary.cmake	Tue Nov 27 21:07:00 2018 +0100
+++ b/cmake/function/MalikaniaDefineLibrary.cmake	Tue Oct 30 13:21:55 2018 +0100
@@ -67,12 +67,7 @@
 			${CMAKE_CURRENT_SOURCE_DIR}
 			${LIB_PUBLIC_INCLUDES}
 	)
-	target_compile_definitions(
-		${LIB_TARGET}
-		PRIVATE ${LIB_FLAGS}
-		CMAKE_CURRENT_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}"
-		CMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
-	)
+	target_compile_definitions(${LIB_TARGET} PRIVATE ${LIB_FLAGS})
 
 	#
 	# Move the library into fakeroot/bin/ directory for Windows and other
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-db-test/CMakeLists.txt	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,53 @@
+#
+# CMakeLists.txt -- CMake build system for malikania
+#
+# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-db-test)
+
+find_program(PG_CTL_EXECUTABLE pg_ctl)
+find_program(PSQL_EXECUTABLE psql)
+
+if (NOT PG_CTL_EXECUTABLE OR NOT PSQL_EXECUTABLE)
+	return ()
+endif ()
+
+set(
+	HEADERS
+	${CMAKE_CURRENT_SOURCE_DIR}/malikania/db/test/db_fixture.hpp
+)
+
+set(
+	SOURCES
+	${CMAKE_CURRENT_SOURCE_DIR}/malikania/db/test/db_fixture.cpp
+)
+
+set(LIBRARIES Boost::boost Boost::filesystem libmlk-db)
+
+malikania_define_library(
+	TARGET libmlk-db-test
+	SOURCES ${HEADERS} ${SOURCES}
+	LIBRARIES ${LIBRARIES}
+	FLAGS
+		PG_CTL_EXECUTABLE="${PG_CTL_EXECUTABLE}"
+		PSQL_EXECUTABLE="${PSQL_EXECUTABLE}"
+		CMAKE_BINARY_DIR="${CMAKE_BINARY_DIR}"
+		CMAKE_SOURCE_DIR="${CMAKE_SOURCE_DIR}"
+		CMAKE_CURRENT_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}"
+		CMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
+	PUBLIC_INCLUDES
+		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-db-test/malikania/db/test/db_fixture.cpp	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,145 @@
+/*
+ * db_fixture.cpp -- database fixture suite
+ *
+ * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <fstream>
+
+#include <boost/filesystem.hpp>
+
+#include <boost/process/io.hpp>
+#include <boost/process/system.hpp>
+
+#include <malikania/db/database.hpp>
+
+#include "db_fixture.hpp"
+
+using boost::filesystem::create_directory;
+using boost::filesystem::remove_all;
+using boost::filesystem::path;
+
+using boost::process::null;
+using boost::process::std_err;
+using boost::process::std_out;
+using boost::process::system;
+
+using boost::system::error_code;
+
+using std::ofstream;
+
+namespace mlk::db::test {
+
+namespace {
+
+// Path to temporary directories.
+const auto db_directory = path(CMAKE_CURRENT_BINARY_DIR) / ".mlk-db";
+const auto socket_directory = path(CMAKE_CURRENT_BINARY_DIR) / ".mlk-db-sockets";
+const auto log_directory = path(CMAKE_CURRENT_BINARY_DIR) / ".mlk-db-log";
+
+// Path to configuration files that we need to change.
+const auto postgresql_conf_path = db_directory / "postgresql.conf";
+const auto pg_hba_conf_path = db_directory / "pg_hba.conf";
+
+// Path to init script.
+// TODO: this will change with mlk-db support.
+const auto init_path = path(CMAKE_SOURCE_DIR) / "libmlk-db" / "script" / "init.sql";
+
+} // !namespace
+
+void db_fixture::init()
+{
+	create_directory(db_directory);
+	create_directory(socket_directory);
+	create_directory(log_directory);
+
+	// Initialize postgres.
+	if (system(PG_CTL_EXECUTABLE, "-D", db_directory.string(), "initdb", std_out > null, std_err > null))
+		throw std::runtime_error("postgres initialization failed");
+}
+
+void db_fixture::configure()
+{
+	// 1. postgresql.conf
+	ofstream postgresql_conf(postgresql_conf_path.string(), ofstream::out | ofstream::trunc);
+	
+	postgresql_conf << "# this is autogenerated.\n";
+	postgresql_conf << "listen_addresses = ''\n";
+	postgresql_conf << "unix_socket_directories = '" << socket_directory.string() << "'\n";
+	postgresql_conf << "log_directory = '" << log_directory.string() << "'" << std::endl;
+
+	// 2. pg_hba.conf
+	ofstream pg_hba_conf(pg_hba_conf_path, ofstream::out | ofstream::trunc);
+
+	pg_hba_conf << "# this is autogenerated.\n\n";
+	pg_hba_conf << "local all all trust" << std::endl;
+}
+
+void db_fixture::start()
+{
+	if (system(PG_CTL_EXECUTABLE, "-D", db_directory.string(), "start", std_out > null, std_err > null))
+		throw std::runtime_error("postgresql startup failed");
+}
+
+void db_fixture::fill()
+{
+	if (system(PSQL_EXECUTABLE, "-h", socket_directory.string(), "template1", "-c", "CREATE DATABASE malikaniadb", std_out > null, std_err > null))
+		throw std::runtime_error("could not create malikaniadb");
+	if (system(PSQL_EXECUTABLE, "-h", socket_directory.string(), "malikaniadb", "-f", init_path.string(), std_out > null, std_err > null))
+		throw std::runtime_error("could not initialize malikaniadb");
+}
+
+void db_fixture::stop()
+{
+	system(PG_CTL_EXECUTABLE, "-D", db_directory.string(), "stop", std_out > null, std_err > null);
+}
+
+void db_fixture::cleanup()
+{
+	error_code ec;
+
+	remove_all(db_directory, ec);
+	remove_all(socket_directory, ec);
+	remove_all(log_directory, ec);
+}
+
+db_fixture::db_fixture()
+{
+	// Cleanup first in case of dirty test end.
+	stop();
+	cleanup();
+
+	init();
+	configure();
+	start();
+	fill();
+
+	// Finally connect.
+	mlk::db::open(socket_directory.string(), "", "", "malikaniadb", "");
+}
+
+db_fixture::~db_fixture()
+{
+	// Disconnect.
+	mlk::db::close();
+
+	// Stop and clean.
+	stop();
+
+	// Remove old files.
+	cleanup();
+}
+
+} // !mlk::db::test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-db-test/malikania/db/test/db_fixture.hpp	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * db_fixture.hpp -- database fixture suite
+ *
+ * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MALIKANIA_DB_TEST_DB_FIXTURE_HPP
+#define MALIKANIA_DB_TEST_DB_FIXTURE_HPP
+
+namespace mlk::db::test {
+
+class db_fixture {
+private:
+	void init();
+	void configure();
+	void fill();
+	void start();
+	void stop();
+	void cleanup();
+
+public:
+	db_fixture();
+	~db_fixture();
+};
+
+} // !mlk::db::test
+
+#endif // !MALIKANIA_DB_TEST_DB_FIXTURE_HPP
--- a/libmlk-db/malikania/db/character.cpp	Tue Nov 27 21:07:00 2018 +0100
+++ b/libmlk-db/malikania/db/character.cpp	Tue Oct 30 13:21:55 2018 +0100
@@ -65,9 +65,6 @@
 
 	const auto r = select(sql, { parent.get_id() });
 
-	if (PQntuples(r.get()) == 0)
-		throw std::runtime_error("failed to load characters");
-
 	std::vector<character> characters;
 
 	for (int i = 0; i < PQntuples(r.get()); ++i)
--- a/libmlk-db/malikania/db/database.cpp	Tue Nov 27 21:07:00 2018 +0100
+++ b/libmlk-db/malikania/db/database.cpp	Tue Oct 30 13:21:55 2018 +0100
@@ -96,62 +96,9 @@
 		throw std::runtime_error(PQerrorMessage(connection.get()));
 }
 
-const std::string init_account(
-	"CREATE TABLE IF NOT EXISTS account("
-	"  id SERIAL,"
-	"  login TEXT NOT NULL,"
-	"  password TEXT NOT NULL,"
-	"  firstname TEXT,"
-	"  lastname TEXT,"
-	"  email TEXT,"
-	"  PRIMARY KEY(id)"
-	")"
-);
-
-const std::string init_character(
-	"CREATE TABLE IF NOT EXISTS character("
-	"  id SERIAL,"
-	"  account_id INTEGER NOT NULL,"
-	"  nickname TEXT NOT NULL,"
-	"  type TEXT NOT NULL,"
-	"  hp_level SMALLINT NOT NULL DEFAULT 1,"
-	"  hp_factor SMALLINT NOT NULL,"
-	"  hp_exp INT NOT NULL,"
-	"  force_level SMALLINT NOT NULL DEFAULT 1,"
-	"  force_factor SMALLINT NOT NULL,"
-	"  force_exp INT NOT NULL,"
-	"  defense_level SMALLINT NOT NULL DEFAULT 1,"
-	"  defense_factor SMALLINT NOT NULL,"
-	"  defense_exp INT NOT NULL,"
-	"  agility_level SMALLINT NOT NULL DEFAULT 1,"
-	"  agility_factor SMALLINT NOT NULL,"
-	"  agility_exp INT NOT NULL,"
-	"  luck_level SMALLINT NOT NULL DEFAULT 1,"
-	"  luck_factor SMALLINT NOT NULL,"
-	"  luck_exp INT NOT NULL,"
-	"  PRIMARY KEY(id),"
-	"  FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE"
-	")"
-);
-
-const std::string init_spell(
-	"CREATE TABLE IF NOT EXISTS spell("
-	"  id SERIAL,"
-	"  character_id INTEGER NOT NULL,"
-	"  type TEXT NOT NULL,"
-	"  level SMALLINT NOT NULL,"
-	"  PRIMARY KEY(id),"
-	"  FOREIGN KEY (character_id) REFERENCES character(id) ON DELETE CASCADE"
-	")"
-);
-
-void init()
+void close()
 {
-	assert(connection);
-
-	exec(init_account);
-	exec(init_character);
-	exec(init_spell);
+	connection = nullptr;
 }
 
 auto select(const std::string& sql, const std::vector<arg>& args) -> result
--- a/libmlk-db/malikania/db/database.hpp	Tue Nov 27 21:07:00 2018 +0100
+++ b/libmlk-db/malikania/db/database.hpp	Tue Oct 30 13:21:55 2018 +0100
@@ -84,11 +84,9 @@
           const std::string& password);
 
 /**
- * Unconditionally init the database.
- *
- * \throw std::runtime_error on errors
+ * Close connection.
  */
-void init();
+void close();
 
 /**
  * Execute a SELECT statement.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-db/script/init.sql	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,60 @@
+--
+-- init.sql -- initialize database
+--
+-- Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+--
+-- Permission to use, copy, modify, and/or distribute this software for any
+-- purpose with or without fee is hereby granted, provided that the above
+-- copyright notice and this permission notice appear in all copies.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--
+
+CREATE TABLE IF NOT EXISTS account(
+	id SERIAL,
+	login TEXT NOT NULL,
+	password TEXT NOT NULL,
+	firstname TEXT,
+	lastname TEXT,
+	email TEXT,
+	PRIMARY KEY(id)
+);
+
+CREATE TABLE IF NOT EXISTS character(
+	id SERIAL,
+	account_id INTEGER NOT NULL,
+	nickname TEXT NOT NULL,
+	type TEXT NOT NULL,
+	hp_level SMALLINT NOT NULL DEFAULT 1,
+	hp_factor SMALLINT NOT NULL,
+	hp_exp INT NOT NULL,
+	force_level SMALLINT NOT NULL DEFAULT 1,
+	force_factor SMALLINT NOT NULL,
+	force_exp INT NOT NULL,
+	defense_level SMALLINT NOT NULL DEFAULT 1,
+	defense_factor SMALLINT NOT NULL,
+	defense_exp INT NOT NULL,
+	agility_level SMALLINT NOT NULL DEFAULT 1,
+	agility_factor SMALLINT NOT NULL,
+	agility_exp INT NOT NULL,
+	luck_level SMALLINT NOT NULL DEFAULT 1,
+	luck_factor SMALLINT NOT NULL,
+	luck_exp INT NOT NULL,
+	PRIMARY KEY(id),
+	FOREIGN KEY (account_id) REFERENCES account(id) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS spell(
+	id SERIAL,
+	character_id INTEGER NOT NULL,
+	type TEXT NOT NULL,
+	level SMALLINT NOT NULL,
+	PRIMARY KEY(id),
+	FOREIGN KEY (character_id) REFERENCES character(id) ON DELETE CASCADE
+);
--- a/mlk-server/main.cpp	Tue Nov 27 21:07:00 2018 +0100
+++ b/mlk-server/main.cpp	Tue Oct 30 13:21:55 2018 +0100
@@ -16,33 +16,6 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <iostream>
-
-#include <malikania/db/database.hpp>
-#include <malikania/db/account.hpp>
-
-#include <malikania/server/server.hpp>
-
-using namespace mlk;
-
 int main()
 {
-	boost::asio::io_context ctx;
-
-	try {
-		server::settings settings;
-
-		settings.key = "/home/markand/server.key";
-		settings.certificate = "/home/markand/server.crt";
-		settings.port = 3320;
-		
-		server::server sv(ctx, settings);
-
-		db::open("", "", "markand", "malikaniadb", "");
-		db::init();
-		
-		ctx.run();
-	} catch (const std::exception& ex) {
-		std::cerr << "abort: " << ex.what() << std::endl;
-	}
 }
--- a/tests/CMakeLists.txt	Tue Nov 27 21:07:00 2018 +0100
+++ b/tests/CMakeLists.txt	Tue Oct 30 13:21:55 2018 +0100
@@ -19,5 +19,6 @@
 project(test)
 
 add_subdirectory(libmlk)
+add_subdirectory(libmlk-db)
 add_subdirectory(libmlk-client)
 add_subdirectory(tools)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/libmlk-db/CMakeLists.txt	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,19 @@
+#
+# CMakeLists.txt -- CMake build system for malikania
+#
+# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+add_subdirectory(account)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/libmlk-db/account/CMakeLists.txt	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,23 @@
+#
+# CMakeLists.txt -- CMake build system for malikania
+#
+# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+malikania_create_test(
+	NAME db-account
+	LIBRARIES libmlk-db-test
+	SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/libmlk-db/account/main.cpp	Tue Oct 30 13:21:55 2018 +0100
@@ -0,0 +1,68 @@
+/*
+ * main.cpp -- test mlk::db::account
+ *
+ * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define BOOST_TEST_MODULE "mlk::db::account"
+#include <boost/test/unit_test.hpp>
+
+#include <malikania/db/account.hpp>
+
+#include <malikania/db/test/db_fixture.hpp>
+
+namespace mlk::db {
+
+namespace {
+
+BOOST_FIXTURE_TEST_SUITE(account_suite, test::db_fixture)
+
+BOOST_AUTO_TEST_CASE(simple)
+{
+	{
+		account ac("markand", "plop");	
+
+		ac.set_email("markand@malikania.fr");
+		ac.set_firstname("David");
+		ac.set_lastname("Demelier");
+
+		BOOST_TEST(ac.is_draft());
+
+		ac.publish();
+
+		BOOST_TEST(ac.is_published());
+	}
+
+	const auto ac = account::find_by_login("markand");
+
+	BOOST_TEST(ac.has_value());
+	BOOST_TEST(ac->is_published());
+	BOOST_TEST(ac->get_email() == "markand@malikania.fr");
+	BOOST_TEST(ac->get_firstname() == "David");
+	BOOST_TEST(ac->get_lastname() == "Demelier");
+}
+
+BOOST_AUTO_TEST_CASE(not_found)
+{
+	const auto ac = account::find_by_login("notexist");
+
+	BOOST_TEST(!ac);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // !namespace
+
+} // !mlk