153 lines
4.3 KiB
Go
153 lines
4.3 KiB
Go
package main
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/descrybe/descrybe-v2/apps/api/internal/billing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestLegacyIDFromSyntheticEmail(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
if got := legacyIDFromSyntheticEmail("user_abc@legacy.local"); got != "user_abc" {
|
||
|
|
t.Fatalf("got %q", got)
|
||
|
|
}
|
||
|
|
if got := legacyIDFromSyntheticEmail(" User_ABC@Legacy.Local "); got != "user_abc" {
|
||
|
|
t.Fatalf("got %q", got)
|
||
|
|
}
|
||
|
|
if got := legacyIDFromSyntheticEmail("real@example.com"); got != "" {
|
||
|
|
t.Fatalf("want empty, got %q", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseEmailPatchJSONMap(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
m, err := parseEmailPatchJSON([]byte(`{"user_1":"A@Example.COM","user_2":""}`))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if m["user_1"] != "a@example.com" {
|
||
|
|
t.Fatalf("got %#v", m)
|
||
|
|
}
|
||
|
|
if _, ok := m["user_2"]; ok {
|
||
|
|
t.Fatal("empty emails must be dropped")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseEmailPatchJSONInventoryEmails(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
raw := []byte(`{
|
||
|
|
"version": 1,
|
||
|
|
"emails": {"user_x":"x@example.com"},
|
||
|
|
"users": [{"legacy_user_id":"user_x","email":"user_x@legacy.local"}]
|
||
|
|
}`)
|
||
|
|
m, err := parseEmailPatchJSON(raw)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if m["user_x"] != "x@example.com" {
|
||
|
|
t.Fatalf("got %#v", m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseEmailPatchJSONArrayClerkish(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
raw := []byte(`[
|
||
|
|
{"id":"user_a","primary_email_address":"a@ex.com"},
|
||
|
|
{"id":"user_b","email_addresses":[{"email_address":"b@ex.com","primary":true}]}
|
||
|
|
]`)
|
||
|
|
m, err := parseEmailPatchJSON(raw)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if m["user_a"] != "a@ex.com" || m["user_b"] != "b@ex.com" {
|
||
|
|
t.Fatalf("got %#v", m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseEmailPatchCSV(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
m, err := parseEmailPatchCSV([]byte("id,primary_email_address\nuser_c,C@Ex.COM\n"))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if m["user_c"] != "c@ex.com" {
|
||
|
|
t.Fatalf("got %#v", m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPlanEmailPatchesSafety(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
rows := []legacyEmailRow{
|
||
|
|
{ID: "u1", Email: "user_1@legacy.local", LegacyUserID: "user_1", A1Member: true},
|
||
|
|
{ID: "u2", Email: "a1-primary@descrybe.local", LegacyUserID: "user_live", A1Member: true},
|
||
|
|
{ID: "u3", Email: "user_3@legacy.local", LegacyUserID: "user_3"},
|
||
|
|
{ID: "u4", Email: "user_4@legacy.local", LegacyUserID: "user_4"},
|
||
|
|
{ID: "u5", Email: "user_5@legacy.local", LegacyUserID: "user_5"},
|
||
|
|
}
|
||
|
|
byLegacy := map[string]string{
|
||
|
|
"user_1": "real1@example.com",
|
||
|
|
"user_live": "should-not-apply@example.com",
|
||
|
|
"user_3": "user_3@legacy.local",
|
||
|
|
"user_4": "taken@example.com",
|
||
|
|
"user_5": "real5@example.com",
|
||
|
|
"user_missing": "ghost@example.com",
|
||
|
|
}
|
||
|
|
occupied := map[string]string{
|
||
|
|
"user_1@legacy.local": "u1",
|
||
|
|
"a1-primary@descrybe.local": "u2",
|
||
|
|
"user_3@legacy.local": "u3",
|
||
|
|
"user_4@legacy.local": "u4",
|
||
|
|
"user_5@legacy.local": "u5",
|
||
|
|
"taken@example.com": "other",
|
||
|
|
}
|
||
|
|
plan := planEmailPatches(rows, byLegacy, occupied)
|
||
|
|
if len(plan.Apply) != 1 || plan.Apply[0].UserID != "u5" || plan.Apply[0].ToEmail != "real5@example.com" {
|
||
|
|
t.Fatalf("apply=%#v", plan.Apply)
|
||
|
|
}
|
||
|
|
if plan.Apply[0].A1Member {
|
||
|
|
t.Fatal("apply list must never include a1_member=true")
|
||
|
|
}
|
||
|
|
reasons := map[string]bool{}
|
||
|
|
for _, s := range plan.Skips {
|
||
|
|
reasons[s.Reason] = true
|
||
|
|
if s.UserID == "u1" && s.Reason != "a1_member" {
|
||
|
|
t.Fatalf("A1 synthetic email must skip as a1_member, skip=%#v", s)
|
||
|
|
}
|
||
|
|
if s.UserID == "u2" && s.Reason != "a1_member" {
|
||
|
|
t.Fatalf("live A1 email must skip as a1_member, skip=%#v", s)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, want := range []string{
|
||
|
|
"a1_member",
|
||
|
|
"target_still_synthetic",
|
||
|
|
"target_email_owned_by_other",
|
||
|
|
"no_synthetic_user_for_legacy_id",
|
||
|
|
} {
|
||
|
|
if !reasons[want] {
|
||
|
|
t.Fatalf("missing skip reason %q in %#v", want, plan.Skips)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPlanEmailPatchesEmptyMap(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
plan := planEmailPatches(nil, nil, nil)
|
||
|
|
if len(plan.Skips) != 1 || !strings.Contains(plan.Skips[0].Reason, "empty") {
|
||
|
|
t.Fatalf("got %#v", plan.Skips)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRowIsA1Member(t *testing.T) {
|
||
|
|
t.Parallel()
|
||
|
|
if !rowIsA1Member(legacyEmailRow{LegacyCompanyIDs: []string{billing.A1LegacyCompanyID}}) {
|
||
|
|
t.Fatal("expected A1 by legacy company id")
|
||
|
|
}
|
||
|
|
if !rowIsA1Member(legacyEmailRow{Companies: []string{"A1 Slovenija"}}) {
|
||
|
|
t.Fatal("expected A1 by name")
|
||
|
|
}
|
||
|
|
if rowIsA1Member(legacyEmailRow{Companies: []string{"Acme"}}) {
|
||
|
|
t.Fatal("Acme is not A1")
|
||
|
|
}
|
||
|
|
}
|