Skip to content

Commit

Permalink
Merge pull request #145 from kossiitkgp/v2-mentor-dashboard
Browse files Browse the repository at this point in the history
[v2] /mentor/dashboard route added
  • Loading branch information
YoganshSharma authored Jul 19, 2023
2 parents 00662b2 + 95a12ba commit 3b4696e
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 0 deletions.
124 changes: 124 additions & 0 deletions controllers/mentor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controllers
import (
"fmt"
"net/http"
"strings"

"github.com/kossiitkgp/kwoc-backend/v2/middleware"
"github.com/kossiitkgp/kwoc-backend/v2/utils"
Expand All @@ -18,6 +19,33 @@ type RegisterMentorReqFields struct {
Email string `json:"email"`
}

type ProjectInfo struct {
Name string `json:"name"`
RepoLink string `json:"repo_link"`
ProjectStatus bool `json:"project_status"`

CommitCount uint `json:"commit_count"`
PullCount uint `json:"pull_count"`
LinesAdded uint `json:"lines_added"`
LinesRemoved uint `json:"lines_removed"`

Pulls []string `json:"pulls"`
}

type StudentInfo struct {
Name string `json:"name"`
Username string `json:"username"`
}

type MentorDashboard struct {
Name string `json:"name"`
Username string `json:"username"`
Email string `json:"email"`

Projects []ProjectInfo `json:"projects"`
Students []StudentInfo `json:"students"`
}

func RegisterMentor(w http.ResponseWriter, r *http.Request) {
app := r.Context().Value(middleware.APP_CTX_KEY).(*middleware.App)
db := app.Db
Expand Down Expand Up @@ -106,3 +134,99 @@ func FetchAllMentors(w http.ResponseWriter, r *http.Request) {

utils.RespondWithJson(r, w, mentors)
}

// /mentor/dashboard/ functions

func CreateMentorDashboard(mentor models.Mentor, db *gorm.DB) MentorDashboard {
var projects []models.Project
var projectsInfo []ProjectInfo
var students []StudentInfo

db.Table("projects").
Where("mentor_id = ? OR secondary_mentor_id = ?", mentor.ID, mentor.ID).
Select("name", "repo_link", "commit_count", "pull_count", "lines_added", "lines_removed", "contributors", "pulls", "project_status").
Find(&projects)

studentMap := make(map[string]bool)
var studentUsernames []string
for _, project := range projects {
pulls := make([]string, 0)
if len(project.Pulls) != 0 {
pulls = strings.Split(project.Pulls, ",")
}

projectInfo := ProjectInfo{
Name: project.Name,
RepoLink: project.RepoLink,
ProjectStatus: project.ProjectStatus,

CommitCount: project.CommitCount,
PullCount: project.PullCount,
LinesAdded: project.LinesAdded,
LinesRemoved: project.LinesRemoved,

Pulls: pulls,
}
projectsInfo = append(projectsInfo, projectInfo)

for _, studentUsername := range strings.Split(project.Contributors, ",") {
contains := studentMap[studentUsername]
if contains {
continue
}

studentMap[studentUsername] = true
studentUsernames = append(studentUsernames, studentUsername)
}
}
db.Table("students").Where("username IN ?", studentUsernames).
Select("name", "username").Find(&students)

return MentorDashboard{
Name: mentor.Name,
Username: mentor.Username,
Email: mentor.Email,

Projects: projectsInfo,
Students: students,
}
}

func FetchMentorDashboard(w http.ResponseWriter, r *http.Request) {
app := r.Context().Value(middleware.APP_CTX_KEY).(*middleware.App)
db := app.Db

var modelMentor models.Mentor

login_username := r.Context().Value(middleware.LoginCtxKey(middleware.LOGIN_CTX_USERNAME_KEY))
tx := db.
Table("mentors").
Where("username = ?", login_username).
Select("name", "username", "email", "ID").
First(&modelMentor)

if tx.Error == gorm.ErrRecordNotFound {
utils.LogErrAndRespond(
r,
w,
tx.Error,
fmt.Sprintf("Mentor `%s` does not exists.", login_username),
http.StatusBadRequest,
)
return
}
if tx.Error != nil {
utils.LogErrAndRespond(
r,
w,
tx.Error,
fmt.Sprintf("Database Error fetching mentor with username `%s`", login_username),
http.StatusInternalServerError,
)
return
}

mentor := CreateMentorDashboard(modelMentor, db)

utils.RespondWithJson(r, w, mentor)
}
143 changes: 143 additions & 0 deletions controllers/mentor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"strings"
"testing"

"github.com/kossiitkgp/kwoc-backend/v2/controllers"
Expand Down Expand Up @@ -196,3 +198,144 @@ func TestFetchMentorOK(t *testing.T) {
}
}
}

