-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexample_embedded_violation_test.go
124 lines (107 loc) · 3.04 KB
/
example_embedded_violation_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package validation_test
import (
"context"
"fmt"
"github.com/muonsoft/validation"
"github.com/muonsoft/validation/it"
"github.com/muonsoft/validation/validator"
)
var ErrModificationProhibited = validation.NewError(
"modification is prohibited",
"Modification of resource is prohibited.",
)
type AccessViolation struct {
validation.Violation
UserID int
Permission string
}
func (err *AccessViolation) Error() string {
return err.Violation.Error()
}
type Blog struct {
Name string
Entries BlogEntries
}
func (b Blog) Validate(ctx context.Context, validator *validation.Validator, userID int) error {
return validator.Validate(
ctx,
validation.StringProperty("name", b.Name, it.IsNotBlank(), it.HasMaxLength(50)),
validation.ValidProperty(
"entries",
validation.ValidatableFunc(func(ctx context.Context, validator *validation.Validator) error {
// passing user id further
return b.Entries.Validate(ctx, validator, userID)
}),
),
)
}
type BlogEntry struct {
AuthorID int
Title string
Text string
}
func (e BlogEntry) Validate(ctx context.Context, validator *validation.Validator, userID int) error {
// creating violation with domain payload
if e.AuthorID != userID {
return &AccessViolation{
Violation: validator.CreateViolation(ctx, ErrModificationProhibited, ErrModificationProhibited.Message()),
UserID: userID,
Permission: "edit",
}
}
return validator.Validate(
ctx,
validation.StringProperty("title", e.Title, it.IsNotBlank(), it.HasMaxLength(100)),
validation.StringProperty("text", e.Text, it.IsNotBlank(), it.HasMaxLength(10000)),
)
}
type BlogEntries []BlogEntry
func (entries BlogEntries) Validate(ctx context.Context, validator *validation.Validator, userID int) error {
violations := validation.NewViolationList()
for i, entry := range entries {
err := violations.AppendFromError(entry.Validate(ctx, validator.AtIndex(i), userID))
if err != nil {
return err
}
}
return violations.AsError()
}
func ExampleValidator_ValidateIt_violationWithPayload() {
blog := Blog{
Name: "News blog",
Entries: []BlogEntry{
{
AuthorID: 123,
Title: "Good weather",
Text: "Good weather is coming!",
},
{
AuthorID: 321,
Title: "Secret entry",
Text: "This should not be edited!",
},
},
}
userID := 123 // user id from session
err := validator.ValidateIt(
context.Background(),
validation.ValidatableFunc(func(ctx context.Context, validator *validation.Validator) error {
return blog.Validate(ctx, validator, userID)
}),
)
if violations, ok := validation.UnwrapViolationList(err); ok {
violations.ForEach(func(i int, violation validation.Violation) error {
fmt.Println(violation)
// unwrap concrete violation from chain
if accessError, ok := violation.(*AccessViolation); ok {
fmt.Println("user id:", accessError.UserID)
fmt.Println("permission:", accessError.Permission)
}
return nil
})
}
// Output:
// violation at "entries[1]": "Modification of resource is prohibited."
// user id: 123
// permission: edit
}