-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding tests for validation and login #15
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package http | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"github.com/stretchr/testify/require" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
) | ||
|
||
func TestLoginUserHandler(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("Errors", testLoginErrors) | ||
t.Run("Success", testLoginSuccess) | ||
} | ||
|
||
func testLoginErrors(t *testing.T) { | ||
t.Parallel() | ||
|
||
methodsToTest := []string{http.MethodDelete, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodOptions} | ||
|
||
for _, method := range methodsToTest { | ||
t.Run(fmt.Sprintf("Method %s not allowed", method), func(t *testing.T) { | ||
t.Parallel() | ||
req, err := http.NewRequest(method, "/", nil) | ||
require.NoError(t, err) | ||
|
||
resp := assertResponseStatus(t, req, http.StatusMovedPermanently) | ||
require.Equal(t, "", resp) | ||
}) | ||
} | ||
|
||
t.Run("Handle error reading request body", func(t *testing.T) { | ||
jessicamosouza marked this conversation as resolved.
Show resolved
Hide resolved
|
||
t.Parallel() | ||
req, err := http.NewRequest(http.MethodGet, "/", &ErrorReader{}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Como |
||
require.NoError(t, err) | ||
|
||
resp := assertResponseStatus(t, req, http.StatusInternalServerError) | ||
require.Equal(t, "Error unmarshalling request body\nemail validation failed: invalid email\n", resp) | ||
}) | ||
|
||
t.Run("Empty body", func(t *testing.T) { | ||
t.Parallel() | ||
req, err := http.NewRequest(http.MethodGet, "/", nil) | ||
require.NoError(t, err) | ||
|
||
resp := assertResponseStatus(t, req, http.StatusBadRequest) | ||
require.Equal(t, "Empty body\n", resp) | ||
}) | ||
|
||
t.Run("Error finding user", func(t *testing.T) { | ||
t.Parallel() | ||
req, err := http.NewRequest(http.MethodGet, "/", bytes.NewBufferString( | ||
`{"email":"maria@email.com", "password":"Password123!"}`)) | ||
require.NoError(t, err) | ||
|
||
resp := assertResponseStatus(t, req, http.StatusBadRequest) | ||
require.Equal(t, "[usermodels] user not found\n", resp) | ||
}) | ||
} | ||
|
||
func testLoginSuccess(t *testing.T) { | ||
t.Parallel() | ||
|
||
t.Run("Successful body read", func(t *testing.T) { | ||
t.Parallel() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C entendeu direitinho pra que o t.Parallel serve e como ele funciona? |
||
req, err := http.NewRequest(http.MethodGet, "/", | ||
bytes.NewBufferString(`{"email":"john@doe.com","password":"Password123!"}`)) | ||
require.NoError(t, err) | ||
|
||
resp := assertResponseStatus(t, req, http.StatusOK) | ||
require.Equal(t, "LoginUserPayload logged successfully!", resp) | ||
}) | ||
} | ||
|
||
func assertResponseStatus(t *testing.T, req *http.Request, status int) string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quando vc define alguma coisa em um arquivo de teste, essa parada fica disponível pra todos os testes que usem o mesmo pacote. Como essa função faz assertion do status HTTP da resposta de LoginUserHandler especificamente, vale um ou outro dos abaixo: Um: Deixar claro no nome que a assertion é para Outro: Aceitar como parâmetro a função. Ficaria algo assim: func assertResponseStatus(t *testing.T, fn http.HandleFunc, req *http.Request, status int) string {
t.Helper()
rec := httptest.NewRecorder()
fn(rec, req)
require.Equal(t, status, rec.Code)
return rec.Body.String()
}
// Usado assim, por exemplo:
assertResponseStatus(t, LoginUserHandler, req, http.StatusOK) Se você optar por outro, vale criar um arquivo Outra dica legal é usar |
||
rec := httptest.NewRecorder() | ||
LoginUserHandler(rec, req) | ||
require.Equal(t, status, rec.Code) | ||
return rec.Body.String() | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -4,6 +4,7 @@ import ( | |||||||||
"errors" | ||||||||||
"fmt" | ||||||||||
"net/mail" | ||||||||||
"regexp" | ||||||||||
"unicode" | ||||||||||
) | ||||||||||
|
||||||||||
|
@@ -34,10 +35,17 @@ func Validate(user User, isSignUp bool) error { | |||||||||
return nil | ||||||||||
} | ||||||||||
|
||||||||||
var re = regexp.MustCompile(`[^a-zA-ZäöüÄÖÜáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛãñõÃÑÕçÇ ^\p{L}'-]`) | ||||||||||
|
||||||||||
func CheckName(name string) error { | ||||||||||
if len(name) < 2 { | ||||||||||
if name == "" { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tende a ser uma boa ideia sanitizar inputs string por espaços antes e depois do texto. É relativamente fácil em interfaces esquecer um espaço antes ou depois do valor de um campo e não perceber.
Suggested change
|
||||||||||
return errors.New("name cannot be empty") | ||||||||||
} else if len(name) < 2 { | ||||||||||
return errors.New("name must contain at least 2 characters") | ||||||||||
} else if re.MatchString(name) { | ||||||||||
return errors.New("name cannot contain special characters") | ||||||||||
} | ||||||||||
|
||||||||||
return nil | ||||||||||
} | ||||||||||
|
||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acho que assim ficaria mais fácil de entender. Pense no código como uma leitura, quanto mais claros os nomes das variáveis forem, menos contexto precisa ser carregado na cabeça pra entender o código.