package model_test import ( "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.yandata.net/iod/iod/go-trustlog/api/model" ) func TestNewEnvelopeConfig(t *testing.T) { t.Parallel() signer := model.NewNopSigner() config := model.NewEnvelopeConfig(signer) assert.NotNil(t, config.Signer) } func TestNewSM2EnvelopeConfig(t *testing.T) { t.Parallel() privateKey := []byte("test-private-key") publicKey := []byte("test-public-key") config := model.NewSM2EnvelopeConfig(privateKey, publicKey) assert.NotNil(t, config.Signer) } func TestNewVerifyConfig(t *testing.T) { t.Parallel() signer := model.NewNopSigner() config := model.NewVerifyConfig(signer) assert.NotNil(t, config.Signer) } func TestNewSM2VerifyConfig(t *testing.T) { t.Parallel() publicKey := []byte("test-public-key") config := model.NewSM2VerifyConfig(publicKey) assert.NotNil(t, config.Signer) } func TestMarshalEnvelope_Nil(t *testing.T) { t.Parallel() _, err := model.MarshalEnvelope(nil) require.Error(t, err) assert.Contains(t, err.Error(), "envelope cannot be nil") } func TestMarshalEnvelope_Basic(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) assert.NotNil(t, data) assert.NotEmpty(t, data) } func TestMarshalEnvelope_EmptyFields(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "", Signature: []byte{}, Body: []byte{}, } data, err := model.MarshalEnvelope(env) require.NoError(t, err) assert.NotNil(t, data) } func TestUnmarshalEnvelope_Nil(t *testing.T) { t.Parallel() _, err := model.UnmarshalEnvelope(nil) require.Error(t, err) assert.Contains(t, err.Error(), "data is empty") } func TestUnmarshalEnvelope_Empty(t *testing.T) { t.Parallel() _, err := model.UnmarshalEnvelope([]byte{}) require.Error(t, err) assert.Contains(t, err.Error(), "data is empty") } func TestMarshalUnmarshalEnvelope_RoundTrip(t *testing.T) { t.Parallel() original := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } // Marshal data, err := model.MarshalEnvelope(original) require.NoError(t, err) require.NotNil(t, data) // Unmarshal result, err := model.UnmarshalEnvelope(data) require.NoError(t, err) require.NotNil(t, result) // Verify assert.Equal(t, original.ProducerID, result.ProducerID) assert.Equal(t, original.Signature, result.Signature) assert.Equal(t, original.Body, result.Body) } func TestUnmarshalEnvelopeProducerID(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) producerID, err := model.UnmarshalEnvelopeProducerID(data) require.NoError(t, err) assert.Equal(t, "producer-1", producerID) } func TestUnmarshalEnvelopeSignature(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) producerID, signature, err := model.UnmarshalEnvelopeSignature(data) require.NoError(t, err) assert.Equal(t, "producer-1", producerID) assert.Equal(t, []byte("signature"), signature) } func TestUnmarshalEnvelopeSignature_EmptyData(t *testing.T) { t.Parallel() _, _, err := model.UnmarshalEnvelopeSignature(nil) require.Error(t, err) assert.Contains(t, err.Error(), "data is empty") } func TestUnmarshalEnvelopeSignature_InvalidData(t *testing.T) { t.Parallel() _, _, err := model.UnmarshalEnvelopeSignature([]byte{0xff, 0xff}) require.Error(t, err) } func TestUnmarshalEnvelopeProducerID_EmptyData(t *testing.T) { t.Parallel() _, err := model.UnmarshalEnvelopeProducerID(nil) require.Error(t, err) assert.Contains(t, err.Error(), "data is empty") } func TestMarshalTrustlog_Nil(t *testing.T) { t.Parallel() _, err := model.MarshalTrustlog(nil, model.EnvelopeConfig{}) require.Error(t, err) assert.Contains(t, err.Error(), "trustlog cannot be nil") } func TestMarshalTrustlog_Basic(t *testing.T) { t.Parallel() op := &model.Operation{ OpID: "op-123", Timestamp: time.Now(), OpSource: model.OpSourceIRP, OpType: model.OpTypeOCCreateHandle, DoPrefix: "test", DoRepository: "repo", Doid: "test/repo/123", ProducerID: "producer-1", OpActor: "actor-1", } err := op.CheckAndInit() require.NoError(t, err) config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalTrustlog(op, config) require.NoError(t, err) assert.NotNil(t, data) } func TestUnmarshalTrustlog_Nil(t *testing.T) { t.Parallel() op := &model.Operation{} err := model.UnmarshalTrustlog(nil, op) require.Error(t, err) assert.Contains(t, err.Error(), "data is empty") } func TestMarshalOperation(t *testing.T) { t.Parallel() op := &model.Operation{ OpID: "op-123", Timestamp: time.Now(), OpSource: model.OpSourceIRP, OpType: model.OpTypeOCCreateHandle, DoPrefix: "test", DoRepository: "repo", Doid: "test/repo/123", ProducerID: "producer-1", OpActor: "actor-1", } err := op.CheckAndInit() require.NoError(t, err) config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalOperation(op, config) require.NoError(t, err) assert.NotNil(t, data) } func TestUnmarshalOperation(t *testing.T) { t.Parallel() op := &model.Operation{ OpID: "op-123", Timestamp: time.Now(), OpSource: model.OpSourceIRP, OpType: model.OpTypeOCCreateHandle, DoPrefix: "test", DoRepository: "repo", Doid: "test/repo/123", ProducerID: "producer-1", OpActor: "actor-1", } err := op.CheckAndInit() require.NoError(t, err) config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalOperation(op, config) require.NoError(t, err) result, err := model.UnmarshalOperation(data) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, op.OpID, result.OpID) } func TestMarshalRecord(t *testing.T) { t.Parallel() rec := &model.Record{ ID: "rec-123", DoPrefix: "test", ProducerID: "producer-1", Timestamp: time.Now(), Operator: "operator-1", Extra: []byte("extra"), RCType: "log", } err := rec.CheckAndInit() require.NoError(t, err) config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalRecord(rec, config) require.NoError(t, err) assert.NotNil(t, data) } func TestUnmarshalRecord(t *testing.T) { t.Parallel() rec := &model.Record{ ID: "rec-123", DoPrefix: "test", ProducerID: "producer-1", Timestamp: time.Now(), Operator: "operator-1", Extra: []byte("extra"), RCType: "log", } err := rec.CheckAndInit() require.NoError(t, err) config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalRecord(rec, config) require.NoError(t, err) result, err := model.UnmarshalRecord(data) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, rec.ID, result.ID) } func TestVerifyEnvelope_Nil(t *testing.T) { t.Parallel() config := model.NewEnvelopeConfig(model.NewNopSigner()) env, err := model.VerifyEnvelope(nil, config) require.Error(t, err) assert.Nil(t, env) assert.Contains(t, err.Error(), "data is empty") } func TestVerifyEnvelope_Basic(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } config := model.NewEnvelopeConfig(model.NewNopSigner()) data, err := model.MarshalEnvelope(env) require.NoError(t, err) verifiedEnv, err := model.VerifyEnvelope(data, config) // NopSigner verifies by comparing body with signature // Since signature != body, verification should fail require.Error(t, err) assert.Nil(t, verifiedEnv) } func TestVerifyEnvelopeWithConfig_Nil(t *testing.T) { t.Parallel() config := model.NewVerifyConfig(model.NewNopSigner()) env, err := model.VerifyEnvelopeWithConfig(nil, config) require.Error(t, err) assert.Nil(t, env) // Error message may vary, just check that it's an error assert.NotEmpty(t, err.Error()) } func TestVerifyEnvelopeWithConfig_NilSigner(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) config := model.VerifyConfig{Signer: nil} verifiedEnv, err := model.VerifyEnvelopeWithConfig(data, config) require.Error(t, err) assert.Nil(t, verifiedEnv) assert.Contains(t, err.Error(), "signer is required") } func TestVerifyEnvelopeWithConfig_Success(t *testing.T) { t.Parallel() // Create envelope with matching body and signature (NopSigner requirement) env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("body"), // Same as body for NopSigner Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) config := model.NewVerifyConfig(model.NewNopSigner()) verifiedEnv, err := model.VerifyEnvelopeWithConfig(data, config) require.NoError(t, err) require.NotNil(t, verifiedEnv) assert.Equal(t, env.ProducerID, verifiedEnv.ProducerID) assert.Equal(t, env.Signature, verifiedEnv.Signature) assert.Equal(t, env.Body, verifiedEnv.Body) } func TestVerifyEnvelope_NilSigner(t *testing.T) { t.Parallel() env := &model.Envelope{ ProducerID: "producer-1", Signature: []byte("signature"), Body: []byte("body"), } data, err := model.MarshalEnvelope(env) require.NoError(t, err) config := model.EnvelopeConfig{Signer: nil} verifiedEnv, err := model.VerifyEnvelope(data, config) require.Error(t, err) assert.Nil(t, verifiedEnv) assert.Contains(t, err.Error(), "signer is required") }