All checks were successful
Deploy Smart Search Backend Test / deploy (push) Successful in 2m25s
340 lines
9.3 KiB
Go
340 lines
9.3 KiB
Go
package tests
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.techease.ru/Smart-search/smart-search-back/internal/model"
|
|
"git.techease.ru/Smart-search/smart-search-back/internal/repository"
|
|
"git.techease.ru/Smart-search/smart-search-back/pkg/crypto"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func (s *IntegrationSuite) TestRepository_InviteDecrementCanBeUsedCount() {
|
|
inviteRepo := repository.NewInviteRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
invite := &model.InviteCode{
|
|
UserID: userID,
|
|
Code: time.Now().UnixNano(),
|
|
CanBeUsedCount: 10,
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
}
|
|
err = inviteRepo.Create(ctx, invite)
|
|
s.Require().NoError(err)
|
|
|
|
tx, err := s.pool.Begin(ctx)
|
|
s.Require().NoError(err)
|
|
defer func() { _ = tx.Rollback(ctx) }()
|
|
|
|
err = inviteRepo.DecrementCanBeUsedCountTx(ctx, tx, invite.Code)
|
|
s.NoError(err)
|
|
|
|
err = tx.Commit(ctx)
|
|
s.NoError(err)
|
|
|
|
found, err := inviteRepo.FindByCode(ctx, invite.Code)
|
|
s.NoError(err)
|
|
s.Equal(9, found.CanBeUsedCount)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_InviteDeactivateExpired() {
|
|
inviteRepo := repository.NewInviteRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
expiredCode := time.Now().UnixNano()
|
|
_, err = s.pool.Exec(ctx, `
|
|
INSERT INTO invite_codes (user_id, code, can_be_used_count, expires_at, is_active)
|
|
VALUES ($1, $2, 10, now() - interval '1 hour', true)
|
|
`, userID, expiredCode)
|
|
s.Require().NoError(err)
|
|
|
|
count, err := inviteRepo.DeactivateExpired(ctx)
|
|
s.NoError(err)
|
|
s.GreaterOrEqual(count, 1)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_InviteGetUserInvites() {
|
|
inviteRepo := repository.NewInviteRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
invite := &model.InviteCode{
|
|
UserID: userID,
|
|
Code: time.Now().UnixNano(),
|
|
CanBeUsedCount: 10,
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
}
|
|
err = inviteRepo.Create(ctx, invite)
|
|
s.Require().NoError(err)
|
|
|
|
invites, err := inviteRepo.GetUserInvites(ctx, userID)
|
|
s.NoError(err)
|
|
s.GreaterOrEqual(len(invites), 1)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_SessionRevoke() {
|
|
sessionRepo := repository.NewSessionRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
session := &model.Session{
|
|
UserID: userID,
|
|
AccessToken: "test-access-token-" + uuid.New().String(),
|
|
RefreshToken: "test-refresh-token-" + uuid.New().String(),
|
|
IP: "127.0.0.1",
|
|
UserAgent: "test-agent",
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
}
|
|
err = sessionRepo.Create(ctx, session)
|
|
s.Require().NoError(err)
|
|
|
|
err = sessionRepo.Revoke(ctx, session.RefreshToken)
|
|
s.NoError(err)
|
|
|
|
_, err = sessionRepo.FindByRefreshToken(ctx, session.RefreshToken)
|
|
s.Error(err)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_SessionDeleteExpired() {
|
|
sessionRepo := repository.NewSessionRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
_, err = s.pool.Exec(ctx, `
|
|
INSERT INTO sessions (user_id, access_token, refresh_token, ip, user_agent, expires_at)
|
|
VALUES ($1, $2, $3, '127.0.0.1', 'test', now() - interval '1 hour')
|
|
`, userID, "expired-access-"+uuid.New().String(), "expired-refresh-"+uuid.New().String())
|
|
s.Require().NoError(err)
|
|
|
|
count, err := sessionRepo.DeleteExpired(ctx)
|
|
s.NoError(err)
|
|
s.GreaterOrEqual(count, 1)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_RequestUpdateWithTZ() {
|
|
requestRepo := repository.NewRequestRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
req := &model.Request{
|
|
UserID: userID,
|
|
RequestTxt: "Test request for TZ update",
|
|
}
|
|
err = requestRepo.Create(ctx, req)
|
|
s.Require().NoError(err)
|
|
|
|
err = requestRepo.UpdateWithTZ(ctx, req.ID, "Generated TZ text", true)
|
|
s.NoError(err)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_RequestGetByID() {
|
|
requestRepo := repository.NewRequestRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
var reqID uuid.UUID
|
|
err = s.pool.QueryRow(ctx, `
|
|
INSERT INTO requests_for_suppliers (user_id, request_txt, final_tz, final_update_tz, mailling_status_id)
|
|
VALUES ($1, 'Test request', 'TZ text', 'Final TZ', 1)
|
|
RETURNING id
|
|
`, userID).Scan(&reqID)
|
|
s.Require().NoError(err)
|
|
|
|
found, err := requestRepo.GetByID(ctx, reqID)
|
|
s.NoError(err)
|
|
s.Equal(reqID, found.ID)
|
|
s.Equal("Test request", found.RequestTxt)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_SupplierBulkInsertAndDelete() {
|
|
supplierRepo := repository.NewSupplierRepository(s.pool)
|
|
requestRepo := repository.NewRequestRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
req := &model.Request{
|
|
UserID: userID,
|
|
RequestTxt: "Test request for suppliers",
|
|
}
|
|
err = requestRepo.Create(ctx, req)
|
|
s.Require().NoError(err)
|
|
|
|
suppliers := []*model.Supplier{
|
|
{Name: "Supplier 1", Email: "s1@test.com"},
|
|
{Name: "Supplier 2", Email: "s2@test.com"},
|
|
}
|
|
err = supplierRepo.BulkInsert(ctx, req.ID, suppliers)
|
|
s.NoError(err)
|
|
|
|
found, err := supplierRepo.GetByRequestID(ctx, req.ID)
|
|
s.NoError(err)
|
|
s.Equal(2, len(found))
|
|
|
|
err = supplierRepo.DeleteByRequestID(ctx, req.ID)
|
|
s.NoError(err)
|
|
|
|
found, err = supplierRepo.GetByRequestID(ctx, req.ID)
|
|
s.NoError(err)
|
|
s.Equal(0, len(found))
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_TokenUsageCreate() {
|
|
tokenRepo := repository.NewTokenUsageRepository(s.pool)
|
|
requestRepo := repository.NewRequestRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
req := &model.Request{
|
|
UserID: userID,
|
|
RequestTxt: "Test request for token usage",
|
|
}
|
|
err = requestRepo.Create(ctx, req)
|
|
s.Require().NoError(err)
|
|
|
|
usage := &model.TokenUsage{
|
|
RequestID: req.ID,
|
|
RequestTokenCount: 100,
|
|
ResponseTokenCount: 50,
|
|
TokenCost: 0.005,
|
|
Type: "openai",
|
|
}
|
|
err = tokenRepo.Create(ctx, usage)
|
|
s.NoError(err)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_TokenUsageGetBalanceStatistics() {
|
|
tokenRepo := repository.NewTokenUsageRepository(s.pool)
|
|
requestRepo := repository.NewRequestRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
req := &model.Request{
|
|
UserID: userID,
|
|
RequestTxt: "Test request for balance statistics",
|
|
}
|
|
err = requestRepo.Create(ctx, req)
|
|
s.Require().NoError(err)
|
|
|
|
usage1 := &model.TokenUsage{
|
|
RequestID: req.ID,
|
|
RequestTokenCount: 100,
|
|
ResponseTokenCount: 50,
|
|
TokenCost: 10.0,
|
|
Type: "openai",
|
|
}
|
|
err = tokenRepo.Create(ctx, usage1)
|
|
s.Require().NoError(err)
|
|
|
|
usage2 := &model.TokenUsage{
|
|
RequestID: req.ID,
|
|
RequestTokenCount: 200,
|
|
ResponseTokenCount: 100,
|
|
TokenCost: 20.0,
|
|
Type: "perplexity",
|
|
}
|
|
err = tokenRepo.Create(ctx, usage2)
|
|
s.Require().NoError(err)
|
|
|
|
averageCost, history, err := tokenRepo.GetBalanceStatistics(ctx, userID)
|
|
s.NoError(err)
|
|
s.Greater(averageCost, 0.0)
|
|
s.GreaterOrEqual(len(history), 2)
|
|
|
|
for _, item := range history {
|
|
s.NotEmpty(item.OperationID)
|
|
s.NotEmpty(item.Data)
|
|
s.GreaterOrEqual(item.Amount, 0.0)
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_TokenUsageGetBalanceStatisticsEmpty() {
|
|
tokenRepo := repository.NewTokenUsageRepository(s.pool)
|
|
ctx := context.Background()
|
|
|
|
averageCost, history, err := tokenRepo.GetBalanceStatistics(ctx, 999999)
|
|
s.NoError(err)
|
|
s.Equal(0.0, averageCost)
|
|
s.Empty(history)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_UserCreate() {
|
|
userRepo := repository.NewUserRepository(s.pool, testCryptoSecret)
|
|
ctx := context.Background()
|
|
|
|
cryptoHelper := crypto.NewCrypto(testCryptoSecret)
|
|
email := fmt.Sprintf("newuser_%d@test.com", time.Now().UnixNano())
|
|
|
|
user := &model.User{
|
|
Email: email,
|
|
EmailHash: cryptoHelper.EmailHash(email),
|
|
PasswordHash: crypto.PasswordHash("password123"),
|
|
Phone: "+1234567890",
|
|
UserName: "New User",
|
|
CompanyName: "Test Company",
|
|
Balance: 100.0,
|
|
PaymentStatus: "active",
|
|
}
|
|
|
|
err := userRepo.Create(ctx, user)
|
|
s.NoError(err)
|
|
s.NotZero(user.ID)
|
|
|
|
_, err = s.pool.Exec(ctx, "DELETE FROM users WHERE id = $1", user.ID)
|
|
s.NoError(err)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_UserCheckInviteLimit() {
|
|
userRepo := repository.NewUserRepository(s.pool, testCryptoSecret)
|
|
ctx := context.Background()
|
|
|
|
var userID int
|
|
err := s.pool.QueryRow(ctx, "SELECT id FROM users LIMIT 1").Scan(&userID)
|
|
s.Require().NoError(err)
|
|
|
|
canInvite, err := userRepo.CheckInviteLimit(ctx, userID)
|
|
s.NoError(err)
|
|
s.True(canInvite)
|
|
}
|
|
|
|
func (s *IntegrationSuite) TestRepository_TxManagerPool() {
|
|
txManager := repository.NewTxManager(s.pool)
|
|
|
|
pool := txManager.Pool()
|
|
s.NotNil(pool)
|
|
s.Equal(s.pool, pool)
|
|
}
|