Files
3ybactuk-marketplace-go-ser…/comments/tests/integration/comments_integration_test.go
2025-07-29 01:10:16 +03:00

231 lines
6.0 KiB
Go
Raw Permalink 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.

//go:build integration
// +build integration
package integration
import (
"context"
"database/sql"
"fmt"
"net"
"testing"
"time"
"github.com/jackc/pgx/v5/pgxpool"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/ozontech/allure-go/pkg/framework/provider"
"github.com/ozontech/allure-go/pkg/framework/suite"
"github.com/pressly/goose/v3"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
repo "route256/comments/infra/repository/sqlc"
"route256/comments/internal/app/server"
"route256/comments/internal/domain/service"
pb "route256/pkg/api/comments/v1"
)
const (
migrationsDir = "../../db/migrations"
)
func startPostgres(ctx context.Context, migrationsDir string) (*pgxpool.Pool, func(), error) {
req := testcontainers.ContainerRequest{
Image: "gitlab-registry.ozon.dev/go/classroom-18/students/base/postgres:16",
Env: map[string]string{
"POSTGRESQL_USERNAME": "user",
"POSTGRESQL_PASSWORD": "postgres",
"POSTGRESQL_DATABASE": "comments_test",
},
ExposedPorts: []string{"5432/tcp"},
WaitingFor: wait.ForListeningPort("5432/tcp").WithStartupTimeout(30 * time.Second),
}
container, err := testcontainers.GenericContainer(ctx,
testcontainers.GenericContainerRequest{ContainerRequest: req, Started: true})
if err != nil {
return nil, nil, err
}
endpoint, err := container.PortEndpoint(ctx, "5432", "")
if err != nil {
container.Terminate(ctx)
return nil, nil, err
}
dsn := fmt.Sprintf("postgresql://user:postgres@%s/comments_test?sslmode=disable", endpoint)
var pool *pgxpool.Pool
for i := 0; i < 30; i++ {
pool, err = pgxpool.New(ctx, dsn)
if err == nil && pool.Ping(ctx) == nil {
break
}
time.Sleep(1 * time.Second)
}
if err != nil {
container.Terminate(ctx)
return nil, nil, err
}
std, err := sql.Open("pgx", dsn)
if err != nil {
container.Terminate(ctx)
return nil, nil, err
}
if err := goose.Up(std, migrationsDir); err != nil {
container.Terminate(ctx)
return nil, nil, err
}
std.Close()
cleanup := func() {
pool.Close()
_ = container.Terminate(context.Background())
}
return pool, cleanup, nil
}
type Suite struct {
suite.Suite
grpcSrv *grpc.Server
grpcConn *grpc.ClientConn
client pb.CommentsClient
cleanup func()
}
func TestLomsIntegrationSuite(t *testing.T) {
suite.RunSuite(t, new(Suite))
}
func (s *Suite) BeforeAll(t provider.T) {
ctx := context.Background()
t.WithNewStep("init cart-service", func(sCtx provider.StepCtx) {
pool, cleanup, err := startPostgres(ctx, migrationsDir)
sCtx.Require().NoError(err, "failed postgres setup")
s.cleanup = cleanup
repo := repo.NewCommentsRepository(pool, pool)
svc := service.NewCommentsService(repo, 1)
commentsServer := server.NewServer(svc)
lis, err := net.Listen("tcp", "127.0.0.1:0")
sCtx.Require().NoError(err)
s.grpcSrv = grpc.NewServer()
pb.RegisterCommentsServer(s.grpcSrv, commentsServer)
go func() { _ = s.grpcSrv.Serve(lis) }()
time.Sleep(50 * time.Millisecond)
conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
sCtx.Require().NoError(err)
s.grpcConn = conn
s.client = pb.NewCommentsClient(conn)
})
}
func (s *Suite) AfterAll(t provider.T) {
s.grpcSrv.Stop()
_ = s.grpcConn.Close()
s.cleanup()
}
func (s *Suite) TestCommentListByOneUser_Success(t provider.T) {
t.Title("Успешное получение списка комментариев, которые оставил один юзер по SKU")
ctx := context.Background()
const (
userID = int64(40)
sku = int64(40)
commentText1 = "тестовый комментарий 1"
commentText2 = "тестовый комментарий 2"
)
var (
commentIDs []int64
commentID int64
)
t.WithNewParameters("userID", userID, "sku", sku)
t.WithNewStep("Создание комментария 1", func(sCtx provider.StepCtx) {
req := &pb.CreateCommentRequest{
UserId: userID,
Sku: sku,
Comment: commentText1,
}
resp, err := s.client.CommentAdd(ctx, req)
sCtx.Require().NoError(err)
commentID = resp.Id
commentIDs = append(commentIDs, commentID)
})
t.WithNewParameters("commentID1", commentID)
t.WithNewStep("Получение первого созданного комментария", func(sCtx provider.StepCtx) {
req := &pb.ListByUserRequest{
UserId: userID,
}
resp, err := s.client.CommentListByUser(ctx, req)
sCtx.Require().NoError(err)
sCtx.Require().Len(resp.Comments, 1)
sCtx.Require().NotNil(resp.Comments[0])
resultComment := resp.Comments[0]
sCtx.Require().Equal(commentID, resultComment.Id)
sCtx.Require().Equal(sku, resultComment.Sku)
sCtx.Require().Equal(commentText1, resultComment.Text)
})
t.WithNewStep("Создание комментария 2", func(sCtx provider.StepCtx) {
req := &pb.CreateCommentRequest{
UserId: userID,
Sku: sku,
Comment: commentText2,
}
resp, err := s.client.CommentAdd(ctx, req)
sCtx.Require().NoError(err)
commentID = resp.Id
commentIDs = append(commentIDs, commentID)
})
t.WithNewParameters("commentID2", commentID)
t.WithNewStep("Получение созданных комментариев в обратном хронологическом порядке", func(sCtx provider.StepCtx) {
req := &pb.ListByUserRequest{
UserId: userID,
}
resp, err := s.client.CommentListByUser(ctx, req)
sCtx.Require().NoError(err)
sCtx.Require().Len(resp.Comments, 2)
sCtx.Require().NotNil(resp.Comments[0])
sCtx.Require().NotNil(resp.Comments[1])
// commentIDs содержит в себе id комментариев в прямом хронологическом порядке
sCtx.Require().Equal(commentIDs[1], resp.Comments[0].Id)
sCtx.Require().Equal(sku, resp.Comments[0].Sku)
sCtx.Require().Equal(commentText2, resp.Comments[0].Text)
sCtx.Require().Equal(commentIDs[0], resp.Comments[1].Id)
sCtx.Require().Equal(sku, resp.Comments[1].Sku)
sCtx.Require().Equal(commentText1, resp.Comments[1].Text)
})
}