• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vocdoni / saas-backend / 16367652533

18 Jul 2025 09:53AM UTC coverage: 57.638% (+0.7%) from 56.89%
16367652533

Pull #165

github

web-flow
[skip-ci] refactor CheckGroupMembersFields (#197)
Pull Request #165: Implements group based census creation

248 of 392 new or added lines in 9 files covered. (63.27%)

5 existing lines in 4 files now uncovered.

5188 of 9001 relevant lines covered (57.64%)

26.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.41
/api/process.go
1
package api
2

3
import (
4
        "encoding/json"
5
        "net/http"
6

7
        "github.com/go-chi/chi/v5"
8
        "github.com/vocdoni/saas-backend/api/apicommon"
9
        "github.com/vocdoni/saas-backend/db"
10
        "github.com/vocdoni/saas-backend/errors"
11
        "github.com/vocdoni/saas-backend/internal"
12
)
13

14
// createProcessHandler godoc
15
//
16
//        @Summary                Create a new voting process
17
//        @Description        Create a new voting process. Requires Manager/Admin role.
18
//        @Tags                        process
19
//        @Accept                        json
20
//        @Produce                json
21
//        @Security                BearerAuth
22
//        @Param                        processId        path                string                                                        true        "Process ID"
23
//        @Param                        request                body                apicommon.CreateProcessRequest        true        "Process creation information"
24
//        @Success                200                        {string}        string                                                        "OK"
25
//        @Failure                400                        {object}        errors.Error                                        "Invalid input data"
26
//        @Failure                401                        {object}        errors.Error                                        "Unauthorized"
27
//        @Failure                404                        {object}        errors.Error                                        "Published census not found"
28
//        @Failure                409                        {object}        errors.Error                                        "Process already exists"
29
//        @Failure                500                        {object}        errors.Error                                        "Internal server error"
30
//        @Router                        /process/{processId} [post]
31
func (a *API) createProcessHandler(w http.ResponseWriter, r *http.Request) {
3✔
32
        processID := internal.HexBytes{}
3✔
33
        if err := processID.ParseString(chi.URLParam(r, "processId")); err != nil {
4✔
34
                errors.ErrMalformedURLParam.Withf("missing process ID").Write(w)
1✔
35
                return
1✔
36
        }
1✔
37

38
        processInfo := &apicommon.CreateProcessRequest{}
2✔
39
        if err := json.NewDecoder(r.Body).Decode(&processInfo); err != nil {
2✔
40
                errors.ErrMalformedBody.Write(w)
×
41
                return
×
42
        }
×
43

44
        if processInfo.PublishedCensusRoot == nil || processInfo.CensusID == nil {
3✔
45
                errors.ErrMalformedBody.Withf("missing published census root or ID").Write(w)
1✔
46
                return
1✔
47
        }
1✔
48

49
        // get the user from the request context
50
        user, ok := apicommon.UserFromContext(r.Context())
1✔
51
        if !ok {
1✔
52
                errors.ErrUnauthorized.Write(w)
×
53
                return
×
54
        }
×
55

56
        census, err := a.db.Census(processInfo.CensusID.String())
1✔
57
        if err != nil {
1✔
58
                if err == db.ErrNotFound {
×
NEW
59
                        errors.ErrMalformedURLParam.Withf("census not found").Write(w)
×
60
                        return
×
61
                }
×
62
                errors.ErrGenericInternalServerError.WithErr(err).Write(w)
×
63
                return
×
64
        }
65

66
        if processInfo.PublishedCensusRoot.String() != census.Published.Root.String() ||
1✔
67
                processInfo.PublishedCensusURI != census.Published.URI {
1✔
NEW
68
                errors.ErrMalformedBody.Withf("published census root or URI does not match census").Write(w)
×
NEW
69
                return
×
NEW
70
        }
×
71

72
        // check the user has the necessary permissions
73
        if !user.HasRoleFor(census.OrgAddress, db.ManagerRole) && !user.HasRoleFor(census.OrgAddress, db.AdminRole) {
1✔
74
                errors.ErrUnauthorized.Withf("user is not admin of organization").Write(w)
×
75
                return
×
76
        }
×
77

78
        // check that the process does not exist
79
        if _, err := a.db.Process(processID); err == nil {
1✔
80
                errors.ErrDuplicateConflict.Withf("process already exists").Write(w)
×
81
                return
×
82
        }
×
83

84
        // finally create the process
85
        process := &db.Process{
1✔
86
                ID:         processID,
1✔
87
                Census:     *census,
1✔
88
                Metadata:   processInfo.Metadata,
1✔
89
                OrgAddress: census.OrgAddress,
1✔
90
        }
1✔
91

1✔
92
        if err := a.db.SetProcess(process); err != nil {
1✔
93
                errors.ErrGenericInternalServerError.WithErr(err).Write(w)
×
94
                return
×
95
        }
×
96

97
        apicommon.HTTPWriteOK(w)
1✔
98
}
99

100
// processInfoHandler godoc
101
//
102
//        @Summary                Get process information
103
//        @Description        Retrieve voting process information by ID. Returns process details including census and metadata.
104
//        @Tags                        process
105
//        @Accept                        json
106
//        @Produce                json
107
//        @Param                        processId        path                string        true        "Process ID"
108
//        @Success                200                        {object}        db.Process
109
//        @Failure                400                        {object}        errors.Error        "Invalid process ID"
110
//        @Failure                404                        {object}        errors.Error        "Process not found"
111
//        @Failure                500                        {object}        errors.Error        "Internal server error"
112
//        @Router                        /process/{processId} [get]
113
func (a *API) processInfoHandler(w http.ResponseWriter, r *http.Request) {
1✔
114
        processID := chi.URLParam(r, "processId")
1✔
115
        if len(processID) == 0 {
1✔
116
                errors.ErrMalformedURLParam.Withf("missing process ID").Write(w)
×
117
                return
×
118
        }
×
119

120
        process, err := a.db.Process([]byte(processID))
1✔
121
        if err != nil {
2✔
122
                if err == db.ErrNotFound {
1✔
123
                        errors.ErrMalformedURLParam.Withf("process not found").Write(w)
×
124
                        return
×
125
                }
×
126
                errors.ErrGenericInternalServerError.WithErr(err).Write(w)
1✔
127
                return
1✔
128
        }
129

130
        apicommon.HTTPWriteJSON(w, process)
×
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc