Merge branch 'dev' into gruppDM

This commit is contained in:
Davenludd 2024-03-20 21:21:59 +01:00
commit b9b17bf229
14 changed files with 325 additions and 62 deletions

View file

@ -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)
} }

View file

@ -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
}

View file

@ -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.")
}
}

View file

@ -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);

View file

@ -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

View file

@ -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())
} }

View file

@ -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

View file

@ -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"`
}

View file

@ -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)

View file

@ -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", {

View file

@ -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("");

View file

@ -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,
); );

View file

@ -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;
}

View file

@ -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)