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

pace / bricks / 12827718001

17 Jan 2025 10:57AM UTC coverage: 56.909% (-0.3%) from 57.237%
12827718001

Pull #384

github

monstermunchkin
Satisfy linters
Pull Request #384: Extend linting

478 of 946 new or added lines in 109 files covered. (50.53%)

133 existing lines in 53 files now uncovered.

5667 of 9958 relevant lines covered (56.91%)

21.51 hits per line

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

84.21
/http/jsonapi/runtime/validation.go
1
// Copyright © 2018 by PACE Telematics GmbH. All rights reserved.
2

3
package runtime
4

5
import (
6
        "errors"
7
        "fmt"
8
        "net/http"
9
        "strings"
10
        "time"
11

12
        valid "github.com/asaskevich/govalidator"
13

14
        "github.com/pace/bricks/pkg/isotime"
15
)
16

17
func init() {
1✔
18
        valid.CustomTypeTagMap.Set("iso8601", valid.CustomTypeValidator(func(i interface{}, o interface{}) bool {
1✔
19
                switch v := i.(type) {
×
20
                case time.Time:
×
21
                        return true
×
22
                case string:
×
23
                        _, err := isotime.ParseISO8601(v)
×
24
                        return err == nil
×
25
                }
26

27
                return false
×
28
        }))
29
}
30

31
// ValidateParameters checks the given struct and returns true if the struct
32
// is valid according to the specification (declared with go-validator struct tags)
33
// In case of an error, an jsonapi error message will be directly send to the client.
34
func ValidateParameters(w http.ResponseWriter, r *http.Request, data interface{}) bool {
1✔
35
        return ValidateStruct(w, r, data, "parameter")
1✔
36
}
1✔
37

38
// ValidateRequest checks the given struct and returns true if the struct
39
// is valid according to the specification (declared with go-validator struct tags)
40
// In case of an error, an jsonapi error message will be directly send to the client.
41
func ValidateRequest(w http.ResponseWriter, r *http.Request, data interface{}) bool {
5✔
42
        return ValidateStruct(w, r, data, "pointer")
5✔
43
}
5✔
44

45
// ValidateStruct checks the given struct and returns true if the struct
46
// is valid according to the specification (declared with go-validator struct tags)
47
// In case of an error, an jsonapi error message will be directly send to the client
48
// The passed source is the source for validation errors (e.g. pointer for data or parameter).
49
func ValidateStruct(w http.ResponseWriter, r *http.Request, data interface{}, source string) bool {
8✔
50
        ok, err := valid.ValidateStruct(data)
8✔
51
        if !ok {
10✔
52
                validErrors := valid.Errors{}
2✔
53

2✔
54
                if errors.As(err, &validErrors) {
4✔
55
                        var e Errors
2✔
56

2✔
57
                        generateValidationErrors(validErrors, &e, source)
2✔
58
                        WriteError(w, http.StatusUnprocessableEntity, e)
2✔
59
                } else {
2✔
NEW
60
                        panic(fmt.Errorf("unhandled error case: %w", err))
×
61
                }
62

63
                return false
2✔
64
        }
65

66
        return true
6✔
67
}
68

69
// convert govalidator errors into jsonapi errors.
70
func generateValidationErrors(validErrors valid.Errors, jsonapiErrors *Errors, source string) {
3✔
71
        for _, err := range validErrors {
7✔
72
                validErrors := valid.Errors{}
4✔
73

4✔
74
                if errors.As(err, &validErrors) {
5✔
75
                        generateValidationErrors(validErrors, jsonapiErrors, source)
1✔
76
                } else {
4✔
77
                        validError := valid.Error{}
3✔
78

3✔
79
                        if errors.As(err, &validError) {
6✔
80
                                *jsonapiErrors = append(*jsonapiErrors, generateValidationError(validError, source))
3✔
81
                        } else {
3✔
NEW
82
                                panic(fmt.Errorf("unhandled error case: %w", err))
×
83
                        }
84
                }
85
        }
86
}
87

88
// BUG(vil): the govalidation error has no reference to the
89
// original StructField. That makes it impossible to generate
90
// correct pointers.
91
// Since the actual data structure and the incoming JSON are very
92
// different, fork and add struct field tags. Add custom tag
93
// and use a custom tag to produce correct source pointer/parameter.
94
// https://github.com/pace/bricks/issues/10
95

96
// generateValidationError generates a new jsonapi error based
97
// on the given govalidator error.
98
func generateValidationError(e valid.Error, source string) *Error {
3✔
99
        path := ""
3✔
100
        for _, p := range append(e.Path, e.Name) {
7✔
101
                path += "/" + strings.ToLower(p)
4✔
102
        }
4✔
103

104
        // params are prefixed with param remove this until above
105
        // described bug is fixed with this simple string replace
106
        if source == "parameter" {
5✔
107
                path = strings.Replace(path, "/param", "", 1)
2✔
108
        }
2✔
109

110
        return &Error{
3✔
111
                Title:  fmt.Sprintf("%s is invalid", e.Name),
3✔
112
                Detail: e.Err.Error(),
3✔
113
                Source: &map[string]interface{}{
3✔
114
                        source: path,
3✔
115
                },
3✔
116
        }
3✔
117
}
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

© 2026 Coveralls, Inc