From 48a8af58dfac0fa0c80a4e909fb954532ccc23a0 Mon Sep 17 00:00:00 2001 From: Tutus Development Date: Sat, 20 Dec 2025 06:44:00 +0000 Subject: [PATCH] Add Eligere native contract tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add basic tests for the Eligere (democratic voting) contract: - TestEligere_GetConfig: Verify default config retrieval - TestEligere_GetProposalCount: Verify initial count is 0 - TestEligere_GetProposal_NonExistent: Verify null for non-existent - TestEligere_CreateProposal_NoVita: Verify Vita requirement - TestEligere_HasVoted_NoVote: Verify hasVoted returns false - TestEligere_Vote_NoVita: Verify Vita requirement for voting Note: Full cross-contract tests for proposal creation/voting with actual Vita holders would require a helper contract since Eligere uses GetCallingScriptHash() for authorization (designed for cross-contract). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- pkg/core/native/native_test/eligere_test.go | 101 ++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 pkg/core/native/native_test/eligere_test.go diff --git a/pkg/core/native/native_test/eligere_test.go b/pkg/core/native/native_test/eligere_test.go new file mode 100644 index 0000000..b84519f --- /dev/null +++ b/pkg/core/native/native_test/eligere_test.go @@ -0,0 +1,101 @@ +package native_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/tutus-one/tutus-chain/pkg/core/native/nativenames" + "github.com/tutus-one/tutus-chain/pkg/core/state" + "github.com/tutus-one/tutus-chain/pkg/neotest" + "github.com/tutus-one/tutus-chain/pkg/vm/stackitem" +) + +func newEligereClient(t *testing.T) *neotest.ContractInvoker { + return newNativeClient(t, nativenames.Eligere) +} + +// TestEligere_GetConfig tests the getConfig method. +func TestEligere_GetConfig(t *testing.T) { + c := newEligereClient(t) + + // Get default config + c.InvokeAndCheck(t, func(t testing.TB, stack []stackitem.Item) { + require.Equal(t, 1, len(stack)) + arr, ok := stack[0].Value().([]stackitem.Item) + require.True(t, ok, "expected array result") + require.GreaterOrEqual(t, len(arr), 7) // EligereConfig has 7 fields + }, "getConfig") +} + +// TestEligere_GetProposalCount tests the getProposalCount method. +func TestEligere_GetProposalCount(t *testing.T) { + c := newEligereClient(t) + + // Initially should be 0 + c.Invoke(t, 0, "getProposalCount") +} + +// TestEligere_GetProposal_NonExistent tests getting a non-existent proposal. +func TestEligere_GetProposal_NonExistent(t *testing.T) { + c := newEligereClient(t) + + // Non-existent proposal should return null + c.InvokeAndCheck(t, func(t testing.TB, stack []stackitem.Item) { + require.Equal(t, 1, len(stack)) + require.Nil(t, stack[0].Value(), "expected null for non-existent proposal") + }, "getProposal", 999) +} + +// TestEligere_CreateProposal_NoVita tests that creating a proposal without a Vita fails. +func TestEligere_CreateProposal_NoVita(t *testing.T) { + c := newEligereClient(t) + e := c.Executor + + acc := e.NewAccount(t) + invoker := c.WithSigners(acc) + + title := "Test Proposal" + contentHash := make([]byte, 32) // 32-byte hash + category := int64(state.ProposalCategoryLawAmendment) + votingStartsAt := int64(10) + votingEndsAt := int64(100) + targetContract := make([]byte, 20) // 20-byte Uint160 + + // Should fail - no Vita registered + invoker.InvokeFail(t, "caller must have active Vita", "createProposal", + title, contentHash, category, votingStartsAt, votingEndsAt, + targetContract, "", []byte{}) +} + +// Note: TestEligere_CreateProposal_Success is skipped because it requires a deployed +// helper contract with a Vita registered to its script hash. The Eligere contract uses +// GetCallingScriptHash() which returns the transaction script for direct calls. + +// TestEligere_HasVoted_NoVote tests hasVoted returns false when not voted. +func TestEligere_HasVoted_NoVote(t *testing.T) { + c := newEligereClient(t) + e := c.Executor + + acc := e.NewAccount(t) + + // hasVoted should return false for any proposal when no vote cast + c.Invoke(t, false, "hasVoted", 0, acc.ScriptHash()) +} + +// TestEligere_Vote_NoVita tests voting without a Vita fails. +func TestEligere_Vote_NoVita(t *testing.T) { + c := newEligereClient(t) + e := c.Executor + + acc := e.NewAccount(t) + invoker := c.WithSigners(acc) + + // Try to vote without Vita + invoker.InvokeFail(t, "caller must have active Vita", "vote", 0, int64(state.VoteChoiceYes)) +} + +// Note: Testing createProposal, vote, tallyVotes, and executeProposal with actual Vita +// holders requires deploying a helper contract that has a Vita registered to its script +// hash and then making cross-contract calls. The Eligere contract uses GetCallingScriptHash() +// which returns the transaction script hash for direct calls, not the signer's account. +// This is the intended design for cross-contract authorization patterns.