1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
mareshq-yggdrasil/internal/server/server_test.go
Vojtech Mares 2d32c80182
feat!: add slug to training
BREAKING CHANGE: update init migration
2024-06-26 22:24:36 +02:00

1199 lines
37 KiB
Go

package server
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/oapi-codegen/runtime/types"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"
"gitlab.mareshq.com/hq/yggdrasil/internal/money"
"gitlab.mareshq.com/hq/yggdrasil/pkg/slug"
"gitlab.mareshq.com/hq/yggdrasil/pkg/training"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
)
func doGet(t *testing.T, app *fiber.App, rawURL string) (*http.Response, error) {
u, err := url.Parse(rawURL)
if err != nil {
t.Fatalf("Invalid url: %s", rawURL)
}
req := httptest.NewRequest("GET", u.RequestURI(), nil)
req.Header.Add("Accept", "application/json")
req.Host = u.Host
return app.Test(req)
}
func doPost(t *testing.T, app *fiber.App, rawURL string, jsonBody interface{}) (*http.Response, error) {
u, err := url.Parse(rawURL)
if err != nil {
t.Fatalf("Invalid url: %s", rawURL)
}
buf, err := json.Marshal(jsonBody)
if err != nil {
return nil, err
}
req := httptest.NewRequest("POST", u.RequestURI(), bytes.NewReader(buf))
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Host = u.Host
return app.Test(req)
}
func doPut(t *testing.T, app *fiber.App, rawURL string, jsonBody interface{}) (*http.Response, error) {
u, err := url.Parse(rawURL)
if err != nil {
t.Fatalf("Invalid url: %s", rawURL)
}
buf, err := json.Marshal(jsonBody)
if err != nil {
return nil, err
}
req := httptest.NewRequest("PUT", u.RequestURI(), bytes.NewReader(buf))
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Host = u.Host
return app.Test(req)
}
func doDelete(t *testing.T, app *fiber.App, rawURL string) (*http.Response, error) {
u, err := url.Parse(rawURL)
if err != nil {
t.Fatalf("Invalid url: %s", rawURL)
}
req := httptest.NewRequest("DELETE", u.RequestURI(), nil)
req.Header.Add("Accept", "application/json")
req.Host = u.Host
return app.Test(req)
}
func TestServer(t *testing.T) {
//var err error
trainingRepo := training.NewInMemoryTrainingRepository()
trainingDateRepo := training.NewInMemoryDateRepository()
trainingDateAttendeeRepo := training.NewInMemoryAttendeeRepository()
handlers := NewAPIHandlers(trainingRepo, trainingDateRepo, trainingDateAttendeeRepo)
app := NewTestingServer(handlers)
t.Run("Add training", func(t *testing.T) {
newTraining := NewTraining{
Name: "Testing Training",
Description: "This is a test training",
Days: 1,
Pricing: []TrainingPrice{
{
Amount: "200",
Currency: "EUR",
Type: OPEN,
},
{
Amount: "1000",
Currency: "EUR",
Type: CORPORATE,
},
{
Amount: "4900",
Currency: "CZK",
Type: OPEN,
},
{
Amount: "24000",
Currency: "CZK",
Type: CORPORATE,
},
},
}
slugString := slug.NewString(newTraining.Name)
rr, _ := doPost(t, app, "/v1/trainings", newTraining)
assert.Equal(t, http.StatusCreated, rr.StatusCode)
var resultTraining Training
err := json.NewDecoder(rr.Body).Decode(&resultTraining)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, newTraining.Name, resultTraining.Name)
assert.Equal(t, slugString, resultTraining.Slug)
assert.Equal(t, newTraining.Description, resultTraining.Description)
assert.Equal(t, newTraining.Days, resultTraining.Days)
assert.Equal(t, newTraining.Pricing, resultTraining.Pricing)
})
t.Run("Training not found", func(t *testing.T) {
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d", 9999999))
assert.Equal(t, http.StatusNotFound, rr.StatusCode)
var trainingError NotFoundError
err := json.NewDecoder(rr.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
})
t.Run("List all trainings", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training",
Description: "This is a test training",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
rr, _ := doGet(t, app, "/v1/trainings")
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trainings []Training
err := json.NewDecoder(rr.Body).Decode(&trainings)
assert.NoError(t, err, "error unmarshalling response")
assert.Greater(t, len(trainings), 0)
})
t.Run("Update training", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training",
Description: "This is a test training",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
updatedSlug := "updated-training"
updTr := NewTraining{
Name: "Updated Training",
Slug: &updatedSlug,
Description: tr.Description,
Days: tr.Days,
Pricing: []TrainingPrice{
{
Amount: decimal.NewFromInt(200).String(),
Currency: money.EUR,
Type: OPEN,
},
},
}
rr, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID), updTr)
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trr Training
err := json.NewDecoder(rr.Body).Decode(&trr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, updTr.Name, trr.Name)
assert.Equal(t, updatedSlug, trr.Slug)
})
t.Run("Delete training", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training",
Description: "This is a test training",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID))
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trr Training
err := json.NewDecoder(rr.Body).Decode(&trr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, tr.ID, trr.Id)
drr, _ := doDelete(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID))
assert.Equal(t, http.StatusNoContent, drr.StatusCode)
rr, _ = doGet(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID))
assert.Equal(t, http.StatusNotFound, rr.StatusCode)
var trainingError NotFoundError
err = json.NewDecoder(rr.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
lrr, _ := doGet(t, app, "/v1/trainings")
assert.Equal(t, http.StatusOK, lrr.StatusCode)
})
t.Run("Add training date", 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
date := time.Date(2024, time.May, 1, 0, 0, 0, 0, time.UTC)
startTime := time.Date(2024, time.May, 1, 9, 0, 0, 0, time.UTC)
newTrainingDate := NewTrainingDate{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: types.Date{Time: date},
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: startTime.Format("15:04"),
Price: Price{
Amount: "200",
Currency: "EUR",
},
}
rr, err := doPost(t, app, fmt.Sprintf("/v1/trainings/%d/dates", tr.ID), newTrainingDate)
assert.Equal(t, http.StatusCreated, rr.StatusCode)
var resultTrainingDate TrainingDate
err = json.NewDecoder(rr.Body).Decode(&resultTrainingDate)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, newTrainingDate.Address, resultTrainingDate.Address)
assert.Equal(t, newTrainingDate.Location, resultTrainingDate.Location)
assert.Equal(t, newTrainingDate.Capacity, resultTrainingDate.Capacity)
assert.Equal(t, newTrainingDate.Days, resultTrainingDate.Days)
assert.Equal(t, newTrainingDate.StartTime, resultTrainingDate.StartTime)
assert.Equal(t, newTrainingDate.IsOnline, resultTrainingDate.IsOnline)
assert.Equal(t, newTrainingDate.Price, resultTrainingDate.Price)
assert.Equal(t, newTrainingDate.Date, resultTrainingDate.Date)
})
t.Run("Training date 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, 999999))
assert.Equal(t, http.StatusNotFound, rr.StatusCode)
var trainingError NotFoundError
err := json.NewDecoder(rr.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
})
t.Run("List all training dates", 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
date := time.Date(2024, time.May, 1, 0, 0, 0, 0, time.UTC)
td := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
trainingCount := 5
for range trainingCount {
_ = handlers.trainingDateRepository.Create(tr.ID, td)
}
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates", tr.ID))
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trainingDates []TrainingDate
err := json.NewDecoder(rr.Body).Decode(&trainingDates)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, len(trainingDates), trainingCount)
})
t.Run("Update training date", 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
date := time.Date(2024, time.May, 1, 0, 0, 0, 0, time.UTC)
td := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
updTd := NewTrainingDate{
Address: "Updated Address 123, NYC",
Capacity: 8,
Date: types.Date{Time: date},
Days: tr.Days,
IsOnline: true,
Location: "NYC",
StartTime: date.Format("15:04"),
Price: Price{
Amount: "200",
Currency: "EUR",
},
}
rr, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID), updTd)
assert.Equal(t, http.StatusOK, rr.StatusCode)
var tdrr TrainingDate
err := json.NewDecoder(rr.Body).Decode(&tdrr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, updTd.Address, tdrr.Address)
assert.Equal(t, updTd.Capacity, tdrr.Capacity)
assert.Equal(t, updTd.Date, tdrr.Date)
assert.Equal(t, updTd.Days, tdrr.Days)
assert.Equal(t, updTd.IsOnline, tdrr.IsOnline)
assert.Equal(t, updTd.Location, tdrr.Location)
assert.Equal(t, updTd.StartTime, tdrr.StartTime)
assert.Equal(t, updTd.Price, tdrr.Price)
})
t.Run("Delete training date", 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
date := time.Date(2024, time.May, 1, 0, 0, 0, 0, time.UTC)
td := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID))
assert.Equal(t, http.StatusOK, rr.StatusCode)
var tdrr TrainingDate
err := json.NewDecoder(rr.Body).Decode(&tdrr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, td.ID, tdrr.Id)
drr, _ := doDelete(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID))
assert.Equal(t, http.StatusNoContent, drr.StatusCode)
rr, _ = doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID))
assert.Equal(t, http.StatusNotFound, rr.StatusCode)
var trainingError NotFoundError
err = json.NewDecoder(rr.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
lrr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates", tr.ID))
assert.Equal(t, http.StatusOK, lrr.StatusCode)
var trainingDates []TrainingDate
err = json.NewDecoder(lrr.Body).Decode(&trainingDates)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, len(trainingDates), 0)
})
t.Run("List upcoming training dates for training", 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.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
now := time.Now()
upcomingTrainingCount := 5
for i := -4; i <= 5; i++ {
date := now.AddDate(0, 0, i)
td := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
}
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/upcoming-dates", tr.ID))
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trainingDatesReturned []TrainingDate
err := json.NewDecoder(rr.Body).Decode(&trainingDatesReturned)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, len(trainingDatesReturned), upcomingTrainingCount)
})
t.Run("List all upcoming training dates", func(t *testing.T) {
tr1 := &training.Training{
Name: "Testing Training for training date 1",
Description: "This is a test training for training date",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr1)
tr2 := &training.Training{
Name: "Testing Training for training date 2",
Description: "This is a test training for training date",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr2)
tr3 := &training.Training{
Name: "Testing Training for training date 3",
Description: "This is a test training for training date",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr3)
allTrainings, _ := handlers.trainingRepository.FindAll()
now := time.Now()
upcomingTrainingCount := 5
for i := -4; i <= upcomingTrainingCount; i++ {
date := now.AddDate(0, 0, i)
td1 := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr1.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr1.ID, td1)
td2 := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr2.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr2.ID, td2)
td3 := &training.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr3.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr3.ID, td3)
}
rr, _ := doGet(t, app, "/v1/trainings/upcoming-dates")
assert.Equal(t, http.StatusOK, rr.StatusCode)
var trainingDatesReturned ListAllUpcomingTrainingDatesResponse
err := json.NewDecoder(rr.Body).Decode(&trainingDatesReturned)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, len(allTrainings), len(trainingDatesReturned))
for _, tdr := range trainingDatesReturned {
if tdr.TrainingID == tr1.ID || tdr.TrainingID == tr2.ID || tdr.TrainingID == tr3.ID {
assert.Equal(t, len(tdr.Dates), upcomingTrainingCount)
}
}
})
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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, 99999999))
assert.Equal(t, http.StatusNotFound, rr.StatusCode)
var notFound NotFoundError
err := json.NewDecoder(rr.Body).Decode(&notFound)
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",
Description: "This is a test training for training date",
Days: 1,
Pricing: []training.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
newTrainingDateAttendee := NewTrainingDateAttendee{
Name: "John Doe",
Email: types.Email("john.doe@example.com"),
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: new(bool),
}
rr, _ := doPost(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees", tr.ID, td.ID), 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.PriceAmount.String(), attendeeResponse.Bill.Amount)
assert.Equal(t, td.PriceCurrency, 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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attendeeCount := 9
attendees := make([]training.Attendee, attendeeCount)
for i := range attendeeCount {
nAtd := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: false,
HasAttended: false,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, nAtd)
attendees[i] = *nAtd
}
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees", tr.ID, td.ID))
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].BillAmount.String(), attendee.Bill.Amount)
assert.Equal(t, attendees[i].BillCurrency, 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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attendee := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: false,
HasAttended: false,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
var resultTrainingDateAttendee TrainingDateAttendee
err := json.NewDecoder(rr.Body).Decode(&resultTrainingDateAttendee)
assert.NoError(t, err, "error unmarshalling response")
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.BillAmount.String(), resultTrainingDateAttendee.Bill.Amount)
assert.Equal(t, attendee.BillCurrency, resultTrainingDateAttendee.Bill.Currency)
assert.Equal(t, attendee.HasPaid, resultTrainingDateAttendee.HasPaid)
assert.Equal(t, attendee.HasAttended, resultTrainingDateAttendee.HasAttended)
})
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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attendee := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
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, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID), 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.PriceAmount.String(), attendeeResponse.Bill.Amount)
assert.Equal(t, td.PriceCurrency, 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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attendee := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: false,
HasAttended: false,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
assert.Equal(t, http.StatusOK, rr.StatusCode)
rr, _ = doDelete(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
assert.Equal(t, http.StatusNoContent, rr.StatusCode)
rr, _ = doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
paid := TrainingDateAttendeePaymentUpdateRequest{
Paid: true,
}
attendee := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: !paid.Paid,
HasAttended: false,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
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, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d/paid", tr.ID, td.ID, attendee.ID), 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, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attended := TrainingDateAttendeeAttendanceUpdateRequest{
Attended: true,
}
attendee := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: false,
HasAttended: !attended.Attended,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, attendee)
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
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, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d/attended", tr.ID, td.ID, attendee.ID), 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, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
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.Price{
{
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.Date{
Address: "Test Address 123, NYC",
Capacity: 12,
Date: date,
Days: tr.Days,
IsOnline: false,
Location: "NYC",
StartTime: date,
PriceAmount: decimal.NewFromInt(200),
PriceCurrency: "EUR",
}
_ = handlers.trainingDateRepository.Create(tr.ID, td)
attendeeCount := 9
for range attendeeCount {
nAtd := &training.Attendee{
Name: "John Doe",
Email: "john.doe@example.com",
Company: "Acme Inc.",
Position: "Software Engineer",
Phone: "+420 123 456 789",
IsStudent: false,
BillAmount: td.PriceAmount,
BillCurrency: td.PriceCurrency,
HasPaid: false,
HasAttended: false,
}
_ = handlers.trainingDateAttendeeRepository.Create(td.ID, nAtd)
}
rr, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/count", tr.ID, td.ID))
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)
})
}