mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-24 14:59:44 -05:00
Fix parser and add unit tests.
This commit is contained in:
parent
b64dbce2da
commit
bd1ea05017
@ -13,13 +13,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
project(keepassx)
|
||||
project(KeePassX)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6.0)
|
||||
|
||||
set( keepassx_VERSION "0.9.0" )
|
||||
option(WITH_TESTS "Enable building of unit tests" ON)
|
||||
|
||||
add_Definitions(-D'KEEPASSX_VERSION="${keepassx_VERSION}"')
|
||||
set( KEEPASSX_VERSION "0.9.0" )
|
||||
|
||||
add_definitions(-DQT_NO_KEYWORDS -Wall)
|
||||
|
||||
if( APPLE OR MINGW )
|
||||
set( PROGNAME KeePassX )
|
||||
@ -27,10 +29,19 @@ else( APPLE OR MINGW )
|
||||
set( PROGNAME keepassx )
|
||||
endif( APPLE OR MINGW )
|
||||
|
||||
set(QT_MIN_VERSION "4.3.0")
|
||||
set(QT_USE_QTXML TRUE)
|
||||
if( WITH_TESTS )
|
||||
enable_testing()
|
||||
set(QT_USE_QTTEST TRUE)
|
||||
endif( WITH_TESTS )
|
||||
|
||||
set(QT_MIN_VERSION "4.6.0")
|
||||
set(QT_USE_QTMAIN TRUE)
|
||||
find_package(Qt4 REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
find_package(Automoc4 REQUIRED)
|
||||
|
||||
add_subdirectory(src)
|
||||
if( WITH_TESTS )
|
||||
add_subdirectory(tests)
|
||||
endif( WITH_TESTS )
|
||||
|
@ -13,8 +13,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
|
||||
configure_file( config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx.h )
|
||||
|
||||
set(keepassx_SOURCES
|
||||
main.cpp
|
||||
core/Database.cpp
|
||||
core/DbAttribute.cpp
|
||||
core/Entry.cpp
|
||||
@ -25,18 +28,7 @@ set(keepassx_SOURCES
|
||||
core/Uuid.cpp
|
||||
)
|
||||
|
||||
set(keepassx_HEADERS
|
||||
core/Database.h
|
||||
core/DbAttribute.h
|
||||
core/Entry.h
|
||||
core/Group.h
|
||||
core/Metadata.h
|
||||
core/Parser.h
|
||||
core/TimeInfo.h
|
||||
core/Uuid.h
|
||||
)
|
||||
automoc4_add_library( keepassx_core STATIC ${keepassx_SOURCES} )
|
||||
|
||||
qt4_wrap_cpp( keepassx_MOC ${keepassx_HEADERS} )
|
||||
|
||||
add_executable( ${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES} ${keepassx_MOC} )
|
||||
target_link_libraries( ${PROGNAME} ${QT_LIBRARIES} )
|
||||
add_executable( ${PROGNAME} WIN32 MACOSX_BUNDLE main.cpp )
|
||||
target_link_libraries( ${PROGNAME} keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} )
|
||||
|
3
src/config-keepassx.h.cmake
Normal file
3
src/config-keepassx.h.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
/* config-keepassx.h. Generated by cmake from config-keepassx.h.cmake */
|
||||
|
||||
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
|
@ -20,12 +20,12 @@
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QXmlStreamReader>
|
||||
|
||||
#include "Metadata.h"
|
||||
#include "Parser.h"
|
||||
|
||||
Database::Database(const QString& filename)
|
||||
Database::Database()
|
||||
{
|
||||
m_filename = filename;
|
||||
|
||||
m_metadata = new Metadata(this);
|
||||
}
|
||||
|
||||
Group* Database::rootGroup()
|
||||
@ -35,8 +35,8 @@ Group* Database::rootGroup()
|
||||
|
||||
void Database::setRootGroup(Group* group)
|
||||
{
|
||||
Q_ASSERT(group == 0 || group->parent() == this);
|
||||
m_rootGroup = group;
|
||||
group->setParent(this);
|
||||
}
|
||||
|
||||
Metadata* Database::metadata()
|
||||
@ -44,12 +44,6 @@ Metadata* Database::metadata()
|
||||
return m_metadata;
|
||||
}
|
||||
|
||||
void Database::open()
|
||||
{
|
||||
Parser* parser = new Parser(this);
|
||||
parser->parse(m_filename);
|
||||
}
|
||||
|
||||
QImage Database::icon(int number)
|
||||
{
|
||||
// TODO implement
|
||||
|
@ -32,7 +32,7 @@ class Database : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Database(const QString& filename);
|
||||
Database();
|
||||
Group* rootGroup();
|
||||
void setRootGroup(Group* group);
|
||||
Metadata* metadata();
|
||||
@ -42,11 +42,9 @@ public:
|
||||
Group* resolveGroup(const Uuid& uuid);
|
||||
|
||||
private:
|
||||
void open();
|
||||
Entry* recFindEntry(const Uuid& uuid, Group* group);
|
||||
Group* recFindGroup(const Uuid& uuid, Group* group);
|
||||
|
||||
QString m_filename;
|
||||
Metadata* m_metadata;
|
||||
Group* m_rootGroup;
|
||||
QHash<Uuid, QImage> m_customIcons;
|
||||
|
@ -19,8 +19,9 @@
|
||||
|
||||
#include "Group.h"
|
||||
|
||||
Entry::Entry() : m_group(0)
|
||||
Entry::Entry()
|
||||
{
|
||||
m_group = 0;
|
||||
}
|
||||
|
||||
Uuid Entry::uuid() const
|
||||
@ -31,6 +32,7 @@ Uuid Entry::uuid() const
|
||||
QImage Entry::icon() const
|
||||
{
|
||||
// TODO implement
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QColor Entry::foregroundColor() const
|
||||
@ -85,6 +87,7 @@ const QHash<QString, QByteArray>& Entry::attachments() const
|
||||
|
||||
void Entry::setUuid(const Uuid& uuid)
|
||||
{
|
||||
Q_ASSERT(!uuid.isNull());
|
||||
m_uuid = uuid;
|
||||
}
|
||||
|
||||
@ -153,7 +156,7 @@ void Entry::addAttachment(const QString& key, const QByteArray& value)
|
||||
void Entry::setGroup(Group* group)
|
||||
{
|
||||
if (m_group) {
|
||||
group->removeEntry(this);
|
||||
m_group->removeEntry(this);
|
||||
}
|
||||
group->addEntry(this);
|
||||
m_group = group;
|
||||
|
@ -22,8 +22,10 @@
|
||||
|
||||
#include "Database.h"
|
||||
|
||||
Group::Group() : m_parent(0)
|
||||
Group::Group()
|
||||
{
|
||||
m_parent = 0;
|
||||
m_db = 0;
|
||||
}
|
||||
|
||||
Uuid Group::uuid() const
|
||||
@ -118,23 +120,38 @@ void Group::setLastTopVisibleEntry(Entry* entry)
|
||||
|
||||
void Group::setParent(Group* parent)
|
||||
{
|
||||
Q_ASSERT(parent != 0);
|
||||
|
||||
if (m_parent) {
|
||||
m_parent->m_children.removeAll(this);
|
||||
}
|
||||
else if (m_db) {
|
||||
m_db->setRootGroup(0);
|
||||
}
|
||||
|
||||
m_parent = parent;
|
||||
m_db = parent->m_db;
|
||||
QObject::setParent(parent);
|
||||
|
||||
parent->m_children << this;
|
||||
}
|
||||
|
||||
void Group::setParent(Database* db)
|
||||
{
|
||||
if (m_db) {
|
||||
Q_ASSERT(db != 0);
|
||||
|
||||
if (m_parent) {
|
||||
m_parent->m_children.removeAll(this);
|
||||
}
|
||||
else if (m_db) {
|
||||
m_db->setRootGroup(0);
|
||||
}
|
||||
|
||||
m_parent = 0;
|
||||
m_db = db;
|
||||
QObject::setParent(db);
|
||||
|
||||
db->setRootGroup(this);
|
||||
}
|
||||
|
||||
QList<Group*> Group::children() const
|
||||
|
@ -17,8 +17,16 @@
|
||||
|
||||
#include "Metadata.h"
|
||||
|
||||
Metadata::Metadata()
|
||||
#include "Database.h"
|
||||
|
||||
Metadata::Metadata(Database* parent) : QObject(parent)
|
||||
{
|
||||
m_generator = "KeePassX";
|
||||
m_maintenanceHistoryDays = 365;
|
||||
m_recycleBin = 0;
|
||||
m_entryTemplatesGroup = 0;
|
||||
m_lastSelectedGroup = 0;
|
||||
m_lastTopVisibleGroup = 0;
|
||||
}
|
||||
|
||||
QString Metadata::generator() const
|
||||
@ -101,9 +109,9 @@ bool Metadata::recycleBinEnabled() const
|
||||
return m_recycleBinEnabled;
|
||||
}
|
||||
|
||||
Uuid Metadata::recycleBinUuid() const
|
||||
const Group* Metadata::recycleBin() const
|
||||
{
|
||||
return m_recycleBinUuid;
|
||||
return m_recycleBin;
|
||||
}
|
||||
|
||||
QDateTime Metadata::recycleBinChanged() const
|
||||
@ -111,7 +119,7 @@ QDateTime Metadata::recycleBinChanged() const
|
||||
return m_recycleBinChanged;
|
||||
}
|
||||
|
||||
Uuid Metadata::entryTemplatesGroup() const
|
||||
const Group* Metadata::entryTemplatesGroup() const
|
||||
{
|
||||
return m_entryTemplatesGroup;
|
||||
}
|
||||
@ -121,12 +129,12 @@ QDateTime Metadata::entryTemplatesGroupChanged() const
|
||||
return m_entryTemplatesGroupChanged;
|
||||
}
|
||||
|
||||
Uuid Metadata::lastSelectedGroup() const
|
||||
const Group* Metadata::lastSelectedGroup() const
|
||||
{
|
||||
return m_lastSelectedGroup;
|
||||
}
|
||||
|
||||
Uuid Metadata::lastTopVisibleGroup() const
|
||||
const Group* Metadata::lastTopVisibleGroup() const
|
||||
{
|
||||
return m_lastTopVisibleGroup;
|
||||
}
|
||||
@ -208,6 +216,7 @@ void Metadata::setAutoEnableVisualHiding(bool value)
|
||||
|
||||
void Metadata::addCustomIcon(const Uuid& uuid, const QImage& image)
|
||||
{
|
||||
Q_ASSERT(!uuid.isNull());
|
||||
Q_ASSERT(!m_customIcons.contains(uuid));
|
||||
|
||||
m_customIcons.insert(uuid, image);
|
||||
@ -215,6 +224,7 @@ void Metadata::addCustomIcon(const Uuid& uuid, const QImage& image)
|
||||
|
||||
void Metadata::removeCustomIcon(const Uuid& uuid)
|
||||
{
|
||||
Q_ASSERT(!uuid.isNull());
|
||||
Q_ASSERT(m_customIcons.contains(uuid));
|
||||
|
||||
m_customIcons.remove(uuid);
|
||||
@ -225,9 +235,9 @@ void Metadata::setRecycleBinEnabled(bool value)
|
||||
m_recycleBinEnabled = value;
|
||||
}
|
||||
|
||||
void Metadata::setRecycleBinUuid(const Uuid& value)
|
||||
void Metadata::setRecycleBin(Group* group)
|
||||
{
|
||||
m_recycleBinUuid = value;
|
||||
m_recycleBin = group;
|
||||
}
|
||||
|
||||
void Metadata::setRecycleBinChanged(const QDateTime& value)
|
||||
@ -235,9 +245,9 @@ void Metadata::setRecycleBinChanged(const QDateTime& value)
|
||||
m_recycleBinChanged = value;
|
||||
}
|
||||
|
||||
void Metadata::setEntryTemplatesGroup(const Uuid& value)
|
||||
void Metadata::setEntryTemplatesGroup(Group* group)
|
||||
{
|
||||
m_entryTemplatesGroup = value;
|
||||
m_entryTemplatesGroup = group;
|
||||
}
|
||||
|
||||
void Metadata::setEntryTemplatesGroupChanged(const QDateTime& value)
|
||||
@ -245,14 +255,14 @@ void Metadata::setEntryTemplatesGroupChanged(const QDateTime& value)
|
||||
m_entryTemplatesGroupChanged = value;
|
||||
}
|
||||
|
||||
void Metadata::setLastSelectedGroup(const Uuid& value)
|
||||
void Metadata::setLastSelectedGroup(Group* group)
|
||||
{
|
||||
m_lastSelectedGroup = value;
|
||||
m_lastSelectedGroup = group;
|
||||
}
|
||||
|
||||
void Metadata::setLastTopVisibleGroup(const Uuid& value)
|
||||
void Metadata::setLastTopVisibleGroup(Group* group)
|
||||
{
|
||||
m_lastTopVisibleGroup = value;
|
||||
m_lastTopVisibleGroup = group;
|
||||
}
|
||||
|
||||
void Metadata::addCustomField(const QString& key, const QString& value)
|
||||
|
@ -24,10 +24,15 @@
|
||||
#include <QtCore/QHash>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
class Metadata
|
||||
class Database;
|
||||
class Group;
|
||||
|
||||
class Metadata : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Metadata();
|
||||
Metadata(Database* parent);
|
||||
|
||||
QString generator() const;
|
||||
QString name() const;
|
||||
@ -45,12 +50,12 @@ public:
|
||||
bool autoEnableVisualHiding() const;
|
||||
QHash<Uuid, QImage> customIcons() const;
|
||||
bool recycleBinEnabled() const;
|
||||
Uuid recycleBinUuid() const;
|
||||
const Group* recycleBin() const;
|
||||
QDateTime recycleBinChanged() const;
|
||||
Uuid entryTemplatesGroup() const;
|
||||
const Group* entryTemplatesGroup() const;
|
||||
QDateTime entryTemplatesGroupChanged() const;
|
||||
Uuid lastSelectedGroup() const;
|
||||
Uuid lastTopVisibleGroup() const;
|
||||
const Group* lastSelectedGroup() const;
|
||||
const Group* lastTopVisibleGroup() const;
|
||||
QHash<QString, QString> customFields() const;
|
||||
|
||||
void setGenerator(const QString& value);
|
||||
@ -70,12 +75,12 @@ public:
|
||||
void addCustomIcon(const Uuid& uuid, const QImage& image);
|
||||
void removeCustomIcon(const Uuid& uuid);
|
||||
void setRecycleBinEnabled(bool value);
|
||||
void setRecycleBinUuid(const Uuid& value);
|
||||
void setRecycleBin(Group* group);
|
||||
void setRecycleBinChanged(const QDateTime& value);
|
||||
void setEntryTemplatesGroup(const Uuid& value);
|
||||
void setEntryTemplatesGroup(Group* group);
|
||||
void setEntryTemplatesGroupChanged(const QDateTime& value);
|
||||
void setLastSelectedGroup(const Uuid& value);
|
||||
void setLastTopVisibleGroup(const Uuid& value);
|
||||
void setLastSelectedGroup(Group* group);
|
||||
void setLastTopVisibleGroup(Group* group);
|
||||
void addCustomField(const QString& key, const QString& value);
|
||||
void removeCustomField(const QString& key);
|
||||
|
||||
@ -99,12 +104,12 @@ private:
|
||||
QHash<Uuid, QImage> m_customIcons;
|
||||
|
||||
bool m_recycleBinEnabled;
|
||||
Uuid m_recycleBinUuid;
|
||||
Group* m_recycleBin;
|
||||
QDateTime m_recycleBinChanged;
|
||||
Uuid m_entryTemplatesGroup;
|
||||
Group* m_entryTemplatesGroup;
|
||||
QDateTime m_entryTemplatesGroupChanged;
|
||||
Uuid m_lastSelectedGroup;
|
||||
Uuid m_lastTopVisibleGroup;
|
||||
Group* m_lastSelectedGroup;
|
||||
Group* m_lastTopVisibleGroup;
|
||||
|
||||
QHash<QString, QString> m_customFields;
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "Parser.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFile>
|
||||
|
||||
#include "Database.h"
|
||||
@ -35,24 +36,31 @@ bool Parser::parse(const QString& filename)
|
||||
m_xml.setDevice(&file);
|
||||
|
||||
m_tmpParent = new Group();
|
||||
m_tmpParent->setParent(m_db);
|
||||
|
||||
if (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||
if (m_xml.name() == "KeePassFile") {
|
||||
parseKeePassFile();
|
||||
}
|
||||
else {
|
||||
raiseError();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_tmpParent->children().isEmpty()) {
|
||||
delete m_tmpParent;
|
||||
if (!m_xml.error() && !m_tmpParent->children().isEmpty()) {
|
||||
raiseError();
|
||||
}
|
||||
|
||||
delete m_tmpParent;
|
||||
|
||||
return !m_xml.error();
|
||||
}
|
||||
|
||||
QString Parser::errorMsg()
|
||||
{
|
||||
return QString("%1\nLine %2, column %3")
|
||||
.arg(m_xml.errorString())
|
||||
.arg(m_xml.lineNumber())
|
||||
.arg(m_xml.columnNumber());
|
||||
}
|
||||
|
||||
void Parser::parseKeePassFile()
|
||||
{
|
||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "KeePassFile");
|
||||
@ -65,7 +73,7 @@ void Parser::parseKeePassFile()
|
||||
parseRoot();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,28 +117,28 @@ void Parser::parseMeta()
|
||||
m_meta->setRecycleBinEnabled(readBool());
|
||||
}
|
||||
else if (m_xml.name() == "RecycleBinUUID") {
|
||||
m_meta->setRecycleBinUuid(readUuid());
|
||||
m_meta->setRecycleBin(getGroup(readUuid()));
|
||||
}
|
||||
else if (m_xml.name() == "RecycleBinChanged") {
|
||||
m_meta->setRecycleBinChanged(readDateTime());
|
||||
}
|
||||
else if (m_xml.name() == "EntryTemplatesGroup") {
|
||||
m_meta->setEntryTemplatesGroup(readUuid());
|
||||
m_meta->setEntryTemplatesGroup(getGroup(readUuid()));
|
||||
}
|
||||
else if (m_xml.name() == "EntryTemplatesGroupChanged") {
|
||||
m_meta->setEntryTemplatesGroupChanged(readDateTime());
|
||||
}
|
||||
else if (m_xml.name() == "LastSelectedGroup") {
|
||||
m_meta->setLastSelectedGroup(readUuid());
|
||||
m_meta->setLastSelectedGroup(getGroup(readUuid()));
|
||||
}
|
||||
else if (m_xml.name() == "LastTopVisibleGroup") {
|
||||
m_meta->setLastTopVisibleGroup(readUuid());
|
||||
m_meta->setLastTopVisibleGroup(getGroup(readUuid()));
|
||||
}
|
||||
else if (m_xml.name() == "CustomData") {
|
||||
parseCustomData();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +167,7 @@ void Parser::parseMemoryProtection()
|
||||
m_meta->setAutoEnableVisualHiding(readBool());
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,7 +181,7 @@ void Parser::parseCustomIcons()
|
||||
parseIcon();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,7 +201,7 @@ void Parser::parseIcon()
|
||||
m_meta->addCustomIcon(uuid, image);
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,7 +210,10 @@ void Parser::parseCustomData()
|
||||
{
|
||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "CustomData");
|
||||
|
||||
// TODO
|
||||
// TODO implement
|
||||
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::parseRoot()
|
||||
@ -218,9 +229,10 @@ void Parser::parseRoot()
|
||||
}
|
||||
else if (m_xml.name() == "DeletedObjects") {
|
||||
// TODO implement
|
||||
skipCurrentElement();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,7 +249,7 @@ Group* Parser::parseGroup()
|
||||
raiseError();
|
||||
}
|
||||
else {
|
||||
group = getGroup(uuid);
|
||||
group = getGroup(uuid);
|
||||
}
|
||||
}
|
||||
else if (m_xml.name() == "Name") {
|
||||
@ -268,16 +280,14 @@ Group* Parser::parseGroup()
|
||||
}
|
||||
else if (m_xml.name() == "EnableAutoType") {
|
||||
// TODO implement
|
||||
skipCurrentElement();
|
||||
}
|
||||
else if (m_xml.name() == "EnableSearching") {
|
||||
// TODO implement
|
||||
skipCurrentElement();
|
||||
}
|
||||
else if (m_xml.name() == "LastTopVisibleEntry") {
|
||||
Uuid uuid = readUuid();
|
||||
if (uuid.isNull())
|
||||
group->setLastTopVisibleEntry(0);
|
||||
else
|
||||
group->setLastTopVisibleEntry(getEntry(uuid));
|
||||
group->setLastTopVisibleEntry(getEntry(readUuid()));
|
||||
}
|
||||
else if (m_xml.name() == "Group") {
|
||||
Group* newGroup = parseGroup();
|
||||
@ -292,7 +302,7 @@ Group* Parser::parseGroup()
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,9 +359,11 @@ Entry* Parser::parseEntry()
|
||||
parseEntryHistory();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void Parser::parseEntryString(Entry *entry)
|
||||
@ -367,7 +379,7 @@ void Parser::parseEntryString(Entry *entry)
|
||||
entry->addAttribute(key, readString());
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,7 +397,7 @@ void Parser::parseEntryBinary(Entry *entry)
|
||||
entry->addAttachment(key, readBinary());
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -408,7 +420,7 @@ void Parser::parseAutoType(Entry* entry)
|
||||
parseAutoTypeAssoc(entry);
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -427,7 +439,7 @@ void Parser::parseAutoTypeAssoc(Entry *entry)
|
||||
entry->addAutoTypeAssociation(assoc);
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -439,9 +451,10 @@ void Parser::parseEntryHistory()
|
||||
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||
if (m_xml.name() == "Entry") {
|
||||
// TODO implement
|
||||
skipCurrentElement();
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -474,7 +487,7 @@ TimeInfo Parser::parseTimes()
|
||||
timeInfo.setLocationChanged(readDateTime());
|
||||
}
|
||||
else {
|
||||
m_xml.skipCurrentElement();
|
||||
skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
@ -490,14 +503,15 @@ bool Parser::readBool()
|
||||
{
|
||||
QString str = readString();
|
||||
|
||||
if (str == "True") {
|
||||
if (str.compare(QLatin1String("True"), Qt::CaseInsensitive) == 0) {
|
||||
return true;
|
||||
}
|
||||
else if (str == "False") {
|
||||
else if (str.compare(QLatin1String("False"), Qt::CaseInsensitive) == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
raiseError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,6 +530,11 @@ QDateTime Parser::readDateTime()
|
||||
QColor Parser::readColor()
|
||||
{
|
||||
QString colorStr = readString();
|
||||
|
||||
if (colorStr.isEmpty()) {
|
||||
return QColor();
|
||||
}
|
||||
|
||||
if (colorStr.length() != 7 || colorStr[0] != '#') {
|
||||
raiseError();
|
||||
return QColor();
|
||||
@ -525,7 +544,7 @@ QColor Parser::readColor()
|
||||
for (int i=0; i<= 2; i++) {
|
||||
QString rgbPartStr = colorStr.mid(1 + 2*i, 2);
|
||||
bool ok;
|
||||
int rgbPart = rgbPartStr.toInt(&ok);
|
||||
int rgbPart = rgbPartStr.toInt(&ok, 16);
|
||||
if (!ok || rgbPart > 255) {
|
||||
raiseError();
|
||||
return QColor();
|
||||
@ -563,7 +582,7 @@ Uuid Parser::readUuid()
|
||||
return Uuid();
|
||||
}
|
||||
else {
|
||||
return Uuid(readBinary());
|
||||
return Uuid(uuidBin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,6 +593,10 @@ QByteArray Parser::readBinary()
|
||||
|
||||
Group* Parser::getGroup(const Uuid& uuid)
|
||||
{
|
||||
if (uuid.isNull()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Q_FOREACH (Group* group, m_groups) {
|
||||
if (group->uuid() == uuid) {
|
||||
return group;
|
||||
@ -589,6 +612,10 @@ Group* Parser::getGroup(const Uuid& uuid)
|
||||
|
||||
Entry* Parser::getEntry(const Uuid& uuid)
|
||||
{
|
||||
if (uuid.isNull()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Q_FOREACH (Entry* entry, m_entries) {
|
||||
if (entry->uuid() == uuid) {
|
||||
return entry;
|
||||
@ -606,3 +633,9 @@ void Parser::raiseError()
|
||||
{
|
||||
m_xml.raiseError(tr("Invalid database file"));
|
||||
}
|
||||
|
||||
void Parser::skipCurrentElement()
|
||||
{
|
||||
qDebug() << "Parser::skipCurrentElement(): skip: " << m_xml.name();
|
||||
m_xml.skipCurrentElement();
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class Parser : public QObject
|
||||
public:
|
||||
Parser(Database* db);
|
||||
bool parse(const QString& filename);
|
||||
QString errorMsg();
|
||||
|
||||
private:
|
||||
void parseKeePassFile();
|
||||
@ -66,6 +67,7 @@ private:
|
||||
Group* getGroup(const Uuid& uuid);
|
||||
Entry* getEntry(const Uuid& uuid);
|
||||
void raiseError();
|
||||
void skipCurrentElement();
|
||||
|
||||
QXmlStreamReader m_xml;
|
||||
Database* m_db;
|
||||
|
@ -39,10 +39,9 @@ Uuid::Uuid(const QByteArray& data)
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
|
||||
QString Uuid::toString() const
|
||||
QString Uuid::toBase64() const
|
||||
{
|
||||
return m_data.toHex();
|
||||
return m_data.toBase64();
|
||||
}
|
||||
|
||||
QByteArray Uuid::toByteArray() const
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
Uuid();
|
||||
Uuid(bool generate);
|
||||
Uuid(const QByteArray& data);
|
||||
QString toString() const;
|
||||
QString toBase64() const;
|
||||
QByteArray toByteArray() const;
|
||||
bool isNull() const;
|
||||
bool operator==(const Uuid& other) const;
|
||||
|
70
tests/CMakeLists.txt
Normal file
70
tests/CMakeLists.txt
Normal file
@ -0,0 +1,70 @@
|
||||
# Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
#
|
||||
# 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 2 or (at your option)
|
||||
# version 3 of the License.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
set( KEEPASSX_TEST_TREE ${CMAKE_SOURCE_DIR}/tests )
|
||||
configure_file( config-keepassx-tests.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepassx-tests.h )
|
||||
|
||||
macro (ADD_UNIT_TEST _test_NAME)
|
||||
set(_srcList ${ARGN})
|
||||
set(_targetName ${_test_NAME})
|
||||
if( ${ARGV1} STREQUAL "TESTNAME" )
|
||||
set(_targetName ${ARGV2})
|
||||
list(REMOVE_AT _srcList 0 1)
|
||||
endif( ${ARGV1} STREQUAL "TESTNAME" )
|
||||
|
||||
set(_nogui)
|
||||
list(GET ${_srcList} 0 first_PARAM)
|
||||
if( ${first_PARAM} STREQUAL "NOGUI" )
|
||||
set(_nogui "NOGUI")
|
||||
endif( ${first_PARAM} STREQUAL "NOGUI" )
|
||||
|
||||
automoc4_add_executable( ${_test_NAME} ${_srcList} )
|
||||
|
||||
if(NOT TEST_OUTPUT)
|
||||
set(TEST_OUTPUT plaintext)
|
||||
endif(NOT TEST_OUTPUT)
|
||||
set(TEST_OUTPUT ${TEST_OUTPUT} CACHE STRING "The output to generate when running the QTest unit tests")
|
||||
|
||||
get_target_property( loc ${_test_NAME} LOCATION )
|
||||
|
||||
if (KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
add_test( ${_targetName} ${loc} -xml -o ${_targetName}.tml)
|
||||
else (KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
add_test( ${_targetName} ${loc} )
|
||||
endif (KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
|
||||
if (NOT MSVC_IDE) #not needed for the ide
|
||||
# if the tests are EXCLUDE_FROM_ALL, add a target "buildtests" to build all tests
|
||||
if (NOT WITH_TESTS)
|
||||
get_directory_property(_buildtestsAdded BUILDTESTS_ADDED)
|
||||
if(NOT _buildtestsAdded)
|
||||
add_custom_target(buildtests)
|
||||
set_directory_properties(PROPERTIES BUILDTESTS_ADDED TRUE)
|
||||
endif(NOT _buildtestsAdded)
|
||||
add_dependencies(buildtests ${_test_NAME})
|
||||
endif (NOT WITH_TESTS)
|
||||
endif (NOT MSVC_IDE)
|
||||
|
||||
endmacro (ADD_UNIT_TEST)
|
||||
|
||||
|
||||
add_unit_test( testparser TestParser.cpp )
|
||||
target_link_libraries( testparser keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} )
|
||||
|
||||
add_unit_test( testgroup TestGroup.cpp )
|
||||
target_link_libraries( testgroup keepassx_core ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} )
|
287
tests/NewDatabase.xml
Normal file
287
tests/NewDatabase.xml
Normal file
@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<KeePassFile>
|
||||
<Meta>
|
||||
<Generator>KeePass</Generator>
|
||||
<DatabaseName>ANAME</DatabaseName>
|
||||
<DatabaseNameChanged>2010-08-08T17:24:53Z</DatabaseNameChanged>
|
||||
<DatabaseDescription>ADESC</DatabaseDescription>
|
||||
<DatabaseDescriptionChanged>2010-08-08T17:27:12Z</DatabaseDescriptionChanged>
|
||||
<DefaultUserName>DEFUSERNAME</DefaultUserName>
|
||||
<DefaultUserNameChanged>2010-08-08T17:27:45Z</DefaultUserNameChanged>
|
||||
<MaintenanceHistoryDays>127</MaintenanceHistoryDays>
|
||||
<MemoryProtection>
|
||||
<ProtectTitle>False</ProtectTitle>
|
||||
<ProtectUserName>True</ProtectUserName>
|
||||
<ProtectPassword>False</ProtectPassword>
|
||||
<ProtectURL>True</ProtectURL>
|
||||
<ProtectNotes>False</ProtectNotes>
|
||||
<AutoEnableVisualHiding>True</AutoEnableVisualHiding>
|
||||
</MemoryProtection>
|
||||
<RecycleBinEnabled>True</RecycleBinEnabled>
|
||||
<RecycleBinUUID>7PAwxNhPaE2klutz45i2xg==</RecycleBinUUID>
|
||||
<RecycleBinChanged>2010-08-08T17:24:17Z</RecycleBinChanged>
|
||||
<EntryTemplatesGroup>AAAAAAAAAAAAAAAAAAAAAA==</EntryTemplatesGroup>
|
||||
<EntryTemplatesGroupChanged>2010-08-08T17:24:19Z</EntryTemplatesGroupChanged>
|
||||
<LastSelectedGroup>zKuE27EWr0mlU75b2SRkTQ==</LastSelectedGroup>
|
||||
<LastTopVisibleGroup>zKuE27EWr0mlU75b2SRkTQ==</LastTopVisibleGroup>
|
||||
<CustomData />
|
||||
</Meta>
|
||||
<Root>
|
||||
<Group>
|
||||
<UUID>zKuE27EWr0mlU75b2SRkTQ==</UUID>
|
||||
<Name>NewDatabase</Name>
|
||||
<Notes />
|
||||
<IconID>49</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:27Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:27Z</CreationTime>
|
||||
<LastAccessTime>2010-08-09T09:09:44Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>2</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:27Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>QW4G0r/z90qql4iKZ0RwlA==</LastTopVisibleEntry>
|
||||
<Entry>
|
||||
<UUID>QW4G0r/z90qql4iKZ0RwlA==</UUID>
|
||||
<IconID>0</IconID>
|
||||
<ForegroundColor>#0000FF</ForegroundColor>
|
||||
<BackgroundColor>#000000</BackgroundColor>
|
||||
<OverrideURL>OMGAURL</OverrideURL>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-09T09:09:31Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-09T09:09:31Z</LastAccessTime>
|
||||
<ExpiryTime>2011-08-08T17:25:58Z</ExpiryTime>
|
||||
<Expires>True</Expires>
|
||||
<UsageCount>6</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<String>
|
||||
<Key>customfield</Key>
|
||||
<Value>customfield value</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>Notes</Key>
|
||||
<Value>Notes</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>Password</Key>
|
||||
<Value>Password</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>Title</Key>
|
||||
<Value>Sample Entry</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>URL</Key>
|
||||
<Value>bleh</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>UserName</Key>
|
||||
<Value>User Name</Value>
|
||||
</String>
|
||||
<AutoType>
|
||||
<Enabled>True</Enabled>
|
||||
<DataTransferObfuscation>1</DataTransferObfuscation>
|
||||
<DefaultSequence>{USERNAME}{TAB}{PASSWORD}{ENTER}</DefaultSequence>
|
||||
<Association>
|
||||
<Window>Target Window</Window>
|
||||
<KeystrokeSequence>{USERNAME}{TAB}{PASSWORD}{TAB}{ENTER}</KeystrokeSequence>
|
||||
</Association>
|
||||
<Association>
|
||||
<Window>Edit Entry</Window>
|
||||
<KeystrokeSequence>{Title}{UserName}{UserName}</KeystrokeSequence>
|
||||
</Association>
|
||||
</AutoType>
|
||||
<History />
|
||||
</Entry>
|
||||
<Group>
|
||||
<UUID>abLbFtNUfEi5TmbaxiW6yg==</UUID>
|
||||
<Name>General</Name>
|
||||
<Notes />
|
||||
<IconID>48</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>u1lTRAICOkWv5QSl2xyU8w==</UUID>
|
||||
<Name>Windows</Name>
|
||||
<Notes />
|
||||
<IconID>38</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>bFe1/LfewEuvlTsT8nJRRg==</UUID>
|
||||
<Name>Network</Name>
|
||||
<Notes />
|
||||
<IconID>3</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>wHmj/+6vTkOpG/eeVp3yjg==</UUID>
|
||||
<Name>Internet</Name>
|
||||
<Notes />
|
||||
<IconID>1</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>9QLqqFgc5EC7ptm2TI1hDA==</UUID>
|
||||
<Name>eMail</Name>
|
||||
<Notes />
|
||||
<IconID>19</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>wQru0ArOaEOy0uUio3subA==</UUID>
|
||||
<Name>Homebanking</Name>
|
||||
<Notes />
|
||||
<IconID>37</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-08T17:24:53Z</LastModificationTime>
|
||||
<CreationTime>2010-08-08T17:24:53Z</CreationTime>
|
||||
<LastAccessTime>2010-08-08T17:24:53Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-08T17:24:17Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>0</UsageCount>
|
||||
<LocationChanged>2010-08-08T17:24:53Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>null</EnableAutoType>
|
||||
<EnableSearching>null</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
</Group>
|
||||
<Group>
|
||||
<UUID>7PAwxNhPaE2klutz45i2xg==</UUID>
|
||||
<Name>Recycle Bin</Name>
|
||||
<Notes />
|
||||
<IconID>43</IconID>
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-09T09:09:44Z</LastModificationTime>
|
||||
<CreationTime>2010-08-09T09:09:44Z</CreationTime>
|
||||
<LastAccessTime>2010-08-09T09:09:44Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-09T09:07:16Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>1</UsageCount>
|
||||
<LocationChanged>2010-08-09T09:09:44Z</LocationChanged>
|
||||
</Times>
|
||||
<IsExpanded>True</IsExpanded>
|
||||
<DefaultAutoTypeSequence />
|
||||
<EnableAutoType>false</EnableAutoType>
|
||||
<EnableSearching>false</EnableSearching>
|
||||
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
|
||||
<Entry>
|
||||
<UUID>KIeQe6yDN0SbjIJ83NB++Q==</UUID>
|
||||
<IconID>0</IconID>
|
||||
<ForegroundColor />
|
||||
<BackgroundColor />
|
||||
<OverrideURL />
|
||||
<Times>
|
||||
<LastModificationTime>2010-08-09T09:09:40Z</LastModificationTime>
|
||||
<CreationTime>2010-08-09T09:09:37Z</CreationTime>
|
||||
<LastAccessTime>2010-08-09T09:09:44Z</LastAccessTime>
|
||||
<ExpiryTime>2010-08-09T09:07:16Z</ExpiryTime>
|
||||
<Expires>False</Expires>
|
||||
<UsageCount>2</UsageCount>
|
||||
<LocationChanged>2010-08-09T09:09:44Z</LocationChanged>
|
||||
</Times>
|
||||
<String>
|
||||
<Key>Notes</Key>
|
||||
<Value />
|
||||
</String>
|
||||
<String>
|
||||
<Key>Password</Key>
|
||||
<Value>5Ciyy3kcVSPFUFqTuK1o</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>Title</Key>
|
||||
<Value>test</Value>
|
||||
</String>
|
||||
<String>
|
||||
<Key>URL</Key>
|
||||
<Value />
|
||||
</String>
|
||||
<String>
|
||||
<Key>UserName</Key>
|
||||
<Value>DEFUSERNAME</Value>
|
||||
</String>
|
||||
<AutoType>
|
||||
<Enabled>True</Enabled>
|
||||
<DataTransferObfuscation>0</DataTransferObfuscation>
|
||||
</AutoType>
|
||||
<History />
|
||||
</Entry>
|
||||
</Group>
|
||||
</Group>
|
||||
<DeletedObjects />
|
||||
</Root>
|
||||
</KeePassFile>
|
68
tests/TestGroup.cpp
Normal file
68
tests/TestGroup.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#include "core/Database.h"
|
||||
|
||||
class TestGroup : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void testParenting();
|
||||
};
|
||||
|
||||
void TestGroup::testParenting()
|
||||
{
|
||||
Database* db = new Database();
|
||||
Group* tmpRoot = new Group();
|
||||
tmpRoot->setParent(db);
|
||||
|
||||
Group* g1 = new Group();
|
||||
Group* g2 = new Group();
|
||||
Group* g3 = new Group();
|
||||
Group* g4 = new Group();
|
||||
g1->setParent(tmpRoot);
|
||||
g2->setParent(tmpRoot);
|
||||
g3->setParent(tmpRoot);
|
||||
g4->setParent(tmpRoot);
|
||||
|
||||
g2->setParent(g1);
|
||||
g4->setParent(g3);
|
||||
g3->setParent(g1);
|
||||
g1->setParent(db);
|
||||
|
||||
QVERIFY(g1->parent() == db);
|
||||
QVERIFY(g2->parent() == g1);
|
||||
QVERIFY(g3->parent() == g1);
|
||||
QVERIFY(g4->parent() == g3);
|
||||
|
||||
QVERIFY(tmpRoot->children().size() == 0);
|
||||
QVERIFY(g1->children().size() == 2);
|
||||
QVERIFY(g2->children().size() == 0);
|
||||
QVERIFY(g3->children().size() == 1);
|
||||
QVERIFY(g4->children().size() == 0);
|
||||
|
||||
QVERIFY(g1->children().contains(g2));
|
||||
QVERIFY(g1->children().contains(g3));
|
||||
QVERIFY(g3->children().contains(g4));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestGroup);
|
||||
|
||||
#include "TestGroup.moc"
|
92
tests/TestParser.cpp
Normal file
92
tests/TestParser.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* 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 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#include "core/Database.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/Parser.h"
|
||||
#include "config-keepassx-tests.h"
|
||||
|
||||
class TestParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testMetadata();
|
||||
void testGroups();
|
||||
|
||||
private:
|
||||
QDateTime genDT(int year, int month, int day, int hour, int min, int second);
|
||||
|
||||
Database* m_db;
|
||||
};
|
||||
|
||||
QDateTime TestParser::genDT(int year, int month, int day, int hour, int min, int second)
|
||||
{
|
||||
QDate date(year, month, day);
|
||||
QTime time(hour, min, second);
|
||||
return QDateTime(date, time, Qt::UTC);
|
||||
}
|
||||
|
||||
void TestParser::initTestCase()
|
||||
{
|
||||
m_db = new Database();
|
||||
Parser* parser = new Parser(m_db);
|
||||
QString xmlFile = QString(KEEPASSX_TEST_DIR).append("/NewDatabase.xml");
|
||||
QVERIFY(parser->parse(xmlFile));
|
||||
}
|
||||
|
||||
void TestParser::testMetadata()
|
||||
{
|
||||
QCOMPARE(m_db->metadata()->generator(), QLatin1String("KeePass"));
|
||||
QCOMPARE(m_db->metadata()->name(), QLatin1String("ANAME"));
|
||||
QCOMPARE(m_db->metadata()->nameChanged(), genDT(2010, 8, 8, 17, 24, 53));
|
||||
QCOMPARE(m_db->metadata()->description(), QLatin1String("ADESC"));
|
||||
QCOMPARE(m_db->metadata()->descriptionChanged(), genDT(2010, 8, 8, 17, 27, 12));
|
||||
QCOMPARE(m_db->metadata()->defaultUserName(), QLatin1String("DEFUSERNAME"));
|
||||
QCOMPARE(m_db->metadata()->defaultUserNameChanged(), genDT(2010, 8, 8, 17, 27, 45));
|
||||
QCOMPARE(m_db->metadata()->maintenanceHistoryDays(), 127);
|
||||
QCOMPARE(m_db->metadata()->protectTitle(), false);
|
||||
QCOMPARE(m_db->metadata()->protectUsername(), true);
|
||||
QCOMPARE(m_db->metadata()->protectPassword(), false);
|
||||
QCOMPARE(m_db->metadata()->protectUrl(), true);
|
||||
QCOMPARE(m_db->metadata()->protectNotes(), false);
|
||||
QCOMPARE(m_db->metadata()->autoEnableVisualHiding(), true);
|
||||
QCOMPARE(m_db->metadata()->recycleBinEnabled(), true);
|
||||
QVERIFY(m_db->metadata()->recycleBin() != 0);
|
||||
QCOMPARE(m_db->metadata()->recycleBin()->name(), QLatin1String("Recycle Bin"));
|
||||
QCOMPARE(m_db->metadata()->recycleBinChanged(), genDT(2010, 8, 8, 17, 24, 17));
|
||||
QVERIFY(m_db->metadata()->entryTemplatesGroup() == 0);
|
||||
QCOMPARE(m_db->metadata()->entryTemplatesGroupChanged(), genDT(2010, 8, 8, 17, 24, 19));
|
||||
QVERIFY(m_db->metadata()->lastSelectedGroup() != 0);
|
||||
QCOMPARE(m_db->metadata()->lastSelectedGroup()->name(), QLatin1String("NewDatabase"));
|
||||
QVERIFY(m_db->metadata()->lastTopVisibleGroup() != 0);
|
||||
QCOMPARE(m_db->metadata()->lastTopVisibleGroup()->name(), QLatin1String("NewDatabase"));
|
||||
}
|
||||
|
||||
void TestParser::testGroups()
|
||||
{
|
||||
QVERIFY(m_db->rootGroup()->name() == QLatin1String("NewDatabase"));
|
||||
QVERIFY(m_db->rootGroup()->uuid().toBase64() == QLatin1String("zKuE27EWr0mlU75b2SRkTQ=="));
|
||||
QVERIFY(m_db->rootGroup()->isExpanded() == true);
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestParser);
|
||||
|
||||
#include "TestParser.moc"
|
3
tests/config-keepassx-tests.h.cmake
Normal file
3
tests/config-keepassx-tests.h.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
/* config-keepassx-tests.h. Generated by cmake from config-keepassx-tests.h.cmake */
|
||||
|
||||
#define KEEPASSX_TEST_DIR "${KEEPASSX_TEST_TREE}"
|
Loading…
Reference in New Issue
Block a user