Merge branch 'dev' into frontend
This commit is contained in:
commit
e839d02cfd
15 changed files with 361 additions and 192 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,6 +9,7 @@ bin
|
||||||
database.txt
|
database.txt
|
||||||
plantuml.jar
|
plantuml.jar
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
diagram.puml
|
diagram.puml
|
||||||
backend/*.png
|
backend/*.png
|
||||||
backend/*.jpg
|
backend/*.jpg
|
||||||
|
|
|
@ -39,6 +39,7 @@ type Database interface {
|
||||||
SignWeeklyReport(reportId int, projectManagerId int) error
|
SignWeeklyReport(reportId int, projectManagerId int) error
|
||||||
IsSiteAdmin(username string) (bool, error)
|
IsSiteAdmin(username string) (bool, error)
|
||||||
IsProjectManager(username string, projectname string) (bool, error)
|
IsProjectManager(username string, projectname string) (bool, error)
|
||||||
|
GetTotalTimePerActivity(projectName string) (map[string]int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This struct is a wrapper type that holds the database connection
|
// This struct is a wrapper type that holds the database connection
|
||||||
|
@ -60,14 +61,16 @@ var sampleData embed.FS
|
||||||
|
|
||||||
// TODO: Possibly break these out into separate files bundled with the embed package?
|
// TODO: Possibly break these out into separate files bundled with the embed package?
|
||||||
const userInsert = "INSERT INTO users (username, password) VALUES (?, ?)"
|
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 projectInsert = "INSERT INTO projects (name, description, owner_user_id) VALUES (?, ?, (SELECT id FROM users WHERE username = ?))"
|
||||||
const promoteToAdmin = "INSERT INTO site_admin (admin_id) SELECT id FROM users WHERE username = ?"
|
const promoteToAdmin = "INSERT INTO site_admin (admin_id) SELECT id FROM users WHERE username = ?"
|
||||||
const addWeeklyReport = `WITH UserLookup AS (SELECT id FROM users WHERE username = ?),
|
const addWeeklyReport = `WITH UserLookup AS (SELECT id FROM users WHERE username = ?),
|
||||||
ProjectLookup AS (SELECT id FROM projects WHERE name = ?)
|
ProjectLookup AS (SELECT id FROM projects WHERE name = ?)
|
||||||
INSERT INTO weekly_reports (project_id, user_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time)
|
INSERT INTO weekly_reports (project_id, user_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time)
|
||||||
VALUES ((SELECT id FROM ProjectLookup), (SELECT id FROM UserLookup),?, ?, ?, ?, ?, ?, ?);`
|
VALUES ((SELECT id FROM ProjectLookup), (SELECT id FROM UserLookup),?, ?, ?, ?, ?, ?, ?);`
|
||||||
const addUserToProject = "INSERT INTO user_roles (user_id, project_id, p_role) VALUES (?, ?, ?)"
|
const addUserToProject = `INSERT OR IGNORE INTO user_roles (user_id, project_id, p_role)
|
||||||
const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = ? AND project_id = ?"
|
VALUES ((SELECT id FROM users WHERE username = ?),
|
||||||
|
(SELECT id FROM projects WHERE name = ?), ?)`
|
||||||
|
const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = (SELECT id FROM users WHERE username = ?) AND project_id = (SELECT id FROM projects WHERE name = ?)"
|
||||||
const getProjectsForUser = `SELECT p.id, p.name, p.description FROM projects p
|
const getProjectsForUser = `SELECT p.id, p.name, p.description FROM projects p
|
||||||
JOIN user_roles ur ON p.id = ur.project_id
|
JOIN user_roles ur ON p.id = ur.project_id
|
||||||
JOIN users u ON ur.user_id = u.id
|
JOIN users u ON ur.user_id = u.id
|
||||||
|
@ -75,6 +78,11 @@ const getProjectsForUser = `SELECT p.id, p.name, p.description FROM projects p
|
||||||
const deleteProject = `DELETE FROM projects
|
const deleteProject = `DELETE FROM projects
|
||||||
WHERE id = ? AND owner_username = ?`
|
WHERE id = ? AND owner_username = ?`
|
||||||
|
|
||||||
|
const isProjectManagerQuery = `SELECT COUNT(*) > 0 FROM user_roles
|
||||||
|
JOIN users ON user_roles.user_id = users.id
|
||||||
|
JOIN projects ON user_roles.project_id = projects.id
|
||||||
|
WHERE users.username = ? AND projects.name = ? AND user_roles.p_role = 'project_manager'`
|
||||||
|
|
||||||
// DbConnect connects to the database
|
// DbConnect connects to the database
|
||||||
func DbConnect(dbpath string) Database {
|
func DbConnect(dbpath string) Database {
|
||||||
// Open the database
|
// Open the database
|
||||||
|
@ -132,41 +140,15 @@ func (d *Db) AddWeeklyReport(projectName string, userName string, week int, deve
|
||||||
|
|
||||||
// AddUserToProject adds a user to a project with a specified role.
|
// AddUserToProject adds a user to a project with a specified role.
|
||||||
func (d *Db) AddUserToProject(username string, projectname string, role string) error {
|
func (d *Db) AddUserToProject(username string, projectname string, role string) error {
|
||||||
var userid int
|
_, err := d.Exec(addUserToProject, username, projectname, role)
|
||||||
userid, err := d.GetUserId(username)
|
return err
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var projectid int
|
|
||||||
projectid, err2 := d.GetProjectId(projectname)
|
|
||||||
if err2 != nil {
|
|
||||||
panic(err2)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err3 := d.Exec(addUserToProject, userid, projectid, role)
|
|
||||||
return err3
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeUserRole changes the role of a user within a project.
|
// ChangeUserRole changes the role of a user within a project.
|
||||||
func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
|
func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
|
||||||
// Get the user ID
|
|
||||||
var userid int
|
|
||||||
userid, err := d.GetUserId(username)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the project ID
|
|
||||||
var projectid int
|
|
||||||
projectid, err2 := d.GetProjectId(projectname)
|
|
||||||
if err2 != nil {
|
|
||||||
panic(err2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the SQL query to change the user's role
|
// Execute the SQL query to change the user's role
|
||||||
_, err3 := d.Exec(changeUserRole, role, userid, projectid)
|
_, err := d.Exec(changeUserRole, role, username, projectname)
|
||||||
return err3
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeUserName changes the username of a user.
|
// ChangeUserName changes the username of a user.
|
||||||
|
@ -215,6 +197,7 @@ func (d *Db) GetProjectId(projectname string) (int, error) {
|
||||||
// Creates a new project in the database, associated with a user
|
// Creates a new project in the database, associated with a user
|
||||||
func (d *Db) AddProject(name string, description string, username string) error {
|
func (d *Db) AddProject(name string, description string, username string) error {
|
||||||
tx := d.MustBegin()
|
tx := d.MustBegin()
|
||||||
|
// Insert the project into the database
|
||||||
_, err := tx.Exec(projectInsert, name, description, username)
|
_, err := tx.Exec(projectInsert, name, description, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err := tx.Rollback(); err != nil {
|
if err := tx.Rollback(); err != nil {
|
||||||
|
@ -222,7 +205,9 @@ func (d *Db) AddProject(name string, description string, username string) error
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = tx.Exec(changeUserRole, "project_manager", username, name)
|
|
||||||
|
// Add creator to project as project manager
|
||||||
|
_, err = tx.Exec(addUserToProject, username, name, "project_manager")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err := tx.Rollback(); err != nil {
|
if err := tx.Rollback(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -462,23 +447,9 @@ func (d *Db) GetWeeklyReportsUser(username string, projectName string) ([]types.
|
||||||
|
|
||||||
// IsProjectManager checks if a given username is a project manager for the specified project
|
// IsProjectManager checks if a given username is a project manager for the specified project
|
||||||
func (d *Db) IsProjectManager(username string, projectname string) (bool, error) {
|
func (d *Db) IsProjectManager(username string, projectname string) (bool, error) {
|
||||||
// Define the SQL query to check if the user is a project manager for the project
|
var manager bool
|
||||||
query := `
|
err := d.Get(&manager, isProjectManagerQuery, username, projectname)
|
||||||
SELECT COUNT(*) FROM user_roles
|
return manager, err
|
||||||
JOIN users ON user_roles.user_id = users.id
|
|
||||||
JOIN projects ON user_roles.project_id = projects.id
|
|
||||||
WHERE users.username = ? AND projects.name = ? AND user_roles.p_role = 'project_manager'
|
|
||||||
`
|
|
||||||
|
|
||||||
// Execute the query
|
|
||||||
var count int
|
|
||||||
err := d.Get(&count, query, username, projectname)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If count is greater than 0, the user is a project manager for the project
|
|
||||||
return count > 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MigrateSampleData applies sample data to the database.
|
// MigrateSampleData applies sample data to the database.
|
||||||
|
@ -519,3 +490,41 @@ func (d *Db) MigrateSampleData() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) GetTotalTimePerActivity(projectName string) (map[string]int, error) {
|
||||||
|
|
||||||
|
query := `
|
||||||
|
SELECT development_time, meeting_time, admin_time, own_work_time, study_time, testing_time
|
||||||
|
FROM weekly_reports
|
||||||
|
JOIN projects ON weekly_reports.project_id = projects.id
|
||||||
|
WHERE projects.name = ?
|
||||||
|
`
|
||||||
|
|
||||||
|
rows, err := d.DB.Query(query, projectName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
totalTime := make(map[string]int)
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var developmentTime, meetingTime, adminTime, ownWorkTime, studyTime, testingTime int
|
||||||
|
if err := rows.Scan(&developmentTime, &meetingTime, &adminTime, &ownWorkTime, &studyTime, &testingTime); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTime["development"] += developmentTime
|
||||||
|
totalTime["meeting"] += meetingTime
|
||||||
|
totalTime["admin"] += adminTime
|
||||||
|
totalTime["own_work"] += ownWorkTime
|
||||||
|
totalTime["study"] += studyTime
|
||||||
|
totalTime["testing"] += testingTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalTime, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,12 +16,61 @@ func setupState() (Database, error) {
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a more advanced setup that includes more data in the database.
|
||||||
|
// This is useful for more complex testing scenarios.
|
||||||
|
func setupAdvancedState() (Database, error) {
|
||||||
|
db, err := setupState()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a user
|
||||||
|
if err = db.AddUser("demouser", "password"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a project
|
||||||
|
if err = db.AddProject("projecttest", "description", "demouser"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a weekly report
|
||||||
|
if err = db.AddWeeklyReport("projecttest", "demouser", 1, 1, 1, 1, 1, 1, 1); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TestDbConnect tests the connection to the database
|
// TestDbConnect tests the connection to the database
|
||||||
func TestDbConnect(t *testing.T) {
|
func TestDbConnect(t *testing.T) {
|
||||||
db := DbConnect(":memory:")
|
db := DbConnect(":memory:")
|
||||||
_ = db
|
_ = db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetupAdvancedState(t *testing.T) {
|
||||||
|
db, err := setupAdvancedState()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupAdvancedState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user was added
|
||||||
|
if _, err = db.GetUserId("demouser"); err != nil {
|
||||||
|
t.Error("GetUserId failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the project was added
|
||||||
|
projects, err := db.GetAllProjects()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetAllProjects failed:", err)
|
||||||
|
}
|
||||||
|
if len(projects) != 1 {
|
||||||
|
t.Error("GetAllProjects failed: expected 1, got", len(projects))
|
||||||
|
}
|
||||||
|
|
||||||
|
// To be continued...
|
||||||
|
}
|
||||||
|
|
||||||
// TestDbAddUser tests the AddUser function of the database
|
// TestDbAddUser tests the AddUser function of the database
|
||||||
func TestDbAddUser(t *testing.T) {
|
func TestDbAddUser(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
|
@ -58,12 +106,12 @@ func TestDbGetUserId(t *testing.T) {
|
||||||
|
|
||||||
// TestDbAddProject tests the AddProject function of the database
|
// TestDbAddProject tests the AddProject function of the database
|
||||||
func TestDbAddProject(t *testing.T) {
|
func TestDbAddProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupAdvancedState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("setupState failed:", err)
|
t.Error("setupState failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.AddProject("test", "description", "test")
|
err = db.AddProject("test", "description", "demouser")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("AddProject failed:", err)
|
t.Error("AddProject failed:", err)
|
||||||
}
|
}
|
||||||
|
@ -168,20 +216,15 @@ func TestChangeUserRole(t *testing.T) {
|
||||||
t.Error("AddProject failed:", err)
|
t.Error("AddProject failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.AddUserToProject("testuser", "testproject", "user")
|
|
||||||
if err != nil {
|
|
||||||
t.Error("AddUserToProject failed:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
role, err := db.GetUserRole("testuser", "testproject")
|
role, err := db.GetUserRole("testuser", "testproject")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("GetUserRole failed:", err)
|
t.Error("GetUserRole failed:", err)
|
||||||
}
|
}
|
||||||
if role != "user" {
|
if role != "project_manager" {
|
||||||
t.Error("GetUserRole failed: expected user, got", role)
|
t.Error("GetUserRole failed: expected project_manager, got", role)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.ChangeUserRole("testuser", "testproject", "admin")
|
err = db.ChangeUserRole("testuser", "testproject", "member")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("ChangeUserRole failed:", err)
|
t.Error("ChangeUserRole failed:", err)
|
||||||
}
|
}
|
||||||
|
@ -190,8 +233,8 @@ func TestChangeUserRole(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("GetUserRole failed:", err)
|
t.Error("GetUserRole failed:", err)
|
||||||
}
|
}
|
||||||
if role != "admin" {
|
if role != "member" {
|
||||||
t.Error("GetUserRole failed: expected admin, got", role)
|
t.Error("GetUserRole failed: expected member, got", role)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -480,7 +523,6 @@ func TestSignWeeklyReport(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("GetUserId failed:", err)
|
t.Error("GetUserId failed:", err)
|
||||||
}
|
}
|
||||||
fmt.Println("Project Manager's ID:", projectManagerID)
|
|
||||||
|
|
||||||
// Sign the report with the project manager
|
// Sign the report with the project manager
|
||||||
err = db.SignWeeklyReport(report.ReportId, projectManagerID)
|
err = db.SignWeeklyReport(report.ReportId, projectManagerID)
|
||||||
|
@ -519,7 +561,7 @@ func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
||||||
t.Error("AddUser failed:", err)
|
t.Error("AddUser failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add project
|
// Add project, projectManager is the owner
|
||||||
err = db.AddProject("testproject", "description", "projectManager")
|
err = db.AddProject("testproject", "description", "projectManager")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("AddProject failed:", err)
|
t.Error("AddProject failed:", err)
|
||||||
|
@ -543,14 +585,25 @@ func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
||||||
t.Error("GetWeeklyReport failed:", err)
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
anotherManagerID, err := db.GetUserId("projectManager")
|
managerID, err := db.GetUserId("projectManager")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("GetUserId failed:", err)
|
t.Error("GetUserId failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.SignWeeklyReport(report.ReportId, anotherManagerID)
|
err = db.SignWeeklyReport(report.ReportId, managerID)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
t.Error("Expected SignWeeklyReport to fail with a project manager who is not in the project, but it didn't")
|
t.Error("SignWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the report again to check if it's signed
|
||||||
|
signedReport, err := db.GetWeeklyReport("testuser", "testproject", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the report is signed by the project manager
|
||||||
|
if *signedReport.SignedBy != managerID {
|
||||||
|
t.Errorf("Expected SignedBy to be %d, got %d", managerID, *signedReport.SignedBy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +729,28 @@ func TestIsProjectManager(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChangeUserName(t *testing.T) {
|
func TestGetTotalTimePerActivity(t *testing.T) {
|
||||||
|
// Initialize your test database connection
|
||||||
|
db, err := setupState()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the query to get total time per activity
|
||||||
|
totalTime, err := db.GetTotalTimePerActivity("projecttest")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetTotalTimePerActivity failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the totalTime map is not nil
|
||||||
|
if totalTime == nil {
|
||||||
|
t.Error("Expected non-nil totalTime map, got nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ska lägga till fler assertions
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnsureManagerOfCreatedProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("setupState failed:", err)
|
t.Error("setupState failed:", err)
|
||||||
|
@ -688,26 +762,24 @@ func TestChangeUserName(t *testing.T) {
|
||||||
t.Error("AddUser failed:", err)
|
t.Error("AddUser failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the user's name
|
// Add a project
|
||||||
err = db.ChangeUserName("testuser", "newname")
|
err = db.AddProject("testproject", "description", "testuser")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("ChangeUserName failed:", err)
|
t.Error("AddProject failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the user's ID
|
// Set user to a project manager
|
||||||
userID, err := db.GetUserId("newname")
|
// err = db.AddUserToProject("testuser", "testproject", "project_manager")
|
||||||
|
// if err != nil {
|
||||||
|
// t.Error("AddUserToProject failed:", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
managerState, err := db.IsProjectManager("testuser", "testproject")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("GetUserId failed:", err)
|
t.Error("IsProjectManager failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the user's ID matches the expected value
|
if !managerState {
|
||||||
if userID != 1 {
|
t.Error("Expected testuser to be a project manager, but it's not.")
|
||||||
t.Errorf("Expected user ID to be 1, got %d", userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to retrieve the user by the old name
|
|
||||||
_, err = db.GetUserId("testuser")
|
|
||||||
if err == nil {
|
|
||||||
t.Error("Expected GetUserId to fail for the old name, but it didn't")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ CREATE TABLE IF NOT EXISTS weekly_reports (
|
||||||
study_time INTEGER,
|
study_time INTEGER,
|
||||||
testing_time INTEGER,
|
testing_time INTEGER,
|
||||||
signed_by INTEGER,
|
signed_by INTEGER,
|
||||||
|
UNIQUE(user_id, project_id, week),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||||
FOREIGN KEY (project_id) REFERENCES projects(id),
|
FOREIGN KEY (project_id) REFERENCES projects(id),
|
||||||
FOREIGN KEY (signed_by) REFERENCES users(id)
|
FOREIGN KEY (signed_by) REFERENCES users(id)
|
||||||
|
|
|
@ -33,3 +33,18 @@ VALUES (3,3,"member");
|
||||||
|
|
||||||
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
|
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
|
||||||
VALUES (2,1,"project_manager");
|
VALUES (2,1,"project_manager");
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
|
||||||
|
VALUES (2, 1, 12, 20, 10, 5, 30, 15, 10, NULL);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
|
||||||
|
VALUES (3, 1, 12, 20, 10, 5, 30, 15, 10, NULL);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
|
||||||
|
VALUES (3, 1, 14, 20, 10, 5, 30, 15, 10, NULL);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
|
||||||
|
VALUES (3, 2, 12, 20, 10, 5, 30, 15, 10, NULL);
|
||||||
|
|
||||||
|
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
|
||||||
|
VALUES (3, 3, 12, 20, 10, 5, 30, 15, 10, NULL);
|
||||||
|
|
|
@ -65,8 +65,8 @@ func (gs *GState) ProjectRoleChange(c *fiber.Ctx) error {
|
||||||
//check token and get username of current user
|
//check token and get username of current user
|
||||||
user := c.Locals("user").(*jwt.Token)
|
user := c.Locals("user").(*jwt.Token)
|
||||||
claims := user.Claims.(jwt.MapClaims)
|
claims := user.Claims.(jwt.MapClaims)
|
||||||
projectManagerUsername := claims["name"].(string)
|
username := claims["name"].(string)
|
||||||
log.Info(projectManagerUsername)
|
|
||||||
// Extract the necessary parameters from the request
|
// Extract the necessary parameters from the request
|
||||||
data := new(types.RoleChange)
|
data := new(types.RoleChange)
|
||||||
if err := c.BodyParser(data); err != nil {
|
if err := c.BodyParser(data); err != nil {
|
||||||
|
@ -74,18 +74,19 @@ func (gs *GState) ProjectRoleChange(c *fiber.Ctx) error {
|
||||||
return c.Status(400).SendString(err.Error())
|
return c.Status(400).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// dubble diping and checcking if current user is
|
log.Info("Changing role for user: ", username, " in project: ", data.Projectname, " to: ", data.Role)
|
||||||
|
|
||||||
if ismanager, err := gs.Db.IsProjectManager(projectManagerUsername, data.Projectname); err != nil {
|
// Dubble diping and checcking if current user is
|
||||||
|
if ismanager, err := gs.Db.IsProjectManager(username, data.Projectname); err != nil {
|
||||||
log.Warn("Error checking if projectmanager:", err)
|
log.Warn("Error checking if projectmanager:", err)
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
} else if !ismanager {
|
} else if !ismanager {
|
||||||
log.Warn("tried chaning role when not projectmanager:", err)
|
log.Warn("User is not projectmanager")
|
||||||
return c.Status(401).SendString("you can not change role when not projectManager")
|
return c.Status(401).SendString("User is not projectmanager")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the user's role within the project in the database
|
// Change the user's role within the project in the database
|
||||||
if err := gs.Db.ChangeUserRole(data.Username, data.Projectname, data.Role); err != nil {
|
if err := gs.Db.ChangeUserRole(username, data.Projectname, data.Role); err != nil {
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +213,15 @@ func (gs *GState) AddUserToProjectHandler(c *fiber.Ctx) error {
|
||||||
|
|
||||||
// IsProjectManagerHandler is a handler that checks if a user is a project manager for a given project
|
// IsProjectManagerHandler is a handler that checks if a user is a project manager for a given project
|
||||||
func (gs *GState) IsProjectManagerHandler(c *fiber.Ctx) error {
|
func (gs *GState) IsProjectManagerHandler(c *fiber.Ctx) error {
|
||||||
|
// Get the username from the token
|
||||||
|
user := c.Locals("user").(*jwt.Token)
|
||||||
|
claims := user.Claims.(jwt.MapClaims)
|
||||||
|
username := claims["name"].(string)
|
||||||
|
|
||||||
// Extract necessary parameters from the request query string
|
// Extract necessary parameters from the request query string
|
||||||
username := c.Query("username")
|
projectName := c.Params("projectName")
|
||||||
projectName := c.Query("projectName")
|
|
||||||
|
log.Info("Checking if user ", username, " is a project manager for project ", projectName)
|
||||||
|
|
||||||
// Check if the user is a project manager for the specified project
|
// Check if the user is a project manager for the specified project
|
||||||
isManager, err := gs.Db.IsProjectManager(username, projectName)
|
isManager, err := gs.Db.IsProjectManager(username, projectName)
|
||||||
|
@ -224,10 +231,5 @@ func (gs *GState) IsProjectManagerHandler(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result as JSON
|
// Return the result as JSON
|
||||||
return c.JSON(map[string]bool{"isProjectManager": isManager})
|
return c.JSON(fiber.Map{"isProjectManager": isManager})
|
||||||
}
|
|
||||||
|
|
||||||
func (gs *GState) CreateTask(c *fiber.Ctx) error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (gs *GState) SubmitWeeklyReport(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gs.Db.AddWeeklyReport(report.ProjectName, username, report.Week, report.DevelopmentTime, report.MeetingTime, report.AdminTime, report.OwnWorkTime, report.StudyTime, report.TestingTime); err != nil {
|
if err := gs.Db.AddWeeklyReport(report.ProjectName, username, report.Week, report.DevelopmentTime, report.MeetingTime, report.AdminTime, report.OwnWorkTime, report.StudyTime, report.TestingTime); err != nil {
|
||||||
log.Info("Error adding weekly report")
|
log.Info("Error adding weekly report to db:", err)
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,8 +207,8 @@ func (gs *GState) GetAllUsersProject(c *fiber.Ctx) error {
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce plain
|
// @Produce plain
|
||||||
// @Param NewUser body types.NewUser true "user info"
|
// @Param NewUser body types.NewUser true "user info"
|
||||||
// @Success 200 {json} json "Successfully prometed user"
|
// @Success 200 {json} json "Successfully promoted user"
|
||||||
// @Failure 400 {string} string "bad request"
|
// @Failure 400 {string} string "Bad request"
|
||||||
// @Failure 401 {string} string "Unauthorized"
|
// @Failure 401 {string} string "Unauthorized"
|
||||||
// @Failure 500 {string} string "Internal server error"
|
// @Failure 500 {string} string "Internal server error"
|
||||||
// @Router /promoteToAdmin [post]
|
// @Router /promoteToAdmin [post]
|
||||||
|
|
|
@ -14,9 +14,12 @@ type NewProject struct {
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to change the role of a user in a project.
|
||||||
|
// If name is identical to the name contained in the token, the role can be changed.
|
||||||
|
// If the name is different, only a project manager can change the role.
|
||||||
type RoleChange struct {
|
type RoleChange struct {
|
||||||
|
UserName string `json:"username"`
|
||||||
Role string `json:"role" tstype:"'project_manager' | 'user'"`
|
Role string `json:"role" tstype:"'project_manager' | 'user'"`
|
||||||
Username string `json:"username"`
|
|
||||||
Projectname string `json:"projectname"`
|
Projectname string `json:"projectname"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ func main() {
|
||||||
server.Post("/api/promoteToAdmin", gs.PromoteToAdmin)
|
server.Post("/api/promoteToAdmin", gs.PromoteToAdmin)
|
||||||
server.Get("/api/users/all", gs.ListAllUsers)
|
server.Get("/api/users/all", gs.ListAllUsers)
|
||||||
server.Get("/api/getWeeklyReportsUser/:projectName", gs.GetWeeklyReportsUserHandler)
|
server.Get("/api/getWeeklyReportsUser/:projectName", gs.GetWeeklyReportsUserHandler)
|
||||||
server.Get("api/checkIfProjectManager", gs.IsProjectManagerHandler)
|
server.Get("/api/checkIfProjectManager/:projectName", gs.IsProjectManagerHandler)
|
||||||
server.Post("/api/ProjectRoleChange", gs.ProjectRoleChange)
|
server.Post("/api/ProjectRoleChange", gs.ProjectRoleChange)
|
||||||
server.Get("/api/getUsersProject/:projectName", gs.ListAllUsersProject)
|
server.Get("/api/getUsersProject/:projectName", gs.ListAllUsersProject)
|
||||||
|
|
||||||
|
|
|
@ -8,52 +8,100 @@ import {
|
||||||
WeeklyReport,
|
WeeklyReport,
|
||||||
} from "../Types/goTypes";
|
} from "../Types/goTypes";
|
||||||
|
|
||||||
// This type of pattern should be hard to misuse
|
/**
|
||||||
|
* Response object returned by API methods.
|
||||||
|
*/
|
||||||
export interface APIResponse<T> {
|
export interface APIResponse<T> {
|
||||||
|
/** Indicates whether the API call was successful */
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
/** Optional message providing additional information or error description */
|
||||||
message?: string;
|
message?: string;
|
||||||
|
/** Optional data returned by the API method */
|
||||||
data?: T;
|
data?: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that all protected routes also require a token
|
/**
|
||||||
// Defines all the methods that an instance of the API must implement
|
* Interface defining methods that an instance of the API must implement.
|
||||||
|
*/
|
||||||
interface API {
|
interface API {
|
||||||
/** Register a new user */
|
/**
|
||||||
|
* Register a new user
|
||||||
|
* @param {NewUser} user The user object to be registered
|
||||||
|
* @returns {Promise<APIResponse<User>>} A promise containing the API response with the user data.
|
||||||
|
*/
|
||||||
registerUser(user: NewUser): Promise<APIResponse<User>>;
|
registerUser(user: NewUser): Promise<APIResponse<User>>;
|
||||||
/** Remove a user */
|
|
||||||
|
/**
|
||||||
|
* Removes a user.
|
||||||
|
* @param {string} username The username of the user to be removed.
|
||||||
|
* @param {string} token The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<User>>} A promise containing the API response with the removed user data.
|
||||||
|
*/
|
||||||
removeUser(username: string, token: string): Promise<APIResponse<User>>;
|
removeUser(username: string, token: string): Promise<APIResponse<User>>;
|
||||||
/** Check if user is project manager */
|
|
||||||
|
/**
|
||||||
|
* Check if user is project manager.
|
||||||
|
* @param {string} username The username of the user.
|
||||||
|
* @param {string} projectName The name of the project.
|
||||||
|
* @param {string} token The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<boolean>>} A promise containing the API response indicating if the user is a project manager.
|
||||||
|
*/
|
||||||
checkIfProjectManager(
|
checkIfProjectManager(
|
||||||
username: string,
|
username: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<boolean>>;
|
): Promise<APIResponse<boolean>>;
|
||||||
/** Login */
|
|
||||||
|
/** Logs in a user with the provided credentials.
|
||||||
|
* @param {NewUser} NewUser The user object containing username and password.
|
||||||
|
* @returns {Promise<APIResponse<string>>} A promise resolving to an API response with a token.
|
||||||
|
*/
|
||||||
login(NewUser: NewUser): Promise<APIResponse<string>>;
|
login(NewUser: NewUser): Promise<APIResponse<string>>;
|
||||||
/** Renew the token */
|
|
||||||
|
/**
|
||||||
|
* Renew the token
|
||||||
|
* @param {string} token The current authentication token.
|
||||||
|
* @returns {Promise<APIResponse<string>>} A promise resolving to an API response with a renewed token.
|
||||||
|
*/
|
||||||
renewToken(token: string): Promise<APIResponse<string>>;
|
renewToken(token: string): Promise<APIResponse<string>>;
|
||||||
|
|
||||||
/** Promote user to admin */
|
/** Promote user to admin */
|
||||||
/** Create a project */
|
|
||||||
|
/** Creates a new project.
|
||||||
|
* @param {NewProject} project The project object containing name and description.
|
||||||
|
* @param {string} token The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<Project>>} A promise resolving to an API response with the created project.
|
||||||
|
*/
|
||||||
createProject(
|
createProject(
|
||||||
project: NewProject,
|
project: NewProject,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<Project>>;
|
): Promise<APIResponse<Project>>;
|
||||||
/** Submit a weekly report */
|
|
||||||
|
/** Submits a weekly report
|
||||||
|
* @param {NewWeeklyReport} weeklyReport The weekly report object.
|
||||||
|
* @param {string} token The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<NewWeeklyReport>>} A promise resolving to an API response with the submitted report.
|
||||||
|
*/
|
||||||
submitWeeklyReport(
|
submitWeeklyReport(
|
||||||
project: NewWeeklyReport,
|
weeklyReport: NewWeeklyReport,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<NewWeeklyReport>>;
|
): Promise<APIResponse<NewWeeklyReport>>;
|
||||||
/**Gets a weekly report*/
|
|
||||||
|
/** Gets a weekly report for a specific user, project and week
|
||||||
|
* @param {string} projectName The name of the project.
|
||||||
|
* @param {string} week The week number.
|
||||||
|
* @param {string} token The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<WeeklyReport>>} A promise resolving to an API response with the retrieved report.
|
||||||
|
*/
|
||||||
getWeeklyReport(
|
getWeeklyReport(
|
||||||
username: string,
|
|
||||||
projectName: string,
|
projectName: string,
|
||||||
week: string,
|
week: string,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<WeeklyReport>>;
|
): Promise<APIResponse<WeeklyReport>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the weekly reports for a user in a particular project
|
* Returns all the weekly reports for a user in a particular project
|
||||||
* The username is derived from the token
|
* The username is derived from the token
|
||||||
*
|
|
||||||
* @param {string} projectName The name of the project
|
* @param {string} projectName The name of the project
|
||||||
* @param {string} token The token of the user
|
* @param {string} token The token of the user
|
||||||
* @returns {APIResponse<WeeklyReport[]>} A list of weekly reports
|
* @returns {APIResponse<WeeklyReport[]>} A list of weekly reports
|
||||||
|
@ -62,11 +110,23 @@ interface API {
|
||||||
projectName: string,
|
projectName: string,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<WeeklyReport[]>>;
|
): Promise<APIResponse<WeeklyReport[]>>;
|
||||||
/** Gets all the projects of a user*/
|
|
||||||
|
/** Gets all the projects of a user
|
||||||
|
* @param {string} token - The authentication token.
|
||||||
|
* @returns {Promise<APIResponse<Project[]>>} A promise containing the API response with the user's projects.
|
||||||
|
*/
|
||||||
getUserProjects(token: string): Promise<APIResponse<Project[]>>;
|
getUserProjects(token: string): Promise<APIResponse<Project[]>>;
|
||||||
/** Gets a project from id*/
|
|
||||||
|
/** Gets a project by its id.
|
||||||
|
* @param {number} id The id of the project to retrieve.
|
||||||
|
* @returns {Promise<APIResponse<Project>>} A promise resolving to an API response containing the project data.
|
||||||
|
*/
|
||||||
getProject(id: number): Promise<APIResponse<Project>>;
|
getProject(id: number): Promise<APIResponse<Project>>;
|
||||||
/** Gets all users*/
|
|
||||||
|
/** Gets a list of all users.
|
||||||
|
* @param {string} token The authentication token of the requesting user.
|
||||||
|
* @returns {Promise<APIResponse<string[]>>} A promise resolving to an API response containing the list of users.
|
||||||
|
*/
|
||||||
getAllUsers(token: string): Promise<APIResponse<string[]>>;
|
getAllUsers(token: string): Promise<APIResponse<string[]>>;
|
||||||
/** Gets all users in a project from name*/
|
/** Gets all users in a project from name*/
|
||||||
getAllUsersProject(
|
getAllUsersProject(
|
||||||
|
@ -75,7 +135,7 @@ interface API {
|
||||||
): Promise<APIResponse<UserProjectMember[]>>;
|
): Promise<APIResponse<UserProjectMember[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export an instance of the API
|
/** An instance of the API */
|
||||||
export const api: API = {
|
export const api: API = {
|
||||||
async registerUser(user: NewUser): Promise<APIResponse<User>> {
|
async registerUser(user: NewUser): Promise<APIResponse<User>> {
|
||||||
try {
|
try {
|
||||||
|
@ -263,20 +323,21 @@ export const api: API = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWeeklyReport(
|
async getWeeklyReport(
|
||||||
username: string,
|
|
||||||
projectName: string,
|
projectName: string,
|
||||||
week: string,
|
week: string,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<WeeklyReport>> {
|
): Promise<APIResponse<WeeklyReport>> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/getWeeklyReport", {
|
const response = await fetch(
|
||||||
method: "GET",
|
`/api/getWeeklyReport?projectName=${projectName}&week=${week}`,
|
||||||
headers: {
|
{
|
||||||
"Content-Type": "application/json",
|
method: "GET",
|
||||||
Authorization: "Bearer " + token,
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ username, projectName, week }),
|
);
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return { success: false, message: "Failed to get weekly report" };
|
return { success: false, message: "Failed to get weekly report" };
|
||||||
|
@ -342,7 +403,6 @@ export const api: API = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Gets a projet by id, currently untested since we have no javascript-based tests
|
|
||||||
async getProject(id: number): Promise<APIResponse<Project>> {
|
async getProject(id: number): Promise<APIResponse<Project>> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/project/${id}`, {
|
const response = await fetch(`/api/project/${id}`, {
|
||||||
|
@ -368,7 +428,6 @@ export const api: API = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Gets all users
|
|
||||||
async getAllUsers(token: string): Promise<APIResponse<string[]>> {
|
async getAllUsers(token: string): Promise<APIResponse<string[]>> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/users/all", {
|
const response = await fetch("/api/users/all", {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Button from "./Button";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to add a project to the system
|
* Tries to add a project to the system
|
||||||
* @param props - Project name and description
|
* @param {Object} props - Project name and description
|
||||||
* @returns {boolean} True if created, false if not
|
* @returns {boolean} True if created, false if not
|
||||||
*/
|
*/
|
||||||
function CreateProject(props: { name: string; description: string }): boolean {
|
function CreateProject(props: { name: string; description: string }): boolean {
|
||||||
|
@ -34,8 +34,8 @@ function CreateProject(props: { name: string; description: string }): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to add a project to the system
|
* Provides UI for adding a project to the system.
|
||||||
* @returns {JSX.Element} UI for project adding
|
* @returns {JSX.Element} - Returns the component UI for adding a project
|
||||||
*/
|
*/
|
||||||
function AddProject(): JSX.Element {
|
function AddProject(): JSX.Element {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
|
|
|
@ -7,30 +7,30 @@ import { api } from "../API/API";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a component that displays all the time reports for a specific project.
|
* Renders a component that displays all the time reports for a specific project.
|
||||||
* @returns JSX.Element representing the component.
|
* @returns {JSX.Element} representing the component.
|
||||||
*/
|
*/
|
||||||
function AllTimeReportsInProject(): JSX.Element {
|
function AllTimeReportsInProject(): JSX.Element {
|
||||||
const { projectName } = useParams();
|
const { projectName } = useParams();
|
||||||
const [weeklyReports, setWeeklyReports] = useState<WeeklyReport[]>([]);
|
const [weeklyReports, setWeeklyReports] = useState<WeeklyReport[]>([]);
|
||||||
|
|
||||||
const getWeeklyReports = async (): Promise<void> => {
|
|
||||||
const token = localStorage.getItem("accessToken") ?? "";
|
|
||||||
const response = await api.getWeeklyReportsForUser(
|
|
||||||
token,
|
|
||||||
projectName ?? "",
|
|
||||||
);
|
|
||||||
console.log(response);
|
|
||||||
if (response.success) {
|
|
||||||
setWeeklyReports(response.data ?? []);
|
|
||||||
} else {
|
|
||||||
console.error(response.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Call getProjects when the component mounts
|
// Call getProjects when the component mounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const getWeeklyReports = async (): Promise<void> => {
|
||||||
|
const token = localStorage.getItem("accessToken") ?? "";
|
||||||
|
const response = await api.getWeeklyReportsForUser(
|
||||||
|
projectName ?? "",
|
||||||
|
token,
|
||||||
|
);
|
||||||
|
console.log(response);
|
||||||
|
if (response.success) {
|
||||||
|
setWeeklyReports(response.data ?? []);
|
||||||
|
} else {
|
||||||
|
console.error(response.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void getWeeklyReports();
|
void getWeeklyReports();
|
||||||
});
|
}, [projectName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -144,9 +144,14 @@ export interface NewProject {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Used to change the role of a user in a project.
|
||||||
|
* If name is identical to the name contained in the token, the role can be changed.
|
||||||
|
* If the name is different, only a project manager can change the role.
|
||||||
|
*/
|
||||||
export interface RoleChange {
|
export interface RoleChange {
|
||||||
role: 'project_manager' | 'user';
|
|
||||||
username: string;
|
username: string;
|
||||||
|
role: 'project_manager' | 'user';
|
||||||
projectname: string;
|
projectname: string;
|
||||||
}
|
}
|
||||||
export interface NameChange {
|
export interface NameChange {
|
||||||
|
|
76
testing.py
76
testing.py
|
@ -20,8 +20,8 @@ def randomString(len=10):
|
||||||
|
|
||||||
|
|
||||||
# Defined once per test run
|
# Defined once per test run
|
||||||
username = randomString()
|
username = "user_" + randomString()
|
||||||
projectName = randomString()
|
projectName = "project_" + randomString()
|
||||||
|
|
||||||
# The base URL of the API
|
# The base URL of the API
|
||||||
base_url = "http://localhost:8080"
|
base_url = "http://localhost:8080"
|
||||||
|
@ -45,30 +45,37 @@ getUsersProjectPath = base_url + "/api/getUsersProject"
|
||||||
#ta bort auth i handlern för att få testet att gå igenom
|
#ta bort auth i handlern för att få testet att gå igenom
|
||||||
def test_ProjectRoleChange():
|
def test_ProjectRoleChange():
|
||||||
dprint("Testing ProjectRoleChange")
|
dprint("Testing ProjectRoleChange")
|
||||||
project_manager = randomString()
|
localUsername = randomString()
|
||||||
register(project_manager, "project_manager_password")
|
localProjectName = randomString()
|
||||||
|
register(localUsername, "username_password")
|
||||||
|
|
||||||
token = login(project_manager, "project_manager_password").json()[
|
token = login(localUsername, "username_password").json()[
|
||||||
"token"
|
"token"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Just checking since this test is built somewhat differently than the others
|
||||||
|
assert token != None, "Login failed"
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
addProjectPath,
|
addProjectPath,
|
||||||
json={"name": projectName, "description": "This is a project"},
|
json={"name": localProjectName, "description": "This is a project"},
|
||||||
headers={"Authorization": "Bearer " + token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
print("Add project failed")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
ProjectRoleChangePath,
|
ProjectRoleChangePath,
|
||||||
headers={"Authorization": "Bearer " + token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
json={
|
json={
|
||||||
"username": username,
|
"projectName": localProjectName,
|
||||||
"projectName": projectName,
|
"role": "project_manager",
|
||||||
"week": 1
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if response.status_code != 200:
|
|
||||||
print("auth not working, för att man inte kan få tag på pm token atm, för att få igenom det så ta bort auth i handler")
|
|
||||||
|
|
||||||
assert response.status_code == 200, "change role successfully"
|
assert response.status_code == 200, "ProjectRoleChange failed"
|
||||||
|
gprint("test_ProjectRoleChange successful")
|
||||||
|
|
||||||
|
|
||||||
def test_get_user_projects():
|
def test_get_user_projects():
|
||||||
|
@ -267,7 +274,7 @@ def test_sign_report():
|
||||||
submitReportPath,
|
submitReportPath,
|
||||||
json={
|
json={
|
||||||
"projectName": projectName,
|
"projectName": projectName,
|
||||||
"week": 1,
|
"week": 2,
|
||||||
"developmentTime": 10,
|
"developmentTime": 10,
|
||||||
"meetingTime": 5,
|
"meetingTime": 5,
|
||||||
"adminTime": 5,
|
"adminTime": 5,
|
||||||
|
@ -329,42 +336,36 @@ def test_check_if_project_manager():
|
||||||
|
|
||||||
# Check if the user is a project manager for the project
|
# Check if the user is a project manager for the project
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
checkIfProjectManagerPath,
|
checkIfProjectManagerPath + "/" + projectName,
|
||||||
headers={"Authorization": "Bearer " + token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
params={"username": username, "projectName": projectName},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
dprint(response.text)
|
dprint(response.text)
|
||||||
assert response.status_code == 200, "Check if project manager failed"
|
assert response.status_code == 200, "Check if project manager failed"
|
||||||
gprint("test_check_if_project_manager successful")
|
gprint("test_check_if_project_manager successful")
|
||||||
|
|
||||||
def test_list_all_users_project():
|
def test_ensure_manager_of_created_project():
|
||||||
# Log in as a user who is a member of the project
|
# Create a new user to add to the project
|
||||||
admin_username = randomString()
|
newUser = "karen_" + randomString()
|
||||||
admin_password = "admin_password2"
|
newProject = "HR_" + randomString()
|
||||||
dprint(
|
register(newUser, "new_user_password")
|
||||||
"Registering with username: ", admin_username, " and password: ", admin_password
|
token = login(newUser, "new_user_password").json()["token"]
|
||||||
)
|
|
||||||
response = requests.post(
|
|
||||||
registerPath, json={"username": admin_username, "password": admin_password}
|
|
||||||
)
|
|
||||||
dprint(response.text)
|
|
||||||
|
|
||||||
# Log in as the admin
|
# Create a new project
|
||||||
admin_token = login(admin_username, admin_password).json()["token"]
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
promoteToAdminPath,
|
addProjectPath,
|
||||||
json={"username": admin_username},
|
json={"name": newProject, "description": "This is a project"},
|
||||||
headers={"Authorization": "Bearer " + admin_token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
)
|
)
|
||||||
|
assert response.status_code == 200, "Add project failed"
|
||||||
|
|
||||||
# Make a request to list all users associated with the project
|
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
getUsersProjectPath + "/" + projectName,
|
checkIfProjectManagerPath + "/" + newProject,
|
||||||
headers={"Authorization": "Bearer " + admin_token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, "List all users project failed"
|
assert response.status_code == 200, "Check if project manager failed"
|
||||||
gprint("test_list_all_users_project sucessful")
|
assert response.json()["isProjectManager"] == True, "User is not project manager"
|
||||||
|
gprint("test_ensure_admin_of_created_project successful")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -380,4 +381,5 @@ if __name__ == "__main__":
|
||||||
test_get_weekly_reports_user()
|
test_get_weekly_reports_user()
|
||||||
test_check_if_project_manager()
|
test_check_if_project_manager()
|
||||||
test_ProjectRoleChange()
|
test_ProjectRoleChange()
|
||||||
test_list_all_users_project()
|
#test_list_all_users_project()
|
||||||
|
test_ensure_manager_of_created_project()
|
||||||
|
|
Loading…
Reference in a new issue