update tests

This commit is contained in:
bronku 2025-03-19 22:10:43 +01:00
parent 23647d74fc
commit 605ea31fe1
3 changed files with 258 additions and 124 deletions

View file

@ -31,7 +31,13 @@ func (h *handler) form(w http.ResponseWriter, r *http.Request) {
Order order
Catalogue []cake
}
data := formData{o, h.s.getCakes()}
cakes, err := h.s.getCakes()
if err != nil {
fmt.Fprint(w, "server side error getting available cakes: ", err)
return
}
data := formData{o, cakes}
fmt.Println(data)
w.Header().Set("content-type", "text/html")
@ -85,7 +91,12 @@ func (h *handler) addOrder(w http.ResponseWriter, r *http.Request) {
n.Accepted = time.Now()
n.Cakes = make([]cake, 0)
for _, e := range h.s.getCakes() {
cakes, err := h.s.getCakes()
if err != nil {
fmt.Fprint(w, "server side error getting available cakes: ", err)
return
}
for _, e := range cakes {
value := r.FormValue(fmt.Sprintf("cake[%d]", e.ID))
if value == "" {
continue
@ -109,7 +120,12 @@ func (h *handler) addOrder(w http.ResponseWriter, r *http.Request) {
func (h *handler) index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "text/html")
err := h.tmpl.ExecuteTemplate(w, "index.html", h.s.getOrders())
orders, err := h.s.getOrders()
if err != nil {
fmt.Fprint(w, "server side error getting orders: ", err)
return
}
err = h.tmpl.ExecuteTemplate(w, "index.html", orders)
if err != nil {
fmt.Println("error executing the template: ", err)
}

View file

@ -1,9 +1,9 @@
// #todo: check for errors in every rows.Scan()
package main
import (
"database/sql"
_ "embed"
"fmt"
"os"
"strconv"
"time"
@ -37,25 +37,27 @@ func NewStore(filename string) (*store, error) {
return &out, nil
}
// #todo: should return an error
func (s *store) getCakes() []cake {
// #todo: error handling
func (s *store) close() {
s.db.Close()
}
func (s *store) getCakes() ([]cake, error) {
rows, err := s.db.Query("select id, name, price from cake")
defer rows.Close()
if err != nil {
return nil
return nil, err
}
defer rows.Close()
cakes := make([]cake, 0)
for rows.Next() {
var c cake
err = rows.Scan(&c.ID, &c.Name, &c.Price)
c.Amount = 0
err = rows.Scan(&c.ID, &c.Name, &c.Price)
if err != nil {
fmt.Println("error scanning rows into cake: ", err)
return nil, err
}
cakes = append(cakes, c)
}
return cakes
return cakes, err
}
func (s *store) saveCake(newCake cake) (int, error) {
@ -74,8 +76,8 @@ func (s *store) saveCake(newCake cake) (int, error) {
// #todo: see if next is required or not to get the first element
row.Next()
row.Scan(&newCake.ID)
return newCake.ID, nil
err = row.Scan(&newCake.ID)
return newCake.ID, err
}
// #todo: retrieve and save order contents
@ -98,26 +100,29 @@ func (s *store) getOrder(id int) (order, error) {
}
// #todo: should return an error
func (s *store) getOrders() []order {
func (s *store) getOrders() ([]order, error) {
var out []order
// #todo: error handling
row, err := s.db.Query("select id, name, surname, phone, location, order_date, delivery_date, status, paid from customer_order;")
defer row.Close()
rows, err := s.db.Query("select id, name, surname, phone, location, order_date, delivery_date, status, paid from customer_order;")
if err != nil {
return out
return out, err
}
defer rows.Close()
for row.Next() {
for rows.Next() {
var o order
var order_date, delivery_date string
row.Scan(&o.ID, &o.Name, &o.Surname, &o.Phone, &o.Location, &order_date, &delivery_date, &o.Status, &o.Paid)
err = rows.Scan(&o.ID, &o.Name, &o.Surname, &o.Phone, &o.Location, &order_date, &delivery_date, &o.Status, &o.Paid)
if err != nil {
return nil, err
}
// #todo: error handling
// figure out what to do with errors, as they shouldn't really crash the app, but there should probably be an indication that something went wrong
o.Accepted, _ = time.Parse("2006-01-02 15:04", order_date)
o.Date, _ = time.Parse("2006-01-02 15:04", delivery_date)
out = append(out, o)
}
return out
return out, nil
}
func (s *store) saveOrder(newOrder order) (int, error) {
@ -139,6 +144,6 @@ func (s *store) saveOrder(newOrder order) (int, error) {
// #todo: see if next is required or not to get the first element
row.Next()
row.Scan(&newOrder.ID)
return newOrder.ID, nil
err = row.Scan(&newOrder.ID)
return newOrder.ID, err
}

View file

@ -5,136 +5,249 @@ import (
"time"
)
func TestCakeOperations(t *testing.T) {
func TestStore(t *testing.T) {
s, err := NewStore(":memory:")
if err != nil {
t.Fatal("Failed to open database", err)
t.Fatalf("Failed to create store: %v", err)
}
defer s.db.Close()
defer s.close()
c := cake{
ID: -1,
Name: "Test Cake",
Price: 10,
}
id, err := s.saveCake(c)
if id == -1 || err != nil {
t.Fatal("Failed to save cake", err)
}
cakes := s.getCakes()
if len(cakes) != 1 {
t.Errorf("Expected 1 cake, got %d", len(cakes))
}
if cakes[0].Name != "Test Cake" || cakes[0].Price != 10 {
t.Errorf("Cake data mismatch. Got %+v", cakes[0])
}
updatedCake := cake{
ID: id,
Name: "Updated Cake",
Price: 15,
}
newID, err := s.saveCake(updatedCake)
if newID != id {
t.Errorf("Update returned different ID. Expected %d, got %d", id, newID)
}
cakes = s.getCakes()
if cakes[0].Name != "Updated Cake" || cakes[0].Price != 15 {
t.Errorf("Cake update failed. Got %+v", cakes[0])
}
}
func TestOrderOperations(t *testing.T) {
s, err := NewStore(":memory:")
// ensure db is empty
cakes, err := s.getCakes()
if err != nil {
t.Fatal("Failed to open database", err)
t.Errorf("Error getting cakes: %v", err)
}
if len(cakes) != 0 {
t.Errorf("Expected empty cakes list, got: %v", cakes)
}
orders, err := s.getOrders()
if err != nil {
t.Errorf("Error getting orders: %v", err)
}
if len(orders) != 0 {
t.Errorf("Expected empty orders list, got: %v", orders)
}
defer s.db.Close()
// create new cake
newCake := cake{Name: "Chocolate Cake", ID: -1, Price: 2500, Amount: -1}
newCake.ID, err = s.saveCake(newCake)
if err != nil {
t.Fatalf("Failed to save new cake: %v", err)
}
if newCake.ID <= 0 {
t.Errorf("Expected positive cake ID, got: %d", newCake.ID)
}
// create another cake
anotherCake := cake{Name: "Another Cake", ID: -1, Price: 3000, Amount: -1}
anotherCake.ID, err = s.saveCake(anotherCake)
if err != nil {
t.Fatalf("Failed to save new cake: %v", err)
}
if anotherCake.ID <= 0 {
t.Errorf("Expected positive cake ID, got: %d", anotherCake.ID)
}
// Update Existing Cake
newCake.Name = "Updated Cake"
newCake.Price = 100
newID, err := s.saveCake(newCake)
if newID != newCake.ID {
t.Error("wrong id")
}
if err != nil {
t.Error("error updating cake", err)
}
// Update Non-existing Cake
var updatedCake cake
updatedCake.ID = 10
_, err = s.saveCake(updatedCake)
if err == nil {
t.Error("did not return an error when attempted to update non existant cake")
}
// get cakes
cakes, err = s.getCakes()
if err != nil {
t.Fatalf("Failed to get all cakes after creation: %v", err)
}
if len(cakes) != 2 {
t.Error("Expected two cakes returned, got ", len(cakes))
}
for i, c := range cakes {
if c.ID == newCake.ID {
newCake.Amount = i
}
if c.ID == anotherCake.ID {
anotherCake.Amount = i
}
}
if newCake.Amount == -1 {
t.Error("not found newCake")
}
if cakes[newCake.Amount].ID != newCake.ID || cakes[newCake.Amount].Name != newCake.Name || cakes[newCake.Amount].Price != newCake.Price {
t.Errorf("Want %v\nGot %v", newCake, cakes)
}
if anotherCake.Amount == -1 {
t.Error("not found anotherCake")
}
if cakes[anotherCake.Amount].ID != anotherCake.ID || cakes[anotherCake.Amount].Name != anotherCake.Name || cakes[anotherCake.Amount].Price != anotherCake.Price {
t.Errorf("Want %v\nGot %v", anotherCake, cakes)
}
// create new order
now := time.Now()
delivery := now.Add(24 * time.Hour)
o := order{
newOrder := order{
ID: -1,
Name: "John",
Surname: "Doe",
Phone: "1234567890",
Location: "123 Test St",
Phone: "123-456-7890",
Location: "Some Location",
Accepted: now,
Date: delivery,
Status: "pending",
Paid: 0,
Date: now.Add(time.Hour * 24),
Status: "Pending",
Paid: 1000,
Cakes: []cake{{ID: newCake.ID, Amount: 2}, {ID: anotherCake.ID, Amount: 10}},
}
id, err := s.saveOrder(o)
if id == -1 || err != nil {
t.Fatal("Failed to save order", err)
}
retrieved, err := s.getOrder(id)
newOrder.ID, err = s.saveOrder(newOrder)
if err != nil {
t.Fatalf("Failed to get order: %v", err)
t.Fatalf("Failed to save new order: %v", err)
}
if newOrder.ID <= 0 {
t.Errorf("Expected positive order ID, got: %d", newOrder.ID)
}
if retrieved.Name != "John" || retrieved.Surname != "Doe" {
t.Errorf("Order names mismatch. Got %+v", retrieved)
// create another order
anotherOrder := order{
ID: -1,
Name: "Jane",
Surname: "Doe",
Phone: "123-456-7890",
Location: "New Location",
Accepted: now,
Date: now.Add(time.Hour * 192),
Status: "Accepted",
Paid: 1500,
Cakes: []cake{{ID: newCake.ID, Amount: 100}},
}
if !timeEqual(retrieved.Date, o.Date) || !timeEqual(retrieved.Accepted, o.Accepted) {
t.Errorf("Order dates mismatch. \nGot %+v\nWant %+v", retrieved, o)
}
orders := s.getOrders()
if len(orders) != 1 {
t.Errorf("Expected 1 order, got %d", len(orders))
}
// Test updating an order
o.ID = id
o.Status = "completed"
newID, err := s.saveOrder(o)
anotherOrder.ID, err = s.saveOrder(anotherOrder)
if err != nil {
t.Fatal("Failed to save order", err)
t.Fatalf("Failed to save new order: %v", err)
}
if newID != id {
t.Errorf("Update returned different ID. Expected %d, got %d", id, newID)
if anotherOrder.ID <= 0 {
t.Errorf("Expected positive order ID, got: %d", anotherOrder.ID)
}
updated, err := s.getOrder(id)
// update existing order
newOrder.Name = "James"
newOrder.Status = "Done"
newOrder.Cakes = newOrder.Cakes[1:]
newID, err = s.saveOrder(newOrder)
if newID != newOrder.ID {
t.Error("wrong id")
}
if err != nil {
t.Fatalf("Failed to get updated order: %v", err)
t.Error("error updating order", err)
}
if updated.Status != "completed" {
t.Errorf("Order update failed. Got %+v", updated)
// update non existing order
var updatedOrder order
updatedOrder.ID = 10
_, err = s.saveOrder(updatedOrder)
if err == nil {
t.Error("did not return an error when attempted to update non existant cake")
}
// get orders
orders, err = s.getOrders()
if err != nil {
t.Fatalf("Failed to get all orders after creation: %v", err)
}
if len(orders) != 2 {
t.Error("Expected two orders returned, got ", len(orders))
}
newOrderPos := -1
anotherOrderPos := -1
for i, o := range orders {
if o.ID == newOrder.ID {
newOrderPos = i
}
if o.ID == anotherOrder.ID {
anotherOrderPos = i
}
}
if newOrderPos == -1 {
t.Error("not found newOrder")
}
if newOrder.Name != orders[newOrderPos].Name ||
newOrder.Surname != orders[newOrderPos].Surname ||
newOrder.Phone != orders[newOrderPos].Phone ||
newOrder.Status != orders[newOrderPos].Status ||
newOrder.Location != orders[newOrderPos].Location ||
newOrder.Accepted.Format("2006-01-02 15:04") != newOrder.Accepted.Format("2006-01-02 15:04") ||
newOrder.Date.Format("2006-01-02 15:04") != newOrder.Date.Format("2006-01-02 15:04") {
t.Errorf("Want %v\nGot %v", newOrder, orders[newOrderPos])
}
if anotherOrderPos == -1 {
t.Error("not found anotherOrder")
}
if anotherOrder.Name != orders[anotherOrderPos].Name ||
anotherOrder.Surname != orders[anotherOrderPos].Surname ||
anotherOrder.Phone != orders[anotherOrderPos].Phone ||
anotherOrder.Status != orders[anotherOrderPos].Status ||
anotherOrder.Location != orders[anotherOrderPos].Location ||
anotherOrder.Accepted.Format("2006-01-02 15:04") != anotherOrder.Accepted.Format("2006-01-02 15:04") ||
anotherOrder.Date.Format("2006-01-02 15:04") != anotherOrder.Date.Format("2006-01-02 15:04") {
t.Errorf("Want %v\nGot %v", anotherOrder, orders[anotherOrderPos])
}
}
func TestStoreInitialization(t *testing.T) {
s, err := NewStore(":memory:")
if err != nil {
t.Fatal("Failed to open database", err)
}
defer s.db.Close()
cakes := s.getCakes()
if len(cakes) != 0 {
t.Errorf("New store should have no cakes, got %d", len(cakes))
func TestSliceComparison(t *testing.T) {
a := []cake{
{Name: "ok", Price: 100, ID: 12, Amount: 10},
{Name: "ok", Price: 11, ID: 13, Amount: 1},
{Name: "ok", Price: 100, ID: 10, Amount: 11},
}
orders := s.getOrders()
if len(orders) != 0 {
t.Errorf("New store should have no orders, got %d", len(orders))
b := []cake{
{Name: "okas", Price: 110, ID: 12, Amount: 10},
{Name: "oksa", Price: 11, ID: 13, Amount: 1},
{Name: "oasdk", Price: 101, ID: 10, Amount: 11},
}
if !areCakeSlicesEqual(a, b) {
t.Error("aren't equal")
}
}
func timeEqual(t1, t2 time.Time) bool {
format := "2006-01-02 15:04"
return t1.Format(format) == t2.Format(format)
func areCakesEqual(a, b cake) bool {
return a.ID == b.ID && a.Amount == b.Amount
}
func areCakeSlicesEqual(a, b []cake) bool {
if len(a) != len(b) {
return false
}
matched := make([]bool, len(a))
mainLoop:
for _, e1 := range a {
for i, e2 := range b {
if matched[i] {
continue
}
if areCakesEqual(e1, e2) {
matched[i] = true
continue mainLoop
}
}
}
for _, e := range matched {
if e == false {
return false
}
}
return true
}