[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [KSecretService] ed2129f: Start a test for the ksecret file format
From:       Michael Leupold <lemma () confuego ! org>
Date:       2010-11-09 19:14:29
Message-ID: 20101109191429.678BDA60E9 () git ! kde ! org
[Download RAW message or body]


	A	 backend/tests/ksecrettest.h	 [License: GPL(v2)]


	A	 backend/tests/ksecrettest.cpp	 [License: GPL(v2)]

commit ed2129fb8c146c2405e63186c1e2cc428ef5c9f9
Author: Michael Leupold <lemma@confuego.org>
Date:   Sat Sep 18 14:10:46 2010 +0000

    Start a test for the ksecret file format backend for ksecretservice. In the \
process of creating it, fix some bugs and start integrating the UI.  
    svn path=/trunk/playground/base/ksecretservice/; revision=1176746

diff --git a/backend/backendmaster.cpp b/backend/backendmaster.cpp
index e0a7435..90f6905 100644
--- a/backend/backendmaster.cpp
+++ b/backend/backendmaster.cpp
@@ -25,8 +25,10 @@
 #include "ui/abstractuimanager.h"
 
 #include <QtCore/QEventLoop>
+#include <QtCore/QCoreApplication>
 
 K_GLOBAL_STATIC(BackendMaster, s_backendMaster)
+bool BackendMaster::s_initialized = false;
 
 BackendMaster::BackendMaster()
  : m_uiManager(0)
@@ -35,11 +37,16 @@ BackendMaster::BackendMaster()
 
 BackendMaster::~BackendMaster()
 {
+   qRemovePostRoutine(s_backendMaster.destroy);
    delete m_uiManager;
 }
 
 BackendMaster *BackendMaster::instance()
 {
+   if (!s_initialized) {
+      s_initialized = true;
+      qAddPostRoutine(s_backendMaster.destroy);
+   }
    return s_backendMaster;
 }
 
diff --git a/backend/backendmaster.h b/backend/backendmaster.h
index 3d8dfbb..92bca84 100644
--- a/backend/backendmaster.h
+++ b/backend/backendmaster.h
@@ -160,6 +160,7 @@ private:
    QList<BackendCollectionManager*> m_collectionManagers;
    
    AbstractUiManager *m_uiManager;
+   static bool s_initialized;
 };
 
 #endif
diff --git a/backend/ksecret/FORMAT b/backend/ksecret/FORMAT
index 0dbddce..855f0b8 100644
--- a/backend/ksecret/FORMAT
+++ b/backend/ksecret/FORMAT
@@ -127,6 +127,9 @@ part-symkey        = key-type enc-symkey
    key-type        = UINT                             ;; method for encrypting the \
key  
    enc-symkey      = BYTEARRAY                        ;; the encrypted symmetric \
master key +   
+   init-vector     = BYTEARRAY                        ;; initialization vector used \
or empty +                                                      ;; if unneeded
 
 
 Encrypted parts
diff --git a/backend/ksecret/ksecretcollection.cpp \
b/backend/ksecret/ksecretcollection.cpp index d29caef..f1e6b95 100644
--- a/backend/ksecret/ksecretcollection.cpp
+++ b/backend/ksecret/ksecretcollection.cpp
@@ -45,8 +45,22 @@ static const QString genericSavingErrorMessage()
                 "There was an error writing the ksecret file.");
 }
 
