From 716b7a67daf90dba750ead076d876367339e4fec Mon Sep 17 00:00:00 2001 From: Vojtech Mares Date: Sun, 19 May 2024 10:08:02 +0200 Subject: [PATCH] test(server): add tests for training date attendee --- internal/server/server_test.go | 561 ++++++++++++++++++++++++++++++++- 1 file changed, 549 insertions(+), 12 deletions(-) diff --git a/internal/server/server_test.go b/internal/server/server_test.go index 320e44a..136911c 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "github.com/gofiber/fiber/v2" + "github.com/google/uuid" "github.com/oapi-codegen/runtime/types" "github.com/shopspring/decimal" "github.com/stretchr/testify/assert" @@ -636,6 +637,48 @@ func TestServer(t *testing.T) { } }) + t.Run("Training date attendee not found", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+uuid.New().String()) + assert.Equal(t, http.StatusNotFound, rr.StatusCode) + + var notFound NotFoundError + err := json.NewDecoder(rr.Body).Decode(¬Found) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, http.StatusNotFound, notFound.Status) + }) + t.Run("Add training date attendee", func(t *testing.T) { tr := &training.Training{ Name: "Testing Training for training date", @@ -671,7 +714,7 @@ func TestServer(t *testing.T) { newTrainingDateAttendee := NewTrainingDateAttendee{ Name: "John Doe", - Email: "john.doe@example.com", + Email: types.Email("john.doe@example.com"), Company: "Acme Inc.", Position: "Software Engineer", Phone: "+420 123 456 789", @@ -681,21 +724,515 @@ func TestServer(t *testing.T) { rr, _ := doPost(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees", newTrainingDateAttendee) assert.Equal(t, http.StatusCreated, rr.StatusCode) + var attendeeResponse TrainingDateAttendee + err := json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, newTrainingDateAttendee.Name, attendeeResponse.Name) + assert.Equal(t, newTrainingDateAttendee.Email, attendeeResponse.Email) + assert.Equal(t, newTrainingDateAttendee.Company, attendeeResponse.Company) + assert.Equal(t, newTrainingDateAttendee.Position, attendeeResponse.Position) + assert.Equal(t, newTrainingDateAttendee.Phone, attendeeResponse.Phone) + assert.Equal(t, newTrainingDateAttendee.IsStudent, attendeeResponse.IsStudent) + assert.Equal(t, td.Price.Amount.String(), attendeeResponse.Bill.Amount) + assert.Equal(t, td.Price.Currency, attendeeResponse.Bill.Currency) + assert.Equal(t, false, attendeeResponse.HasPaid) + assert.Equal(t, false, attendeeResponse.HasAttended) + }) + + t.Run("List all training date attendees", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attendeeCount := 9 + attendees := make([]training.TrainingDateAttendee, attendeeCount) + for i := range attendeeCount { + nAtd := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: false, + } + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, nAtd) + attendees[i] = *nAtd + } + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees") + assert.Equal(t, http.StatusOK, rr.StatusCode) + + var attendeesResponse ListTrainingDateAttendeesResponse + err := json.NewDecoder(rr.Body).Decode(&attendeesResponse) + assert.NoError(t, err, "error getting response", err) + + assert.Equal(t, attendeeCount, len(attendeesResponse)) + + for i, attendee := range attendeesResponse { + assert.Equal(t, attendees[i].Name, attendee.Name) + assert.Equal(t, attendees[i].Email, string(attendee.Email)) + assert.Equal(t, attendees[i].Company, attendee.Company) + assert.Equal(t, attendees[i].Position, attendee.Position) + assert.Equal(t, attendees[i].IsStudent, *attendee.IsStudent) + assert.Equal(t, attendees[i].Phone, attendee.Phone) + assert.Equal(t, attendees[i].Bill.Amount.String(), attendee.Bill.Amount) + assert.Equal(t, attendees[i].Bill.Currency, attendee.Bill.Currency) + assert.Equal(t, attendees[i].HasPaid, attendee.HasPaid) + assert.Equal(t, attendees[i].HasAttended, attendee.HasAttended) + } + }) + + t.Run("Get training date attendee", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attendee := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: false, + } + + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee) + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + var resultTrainingDateAttendee TrainingDateAttendee err := json.NewDecoder(rr.Body).Decode(&resultTrainingDateAttendee) assert.NoError(t, err, "error unmarshalling response") - assert.Equal(t, newTrainingDateAttendee.Name, resultTrainingDateAttendee.Name) - assert.Equal(t, newTrainingDateAttendee.Email, resultTrainingDateAttendee.Email) - assert.Equal(t, newTrainingDateAttendee.Company, resultTrainingDateAttendee.Company) - assert.Equal(t, newTrainingDateAttendee.Position, resultTrainingDateAttendee.Position) - assert.Equal(t, newTrainingDateAttendee.IsStudent, resultTrainingDateAttendee.IsStudent) - assert.Equal(t, newTrainingDateAttendee.Phone, resultTrainingDateAttendee.Phone) + assert.Equal(t, attendee.Name, resultTrainingDateAttendee.Name) + assert.Equal(t, attendee.Email, string(resultTrainingDateAttendee.Email)) + assert.Equal(t, attendee.Company, resultTrainingDateAttendee.Company) + assert.Equal(t, attendee.Position, resultTrainingDateAttendee.Position) + assert.Equal(t, attendee.IsStudent, *resultTrainingDateAttendee.IsStudent) + assert.Equal(t, attendee.Phone, resultTrainingDateAttendee.Phone) + assert.Equal(t, attendee.Bill.Amount.String(), resultTrainingDateAttendee.Bill.Amount) + assert.Equal(t, attendee.Bill.Currency, resultTrainingDateAttendee.Bill.Currency) + assert.Equal(t, attendee.HasPaid, resultTrainingDateAttendee.HasPaid) + assert.Equal(t, attendee.HasAttended, resultTrainingDateAttendee.HasAttended) + }) - amount, _ := decimal.NewFromString(resultTrainingDateAttendee.Bill.Amount) + t.Run("Update training date attendee", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } - assert.Equal(t, td.Price.Amount, amount) - assert.Equal(t, td.Price.Currency, resultTrainingDateAttendee.Bill.Currency) - assert.Equal(t, resultTrainingDateAttendee.HasPaid, false) - assert.Equal(t, resultTrainingDateAttendee.HasAttended, false) + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attendee := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: false, + } + + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee) + + newTrainingDateAttendee := NewTrainingDateAttendee{ + Name: "John Doe", + Email: types.Email("jdoe@example.com"), + Company: "Acme Corp Inc.", + Position: "Senior Software Engineer", + Phone: "+420 987 654 321", + IsStudent: new(bool), + } + + rr, _ := doPut(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String(), newTrainingDateAttendee) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + var attendeeResponse UpdateTrainingDateAttendeeResponse + err := json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error getting response", err) + assert.Equal(t, newTrainingDateAttendee.Name, attendeeResponse.Name) + assert.Equal(t, newTrainingDateAttendee.Email, attendeeResponse.Email) + assert.Equal(t, newTrainingDateAttendee.Company, attendeeResponse.Company) + assert.Equal(t, newTrainingDateAttendee.Position, attendeeResponse.Position) + assert.Equal(t, newTrainingDateAttendee.Phone, attendeeResponse.Phone) + assert.Equal(t, newTrainingDateAttendee.IsStudent, attendeeResponse.IsStudent) + assert.Equal(t, td.Price.Amount.String(), attendeeResponse.Bill.Amount) + assert.Equal(t, td.Price.Currency, attendeeResponse.Bill.Currency) + assert.Equal(t, attendee.HasPaid, attendeeResponse.HasPaid) + assert.Equal(t, attendee.HasAttended, attendeeResponse.HasAttended) + }) + + t.Run("Delete training date attendee", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attendee := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: false, + } + + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee) + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + rr, _ = doDelete(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusNoContent, rr.StatusCode) + + rr, _ = doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusNotFound, rr.StatusCode) + }) + + t.Run("Mark training date attendee as paid", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + paid := TrainingDateAttendeePaymentUpdateRequest{ + Paid: true, + } + + attendee := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: !paid.Paid, + HasAttended: false, + } + + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee) + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + var attendeeResponse TrainingDateAttendee + err := json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, !paid.Paid, attendeeResponse.HasPaid) + + rr, _ = doPut(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()+"/paid", paid) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + err = json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, paid.Paid, attendeeResponse.HasPaid) + + rr, _ = doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + err = json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, paid.Paid, attendeeResponse.HasPaid) + }) + + t.Run("Mark training date attendee as attended", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attended := TrainingDateAttendeeAttendanceUpdateRequest{ + Attended: true, + } + + attendee := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: !attended.Attended, + } + + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee) + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + var attendeeResponse TrainingDateAttendee + err := json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, !attended.Attended, attendeeResponse.HasAttended) + + rr, _ = doPut(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()+"/attended", attended) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + err = json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, attended.Attended, attendeeResponse.HasAttended) + + rr, _ = doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/"+attendee.ID.String()) + assert.Equal(t, http.StatusOK, rr.StatusCode) + + err = json.NewDecoder(rr.Body).Decode(&attendeeResponse) + assert.NoError(t, err, "error unmarshalling response") + assert.Equal(t, attended.Attended, attendeeResponse.HasAttended) + }) + + t.Run("Get count of training date attendees", func(t *testing.T) { + tr := &training.Training{ + Name: "Testing Training for training date", + Description: "This is a test training for training date", + Days: 1, + Pricing: []training.TrainingPrice{ + { + Amount: decimal.NewFromInt(200), + Currency: "EUR", + Type: training.OpenTrainingPrice, + }, + }, + } + + _ = handlers.trainingRepository.Create(tr) + + date := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC) + + td := &training.TrainingDate{ + Address: "Test Address 123, NYC", + Capacity: 12, + Date: date, + Days: tr.Days, + IsOnline: false, + Location: "NYC", + StartTime: date, + Price: money.Price{ + Amount: decimal.NewFromInt(200), + Currency: "EUR", + }, + } + _ = handlers.trainingDateRepository.Create(tr.ID, td) + + attendeeCount := 9 + for range attendeeCount { + nAtd := &training.TrainingDateAttendee{ + Name: "John Doe", + Email: "john.doe@example.com", + Company: "Acme Inc.", + Position: "Software Engineer", + Phone: "+420 123 456 789", + IsStudent: false, + Bill: money.Price{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + HasPaid: false, + HasAttended: false, + } + _ = handlers.trainingDateAttendeeRepository.Create(td.ID, nAtd) + } + + rr, _ := doGet(t, app, "/v1/trainings/"+tr.ID.String()+"/dates/"+td.ID.String()+"/attendees/count") + assert.Equal(t, http.StatusOK, rr.StatusCode) + + var attendeesResponse GetTrainingDateAttendeeCountResponse + err := json.NewDecoder(rr.Body).Decode(&attendeesResponse) + assert.NoError(t, err, "error getting response", err) + + assert.Equal(t, int8(attendeeCount), attendeesResponse.Count) }) }