add user type

master
Joshua Herring 3 weeks ago
parent ddfa9535ab
commit 86ebe6bb90

@ -0,0 +1,56 @@
package dbi
import (
"context"
"database/sql"
"fmt"
)
type User struct {
APIKey string `json:"api_key"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Password string `json:"password"`
Status string `json:"status"`
Username string `json:"username"`
}
func CreateUser(conn *sql.Conn, user *User) error {
_, err := conn.ExecContext(context.Background(),
`INSERT INTO users (APIKey, FirstName, LastName, Password, Status, Username)
VALUES (?, ?, ?, ?, ?, ?)`,
user.APIKey, user.FirstName, user.LastName, user.Password, user.Status, user.Username,
)
return err
}
func GetUser(conn *sql.Conn, username string) (User, error) {
row := conn.QueryRowContext(context.Background(),
`SELECT APIKey, FirstName, LastName, Password, Status, Username
FROM users WHERE Username = ?`,
username,
)
var u User
err := row.Scan(&u.APIKey, &u.FirstName, &u.LastName, &u.Password, &u.Status, &u.Username)
if err == sql.ErrNoRows {
return User{}, fmt.Errorf("user %q not found", username)
}
return u, err
}
func UpdateUser(conn *sql.Conn, user *User) error {
_, err := conn.ExecContext(context.Background(),
`UPDATE users SET APIKey = ?, FirstName = ?, LastName = ?, Password = ?, Status = ?
WHERE Username = ?`,
user.APIKey, user.FirstName, user.LastName, user.Password, user.Status, user.Username,
)
return err
}
func DeleteUser(conn *sql.Conn, username string) error {
_, err := conn.ExecContext(context.Background(),
`DELETE FROM users WHERE Username = ?`,
username,
)
return err
}

@ -0,0 +1,152 @@
package dbi
import (
"context"
"database/sql"
"math/rand"
"testing"
_ "modernc.org/sqlite"
)
func testDB(t *testing.T) *sql.DB {
t.Helper()
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
t.Fatalf("open in-memory db: %v", err)
}
if _, err := db.Exec(ActivityReportSchema); err != nil {
t.Fatalf("apply schema: %v", err)
}
t.Cleanup(func() { db.Close() })
return db
}
func testConn(t *testing.T, db *sql.DB) *sql.Conn {
t.Helper()
conn, err := db.Conn(context.Background())
if err != nil {
t.Fatalf("get conn: %v", err)
}
t.Cleanup(func() { conn.Close() })
return conn
}
func randString(n int) string {
const letters = "abcdefghijklmnopqrstuvwxyz"
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func genUser() User {
return User{
APIKey: randString(16),
FirstName: randString(8),
LastName: randString(8),
Password: randString(20),
Status: "faculty",
Username: randString(10),
}
}
func TestCreateUser(t *testing.T) {
conn := testConn(t, testDB(t))
u := genUser()
if err := CreateUser(conn, &u); err != nil {
t.Fatalf("CreateUser: %v", err)
}
got, err := GetUser(conn, u.Username)
if err != nil {
t.Fatalf("GetUser after create: %v", err)
}
if got != u {
t.Errorf("got %+v, want %+v", got, u)
}
}
func TestCreateUserDuplicateUsername(t *testing.T) {
conn := testConn(t, testDB(t))
u := genUser()
if err := CreateUser(conn, &u); err != nil {
t.Fatalf("first CreateUser: %v", err)
}
if err := CreateUser(conn, &u); err == nil {
t.Error("expected error on duplicate username, got nil")
}
}
func TestGetUser(t *testing.T) {
conn := testConn(t, testDB(t))
u := genUser()
if err := CreateUser(conn, &u); err != nil {
t.Fatalf("CreateUser: %v", err)
}
got, err := GetUser(conn, u.Username)
if err != nil {
t.Fatalf("GetUser: %v", err)
}
if got != u {
t.Errorf("got %+v, want %+v", got, u)
}
}
func TestGetUserNotFound(t *testing.T) {
conn := testConn(t, testDB(t))
_, err := GetUser(conn, randString(10))
if err == nil {
t.Error("expected error for missing user, got nil")
}
}
func TestUpdateUser(t *testing.T) {
conn := testConn(t, testDB(t))
u := genUser()
if err := CreateUser(conn, &u); err != nil {
t.Fatalf("CreateUser: %v", err)
}
u.FirstName = randString(8)
u.LastName = randString(8)
u.APIKey = randString(16)
u.Status = "admin"
if err := UpdateUser(conn, &u); err != nil {
t.Fatalf("UpdateUser: %v", err)
}
got, err := GetUser(conn, u.Username)
if err != nil {
t.Fatalf("GetUser after update: %v", err)
}
if got != u {
t.Errorf("got %+v, want %+v", got, u)
}
}
func TestDeleteUser(t *testing.T) {
conn := testConn(t, testDB(t))
u := genUser()
if err := CreateUser(conn, &u); err != nil {
t.Fatalf("CreateUser: %v", err)
}
if err := DeleteUser(conn, u.Username); err != nil {
t.Fatalf("DeleteUser: %v", err)
}
_, err := GetUser(conn, u.Username)
if err == nil {
t.Error("expected error after delete, got nil")
}
}
Loading…
Cancel
Save