Skip to content

Commit 57caa27

Browse files
committed
test: add KWH deposit tests for InstrumentAmount input path
Cover: KWH deposit success, instrument mismatch, invalid/malformed amounts, legacy MoneyAmount backwards compat, input-takes-precedence, and neither-input-nor-amount error case. All 7 tests pass alongside existing deposit tests.
1 parent c2ec5be commit 57caa27

1 file changed

Lines changed: 224 additions & 0 deletions

File tree

services/current-account/service/grpc_service_test.go

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/google/uuid"
1717
commonpb "github.com/meridianhub/meridian/api/proto/meridian/common/v1"
1818
pb "github.com/meridianhub/meridian/api/proto/meridian/current_account/v1"
19+
quantityv1 "github.com/meridianhub/meridian/api/proto/meridian/quantity/v1"
1920
"github.com/meridianhub/meridian/services/current-account/adapters/persistence"
2021
"github.com/meridianhub/meridian/services/current-account/domain"
2122
"github.com/meridianhub/meridian/services/reference-data/cache"
@@ -658,6 +659,229 @@ func TestExecuteDepositCurrencyMismatch(t *testing.T) {
658659
}
659660
}
660661

662+
func TestExecuteDeposit_InstrumentAmountInput_KWH(t *testing.T) {
663+
db, ctx, cleanup := setupTestDB(t)
664+
defer cleanup()
665+
666+
repo := persistence.NewRepository(db)
667+
// Mock PK returns 1500 minor units (1500 KWH with precision 0)
668+
svc := mustNewServiceWithPositionKeeping(t, repo, nil, map[string]int64{
669+
"ACC-KWH-001": 1500,
670+
})
671+
672+
// Create KWH energy account (precision 0 = whole kWh units)
673+
account, err := domain.NewCurrentAccountWithDimension(
674+
"ACC-KWH-001", "KWH-IDENT-001", uuid.New().String(), "KWH", "ENERGY", 0,
675+
)
676+
require.NoError(t, err)
677+
require.NoError(t, repo.Save(ctx, account))
678+
679+
// Deposit 8.5 KWH using InstrumentAmount input field
680+
req := &pb.ExecuteDepositRequest{
681+
AccountId: "ACC-KWH-001",
682+
Description: "Meter read 2026-03-20: 8.50 kWh",
683+
Input: &quantityv1.InstrumentAmount{
684+
Amount: "8.5",
685+
InstrumentCode: "KWH",
686+
Version: 1,
687+
},
688+
}
689+
690+
resp, err := svc.ExecuteDeposit(ctx, req)
691+
require.NoError(t, err, "KWH deposit via InstrumentAmount should succeed")
692+
693+
require.Equal(t, "ACC-KWH-001", resp.AccountId)
694+
require.NotEmpty(t, resp.TransactionId)
695+
require.Equal(t, pb.TransactionStatus_TRANSACTION_STATUS_COMPLETED, resp.Status)
696+
}
697+
698+
func TestExecuteDeposit_InstrumentAmountInput_InstrumentMismatch(t *testing.T) {
699+
db, ctx, cleanup := setupTestDB(t)
700+
defer cleanup()
701+
702+
repo := persistence.NewRepository(db)
703+
svc := mustNewService(t, repo, nil)
704+
705+
// Create GBP account
706+
account, err := domain.NewCurrentAccount("ACC-001", "ACC-001", uuid.New().String(), "GBP")
707+
require.NoError(t, err)
708+
require.NoError(t, repo.Save(ctx, account))
709+
710+
// Try to deposit KWH to a GBP account
711+
req := &pb.ExecuteDepositRequest{
712+
AccountId: "ACC-001",
713+
Input: &quantityv1.InstrumentAmount{
714+
Amount: "100",
715+
InstrumentCode: "KWH",
716+
Version: 1,
717+
},
718+
}
719+
720+
_, err = svc.ExecuteDeposit(ctx, req)
721+
require.Error(t, err)
722+
723+
st, ok := status.FromError(err)
724+
require.True(t, ok)
725+
require.Equal(t, codes.InvalidArgument, st.Code())
726+
require.Contains(t, st.Message(), "instrument mismatch")
727+
}
728+
729+
func TestExecuteDeposit_InstrumentAmountInput_InvalidAmount(t *testing.T) {
730+
db, ctx, cleanup := setupTestDB(t)
731+
defer cleanup()
732+
733+
repo := persistence.NewRepository(db)
734+
svc := mustNewService(t, repo, nil)
735+
736+
// Create KWH account
737+
account, err := domain.NewCurrentAccountWithDimension(
738+
"ACC-KWH-001", "KWH-IDENT-001", uuid.New().String(), "KWH", "ENERGY", 0,
739+
)
740+
require.NoError(t, err)
741+
require.NoError(t, repo.Save(ctx, account))
742+
743+
// Non-positive amount
744+
req := &pb.ExecuteDepositRequest{
745+
AccountId: "ACC-KWH-001",
746+
Input: &quantityv1.InstrumentAmount{
747+
Amount: "-5",
748+
InstrumentCode: "KWH",
749+
Version: 1,
750+
},
751+
}
752+
753+
_, err = svc.ExecuteDeposit(ctx, req)
754+
require.Error(t, err)
755+
756+
st, ok := status.FromError(err)
757+
require.True(t, ok)
758+
require.Equal(t, codes.InvalidArgument, st.Code())
759+
require.Contains(t, st.Message(), "positive")
760+
}
761+
762+
func TestExecuteDeposit_InstrumentAmountInput_MalformedAmount(t *testing.T) {
763+
db, ctx, cleanup := setupTestDB(t)
764+
defer cleanup()
765+
766+
repo := persistence.NewRepository(db)
767+
svc := mustNewService(t, repo, nil)
768+
769+
// Create KWH account
770+
account, err := domain.NewCurrentAccountWithDimension(
771+
"ACC-KWH-001", "KWH-IDENT-001", uuid.New().String(), "KWH", "ENERGY", 0,
772+
)
773+
require.NoError(t, err)
774+
require.NoError(t, repo.Save(ctx, account))
775+
776+
// Malformed amount string
777+
req := &pb.ExecuteDepositRequest{
778+
AccountId: "ACC-KWH-001",
779+
Input: &quantityv1.InstrumentAmount{
780+
Amount: "not-a-number",
781+
InstrumentCode: "KWH",
782+
Version: 1,
783+
},
784+
}
785+
786+
_, err = svc.ExecuteDeposit(ctx, req)
787+
require.Error(t, err)
788+
789+
st, ok := status.FromError(err)
790+
require.True(t, ok)
791+
require.Equal(t, codes.InvalidArgument, st.Code())
792+
}
793+
794+
func TestExecuteDeposit_LegacyMoneyAmount_StillWorks(t *testing.T) {
795+
db, ctx, cleanup := setupTestDB(t)
796+
defer cleanup()
797+
798+
repo := persistence.NewRepository(db)
799+
svc := mustNewServiceWithPositionKeeping(t, repo, nil, map[string]int64{
800+
"ACC-GBP-001": 10050,
801+
})
802+
803+
// Create GBP account
804+
account, err := domain.NewCurrentAccount("ACC-GBP-001", "ACC-GBP-001", uuid.New().String(), "GBP")
805+
require.NoError(t, err)
806+
require.NoError(t, repo.Save(ctx, account))
807+
808+
// Legacy path: use MoneyAmount (backwards compat)
809+
req := &pb.ExecuteDepositRequest{
810+
AccountId: "ACC-GBP-001",
811+
Amount: &commonpb.MoneyAmount{
812+
Amount: &money.Money{
813+
CurrencyCode: "GBP",
814+
Units: 100,
815+
Nanos: 500000000,
816+
},
817+
},
818+
Description: "Legacy GBP deposit",
819+
}
820+
821+
resp, err := svc.ExecuteDeposit(ctx, req)
822+
require.NoError(t, err, "legacy MoneyAmount deposit should still work")
823+
require.Equal(t, "ACC-GBP-001", resp.AccountId)
824+
require.Equal(t, pb.TransactionStatus_TRANSACTION_STATUS_COMPLETED, resp.Status)
825+
}
826+
827+
func TestExecuteDeposit_InputTakesPrecedenceOverAmount(t *testing.T) {
828+
db, ctx, cleanup := setupTestDB(t)
829+
defer cleanup()
830+
831+
repo := persistence.NewRepository(db)
832+
svc := mustNewServiceWithPositionKeeping(t, repo, nil, map[string]int64{
833+
"ACC-KWH-002": 500,
834+
})
835+
836+
// Create KWH account
837+
account, err := domain.NewCurrentAccountWithDimension(
838+
"ACC-KWH-002", "KWH-IDENT-002", uuid.New().String(), "KWH", "ENERGY", 0,
839+
)
840+
require.NoError(t, err)
841+
require.NoError(t, repo.Save(ctx, account))
842+
843+
// Both input and amount provided - input should take precedence
844+
req := &pb.ExecuteDepositRequest{
845+
AccountId: "ACC-KWH-002",
846+
Amount: &commonpb.MoneyAmount{
847+
Amount: &money.Money{
848+
CurrencyCode: "GBP", // wrong instrument - should be ignored
849+
Units: 999,
850+
},
851+
},
852+
Input: &quantityv1.InstrumentAmount{
853+
Amount: "10",
854+
InstrumentCode: "KWH",
855+
Version: 1,
856+
},
857+
}
858+
859+
resp, err := svc.ExecuteDeposit(ctx, req)
860+
require.NoError(t, err, "input field should take precedence over amount field")
861+
require.Equal(t, "ACC-KWH-002", resp.AccountId)
862+
require.Equal(t, pb.TransactionStatus_TRANSACTION_STATUS_COMPLETED, resp.Status)
863+
}
864+
865+
func TestExecuteDeposit_NeitherInputNorAmount_ReturnsError(t *testing.T) {
866+
db, ctx, cleanup := setupTestDB(t)
867+
defer cleanup()
868+
869+
repo := persistence.NewRepository(db)
870+
svc := mustNewService(t, repo, nil)
871+
872+
req := &pb.ExecuteDepositRequest{
873+
AccountId: "ACC-001",
874+
// Neither amount nor input provided
875+
}
876+
877+
_, err := svc.ExecuteDeposit(ctx, req)
878+
require.Error(t, err)
879+
880+
st, ok := status.FromError(err)
881+
require.True(t, ok)
882+
require.Equal(t, codes.InvalidArgument, st.Code())
883+
}
884+
661885
func TestInitiateCurrentAccountUnsupportedCurrency(t *testing.T) {
662886
db, ctx, cleanup := setupTestDB(t)
663887
defer cleanup()

0 commit comments

Comments
 (0)