Skip to content

Commit

Permalink
Add URL escape and unespace normalizers and tests to v2. (#143)
Browse files Browse the repository at this point in the history
# Describe Request

Add URL escape and unespace normalizers and tests to v2.

# Change Type

New code.
  • Loading branch information
cinar authored Dec 27, 2024
1 parent 34b6645 commit 6779e95
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 30 deletions.
1 change: 1 addition & 0 deletions v2/maker.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var makers = map[string]MakeCheckFunc{
nameTrimSpace: makeTrimSpace,
nameURL: makeURL,
nameURLEscape: makeURLEscape,
nameURLUnescape: makeURLUnescape,
}

// makeChecks take a checker config and returns the check functions.
Expand Down
27 changes: 10 additions & 17 deletions v2/url_escape.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,21 @@ import (
"reflect"
)

const (
// nameURLEscape is the name of the URL escape normalizer.
nameURLEscape = "url-escape"
)
// nameURLEscape is the name of the URL escape normalizer.
const nameURLEscape = "url-escape"

// normalizeURLEscape applies URL escaping to special characters.
// Uses net.url.QueryEscape for the actual escape operation.
func normalizeURLEscape(value string) (string, error) {
// URLEscape applies URL escaping to special characters.
func URLEscape(value string) (string, error) {
return url.QueryEscape(value), nil
}

// checkURLEscape checks if the value is a valid URL escape string.
func checkURLEscape(value reflect.Value) (reflect.Value, error) {
escaped, err := normalizeURLEscape(value.Interface().(string))
if err != nil {
return value, err
}
value.SetString(escaped)
return value, nil
// reflectURLEscape applies URL escaping to special characters.
func reflectURLEscape(value reflect.Value) (reflect.Value, error) {
newValue, err := URLEscape(value.Interface().(string))
return reflect.ValueOf(newValue), err
}

// makeURLEscape makes a normalizer function for the URL escape normalizer.
// makeURLEscape returns the URL escape normalizer function.
func makeURLEscape(_ string) CheckFunc[reflect.Value] {
return checkURLEscape
return reflectURLEscape
}
30 changes: 17 additions & 13 deletions v2/url_escape_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ import (
v2 "github.com/cinar/checker/v2"
)

func TestNormalizeURLEscapeNonString(t *testing.T) {
defer FailIfNoPanic(t, "expected panic")
func TestURLEscape(t *testing.T) {
input := "param1/param2 = 1 + 2 & 3 + 4"
expected := "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4"

type Request struct {
Query int `checkers:"url-escape"`
actual, err := v2.URLEscape(input)
if err != nil {
t.Fatal(err)
}

request := &Request{}

v2.CheckStruct(request)
if actual != expected {
t.Fatalf("actual %s expected %s", actual, expected)
}
}

func TestNormalizeURLEscape(t *testing.T) {
func TestReflectURLEscape(t *testing.T) {
type Request struct {
Query string `checkers:"url-escape"`
}
Expand All @@ -32,12 +34,14 @@ func TestNormalizeURLEscape(t *testing.T) {
Query: "param1/param2 = 1 + 2 & 3 + 4",
}

_, valid := v2.CheckStruct(request)
if !valid {
t.Fail()
expected := "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4"

errs, ok := v2.CheckStruct(request)
if !ok {
t.Fatalf("got unexpected errors %v", errs)
}

if request.Query != "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4" {
t.Fail()
if request.Query != expected {
t.Fatalf("actual %s expected %s", request.Query, expected)
}
}
31 changes: 31 additions & 0 deletions v2/url_unescape.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2023-2024 Onur Cinar.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// https://github.com/cinar/checker

package v2

import (
"net/url"
"reflect"
)

// nameURLUnescape is the name of the URL unescape normalizer.
const nameURLUnescape = "url-unescape"

// URLUnescape applies URL unescaping to special characters.
func URLUnescape(value string) (string, error) {
unescaped, err := url.QueryUnescape(value)
return unescaped, err
}

// reflectURLUnescape applies URL unescaping to special characters.
func reflectURLUnescape(value reflect.Value) (reflect.Value, error) {
newValue, err := URLUnescape(value.Interface().(string))
return reflect.ValueOf(newValue), err
}

// makeURLUnescape returns the URL unescape normalizer function.
func makeURLUnescape(_ string) CheckFunc[reflect.Value] {
return reflectURLUnescape
}
47 changes: 47 additions & 0 deletions v2/url_unescape_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2023-2024 Onur Cinar.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// https://github.com/cinar/checker

package v2_test

import (
"testing"

v2 "github.com/cinar/checker/v2"
)

func TestURLUnescape(t *testing.T) {
input := "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4"
expected := "param1/param2 = 1 + 2 & 3 + 4"

actual, err := v2.URLUnescape(input)
if err != nil {
t.Fatal(err)
}

if actual != expected {
t.Fatalf("actual %s expected %s", actual, expected)
}
}

func TestReflectURLUnescape(t *testing.T) {
type Request struct {
Query string `checkers:"url-unescape"`
}

request := &Request{
Query: "param1%2Fparam2+%3D+1+%2B+2+%26+3+%2B+4",
}

expected := "param1/param2 = 1 + 2 & 3 + 4"

errs, ok := v2.CheckStruct(request)
if !ok {
t.Fatalf("got unexpected errors %v", errs)
}

if request.Query != expected {
t.Fatalf("actual %s expected %s", request.Query, expected)
}
}

0 comments on commit 6779e95

Please sign in to comment.