added test cases for POST /account/create and GET /account/get

This commit is contained in:
Pasha 2025-05-23 18:03:53 +03:00
parent 63c7cbe0b7
commit 454f5b4d5f

240
tests/main_test.go Normal file

@ -0,0 +1,240 @@
package tests
import (
"bytes"
"encoding/json"
"gitea.pena/SQuiz/common/model"
"github.com/stretchr/testify/assert"
"io"
"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")
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"))
body, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
var acc model.Account
err = json.Unmarshal(body, &acc)
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
}