-KSecretCollection *KSecretCollection::create(const QString &id, \
                BackendCollectionManager *parent,
-                                             QString &errorMessage)
+// create a symmetric encryption key from a user-supplied password using
+// PBKDF2.
+// Returns a zero-length key if creating the key failed.
+static QCA::SymmetricKey createKeyFromPassword(const QCA::SecureArray &password,
+                                               int keyLength)
+{
+   if (!QCA::isSupported("sha1")) {
+      return QCA::SymmetricKey();
+   }
+   
+   QCA::PBKDF2 deriv("sha1");
+   return deriv.makeKey(password, QCA::InitializationVector(), keyLength, 10000);
+}
+
+KSecretCollection *KSecretCollection::create(const QString &id, const \
QCA::SecureArray &password, +                                             \
BackendCollectionManager *parent, QString &errorMessage)  {
    KSecretCollection *coll = new KSecretCollection(parent);
    coll->m_id = id;
@@ -62,24 +76,28 @@ KSecretCollection *KSecretCollection::create(const QString &id, \
BackendCollectio  // create a new symmetric key
    // TODO: is minimum() right in all cases?
    coll->m_symmetricKey = new \
QCA::SymmetricKey(coll->m_cipher->keyLength().minimum()); +   QCA::Cipher *keyCipher \
= coll->m_cipher; +   int keyLength = keyCipher->keyLength().minimum();
+   QCA::SymmetricKey keyUnlockKey = createKeyFromPassword(password, keyLength);
+   if (keyUnlockKey.isEmpty()) {
+      delete coll;
+      return 0;
+   }
    
-   // FIXME: this is bogus. Actually the unlocking method needs to be chosen.
-   //        here we just use a bogus key to encrypt the symmetric key using
-   //        blowfish.
-   QCA::SymmetricKey *keyUnlockKey = new \
QCA::SymmetricKey(QByteArray("12345678901234567890")); +   QCA::InitializationVector \
iv = QCA::InitializationVector(keyLength);  EncryptedKey *key = new EncryptedKey;
-   key->m_type = KSecretFile::KeyBogus;
-   QCA::Cipher keyCipher("blowfish", QCA::Cipher::CBC);
-   keyCipher.setup(QCA::Encode, *keyUnlockKey);
-   key->m_key.append(keyCipher.update(*coll->m_symmetricKey).toByteArray());
-   key->m_key.append(keyCipher.final().toByteArray());
+   key->m_type = KSecretFile::KeyPassword;
+   key->m_iv = iv.toByteArray();
+   keyCipher->setup(QCA::Encode, keyUnlockKey, iv);
+   key->m_key.append(keyCipher->update(*coll->m_symmetricKey).toByteArray());
+   key->m_key.append(keyCipher->final().toByteArray());
    coll->m_encryptedSymKeys.append(key);
    return coll;
 }
 
 KSecretCollection::KSecretCollection(BackendCollectionManager *parent)
  : BackendCollection(parent), m_hash(0), m_cipher(0),
-   m_symmetricKey(0)
+   m_symmetricKey(0), m_mac(0)
 {
 }
 
@@ -113,6 +131,7 @@ BackendReturn<void> KSecretCollection::setLabel(const QString \
&label)  }
    
    m_label = label;
+   emit collectionChanged(this);
    return NoError;
 }
 
@@ -129,7 +148,7 @@ QDateTime KSecretCollection::modified() const
 bool KSecretCollection::isLocked() const
 {
    // a collection is unlocked if m_cipher is initialized
-   return (m_symmetricKey != 0);
+   return (m_symmetricKey == 0);
 }
 
 BackendReturn<QList<BackendItem*> > KSecretCollection::items() const
@@ -178,7 +197,10 @@ LockCollectionJob *KSecretCollection::createLockJob()
    return new KSecretLockCollectionJob(this);
 }
 
-
+DeleteCollectionJob *KSecretCollection::createDeleteJob()
+{
+   return new KSecretDeleteCollectionJob(this);
+}
 
 BackendReturn<bool> KSecretCollection::deleteCollection()
 {
@@ -389,6 +411,12 @@ BackendReturn<bool> KSecretCollection::lock()
          // FIXME: it.value()->removeSecrets();
       }
       
+      // remove symmetric key
+      delete m_symmetricKey;
+      m_symmetricKey = 0;
+      
+      emit collectionChanged(this);
+      
       return true;
    }
 }
