Database refactor and test coverage

This commit is contained in:
Imbus 2024-03-14 13:39:56 +01:00
parent 327f90e448
commit 6c8abf1f53
4 changed files with 84 additions and 16 deletions

View file

@ -20,8 +20,8 @@ type Database interface {
GetUserId(username string) (int, error)
AddProject(name string, description string, username string) error
Migrate(dirname string) error
// AddTimeReport(projectname string, start time.Time, end time.Time) error
// AddUserToProject(username string, projectname string) error
AddTimeReport(projectName string, userName string, start time.Time, end time.Time) error
AddUserToProject(username string, projectname string, role string) error
// ChangeUserRole(username string, projectname string, role string) error
// AddTimeReport(projectname string, start time.Time, end time.Time) error
// AddUserToProject(username string, projectname string) error
@ -37,12 +37,16 @@ type Db struct {
//go:embed migrations
var scripts embed.FS
// TODO: Possibly break these out into separate files bundled with the embed package?
const userInsert = "INSERT INTO users (username, password) VALUES (?, ?)"
const projectInsert = "INSERT INTO projects (name, description, owner_user_id) SELECT ?, ?, id FROM users WHERE username = ?"
const promoteToAdmin = "INSERT INTO site_admin (admin_id) SELECT id FROM users WHERE username = ?"
const addTimeReport = "INSERT INTO activity (report_id, activity_nbr, start_time, end_time, break, comment) VALUES (?, ?, ?, ?, ?, ?)" // WIP
const addUserToProject = "INSERT INTO project_member (project_id, user_id, role) VALUES (?, ?, ?)" // WIP
// const changeUserRole = ""
const addTimeReport = `WITH UserLookup AS (SELECT id FROM users WHERE username = ?),
ProjectLookup AS (SELECT id FROM projects WHERE name = ?)
INSERT INTO time_reports (project_id, user_id, start, end)
VALUES ((SELECT id FROM ProjectLookup), (SELECT id FROM UserLookup), ?, ?);`
const addUserToProject = "INSERT INTO user_roles (user_id, project_id, p_role) VALUES (?, ?, ?)" // WIP
const changeUserRole = "UPDATE project_member SET role = ? WHERE user_id = ? AND project_id = ?"
// DbConnect connects to the database
func DbConnect(dbpath string) Database {
@ -61,8 +65,8 @@ func DbConnect(dbpath string) Database {
return &Db{db}
}
func (d *Db) AddTimeReport(projectname string, start time.Time, end time.Time, breakTime uint32) error { // WIP
_, err := d.Exec(addTimeReport, projectname, 0, start, end, breakTime, false)
func (d *Db) AddTimeReport(projectName string, userName string, start time.Time, end time.Time) error { // WIP
_, err := d.Exec(addTimeReport, userName, projectName, start, end)
return err
}
@ -79,13 +83,26 @@ func (d *Db) AddUserToProject(username string, projectname string, role string)
panic(err2)
}
_, err3 := d.Exec(addUserToProject, projectid, userid, role)
_, err3 := d.Exec(addUserToProject, userid, projectid, role)
return err3
}
// func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
var userid int
userid, err := d.GetUserId(username)
if err != nil {
panic(err)
}
// }
var projectid int
projectid, err2 := d.GetProjectId(projectname)
if err2 != nil {
panic(err2)
}
_, err3 := d.Exec(changeUserRole, role, userid, projectid)
return err3
}
// AddUser adds a user to the database
func (d *Db) AddUser(username string, password string) error {
@ -112,7 +129,7 @@ func (d *Db) GetUserId(username string) (int, error) {
func (d *Db) GetProjectId(projectname string) (int, error) { // WIP, denna kan vara goof
var id int
err := d.Get(&id, "SELECT id FROM project WHERE project_name = ?", projectname)
err := d.Get(&id, "SELECT id FROM projects WHERE name = ?", projectname)
return id, err
}

View file

@ -2,6 +2,7 @@ package database
import (
"testing"
"time"
)
// Tests are not guaranteed to be sequential
@ -92,9 +93,60 @@ func TestPromoteToAdmin(t *testing.T) {
}
}
// func TestAddTimeReport(t *testing.T) {
func TestAddTimeReport(t *testing.T) {
db, err := setupState()
if err != nil {
t.Error("setupState failed:", err)
}
// }
err = db.AddUser("testuser", "password")
if err != nil {
t.Error("AddUser failed:", err)
}
err = db.AddProject("testproject", "description", "testuser")
if err != nil {
t.Error("AddProject failed:", err)
}
var now = time.Now()
var then = now.Add(time.Hour)
err = db.AddTimeReport("testproject", "testuser", now, then)
if err != nil {
t.Error("AddTimeReport failed:", err)
}
}
func TestAddUserToProject(t *testing.T) {
db, err := setupState()
if err != nil {
t.Error("setupState failed:", err)
}
err = db.AddUser("testuser", "password")
if err != nil {
t.Error("AddUser failed:", err)
}
err = db.AddProject("testproject", "description", "testuser")
if err != nil {
t.Error("AddProject failed:", err)
}
var now = time.Now()
var then = now.Add(time.Hour)
err = db.AddTimeReport("testproject", "testuser", now, then)
if err != nil {
t.Error("AddTimeReport failed:", err)
}
err = db.AddUserToProject("testuser", "testproject", "user")
if err != nil {
t.Error("AddUserToProject failed:", err)
}
}
// func TestAddUserToProject(t *testing.T) {

View file

@ -1,11 +1,9 @@
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY,
projectId TEXT DEFAULT (HEX(RANDOMBLOB(4))) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL UNIQUE,
description TEXT NOT NULL,
owner_user_id INTEGER NOT NULL,
FOREIGN KEY (owner_user_id) REFERENCES users (id)
);
CREATE INDEX IF NOT EXISTS projects_projectId_index ON projects (projectId);
CREATE INDEX IF NOT EXISTS projects_user_id_index ON projects (owner_user_id);

View file

@ -1,10 +1,11 @@
CREATE TABLE IF NOT EXISTS time_reports (
id INTEGER PRIMARY KEY,
reportId TEXT DEFAULT (HEX(RANDOMBLOB(6))) NOT NULL UNIQUE,
project_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
start DATETIME NOT NULL,
end DATETIME NOT NULL,
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
CREATE TRIGGER IF NOT EXISTS time_reports_start_before_end