Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: endpoint /elections now filters by title and description (WIP) #1373

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
api: endpoint /elections now filters by title and description (WIP)
  • Loading branch information
altergui committed Aug 28, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 43d20894d6f619ddb1835272cd480759a2920bc7
2 changes: 2 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -67,6 +67,8 @@ const (
ParamVoteId = "voteId"
ParamPage = "page"
ParamLimit = "limit"
ParamTitle = "title"
ParamDescription = "description"
ParamStatus = "status"
ParamWithResults = "withResults"
ParamFinalResults = "finalResults"
4 changes: 4 additions & 0 deletions api/api_types.go
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@ type ElectionParams struct {
StartDateBefore *time.Time `json:"startDateBefore,omitempty"`
EndDateAfter *time.Time `json:"endDateAfter,omitempty"`
EndDateBefore *time.Time `json:"endDateBefore,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
}

// OrganizationParams allows the client to filter organizations
@@ -122,6 +124,8 @@ type ElectionSummary struct {
Results [][]*types.BigInt `json:"result,omitempty"`
ManuallyEnded bool `json:"manuallyEnded"`
ChainID string `json:"chainId"`
Title string `json:"title"`
Description string `json:"description"`
}

// ElectionsList is used to return a paginated list to the client
8 changes: 8 additions & 0 deletions api/elections.go
Original file line number Diff line number Diff line change
@@ -256,6 +256,8 @@ func (a *API) electionListByPageHandler(_ *apirest.APIdata, ctx *httprouter.HTTP
// @Param organizationId query string false "Filter by partial organizationId"
// @Param status query string false "Election status" Enums(ready, paused, canceled, ended, results)
// @Param electionId query string false "Filter by partial electionId"
// @Param title query string false "Filter by election title"
// @Param descrition query string false "Filter by election description"
// @Param withResults query boolean false "Filter by (partial or final) results available or not"
// @Param finalResults query boolean false "Filter by final results available or not"
// @Param manuallyEnded query boolean false "Filter by whether the election was manually ended or not"
@@ -268,6 +270,8 @@ func (a *API) electionListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContex
ParamStatus,
ParamOrganizationId,
ParamElectionId,
ParamTitle,
ParamDescription,
ParamWithResults,
ParamFinalResults,
ParamManuallyEnded,
@@ -316,6 +320,8 @@ func (a *API) electionList(params *ElectionParams) (*ElectionsList, error) {
params.StartDateBefore,
params.EndDateAfter,
params.EndDateBefore,
params.Title,
params.Description,
)
if err != nil {
return nil, ErrIndexerQueryFailed.WithErr(err)
@@ -831,6 +837,8 @@ func electionParams(f func(key string) string, keys ...string) (*ElectionParams,
PaginationParams: pagination,
OrganizationID: util.TrimHex(strings[ParamOrganizationId]),
ElectionID: util.TrimHex(strings[ParamElectionId]),
Title: strings[ParamTitle],
Description: strings[ParamDescription],
Status: strings[ParamStatus],
WithResults: bools[ParamWithResults],
FinalResults: bools[ParamFinalResults],
2 changes: 2 additions & 0 deletions vochain/indexer/db/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 39 additions & 23 deletions vochain/indexer/db/processes.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 17 additions & 17 deletions vochain/indexer/indexer_test.go
Original file line number Diff line number Diff line change
@@ -332,7 +332,7 @@ func testProcessList(t *testing.T, procsCount int) {
for len(procs) < procsCount {
fmt.Printf("%x\n", eidProcsCount)
fmt.Printf("%s\n", hex.EncodeToString(eidProcsCount))
list, total, err := idx.ProcessList(10, last, hex.EncodeToString(eidProcsCount), "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, total, err := idx.ProcessList(10, last, hex.EncodeToString(eidProcsCount), "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -351,7 +351,7 @@ func testProcessList(t *testing.T, procsCount int) {
}
qt.Assert(t, procs, qt.HasLen, procsCount)

_, total, err := idx.ProcessList(64, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
_, total, err := idx.ProcessList(64, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, total, qt.Equals, uint64(10+procsCount))

@@ -369,7 +369,7 @@ func testProcessList(t *testing.T, procsCount int) {
qt.Assert(t, countEntityProcs([]byte("not an entity id that exists")), qt.Equals, int64(-1))

// Past the end (from=10000) should return an empty list
emptyList, _, err := idx.ProcessList(64, 10000, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
emptyList, _, err := idx.ProcessList(64, 10000, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, emptyList, qt.DeepEquals, [][]byte{})
}
@@ -459,7 +459,7 @@ func TestProcessSearch(t *testing.T) {
app.AdvanceTestBlock()

// Exact process search
list, _, err := idx.ProcessList(10, 0, hex.EncodeToString(eidTest), pidExact, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err := idx.ProcessList(10, 0, hex.EncodeToString(eidTest), pidExact, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -468,7 +468,7 @@ func TestProcessSearch(t *testing.T) {
}
// Exact process search, with it being encrypted.
// This once caused a sqlite bug due to a mistake in the SQL query.
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), pidExactEncrypted, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), pidExactEncrypted, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -477,7 +477,7 @@ func TestProcessSearch(t *testing.T) {
}
// Search for nonexistent process
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest),
"4011d50537fa164b6fef261141797bbe4014526f", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
"4011d50537fa164b6fef261141797bbe4014526f", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -486,7 +486,7 @@ func TestProcessSearch(t *testing.T) {
}
// Search containing part of all manually-defined processes
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest),
"011d50537fa164b6fef261141797bbe4014526e", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
"011d50537fa164b6fef261141797bbe4014526e", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -495,7 +495,7 @@ func TestProcessSearch(t *testing.T) {
}

list, _, err = idx.ProcessList(100, 0, hex.EncodeToString(eidTest),
"0c6ca22d2c175a1fbdd15d7595ae532bb1094b5", 0, 0, models.ProcessStatus_ENDED, nil, nil, nil, nil, nil, nil, nil)
"0c6ca22d2c175a1fbdd15d7595ae532bb1094b5", 0, 0, models.ProcessStatus_ENDED, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -504,17 +504,17 @@ func TestProcessSearch(t *testing.T) {
}

// Partial process search as uppercase hex
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), "011D50537FA164B6FEF261141797BBE4014526E", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), "011D50537FA164B6FEF261141797BBE4014526E", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, list, qt.HasLen, len(processIds))
// Partial process search as mixed case hex
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), "011D50537fA164B6FeF261141797BbE4014526E", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(10, 0, hex.EncodeToString(eidTest), "011D50537fA164B6FeF261141797BbE4014526E", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, list, qt.HasLen, len(processIds))

// Search with an exact Entity ID, but starting with a null byte.
// This can trip up sqlite, as it assumes TEXT strings are NUL-terminated.
list, _, err = idx.ProcessList(100, 0, "\x00foobar", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(100, 0, "\x00foobar", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
t.Fatal(err)
}
@@ -523,12 +523,12 @@ func TestProcessSearch(t *testing.T) {
}

// list all processes, with a max of 10
list, _, err = idx.ProcessList(10, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(10, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, list, qt.HasLen, 10)

// list all processes, with a max of 1000
list, _, err = idx.ProcessList(1000, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(1000, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
qt.Assert(t, list, qt.HasLen, 21)
}
@@ -577,25 +577,25 @@ func TestProcessListWithNamespaceAndStatus(t *testing.T) {
app.AdvanceTestBlock()

// Get the process list for namespace 123
list, _, err := idx.ProcessList(100, 0, hex.EncodeToString(eid20), "", 123, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err := idx.ProcessList(100, 0, hex.EncodeToString(eid20), "", 123, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
// Check there are exactly 10
qt.Assert(t, len(list), qt.CmpEquals(), 10)

// Get the process list for all namespaces
list, _, err = idx.ProcessList(100, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(100, 0, "", "", 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
// Check there are exactly 10 + 10
qt.Assert(t, len(list), qt.CmpEquals(), 20)

// Get the process list for namespace 10
list, _, err = idx.ProcessList(100, 0, "", "", 10, 0, 0, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(100, 0, "", "", 10, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
// Check there is exactly 1
qt.Assert(t, len(list), qt.CmpEquals(), 1)

// Get the process list for namespace 10
list, _, err = idx.ProcessList(100, 0, "", "", 0, 0, models.ProcessStatus_READY, nil, nil, nil, nil, nil, nil, nil)
list, _, err = idx.ProcessList(100, 0, "", "", 0, 0, models.ProcessStatus_READY, nil, nil, nil, nil, nil, nil, nil, "", "")
qt.Assert(t, err, qt.IsNil)
// Check there is exactly 1
qt.Assert(t, len(list), qt.CmpEquals(), 10)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- +goose Up
ALTER TABLE processes ADD COLUMN title TEXT NOT NULL DEFAULT '';
ALTER TABLE processes ADD COLUMN description TEXT NOT NULL DEFAULT '';

-- +goose Down
ALTER TABLE processes DROP COLUMN description;
ALTER TABLE processes DROP COLUMN title;
5 changes: 4 additions & 1 deletion vochain/indexer/process.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ func (idx *Indexer) ProcessList(limit, offset int, entityID string, processID st
namespace uint32, srcNetworkID int32, status models.ProcessStatus,
withResults, finalResults, manuallyEnded *bool,
startDateAfter, startDateBefore, endDateAfter, endDateBefore *time.Time,
title, description string,
) ([][]byte, uint64, error) {
if offset < 0 {
return nil, 0, fmt.Errorf("invalid value: offset cannot be %d", offset)
@@ -78,6 +79,8 @@ func (idx *Indexer) ProcessList(limit, offset int, entityID string, processID st
StartDateBefore: startDateBefore,
EndDateAfter: endDateAfter,
EndDateBefore: endDateBefore,
Title: title,
Description: description,
})
if err != nil {
return nil, 0, err
@@ -98,7 +101,7 @@ func (idx *Indexer) ProcessExists(processID string) bool {
if len(processID) != 64 {
return false
}
_, count, err := idx.ProcessList(1, 0, "", processID, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil)
_, count, err := idx.ProcessList(1, 0, "", processID, 0, 0, 0, nil, nil, nil, nil, nil, nil, nil, "", "")
if err != nil {
log.Errorw(err, "indexer query failed")
}
Loading