summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHuynh Tran <nthuynh75@gmail.com>2005-06-27 15:41:00 +0000
committerHuynh Tran <nthuynh75@gmail.com>2005-06-27 15:41:00 +0000
commita78e59b9f2fb4eb7971eb5f46637df80157d787a (patch)
tree24e94f377228d9cfaeb5d487031bcdc326bb7c68 /src
parentbfcc4c6858238f343508b53f7fe90b9e9ac0ed01 (diff)
downloadmanaserv-a78e59b9f2fb4eb7971eb5f46637df80157d787a.tar.gz
manaserv-a78e59b9f2fb4eb7971eb5f46637df80157d787a.tar.bz2
manaserv-a78e59b9f2fb4eb7971eb5f46637df80157d787a.tar.xz
manaserv-a78e59b9f2fb4eb7971eb5f46637df80157d787a.zip
Implemented addAccount() (+ unit tests).
Diffstat (limited to 'src')
-rw-r--r--src/account.cpp44
-rw-r--r--src/account.h41
-rw-r--r--src/dalstorage.cpp304
-rw-r--r--src/dalstorage.h37
-rw-r--r--src/object.cpp2
-rw-r--r--src/storage.h20
-rw-r--r--src/tests/testaccount.cpp49
-rw-r--r--src/tests/testaccount.h4
-rw-r--r--src/tests/testcipher.cpp14
-rw-r--r--src/tests/teststorage.cpp209
-rw-r--r--src/tests/teststorage.h24
11 files changed, 634 insertions, 114 deletions
diff --git a/src/account.cpp b/src/account.cpp
index 7fd8f778..ed2c358e 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -32,10 +32,16 @@ namespace tmwserv
/**
- * Default constructor.
+ * Constructor with initial account info.
*/
-Account::Account(void)
- throw()
+Account::Account(const std::string& name,
+ const std::string& password,
+ const std::string& email)
+ : mName(name),
+ mPassword(password),
+ mEmail(email),
+ mCharacters(),
+ mLevel(AL_NORMAL)
{
// NOOP
}
@@ -49,11 +55,12 @@ Account::Account(const std::string& name,
const std::string& email,
const Beings& characters)
: mName(name),
+ mPassword(password),
mEmail(email),
- mCharacters(characters)
+ mCharacters(characters),
+ mLevel(AL_NORMAL)
{
- // password must be encrypted.
- setPassword(password);
+ // NOOP
}
@@ -104,15 +111,14 @@ Account::getName(void) const
void
Account::setPassword(const std::string& password)
{
- // use MD5 digest algorithm to cipher the password.
- mPassword = utils::Cipher::instance().md5(password);
+ mPassword = password;
}
/**
* Get the user password.
*/
-const std::string&
+const std::string
Account::getPassword(void) const
{
return mPassword;
@@ -141,6 +147,26 @@ Account::getEmail(void) const
/**
+ * Set the account level.
+ */
+void
+Account::setLevel(const AccountLevels level)
+{
+ mLevel = level;
+}
+
+
+/**
+ * Get the account level.
+ */
+AccountLevels
+Account::getLevel(void) const
+{
+ return mLevel;
+}
+
+
+/**
* Set the characters.
*/
void
diff --git a/src/account.h b/src/account.h
index 62c0ec7c..704a6739 100644
--- a/src/account.h
+++ b/src/account.h
@@ -28,7 +28,7 @@
#include <string>
#include <vector>
-#include "object.h"
+#include "defines.h"
namespace tmwserv
@@ -42,10 +42,15 @@ class Account
{
public:
/**
- * Default constructor.
+ * Constructor with initial account info.
+ *
+ * @param name the user name.
+ * @param password the user password.
+ * @param email the user email.
*/
- Account(void)
- throw();
+ Account(const std::string& name,
+ const std::string& password,
+ const std::string& email);
/**
@@ -102,7 +107,7 @@ class Account
*
* @return the user password.
*/
- const std::string&
+ const std::string
getPassword(void) const;
@@ -125,6 +130,24 @@ class Account
/**
+ * Set the account level.
+ *
+ * @param level the new level.
+ */
+ void
+ setLevel(const AccountLevels level);
+
+
+ /**
+ * Get the account level.
+ *
+ * @return the account level.
+ */
+ AccountLevels
+ getLevel(void) const;
+
+
+ /**
* Set the characters.
*
* @param characters a list of characters.
@@ -162,6 +185,13 @@ class Account
private:
/**
+ * Default constructor.
+ */
+ Account(void)
+ throw();
+
+
+ /**
* Copy constructor.
*/
Account(const Account& rhs);
@@ -179,6 +209,7 @@ class Account
std::string mPassword; /**< user password (encrypted) */
std::string mEmail; /**< user email address */
Beings mCharacters; /**< player data */
+ AccountLevels mLevel; /**< account level */
};
diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp
index 14c3ff7a..4e633718 100644
--- a/src/dalstorage.cpp
+++ b/src/dalstorage.cpp
@@ -22,7 +22,9 @@
#include <sstream>
+#include <vector>
+#include "utils/cipher.h"
#include "utils/functors.h"
#include "utils/logger.h"
@@ -194,13 +196,19 @@ DALStorage::getAccount(const std::string& userName)
// create an Account instance
// and initialize it with information about the user.
- Account* account = new Account();
- account->setName(accountInfo(0, 1));
- account->setPassword(accountInfo(0, 2));
- account->setEmail(accountInfo(0, 3));
+ Account* account = new Account(accountInfo(0, 1),
+ accountInfo(0, 2),
+ accountInfo(0, 3));
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned int.
+ string_to<unsigned int> toUint;
// add the new Account to the list.
- mAccounts.insert(std::make_pair(account, AS_ACC_TO_UPDATE));
+ AccountInfo ai;
+ ai.status = AS_ACC_TO_UPDATE;
+ ai.id = toUint(accountInfo(0, 0));
+ mAccounts.insert(std::make_pair(account, ai));
// load the characters associated with the account.
sql = "select * from ";
@@ -213,10 +221,6 @@ DALStorage::getAccount(const std::string& userName)
if (!charInfo.isEmpty()) {
Beings beings;
- // specialize the string_to functor to convert
- // a string to an unsigned int.
- string_to<unsigned int> toUint;
-
for (unsigned int i = 0; i < charInfo.rows(); ++i) {
Being* being =
new Being(charInfo(i, 2), // name
@@ -249,7 +253,7 @@ DALStorage::getAccount(const std::string& userName)
* Add a new account.
*/
void
-DALStorage::addAccount(Account* account)
+DALStorage::addAccount(const Account* account)
{
if (account == 0) {
// maybe we should throw an exception instead
@@ -258,7 +262,12 @@ DALStorage::addAccount(Account* account)
// mark this account as new so that the next flush will execute a SQL
// insert query instead of a SQL update query.
- mAccounts.insert(std::make_pair(account, AS_NEW_ACCOUNT));
+ AccountInfo ai;
+ ai.status = AS_NEW_ACCOUNT;
+ // the account id is set to 0 because we know nothing about it at the
+ // moment, it will be updated once saved into the database.
+ ai.id = 0;
+ mAccounts.insert(std::make_pair(const_cast<Account*>(account), ai));
}
@@ -277,17 +286,24 @@ DALStorage::delAccount(const std::string& userName)
);
if (it != mAccounts.end()) {
- switch (it->second) {
+ switch ((it->second).status) {
case AS_NEW_ACCOUNT:
- // this is a newly added account and it has not even been
- // saved into the database: remove it immediately.
- delete it->first;
+ {
+ // this is a newly added account and it has not even been
+ // saved into the database: remove it immediately.
+
+ // TODO: delete the associated characters.
+
+ delete it->first;
+
+ // TODO: remove from the map.
+ }
break;
case AS_ACC_TO_UPDATE:
// change the status to AS_ACC_TO_DELETE so that it will be
// deleted at the next flush.
- it->second = AS_ACC_TO_DELETE;
+ (it->second).status = AS_ACC_TO_DELETE;
break;
default:
@@ -301,26 +317,10 @@ DALStorage::delAccount(const std::string& userName)
using namespace dal;
try {
- std::string sql("select id from ");
- sql += ACCOUNTS_TBL_NAME;
- sql += " where username = '";
- sql += userName;
- sql += "';";
- const RecordSet& accountInfo = mDb->execSql(sql);
-
- // the account does not even exist in the database,
- // there is nothing to do then.
- if (accountInfo.isEmpty()) {
- return;
- }
-
- // TODO: actually deleting the account from the database.
- // order of deletion:
- // 1. inventories of all the characters of the account,
- // 2. all the characters,
- // 3. the account itself.
+ // look for the account directly into the database.
+ _delAccount(userName);
}
- catch (const DbSqlQueryExecFailure& e) {
+ catch (const dal::DbSqlQueryExecFailure& e) {
// TODO: throw an exception.
}
}
@@ -332,15 +332,27 @@ DALStorage::delAccount(const std::string& userName)
void
DALStorage::flush(void)
{
- // TODO
- // For each account in memory:
- // - get the status
- // - if AS_NEW_ACCOUNT then insert into database;
- // - if AS_ACC_TO_UPDATE then update values from the database
- // - if AS_ACC_TO_DELETE then delete from database
- // Notes:
- // - this will probably involve more than one table as the account may
- // have characters associated to it.
+ Accounts::const_iterator it = mAccounts.begin();
+ Accounts::const_iterator it_end = mAccounts.end();
+ for (; it != it_end; ++it) {
+ switch ((it->second).status) {
+ case AS_NEW_ACCOUNT:
+ _addAccount(it->first);
+ break;
+
+ case AS_ACC_TO_UPDATE:
+ _updAccount(it->first);
+ break;
+
+ case AS_ACC_TO_DELETE:
+ // TODO: accounts to be deleted must be handled differently
+ // as mAccounts will be altered once the accounts are deleted.
+ break;
+
+ default:
+ break;
+ }
+ }
}
@@ -371,4 +383,208 @@ DALStorage::createTable(const std::string& tblName,
}
+/**
+ * Add an account to the database.
+ */
+void
+DALStorage::_addAccount(const Account* account)
+{
+ if (account == 0) {
+ return;
+ }
+
+ // assume that account is an element of mAccounts as this method is
+ // private and only called by flush().
+
+ using namespace dal;
+
+ // TODO: we should start a transaction here so that in case of problem
+ // the lost of data would be minimized.
+
+ // insert the account.
+ std::ostringstream sql1;
+ sql1 << "insert into " << ACCOUNTS_TBL_NAME << " values (null, '"
+ << account->getName() << "', '"
+ << utils::Cipher::instance().md5(account->getPassword()) << "', '"
+ << account->getEmail() << "', "
+ << account->getLevel() << ", 0);";
+ mDb->execSql(sql1.str());
+
+ // get the account id.
+ std::ostringstream sql2;
+ sql2 << "select id from " << ACCOUNTS_TBL_NAME
+ << " where username = '" << account->getName() << "';";
+ const RecordSet& accountInfo = mDb->execSql(sql2.str());
+ string_to<unsigned int> toUint;
+
+ Accounts::iterator account_it =
+ std::find_if(
+ mAccounts.begin(),
+ mAccounts.end(),
+ account_by_name(account->getName())
+ );
+
+ // update the info of the account.
+ (account_it->second).status = AS_ACC_TO_UPDATE;
+ (account_it->second).id = toUint(accountInfo(0, 0));
+
+ // insert the characters.
+ Beings& characters = (const_cast<Account*>(account))->getCharacters();
+
+ Beings::const_iterator it = characters.begin();
+ Beings::const_iterator it_end = characters.end();
+ for (; it != it_end; ++it) {
+ // TODO: location on the map & statistics & inventories.
+ std::ostringstream sql3;
+ sql3 << "insert into " << CHARACTERS_TBL_NAME << " values (null, '"
+ << account->getName() << "', '"
+ << (*it)->getName() << "', '"
+ << (*it)->getGender() << "', "
+ << (*it)->getLevel() << ", "
+ << (*it)->getMoney() << ", "
+ << "0, 0, 0, 0, 0, 0, 0, 0, 0"
+ << ");";
+ mDb->execSql(sql3.str());
+ }
+}
+
+
+/**
+ * Update an account from the database.
+ */
+void
+DALStorage::_updAccount(const Account* account)
+{
+ if (account == 0) {
+ return;
+ }
+
+ // assume that account is an element of mAccounts as this method is
+ // private and only called by flush().
+
+ using namespace dal;
+
+ // TODO: we should start a transaction here so that in case of problem
+ // the lost of data would be minimized.
+
+ Accounts::iterator account_it =
+ std::find_if(
+ mAccounts.begin(),
+ mAccounts.end(),
+ account_by_name(account->getName())
+ );
+
+ // doublecheck that this account already exists in the database
+ // and therefore its status must be AS_ACC_TO_UPDATE.
+ if ((account_it->second).status != AS_ACC_TO_UPDATE) {
+ return; // should we throw an exception here instead?
+ }
+
+ // update the account.
+ std::ostringstream sql1;
+ sql1 << "update " << ACCOUNTS_TBL_NAME
+ << " set username = '" << account->getName() << "', "
+ << "password = '" << account->getPassword() << "', "
+ << "email = '" << account->getEmail() << "', "
+ << "level = '" << account->getLevel() << "' "
+ << "where id = '" << (account_it->second).id << "';";
+ mDb->execSql(sql1.str());
+
+ // insert the characters.
+ Beings& characters = (const_cast<Account*>(account))->getCharacters();
+
+ Beings::const_iterator it = characters.begin();
+ Beings::const_iterator it_end = characters.end();
+ for (; it != it_end; ++it) {
+ // TODO: location on the map & statistics & inventories.
+ std::ostringstream sql2;
+ sql2 << "update " << CHARACTERS_TBL_NAME
+ << "(user_id, name, gender, level, money) values ("
+ << " set name = '" << (*it)->getName() << "', "
+ << " gender = '" << (*it)->getGender() << "', "
+ << " level = '" << (*it)->getLevel() << "', "
+ << " money = '" << (*it)->getMoney() << "' "
+ << "where user_id = '" << (account_it->second).id << "';";
+ mDb->execSql(sql2.str());
+ }
+}
+
+
+/**
+ * Delete an account and its associated data from the database.
+ */
+void
+DALStorage::_delAccount(const std::string& userName)
+{
+ using namespace dal;
+
+ // TODO: optimize, we may be doing too much SQL queries here but this
+ // code should work with any database :(
+
+ // get the account id.
+ std::string sql("select id from ");
+ sql += ACCOUNTS_TBL_NAME;
+ sql += " where username = '";
+ sql += userName;
+ sql += "';";
+ const RecordSet& accountInfo = mDb->execSql(sql);
+
+ // the account does not even exist in the database,
+ // there is nothing to do then.
+ if (accountInfo.isEmpty()) {
+ return;
+ }
+
+ // save the account id.
+ std::string accountId(accountInfo(0, 0));
+
+ // get the characters that belong to the account.
+ sql = "select id from ";
+ sql += CHARACTERS_TBL_NAME;
+ sql += " where user_id = '";
+ sql += accountId;
+ sql += "';";
+ const RecordSet& charsInfo = mDb->execSql(sql);
+
+ // save the character ids.
+ using namespace std;
+ vector<string> charIds;
+ for (unsigned int i = 0; i < charsInfo.rows(); ++i) {
+ charIds.push_back(charsInfo(i, 0));
+ }
+
+ // TODO: we should start a transaction here so that in case of problem
+ // the lost of data would be minimized.
+
+ // actually removing data.
+ vector<string>::const_iterator it = charIds.begin();
+ vector<string>::const_iterator it_end = charIds.end();
+ for (; it != it_end; ++it) {
+ // delete the inventory.
+ sql = "delete from ";
+ sql += INVENTORIES_TBL_NAME;
+ sql += " where owner_id = '";
+ sql += (*it);
+ sql += "';";
+ mDb->execSql(sql);
+
+ // now delete the character.
+ sql = "delete from ";
+ sql += CHARACTERS_TBL_NAME;
+ sql += " where id = '";
+ sql += (*it);
+ sql += "';";
+ mDb->execSql(sql);
+ }
+
+ // delete the account.
+ sql = "delete from ";
+ sql += ACCOUNTS_TBL_NAME;
+ sql += " where id = '";
+ sql += accountId;
+ sql += "';";
+ mDb->execSql(sql);
+}
+
+
} // namespace tmwserv
diff --git a/src/dalstorage.h b/src/dalstorage.h
index 78a689c7..80408f6c 100644
--- a/src/dalstorage.h
+++ b/src/dalstorage.h
@@ -81,7 +81,7 @@ class DALStorage: public Storage
* @param account the new account.
*/
void
- addAccount(Account* account);
+ addAccount(const Account* account);
/**
@@ -95,6 +95,8 @@ class DALStorage: public Storage
/**
* Save changes to the database permanently.
+ *
+ * @exception tmwserv::dal::DbSqlQueryExecFailure.
*/
void
flush(void);
@@ -140,6 +142,39 @@ class DALStorage: public Storage
const std::string& sql);
+ /**
+ * Add an account to the database.
+ *
+ * @param account the account to add.
+ *
+ * @exeception tmwserv::dal::DbSqlQueryExecFailure.
+ */
+ void
+ _addAccount(const Account* account);
+
+
+ /**
+ * Update an account from the database.
+ *
+ * @param account the account to update.
+ *
+ * @exception tmwserv::dal::DbSqlQueryExecFailure.
+ */
+ void
+ _updAccount(const Account* account);
+
+
+ /**
+ * Delete an account and its associated data from the database.
+ *
+ * @param userName the owner of the account.
+ *
+ * @exeception tmwserv::dal::DbSqlQueryExecFailure.
+ */
+ void
+ _delAccount(const std::string& userName);
+
+
private:
std::auto_ptr<dal::DataProvider> mDb; /**< the data provider */
};
diff --git a/src/object.cpp b/src/object.cpp
index 9ae2bd61..f67bae05 100644
--- a/src/object.cpp
+++ b/src/object.cpp
@@ -38,7 +38,7 @@ Being::Being(const std::string &bName, unsigned int bGender,
dexterity(bDexterity),
luck(bLuck)
{
- std::cout << "New being create with name \"" + name + "\"" << std::endl;
+ //std::cout << "New being create with name \"" + name + "\"" << std::endl;
}
void Being::update()
diff --git a/src/storage.h b/src/storage.h
index 5b695bb0..4c6310d6 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -62,6 +62,15 @@ typedef enum {
/**
+ * Structure type for the account info.
+ */
+typedef struct {
+ AccountStatus status;
+ unsigned int id;
+} AccountInfo;
+
+
+/**
* Functor to be used as the sorting criterion of the map defined below.
*/
struct account_sort_by_name
@@ -77,8 +86,13 @@ struct account_sort_by_name
/**
* Data type for the list of accounts.
+ *
+ * Notes:
+ * - the account id is not attribute of Account but AccountInfo because
+ * only the storage should modify this value, this attribute is for
+ * internal use.
*/
-typedef std::map<Account*, AccountStatus, account_sort_by_name> Accounts;
+typedef std::map<Account*, AccountInfo, account_sort_by_name> Accounts;
/**
@@ -101,7 +115,7 @@ class account_by_name
* Operator().
*/
bool
- operator()(std::pair<Account*, AccountStatus> elem) const
+ operator()(std::pair<Account*, AccountInfo> elem) const
{
return (elem.first)->getName() == mName;
}
@@ -255,7 +269,7 @@ class Storage
* @param account the new account.
*/
virtual void
- addAccount(Account* account) = 0;
+ addAccount(const Account* account) = 0;
/**
diff --git a/src/tests/testaccount.cpp b/src/tests/testaccount.cpp
index 987ab81c..a086ef62 100644
--- a/src/tests/testaccount.cpp
+++ b/src/tests/testaccount.cpp
@@ -70,36 +70,22 @@ AccountTest::tearDown(void)
/**
- * Test creating an Account using the default constructor
- * and setting the account info using the mutators.
+ * Test creating an Account passing the initial account info
+ * to the constructor.
*/
void
AccountTest::testCreate1(void)
{
const std::string name("frodo");
const std::string password("baggins");
- const std::string encrypted("d70d266f4c276b5706881a46f43a88b0");
const std::string email("frodo@theshire.com");
- Account account;
- account.setName(name);
- account.setPassword(password);
- account.setEmail(email);
- account.setCharacters(mCharacters);
-
- CPPUNIT_ASSERT_EQUAL(account.getName(), name);
- CPPUNIT_ASSERT_EQUAL(account.getPassword(), encrypted);
- CPPUNIT_ASSERT_EQUAL(account.getEmail(), email);
-
- CPPUNIT_ASSERT_EQUAL(mAccount->getCharacters().size(),
- mCharacters.size());
-
- Beings& characters = account.getCharacters();
+ Account account(name, password, email);
- for (size_t i = 0; i < mCharacters.size(); ++i) {
- CPPUNIT_ASSERT_EQUAL(characters[i]->getName(),
- mCharacters[i]->getName());
- }
+ CPPUNIT_ASSERT_EQUAL(name, account.getName());
+ CPPUNIT_ASSERT_EQUAL(password, account.getPassword());
+ CPPUNIT_ASSERT_EQUAL(email, account.getEmail());
+ CPPUNIT_ASSERT_EQUAL((size_t) 0, account.getCharacters().size());
}
@@ -112,17 +98,16 @@ AccountTest::testCreate2(void)
{
const std::string name("frodo");
const std::string password("baggins");
- const std::string encrypted("d70d266f4c276b5706881a46f43a88b0");
const std::string email("frodo@theshire.com");
Account account(name, password, email, mCharacters);
- CPPUNIT_ASSERT_EQUAL(account.getName(), name);
- CPPUNIT_ASSERT_EQUAL(account.getPassword(), encrypted);
- CPPUNIT_ASSERT_EQUAL(account.getEmail(), email);
+ CPPUNIT_ASSERT_EQUAL(name, account.getName());
+ CPPUNIT_ASSERT_EQUAL(password, account.getPassword());
+ CPPUNIT_ASSERT_EQUAL(email, account.getEmail());
- CPPUNIT_ASSERT_EQUAL(mAccount->getCharacters().size(),
- mCharacters.size());
+ CPPUNIT_ASSERT_EQUAL(mCharacters.size(),
+ mAccount->getCharacters().size());
Beings& characters = account.getCharacters();
@@ -143,7 +128,7 @@ AccountTest::testAddCharacter1(void)
mAccount->addCharacter(bilbo);
- CPPUNIT_ASSERT_EQUAL(mAccount->getCharacters().size(), (size_t) 4);
+ CPPUNIT_ASSERT_EQUAL((size_t) 4, mAccount->getCharacters().size());
std::vector<std::string> names;
names.push_back("sam");
@@ -152,7 +137,7 @@ AccountTest::testAddCharacter1(void)
names.push_back("bilbo");
for (size_t i = 0; i < mCharacters.size(); ++i) {
- CPPUNIT_ASSERT_EQUAL(mCharacters[i]->getName(), names[i]);
+ CPPUNIT_ASSERT_EQUAL(names[i], mCharacters[i]->getName());
}
delete bilbo;
@@ -167,7 +152,7 @@ AccountTest::testAddCharacter2(void)
{
mAccount->addCharacter(NULL);
- CPPUNIT_ASSERT_EQUAL(mAccount->getCharacters().size(), (size_t) 3);
+ CPPUNIT_ASSERT_EQUAL((size_t) 3, mAccount->getCharacters().size());
std::vector<std::string> names;
names.push_back("sam");
@@ -175,7 +160,7 @@ AccountTest::testAddCharacter2(void)
names.push_back("pippin");
for (size_t i = 0; i < mCharacters.size(); ++i) {
- CPPUNIT_ASSERT_EQUAL(mCharacters[i]->getName(), names[i]);
+ CPPUNIT_ASSERT_EQUAL(names[i], mCharacters[i]->getName());
}
}
@@ -191,7 +176,7 @@ AccountTest::testGetCharacter1(void)
Being* merry = mAccount->getCharacter(name);
CPPUNIT_ASSERT(merry != 0);
- CPPUNIT_ASSERT_EQUAL(merry->getName(), name);
+ CPPUNIT_ASSERT_EQUAL(name, merry->getName());
}
diff --git a/src/tests/testaccount.h b/src/tests/testaccount.h
index 8806e766..fc2363c6 100644
--- a/src/tests/testaccount.h
+++ b/src/tests/testaccount.h
@@ -64,8 +64,8 @@ class AccountTest: public CppUnit::TestFixture
/**
- * Test creating an Account using the default constructor
- * and setting the account info using the mutators.
+ * Test creating an Account passing the initial account info
+ * to the constructor.
*/
void
testCreate1(void);
diff --git a/src/tests/testcipher.cpp b/src/tests/testcipher.cpp
index 0c40fdf9..d51a4404 100644
--- a/src/tests/testcipher.cpp
+++ b/src/tests/testcipher.cpp
@@ -63,7 +63,7 @@ CipherTest::testMd5_1(void)
const std::string expected("d41d8cd98f00b204e9800998ecf8427e");
std::string actual(Cipher::instance().md5(""));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -76,7 +76,7 @@ CipherTest::testMd5_2(void)
const std::string expected("0cc175b9c0f1b6a831c399e269772661");
std::string actual(Cipher::instance().md5("a"));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -89,7 +89,7 @@ CipherTest::testMd5_3(void)
const std::string expected("900150983cd24fb0d6963f7d28e17f72");
std::string actual(Cipher::instance().md5("abc"));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -102,7 +102,7 @@ CipherTest::testMd5_4(void)
const std::string expected("f96b697d7cb7938d525a2f31aaf161d0");
std::string actual(Cipher::instance().md5("message digest"));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -115,7 +115,7 @@ CipherTest::testMd5_5(void)
const std::string expected("c3fcd3d76192e4007dfb496cca67e13b");
std::string actual(Cipher::instance().md5("abcdefghijklmnopqrstuvwxyz"));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -132,7 +132,7 @@ CipherTest::testMd5_6(void)
s += "0123456789";
std::string actual(Cipher::instance().md5(s));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
@@ -150,5 +150,5 @@ CipherTest::testMd5_7(void)
}
std::string actual(Cipher::instance().md5(s));
- CPPUNIT_ASSERT_EQUAL(actual, expected);
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
}
diff --git a/src/tests/teststorage.cpp b/src/tests/teststorage.cpp
index ac831513..59a5fd4f 100644
--- a/src/tests/teststorage.cpp
+++ b/src/tests/teststorage.cpp
@@ -26,7 +26,6 @@
#include <physfs.h>
#include "../utils/cipher.h"
-
#include "../dalstoragesql.h"
#include "../storage.h"
#include "teststorage.h"
@@ -92,13 +91,13 @@ StorageTest::testGetAccount1(void)
CPPUNIT_ASSERT(myStorage.isOpen());
- Account* account = myStorage.getAccount("kindjal");
+ std::string name("frodo");
+ Account* account = myStorage.getAccount(name);
using namespace tmwserv::utils;
- std::string name("kindjal");
- std::string password(Cipher::instance().md5("kindjal"));
- std::string email("kindjal@domain");
+ std::string password(Cipher::instance().md5(name));
+ std::string email("frodo@domain");
CPPUNIT_ASSERT(account != 0);
CPPUNIT_ASSERT_EQUAL(account->getName(), name);
@@ -126,12 +125,199 @@ StorageTest::testGetAccount2(void)
/**
+ * Test passing a null pointer to addAcccount().
+ */
+void
+StorageTest::testAddAccount1(void)
+{
+ Storage& myStorage = Storage::instance(mStorageName);
+
+ if (!myStorage.isOpen()) {
+ CPPUNIT_FAIL("the storage is not opened.");
+ }
+
+ // TODO: when addAccount will throw exceptions, test the exceptions
+ // thrown.
+ // nothing should happen at the moment.
+ myStorage.addAccount(NULL);
+ myStorage.flush();
+
+#if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT) || \
+ defined (SQLITE_SUPPORT)
+
+ using namespace tmwserv::dal;
+
+ std::auto_ptr<DataProvider> db(DataProviderFactory::createDataProvider());
+
+ try {
+#ifdef SQLITE_SUPPORT
+ std::string dbFile(mStorageName);
+ dbFile += ".db";
+ db->connect(dbFile, mStorageUser, mStorageUserPassword);
+#else
+ db->connect(mStorageName, mStorageUser, mStorageUserPassword);
+#endif
+
+ std::string sql("select * from ");
+ sql += ACCOUNTS_TBL_NAME;
+ sql += ";";
+ const RecordSet& rs = db->execSql(sql);
+
+ CPPUNIT_ASSERT(rs.rows() == 3);
+
+ std::string frodo("frodo");
+ std::string merry("merry");
+ std::string pippin("pippin");
+
+ CPPUNIT_ASSERT_EQUAL(rs(0, "username"), frodo);
+ CPPUNIT_ASSERT_EQUAL(rs(1, "username"), merry);
+ CPPUNIT_ASSERT_EQUAL(rs(2, "username"), pippin);
+
+ db->disconnect();
+ }
+ catch (const DbConnectionFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const DbSqlQueryExecFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const DbDisconnectionFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const std::exception& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (...) {
+ CPPUNIT_FAIL("unexpected exception");
+ }
+#else
+ // if we are in this block it means that we are not using a database
+ // to persist the data from the storage.
+ // at the moment, Storage assume that the data are persisted in a database
+ // so let's raise a preprocessing error.
+#error "no database backend defined"
+#endif
+}
+
+
+/**
+ * Test adding a new account.
+ */
+void
+StorageTest::testAddAccount2(void)
+{
+ Storage& myStorage = Storage::instance(mStorageName);
+
+ if (!myStorage.isOpen()) {
+ CPPUNIT_FAIL("the storage is not opened.");
+ }
+
+ // prepare new account.
+ std::string sam1("sam1");
+ std::string sam2("sam2");
+ Being* b1 = new Being(sam1, 1, 1, 1, 1, 1, 1, 1, 1);
+ Being* b2 = new Being(sam2, 1, 1, 1, 1, 1, 1, 1, 1);
+ Beings characters;
+ characters.push_back(b1);
+ characters.push_back(b2);
+
+ std::string sam("sam");
+ Account* acc = new Account(sam, sam, "sam@domain", characters);
+
+ // TODO: when addAccount will throw exceptions, test the exceptions
+ // thrown.
+ myStorage.addAccount(acc);
+ myStorage.flush();
+
+#if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT) || \
+ defined (SQLITE_SUPPORT)
+
+ using namespace tmwserv::dal;
+
+ std::auto_ptr<DataProvider> db(DataProviderFactory::createDataProvider());
+
+ try {
+#ifdef SQLITE_SUPPORT
+ std::string dbFile(mStorageName);
+ dbFile += ".db";
+ db->connect(dbFile, mStorageUser, mStorageUserPassword);
+#else
+ db->connect(mStorageName, mStorageUser, mStorageUserPassword);
+#endif
+
+ std::string sql("select * from ");
+ sql += ACCOUNTS_TBL_NAME;
+ sql += ";";
+ const RecordSet& rs = db->execSql(sql);
+
+ CPPUNIT_ASSERT(rs.rows() == 4);
+
+ std::string frodo("frodo");
+ std::string merry("merry");
+ std::string pippin("pippin");
+
+ CPPUNIT_ASSERT_EQUAL(rs(0, "username"), frodo);
+ CPPUNIT_ASSERT_EQUAL(rs(1, "username"), merry);
+ CPPUNIT_ASSERT_EQUAL(rs(2, "username"), pippin);
+ CPPUNIT_ASSERT_EQUAL(rs(3, "username"), sam);
+
+ sql = "select * from ";
+ sql += CHARACTERS_TBL_NAME;
+ sql += " where user_id = '";
+ sql += sam;
+ sql += "';";
+
+ db->execSql(sql);
+
+ CPPUNIT_ASSERT(rs.rows() == 2);
+
+ CPPUNIT_ASSERT_EQUAL(rs(0, "name"), sam1);
+ CPPUNIT_ASSERT_EQUAL(rs(1, "name"), sam2);
+
+ db->disconnect();
+ }
+ catch (const DbConnectionFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const DbSqlQueryExecFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const DbDisconnectionFailure& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (const std::exception& e) {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch (...) {
+ CPPUNIT_FAIL("unexpected exception");
+ }
+#else
+ // if we are in this block it means that we are not using a database
+ // to persist the data from the storage.
+ // at the moment, Storage assume that the data are persisted in a database
+ // so let's raise a preprocessing error.
+#error "no database backend defined"
+#endif
+}
+
+
+/**
+ * Test updating an existing account.
+ */
+void
+StorageTest::testUpdAccount1(void)
+{
+ // TODO
+}
+
+
+/**
* Initialize the storage.
*/
void
StorageTest::initStorage(void)
{
-#if defined (MYSQL_SUPPORT) || defined (POSTGRE_SUPPORT) || \
+#if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT) || \
defined (SQLITE_SUPPORT)
// we are using a database to persist the data from the storage.
@@ -177,7 +363,9 @@ StorageTest::initStorage(void)
db->execSql(SQL_INVENTORIES_TABLE);
// populate the tables.
- insertAccount(db, "kindjal");
+ insertAccount(db, "frodo");
+ insertAccount(db, "merry");
+ insertAccount(db, "pippin");
db->disconnect();
}
@@ -212,7 +400,7 @@ StorageTest::initStorage(void)
void
StorageTest::cleanStorage(void)
{
-#if defined (MYSQL_SUPPORT) || defined (POSTGRE_SUPPORT) || \
+#if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT) || \
defined (SQLITE_SUPPORT)
// we are using a database to persist the data from the storage.
@@ -302,8 +490,9 @@ StorageTest::insertAccount(std::auto_ptr<DataProvider>& db,
// the password will be identical to the name.
sql << "insert into " << ACCOUNTS_TBL_NAME << " values "
- << "(null, '" << name << "', '" << name << "', '"
- << name << "@domain', 1, 0);";
+ << "(null, '" << name << "', '"
+ << tmwserv::utils::Cipher::instance().md5(name) << "', '"
+ << name << "@domain', 0, 0);";
db->execSql(sql.str());
}
diff --git a/src/tests/teststorage.h b/src/tests/teststorage.h
index f8230735..1d71a860 100644
--- a/src/tests/teststorage.h
+++ b/src/tests/teststorage.h
@@ -52,6 +52,9 @@ class StorageTest: public CppUnit::TestFixture
// add tests to the test suite.
CPPUNIT_TEST(testGetAccount1);
CPPUNIT_TEST(testGetAccount2);
+ CPPUNIT_TEST(testAddAccount1);
+ CPPUNIT_TEST(testAddAccount2);
+ CPPUNIT_TEST(testUpdAccount1);
CPPUNIT_TEST_SUITE_END();
@@ -85,6 +88,27 @@ class StorageTest: public CppUnit::TestFixture
testGetAccount2(void);
+ /**
+ * Test passing a null pointer to addAcccount().
+ */
+ void
+ testAddAccount1(void);
+
+
+ /**
+ * Test adding a new account.
+ */
+ void
+ testAddAccount2(void);
+
+
+ /**
+ * Test updating an existing account.
+ */
+ void
+ testUpdAccount1(void);
+
+
private:
/**
* Initialize the storage.