package test import ( "context" "encoding/json" "fmt" "log" "net/http" "net/http/httptest" "os" "strings" "testing" "git.huntm.net/wedding/server/admin" "git.huntm.net/wedding/server/guest" "github.com/jackc/pgx/v5/pgxpool" ) var ( user = os.Getenv("USER") password = os.Getenv("PASS") host = "localhost" port = "5432" database = "postgres" ) func TestUpdateRSVP(test *testing.T) { databasePool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s:%s/%s", user, password, host, port, database)) if err != nil { test.Error(err) } defer databasePool.Close() guestStore := guest.NewStore(databasePool) guestHandler := guest.NewGuestHandler(guestStore) adminStore := admin.NewStore(databasePool) adminHandler := admin.NewAdminHandler(adminStore, guestStore) adminLogin := logInAdmin(adminHandler, test) adminToken := adminLogin.Token postGuest(guestHandler, adminToken, test) guestLogin := logInGuest(guestHandler, test) guestToken := guestLogin.Token addPartyMember(guestHandler, guestToken, test) guests := getGuests(guestHandler, adminToken, test) guest := findGuest(guests) assertEquals(test, guest.Attendance, "accept") assertEquals(test, guest.Email, "mhunteman@cox.net") assertEquals(test, guest.Message, "We'll be there!") assertEquals(test, guest.PartySize, 2) assertEquals(test, guest.PartyList[0].FirstName, "Madison") assertEquals(test, guest.PartyList[0].LastName, "Rossitto") deletePartyMember(guestHandler, guestToken, test) guests = getGuests(guestHandler, adminToken, test) guest = findGuest(guests) assertEquals(test, guest.Attendance, "") assertEquals(test, guest.Email, "") assertEquals(test, guest.Message, "") assertEquals(test, guest.PartySize, 1) deleteGuest(guestHandler, adminToken, test) } func logInGuest(guestHandler *guest.GuestHandler, test *testing.T) guest.Login { response := httptest.NewRecorder() loginRequest, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s:8080/guests/login", host), strings.NewReader(getName())) if err != nil { test.Error(err) } guestHandler.ServeHTTP(response, loginRequest) assertEquals(test, response.Result().StatusCode, 200) var login guest.Login if err = json.NewDecoder(response.Body).Decode(&login); err != nil { log.Fatal(err) } return login } func addPartyMember(guestHandler *guest.GuestHandler, token string, test *testing.T) { response := httptest.NewRecorder() putRequest, err := http.NewRequest(http.MethodPut, fmt.Sprintf("http://%s:8080/guests/1", host), strings.NewReader(getUpdatedGuest())) if err != nil { test.Error(err) } putRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, putRequest) assertEquals(test, response.Result().StatusCode, 200) } func logInAdmin(adminHandler *admin.AdminHandler, test *testing.T) admin.Login { response := httptest.NewRecorder() loginRequest, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s:8080/admin/login", host), strings.NewReader(getCredentials())) if err != nil { test.Error(err) } adminHandler.ServeHTTP(response, loginRequest) assertEquals(test, response.Result().StatusCode, 200) var login admin.Login if err = json.NewDecoder(response.Body).Decode(&login); err != nil { log.Fatal(err) } return login } func getGuests(guestHandler *guest.GuestHandler, token string, test *testing.T) []guest.Guest { response := httptest.NewRecorder() getRequest, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:8080/guests/", host), nil) if err != nil { test.Error(err) } getRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, getRequest) assertEquals(test, response.Result().StatusCode, 200) var guests []guest.Guest if err := json.NewDecoder(response.Body).Decode(&guests); err != nil { test.Error(err) } return guests } func deletePartyMember(guestHandler *guest.GuestHandler, token string, test *testing.T) { response := httptest.NewRecorder() putRequest, err := http.NewRequest(http.MethodPut, fmt.Sprintf("http://%s:8080/guests/1", host), strings.NewReader(getEmptyGuest())) if err != nil { test.Error(err) } putRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, putRequest) assertEquals(test, response.Result().StatusCode, 200) } func findGuest(guests []guest.Guest) *guest.Guest { for _, guest := range guests { if guest.ID == 1 { return &guest } } return nil } func assertEquals(test testing.TB, actual any, expected any) { test.Helper() if actual != expected { test.Errorf("Actual: %s, expected: %s", actual, expected) } } func getName() string { return "{ \"firstName\": \"Michael\", \"lastName\": \"Hunteman\"}" } func getCredentials() string { return fmt.Sprintf("{ \"username\": \"mhunteman\", \"password\": \"%s\"}", os.Getenv("PASS")) } func getUpdatedGuest() string { return `{"id":1,"firstName":"Michael","lastName":"Hunteman", "attendance":"accept", "email":"mhunteman@cox.net","message":"We'll be there!","partySize":2, "partyList":[{"firstName":"Madison","lastName":"Rossitto"}]}` } func getEmptyGuest() string { return `{"id":1,"firstName":"Michael","lastName":"Hunteman","attendance":"", "email":"","message":"","partySize":1,"partyList":[]}` } func TestAddGuest(test *testing.T) { databasePool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s:%s/%s", user, password, host, port, database)) if err != nil { test.Error(err) } defer databasePool.Close() guestStore := guest.NewStore(databasePool) guestHandler := guest.NewGuestHandler(guestStore) adminStore := admin.NewStore(databasePool) adminHandler := admin.NewAdminHandler(adminStore, guestStore) adminLogin := logInAdmin(adminHandler, test) adminToken := adminLogin.Token deleteGuest(guestHandler, adminToken, test) guests := getGuests(guestHandler, adminToken, test) assertEquals(test, findGuest(guests), findGuest([]guest.Guest{})) postGuest(guestHandler, adminToken, test) guests = getGuests(guestHandler, adminToken, test) guest := findGuest(guests) assertEquals(test, guest.FirstName, "Michael") assertEquals(test, guest.LastName, "Hunteman") assertEquals(test, guest.Attendance, "") assertEquals(test, guest.Email, "") assertEquals(test, guest.Message, "") assertEquals(test, guest.PartySize, 1) deleteGuest(guestHandler, adminToken, test) } func deleteGuest(guestHandler *guest.GuestHandler, token string, test *testing.T) { response := httptest.NewRecorder() deleteRequest, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("http://%s:8080/guests/1", host), nil) if err != nil { test.Error(err) } deleteRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, deleteRequest) assertEquals(test, response.Result().StatusCode, 200) } func postGuest(guestHandler *guest.GuestHandler, token string, test *testing.T) { response := httptest.NewRecorder() putRequest, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s:8080/guests/", host), strings.NewReader(getEmptyGuest())) if err != nil { test.Error(err) } putRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, putRequest) assertEquals(test, response.Result().StatusCode, 200) } func TestInvalidGuest(test *testing.T) { databasePool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s:%s/%s", user, password, host, port, database)) if err != nil { test.Error(err) } defer databasePool.Close() guestStore := guest.NewStore(databasePool) guestHandler := guest.NewGuestHandler(guestStore) logInInvalidGuest(guestHandler, test) updateInvalidGuest(guestHandler, "", test) } func logInInvalidGuest(guestHandler *guest.GuestHandler, test *testing.T) { response := httptest.NewRecorder() loginRequest, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s:8080/guests/login", host), strings.NewReader("{}")) if err != nil { test.Error(err) } guestHandler.ServeHTTP(response, loginRequest) assertEquals(test, response.Result().StatusCode, 401) } func updateInvalidGuest(guestHandler *guest.GuestHandler, token string, test *testing.T) { response := httptest.NewRecorder() putRequest, err := http.NewRequest(http.MethodPut, fmt.Sprintf("http://%s:8080/guests/1", host), strings.NewReader(getUpdatedGuest())) if err != nil { test.Error(err) } putRequest.Header.Set("Authorization", token) guestHandler.ServeHTTP(response, putRequest) assertEquals(test, response.Result().StatusCode, 400) } func TestInvalidAdmin(test *testing.T) { databasePool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s:%s/%s", user, password, host, port, database)) if err != nil { test.Error(err) } defer databasePool.Close() guestStore := guest.NewStore(databasePool) adminStore := admin.NewStore(databasePool) adminHandler := admin.NewAdminHandler(adminStore, guestStore) logInInvalidAdmin(adminHandler, "", test) } func logInInvalidAdmin(adminHandler *admin.AdminHandler, token string, test *testing.T) { response := httptest.NewRecorder() putRequest, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s:8080/admin/login", host), strings.NewReader("{}")) if err != nil { test.Error(err) } putRequest.Header.Set("Authorization", token) adminHandler.ServeHTTP(response, putRequest) assertEquals(test, response.Result().StatusCode, 401) }