Merge branch 'dev' into gruppDM
This commit is contained in:
commit
b9b17bf229
14 changed files with 325 additions and 62 deletions
|
@ -5,8 +5,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TestNewConfig tests the creation of a new configuration object
|
||||||
func TestNewConfig(t *testing.T) {
|
func TestNewConfig(t *testing.T) {
|
||||||
|
// Arrange
|
||||||
c := NewConfig()
|
c := NewConfig()
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
if c.Port != 8080 {
|
if c.Port != 8080 {
|
||||||
t.Errorf("Expected port to be 8080, got %d", c.Port)
|
t.Errorf("Expected port to be 8080, got %d", c.Port)
|
||||||
}
|
}
|
||||||
|
@ -24,9 +28,15 @@ func TestNewConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestWriteConfig tests the function to write the configuration to a file
|
||||||
func TestWriteConfig(t *testing.T) {
|
func TestWriteConfig(t *testing.T) {
|
||||||
|
// Arrange
|
||||||
c := NewConfig()
|
c := NewConfig()
|
||||||
|
|
||||||
|
//Act
|
||||||
err := c.WriteConfigToFile("test.toml")
|
err := c.WriteConfigToFile("test.toml")
|
||||||
|
|
||||||
|
// Assert
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error, got %s", err)
|
t.Errorf("Expected no error, got %s", err)
|
||||||
}
|
}
|
||||||
|
@ -35,14 +45,23 @@ func TestWriteConfig(t *testing.T) {
|
||||||
_ = os.Remove("test.toml")
|
_ = os.Remove("test.toml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestReadConfig tests the function to read the configuration from a file
|
||||||
func TestReadConfig(t *testing.T) {
|
func TestReadConfig(t *testing.T) {
|
||||||
|
// Arrange
|
||||||
c := NewConfig()
|
c := NewConfig()
|
||||||
|
|
||||||
|
// Act
|
||||||
err := c.WriteConfigToFile("test.toml")
|
err := c.WriteConfigToFile("test.toml")
|
||||||
|
|
||||||
|
// Assert
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error, got %s", err)
|
t.Errorf("Expected no error, got %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Act
|
||||||
c2, err := ReadConfigFromFile("test.toml")
|
c2, err := ReadConfigFromFile("test.toml")
|
||||||
|
|
||||||
|
// Assert
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Expected no error, got %s", err)
|
t.Errorf("Expected no error, got %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ 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
|
||||||
|
@ -66,10 +69,8 @@ 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 (?, ?, ?)" // WIP
|
const addUserToProject = "INSERT INTO user_roles (user_id, project_id, p_role) VALUES (?, ?, ?)"
|
||||||
const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = ? AND project_id = ?"
|
const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = ? AND project_id = ?"
|
||||||
const changeUserName = "UPDATE user SET username = ? WHERE user_id = ?" // WIP
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -133,7 +134,7 @@ 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 { // WIP
|
func (d *Db) AddUserToProject(username string, projectname string, role string) error {
|
||||||
var userid int
|
var userid int
|
||||||
userid, err := d.GetUserId(username)
|
userid, err := d.GetUserId(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -171,18 +172,11 @@ func (d *Db) ChangeUserRole(username string, projectname string, role string) er
|
||||||
return err3
|
return err3
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeUserRole changes the role of a user within a project.
|
// ChangeUserName changes the username of a user.
|
||||||
func (d *Db) ChangeUserName(username string, newname string) error {
|
func (d *Db) ChangeUserName(username string, newname string) error {
|
||||||
// Get the user ID
|
// Execute the SQL query to update the username
|
||||||
var userid int
|
_, err := d.Exec("UPDATE users SET username = ? WHERE username = ?", newname, username)
|
||||||
userid, err := d.GetUserId(username)
|
return err
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the SQL query to change the user's role
|
|
||||||
_, err2 := d.Exec(changeUserName, username, userid)
|
|
||||||
return err2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserRole retrieves the role of a user within a project.
|
// GetUserRole retrieves the role of a user within a project.
|
||||||
|
@ -528,3 +522,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
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
// Tests are not guaranteed to be sequential
|
// Tests are not guaranteed to be sequential
|
||||||
|
|
||||||
|
// setupState initializes a database instance with necessary setup for testing
|
||||||
func setupState() (Database, error) {
|
func setupState() (Database, error) {
|
||||||
db := DbConnect(":memory:")
|
db := DbConnect(":memory:")
|
||||||
err := db.Migrate()
|
err := db.Migrate()
|
||||||
|
@ -16,11 +17,13 @@ func setupState() (Database, error) {
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDbAddUser tests the AddUser function of the database
|
||||||
func TestDbAddUser(t *testing.T) {
|
func TestDbAddUser(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,6 +35,7 @@ func TestDbAddUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDbGetUserId tests the GetUserID function of the database
|
||||||
func TestDbGetUserId(t *testing.T) {
|
func TestDbGetUserId(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -52,6 +56,7 @@ func TestDbGetUserId(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDbAddProject tests the AddProject function of the database
|
||||||
func TestDbAddProject(t *testing.T) {
|
func TestDbAddProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -64,6 +69,7 @@ func TestDbAddProject(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDbRemoveUser tests the RemoveUser function of the database
|
||||||
func TestDbRemoveUser(t *testing.T) {
|
func TestDbRemoveUser(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -76,6 +82,7 @@ func TestDbRemoveUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPromoteToAdmin tests the PromoteToAdmin function of the database
|
||||||
func TestPromoteToAdmin(t *testing.T) {
|
func TestPromoteToAdmin(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -93,6 +100,7 @@ func TestPromoteToAdmin(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAddWeeklyReport tests the AddWeeklyReport function of the database
|
||||||
func TestAddWeeklyReport(t *testing.T) {
|
func TestAddWeeklyReport(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -115,6 +123,7 @@ func TestAddWeeklyReport(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAddUserToProject tests the AddUseToProject function of the database
|
||||||
func TestAddUserToProject(t *testing.T) {
|
func TestAddUserToProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -142,6 +151,7 @@ func TestAddUserToProject(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestChangeUserRole tests the ChangeUserRole function of the database
|
||||||
func TestChangeUserRole(t *testing.T) {
|
func TestChangeUserRole(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -186,6 +196,7 @@ func TestChangeUserRole(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetAllUsersProject tests the GetAllUsersProject function of the database
|
||||||
func TestGetAllUsersProject(t *testing.T) {
|
func TestGetAllUsersProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -252,6 +263,7 @@ func TestGetAllUsersProject(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetAllUsersApplication tests the GetAllUsersApplicsation function of the database
|
||||||
func TestGetAllUsersApplication(t *testing.T) {
|
func TestGetAllUsersApplication(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -298,6 +310,7 @@ func TestGetAllUsersApplication(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetProjectsForUser tests the GetProjectsForUser function of the database
|
||||||
func TestGetProjectsForUser(t *testing.T) {
|
func TestGetProjectsForUser(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -338,6 +351,7 @@ func TestGetProjectsForUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAddProject tests AddProject function of the database
|
||||||
func TestAddProject(t *testing.T) {
|
func TestAddProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -373,6 +387,7 @@ func TestAddProject(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetWeeklyReport tests GetWeeklyReport function of the database
|
||||||
func TestGetWeeklyReport(t *testing.T) {
|
func TestGetWeeklyReport(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -412,6 +427,7 @@ func TestGetWeeklyReport(t *testing.T) {
|
||||||
// Check other fields similarly
|
// Check other fields similarly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSignWeeklyReport tests SignWeeklyReport function of the database
|
||||||
func TestSignWeeklyReport(t *testing.T) {
|
func TestSignWeeklyReport(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -484,6 +500,7 @@ func TestSignWeeklyReport(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSignWeeklyReportByAnotherProjectManager tests the scenario where a project manager attempts to sign a weekly report for a user who is not assigned to their project
|
||||||
func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -537,6 +554,7 @@ func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestGetProject tests GetProject function of the database
|
||||||
func TestGetProject(t *testing.T) {
|
func TestGetProject(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -657,3 +675,52 @@ func TestIsProjectManager(t *testing.T) {
|
||||||
t.Error("Expected projectManager to be a project manager, but it's not.")
|
t.Error("Expected projectManager to be a project manager, but it's not.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a user
|
||||||
|
err = db.AddUser("testuser", "password")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUser failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a project
|
||||||
|
err = db.AddProject("testproject", "description", "testuser")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddProject failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
managerState, err := db.IsProjectManager("testuser", "testproject")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("IsProjectManager failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !managerState {
|
||||||
|
t.Error("Expected testuser to be a project manager, but it's not.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 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 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 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 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 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);
|
||||||
|
|
|
@ -212,8 +212,12 @@ 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.Query("projectName")
|
projectName := c.Query("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
|
||||||
|
|
|
@ -117,14 +117,22 @@ func (gs *GState) SignReport(c *fiber.Ctx) error {
|
||||||
|
|
||||||
// GetWeeklyReportsUserHandler retrieves all weekly reports for a user in a specific project
|
// GetWeeklyReportsUserHandler retrieves all weekly reports for a user in a specific project
|
||||||
func (gs *GState) GetWeeklyReportsUserHandler(c *fiber.Ctx) error {
|
func (gs *GState) GetWeeklyReportsUserHandler(c *fiber.Ctx) error {
|
||||||
// Extract necessary parameters from the request
|
// Extract the necessary parameters from the token
|
||||||
username := c.Params("username")
|
user := c.Locals("user").(*jwt.Token)
|
||||||
|
claims := user.Claims.(jwt.MapClaims)
|
||||||
|
username := claims["name"].(string)
|
||||||
|
|
||||||
|
// Extract necessary (path) parameters from the request
|
||||||
projectName := c.Params("projectName")
|
projectName := c.Params("projectName")
|
||||||
|
|
||||||
|
// TODO: Here we need to check whether the user is a member of the project
|
||||||
|
// If not, we should return an error. On the other hand, if the user not a member,
|
||||||
|
// the returned list of reports will (should) allways be empty.
|
||||||
|
|
||||||
// Retrieve weekly reports for the user in the project from the database
|
// Retrieve weekly reports for the user in the project from the database
|
||||||
reports, err := gs.Db.GetWeeklyReportsUser(username, projectName)
|
reports, err := gs.Db.GetWeeklyReportsUser(username, projectName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error getting weekly reports for user:", err)
|
log.Error("Error getting weekly reports for user:", username, "in project:", projectName, ":", err)
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ func (gs *GState) ChangeUserName(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
} else if !ismanager {
|
} else if !ismanager {
|
||||||
log.Warn("tried changing name when not projectmanager:", err)
|
log.Warn("tried changing name when not projectmanager:", err)
|
||||||
return c.Status(401).SendString("you can not change name when not projectManager")
|
return c.Status(401).SendString("you can not change name when not projectmanager")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the user's name within the project in the database
|
// Change the user's name within the project in the database
|
||||||
|
|
|
@ -32,3 +32,8 @@ type PublicUser struct {
|
||||||
type Token struct {
|
type Token struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StrNameChange struct {
|
||||||
|
PrevName string `json:"prevName" db:"prevName"`
|
||||||
|
NewName string `json:"newName" db:"newName"`
|
||||||
|
}
|
||||||
|
|
|
@ -97,8 +97,8 @@ func main() {
|
||||||
server.Put("/api/changeUserName", gs.ChangeUserName)
|
server.Put("/api/changeUserName", gs.ChangeUserName)
|
||||||
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", 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)
|
||||||
|
|
||||||
|
|
|
@ -7,62 +7,131 @@ 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} username The username of the user.
|
||||||
|
* @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,
|
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
|
||||||
|
* The username is derived from the token
|
||||||
|
* @param {string} projectName The name of the project
|
||||||
|
* @param {string} token The token of the user
|
||||||
|
* @returns {APIResponse<WeeklyReport[]>} A list of weekly reports
|
||||||
|
*/
|
||||||
getWeeklyReportsForUser(
|
getWeeklyReportsForUser(
|
||||||
username: string,
|
|
||||||
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 a project from id*/
|
|
||||||
|
/** 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[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
|
@ -277,26 +346,24 @@ export const api: API = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async getWeeklyReportsForUser(
|
async getWeeklyReportsForUser(
|
||||||
username: string,
|
|
||||||
projectName: string,
|
projectName: string,
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<APIResponse<WeeklyReport[]>> {
|
): Promise<APIResponse<WeeklyReport[]>> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(`/api/getWeeklyReportsUser/${projectName}`, {
|
||||||
`/api/getWeeklyReportsUser?username=${username}&projectName=${projectName}`,
|
method: "GET",
|
||||||
{
|
headers: {
|
||||||
method: "GET",
|
"Content-Type": "application/json",
|
||||||
headers: {
|
Authorization: "Bearer " + token,
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: "Bearer " + token,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "Failed to get weekly reports for project",
|
message:
|
||||||
|
"Failed to get weekly reports for project: Response code " +
|
||||||
|
response.status,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const data = (await response.json()) as WeeklyReport[];
|
const data = (await response.json()) as WeeklyReport[];
|
||||||
|
@ -305,7 +372,7 @@ export const api: API = {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: "fucked again",
|
message: "Failed to get weekly reports for project, unknown error",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -331,7 +398,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}`, {
|
||||||
|
@ -357,7 +423,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,7 +7,7 @@ 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();
|
||||||
|
@ -16,7 +16,6 @@ function AllTimeReportsInProject(): JSX.Element {
|
||||||
const getWeeklyReports = async (): Promise<void> => {
|
const getWeeklyReports = async (): Promise<void> => {
|
||||||
const token = localStorage.getItem("accessToken") ?? "";
|
const token = localStorage.getItem("accessToken") ?? "";
|
||||||
const response = await api.getWeeklyReportsForUser(
|
const response = await api.getWeeklyReportsForUser(
|
||||||
localStorage.getItem("username") ?? "",
|
|
||||||
projectName ?? "",
|
projectName ?? "",
|
||||||
token,
|
token,
|
||||||
);
|
);
|
||||||
|
|
|
@ -40,6 +40,44 @@ export interface NewWeeklyReport {
|
||||||
*/
|
*/
|
||||||
testingTime: number /* int */;
|
testingTime: number /* int */;
|
||||||
}
|
}
|
||||||
|
export interface WeeklyReportList {
|
||||||
|
/**
|
||||||
|
* The name of the project, as it appears in the database
|
||||||
|
*/
|
||||||
|
projectName: string;
|
||||||
|
/**
|
||||||
|
* The week number
|
||||||
|
*/
|
||||||
|
week: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent on development
|
||||||
|
*/
|
||||||
|
developmentTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent in meetings
|
||||||
|
*/
|
||||||
|
meetingTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent on administrative tasks
|
||||||
|
*/
|
||||||
|
adminTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent on personal projects
|
||||||
|
*/
|
||||||
|
ownWorkTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent on studying
|
||||||
|
*/
|
||||||
|
studyTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* Total time spent on testing
|
||||||
|
*/
|
||||||
|
testingTime: number /* int */;
|
||||||
|
/**
|
||||||
|
* The project manager who signed it
|
||||||
|
*/
|
||||||
|
signedBy?: number /* int */;
|
||||||
|
}
|
||||||
export interface WeeklyReport {
|
export interface WeeklyReport {
|
||||||
/**
|
/**
|
||||||
* The ID of the report
|
* The ID of the report
|
||||||
|
@ -106,6 +144,15 @@ export interface NewProject {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
export interface RoleChange {
|
||||||
|
role: 'project_manager' | 'user';
|
||||||
|
username: string;
|
||||||
|
projectname: string;
|
||||||
|
}
|
||||||
|
export interface NameChange {
|
||||||
|
id: number /* int */;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// source: users.go
|
// source: users.go
|
||||||
|
@ -138,3 +185,7 @@ export interface PublicUser {
|
||||||
export interface Token {
|
export interface Token {
|
||||||
token: string;
|
token: string;
|
||||||
}
|
}
|
||||||
|
export interface StrNameChange {
|
||||||
|
prevName: string;
|
||||||
|
newName: string;
|
||||||
|
}
|
||||||
|
|
|
@ -314,9 +314,8 @@ def test_get_weekly_reports_user():
|
||||||
|
|
||||||
# Get weekly reports for the user in the project
|
# Get weekly reports for the user in the project
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
getWeeklyReportsUserPath,
|
getWeeklyReportsUserPath + "/" + projectName,
|
||||||
headers={"Authorization": "Bearer " + token},
|
headers={"Authorization": "Bearer " + token},
|
||||||
params={"username": username, "projectName": projectName},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
dprint(response.text)
|
dprint(response.text)
|
||||||
|
@ -330,9 +329,8 @@ 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)
|
||||||
|
|
Loading…
Reference in a new issue