Skip to content

Commit

Permalink
test(submissions): Add test to ensure students can receive real time …
Browse files Browse the repository at this point in the history
…updates about their submissions
  • Loading branch information
PedroChaparro committed Jan 7, 2024
1 parent a80f19c commit 536c91b
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
23 changes: 23 additions & 0 deletions __tests__/integration/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/UPB-Code-Labs/main-api/src/accounts/infrastructure/requests"
configInfrastructure "github.com/UPB-Code-Labs/main-api/src/config/infrastructure"
sharedInfrastructure "github.com/UPB-Code-Labs/main-api/src/shared/infrastructure"
submissionsImplementations "github.com/UPB-Code-Labs/main-api/src/submissions/infrastructure/implementations"
"github.com/gin-gonic/gin"
)

Expand Down Expand Up @@ -42,6 +43,13 @@ func TestMain(m *testing.M) {
setupDatabase()
defer sharedInfrastructure.ClosePostgresConnection()

// Setup RabbitMQ
setupRabbitMQ()
defer sharedInfrastructure.CloseRabbitMQConnection()

// Setup SSE
setupSSE()

// Setup http router
setupRouter()
registerBaseAccounts()
Expand All @@ -56,6 +64,21 @@ func setupDatabase() {
configInfrastructure.RunMigrations()
}

func setupRabbitMQ() {
// Connect to RabbitMQ
sharedInfrastructure.ConnectToRabbitMQ()

// Start listening for messages in the submissions real time updates queue
submissionsRealTimeUpdatesQueueMgr := submissionsImplementations.GetSubmissionsRealTimeUpdatesQueueMgrInstance()
go submissionsRealTimeUpdatesQueueMgr.ListenForUpdates()
}

func setupSSE() {
// Start listening for SSE connections
realTimeSubmissionsUpdatesSender := submissionsImplementations.GetSubmissionsRealTimeUpdatesSenderInstance()
go realTimeSubmissionsUpdatesSender.Listen()
}

func setupRouter() {
router = configInfrastructure.InstanceHttpServer()
}
Expand Down
69 changes: 69 additions & 0 deletions __tests__/integration/submissions_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package integration

import (
"bufio"
"encoding/json"
"net/http"
"strings"
"testing"

submissionsDTOs "github.com/UPB-Code-Labs/main-api/src/submissions/domain/dtos"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -87,4 +91,69 @@ func TestSubmitSolutionToTestBlock(t *testing.T) {

c.Equal(http.StatusCreated, status)
c.NotEmpty(submissionResponse["uuid"])

// ## Get submission status
submissionUUID := submissionResponse["uuid"].(string)

response := GetRealTimeSubmissionStatus(testBlockUUID, cookie)
c.Nil(response.err)

// Receive events
EXPECTED_EVENTS_COUNT := 3
receivedEventsCount := 0
receivedEvents := make(
[]*submissionsDTOs.SubmissionStatusUpdateDTO,
EXPECTED_EVENTS_COUNT,
)

scanner := bufio.NewScanner(response.w.Body)
for scanner.Scan() {
// Read the rew text
response := scanner.Text()

// Check if it is a data event
isData := strings.HasPrefix(response, "data:")
if !isData {
continue
}

// Remove the prefix
response = strings.TrimPrefix(response, "data:")
response = strings.TrimSpace(response)

var event submissionsDTOs.SubmissionStatusUpdateDTO
err := json.Unmarshal([]byte(response), &event)
c.Nil(err)

// Add the event to the list
receivedEvents[receivedEventsCount] = &event

receivedEventsCount++
if receivedEventsCount == EXPECTED_EVENTS_COUNT {
break
}
}

c.Nil(scanner.Err())

// Check the events
partialEventsStatus := []string{
"pending",
"running",
}

c.Equal(EXPECTED_EVENTS_COUNT, receivedEventsCount)
for idx, event := range receivedEvents {
c.Equal(submissionUUID, event.SubmissionUUID)

if idx < 2 {
c.Equal(partialEventsStatus[idx], event.SubmissionStatus)
c.False(event.TestsPassed)
c.Empty(event.TestsOutput)
} else {
c.Equal("ready", event.SubmissionStatus)
c.True(event.TestsPassed)
c.NotEmpty(event.TestsOutput)
}
}
}
40 changes: 40 additions & 0 deletions __tests__/integration/submissions_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,43 @@ func SubmitSolutionToTestBlock(dto *SubmitSToTestBlockUtilsDTO) (response map[st
jsonResponse := ParseJsonResponse(w.Body)
return jsonResponse, w.Code
}

type closeNotifierRecorder struct {
*httptest.ResponseRecorder
closeNotify chan bool
}

func (c *closeNotifierRecorder) CloseNotify() <-chan bool {
return c.closeNotify
}

type RealTimeSubmissionStatusResponse struct {
w *closeNotifierRecorder
r *http.Request
err error
}

// GetRealTimeSubmissionStatus sends a request to the server to get the real time status of a submission and returns the response recorder
func GetRealTimeSubmissionStatus(testBlockUUID string, cookie *http.Cookie) *RealTimeSubmissionStatusResponse {
// Create the request
endpoint := fmt.Sprintf("/api/v1/submissions/%s/status", testBlockUUID)
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return &RealTimeSubmissionStatusResponse{err: err}
}

req.AddCookie(cookie)

// Send the request
w := &closeNotifierRecorder{
ResponseRecorder: httptest.NewRecorder(),
closeNotify: make(chan bool, 1),
}
router.ServeHTTP(w, req)

return &RealTimeSubmissionStatusResponse{
w: w,
r: req,
err: err,
}
}

0 comments on commit 536c91b

Please sign in to comment.