Skip to content

Commit

Permalink
add TestAPIElectionsByPage and some dirty refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
altergui committed Jun 19, 2024
1 parent 1d286ca commit f1f9e90
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 21 deletions.
6 changes: 6 additions & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ type ElectionSummary struct {
ChainID string `json:"chainId"`
}

// ElectionsList wraps the elections list to consistently return the list inside an object,
// return empty object if the list does not contains any result
type ElectionsList struct {
Elections []ElectionSummary `json:"elections"`
}

// ElectionResults is the struct used to wrap the results of an election
type ElectionResults struct {
// ABIEncoded is the abi encoded election results
Expand Down
20 changes: 6 additions & 14 deletions api/elections.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,15 @@ func (a *API) electionFullListByPage(ctx *httprouter.HTTPContext, page int) erro
return ErrCantFetchElectionList.WithErr(err)
}

list := []ElectionSummary{}
list := ElectionsList{}
for _, eid := range elections {
e, err := a.indexer.ProcessInfo(eid)
if err != nil {
return ErrCantFetchElection.Withf("(%x): %v", eid, err)
}
list = append(list, a.electionSummary(e))
list.Elections = append(list.Elections, a.electionSummary(e))
}
// wrap list in a struct to consistently return list in an object, return empty
// object if the list does not contains any result
data, err := json.Marshal(struct {
Elections []ElectionSummary `json:"elections"`
}{list})
data, err := json.Marshal(list)
if err != nil {
return ErrMarshalingServerJSONFailed.WithErr(err)
}
Expand Down Expand Up @@ -702,20 +698,16 @@ func (a *API) electionFilterPaginatedHandler(msg *apirest.APIdata, ctx *httprout
return ErrElectionNotFound
}