@@ -399,13 +427,13 @@ bool KSecretCollection::setupAlgorithms(QString &errorMessage)
    switch (m_algoHash) {
 
    case KSecretFile::SHA256:
-      if (!QCA::isSupported("sha256") || !QCA::isSupported("hmac(sha256))")) {
+      if (!QCA::isSupported("sha256") || !QCA::isSupported("hmac(sha256)")) {
          errorMessage = i18nc("Error message: unsupported hashing algorithm SHA256 \
                used",
                               "The hashing algorithm SHA256 is not supported by your \
installation.");  return false;
       }
       m_hash = new QCA::Hash("sha256");
-      m_mac = new QCA::MessageAuthenticationCode("hmac(sha256))", \
QCA::SymmetricKey()); +      m_mac = new \
QCA::MessageAuthenticationCode("hmac(sha256)", QCA::SymmetricKey());  break;
 
    default:
@@ -417,12 +445,12 @@ bool KSecretCollection::setupAlgorithms(QString &errorMessage)
    switch (m_algoCipher) {
 
    case KSecretFile::AES256:
-      if (!QCA::isSupported("aes256")) {
+      if (!QCA::isSupported("aes256-cbc-pkcs7")) {
          errorMessage = i18nc("Error message: unsupported encryption algorithm \
                AES256 used",
                               "The encryption algorithm AES256 is not suppored by \
your installation.");  return false;
       }
-      m_cipher = new QCA::Cipher("aes256", QCA::Cipher::CBC);
+      m_cipher = new QCA::Cipher("aes256", QCA::Cipher::CBC, QCA::Cipher::PKCS7);
       break;
 
    default:
@@ -819,7 +847,18 @@ bool KSecretCollection::serialize(QString &errorMessage) const
       return false;
    }
 
-   if (!serializeHeader(file) || !serializeParts(file)) {
+   if (!serializeHeader(file)) {
+      errorMessage = genericSavingErrorMessage();
+      return false;
+   }
+   
+   // collection properties
+   if (!file.writeString(m_id) || !file.writeString(m_label) ||
+       !file.writeDatetime(m_created) || !file.writeDatetime(m_modified)) {
+      return false;
+   }
+   
+   if (!serializeParts(file)) {
       errorMessage = genericSavingErrorMessage();
       return false;
    }
@@ -864,15 +903,6 @@ bool KSecretCollection::serializeParts(KSecretFile &file) const
       return false;
    }
    
-   // collection properties part
-   filePartEntries[curFilePartEntry].m_type = KSecretFile::PartCollProps;
-   filePartEntries[curFilePartEntry].m_position = (quint32)file.pos();
-   if (!file.writeString(m_id) || !file.writeString(m_label) ||
-       !file.writeDatetime(m_created) || !file.writeDatetime(m_modified)) {
-      return false;
-   }
-   curFilePartEntry++;
-
    // config part
    if (!serializeConfigPart(file, filePartEntries[curFilePartEntry])) {
       return false;
@@ -914,7 +944,8 @@ bool KSecretCollection::serializeParts(KSecretFile &file) const
    Q_FOREACH(EncryptedKey *key, m_encryptedSymKeys) {
       filePartEntries[curFilePartEntry].m_type = KSecretFile::PartSymKey;
       filePartEntries[curFilePartEntry].m_position = (quint32)file.pos();
-      if (!file.writeUint(key->m_type) || !file.writeBytearray(key->m_key)) {
+      if (!file.writeUint(key->m_type) || !file.writeBytearray(key->m_key) ||
+          !file.writeBytearray(key->m_iv)) {
          return false;
       }
       filePartEntries[curFilePartEntry].m_length =
diff --git a/backend/ksecret/ksecretcollection.h \
b/backend/ksecret/ksecretcollection.h index bfe94db..5548b12 100644
--- a/backend/ksecret/ksecretcollection.h
+++ b/backend/ksecret/ksecretcollection.h
@@ -51,6 +51,7 @@ struct EncryptedKey
 {
    quint32 m_type;
    QByteArray m_key;
+   QByteArray m_iv;
 };
 
 /**
@@ -84,12 +85,13 @@ public:
     * Create a new collection.
     *
     * @param id id for the new collection
+    * @param password password to use for encrypting the collection
     * @param parent parent collection manager
     * @param errorMessage set in case of an error
     * @return the new collection or 0 in case of an error
     */
-   static KSecretCollection *create(const QString &id, BackendCollectionManager \
                *parent,
-                                    QString &errorMessage);
+   static KSecretCollection *create(const QString &id, const QCA::SecureArray \
&password, +                                    BackendCollectionManager *parent, \
QString &errorMessage);  
    /**
     * Destructor
@@ -272,7 +274,7 @@ protected:
     * @remarks this is used by KSecretDeleteCollectionJob
     */
    BackendReturn<bool> deleteCollection();
-                                         
+
 private:
    friend class KSecretUnlockCollectionJob;
    friend class KSecretLockCollectionJob;
diff --git a/backend/ksecret/ksecretcollectionmanager.cpp \
b/backend/ksecret/ksecretcollectionmanager.cpp index 6b56d40..d2a5ef9 100644
--- a/backend/ksecret/ksecretcollectionmanager.cpp
+++ b/backend/ksecret/ksecretcollectionmanager.cpp
@@ -40,6 +40,15 @@ KSecretCollectionManager::~KSecretCollectionManager()
    // TODO: cleanup?
 }
 
+CreateCollectionJob *KSecretCollectionManager::createCreateCollectionJob(const \
QString &label, +                                                                     \
bool locked) +{
+   KSecretCreateCollectionJob *job = new KSecretCreateCollectionJob(label, locked, \
this); +   connect(job, SIGNAL(result(QueuedJob*)),
+                SLOT(createCollectionJobResult(QueuedJob*)));
+   return job;
+}
+
 void KSecretCollectionManager::addCollection(KSecretCollection *collection)
 {
    m_collections.insert(collection->path(), collection);
@@ -75,6 +84,8 @@ void KSecretCollectionManager::createCollectionJobResult(QueuedJob \
*job)  
    connect(ccj->collection(), SIGNAL(collectionDeleted(BackendCollection*)),
                               SIGNAL(collectionDeleted(BackendCollection*)));
+   connect(ccj->collection(), SIGNAL(collectionChanged(BackendCollection*)),
+                              SIGNAL(collectionChanged(BackendCollection*)));
    emit collectionCreated(ccj->collection());
 }
 
diff --git a/backend/ksecret/ksecretfile.cpp b/backend/ksecret/ksecretfile.cpp
index 7f0e76c..8ebad21 100644
--- a/backend/ksecret/ksecretfile.cpp
+++ b/backend/ksecret/ksecretfile.cpp
@@ -37,7 +37,6 @@ KSecretFile::KSecretFile(QIODevice *device, OpenMode mode)
 KSecretFile::~KSecretFile()
 {
    m_device->close();
-   delete m_device;
 }
 
 void KSecretFile::close()
@@ -84,7 +83,7 @@ bool KSecretFile::writeMagic()
       return false;
    }
    
-   if (m_device->write(KSECRET_MAGIC) != KSECRET_MAGIC_LEN) {
+   if (m_device->write(KSECRET_MAGIC, KSECRET_MAGIC_LEN) != KSECRET_MAGIC_LEN) {
       m_valid = false;
    }
    return m_valid;
diff --git a/backend/ksecret/ksecretjobs.cpp b/backend/ksecret/ksecretjobs.cpp
index 9c81fb0..7f365aa 100644
--- a/backend/ksecret/ksecretjobs.cpp
+++ b/backend/ksecret/ksecretjobs.cpp
@@ -20,9 +20,12 @@
 
 #include "ksecretjobs.h"
 
+#include <backend/backendmaster.h>
+#include <ui/abstractuimanager.h>
 #include <secrettool.h>
 
 #include <QtCore/QTimer>
+#include <klocalizedstring.h>
 
 KSecretCreateCollectionJob::KSecretCreateCollectionJob(const QString &label, bool \
                locked,
                                                        KSecretCollectionManager \
*manager) @@ -44,10 +47,36 @@ void KSecretCreateCollectionJob::exec()
 
 void KSecretCreateCollectionJob::start()
 {
+   // start a job for getting a new password for the collection from the user.
+   AbstractUiManager *uiManager = BackendMaster::instance()->uiManager();
+   AbstractNewPasswordJob *subJob = uiManager->createNewPasswordJob(label());
+   connect(subJob, SIGNAL(result(QueuedJob*)),
+                   SLOT(newPasswordJobResult(QueuedJob*)));
+   subJob->enqueue();
+}
+
+void KSecretCreateCollectionJob::newPasswordJobResult(QueuedJob *job)
+{
+   AbstractNewPasswordJob *npj = qobject_cast<AbstractNewPasswordJob*>(job);
+   Q_ASSERT(npj);
+
+   if (npj->cancelled()) {
+      setCollection(0);
+      setError(ErrorOther, i18n("Creating the collection was cancelled by the \
uesr.")); +      emitResult();
+      return;
+   }
+   
    // TODO: collection needs authentication methods, filenames, ...
    QString errorMessage;
-   KSecretCollection *coll = KSecretCollection::create(createId(), manager(),
-                                                         errorMessage);
+   KSecretCollection *coll = KSecretCollection::create(createId(), npj->password(),
+                                                       manager(), errorMessage);
+   if (!coll) {
+      setCollection(0);
+      setError(ErrorOther, errorMessage);
+      emitResult();
+      return;
+   }
    coll->setLabel(label());
    
    // NOTE: coll has to be added to m_collections before serializing it for the
@@ -152,8 +181,8 @@ void KSecretLockCollectionJob::exec()
       setResult(false);
    } else {
       setResult(true);
-      emitResult();
    }
+   emitResult();
 }
 
 KSecretDeleteCollectionJob::KSecretDeleteCollectionJob(KSecretCollection \
                *collection)
diff --git a/backend/ksecret/ksecretjobs.h b/backend/ksecret/ksecretjobs.h
index c418d9f..8bcaa84 100644
--- a/backend/ksecret/ksecretjobs.h
+++ b/backend/ksecret/ksecretjobs.h
@@ -24,7 +24,9 @@
 #include "ksecretcollectionmanager.h"
 #include "ksecretcollection.h"
 #include "ksecretitem.h"
-#include "../backendjob.h"
+
+#include <backend/backendjob.h>
+#include <ui/abstractuijobs.h>
 
 #include <QtCore/QPointer>
 
@@ -41,6 +43,9 @@ public:
    virtual bool isImmediate() const;
    virtual void exec();
    virtual void start();
+
+private Q_SLOTS:
+   void newPasswordJobResult(QueuedJob *job);
    
 private:
    KSecretCollectionManager *m_manager;
diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt
index d37fd1d..03f75e9 100644
--- a/backend/tests/CMakeLists.txt
+++ b/backend/tests/CMakeLists.txt
@@ -10,6 +10,16 @@ TARGET_LINK_LIBRARIES (ksecretservice_backend_test
 
 ADD_TEST (BackendItemCollectionHandlingTest ksecretservice_backend_test)
 
+KDE4_ADD_EXECUTABLE (ksecretservice_ksecret_test ksecrettest.cpp)
+TARGET_LINK_LIBRARIES (ksecretservice_ksecret_test
+   ksecretservicebackend
+   ksecretservicelib
+   ksecretserviceui
+   ${QT_QTTEST_LIBRARIES}
+)
+
+ADD_TEST (KSecretTest ksecretservice_ksecret_test)
+
 KDE4_ADD_EXECUTABLE (securebuffer_test securebuffertest.cpp)
 TARGET_LINK_LIBRARIES (securebuffer_test ksecretservicebackend \
${QT_QTTEST_LIBRARIES})  
diff --git a/backend/tests/ksecrettest.cpp b/backend/tests/ksecrettest.cpp
new file mode 100644
index 0000000..d79b6d2
--- /dev/null
+++ b/backend/tests/ksecrettest.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010, Dario Freddi <dario.freddi@collabora.co.uk>
+ *
+ * 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 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of 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 "ksecrettest.h"
+#include <backendmaster.h>
+#include <ksecret/ksecretcollectionmanager.h>
+#include <backendcollection.h>
+#include <backenditem.h>
+#include <ui/nouimanager.h>
+
+Q_DECLARE_METATYPE(BackendCollection*)
+Q_DECLARE_METATYPE(BackendItem*)
+
+void KSecretTest::initTestCase()
+{
+   qRegisterMetaType<BackendCollection*>();
+   qRegisterMetaType<BackendItem*>();
+   QCA::init();
+   BackendMaster *master = BackendMaster::instance();
+   master->setUiManager(new NoUiManager);
+   m_manager = new KSecretCollectionManager("/tmp", master);
+   master->addManager(m_manager);
+}
+
+void KSecretTest::testCreateCollectionAsync()
+{
+   CreateCollectionJob *createColl = m_manager->createCreateCollectionJob("test", \
false); +   QSignalSpy managerSpy(m_manager, \
SIGNAL(collectionCreated(BackendCollection*))); +   QSignalSpy \
masterSpy(BackendMaster::instance(), SIGNAL(collectionCreated(BackendCollection*))); \
+   QTestEventLoop loop; +   QVERIFY(loop.connect(createColl, \
SIGNAL(result(QueuedJob*)), SLOT(exitLoop()))); +   createColl->enqueue();
+   if (!createColl->isFinished()) {
+      loop.enterLoop(5);
+   }
+   
+   QVERIFY(createColl->isFinished());
+   QCOMPARE(createColl->error(), NoError);
+   QVERIFY(!createColl->isDismissed());
+   QVERIFY(createColl->collection() != 0);
+   
+   // Verify signals
+   QCOMPARE(managerSpy.count(), 1);
+   QCOMPARE(managerSpy.takeFirst().at(0).value<BackendCollection*>(), \
createColl->collection()); +   QCOMPARE(masterSpy.count(), 1);
+   QCOMPARE(masterSpy.takeFirst().at(0).value<BackendCollection*>(), \
createColl->collection()); +   
+   // Check the collection is present and alive
+   BackendMaster *master = BackendMaster::instance();
+   QCOMPARE(master->collections().size(), 1);
+   QCOMPARE(master->collections().first(), createColl->collection());
+   QCOMPARE(master->collections().first()->label().value(), QLatin1String("test"));
+   
+   // TODO: check collection attributes (eg. timestamps)
+   
+   // TODO: check if the collection has been written to disk
+   
+   // remember the collection
+   m_collection = createColl->collection();
+}
+
+void KSecretTest::testLockCollectionAsync()
+{
+   LockCollectionJob *lockColl = m_collection->createLockJob();
+   BackendMaster *master = BackendMaster::instance();
+   QSignalSpy masterSpy(master, SIGNAL(collectionChanged(BackendCollection*)));
+   QSignalSpy managerSpy(m_manager, SIGNAL(collectionChanged(BackendCollection*)));
+   QSignalSpy collSpy(m_collection, SIGNAL(collectionChanged(BackendCollection*)));
+   QTestEventLoop loop;
+   QVERIFY(loop.connect(lockColl, SIGNAL(result(QueuedJob*)), SLOT(exitLoop())));
+   lockColl->enqueue();
+   if (!lockColl->isFinished()) {
+      loop.enterLoop(5);
+   }
+   
+   QVERIFY(lockColl->isFinished());
+   QCOMPARE(lockColl->error(), NoError);
+   QVERIFY(!lockColl->isDismissed());
+   QVERIFY(lockColl->result());
+   QVERIFY(m_collection->isLocked());
+   
+   // Verify signals
+   QCOMPARE(managerSpy.count(), 1);
+   QCOMPARE(managerSpy.takeFirst().at(0).value<BackendCollection*>(), m_collection);
+   QCOMPARE(masterSpy.count(), 1);
+   QCOMPARE(masterSpy.takeFirst().at(0).value<BackendCollection*>(), m_collection);
+   QCOMPARE(collSpy.count(), 1);
+   QCOMPARE(collSpy.takeFirst().at(0).value<BackendCollection*>(), m_collection);
+}
+
+void KSecretTest::testUnlockCollectionAsync()
+{
+}
+
+void KSecretTest::testCreateItemAsync()
+{
+}
+
+void KSecretTest::testReplaceItemAsync()
+{
+}
+
+void KSecretTest::testDoNotReplaceItemAsync()
+{
+}
+
+void KSecretTest::testDeleteItemAsync()
+{
+}
+
+void KSecretTest::testDeleteCollectionAsync()
+{
+}
+
+void KSecretTest::cleanupTestCase()
+{
+}
+   
+QTEST_MAIN(KSecretTest)
+#include "ksecrettest.moc"
diff --git a/backend/tests/ksecrettest.h b/backend/tests/ksecrettest.h
new file mode 100644
index 0000000..0ea2a63
--- /dev/null
+++ b/backend/tests/ksecrettest.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010, Dario Freddi <dario.freddi@collabora.co.uk>
+ *
+ * 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 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of 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/>.
+ */
+
+#ifndef KSECRETTEST_H
+#define KSECRETTEST_H
+
+#include <QtTest>
+
+class BackendCollectionManager;
+class BackendCollection;
+
+class KSecretTest : public QObject
+{
+   Q_OBJECT
+   
+private Q_SLOTS:
+   void initTestCase();
+   
+   void testCreateCollectionAsync();
+   void testLockCollectionAsync();
+   void testUnlockCollectionAsync();
+   void testCreateItemAsync();
+   void testReplaceItemAsync();
+   void testDoNotReplaceItemAsync();
+   void testDeleteItemAsync();
+   void testDeleteCollectionAsync();
+
+   void cleanupTestCase();
+   
+private:
+   BackendCollectionManager *m_manager;
+   BackendCollection *m_collection;
+};
+
+#endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic