2025-05-23 15:03:53 +00:00
|
|
|
package tests
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"gitea.pena/SQuiz/common/model"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var baseURL = os.Getenv("API_BASE_URL")
|
|
|
|
var validToken = os.Getenv("VALID_JWT_TOKEN")
|
|
|
|
var expiredToken = os.Getenv("EXPIRED_JWT_TOKEN")
|
2025-05-26 12:09:48 +00:00
|
|
|
var validTokenForDelete = os.Getenv("VALID_JWT_TOKEN_FOR_DELETE")
|
2025-05-26 13:46:21 +00:00
|
|
|
var validAdminToken = os.Getenv("VALID_ADMIN_JWT_TOKEN")
|
2025-05-26 14:23:55 +00:00
|
|
|
var existingUserIDToken = os.Getenv("EXISTING_USER_ID_JWT_TOKEN")
|
2025-05-23 15:03:53 +00:00
|
|
|
|
2025-05-28 12:30:44 +00:00
|
|
|
var userIDForDelete = os.Getenv("USER_ID_FOR_DELETE")
|
2025-05-23 15:03:53 +00:00
|
|
|
var existingUserID = os.Getenv("EXISTING_USER_ID")
|
|
|
|
var testUserID = os.Getenv("TEST_USER_ID")
|
|
|
|
var sqlInjectionInput = "'; DROP TABLE accounts; --"
|
|
|
|
var xssInput = "<script>alert('xss')</script>"
|
|
|
|
|
|
|
|
func TestGetAccount_Success(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
|
|
|
|
client := &http.Client{Timeout: 5 * time.Second}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var acc model.Account
|
2025-05-26 12:09:48 +00:00
|
|
|
err = json.NewDecoder(resp.Body).Decode(&acc)
|
2025-05-23 15:03:53 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotEmpty(t, acc.ID)
|
|
|
|
assert.NotEmpty(t, acc.UserID)
|
|
|
|
assert.IsType(t, map[string]interface{}{}, acc.Privileges)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccount_Auth(t *testing.T) {
|
|
|
|
t.Run("AccountNoToken", func(t *testing.T) {
|
|
|
|
resp, err := http.Get(baseURL + "/account/get")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("AccountInvalidToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer invalid_token")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("AccountExpiredToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+expiredToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccount_NotFound(t *testing.T) {
|
|
|
|
t.Run("DeletedAccount", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+os.Getenv("DELETED_ACCOUNT_TOKEN"))
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccount_Privileges(t *testing.T) {
|
|
|
|
t.Run("NoPrivileges", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+os.Getenv("NO_PRIVILEGES_TOKEN"))
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
|
|
|
|
var acc model.Account
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&acc)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Empty(t, acc.Privileges)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("MultiplePrivileges", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+os.Getenv("MULTI_PRIVILEGES_TOKEN"))
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
|
|
|
|
var acc model.Account
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&acc)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Greater(t, len(acc.Privileges), 1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAccount_Performance(t *testing.T) {
|
|
|
|
t.Run("AccountResponseTime", func(t *testing.T) {
|
|
|
|
start := time.Now()
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
duration := time.Since(start)
|
|
|
|
assert.Less(t, duration.Milliseconds(), int64(500))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("AccountLoadTest", func(t *testing.T) {
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/account/get", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err == nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 1.3.6 1.3.7 1.3.8. 1.4 пока не знаю как делать надо подумать
|
|
|
|
|
|
|
|
func TestCreateAccount(t *testing.T) {
|
|
|
|
t.Run("Success", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{
|
|
|
|
"user_id": testUserID,
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("MissingToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("POST", baseURL+"/account/create", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, expiredToken, map[string]interface{}{
|
|
|
|
"user_id": "some-id",
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, expiredToken, map[string]interface{}{
|
|
|
|
"user_id": "some-id",
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("Conflict_ExistingUserID", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{
|
|
|
|
"user_id": existingUserID,
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusConflict, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("EmptyJSON", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidFormat", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{
|
|
|
|
"user_id": 123,
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("SQLInjection", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{
|
|
|
|
"user_id": sqlInjectionInput,
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.NotEqual(t, http.StatusInternalServerError, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("XSSInjection", func(t *testing.T) {
|
|
|
|
resp := createAccountRequest(t, validToken, map[string]interface{}{
|
|
|
|
"user_id": xssInput,
|
|
|
|
})
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.NotEqual(t, http.StatusInternalServerError, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
// todo 2.3.6 2.3.7 2.3.8 2.4
|
|
|
|
}
|
|
|
|
|
|
|
|
func createAccountRequest(t *testing.T, token string, payload map[string]interface{}) *http.Response {
|
|
|
|
body, err := json.Marshal(payload)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("POST", baseURL+"/account/create", bytes.NewBuffer(body))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
return resp
|
|
|
|
}
|
2025-05-26 12:09:48 +00:00
|
|
|
|
|
|
|
func TestDeleteAccount_Success(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validTokenForDelete)
|
|
|
|
|
|
|
|
client := &http.Client{Timeout: 5 * time.Second}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var result map[string]string
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotEmpty(t, result["accountId"])
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccount_Auth(t *testing.T) {
|
|
|
|
t.Run("NoToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer invalid_token")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+expiredToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccount_AlreadyDeleted(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validTokenForDelete)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccount_NonExistent(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validTokenForDelete)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 3.3.4 3.3.5
|
|
|
|
|
|
|
|
func TestDeleteAccount_Performance(t *testing.T) {
|
|
|
|
t.Run("ResponseTime", func(t *testing.T) {
|
|
|
|
req, _ := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
|
|
|
|
start := time.Now()
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
duration := time.Since(start)
|
|
|
|
assert.Less(t, duration.Milliseconds(), int64(500))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccount_Load(t *testing.T) {
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 50; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/delete", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
if resp != nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 3.3.7 3.3.8 3.4
|
2025-05-26 13:46:21 +00:00
|
|
|
|
|
|
|
func TestGetAccounts_Success(t *testing.T) {
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"limit": 10,
|
|
|
|
"page": 1,
|
|
|
|
}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
client := &http.Client{}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var result struct {
|
|
|
|
Count uint64 `json:"count"`
|
|
|
|
Items []model.Account `json:"items"`
|
|
|
|
}
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
assert.LessOrEqual(t, len(result.Items), 2)
|
|
|
|
for _, acc := range result.Items {
|
|
|
|
assert.NotEmpty(t, acc.ID)
|
|
|
|
assert.NotEmpty(t, acc.UserID)
|
|
|
|
assert.NotEmpty(t, acc.CreatedAt)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccounts_Auth(t *testing.T) {
|
|
|
|
t.Run("NoToken", func(t *testing.T) {
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"limit": 10,
|
|
|
|
"page": 1,
|
|
|
|
}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"limit": 10,
|
|
|
|
"page": 1,
|
|
|
|
}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer invalid_token")
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
|
|
|
body := map[string]interface{}{
|
|
|
|
"limit": 10,
|
|
|
|
"page": 1,
|
|
|
|
}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+expiredToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAccounts_Pagination(t *testing.T) {
|
|
|
|
t.Run("ValidPagination", func(t *testing.T) {
|
|
|
|
body := map[string]interface{}{"limit": 5, "page": 1}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
})
|
|
|
|
// todo
|
|
|
|
//t.Run("ZeroPagination", func(t *testing.T) {
|
|
|
|
// body := map[string]interface{}{"limit": 0, "page": 0}
|
|
|
|
// b, err := json.Marshal(body)
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
// req.Header.Set("Content-Type", "application/json")
|
|
|
|
//
|
|
|
|
// resp, err := http.DefaultClient.Do(req)
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// defer resp.Body.Close()
|
|
|
|
// assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
//})
|
|
|
|
|
|
|
|
// todo
|
|
|
|
//t.Run("TooHighLimit", func(t *testing.T) {
|
|
|
|
// body := map[string]interface{}{"limit": 1000}
|
|
|
|
// b, err := json.Marshal(body)
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
// req.Header.Set("Content-Type", "application/json")
|
|
|
|
//
|
|
|
|
// resp, err := http.DefaultClient.Do(req)
|
|
|
|
// assert.NoError(t, err)
|
|
|
|
// defer resp.Body.Close()
|
|
|
|
// assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
//})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 4.3.4 4.3.5
|
|
|
|
|
|
|
|
func TestGetAccounts_Performance(t *testing.T) {
|
|
|
|
t.Run("ResponseTimeUnder500ms", func(t *testing.T) {
|
|
|
|
body := map[string]interface{}{"limit": 10, "page": 1}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
start := time.Now()
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
duration := time.Since(start)
|
|
|
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Less(t, duration.Milliseconds(), int64(500))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("LoadTest100Requests", func(t *testing.T) {
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
body := map[string]interface{}{"limit": 10, "page": 1}
|
|
|
|
b, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/accounts", bytes.NewReader(b))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err == nil {
|
|
|
|
resp.Body.Close()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 4.3.7 4.3.8 4.4
|
2025-05-26 14:23:55 +00:00
|
|
|
|
|
|
|
func TestGetPrivilege_Success(t *testing.T) {
|
|
|
|
body := map[string]string{"userId": existingUserID}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+existingUserIDToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var privileges []model.ShortPrivilege
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&privileges)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
for _, p := range privileges {
|
|
|
|
assert.NotEmpty(t, p.ID)
|
|
|
|
assert.NotEmpty(t, p.PrivilegeID)
|
|
|
|
assert.NotEmpty(t, p.PrivilegeName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetPrivilege_Auth(t *testing.T) {
|
|
|
|
t.Run("NoToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer invalid_token")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+expiredToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetPrivilege_InputValidation(t *testing.T) {
|
|
|
|
t.Run("MissingUserID", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/", nil)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidUserID", func(t *testing.T) {
|
|
|
|
body := map[string]int{"userId": 111}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/!!!", bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("NonExistentUserID", func(t *testing.T) {
|
|
|
|
nonExistentID := "non_existent_user_123"
|
|
|
|
body := map[string]string{"userId": nonExistentID}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+nonExistentID, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
|
|
|
|
var privileges []model.ShortPrivilege
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&privileges)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Empty(t, privileges)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 5.3.4
|
|
|
|
|
|
|
|
func TestGetPrivilege_Security(t *testing.T) {
|
|
|
|
t.Run("SQLInjection", func(t *testing.T) {
|
|
|
|
injection := "1' OR '1'='1"
|
|
|
|
body := map[string]string{"userId": injection}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+injection, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("XSS", func(t *testing.T) {
|
|
|
|
body := map[string]string{"userId": xssInput}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+xssInput, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetPrivilege_Performance(t *testing.T) {
|
|
|
|
t.Run("ResponseTime", func(t *testing.T) {
|
|
|
|
body := map[string]string{"userId": existingUserID}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
start := time.Now()
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+existingUserIDToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer resp.Body.Close()
|
|
|
|
assert.Less(t, time.Since(start).Milliseconds(), int64(300))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("LoadTest", func(t *testing.T) {
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
body := map[string]string{"userId": existingUserID}
|
|
|
|
data, err := json.Marshal(body)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req, err := http.NewRequest("GET", baseURL+"/privilege/"+existingUserID, bytes.NewBuffer(data))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+existingUserIDToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
if resp != nil {
|
|
|
|
defer resp.Body.Close()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 5.3.7 5.3.8 5.4
|
2025-05-28 11:59:36 +00:00
|
|
|
|
|
|
|
func deleteAccountByUserIDRequest(token string, body interface{}) (*http.Response, error) {
|
|
|
|
payload, err := json.Marshal(body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/"+body.(map[string]string)["userId"], bytes.NewReader(payload))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
return http.DefaultClient.Do(req)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccountByUserID_Success(t *testing.T) {
|
2025-05-28 12:30:44 +00:00
|
|
|
resp, err := deleteAccountByUserIDRequest(validAdminToken, map[string]string{"userId": userIDForDelete})
|
2025-05-28 11:59:36 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var result map[string]string
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, testUserID, result["userId"])
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccountByUserID_Auth(t *testing.T) {
|
|
|
|
t.Run("NoToken", func(t *testing.T) {
|
2025-05-28 12:30:44 +00:00
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/"+userIDForDelete, nil)
|
2025-05-28 11:59:36 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
2025-05-28 12:30:44 +00:00
|
|
|
resp, err := deleteAccountByUserIDRequest("invalid_token", map[string]string{"userId": userIDForDelete})
|
2025-05-28 11:59:36 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
2025-05-28 12:30:44 +00:00
|
|
|
resp, err := deleteAccountByUserIDRequest(expiredToken, map[string]string{"userId": userIDForDelete})
|
2025-05-28 11:59:36 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDeleteAccountByUserID_Validation(t *testing.T) {
|
|
|
|
t.Run("EmptyBody", func(t *testing.T) {
|
|
|
|
req, err := http.NewRequest("DELETE", baseURL+"/account/", bytes.NewReader([]byte(`{}`)))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidUserID", func(t *testing.T) {
|
|
|
|
resp, err := deleteAccountByUserIDRequest(validAdminToken, map[string]string{"userId": "invalid_id"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 6.3.4 6.3.5
|
|
|
|
|
|
|
|
func TestDeleteAccountByUserID_SQLInjection_XSS(t *testing.T) {
|
|
|
|
t.Run("SQLInjection", func(t *testing.T) {
|
|
|
|
resp, err := deleteAccountByUserIDRequest(validAdminToken, map[string]string{"userId": sqlInjectionInput})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("XSS", func(t *testing.T) {
|
|
|
|
resp, err := deleteAccountByUserIDRequest(validAdminToken, map[string]string{"userId": xssInput})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 6.3.7 6.3.8 6.3.9 6.4
|
2025-05-28 12:30:44 +00:00
|
|
|
|
|
|
|
func manualDoneRequest(token string, body map[string]string) (*http.Response, error) {
|
|
|
|
payload, err := json.Marshal(body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", baseURL+"/account/manualdone", bytes.NewReader(payload))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
return http.DefaultClient.Do(req)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManualDone_Success(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(validAdminToken, map[string]string{"id": testUserID})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
|
|
|
|
|
|
|
var result map[string]interface{}
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, testUserID, result["id"])
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManualDone_Auth(t *testing.T) {
|
|
|
|
t.Run("NoToken", func(t *testing.T) {
|
|
|
|
payload, err := json.Marshal(map[string]string{"id": testUserID})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
req, err := http.NewRequest("POST", baseURL+"/account/manualdone", bytes.NewReader(payload))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidToken", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest("invalid_token", map[string]string{"id": testUserID})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("ExpiredToken", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(expiredToken, map[string]string{"id": testUserID})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManualDone_Validation(t *testing.T) {
|
|
|
|
t.Run("EmptyBody", func(t *testing.T) {
|
|
|
|
payload := []byte(`{}`)
|
|
|
|
|
|
|
|
req, err := http.NewRequest("POST", baseURL+"/account/manualdone", bytes.NewReader(payload))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
req.Header.Set("Authorization", "Bearer "+validAdminToken)
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("InvalidID", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(validAdminToken, map[string]string{"id": "invalid_id"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("NonExistentID", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(validAdminToken, map[string]string{"id": "nonexistent_id"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 7.3.4 7.3.5
|
|
|
|
|
|
|
|
func TestManualDone_Security(t *testing.T) {
|
|
|
|
t.Run("SQLInjection", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(validAdminToken, map[string]string{"id": "1' OR '1'='1"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("XSSAttack", func(t *testing.T) {
|
|
|
|
resp, err := manualDoneRequest(validAdminToken, map[string]string{"id": "<script>alert('xss')</script>"})
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo 7.3.7 7.3.8 7.3.9 7.4
|