validation_test.HandleBooks   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

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