wishli-api/coverage/coverage_unit.html
2025-03-23 20:05:51 +03:00

430 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>unit: Go Coverage Report</title>
<style>
body {
background: black;
color: rgb(80, 80, 80);
}
body, pre, #legend span {
font-family: Menlo, monospace;
font-weight: bold;
}
#topbar {
background: black;
position: fixed;
top: 0; left: 0; right: 0;
height: 42px;
border-bottom: 1px solid rgb(80, 80, 80);
}
#content {
margin-top: 50px;
}
#nav, #legend {
float: left;
margin-left: 10px;
}
#legend {
margin-top: 12px;
}
#nav {
margin-top: 10px;
}
#legend span {
margin: 0 5px;
}
.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }
</style>
</head>
<body>
<div id="topbar">
<div id="nav">
<select id="files">
<option value="file0">wish-list-api/tests/unit/mock_auth.go (22.5%)</option>
<option value="file1">wish-list-api/tests/unit/mock_repository.go (56.5%)</option>
</select>
</div>
<div id="legend">
<span>not tracked</span>
<span class="cov0">not covered</span>
<span class="cov8">covered</span>
</div>
</div>
<div id="content">
<pre class="file" id="file0" style="display: none">package unit
import (
"errors"
"time"
"wish-list-api/pkg/auth"
"wish-list-api/pkg/entities"
"github.com/golang-jwt/jwt/v5"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// MockAuthService реализует интерфейс auth.Service
type MockAuthService struct {
users map[primitive.ObjectID]*entities.User
// Токен -&gt; ID пользователя
tokens map[string]primitive.ObjectID
}
// NewMockAuthService создает новый mock сервис аутентификации
func NewMockAuthService() auth.Service <span class="cov8" title="1">{
return &amp;MockAuthService{
users: make(map[primitive.ObjectID]*entities.User),
tokens: make(map[string]primitive.ObjectID),
}
}</span>
// AddMockUser добавляет мок-пользователя в сервис
func (m *MockAuthService) AddMockUser(user *entities.User, token string) <span class="cov8" title="1">{
m.users[user.ID] = user
m.tokens[token] = user.ID
}</span>
// Login реализация для теста
func (m *MockAuthService) Login(credentials *entities.LoginRequest) (*entities.TokenPair, error) <span class="cov0" title="0">{
for _, user := range m.users </span><span class="cov0" title="0">{
if user.Email == credentials.Email &amp;&amp; m.ComparePasswords(user.Password, credentials.Password) </span><span class="cov0" title="0">{
token := "mock-token-for-" + user.ID.Hex()
m.tokens[token] = user.ID
return &amp;entities.TokenPair{
AccessToken: token,
RefreshToken: "refresh-" + token,
}, nil
}</span>
}
<span class="cov0" title="0">return nil, errors.New("invalid credentials")</span>
}
// Register реализация для теста
func (m *MockAuthService) Register(userData *entities.RegisterRequest) (*entities.User, error) <span class="cov0" title="0">{
// Проверяем, что email не занят
for _, existingUser := range m.users </span><span class="cov0" title="0">{
if existingUser.Email == userData.Email </span><span class="cov0" title="0">{
return nil, errors.New("email already exists")
}</span>
}
// Создаем нового пользователя
<span class="cov0" title="0">hashedPassword, _ := m.HashPassword(userData.Password)
user := &amp;entities.User{
ID: primitive.NewObjectID(),
Email: userData.Email,
Password: hashedPassword,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// Сохраняем пользователя
m.users[user.ID] = user
return user, nil</span>
}
// RefreshToken реализация для теста
func (m *MockAuthService) RefreshToken(refreshToken string) (*entities.TokenPair, error) <span class="cov0" title="0">{
// Предполагаем, что refresh token имеет вид "refresh-&lt;access-token&gt;"
if len(refreshToken) &lt; 8 </span><span class="cov0" title="0">{
return nil, errors.New("invalid refresh token")
}</span>
<span class="cov0" title="0">accessToken := refreshToken[8:] // Получаем access token из refresh token
userID, ok := m.tokens[accessToken]
if !ok </span><span class="cov0" title="0">{
return nil, errors.New("invalid refresh token")
}</span>
<span class="cov0" title="0">newToken := "mock-token-for-" + userID.Hex() + "-refreshed"
m.tokens[newToken] = userID
return &amp;entities.TokenPair{
AccessToken: newToken,
RefreshToken: "refresh-" + newToken,
}, nil</span>
}
// ValidateToken реализация для теста
func (m *MockAuthService) ValidateToken(tokenString string) (*jwt.Token, error) <span class="cov0" title="0">{
// Проверяем, имеет ли токен префикс "Bearer "
if len(tokenString) &gt; 7 &amp;&amp; tokenString[:7] == "Bearer " </span><span class="cov0" title="0">{
tokenString = tokenString[7:]
}</span>
<span class="cov0" title="0">userID, ok := m.tokens[tokenString]
if !ok </span><span class="cov0" title="0">{
return nil, errors.New("invalid token")
}</span>
// Создаем mock JWT token
<span class="cov0" title="0">token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": userID.Hex(),
"exp": time.Now().Add(time.Hour).Unix(),
})
return token, nil</span>
}
// GetUserIDFromToken реализация для теста
func (m *MockAuthService) GetUserIDFromToken(tokenString string) (string, error) <span class="cov8" title="1">{
// Проверяем, имеет ли токен префикс "Bearer "
if len(tokenString) &gt; 7 &amp;&amp; tokenString[:7] == "Bearer " </span><span class="cov8" title="1">{
tokenString = tokenString[7:]
}</span>
<span class="cov8" title="1">userID, ok := m.tokens[tokenString]
if !ok </span><span class="cov8" title="1">{
return "", errors.New("invalid token")
}</span>
<span class="cov8" title="1">return userID.Hex(), nil</span>
}
// HashPassword реализация для теста
func (m *MockAuthService) HashPassword(password string) (string, error) <span class="cov0" title="0">{
// Просто возвращаем пароль с префиксом для имитации хеширования
return "hashed_" + password, nil
}</span>
// ComparePasswords реализация для теста
func (m *MockAuthService) ComparePasswords(hashedPassword string, plainPassword string) bool <span class="cov0" title="0">{
// Проверяем, соответствует ли "хешированный" пароль нашей простой схеме
return hashedPassword == "hashed_"+plainPassword
}</span>
</pre>
<pre class="file" id="file1" style="display: none">package unit
import (
"errors"
"time"
"wish-list-api/api/presenter"
"wish-list-api/pkg/entities"
wishlist "wish-list-api/pkg/wish-list"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// MockWishListRepository реализует интерфейс Repository для тестирования
type MockWishListRepository struct {
wishLists map[string]*entities.WishList
wishListItems map[string]*entities.WishListItem
}
// NewMockWishListRepository создает новый экземпляр мок-репозитория
func NewMockWishListRepository() wishlist.Repository <span class="cov8" title="1">{
return &amp;MockWishListRepository{
wishLists: make(map[string]*entities.WishList),
wishListItems: make(map[string]*entities.WishListItem),
}
}</span>
// CreateWishList реализует создание списка желаний
func (r *MockWishListRepository) CreateWishList(wishList *entities.WishList) (*entities.WishList, error) <span class="cov8" title="1">{
if wishList.ID == "" </span><span class="cov8" title="1">{
wishList.ID = "mock-id-" + time.Now().String()
}</span>
<span class="cov8" title="1">wishList.CreatedAt = time.Now()
wishList.UpdatedAt = time.Now()
r.wishLists[wishList.ID] = wishList
return wishList, nil</span>
}
// ReadWishList реализует чтение списка желаний по ID
func (r *MockWishListRepository) ReadWishList(ID string) (*entities.WishList, error) <span class="cov8" title="1">{
if wishList, ok := r.wishLists[ID]; ok </span><span class="cov8" title="1">{
return wishList, nil
}</span>
<span class="cov8" title="1">return nil, errors.New("wishlist not found")</span>
}
// ReadAllWishLists реализует чтение всех списков желаний пользователя
func (r *MockWishListRepository) ReadAllWishLists(userID string) (*[]presenter.WishList, error) <span class="cov0" title="0">{
var result []presenter.WishList
for _, wl := range r.wishLists </span><span class="cov0" title="0">{
if wl.UserID == userID </span><span class="cov0" title="0">{
objID, _ := primitive.ObjectIDFromHex(wl.ID)
result = append(result, presenter.WishList{
ID: objID,
Title: wl.Title,
UserID: wl.UserID,
Description: wl.Description,
IsPublic: wl.IsPublic,
PhotoURL: wl.PhotoURL,
CreatedAt: wl.CreatedAt,
UpdatedAt: wl.UpdatedAt,
})
}</span>
}
<span class="cov0" title="0">return &amp;result, nil</span>
}
// ReadPublicWishLists реализует чтение всех публичных списков желаний
func (r *MockWishListRepository) ReadPublicWishLists() (*[]presenter.WishList, error) <span class="cov0" title="0">{
var result []presenter.WishList
for _, wl := range r.wishLists </span><span class="cov0" title="0">{
if wl.IsPublic </span><span class="cov0" title="0">{
objID, _ := primitive.ObjectIDFromHex(wl.ID)
result = append(result, presenter.WishList{
ID: objID,
Title: wl.Title,
UserID: wl.UserID,
Description: wl.Description,
IsPublic: wl.IsPublic,
PhotoURL: wl.PhotoURL,
CreatedAt: wl.CreatedAt,
UpdatedAt: wl.UpdatedAt,
})
}</span>
}
<span class="cov0" title="0">return &amp;result, nil</span>
}
// UpdateWishList реализует обновление списка желаний
func (r *MockWishListRepository) UpdateWishList(wishList *entities.WishList) (*entities.WishList, error) <span class="cov8" title="1">{
if _, ok := r.wishLists[wishList.ID]; !ok </span><span class="cov8" title="1">{
return nil, errors.New("wishlist not found")
}</span>
<span class="cov8" title="1">wishList.UpdatedAt = time.Now()
r.wishLists[wishList.ID] = wishList
return wishList, nil</span>
}
// DeleteWishList реализует удаление списка желаний
func (r *MockWishListRepository) DeleteWishList(ID string) error <span class="cov8" title="1">{
if _, ok := r.wishLists[ID]; !ok </span><span class="cov8" title="1">{
return errors.New("wishlist not found")
}</span>
<span class="cov8" title="1">delete(r.wishLists, ID)
// Удаляем все элементы, связанные с этим списком
for id, item := range r.wishListItems </span><span class="cov0" title="0">{
if item.WishListID == ID </span><span class="cov0" title="0">{
delete(r.wishListItems, id)
}</span>
}
<span class="cov8" title="1">return nil</span>
}
// CreateWishListItem реализует создание элемента списка желаний
func (r *MockWishListRepository) CreateWishListItem(item *entities.WishListItem) (*entities.WishListItem, error) <span class="cov8" title="1">{
if _, ok := r.wishLists[item.WishListID]; !ok </span><span class="cov8" title="1">{
return nil, errors.New("wishlist not found")
}</span>
<span class="cov8" title="1">if item.ID == "" </span><span class="cov8" title="1">{
item.ID = "mock-item-id-" + time.Now().String()
}</span>
<span class="cov8" title="1">item.CreatedAt = time.Now()
item.UpdatedAt = time.Now()
r.wishListItems[item.ID] = item
return item, nil</span>
}
// ReadWishListItem реализует чтение элемента списка желаний по ID
func (r *MockWishListRepository) ReadWishListItem(ID string) (*entities.WishListItem, error) <span class="cov0" title="0">{
if item, ok := r.wishListItems[ID]; ok </span><span class="cov0" title="0">{
return item, nil
}</span>
<span class="cov0" title="0">return nil, errors.New("wishlist item not found")</span>
}
// ReadAllWishListItems реализует чтение всех элементов списка желаний
func (r *MockWishListRepository) ReadAllWishListItems(wishListID string) (*[]presenter.WishListItem, error) <span class="cov8" title="1">{
if _, ok := r.wishLists[wishListID]; !ok </span><span class="cov0" title="0">{
return nil, errors.New("wishlist not found")
}</span>
<span class="cov8" title="1">var result []presenter.WishListItem
for _, item := range r.wishListItems </span><span class="cov8" title="1">{
if item.WishListID == wishListID </span><span class="cov8" title="1">{
objID, _ := primitive.ObjectIDFromHex(item.ID)
result = append(result, presenter.WishListItem{
ID: objID,
Title: item.Title,
URL: item.URL,
Cost: item.Cost,
WishListID: item.WishListID,
Description: item.Description,
PhotoURL: item.PhotoURL,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}</span>
}
<span class="cov8" title="1">return &amp;result, nil</span>
}
// UpdateWishListItem реализует обновление элемента списка желаний
func (r *MockWishListRepository) UpdateWishListItem(item *entities.WishListItem) (*entities.WishListItem, error) <span class="cov0" title="0">{
if _, ok := r.wishListItems[item.ID]; !ok </span><span class="cov0" title="0">{
return nil, errors.New("wishlist item not found")
}</span>
<span class="cov0" title="0">item.UpdatedAt = time.Now()
r.wishListItems[item.ID] = item
return item, nil</span>
}
// DeleteWishListItem реализует удаление элемента списка желаний
func (r *MockWishListRepository) DeleteWishListItem(ID string) error <span class="cov0" title="0">{
if _, ok := r.wishListItems[ID]; !ok </span><span class="cov0" title="0">{
return errors.New("wishlist item not found")
}</span>
<span class="cov0" title="0">delete(r.wishListItems, ID)
return nil</span>
}
</pre>
</div>
</body>
<script>
(function() {
var files = document.getElementById('files');
var visible;
files.addEventListener('change', onChange, false);
function select(part) {
if (visible)
visible.style.display = 'none';
visible = document.getElementById(part);
if (!visible)
return;
files.value = part;
visible.style.display = 'block';
location.hash = part;
}
function onChange() {
select(files.value);
window.scrollTo(0, 0);
}
if (location.hash != "") {
select(location.hash.substr(1));
}
if (!visible) {
select("file0");
}
})();
</script>
</html>