about summary refs log tree commit diff stats
path: root/registry/user_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'registry/user_test.go')
-rw-r--r--registry/user_test.go349
1 files changed, 349 insertions, 0 deletions
diff --git a/registry/user_test.go b/registry/user_test.go
new file mode 100644
index 0000000..f0c9622
--- /dev/null
+++ b/registry/user_test.go
@@ -0,0 +1,349 @@
+/*
+Copyright (c) 2019 Ben Morrison (gbmor)
+
+This file is part of Registry.
+
+Registry 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 3 of the License, or
+(at your option) any later version.
+
+Registry 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 Registry.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+package registry // import "git.sr.ht/~gbmor/getwtxt/registry"
+
+import (
+	"bufio"
+	"fmt"
+	"net/http"
+	"os"
+	"reflect"
+	"testing"
+)
+
+var addUserCases = []struct {
+	name      string
+	nick      string
+	url       string
+	wantErr   bool
+	localOnly bool
+}{
+	{
+		name:      "Legitimate User (Local Only)",
+		nick:      "testuser1",
+		url:       "http://localhost:8080/twtxt.txt",
+		wantErr:   false,
+		localOnly: true,
+	},
+	{
+		name:      "Empty Query",
+		nick:      "",
+		url:       "",
+		wantErr:   true,
+		localOnly: false,
+	},
+	{
+		name:      "Invalid URL",
+		nick:      "foo",
+		url:       "foobarringtons",
+		wantErr:   true,
+		localOnly: false,
+	},
+	{
+		name:      "Garbage Data",
+		nick:      "",
+		url:       "",
+		wantErr:   true,
+		localOnly: false,
+	},
+}
+
+// Tests if we can successfully add a user to the registry
+func Test_Registry_AddUser(t *testing.T) {
+	registry := initTestEnv()
+	if !addUserCases[0].localOnly {
+		http.Handle("/twtxt.txt", http.HandlerFunc(twtxtHandler))
+		go fmt.Println(http.ListenAndServe(":8080", nil))
+	}
+	var buf = make([]byte, 256)
+	// read random data into case 5
+	rando, _ := os.Open("/dev/random")
+	reader := bufio.NewReader(rando)
+	n, err := reader.Read(buf)
+	if err != nil || n == 0 {
+		t.Errorf("Couldn't set up test: %v\n", err)
+	}
+	addUserCases[3].nick = string(buf)
+	addUserCases[3].url = string(buf)
+
+	statuses, err := registry.GetStatuses()
+	if err != nil {
+		t.Errorf("Error setting up test: %v\n", err)
+	}
+
+	for n, tt := range addUserCases {
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.localOnly {
+				t.Skipf("Local-only test. Skipping ... ")
+			}
+
+			err := registry.AddUser(tt.nick, tt.url, nil, statuses)
+
+			// only run some checks if we don't want an error
+			if !tt.wantErr {
+				if err != nil {
+					t.Errorf("Got error: %v\n", err)
+				}
+
+				// make sure we have *something* in the registry
+				if reflect.ValueOf(registry.Users[tt.url]).IsNil() {
+					t.Errorf("Failed to add user %v registry.\n", tt.url)
+				}
+
+				// see if the nick in the registry is the same
+				// as the test case. verifies the URL and the nick
+				// since the URL is used as the key
+				data := registry.Users[tt.url]
+				if data.Nick != tt.nick {
+					t.Errorf("Incorrect user data added to registry for user %v.\n", tt.url)
+				}
+			}
+			// check for the cases that should throw an error
+			if tt.wantErr && err == nil {
+				t.Errorf("Expected error for case %v, got nil\n", n)
+			}
+		})
+	}
+}
+func Benchmark_Registry_AddUser(b *testing.B) {
+	registry := initTestEnv()
+	statuses, err := registry.GetStatuses()
+	if err != nil {
+		b.Errorf("Error setting up test: %v\n", err)
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		for _, tt := range addUserCases {
+			err := registry.AddUser(tt.nick, tt.url, nil, statuses)
+			if err != nil {
+				continue
+			}
+			registry.Users[tt.url] = &User{}
+		}
+	}
+}
+
+var delUserCases = []struct {
+	name    string
+	url     string
+	wantErr bool
+}{
+	{
+		name:    "Valid User",
+		url:     "https://example.com/twtxt.txt",
+		wantErr: false,
+	},
+	{
+		name:    "Valid User",
+		url:     "https://example3.com/twtxt.txt",
+		wantErr: false,
+	},
+	{
+		name:    "Already Deleted User",
+		url:     "https://example3.com/twtxt.txt",
+		wantErr: true,
+	},
+	{
+		name:    "Empty Query",
+		url:     "",
+		wantErr: true,
+	},
+	{
+		name:    "Garbage Data",
+		url:     "",
+		wantErr: true,
+	},
+}
+
+// Tests if we can successfully delete a user from the registry
+func Test_Registry_DelUser(t *testing.T) {
+	registry := initTestEnv()
+	var buf = make([]byte, 256)
+	// read random data into case 5
+	rando, _ := os.Open("/dev/random")
+	reader := bufio.NewReader(rando)
+	n, err := reader.Read(buf)
+	if err != nil || n == 0 {
+		t.Errorf("Couldn't set up test: %v\n", err)
+	}
+	delUserCases[4].url = string(buf)
+
+	for n, tt := range delUserCases {
+		t.Run(tt.name, func(t *testing.T) {
+
+			err := registry.DelUser(tt.url)
+			if !reflect.ValueOf(registry.Users[tt.url]).IsNil() {
+				t.Errorf("Failed to delete user %v from registry.\n", tt.url)
+			}
+			if tt.wantErr && err == nil {
+				t.Errorf("Expected error but did not receive. Case %v\n", n)
+			}
+			if !tt.wantErr && err != nil {
+				t.Errorf("Unexpected error for case %v: %v\n", n, err)
+			}
+		})
+	}
+}
+func Benchmark_Registry_DelUser(b *testing.B) {
+	registry := initTestEnv()
+
+	data1 := &User{
+		Nick:   registry.Users[delUserCases[0].url].Nick,
+		Date:   registry.Users[delUserCases[0].url].Date,
+		Status: registry.Users[delUserCases[0].url].Status,
+	}
+
+	data2 := &User{
+		Nick:   registry.Users[delUserCases[1].url].Nick,
+		Date:   registry.Users[delUserCases[1].url].Date,
+		Status: registry.Users[delUserCases[1].url].Status,
+	}
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		for _, tt := range delUserCases {
+			err := registry.DelUser(tt.url)
+			if err != nil {
+				continue
+			}
+		}
+
+		registry.Users[delUserCases[0].url] = data1
+		registry.Users[delUserCases[1].url] = data2
+	}
+}
+
+var getUserStatusCases = []struct {
+	name    string
+	url     string
+	wantErr bool
+}{
+	{
+		name:    "Valid User",
+		url:     "https://example.com/twtxt.txt",
+		wantErr: false,
+	},
+	{
+		name:    "Valid User",
+		url:     "https://example3.com/twtxt.txt",
+		wantErr: false,
+	},
+	{
+		name:    "Nonexistent User",
+		url:     "https://doesn't.exist/twtxt.txt",
+		wantErr: true,
+	},
+	{
+		name:    "Empty Query",
+		url:     "",
+		wantErr: true,
+	},
+	{
+		name:    "Garbage Data",
+		url:     "",
+		wantErr: true,
+	},
+}
+
+// Checks if we can retrieve a single user's statuses
+func Test_Registry_GetUserStatuses(t *testing.T) {
+	registry := initTestEnv()
+	var buf = make([]byte, 256)
+	// read random data into case 5
+	rando, _ := os.Open("/dev/random")
+	reader := bufio.NewReader(rando)
+	n, err := reader.Read(buf)
+	if err != nil || n == 0 {
+		t.Errorf("Couldn't set up test: %v\n", err)
+	}
+	getUserStatusCases[4].url = string(buf)
+
+	for n, tt := range getUserStatusCases {
+		t.Run(tt.name, func(t *testing.T) {
+
+			statuses, err := registry.GetUserStatuses(tt.url)
+
+			if !tt.wantErr {
+				if reflect.ValueOf(statuses).IsNil() {
+					t.Errorf("Failed to pull statuses for user %v\n", tt.url)
+				}
+				// see if the function returns the same data
+				// that we already have
+				data := registry.Users[tt.url]
+				if !reflect.DeepEqual(data.Status, statuses) {
+					t.Errorf("Incorrect data retrieved as statuses for user %v.\n", tt.url)
+				}
+			}
+
+			if tt.wantErr && err == nil {
+				t.Errorf("Expected error, received nil for case %v: %v\n", n, tt.url)
+			}
+		})
+	}
+}
+func Benchmark_Registry_GetUserStatuses(b *testing.B) {
+	registry := initTestEnv()
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		for _, tt := range getUserStatusCases {
+			_, err := registry.GetUserStatuses(tt.url)
+			if err != nil {
+				continue
+			}
+		}
+	}
+}
+
+// Tests if we can retrieve all user statuses at once
+func Test_Registry_GetStatuses(t *testing.T) {
+	registry := initTestEnv()
+	t.Run("Registry.GetStatuses()", func(t *testing.T) {
+
+		statuses, err := registry.GetStatuses()
+		if reflect.ValueOf(statuses).IsNil() || err != nil {
+			t.Errorf("Failed to pull all statuses. %v\n", err)
+		}
+
+		// Now do the same query manually to see
+		// if we get the same result
+		unionmap := NewTimeMap()
+		for _, v := range registry.Users {
+			for i, e := range v.Status {
+				unionmap[i] = e
+			}
+		}
+		if !reflect.DeepEqual(statuses, unionmap) {
+			t.Errorf("Incorrect data retrieved as statuses.\n")
+		}
+	})
+}
+func Benchmark_Registry_GetStatuses(b *testing.B) {
+	registry := initTestEnv()
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		_, err := registry.GetStatuses()
+		if err != nil {
+			continue
+		}
+	}
+}