package outboundintentv1

import "testing"

func TestDecodeUpsertDesiredStateV2(t *testing.T) {
	raw := []byte(`{"version":2,"writeDisposition":"UPDATE_EXISTING_ONLY","targetObject":"contacts","bodyRoot":"properties","mappedFields":{"email":"a@example.com"}}`)
	intent := testIntent(raw, 41)
	intent.PayloadFormatVersion = 2

	payload, err := DecodeUpsertDesiredStateV2(intent)
	if err != nil {
		t.Fatalf("DecodeUpsertDesiredStateV2: %v", err)
	}
	if payload.WriteDisposition != UpsertWriteUpdateExistingOnly || payload.TargetObject != "contacts" {
		t.Fatalf("payload = %#v", payload)
	}
	if _, err := DecodeUpsertDesiredStateV1(intent); err == nil {
		t.Fatal("v1 decoder accepted a v2 desired-state payload")
	}
}

func TestDecodeUpsertDesiredStateV2FailsClosed(t *testing.T) {
	for name, raw := range map[string]string{
		"missing disposition": `{"version":2,"targetObject":"contacts","mappedFields":{"email":"a@example.com"}}`,
		"unknown disposition": `{"version":2,"writeDisposition":"CREATE_IF_MISSING","targetObject":"contacts","mappedFields":{"email":"a@example.com"}}`,
		"provider identity":   `{"version":2,"writeDisposition":"UPDATE_EXISTING_ONLY","targetObject":"contacts","mappedFields":{"email":"a@example.com"},"remoteId":"provider-1"}`,
		"noncanonical":        `{ "version":2,"writeDisposition":"CREATE_OR_UPDATE","targetObject":"contacts","mappedFields":{"email":"a@example.com"}}`,
	} {
		t.Run(name, func(t *testing.T) {
			intent := testIntent([]byte(raw), 41)
			intent.PayloadFormatVersion = 2
			if _, err := DecodeUpsertDesiredStateV2(intent); err == nil {
				t.Fatal("malformed v2 payload was accepted")
			}
		})
	}
}
