summary refs log tree commit diff stats
path: root/registry/user_test.go
diff options
context:
space:
mode:
authorBen Morrison <ben@gbmor.dev>2020-06-20 02:27:31 -0400
committerBen Morrison <ben@gbmor.dev>2020-06-20 02:27:31 -0400
commit538e305925b9b04102ef0a4fb7cca19a6c116142 (patch)
tree8e68b426c40c3151f39da1be874d2938f31ab5f9 /registry/user_test.go
parent0a69c582ec8b88b1d3af70ef43c3eeb1b99f973d (diff)
downloadgetwtxt-538e305925b9b04102ef0a4fb7cca19a6c116142.tar.gz
updating module to live at sourcehut
Also moving the 'registry' library into this repo, rather
than maintaining them separately. It will still be decoupled,
just live in this repository.
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
+		}
+	}
+}