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

1296 lines
40 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: add",
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)
createResp, _ := doPost(t, app, "/v1/trainings", newTraining)
defer func() { _ = createResp.Body.Close() }()
assert.Equal(t, http.StatusCreated, createResp.StatusCode)
var resultTraining Training
err := json.NewDecoder(createResp.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) {
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d", 9999999))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, getResp.StatusCode)
var trainingError NotFoundError
err := json.NewDecoder(getResp.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
})
t.Run("Get training by slug", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training: get with slug",
Description: "This is a test training with slug",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/by-slug/%s", tr.Slug))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trr Training
err := json.NewDecoder(getResp.Body).Decode(&trr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, tr.Name, trr.Name)
assert.Equal(t, tr.ID, trr.Id)
assert.Equal(t, tr.Slug, trr.Slug)
assert.Equal(t, false, trr.Published)
assert.Equal(t, false, trr.Retired)
})
t.Run("List all trainings", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training: list",
Description: "This is a test training",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
getResp, _ := doGet(t, app, "/v1/trainings")
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trainings []Training
err := json.NewDecoder(getResp.Body).Decode(&trainings)
assert.NoError(t, err, "error unmarshalling response")
assert.Greater(t, len(trainings), 0)
for _, trr := range trainings {
assert.NotEmpty(t, trr.Name)
assert.NotEmpty(t, trr.Slug)
assert.NotEmpty(t, trr.Description)
assert.NotEmpty(t, trr.Days)
assert.False(t, trr.Published)
assert.False(t, trr.Retired)
}
})
t.Run("Update training", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training: update",
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,
},
},
}
updateResp, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID), updTr)
defer func() { _ = updateResp.Body.Close() }()
assert.Equal(t, http.StatusOK, updateResp.StatusCode)
var trr Training
err := json.NewDecoder(updateResp.Body).Decode(&trr)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, updTr.Name, trr.Name)
assert.Equal(t, updatedSlug, trr.Slug)
assert.Equal(t, false, trr.Published)
assert.Equal(t, false, trr.Retired)
})
t.Run("Delete training", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training: delete",
Description: "This is a test training",
Days: 1,
Pricing: []training.Price{
{
Amount: decimal.NewFromInt(200),
Currency: "EUR",
Type: training.OpenTrainingPrice,
},
},
}
_ = handlers.trainingRepository.Create(tr)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trr Training
err := json.NewDecoder(getResp.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))
defer func() { _ = drr.Body.Close() }()
assert.Equal(t, http.StatusNoContent, drr.StatusCode)
deletedTrainingResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d", tr.ID))
defer func() { _ = deletedTrainingResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, deletedTrainingResp.StatusCode)
var trainingError NotFoundError
err = json.NewDecoder(deletedTrainingResp.Body).Decode(&trainingError)
assert.NoError(t, err, "error getting response", err)
assert.Equal(t, http.StatusNotFound, trainingError.Status)
})
t.Run("Add training date", func(t *testing.T) {
tr := &training.Training{
Name: "Testing Training: add 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",
},
}
createResp, err := doPost(t, app, fmt.Sprintf("/v1/trainings/%d/dates", tr.ID), newTrainingDate)
defer func() { _ = createResp.Body.Close() }()
assert.Equal(t, http.StatusCreated, createResp.StatusCode)
var resultTrainingDate TrainingDate
err = json.NewDecoder(createResp.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: date not found",
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)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, 999999))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, getResp.StatusCode)
var trainingError NotFoundError
err := json.NewDecoder(getResp.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: list dates",
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)
}
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates", tr.ID))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trainingDates []TrainingDate
err := json.NewDecoder(getResp.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: update 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",
},
}
updateResp, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID), updTd)
defer func() { _ = updateResp.Body.Close() }()
assert.Equal(t, http.StatusOK, updateResp.StatusCode)
var tdrr TrainingDate
err := json.NewDecoder(updateResp.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: delete 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)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var tdrr TrainingDate
err := json.NewDecoder(getResp.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))
defer func() { _ = drr.Body.Close() }()
assert.Equal(t, http.StatusNoContent, drr.StatusCode)
deletedTrainingResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d", tr.ID, td.ID))
defer func() { _ = deletedTrainingResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, deletedTrainingResp.StatusCode)
var trainingError NotFoundError
err = json.NewDecoder(deletedTrainingResp.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))
defer func() { _ = lrr.Body.Close() }()
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: list upcoming dates",
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)
}
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/upcoming-dates", tr.ID))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trainingDatesReturned []TrainingDate
err := json.NewDecoder(getResp.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: list dates for training id=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)
}
getResp, _ := doGet(t, app, "/v1/trainings/upcoming-dates")
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var trainingDatesReturned ListAllUpcomingTrainingDatesResponse
err := json.NewDecoder(getResp.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: attendee not found",
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)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, 99999999))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, getResp.StatusCode)
var notFound NotFoundError
err := json.NewDecoder(getResp.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: add attendee",
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),
}
createResp, _ := doPost(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees", tr.ID, td.ID), newTrainingDateAttendee)
defer func() { _ = createResp.Body.Close() }()
assert.Equal(t, http.StatusCreated, createResp.StatusCode)
var attendeeResponse TrainingDateAttendee
err := json.NewDecoder(createResp.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: list attendees",
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
}
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees", tr.ID, td.ID))
defer func() { _ = getResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getResp.StatusCode)
var attendeesResponse ListTrainingDateAttendeesResponse
err := json.NewDecoder(getResp.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: "Test training: get attendee",
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)
getResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
defer func() { _ = getResp.Body.Close() }()
var resultTrainingDateAttendee TrainingDateAttendee
err := json.NewDecoder(getResp.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: update attendee",
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),
}
updateResp, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID), newTrainingDateAttendee)
defer func() { _ = updateResp.Body.Close() }()
assert.Equal(t, http.StatusOK, updateResp.StatusCode)
var attendeeResponse UpdateTrainingDateAttendeeResponse
err := json.NewDecoder(updateResp.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: delete attendee",
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))
defer func() { _ = rr.Body.Close() }()
assert.Equal(t, http.StatusOK, rr.StatusCode)
deleteResp, _ := doDelete(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
defer func() { _ = deleteResp.Body.Close() }()
assert.Equal(t, http.StatusNoContent, deleteResp.StatusCode)
deletedResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
defer func() { _ = deletedResp.Body.Close() }()
assert.Equal(t, http.StatusNotFound, deletedResp.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))
defer func() { _ = rr.Body.Close() }()
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)
updateResp, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d/paid", tr.ID, td.ID, attendee.ID), paid)
defer func() { _ = updateResp.Body.Close() }()
assert.Equal(t, http.StatusOK, updateResp.StatusCode)
err = json.NewDecoder(updateResp.Body).Decode(&attendeeResponse)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, paid.Paid, attendeeResponse.HasPaid)
getAttendeeResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
defer func() { _ = getAttendeeResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getAttendeeResp.StatusCode)
err = json.NewDecoder(getAttendeeResp.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: mark attendee as attended",
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))
defer func() { _ = rr.Body.Close() }()
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)
updateResp, _ := doPut(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d/attended", tr.ID, td.ID, attendee.ID), attended)
defer func() { _ = updateResp.Body.Close() }()
assert.Equal(t, http.StatusOK, updateResp.StatusCode)
err = json.NewDecoder(updateResp.Body).Decode(&attendeeResponse)
assert.NoError(t, err, "error unmarshalling response")
assert.Equal(t, attended.Attended, attendeeResponse.HasAttended)
getAttendeeResp, _ := doGet(t, app, fmt.Sprintf("/v1/trainings/%d/dates/%d/attendees/%d", tr.ID, td.ID, attendee.ID))
defer func() { _ = getAttendeeResp.Body.Close() }()
assert.Equal(t, http.StatusOK, getAttendeeResp.StatusCode)
err = json.NewDecoder(getAttendeeResp.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: get attendee count",
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))
defer func() { _ = rr.Body.Close() }()
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)
})
}