Passed
Pull Request — main (#48)
by Igor
02:21
created

validation_test.Book.Validate   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
dl 0
loc 6
c 0
b 0
f 0
rs 10
nop 1
1
package validation_test
2
3
import (
4
	"encoding/json"
5
	"fmt"
6
	"net/http"
7
	"net/http/httptest"
8
	"strings"
9
10
	languagepkg "github.com/muonsoft/language"
11
	"github.com/muonsoft/validation"
12
	"github.com/muonsoft/validation/it"
13
	"github.com/muonsoft/validation/message/translations/russian"
14
	"golang.org/x/text/language"
15
)
16
17
type Book struct {
18
	Title    string   `json:"title"`
19
	Author   string   `json:"author"`
20
	Keywords []string `json:"keywords"`
21
}
22
23
func (b Book) Validate(validator *validation.Validator) error {
24
	return validator.Validate(
25
		validation.StringProperty("title", &b.Title, it.IsNotBlank()),
26
		validation.StringProperty("author", &b.Author, it.IsNotBlank()),
27
		validation.CountableProperty("keywords", len(b.Keywords), it.HasCountBetween(1, 10)),
28
		validation.EachStringProperty("keywords", b.Keywords, it.IsNotBlank()),
29
	)
30
}
31
32
func HandleBooks(writer http.ResponseWriter, request *http.Request) {
33
	var book Book
34
	err := json.NewDecoder(request.Body).Decode(&book)
35
	if err != nil {
36
		http.Error(writer, "invalid request", http.StatusBadRequest)
37
		return
38
	}
39
40
	// setting up validator
41
	validator, err := validation.NewValidator(validation.Translations(russian.Messages))
42
	if err != nil {
43
		http.Error(writer, err.Error(), http.StatusInternalServerError)
44
		return
45
	}
46
47
	err = validator.WithContext(request.Context()).ValidateValidatable(book)
48
	if err != nil {
49
		violations, ok := validation.UnwrapViolationList(err)
50
		if ok {
51
			response, _ := json.Marshal(violations)
52
			writer.WriteHeader(http.StatusUnprocessableEntity)
53
			writer.Header().Set("Content-Type", "application/json")
54
			writer.Write(response)
55
			return
56
		}
57
58
		http.Error(writer, err.Error(), http.StatusInternalServerError)
59
		return
60
	}
61
62
	// handle valid book
63
64
	writer.WriteHeader(http.StatusCreated)
65
	writer.Write([]byte("ok"))
66
}
67
68
func ExampleValidator_Validate_httpHandler() {
69
	var handler http.Handler
70
	handler = http.HandlerFunc(HandleBooks)
71
	// middleware set up: we need to set supported languages
72
	// detected language will be passed via request context
73
	handler = languagepkg.NewMiddleware(handler, languagepkg.SupportedLanguages(language.English, language.Russian))
74
75
	// creating request with the language-specific header
76
	request := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(`{}`))
77
	request.Header.Set("Accept-Language", "ru")
78
79
	recorder := httptest.NewRecorder()
80
	handler.ServeHTTP(recorder, request)
81
82
	// recorded response should contain array of violations
83
	fmt.Println(recorder.Body.String())
84
	// Output:
85
	// [{"code":"notBlank","message":"Значение не должно быть пустым.","propertyPath":"title"},{"code":"notBlank","message":"Значение не должно быть пустым.","propertyPath":"author"},{"code":"countTooFew","message":"Эта коллекция должна содержать 1 элемент или больше.","propertyPath":"keywords"}]
86
}
87