Turnpike/handle_import_test.go

142 lines
3.6 KiB
Go

package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"
)
func postCSV(t *testing.T, mux *http.ServeMux, token, csv string) *httptest.ResponseRecorder {
t.Helper()
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
part, _ := writer.CreateFormFile("csv", "attendees.csv")
io.WriteString(part, csv)
writer.Close()
req := httptest.NewRequest("POST", "/api/import", &buf)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", "Bearer "+token)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
return w
}
func TestImportCrowdWorkFormat(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
csv := "Patron Name,Patron Email,Order Number,Tier Name\nAlice,alice@test.com,ORD-1,GA\nBob,bob@test.com,ORD-2,VIP\n"
w := postCSV(t, mux, token, csv)
if w.Code != http.StatusOK {
t.Fatalf("status = %d\nbody: %s", w.Code, w.Body.String())
}
result := parseJSON(t, w)
if result["inserted"] != float64(2) {
t.Errorf("inserted = %v, want 2", result["inserted"])
}
}
func TestImportGenericFormat(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
csv := "name,email,ticket_id,ticket_type,note\nAlice,alice@test.com,T1,GA,VIP guest\n"
w := postCSV(t, mux, token, csv)
if w.Code != http.StatusOK {
t.Fatalf("status = %d", w.Code)
}
result := parseJSON(t, w)
if result["inserted"] != float64(1) {
t.Errorf("inserted = %v", result["inserted"])
}
}
func TestImportPartySizeDedup(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
// 3 rows same name+order = 1 record, party_size=3
csv := "Patron Name,Patron Email,Order Number,Tier Name\nAlice,alice@test.com,ORD-1,GA\nAlice,alice@test.com,ORD-1,GA\nAlice,alice@test.com,ORD-1,GA\n"
w := postCSV(t, mux, token, csv)
result := parseJSON(t, w)
if result["inserted"] != float64(1) {
t.Errorf("inserted = %v, want 1", result["inserted"])
}
if result["grouped"] != float64(2) {
t.Errorf("grouped = %v, want 2", result["grouped"])
}
attendees, _ := app.listAttendees("", "", "")
if len(attendees) != 1 {
t.Fatalf("attendee count = %d, want 1", len(attendees))
}
if attendees[0].PartySize != 3 {
t.Errorf("party_size = %d, want 3", attendees[0].PartySize)
}
}
func TestImportReimportSkips(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
csv := "name\nAlice\nBob\n"
postCSV(t, mux, token, csv)
// Re-import same data
w := postCSV(t, mux, token, csv)
result := parseJSON(t, w)
if result["inserted"] != float64(0) {
t.Errorf("re-import inserted = %v, want 0", result["inserted"])
}
if result["skipped"] != float64(2) {
t.Errorf("skipped = %v, want 2", result["skipped"])
}
}
func TestImportMissingNameColumn(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
csv := "email,phone\nalice@test.com,555-1234\n"
w := postCSV(t, mux, token, csv)
if w.Code != http.StatusBadRequest {
t.Errorf("status = %d, want 400", w.Code)
}
}
func TestImportBOM(t *testing.T) {
app := testApp(t)
admin := testAdminUser(t, app)
token := testToken(t, app, admin)
mux := testMux(app)
// BOM-encoded CSV
csv := "\xef\xbb\xbfname,email\nAlice,alice@test.com\n"
w := postCSV(t, mux, token, csv)
if w.Code != http.StatusOK {
t.Fatalf("status = %d", w.Code)
}
result := parseJSON(t, w)
if result["inserted"] != float64(1) {
t.Errorf("inserted = %v, want 1", result["inserted"])
}
}