var list []ElectionSummary
var list ElectionsList
// get election summary
for _, eid := range elections {
e, err := a.indexer.ProcessInfo(eid)
if err != nil {
return ErrCantFetchElection.WithErr(err)
}
list = append(list, a.electionSummary(e))
list.Elections = append(list.Elections, a.electionSummary(e))
}
data, err := json.Marshal(struct {
Elections []ElectionSummary `json:"elections"`
}{
Elections: list,
})
data, err := json.Marshal(list)
if err != nil {
return ErrMarshalingServerJSONFailed.WithErr(err)
}
Expand Down
85 changes: 80 additions & 5 deletions test/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func TestAPIcensusAndVote(t *testing.T) {
qt.Assert(t, censusData.Weight.String(), qt.Equals, "1")

electionParams := electionprice.ElectionParameters{ElectionDuration: 100, MaxCensusSize: 100}
election := createElection(t, c, server.Account, electionParams, censusData.CensusRoot, 0, server.VochainAPP.ChainID(), false)
election := createElection(t, c, server.Account, electionParams, censusData.CensusRoot, 0, server.VochainAPP.ChainID(), false, 0)

// Block 2
server.VochainAPP.AdvanceTestBlock()
Expand Down Expand Up @@ -441,7 +441,7 @@ func runAPIElectionCostWithParams(t *testing.T,
qt.Assert(t, requestAccount(t, c, signer.Address().String()).Balance,
qt.Equals, initialBalance)

createElection(t, c, signer, electionParams, censusRoot, startBlock, server.VochainAPP.ChainID(), false)
createElection(t, c, signer, electionParams, censusRoot, startBlock, server.VochainAPP.ChainID(), false, 0)

// Block 3
server.VochainAPP.AdvanceTestBlock()
Expand Down Expand Up @@ -507,6 +507,7 @@ func createElection(t testing.TB, c *testutil.TestHTTPclient,
startBlock uint32,
chainID string,
encryptedMetadata bool,
nonce uint32,
) api.ElectionCreate {
metadataBytes, err := json.Marshal(
&api.ElectionMetadata{
Expand All @@ -529,7 +530,7 @@ func createElection(t testing.TB, c *testutil.TestHTTPclient,
tx := models.Tx_NewProcess{
NewProcess: &models.NewProcessTx{
Txtype: models.TxType_NEW_PROCESS,
Nonce: 0,
Nonce: nonce,
Process: &models.Process{
StartBlock: startBlock,
BlockCount: electionParams.ElectionDuration,
Expand Down Expand Up @@ -733,7 +734,7 @@ func TestAPIBuildElectionID(t *testing.T) {

// create a new election
electionParams := electionprice.ElectionParameters{ElectionDuration: 100, MaxCensusSize: 100}
response := createElection(t, c, signer, electionParams, censusRoot, 0, server.VochainAPP.ChainID(), false)
response := createElection(t, c, signer, electionParams, censusRoot, 0, server.VochainAPP.ChainID(), false, 0)

// Block 4
server.VochainAPP.AdvanceTestBlock()
Expand Down Expand Up @@ -804,7 +805,7 @@ func TestAPIEncryptedMetadata(t *testing.T) {

// create a new election
electionParams := electionprice.ElectionParameters{ElectionDuration: 100, MaxCensusSize: 100}
electionResponse := createElection(t, c, signer, electionParams, censusRoot, 0, server.VochainAPP.ChainID(), true)
electionResponse := createElection(t, c, signer, electionParams, censusRoot, 0, server.VochainAPP.ChainID(), true, 0)

// Block 4
server.VochainAPP.AdvanceTestBlock()
Expand All @@ -830,3 +831,77 @@ func TestAPIEncryptedMetadata(t *testing.T) {
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, metadata.Title["default"], qt.Equals, "test election")
}

func TestAPIElectionsByPage(t *testing.T) {
server := testcommon.APIserver{}
server.Start(t,
api.ChainHandler,
api.CensusHandler,
api.VoteHandler,
api.AccountHandler,
api.ElectionHandler,
api.WalletHandler,
)
// Block 1
server.VochainAPP.AdvanceTestBlock()

token1 := uuid.New()
c := testutil.NewTestHTTPclient(t, server.ListenAddr, &token1)

// create a new census
resp, code := c.Request("POST", nil, "censuses", "weighted")
qt.Assert(t, code, qt.Equals, 200)
censusData := &api.Census{}
qt.Assert(t, json.Unmarshal(resp, censusData), qt.IsNil)
id1 := censusData.CensusID.String()

// add a bunch of keys and values (weights)
rnd := testutil.NewRandom(1)
cparts := api.CensusParticipants{}
for i := 1; i < 10; i++ {
cparts.Participants = append(cparts.Participants, api.CensusParticipant{
Key: rnd.RandomBytes(20),
Weight: (*types.BigInt)(big.NewInt(int64(1))),
})
}
_, code = c.Request("POST", &cparts, "censuses", id1, "participants")
qt.Assert(t, code, qt.Equals, 200)

resp, code = c.Request("POST", nil, "censuses", id1, "publish")
qt.Assert(t, code, qt.Equals, 200)
qt.Assert(t, json.Unmarshal(resp, censusData), qt.IsNil)
qt.Assert(t, censusData.CensusID, qt.IsNotNil)

electionParams := electionprice.ElectionParameters{ElectionDuration: 100, MaxCensusSize: 100}
for nonce := uint32(0); nonce < 20; nonce++ {
createElection(t, c, server.Account, electionParams, censusData.CensusRoot, 0, server.VochainAPP.ChainID(), false, nonce)
}

// Block 2
server.VochainAPP.AdvanceTestBlock()
waitUntilHeight(t, c, 2)

// Get the list of elections and check it
fetchEL := func(method string, jsonBody any, query string, urlPath ...string) api.ElectionsList {
resp, code = c.RequestWithQuery(method, jsonBody, query, urlPath...)
elections := api.ElectionsList{}
qt.Assert(t, code, qt.Equals, 200)
err := json.Unmarshal(resp, &elections)
qt.Assert(t, err, qt.IsNil)
return elections
}

el := make(map[string]api.ElectionsList)
el["0"] = fetchEL("GET", nil, "", "elections")
el["1"] = fetchEL("GET", nil, "page=1", "elections")
el["p0"] = fetchEL("GET", nil, "", "elections", "page", "0")
el["p1"] = fetchEL("GET", nil, "", "elections", "page", "1")

qt.Assert(t, el["0"], qt.Not(qt.DeepEquals), el["1"])
qt.Assert(t, el["0"], qt.DeepEquals, el["p0"])
qt.Assert(t, el["1"], qt.DeepEquals, el["p1"])

for _, item := range el {
qt.Assert(t, len(item.Elections), qt.Equals, api.MaxPageSize)
}
}
15 changes: 13 additions & 2 deletions test/testcommon/testutil/apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,27 @@ type TestHTTPclient struct {
t testing.TB
}

func (c *TestHTTPclient) Request(method string, jsonBody any, urlPath ...string) ([]byte, int) {
body, err := json.Marshal(jsonBody)
func (c *TestHTTPclient) RequestWithQuery(method string, jsonBody any, query string, urlPath ...string) ([]byte, int) {
u, err := url.Parse(c.addr.String())
qt.Assert(c.t, err, qt.IsNil)
u.RawQuery = query
return c.request(method, u, jsonBody, urlPath...)
}

func (c *TestHTTPclient) Request(method string, jsonBody any, urlPath ...string) ([]byte, int) {
u, err := url.Parse(c.addr.String())
qt.Assert(c.t, err, qt.IsNil)
return c.request(method, u, jsonBody, urlPath...)
}

func (c *TestHTTPclient) request(method string, u *url.URL, jsonBody any, urlPath ...string) ([]byte, int) {
u.Path = path.Join(u.Path, path.Join(urlPath...))
headers := http.Header{}
if c.token != nil {
headers = http.Header{"Authorization": []string{"Bearer " + c.token.String()}}
}
body, err := json.Marshal(jsonBody)
qt.Assert(c.t, err, qt.IsNil)
c.t.Logf("querying %s", u)
resp, err := c.c.Do(&http.Request{
Method: method,
Expand Down

0 comments on commit f1f9e90

Please sign in to comment.