Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: v0.18.0 #72

Merged
merged 65 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
007881b
chore(release): v0.0.2 [skip ci]
PedroChaparro Sep 20, 2023
b79e305
feat: Register student (#25)
PedroChaparro Sep 22, 2023
fea865d
chore(release): v0.1.0 [skip ci]
PedroChaparro Sep 22, 2023
d0baca9
fix(cd): Release development docker container (#26)
PedroChaparro Sep 22, 2023
849375c
chore(release): v0.1.1 [skip ci]
PedroChaparro Sep 22, 2023
2f89bc2
fix(cd): Run package pipeline when a tag is pushed (#27)
PedroChaparro Sep 22, 2023
43270f7
chore(release): v0.1.2 [skip ci]
PedroChaparro Sep 22, 2023
6609c90
fix(cd): Update tags filter
PedroChaparro Sep 22, 2023
c6a4310
chore(release): v0.1.3 [skip ci]
PedroChaparro Sep 22, 2023
50cbbac
fix(cd): Update pipeline trigger
PedroChaparro Sep 22, 2023
c0bc504
chore(release): v0.1.4 [skip ci]
PedroChaparro Sep 22, 2023
c662636
chore(cd): Restore tags filter
PedroChaparro Sep 22, 2023
26ad63f
refactor(accounts): Register student (#29)
PedroChaparro Sep 22, 2023
52edddd
feat: Register admin (#30)
PedroChaparro Sep 22, 2023
34fd9b9
chore(release): v0.2.0 [skip ci]
PedroChaparro Sep 22, 2023
f49dbb3
feat(session): Login endpoint (#31)
PedroChaparro Sep 22, 2023
01b0daf
chore(release): v0.3.0 [skip ci]
PedroChaparro Sep 22, 2023
8646b08
feat: Auth middlewares (#32)
PedroChaparro Sep 25, 2023
4ed970a
chore(release): v0.4.0 [skip ci]
PedroChaparro Sep 25, 2023
b297ec9
feat: Register teacher (#33)
PedroChaparro Sep 25, 2023
43db727
chore(release): v0.5.0 [skip ci]
PedroChaparro Sep 25, 2023
a3392f6
build: Remove binary step
PedroChaparro Sep 25, 2023
320e4e2
fix: Add CORS middleware
PedroChaparro Sep 25, 2023
cb05dbc
chore(release): v0.5.1 [skip ci]
PedroChaparro Sep 25, 2023
69b748f
Merge branch 'main' into dev
PedroChaparro Sep 25, 2023
a866d8e
feat: whoami (#38)
PedroChaparro Sep 25, 2023
67c48e2
chore(release): v0.6.0 [skip ci]
PedroChaparro Sep 25, 2023
81d5536
feat: Logout (#39)
PedroChaparro Sep 25, 2023
67d086e
chore(release): v0.7.0 [skip ci]
PedroChaparro Sep 25, 2023
7ba0762
feat: List admins (#40)
PedroChaparro Sep 25, 2023
25a06ca
chore(release): v0.8.0 [skip ci]
PedroChaparro Sep 25, 2023
7d85870
Merge branch 'main' into dev
PedroChaparro Sep 26, 2023
f4fdc3e
refactor: Return admins UUID (#42)
PedroChaparro Sep 27, 2023
09e15f8
feat: Create courses (#43)
PedroChaparro Sep 27, 2023
eb58249
chore(release): v0.9.0 [skip ci]
PedroChaparro Sep 27, 2023
752c910
refactor: Packages folders (#47)
PedroChaparro Sep 29, 2023
35af762
feat: Get invitation code (#50)
PedroChaparro Sep 29, 2023
7aa44ab
chore(release): v0.10.0 [skip ci]
PedroChaparro Sep 29, 2023
6206f3c
feat: Join course using invitation code (#51)
PedroChaparro Sep 29, 2023
00b8a38
chore(release): v0.11.0 [skip ci]
PedroChaparro Sep 29, 2023
2265a05
feat: Get teachers and students courses (#52)
PedroChaparro Sep 30, 2023
926c820
chore(release): v0.12.0 [skip ci]
PedroChaparro Sep 30, 2023
b9c6153
docs(openapi): Update spec (#54)
PedroChaparro Sep 30, 2023
28ec783
feat: Toggle course visibility (#55)
PedroChaparro Sep 30, 2023
850371e
chore(release): v0.13.0 [skip ci]
PedroChaparro Sep 30, 2023
cd78130
Merge branch 'main' into dev
PedroChaparro Sep 30, 2023
c534e71
fix: Send course information when an student joins using invitation c…
PedroChaparro Oct 4, 2023
386a69f
chore(release): v0.13.1 [skip ci]
PedroChaparro Oct 4, 2023
b8f1519
Merge branch 'main' into dev
PedroChaparro Oct 4, 2023
072a005
fix: Use case insensitive text for emails (#62)
PedroChaparro Oct 5, 2023
e2c0ebd
chore(release): v0.13.2 [skip ci]
PedroChaparro Oct 5, 2023
313d795
fix: Save who created admin and teacher accounts (#63)
PedroChaparro Oct 5, 2023
6b4f29d
chore(release): v0.13.3 [skip ci]
PedroChaparro Oct 5, 2023
7e7110b
feat: Rename course (#64)
PedroChaparro Oct 5, 2023
766ea63
chore(release): v0.14.0 [skip ci]
PedroChaparro Oct 5, 2023
f72482b
feat: Search students by full name (#65)
PedroChaparro Oct 6, 2023
88d4c31
chore(release): v0.15.0 [skip ci]
PedroChaparro Oct 6, 2023
565c90d
feat: Enroll student (#66)
PedroChaparro Oct 6, 2023
02bca07
chore(release): v0.16.0 [skip ci]
PedroChaparro Oct 6, 2023
f4b8741
feat: List enrolled students (#68)
PedroChaparro Oct 6, 2023
bc4a736
chore(release): v0.17.0 [skip ci]
PedroChaparro Oct 6, 2023
5703b9f
Merge branch 'main' into dev
PedroChaparro Oct 6, 2023
ae60ba4
feat: Get course by UUID (#71)
PedroChaparro Oct 8, 2023
172a823
chore(release): v0.18.0 [skip ci]
PedroChaparro Oct 8, 2023
ecf8703
Merge branch 'main' into dev
PedroChaparro Oct 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# [0.18.0](https://github.com/upb-code-labs/main-api/compare/v0.17.0...v0.18.0) (2023-10-08)


### Features

* Get course by UUID ([#71](https://github.com/upb-code-labs/main-api/issues/71)) ([ae60ba4](https://github.com/upb-code-labs/main-api/commit/ae60ba45081750d68edb079f201f0317eecd3ceb))



# [0.17.0](https://github.com/upb-code-labs/main-api/compare/v0.16.0...v0.17.0) (2023-10-06)


Expand Down Expand Up @@ -34,12 +43,3 @@



## [0.13.3](https://github.com/upb-code-labs/main-api/compare/v0.13.2...v0.13.3) (2023-10-05)


### Bug Fixes

* Save who created admin and teacher accounts ([#63](https://github.com/upb-code-labs/main-api/issues/63)) ([313d795](https://github.com/upb-code-labs/main-api/commit/313d795ca236cbf2f188e9f3985a364a7d4ff25c))



55 changes: 55 additions & 0 deletions __tests__/integration/courses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,61 @@ type InvitationCodeTestCase struct {
ExpectedStatusCode int
}

func TestGetCourseByUUID(t *testing.T) {
c := require.New(t)

// Create a course
courseName := "Course [Test Get Course By UUID]"
courseUUID, code := CreateCourse(courseName)
c.Equal(http.StatusCreated, code)
c.NotEmpty(courseUUID)

testCases := []InvitationCodeTestCase{
{
CourseUUID: "not-valid",
ExpectedStatusCode: http.StatusBadRequest,
},
{
// Non-existent course
CourseUUID: "3febe413-d8cc-4d77-961a-cba1a4eaa64e",
ExpectedStatusCode: http.StatusNotFound,
},
{
CourseUUID: courseUUID,
ExpectedStatusCode: http.StatusOK,
},
}

// --- 1. Try with a teacher account ---
w, r := PrepareRequest("POST", "/api/v1/session/login", map[string]interface{}{
"email": registeredTeacherEmail,
"password": registeredTeacherPass,
})
router.ServeHTTP(w, r)
cookie := w.Result().Cookies()[0]

for _, testCase := range testCases {
response, code := GetCourseByUUID(cookie, testCase.CourseUUID)
c.Equal(testCase.ExpectedStatusCode, code)

if code == http.StatusOK {
c.Equal(courseName, response["name"])
c.Equal(courseUUID, response["uuid"])
c.NotEmpty(response["color"])
}
}
}

func GetCourseByUUID(cookie *http.Cookie, courseUUID string) (response map[string]interface{}, statusCode int) {
endpoint := fmt.Sprintf("/api/v1/courses/%s", courseUUID)
w, r := PrepareRequest("GET", endpoint, nil)
r.AddCookie(cookie)
router.ServeHTTP(w, r)

jsonResponse := ParseJsonResponse(w.Body)
return jsonResponse, w.Code
}

func TestGetInvitationCode(t *testing.T) {
c := require.New(t)

Expand Down
2 changes: 1 addition & 1 deletion sql/migrations/20230920232901_init.down.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DROP INDEX IF EXISTS idx_users_role;
-- ## Views
DROP VIEW IF EXISTS courses_with_color;

DROP VIEW IF EXISTS courses_has_users_views;
DROP VIEW IF EXISTS courses_has_users_view;

DROP VIEW IF EXISTS users_with_creator;

Expand Down
2 changes: 1 addition & 1 deletion sql/migrations/20230920232901_init.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ FROM

--- ### courses_has_users
CREATE
OR REPLACE VIEW courses_has_users_views AS
OR REPLACE VIEW courses_has_users_view AS
SELECT
courses_has_users.course_id,
courses.name AS course_name,
Expand Down
26 changes: 23 additions & 3 deletions src/courses/application/use_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ func (useCases *CoursesUseCases) SaveCourse(dto *dtos.CreateCourseDTO) (*entitie
return useCases.Repository.SaveCourse(dto)
}

func (useCases *CoursesUseCases) GetCourse(userUUID, courseUUID string) (*entities.Course, error) {
// Get the course
course, err := useCases.Repository.GetCourseByUUID(courseUUID)
if err != nil {
return nil, err
}

// Check the user is enrolled in the course
isStudentInCourse, err := useCases.Repository.IsUserInCourse(userUUID, courseUUID)
if err != nil {
return nil, err
}
if !isStudentInCourse {
return nil, errors.UserNotInCourseError{}
}

// Return the data
return course, nil
}

func (useCases *CoursesUseCases) JoinCourseUsingInvitationCode(dto *dtos.JoinCourseUsingInvitationCodeDTO) (*entities.Course, error) {
// Get the course by the invitation code
course, err := useCases.Repository.GetCourseByInvitationCode(dto.InvitationCode)
Expand All @@ -99,7 +119,7 @@ func (useCases *CoursesUseCases) JoinCourseUsingInvitationCode(dto *dtos.JoinCou
}

// Check if the student is already in the course
isStudentInCourse, err := useCases.Repository.IsStudentInCourse(dto.StudentUUID, course.UUID)
isStudentInCourse, err := useCases.Repository.IsUserInCourse(dto.StudentUUID, course.UUID)
if err != nil {
return nil, err
}
Expand All @@ -119,7 +139,7 @@ func (useCases *CoursesUseCases) GetEnrolledCourses(userUUID string) (*dtos.Enro

func (useCases *CoursesUseCases) ToggleCourseVisibility(courseUUID, userUUID string) (bool, error) {
// Check the user is enrolled in the course
isStudentInCourse, err := useCases.Repository.IsStudentInCourse(userUUID, courseUUID)
isStudentInCourse, err := useCases.Repository.IsUserInCourse(userUUID, courseUUID)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -165,7 +185,7 @@ func (useCases *CoursesUseCases) AddStudentToCourse(dto *dtos.AddStudentToCourse
}

// Check the student is not already in the course
isStudentInCourse, err := useCases.Repository.IsStudentInCourse(dto.StudentUUID, dto.CourseUUID)
isStudentInCourse, err := useCases.Repository.IsUserInCourse(dto.StudentUUID, dto.CourseUUID)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion src/courses/domain/definitions/courses_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type CoursesRepository interface {
GetCourseByInvitationCode(invitationCode string) (*entities.Course, error)

AddStudentToCourse(studentUUID, courseUUID string) error
IsStudentInCourse(studentUUID, courseUUID string) (bool, error)
IsUserInCourse(userUUID, courseUUID string) (bool, error)
GetEnrolledCourses(studentUUID string) (*dtos.EnrolledCoursesDto, error)
GetEnrolledStudents(courseUUID string) ([]*dtos.EnrolledStudentDTO, error)

Expand Down
26 changes: 26 additions & 0 deletions src/courses/infrastructure/http/http_controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,32 @@ func (controller *CoursesController) HandleCreateCourse(c *gin.Context) {
})
}

func (controller *CoursesController) HandleGetCourse(c *gin.Context) {
user_uuid := c.GetString("session_uuid")

// Validate course uuid
courseUUID := c.Param("course_uuid")
if err := infrastructure.GetValidator().Var(courseUUID, "uuid4"); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "Invalid course uuid",
})
return
}

// Get course
course, err := controller.UseCases.GetCourse(user_uuid, courseUUID)
if err != nil {
c.Error(err)
return
}

c.JSON(http.StatusOK, gin.H{
"uuid": course.UUID,
"name": course.Name,
"color": course.Color,
})
}

func (controller *CoursesController) HandleGetInvitationCode(c *gin.Context) {
teacherUUID := c.GetString("session_uuid")

Expand Down
7 changes: 7 additions & 0 deletions src/courses/infrastructure/http/http_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ func StartCoursesRoutes(g *gin.RouterGroup) {
controller.HandleGetEnrolledCourses,
)

coursesGroup.GET(
":course_uuid",
infrastructure.WithAuthenticationMiddleware(),
infrastructure.WithAuthorizationMiddleware([]string{"teacher", "student"}),
controller.HandleGetCourse,
)

coursesGroup.GET(
":course_uuid/invitation-code",
infrastructure.WithAuthenticationMiddleware(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,19 @@ func (repository *CoursesPostgresRepository) AddStudentToCourse(studentUUID, cou
return nil
}

func (repository *CoursesPostgresRepository) IsStudentInCourse(studentUUID, courseUUID string) (bool, error) {
func (repository *CoursesPostgresRepository) IsUserInCourse(userUUID, courseUUID string) (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()

query := `
SELECT COUNT(user_id) > 0
FROM courses_has_users
WHERE course_id = $1 AND user_id = $2
FROM courses_has_users_view
WHERE course_id = $1 AND
user_id = $2 AND
is_user_active = TRUE
`

row := repository.Connection.QueryRowContext(ctx, query, courseUUID, studentUUID)
row := repository.Connection.QueryRowContext(ctx, query, courseUUID, userUUID)
if row.Err() != nil {
return false, row.Err()
}
Expand All @@ -296,7 +298,7 @@ func (repository *CoursesPostgresRepository) GetEnrolledCourses(studentUUID stri

query := `
SELECT course_id, course_teacher_id, course_name, course_color, is_class_hidden
FROM courses_has_users_views
FROM courses_has_users_view
WHERE user_id = $1
AND is_user_active = TRUE
`
Expand Down Expand Up @@ -381,7 +383,7 @@ func (repository *CoursesPostgresRepository) GetEnrolledStudents(courseUUID stri

query := `
SELECT user_id, user_full_name, user_email, user_institutional_id, is_user_active
FROM courses_has_users_views
FROM courses_has_users_view
WHERE course_id = $1 AND user_role = 'student'
`

Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "0.17.0"
"version": "0.18.0"
}
Loading