2014-06-23 16:01:45 +00:00
|
|
|
# -*- encoding: utf-8 -*-
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
2014-06-28 16:21:44 +00:00
|
|
|
import unittest
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-23 16:01:45 +00:00
|
|
|
from isso import config
|
2014-06-27 09:24:02 +00:00
|
|
|
from isso.db import SQLite3, Adapter
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-04-20 13:39:43 +00:00
|
|
|
from isso.compat import iteritems
|
|
|
|
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
class TestSQLite3(unittest.TestCase):
|
|
|
|
|
|
|
|
def test_connection(self):
|
|
|
|
con = SQLite3(":memory:")
|
|
|
|
|
|
|
|
con.connect()
|
|
|
|
self.assertTrue(hasattr(con.local, "conn"))
|
|
|
|
|
|
|
|
con.close()
|
|
|
|
self.assertIsNone(con.local.conn)
|
|
|
|
|
|
|
|
def test_autoconnect(self):
|
|
|
|
con = SQLite3(":memory:")
|
|
|
|
con.execute("")
|
|
|
|
self.assertTrue(hasattr(con.local, "conn"))
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
def test_rollback(self):
|
|
|
|
con = SQLite3(":memory:")
|
|
|
|
con.execute("CREATE TABLE foo (bar INTEGER)")
|
|
|
|
con.execute("INSERT INTO foo (bar) VALUES (42)")
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
try:
|
|
|
|
with con.transaction as con:
|
|
|
|
con.execute("INSERT INTO foo (bar) VALUES (23)")
|
|
|
|
raise ValueError("some error")
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
self.assertEqual(len(con.execute("SELECT bar FROM foo").fetchall()), 1)
|
|
|
|
|
|
|
|
|
|
|
|
class TestDBMigration(unittest.TestCase):
|
2014-03-28 12:20:43 +00:00
|
|
|
|
|
|
|
def test_defaults(self):
|
|
|
|
|
2014-06-23 16:01:45 +00:00
|
|
|
conf = config.new({
|
|
|
|
"general": {
|
|
|
|
"dbpath": "/dev/null",
|
|
|
|
"max-age": "1h"
|
|
|
|
}
|
|
|
|
})
|
2014-06-27 09:24:02 +00:00
|
|
|
db = Adapter(SQLite3(":memory:"), conf)
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
self.assertEqual(db.version, Adapter.MAX_VERSION)
|
2014-03-28 12:20:43 +00:00
|
|
|
self.assertTrue(db.preferences.get("session-key", "").isalnum())
|
|
|
|
|
|
|
|
def test_session_key_migration(self):
|
|
|
|
|
2014-06-23 16:01:45 +00:00
|
|
|
conf = config.new({
|
|
|
|
"general": {
|
|
|
|
"dbpath": "/dev/null",
|
|
|
|
"max-age": "1h"
|
|
|
|
}
|
|
|
|
})
|
2014-03-28 12:20:43 +00:00
|
|
|
conf.set("general", "session-key", "supersecretkey")
|
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
connection = SQLite3(":memory:")
|
|
|
|
|
|
|
|
with connection.transaction as con:
|
2014-03-28 12:20:43 +00:00
|
|
|
con.execute("PRAGMA user_version = 1")
|
|
|
|
con.execute("CREATE TABLE threads (id INTEGER PRIMARY KEY)")
|
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
db = Adapter(connection, conf)
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
self.assertEqual(db.version, Adapter.MAX_VERSION)
|
2014-03-28 12:20:43 +00:00
|
|
|
self.assertEqual(db.preferences.get("session-key"),
|
|
|
|
conf.get("general", "session-key"))
|
|
|
|
|
|
|
|
# try again, now with the session-key removed from our conf
|
|
|
|
conf.remove_option("general", "session-key")
|
2014-06-27 09:24:02 +00:00
|
|
|
db = Adapter(connection, conf)
|
2014-03-28 12:20:43 +00:00
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
self.assertEqual(db.version, Adapter.MAX_VERSION)
|
2014-03-28 12:20:43 +00:00
|
|
|
self.assertEqual(db.preferences.get("session-key"),
|
|
|
|
"supersecretkey")
|
2014-04-20 13:39:43 +00:00
|
|
|
|
|
|
|
def test_limit_nested_comments(self):
|
|
|
|
|
|
|
|
tree = {
|
|
|
|
1: None,
|
|
|
|
2: None,
|
|
|
|
3: 2,
|
|
|
|
4: 3,
|
|
|
|
7: 3,
|
|
|
|
5: 2,
|
|
|
|
6: None
|
|
|
|
}
|
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
connection = SQLite3(":memory:")
|
|
|
|
|
|
|
|
with connection.transaction as con:
|
2014-04-20 13:39:43 +00:00
|
|
|
con.execute("PRAGMA user_version = 2")
|
|
|
|
con.execute("CREATE TABLE threads ("
|
|
|
|
" id INTEGER PRIMARY KEY,"
|
|
|
|
" uri VARCHAR UNIQUE,"
|
|
|
|
" title VARCHAR)")
|
|
|
|
con.execute("CREATE TABLE comments ("
|
|
|
|
" tid REFERENCES threads(id),"
|
|
|
|
" id INTEGER PRIMARY KEY,"
|
|
|
|
" parent INTEGER,"
|
|
|
|
" created FLOAT NOT NULL, modified FLOAT,"
|
|
|
|
" text VARCHAR, email VARCHAR, website VARCHAR,"
|
|
|
|
" mode INTEGER,"
|
|
|
|
" remote_addr VARCHAR,"
|
|
|
|
" likes INTEGER DEFAULT 0,"
|
|
|
|
" dislikes INTEGER DEFAULT 0,"
|
|
|
|
" voters BLOB)")
|
|
|
|
|
|
|
|
con.execute("INSERT INTO threads (uri, title) VALUES (?, ?)", ("/", "Test"))
|
|
|
|
for (id, parent) in iteritems(tree):
|
|
|
|
con.execute("INSERT INTO comments ("
|
|
|
|
" tid, parent, created)"
|
|
|
|
"VALUEs (?, ?, ?)", (id, parent, id))
|
|
|
|
|
2014-06-23 16:01:45 +00:00
|
|
|
conf = config.new({
|
|
|
|
"general": {
|
|
|
|
"dbpath": "/dev/null",
|
|
|
|
"max-age": "1h"
|
|
|
|
}
|
|
|
|
})
|
2014-06-27 09:24:02 +00:00
|
|
|
Adapter(connection, conf)
|
2014-04-20 13:39:43 +00:00
|
|
|
|
|
|
|
flattened = [
|
|
|
|
(1, None),
|
|
|
|
(2, None),
|
|
|
|
(3, 2),
|
|
|
|
(4, 2),
|
|
|
|
(5, 2),
|
|
|
|
(6, None),
|
|
|
|
(7, 2)
|
|
|
|
]
|
|
|
|
|
2014-06-27 09:24:02 +00:00
|
|
|
with connection.transaction as con:
|
2014-04-20 13:39:43 +00:00
|
|
|
rv = con.execute("SELECT id, parent FROM comments ORDER BY created").fetchall()
|
|
|
|
self.assertEqual(flattened, rv)
|