update cart
This commit is contained in:
@@ -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
42
main.go
@@ -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
286
main_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user