update cart
Some checks failed
Build and Publish / BuildAndDeploy (push) Successful in 3m12s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled

This commit is contained in:
2025-09-28 15:56:40 +02:00
parent b4c9d09657
commit d98122756a
3 changed files with 316 additions and 19 deletions

View File

@@ -3,10 +3,11 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/google/uuid"
"io" "io"
"log" "log"
"net/http" "net/http"
"github.com/google/uuid"
) )
type KlarnaClient struct { type KlarnaClient struct {
@@ -60,7 +61,7 @@ func (k *KlarnaClient) getOrderResponse(res *http.Response) (*CheckoutOrder, err
log.Println(string(body)) log.Println(string(body))
} }
return nil, fmt.Errorf(res.Status) return nil, fmt.Errorf("%s", res.Status)
} }
func (k *KlarnaClient) CreateOrder(reader io.Reader) (*CheckoutOrder, error) { func (k *KlarnaClient) CreateOrder(reader io.Reader) (*CheckoutOrder, error) {

42
main.go
View File

@@ -8,6 +8,7 @@ import (
"net/http/pprof" "net/http/pprof"
"os" "os"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
"time" "time"
@@ -127,16 +128,33 @@ var tpl = `<!DOCTYPE html>
</html> </html>
` `
func main() { func getCountryFromHost(host string) string {
baseUrl := os.Getenv("BASE_URL") if strings.Contains(strings.ToLower(host), "-no") {
return "no"
}
return "se"
}
func getCheckoutOrder(host string, cartId CartId) *messages.CreateCheckoutOrder {
baseUrl := fmt.Sprintf("https://%s", host)
cartBaseUrl := os.Getenv("CART_BASE_URL") cartBaseUrl := os.Getenv("CART_BASE_URL")
if cartBaseUrl == "" { if cartBaseUrl == "" {
cartBaseUrl = "https://cart.tornberg.me" cartBaseUrl = "https://cart.tornberg.me"
} }
if baseUrl == "" { country := getCountryFromHost(host)
baseUrl = "https://slask-finder.tornberg.me"
return &messages.CreateCheckoutOrder{
Terms: fmt.Sprintf("%s/terms", baseUrl),
Checkout: fmt.Sprintf("%s/checkout?order_id={checkout.order.id}", baseUrl),
Confirmation: fmt.Sprintf("%s/confirmation/{checkout.order.id}", baseUrl),
Validation: fmt.Sprintf("%s/validation", cartBaseUrl),
Push: fmt.Sprintf("%s/push?order_id={checkout.order.id}", cartBaseUrl),
Country: country,
} }
// Create a new instance of the server }
func main() {
storage, err := NewDiskStorage(fmt.Sprintf("data/%s_state.gob", name)) storage, err := NewDiskStorage(fmt.Sprintf("data/%s_state.gob", name))
if err != nil { if err != nil {
log.Printf("Error loading state: %v\n", err) log.Printf("Error loading state: %v\n", err)
@@ -206,12 +224,11 @@ func main() {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte("ok")) w.Write([]byte("ok"))
}) })
mux.HandleFunc("/checkout", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/checkout", func(w http.ResponseWriter, r *http.Request) {
orderId := r.URL.Query().Get("order_id") orderId := r.URL.Query().Get("order_id")
order := &CheckoutOrder{} order := &CheckoutOrder{}
country := "se"
log.Printf("host: %s, referer: %s", r.Host, r.Referer())
log.Printf("Checkout for country %s, method: %s, order_id: %s", country, r.Method, orderId)
if orderId == "" { if orderId == "" {
cookie, err := r.Cookie("cartid") cookie, err := r.Cookie("cartid")
if err != nil { if err != nil {
@@ -227,14 +244,7 @@ func main() {
cartId := ToCartId(cookie.Value) cartId := ToCartId(cookie.Value)
reply, err := syncedServer.pool.Process(cartId, Message{ reply, err := syncedServer.pool.Process(cartId, Message{
Type: CreateCheckoutOrderType, Type: CreateCheckoutOrderType,
Content: &messages.CreateCheckoutOrder{ Content: getCheckoutOrder(r.Host, cartId),
Terms: fmt.Sprintf("%s/terms", baseUrl),
Checkout: fmt.Sprintf("%s/checkout?order_id={checkout.order.id}", baseUrl),
Confirmation: fmt.Sprintf("%s/confirmation/{checkout.order.id}", baseUrl),
Validation: fmt.Sprintf("%s/validation", cartBaseUrl),
Push: fmt.Sprintf("%s/push?order_id={checkout.order.id}", cartBaseUrl),
Country: country,
},
}) })
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)

286
main_test.go Normal file
View File

@@ -0,0 +1,286 @@
package main
import (
"os"
"testing"
)
func TestGetCountryFromHost(t *testing.T) {
tests := []struct {
name string
host string
expected string
}{
{
name: "Norwegian host",
host: "s10n-no.tornberg.me",
expected: "no",
},
{
name: "Swedish host",
host: "s10n-se.tornberg.me",
expected: "se",
},
{
name: "Host with -no in the middle",
host: "api-no-staging.tornberg.me",
expected: "no",
},
{
name: "Host without country suffix",
host: "s10n.tornberg.me",
expected: "se",
},
{
name: "Host with different domain",
host: "example-no.com",
expected: "no",
},
{
name: "Empty host",
host: "",
expected: "se",
},
{
name: "Host with uppercase",
host: "S10N-NO.TORNBERG.ME",
expected: "no",
},
{
name: "Host with mixed case",
host: "S10n-No.Tornberg.Me",
expected: "no",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getCountryFromHost(tt.host)
if result != tt.expected {
t.Errorf("getCountryFromHost(%q) = %q, want %q", tt.host, result, tt.expected)
}
})
}
}
func TestGetCheckoutOrder(t *testing.T) {
// Save original environment variable and restore after test
originalCartBaseUrl := os.Getenv("CART_BASE_URL")
defer func() {
if originalCartBaseUrl == "" {
os.Unsetenv("CART_BASE_URL")
} else {
os.Setenv("CART_BASE_URL", originalCartBaseUrl)
}
}()
tests := []struct {
name string
host string
cartId CartId
cartBaseUrl string
expectedUrls struct {
terms string
checkout string
confirmation string
validation string
push string
country string
}
}{
{
name: "Norwegian host with default cart base URL",
host: "s10n-no.tornberg.me",
cartId: ToCartId("test-cart-123"),
cartBaseUrl: "", // Use default
expectedUrls: struct {
terms string
checkout string
confirmation string
validation string
push string
country string
}{
terms: "https://s10n-no.tornberg.me/terms",
checkout: "https://s10n-no.tornberg.me/checkout?order_id={checkout.order.id}",
confirmation: "https://s10n-no.tornberg.me/confirmation/{checkout.order.id}",
validation: "https://cart.tornberg.me/validation",
push: "https://cart.tornberg.me/push?order_id={checkout.order.id}",
country: "no",
},
},
{
name: "Swedish host with default cart base URL",
host: "s10n-se.tornberg.me",
cartId: ToCartId("test-cart-456"),
cartBaseUrl: "", // Use default
expectedUrls: struct {
terms string
checkout string
confirmation string
validation string
push string
country string
}{
terms: "https://s10n-se.tornberg.me/terms",
checkout: "https://s10n-se.tornberg.me/checkout?order_id={checkout.order.id}",
confirmation: "https://s10n-se.tornberg.me/confirmation/{checkout.order.id}",
validation: "https://cart.tornberg.me/validation",
push: "https://cart.tornberg.me/push?order_id={checkout.order.id}",
country: "se",
},
},
{
name: "Norwegian host with custom cart base URL",
host: "s10n-no.tornberg.me",
cartId: ToCartId("test-cart-789"),
cartBaseUrl: "https://custom-cart.example.com",
expectedUrls: struct {
terms string
checkout string
confirmation string
validation string
push string
country string
}{
terms: "https://s10n-no.tornberg.me/terms",
checkout: "https://s10n-no.tornberg.me/checkout?order_id={checkout.order.id}",
confirmation: "https://s10n-no.tornberg.me/confirmation/{checkout.order.id}",
validation: "https://custom-cart.example.com/validation",
push: "https://custom-cart.example.com/push?order_id={checkout.order.id}",
country: "no",
},
},
{
name: "Host without country code defaults to Swedish",
host: "s10n.tornberg.me",
cartId: ToCartId("test-cart-default"),
cartBaseUrl: "",
expectedUrls: struct {
terms string
checkout string
confirmation string
validation string
push string
country string
}{
terms: "https://s10n.tornberg.me/terms",
checkout: "https://s10n.tornberg.me/checkout?order_id={checkout.order.id}",
confirmation: "https://s10n.tornberg.me/confirmation/{checkout.order.id}",
validation: "https://cart.tornberg.me/validation",
push: "https://cart.tornberg.me/push?order_id={checkout.order.id}",
country: "se",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set up environment variable for this test
if tt.cartBaseUrl == "" {
os.Unsetenv("CART_BASE_URL")
} else {
os.Setenv("CART_BASE_URL", tt.cartBaseUrl)
}
result := getCheckoutOrder(tt.host, tt.cartId)
// Verify the result is not nil
if result == nil {
t.Fatal("getCheckoutOrder returned nil")
}
// Check each URL field
if result.Terms != tt.expectedUrls.terms {
t.Errorf("Terms URL: got %q, want %q", result.Terms, tt.expectedUrls.terms)
}
if result.Checkout != tt.expectedUrls.checkout {
t.Errorf("Checkout URL: got %q, want %q", result.Checkout, tt.expectedUrls.checkout)
}
if result.Confirmation != tt.expectedUrls.confirmation {
t.Errorf("Confirmation URL: got %q, want %q", result.Confirmation, tt.expectedUrls.confirmation)
}
if result.Validation != tt.expectedUrls.validation {
t.Errorf("Validation URL: got %q, want %q", result.Validation, tt.expectedUrls.validation)
}
if result.Push != tt.expectedUrls.push {
t.Errorf("Push URL: got %q, want %q", result.Push, tt.expectedUrls.push)
}
if result.Country != tt.expectedUrls.country {
t.Errorf("Country: got %q, want %q", result.Country, tt.expectedUrls.country)
}
})
}
}
func TestGetCheckoutOrderIntegration(t *testing.T) {
// Test that both functions work together correctly
hosts := []string{"s10n-no.tornberg.me", "s10n-se.tornberg.me"}
cartId := ToCartId("integration-test-cart")
for _, host := range hosts {
t.Run(host, func(t *testing.T) {
// Get country from host
country := getCountryFromHost(host)
// Get checkout order
order := getCheckoutOrder(host, cartId)
// Verify that the country in the order matches what getCountryFromHost returns
if order.Country != country {
t.Errorf("Country mismatch: getCountryFromHost(%q) = %q, but order.Country = %q",
host, country, order.Country)
}
// Verify that all URLs contain the correct host
expectedBaseUrl := "https://" + host
if !containsPrefix(order.Terms, expectedBaseUrl) {
t.Errorf("Terms URL should start with %q, got %q", expectedBaseUrl, order.Terms)
}
if !containsPrefix(order.Checkout, expectedBaseUrl) {
t.Errorf("Checkout URL should start with %q, got %q", expectedBaseUrl, order.Checkout)
}
if !containsPrefix(order.Confirmation, expectedBaseUrl) {
t.Errorf("Confirmation URL should start with %q, got %q", expectedBaseUrl, order.Confirmation)
}
})
}
}
// Helper function to check if a string starts with a prefix
func containsPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
// Benchmark tests to measure performance
func BenchmarkGetCountryFromHost(b *testing.B) {
hosts := []string{
"s10n-no.tornberg.me",
"s10n-se.tornberg.me",
"api-no-staging.tornberg.me",
"s10n.tornberg.me",
}
for i := 0; i < b.N; i++ {
for _, host := range hosts {
getCountryFromHost(host)
}
}
}
func BenchmarkGetCheckoutOrder(b *testing.B) {
host := "s10n-no.tornberg.me"
cartId := ToCartId("benchmark-cart")
for i := 0; i < b.N; i++ {
getCheckoutOrder(host, cartId)
}
}