Skip to content

Commit

Permalink
Fix class; Update letterBytes for random string
Browse files Browse the repository at this point in the history
  • Loading branch information
suntt2019 committed Feb 25, 2021
1 parent 828563d commit 3561edb
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 34 deletions.
23 changes: 2 additions & 21 deletions app/controller/class.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,8 @@ import (
"github.com/pkg/errors"
"gorm.io/gorm"
"net/http"
"sync"
)

var inviteCodeLock sync.Mutex

func GenerateInviteCode() (code string) {
inviteCodeLock.Lock()
defer inviteCodeLock.Unlock()
crashed := true
for crashed {
// 5: Fixed invite code length
code = utils.RandStr(5)
crashed = false
var count int64
utils.PanicIfDBError(base.DB.Model(models.Class{}).Where("invite_code = ?", code).Count(&count),
"could not check if invite code crashed for generating invite code")
crashed = count >= 1
}
return
}

func CreateClass(c echo.Context) error {
user := c.Get("user").(models.User)
req := request.CreateClassRequest{}
Expand All @@ -43,7 +24,7 @@ func CreateClass(c echo.Context) error {
Name: req.Name,
CourseName: req.CourseName,
Description: req.Description,
InviteCode: GenerateInviteCode(),
InviteCode: utils.GenerateInviteCode(),
Managers: []models.User{
user,
},
Expand Down Expand Up @@ -171,7 +152,7 @@ func RefreshInviteCode(c echo.Context) error {
panic(errors.Wrap(err, "could not find class for refreshing invite code"))
}
}
class.InviteCode = GenerateInviteCode()
class.InviteCode = utils.GenerateInviteCode()
utils.PanicIfDBError(base.DB.Save(&class), "could not update class for refreshing invite code")
return c.JSON(http.StatusOK, response.RefreshInviteCodeResponse{
Message: "SUCCESS",
Expand Down
16 changes: 5 additions & 11 deletions app/controller/class_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package controller_test

import (
"fmt"
"github.com/leoleoasd/EduOJBackend/app/controller"
"github.com/leoleoasd/EduOJBackend/app/request"
"github.com/leoleoasd/EduOJBackend/app/response"
"github.com/leoleoasd/EduOJBackend/app/response/resource"
"github.com/leoleoasd/EduOJBackend/base"
"github.com/leoleoasd/EduOJBackend/base/utils"
"github.com/leoleoasd/EduOJBackend/database/models"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
Expand All @@ -16,14 +16,14 @@ import (
)

func checkInviteCode(t *testing.T, code string) {
assert.Regexp(t, regexp.MustCompile("^[a-zA-Z]{5}$"), code)
assert.Regexp(t, regexp.MustCompile("^[a-zA-Z2-9]{5}$"), code)
var count int64
assert.NoError(t, base.DB.Model(models.Class{}).Where("invite_code = ?", code).Count(&count).Error)
assert.Equal(t, int64(1), count)
}

func createClassForTest(t *testing.T, name string, id int, managers, students []models.User) models.Class {
inviteCode := controller.GenerateInviteCode()
inviteCode := utils.GenerateInviteCode()
class := models.Class{
Name: fmt.Sprintf("test_%s_%d_name", name, id),
CourseName: fmt.Sprintf("test_%s_%d_course_name", name, id),
Expand All @@ -36,12 +36,6 @@ func createClassForTest(t *testing.T, name string, id int, managers, students []
return class
}

func TestGenerateInviteCode(t *testing.T) {
t.Parallel()
class := createClassForTest(t, "test_generate_invite_code_success", 0, nil, nil)
checkInviteCode(t, class.InviteCode)
}

func TestCreateClass(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -733,7 +727,7 @@ func TestJoinClass(t *testing.T) {
method: "POST",
path: base.Echo.Reverse("class.joinClass", -1),
req: request.JoinClassRequest{
InviteCode: controller.GenerateInviteCode(),
InviteCode: utils.GenerateInviteCode(),
},
reqOptions: []reqOption{applyAdminUser},
statusCode: http.StatusNotFound,
Expand All @@ -745,7 +739,7 @@ func TestJoinClass(t *testing.T) {
method: "POST",
path: base.Echo.Reverse("class.joinClass", class1.ID),
req: request.JoinClassRequest{
InviteCode: controller.GenerateInviteCode(),
InviteCode: utils.GenerateInviteCode(),
},
reqOptions: []reqOption{applyNormalUser},
statusCode: http.StatusForbidden,
Expand Down
2 changes: 1 addition & 1 deletion app/request/class.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type RefreshInviteCodeRequest struct {
}

type JoinClassRequest struct {
InviteCode string `json:"invite_code" form:"invite_code" query:"invite_code" validate:"required,alpha,max=255"`
InviteCode string `json:"invite_code" form:"invite_code" query:"invite_code" validate:"required,max=255"`
}

type DeleteClassRequest struct {
Expand Down
22 changes: 22 additions & 0 deletions base/utils/class.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package utils

import (
"github.com/leoleoasd/EduOJBackend/base"
"github.com/leoleoasd/EduOJBackend/database/models"
"sync"
)

var inviteCodeLock sync.Mutex

func GenerateInviteCode() (code string) {
inviteCodeLock.Lock()
defer inviteCodeLock.Unlock()
var count int64 = 1
for count > 0 {
// 5: Fixed invite code length
code = RandStr(5)
PanicIfDBError(base.DB.Model(models.Class{}).Where("invite_code = ?", code).Count(&count),
"could not check if invite code crashed for generating invite code")
}
return
}
37 changes: 37 additions & 0 deletions base/utils/class_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package utils

import (
"fmt"
"github.com/leoleoasd/EduOJBackend/base"
"github.com/leoleoasd/EduOJBackend/database/models"
"github.com/stretchr/testify/assert"
"regexp"
"testing"
)

func checkInviteCode(t *testing.T, code string) {
assert.Regexp(t, regexp.MustCompile("^[a-zA-Z2-9]{5}$"), code)
var count int64
assert.NoError(t, base.DB.Model(models.Class{}).Where("invite_code = ?", code).Count(&count).Error)
assert.Equal(t, int64(1), count)
}

func createClassForTest(t *testing.T, name string, id int, managers, students []models.User) models.Class {
inviteCode := GenerateInviteCode()
class := models.Class{
Name: fmt.Sprintf("test_%s_%d_name", name, id),
CourseName: fmt.Sprintf("test_%s_%d_course_name", name, id),
Description: fmt.Sprintf("test_%s_%d_description", name, id),
InviteCode: inviteCode,
Managers: managers,
Students: students,
}
assert.NoError(t, base.DB.Create(&class).Error)
return class
}

func TestGenerateInviteCode(t *testing.T) {
t.Parallel()
class := createClassForTest(t, "test_generate_invite_code_success", 0, nil, nil)
checkInviteCode(t, class.InviteCode)
}
2 changes: 1 addition & 1 deletion base/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

// Random string generator by https://stackoverflow.com/a/22892986/8031146

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const letterBytes = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
Expand Down

0 comments on commit 3561edb

Please sign in to comment.