mirror of
				https://github.com/3ybactuk/marketplace-go-service-project.git
				synced 2025-10-30 14:03:45 +03:00 
			
		
		
		
	[hw-6] add notifier service, kafka
This commit is contained in:
		| @@ -8,6 +8,7 @@ import ( | ||||
| 	"database/sql" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| @@ -18,9 +19,10 @@ import ( | ||||
| 	"github.com/pressly/goose/v3" | ||||
| 	"github.com/testcontainers/testcontainers-go" | ||||
| 	"github.com/testcontainers/testcontainers-go/wait" | ||||
| 	"go.uber.org/goleak" | ||||
| 	"google.golang.org/grpc" | ||||
| 	"google.golang.org/grpc/codes" | ||||
| 	"google.golang.org/grpc/credentials/insecure" | ||||
| 	"google.golang.org/grpc/status" | ||||
|  | ||||
| 	"route256/loms/internal/app/server" | ||||
| 	"route256/loms/internal/domain/entity" | ||||
| @@ -42,6 +44,13 @@ const ( | ||||
| 	migrationsDir = "../../db/migrations" | ||||
| ) | ||||
|  | ||||
| // TODO: drop, use actual kafka for tests. | ||||
| type mockKafkaProducer struct{} | ||||
|  | ||||
| func (kp mockKafkaProducer) Send(_ context.Context, id entity.ID, status string) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| 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", | ||||
| @@ -111,8 +120,6 @@ type LomsIntegrationSuite struct { | ||||
| } | ||||
|  | ||||
| func TestLomsIntegrationSuite(t *testing.T) { | ||||
| 	defer goleak.VerifyNone(t) | ||||
|  | ||||
| 	suite.RunSuite(t, new(LomsIntegrationSuite)) | ||||
| } | ||||
|  | ||||
| @@ -129,7 +136,7 @@ func (s *LomsIntegrationSuite) BeforeAll(t provider.T) { | ||||
|  | ||||
| 		txManager := postgres.NewTxManager(pool, pool) | ||||
|  | ||||
| 		svc := lomsService.NewLomsService(orderRepo, stockRepo, txManager) | ||||
| 		svc := lomsService.NewLomsService(orderRepo, stockRepo, txManager, &mockKafkaProducer{}) | ||||
| 		lomsServer := server.NewServer(svc) | ||||
|  | ||||
| 		lis, err := net.Listen("tcp", "127.0.0.1:0") | ||||
| @@ -208,3 +215,122 @@ func (s *LomsIntegrationSuite) TestStocksInfoPositive(t provider.T) { | ||||
| 		sCtx.Require().Greater(resp.Count, uint32(0)) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (s *LomsIntegrationSuite) TestOrderCreate_SuccessAsync(t provider.T) { | ||||
| 	t.Title("Успешное создание заказов (async)") | ||||
|  | ||||
| 	const ( | ||||
| 		sku   = 1625903 | ||||
| 		count = 1 | ||||
|  | ||||
| 		ordersCount = 100 | ||||
| 	) | ||||
|  | ||||
| 	var ( | ||||
| 		userIDs = []int64{42, 43, 44} | ||||
| 		orders  = make([]struct { | ||||
| 			userID  int64 | ||||
| 			orderID int64 | ||||
| 		}, ordersCount) | ||||
|  | ||||
| 		initStocksCount uint64 | ||||
|  | ||||
| 		ctx = context.Background() | ||||
| 	) | ||||
|  | ||||
| 	t.WithNewStep("Получение изначальных стоков", func(sCtx provider.StepCtx) { | ||||
| 		stockCount, err := s.lomsClient.StocksInfo(ctx, &pb.StocksInfoRequest{Sku: sku}) | ||||
| 		sCtx.Require().NoError(err) | ||||
| 		initStocksCount = uint64(stockCount.GetCount()) | ||||
| 	}) | ||||
|  | ||||
| 	t.WithNewStep("Создание заказов", func(sCtx provider.StepCtx) { | ||||
| 		var wg sync.WaitGroup | ||||
|  | ||||
| 		for i := range ordersCount { | ||||
| 			wg.Add(1) | ||||
| 			go func() { | ||||
| 				defer wg.Done() | ||||
|  | ||||
| 				userID := userIDs[i%len(userIDs)] | ||||
|  | ||||
| 				req := &pb.OrderCreateRequest{ | ||||
| 					UserId: userID, | ||||
| 					Items: []*pb.OrderItem{ | ||||
| 						{ | ||||
| 							Sku:   sku, | ||||
| 							Count: count, | ||||
| 						}, | ||||
| 					}, | ||||
| 				} | ||||
| 				orderCreateResp, err := s.lomsClient.OrderCreate(ctx, req) | ||||
| 				sCtx.Require().NoError(err) | ||||
| 				sCtx.Require().Greater(orderCreateResp.OrderId, int64(0)) | ||||
|  | ||||
| 				orders[i].userID = userID | ||||
| 				orders[i].orderID = orderCreateResp.OrderId | ||||
| 			}() | ||||
| 		} | ||||
| 		wg.Wait() | ||||
| 	}) | ||||
|  | ||||
| 	t.WithNewStep("Проверка заказов", func(sCtx provider.StepCtx) { | ||||
| 		for _, order := range orders { | ||||
| 			res, err := s.lomsClient.OrderInfo(ctx, &pb.OrderInfoRequest{ | ||||
| 				OrderId: order.orderID, | ||||
| 			}) | ||||
| 			sCtx.Require().NoError(err) | ||||
|  | ||||
| 			expected := entity.Order{ | ||||
| 				Status: "awaiting payment", | ||||
| 				UserID: entity.ID(order.userID), | ||||
| 				Items: []entity.OrderItem{ | ||||
| 					{ | ||||
| 						ID:    sku, | ||||
| 						Count: count, | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
|  | ||||
| 			sCtx.Require().Equal(expected.Status, res.Status, "Не совпадает статус заказа") | ||||
| 			sCtx.Require().Equal(expected.UserID, entity.ID(res.UserId), "Не совпадает пользователь заказа") | ||||
| 			sCtx.Require().Equal(len(expected.Items), len(res.Items), "Не совпадает количество товаров в заказе") | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.WithNewStep("Проверка стоков", func(sCtx provider.StepCtx) { | ||||
| 		stocksCount, err := s.lomsClient.StocksInfo(ctx, &pb.StocksInfoRequest{ | ||||
| 			Sku: sku, | ||||
| 		}) | ||||
| 		sCtx.Require().NoError(err) | ||||
| 		sCtx.Require().Equal(uint32(initStocksCount-ordersCount*count), stocksCount.Count) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (s *LomsIntegrationSuite) TestOrderCreate_NoStockInfo(t provider.T) { | ||||
| 	t.Title("Неуспешное создание заказ из-за отсутствия информации о стоках товара") | ||||
|  | ||||
| 	const ( | ||||
| 		userID = 42 | ||||
| 		sku    = 404 | ||||
| 	) | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	t.WithNewStep("Создание заказа", func(sCtx provider.StepCtx) { | ||||
| 		req := &pb.OrderCreateRequest{ | ||||
| 			UserId: userID, | ||||
| 			Items: []*pb.OrderItem{ | ||||
| 				{ | ||||
| 					Sku:   sku, | ||||
| 					Count: 1, | ||||
| 				}, | ||||
| 			}, | ||||
| 		} | ||||
| 		_, err := s.lomsClient.OrderCreate(ctx, req) | ||||
|  | ||||
| 		e, ok := status.FromError(err) | ||||
| 		sCtx.Require().True(ok) | ||||
| 		sCtx.Require().Equal(codes.FailedPrecondition, e.Code(), "expect 400 (failed precondition) status code, got: %s", err.Error()) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Никита Шубин
					Никита Шубин