// Test unauthenticated request to /mentor/dashboard/
func TestMentorDashboardNoAuth(t *testing.T) {
testRequestNoAuth(t, "GET", "/mentor/dashboard/")
}

// Test request to /mentor/dashboard/ with invalid jwt
func TestMentorDashboardInvalidAuth(t *testing.T) {
testRequestInvalidAuth(t, "GET", "/mentor/dashboard/")
}

// Test unauthenticated request to /mentor/dashboard/ with no registration
func TestMentorDashboardNoReg(t *testing.T) {
// Set up a local test database path
db := setTestDB()
defer unsetTestDB()

// Generate a jwt secret key for testing
setTestJwtSecretKey()
defer unsetTestJwtSecretKey()

// Test login fields
testUsername := getTestUsername()
testLoginFields := utils.LoginJwtFields{Username: testUsername}

testJwt, _ := utils.GenerateLoginJwtString(testLoginFields)

req, _ := http.NewRequest(
"GET",
"/mentor/dashboard/",
nil,
)
req.Header.Add("Bearer", testJwt)

res := executeRequest(req, db)

expectStatusCodeToBe(t, res, http.StatusBadRequest)
expectResponseBodyToBe(t, res, fmt.Sprintf("Mentor `%s` does not exists.", testUsername))
}

// Test requests to /mentor/dashboard/ with registered and proper authentication
func TestMentorDashboardOK(t *testing.T) {
// Set up a local test database path
db := setTestDB()
defer unsetTestDB()

// Generate a jwt secret key for testing
setTestJwtSecretKey()
defer unsetTestJwtSecretKey()

// Test login fields
testUsername := getTestUsername()
testLoginFields := utils.LoginJwtFields{Username: testUsername}

testJwt, _ := utils.GenerateLoginJwtString(testLoginFields)

modelMentor := models.Mentor{
Name: "TestMentor",
Email: "iamamentor@cool.com",
Username: testUsername,
}

db.Table("mentors").Create(&modelMentor)

testProjects := generateTestProjects(5, false, true)
testProjects[1].MentorId = int32(modelMentor.ID)
testProjects[3].SecondaryMentorId = int32(modelMentor.ID)

var projects []controllers.ProjectInfo
var students []controllers.StudentInfo

modelStudents := generateTestStudents(5)

for i, student := range modelStudents {
if i < 3 {
testProjects[1].Contributors = testProjects[1].Contributors + student.Username + ","
} else {
testProjects[3].Contributors = testProjects[3].Contributors + student.Username + ","
}
}

testProjects[1].Contributors = strings.TrimSuffix(testProjects[1].Contributors, ",")
testProjects[3].Contributors = strings.TrimSuffix(testProjects[3].Contributors, ",")

for _, p := range testProjects {
if (p.MentorId != int32(modelMentor.ID)) && (p.SecondaryMentorId != int32(modelMentor.ID)) {
continue
}

pulls := make([]string, 0)

projects = append(projects, controllers.ProjectInfo{
Name: p.Name,
RepoLink: p.RepoLink,
ProjectStatus: p.ProjectStatus,

CommitCount: p.CommitCount,
PullCount: p.PullCount,
LinesAdded: p.LinesAdded,
LinesRemoved: p.LinesRemoved,

Pulls: pulls,
})
}

for _, student := range modelStudents {
students = append(students, controllers.StudentInfo{
Name: student.Name,
Username: student.Username,
})
}

db.Table("projects").Create(testProjects)
db.Table("students").Create(modelStudents)

testMentor := controllers.MentorDashboard{
Name: modelMentor.Name,
Username: modelMentor.Username,
Email: modelMentor.Email,

Projects: projects,
Students: students,
}

req, _ := http.NewRequest(
"GET",
"/mentor/dashboard/",
nil,
)
req.Header.Add("Bearer", testJwt)

res := executeRequest(req, db)

var resMentor controllers.MentorDashboard
_ = json.NewDecoder(res.Body).Decode(&resMentor)

expectStatusCodeToBe(t, res, http.StatusOK)
if !reflect.DeepEqual(testMentor, resMentor) {
t.Fatalf("Incorrect data returned from /mentor/dashboard/")
}
}
6 changes: 6 additions & 0 deletions server/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ func getRoutes(app *middleware.App) []Route {
"/mentor/all/",
middleware.WithLogin(middleware.WrapApp(app, controllers.FetchAllMentors)),
},
{
"Mentor Dashboard",
"GET",
"/mentor/dashboard/",
middleware.WithLogin(middleware.WrapApp(app, controllers.FetchMentorDashboard)),
},
{
"HealthCheck",
"GET",
Expand Down

0 comments on commit 3b4696e

Please sign in to comment.