gosora/misc_test.go
Azareal 217e7abab3 Another mooostly technical commit, don't worry we'll be getting to the fun stuff soon!
The query statements now use camelCase instead of undercase.
Added more documentation.
Renamed a few config variables.
The length counters in the MemoryUserStore and MemoryTopicStore are now atomic.
Added the Flush method to the UserCache and TopicCache.
Made more visual improvements to Tempra Conflux.
The avatar block vanished from the opening posts for topics for some reason, I added it back.
Added more tests.

And many more changes...
2017-09-18 18:03:52 +01:00

469 lines
11 KiB
Go

package main
import "strconv"
import "testing"
// TODO: Generate a test database to work with rather than a live one
// TODO: We might need to refactor TestUserStore soon, as it's getting fairly complex
func TestUserStore(t *testing.T) {
if !gloinited {
err := gloinit()
if err != nil {
t.Fatal(err)
}
}
if !pluginsInited {
initPlugins()
}
users = NewMemoryUserStore(config.UserCacheCapacity)
users.(UserCache).Flush()
userStoreTest(t)
users = NewSQLUserStore()
userStoreTest(t)
}
func userStoreTest(t *testing.T) {
var user *User
var err error
var length int
ucache, hasCache := users.(UserCache)
if hasCache && ucache.GetLength() != 0 {
t.Error("Initial ucache length isn't zero")
}
_, err = users.Get(-1)
if err == nil {
t.Error("UID #-1 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
if hasCache && ucache.GetLength() != 0 {
t.Error("There shouldn't be anything in the user cache")
}
_, err = users.Get(0)
if err == nil {
t.Error("UID #0 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
if hasCache && ucache.GetLength() != 0 {
t.Error("There shouldn't be anything in the user cache")
}
user, err = users.Get(1)
if err == ErrNoRows {
t.Error("Couldn't find UID #1")
} else if err != nil {
t.Fatal(err)
}
if user.ID != 1 {
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
}
if hasCache {
length = ucache.GetLength()
if length != 1 {
t.Error("User cache length should be 1, not " + strconv.Itoa(length))
}
user, err = ucache.CacheGet(1)
if err == ErrNoRows {
t.Error("Couldn't find UID #1 in the cache")
} else if err != nil {
t.Fatal(err)
}
if user.ID != 1 {
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
}
ucache.Flush()
length = ucache.GetLength()
if length != 0 {
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
}
}
// TODO: Lock onto the specific error type. Is this even possible without sacrificing the detailed information in the error message?
var userList map[int]*User
userList, _ = users.BulkGetMap([]int{-1})
if len(userList) > 0 {
t.Error("There shouldn't be any results for UID #-1")
}
if hasCache {
length = ucache.GetLength()
if length != 0 {
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
}
}
userList, _ = users.BulkGetMap([]int{0})
if len(userList) > 0 {
t.Error("There shouldn't be any results for UID #0")
}
if hasCache {
length = ucache.GetLength()
if length != 0 {
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
}
}
userList, _ = users.BulkGetMap([]int{1})
if len(userList) == 0 {
t.Error("The returned map is empty for UID #1")
} else if len(userList) > 1 {
t.Error("Too many results were returned for UID #1")
}
user, ok := userList[1]
if !ok {
t.Error("We couldn't find UID #1 in the returned map")
t.Error("userList", userList)
}
if user.ID != 1 {
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
}
if hasCache {
length = ucache.GetLength()
if length != 1 {
t.Error("User cache length should be 1, not " + strconv.Itoa(length))
}
user, err = ucache.CacheGet(1)
if err == ErrNoRows {
t.Error("Couldn't find UID #1 in the cache")
} else if err != nil {
t.Fatal(err)
}
if user.ID != 1 {
t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
}
ucache.Flush()
}
ok = users.Exists(-1)
if ok {
t.Error("UID #-1 shouldn't exist")
}
ok = users.Exists(0)
if ok {
t.Error("UID #0 shouldn't exist")
}
ok = users.Exists(1)
if !ok {
t.Error("UID #1 should exist")
}
if hasCache {
length = ucache.GetLength()
if length != 0 {
t.Error("User cache length should be 0, not " + strconv.Itoa(length))
}
}
count := users.GetGlobalCount()
if count <= 0 {
t.Error("The number of users should be bigger than zero")
t.Error("count", count)
}
}
func TestTopicStore(t *testing.T) {
if !gloinited {
err := gloinit()
if err != nil {
t.Fatal(err)
}
}
if !pluginsInited {
initPlugins()
}
topics = NewMemoryTopicStore(config.TopicCacheCapacity)
topicStoreTest(t)
topics = NewSQLTopicStore()
topicStoreTest(t)
}
func topicStoreTest(t *testing.T) {
var topic *Topic
var err error
_, err = topics.Get(-1)
if err == nil {
t.Error("TID #-1 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
_, err = topics.Get(0)
if err == nil {
t.Error("TID #0 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
topic, err = topics.Get(1)
if err == ErrNoRows {
t.Error("Couldn't find TID #1")
} else if err != nil {
t.Fatal(err)
}
if topic.ID != 1 {
t.Error("topic.ID does not match the requested TID. Got '" + strconv.Itoa(topic.ID) + "' instead.")
}
// TODO: Add BulkGetMap() to the TopicStore
ok := topics.Exists(-1)
if ok {
t.Error("TID #-1 shouldn't exist")
}
ok = topics.Exists(0)
if ok {
t.Error("TID #0 shouldn't exist")
}
ok = topics.Exists(1)
if !ok {
t.Error("TID #1 should exist")
}
count := topics.GetGlobalCount()
if count <= 0 {
t.Error("The number of topics should be bigger than zero")
t.Error("count", count)
}
}
func TestForumStore(t *testing.T) {
if !gloinited {
gloinit()
}
if !pluginsInited {
initPlugins()
}
var forum *Forum
var err error
_, err = fstore.Get(-1)
if err == nil {
t.Error("FID #-1 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
forum, err = fstore.Get(0)
if err == ErrNoRows {
t.Error("Couldn't find FID #0")
} else if err != nil {
t.Fatal(err)
}
if forum.ID != 0 {
t.Error("forum.ID doesn't not match the requested UID. Got '" + strconv.Itoa(forum.ID) + "' instead.")
}
if forum.Name != "Uncategorised" {
t.Error("FID #0 is named '" + forum.Name + "' and not 'Uncategorised'")
}
forum, err = fstore.Get(1)
if err == ErrNoRows {
t.Error("Couldn't find FID #1")
} else if err != nil {
t.Fatal(err)
}
if forum.ID != 1 {
t.Error("forum.ID doesn't not match the requested FID. Got '" + strconv.Itoa(forum.ID) + "' instead.'")
}
if forum.Name != "Reports" {
t.Error("FID #0 is named '" + forum.Name + "' and not 'Reports'")
}
forum, err = fstore.Get(2)
if err == ErrNoRows {
t.Error("Couldn't find FID #2")
} else if err != nil {
t.Fatal(err)
}
_ = forum
ok := fstore.Exists(-1)
if ok {
t.Error("FID #-1 shouldn't exist")
}
ok = fstore.Exists(0)
if !ok {
t.Error("FID #0 should exist")
}
ok = fstore.Exists(1)
if !ok {
t.Error("FID #1 should exist")
}
}
func TestGroupStore(t *testing.T) {
if !gloinited {
gloinit()
}
if !pluginsInited {
initPlugins()
}
var group *Group
var err error
_, err = gstore.Get(-1)
if err == nil {
t.Error("GID #-1 shouldn't exist")
} else if err != ErrNoRows {
t.Fatal(err)
}
group, err = gstore.Get(0)
if err == ErrNoRows {
t.Error("Couldn't find GID #0")
} else if err != nil {
t.Fatal(err)
}
if group.ID != 0 {
t.Error("group.ID doesn't not match the requested GID. Got '" + strconv.Itoa(group.ID) + "' instead.")
}
if group.Name != "Unknown" {
t.Error("GID #0 is named '" + group.Name + "' and not 'Unknown'")
}
// ? - What if they delete this group? x.x
// ? - Maybe, pick a random group ID? That would take an extra query, and I'm not sure if I want to be rewriting custom test queries. Possibly, a Random() method on the GroupStore? Seems useless for normal use, it might have some merit for the TopicStore though
group, err = gstore.Get(1)
if err == ErrNoRows {
t.Error("Couldn't find GID #1")
} else if err != nil {
t.Fatal(err)
}
if group.ID != 1 {
t.Error("group.ID doesn't not match the requested GID. Got '" + strconv.Itoa(group.ID) + "' instead.'")
}
_ = group
ok := gstore.Exists(-1)
if ok {
t.Error("GID #-1 shouldn't exist")
}
ok = gstore.Exists(0)
if !ok {
t.Error("GID #0 should exist")
}
ok = gstore.Exists(1)
if !ok {
t.Error("GID #1 should exist")
}
}
func TestSlugs(t *testing.T) {
var res string
var msgList []MEPair
msgList = addMEPair(msgList, "Unknown", "unknown")
msgList = addMEPair(msgList, "Unknown2", "unknown2")
msgList = addMEPair(msgList, "Unknown ", "unknown")
msgList = addMEPair(msgList, "Unknown 2", "unknown-2")
msgList = addMEPair(msgList, "Unknown 2", "unknown-2")
msgList = addMEPair(msgList, "Admin Alice", "admin-alice")
msgList = addMEPair(msgList, "Admin_Alice", "adminalice")
msgList = addMEPair(msgList, "Admin_Alice-", "adminalice")
msgList = addMEPair(msgList, "-Admin_Alice-", "adminalice")
msgList = addMEPair(msgList, "-Admin@Alice-", "adminalice")
msgList = addMEPair(msgList, "-Admin😀Alice-", "adminalice")
msgList = addMEPair(msgList, "u", "u")
msgList = addMEPair(msgList, "", "untitled")
msgList = addMEPair(msgList, " ", "untitled")
msgList = addMEPair(msgList, "-", "untitled")
msgList = addMEPair(msgList, "--", "untitled")
msgList = addMEPair(msgList, "é", "é")
msgList = addMEPair(msgList, "-é-", "é")
for _, item := range msgList {
t.Log("Testing string '" + item.Msg + "'")
res = nameToSlug(item.Msg)
if res != item.Expects {
t.Error("Bad output:", "'"+res+"'")
t.Error("Expected:", item.Expects)
}
}
}
func TestAuth(t *testing.T) {
// bcrypt likes doing stupid things, so this test will probably fail
var realPassword string
var hashedPassword string
var password string
var salt string
var err error
/* No extra salt tests, we might not need this extra salt, as bcrypt has it's own? */
realPassword = "Madame Cassandra's Mystic Orb"
t.Log("Set real_password to '" + realPassword + "'")
t.Log("Hashing the real password")
hashedPassword, err = BcryptGeneratePasswordNoSalt(realPassword)
if err != nil {
t.Error(err)
}
password = realPassword
t.Log("Testing password '" + password + "'")
t.Log("Testing salt '" + salt + "'")
err = CheckPassword(hashedPassword, password, salt)
if err == ErrMismatchedHashAndPassword {
t.Error("The two don't match")
} else if err == ErrPasswordTooLong {
t.Error("CheckPassword thinks the password is too long")
} else if err != nil {
t.Error(err)
}
password = "hahaha"
t.Log("Testing password '" + password + "'")
t.Log("Testing salt '" + salt + "'")
err = CheckPassword(hashedPassword, password, salt)
if err == ErrPasswordTooLong {
t.Error("CheckPassword thinks the password is too long")
} else if err == nil {
t.Error("The two shouldn't match!")
}
password = "Madame Cassandra's Mystic"
t.Log("Testing password '" + password + "'")
t.Log("Testing salt '" + salt + "'")
err = CheckPassword(hashedPassword, password, salt)
if err == ErrPasswordTooLong {
t.Error("CheckPassword thinks the password is too long")
} else if err == nil {
t.Error("The two shouldn't match!")
}
}