diff --git a/.env.test b/.env.test deleted file mode 100644 index f6d855c..0000000 --- a/.env.test +++ /dev/null @@ -1,27 +0,0 @@ -HTTP_HOST=0.0.0.0 -HTTP_PORT=8082 - -GRPC_HOST=0.0.0.0 -GRPC_PORT=9082 -GRPC_DOMEN=customer-app:9082 - -MONGO_HOST=mongo -MONGO_PORT=27017 -MONGO_USER=test -MONGO_PASSWORD=test -MONGO_DB_NAME=admin -MONGO_AUTH=admin - -AUTH_MICROSERVICE_USER_URL=http://pena-auth-service:8000/user -HUBADMIN_MICROSERVICE_TARIFF_URL=http://hub-admin-service:8010/tariff -CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrf-service:8020/translate -DISCOUNT_MICROSERVICE_GRPC_HOST=discount-service:9040 -PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085 - -KAFKA_BROKERS=localhost:8080,localhost:1111 -KAFKA_TOPIC_TARIFF=tariff - -# JWT settings -JWT_ISSUER="pena-auth-service" -JWT_AUDIENCE="pena" -JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm6980fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6BdA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----" diff --git a/Dockerfile b/Dockerfile index 827843a..330ab65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,72 +1,54 @@ # BUILD FROM golang:1.20.3-alpine AS build -# Update depences -RUN apk update && apk add --no-cache curl -# Create build directory -RUN mkdir /app/bin -p -RUN mkdir /bin/golang-migrate -p -# Download migrate app -RUN GOLANG_MIGRATE_VERSION=v4.15.1 && \ - curl -L https://github.com/golang-migrate/migrate/releases/download/${GOLANG_MIGRATE_VERSION}/migrate.linux-amd64.tar.gz |\ - tar xvz migrate -C /bin/golang-migrate -# Download health check utility -RUN GRPC_HEALTH_PROBE_VERSION=v0.4.6 && \ - wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ - chmod +x /bin/grpc_health_probe -# Download debugger -# Set home directory +# Update packages and clear cache +RUN apk update && apk add --no-cache curl && rm -rf /var/cache/apk/* +# Set work directory WORKDIR /app -# Copy go.mod -ADD go.mod go.sum /app/ +# Create binary directory +RUN mkdir /app/bin -p +# Create golang migrate util directory +RUN mkdir /bin/golang-migrate -p +# Add migrate tool +ADD ./tools/migrate /bin/golang-migrate/ +# Add main files to app +ADD . . # Download go depences RUN go mod download -# Copy all local files -ADD . /app # Build app RUN GOOS=linux go build -o bin ./... # TEST -FROM alpine:latest AS test +FROM alpine:3.18.3 AS test # Install packages -RUN apk --no-cache add ca-certificates +RUN apk --no-cache add ca-certificates && rm -rf /var/cache/apk/* +# Set GO111MODULE env ENV GO111MODULE=off # Create home directory WORKDIR /app # Copy build file COPY --from=build /app/bin/app ./app -# CMD -CMD [ "./app" ] - - -# MIGRATION -FROM alpine:latest AS migration - -# Install packages -RUN apk --no-cache add ca-certificates -# Create home directory -WORKDIR /app # Copy migration dir COPY --from=build /app/migrations/test ./migrations # Install migrate tool COPY --from=build /bin/golang-migrate /usr/local/bin +# CMD +CMD [ "./app" ] # PRODUCTION -FROM alpine:latest AS production +FROM alpine:3.18.3 AS production # Install packages -RUN apk --no-cache add ca-certificates +RUN apk --no-cache add ca-certificates && rm -rf /var/cache/apk/* # Create home directory WORKDIR /app # Copy build file COPY --from=build /app/bin/app ./app -# Copy grpc health probe dir -COPY --from=build /bin/grpc_health_probe /bin/grpc_health_probe # Install migrate tool COPY --from=build /bin/golang-migrate /usr/local/bin # CMD diff --git a/Makefile b/Makefile index 02d812b..d7dc553 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,8 @@ install: ## install all go dependencies generate: ## generate grpc proto for golang buf generate - go generate ./internal/interface/swagger + oapi-codegen --config ./api/openapi/v1/api.yaml ./api/openapi/v1/openapi.yaml + oapi-codegen --config ./api/openapi/v1/models.yaml ./api/openapi/v1/openapi.yaml test: ## run all layers tests @make test.unit @@ -29,13 +30,16 @@ test.integration: ## run integration tests @make test.integration.down test.integration.up: ## build integration test environment - docker-compose -f deployments/test/docker-compose.yaml --env-file ./.env.test up -d - -test.integration.start: ## run integration test - go test -tags integration ./tests/integration/... + docker-compose -f deployments/test/docker-compose.yaml up -d test.integration.down: ## shutting down integration environment - docker-compose -f deployments/test/docker-compose.yaml --env-file ./.env.test down --volumes --rmi local + docker-compose -f deployments/test/docker-compose.yaml down --volumes --rmi local + +test.integration.start: ## run integration test + go test ./tests/integration/... + +test.e2e.start: ## run integration test + go test ./tests/e2e/... run: ## run app go run ./cmd/app/main.go diff --git a/internal/interface/swagger/api.yaml b/api/openapi/v1/api.yaml similarity index 63% rename from internal/interface/swagger/api.yaml rename to api/openapi/v1/api.yaml index a2634dd..871b476 100644 --- a/internal/interface/swagger/api.yaml +++ b/api/openapi/v1/api.yaml @@ -1,4 +1,4 @@ -output: api.gen.go +output: ./internal/interface/swagger/api.gen.go package: swagger generate: echo-server: true diff --git a/api/openapi/v1/models.yaml b/api/openapi/v1/models.yaml new file mode 100644 index 0000000..43295b3 --- /dev/null +++ b/api/openapi/v1/models.yaml @@ -0,0 +1,4 @@ +output: ./internal/interface/swagger/models.gen.go +package: swagger +generate: + models: true diff --git a/openapi.yaml b/api/openapi/v1/openapi.yaml similarity index 100% rename from openapi.yaml rename to api/openapi/v1/openapi.yaml diff --git a/proto/broker/models.proto b/api/proto/broker/models.proto similarity index 100% rename from proto/broker/models.proto rename to api/proto/broker/models.proto diff --git a/proto/callback/service.proto b/api/proto/callback/service.proto similarity index 100% rename from proto/callback/service.proto rename to api/proto/callback/service.proto diff --git a/proto/customer/service.proto b/api/proto/customer/service.proto similarity index 100% rename from proto/customer/service.proto rename to api/proto/customer/service.proto diff --git a/proto/discount/audit.model.proto b/api/proto/discount/audit.model.proto similarity index 100% rename from proto/discount/audit.model.proto rename to api/proto/discount/audit.model.proto diff --git a/proto/discount/discount.model.proto b/api/proto/discount/discount.model.proto similarity index 100% rename from proto/discount/discount.model.proto rename to api/proto/discount/discount.model.proto diff --git a/proto/discount/service.proto b/api/proto/discount/service.proto similarity index 100% rename from proto/discount/service.proto rename to api/proto/discount/service.proto diff --git a/proto/google/api/annotations.proto b/api/proto/google/api/annotations.proto similarity index 100% rename from proto/google/api/annotations.proto rename to api/proto/google/api/annotations.proto diff --git a/proto/google/api/http.proto b/api/proto/google/api/http.proto similarity index 100% rename from proto/google/api/http.proto rename to api/proto/google/api/http.proto diff --git a/proto/treasurer/payment.model.proto b/api/proto/treasurer/payment.model.proto similarity index 100% rename from proto/treasurer/payment.model.proto rename to api/proto/treasurer/payment.model.proto diff --git a/proto/treasurer/service.proto b/api/proto/treasurer/service.proto similarity index 100% rename from proto/treasurer/service.proto rename to api/proto/treasurer/service.proto diff --git a/buf.work.yaml b/buf.work.yaml index fd67f23..c0b5312 100644 --- a/buf.work.yaml +++ b/buf.work.yaml @@ -1,3 +1,3 @@ version: v1 directories: - - proto \ No newline at end of file + - api/proto \ No newline at end of file diff --git a/deployments/test/.env.test b/deployments/test/.env.test index c27b275..fad1595 100644 --- a/deployments/test/.env.test +++ b/deployments/test/.env.test @@ -1,27 +1,4 @@ -# HTTP settings -HTTP_HOST=0.0.0.0 -HTTP_PORT=8080 - -# MONGO settings -MONGO_HOST=localhost -MONGO_PORT=27017 -MONGO_USER=test -MONGO_PASSWORD=test -MONGO_AUTH=admin -MONGO_DB_NAME=admin - -# Auth Microservice settings -AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user - -# Hub Admin Microservice settings -HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff - -# Currency Microservice settings -CURRENCY_MICROSERVICE_TRANSLATE_URL=http://localhost:8002/change - -# Admin - # JWT settings JWT_ISSUER="pena-auth-service" JWT_AUDIENCE="pena" -JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyt4XuLovUY7i12K2PIMbQZOKn+wFFKUvxvKQDel049/+VMpHMx1FLolUKuyGp9zi6gOwjHsBPgc9oqr/eaXGQSh7Ult7i9f+Ht563Y0er5UU9Zc5ZPSxf9O75KYD48ruGkqiFoncDqPENK4dtUa7w0OqlN4bwVBbmIsP8B3EDC5Dof+vtiNTSHSXPx+zifKeZGyknp+nyOHVrRDhPjOhzQzCom0MSZA/sJYmps8QZgiPA0k4Z6jTupDymPOIwYeD2C57zSxnAv0AfC3/pZYJbZYH/0TszRzmy052DME3zMnhMK0ikdN4nzYqU0dkkA5kb5GtKDymspHIJ9eWbUuwgtg8Rq/LrVBj1I3UFgs0ibio40k6gqinLKslc5Y1I5mro7J3OSEP5eO/XeDLOLlOJjEqkrx4fviI1cL3m5L6QV905xmcoNZG1+RmOg7D7cZQUf27TXqM381jkbNdktm1JLTcMScxuo3vaRftnIVw70V8P8sIkaKY8S8HU1sQgE2LB9t04oog5u59htx2FHv4B13NEm8tt8Tv1PexpB4UVh7PIualF6SxdFBrKbraYej72wgjXVPQ0eGXtGGD57j8DUEzk7DK2OvIWhehlVqtiRnFdAvdBj2ynHT2/5FJ/Zpd4n5dKGJcQvy1U1qWMs+8M7AHfWyt2+nZ04s48+bK3yMCAwEAAQ==\n-----END PUBLIC KEY-----" +JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69\n80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B\ndA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y\n+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----" diff --git a/deployments/test/docker-compose.yaml b/deployments/test/docker-compose.yaml index bf7e447..c5a5c92 100644 --- a/deployments/test/docker-compose.yaml +++ b/deployments/test/docker-compose.yaml @@ -1,7 +1,11 @@ version: "3" +volumes: + redpanda: null + services: - app: + customer-service: + container_name: customer-service build: context: ../../. dockerfile: Dockerfile @@ -10,59 +14,162 @@ services: - .env.test environment: - HTTP_HOST=0.0.0.0 - - HTTP_PORT=8082 + - HTTP_PORT=8000 - GRPC_HOST=0.0.0.0 - - GRPC_PORT=9082 - - GRPC_DOMEN=customer-app:9082 + - GRPC_PORT=9000 + - GRPC_DOMEN=customer-service:9000 - - MONGO_HOST=mongo + - MONGO_HOST=customer-db - MONGO_PORT=27017 - MONGO_USER=test - MONGO_PASSWORD=test - MONGO_DB_NAME=admin - MONGO_AUTH=admin - - JWT_ISSUER=issuer - - JWT_AUDIENCE=audience + - KAFKA_BROKERS=customer-redpanda:9092 + - KAFKA_TOPIC_TARIFF=tariffs - AUTH_MICROSERVICE_USER_URL=http://pena-auth-service:8000/user - - HUBADMIN_MICROSERVICE_TARIFF_URL=http://hub-admin-service:8010/tariff - - CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrf-service:8020/translate - - DISCOUNT_MICROSERVICE_GRPC_HOST=discount-service:9040 + - HUBADMIN_MICROSERVICE_TARIFF_URL=http://hub-admin-backend-service:8000/tariff + - CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrfworker-service:8000/change + - DISCOUNT_MICROSERVICE_GRPC_HOST=discount-service:9000 - PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085 ports: - - 8082:8082 + - 8082:8000 + - 9092:9000 depends_on: - - migration + - customer-db + - customer-migration + - redpanda networks: - - integration_test + - test - migration: + customer-migration: + container_name: customer-migration build: context: ../../. dockerfile: Dockerfile - target: migration + target: test command: [ "sh", "-c", - 'migrate -source file://migrations -database "mongodb://test:test@mongo:27017/admin?authSource=admin" up', + 'migrate -source file://migrations -database "mongodb://test:test@customer-db:27017/admin?authSource=admin" up', ] depends_on: - - mongo + - customer-db networks: - - integration_test + - test - mongo: - image: 'mongo:6.0.3' + customer-db: + container_name: customer-db + image: "mongo:6.0.3" environment: MONGO_INITDB_ROOT_USERNAME: test MONGO_INITDB_ROOT_PASSWORD: test ports: - - '27017:27017' + - "27024:27017" networks: - - integration_test + - test + + redpanda: + container_name: customer-redpanda + tty: true + image: docker.redpanda.com/redpandadata/redpanda:v23.1.13 + command: + - redpanda start + - --smp 1 + - --overprovisioned + - --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092 + # Address the broker advertises to clients that connect to the Kafka API. + # Use the internal addresses to connect to the Redpanda brokers + # from inside the same Docker network. + # Use the external addresses to connect to the Redpanda brokers + # from outside the Docker network. + - --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092 + - --pandaproxy-addr internal://0.0.0.0:8082,external://0.0.0.0:18082 + # Address the broker advertises to clients that connect to the HTTP Proxy. + - --advertise-pandaproxy-addr internal://redpanda:8082,external://localhost:18082 + - --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081 + # Redpanda brokers use the RPC API to communicate with each other internally. + - --rpc-addr redpanda:33145 + - --advertise-rpc-addr redpanda:33145 + ports: + - 18081:18081 + - 18082:18082 + - 19092:19092 + - 19644:9644 + volumes: + - redpanda:/var/lib/redpanda/data + networks: + - test + healthcheck: + test: ["CMD-SHELL", "rpk cluster health | grep -E 'Healthy:.+true' || exit 1"] + interval: 15s + timeout: 3s + retries: 5 + start_period: 5s + + console: + tty: true + image: docker.redpanda.com/redpandadata/console:v2.2.4 + entrypoint: /bin/sh + command: -c "echo \"$$CONSOLE_CONFIG_FILE\" > /tmp/config.yml; /app/console" + environment: + CONFIG_FILEPATH: /tmp/config.yml + CONSOLE_CONFIG_FILE: | + kafka: + brokers: ["redpanda:9092"] + schemaRegistry: + enabled: true + urls: ["http://redpanda:8081"] + redpanda: + adminApi: + enabled: true + urls: ["http://redpanda:9644"] + connect: + enabled: true + clusters: + - name: local-connect-cluster + url: http://connect:8083 + ports: + - 8080:8080 + networks: + - test + depends_on: + - redpanda + + connect: + tty: true + image: docker.redpanda.com/redpandadata/connectors:latest + hostname: connect + container_name: connect + networks: + - test + # platform: 'linux/amd64' + depends_on: + - redpanda + ports: + - "8083:8083" + environment: + CONNECT_CONFIGURATION: | + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + config.storage.replication.factor=-1 + offset.storage.replication.factor=-1 + status.storage.replication.factor=-1 + offset.flush.interval.ms=1000 + producer.linger.ms=50 + producer.batch.size=131072 + CONNECT_BOOTSTRAP_SERVERS: redpanda:9092 + CONNECT_GC_LOG_ENABLED: "false" + CONNECT_HEAP_OPTS: -Xms512M -Xmx512M + CONNECT_LOG_LEVEL: info networks: - integration_test: \ No newline at end of file + test: \ No newline at end of file diff --git a/internal/app/app.go b/internal/app/app.go index 5507b6a..ffcbdec 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -40,7 +40,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) { if err := kafka.Initialize(ctx, config.Service.Kafka.Brokers, []string{ config.Service.Kafka.Tariff.Topic, }); err != nil { - return err + return fmt.Errorf("failed initialize kafka: %w", err) } mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{ diff --git a/internal/interface/controller/rest/cart/cart.go b/internal/interface/controller/rest/cart/cart.go index 71cd8fe..aef0225 100644 --- a/internal/interface/controller/rest/cart/cart.go +++ b/internal/interface/controller/rest/cart/cart.go @@ -15,9 +15,9 @@ import ( ) type cartService interface { - Remove(ctx context.Context, userID, itemID string) ([]string, errors.Error) - Add(context.Context, *models.AddItemToCart) ([]string, errors.Error) - Pay(ctx context.Context, token, userID string) errors.Error + Remove(ctx context.Context, userID, itemID string) (*models.Account, errors.Error) + Add(context.Context, *models.AddItemToCart) (*models.Account, errors.Error) + Pay(ctx context.Context, token, userID string) (*models.Account, errors.Error) } type Deps struct { @@ -114,10 +114,11 @@ func (receiver *Controller) Pay(ctx echo.Context) error { return errors.HTTP(ctx, errors.NewWithMessage("failed to convert access token payload to string", errors.ErrInvalidArgs)) } - if err := receiver.cartService.Pay(ctx.Request().Context(), token, userID); err != nil { + account, err := receiver.cartService.Pay(ctx.Request().Context(), token, userID) + if err != nil { receiver.logger.Error("failed to pay cart on of ", zap.Error(err)) return errors.HTTP(ctx, err) } - return ctx.JSON(http.StatusOK, true) + return ctx.JSON(http.StatusOK, account) } diff --git a/internal/interface/swagger/api.go b/internal/interface/swagger/api.go index 822a219..3784d8c 100644 --- a/internal/interface/swagger/api.go +++ b/internal/interface/swagger/api.go @@ -6,9 +6,6 @@ import ( "github.com/labstack/echo/v4" ) -//go:generate oapi-codegen --config api.yaml ../../../openapi.yaml -//go:generate oapi-codegen --config models.yaml ../../../openapi.yaml - type accountController interface { RemoveAccount(ctx echo.Context) error GetAccount(ctx echo.Context) error diff --git a/internal/interface/swagger/models.yaml b/internal/interface/swagger/models.yaml deleted file mode 100644 index 9ef06be..0000000 --- a/internal/interface/swagger/models.yaml +++ /dev/null @@ -1,4 +0,0 @@ -output: models.gen.go -package: swagger -generate: - models: true diff --git a/internal/models/tariff.go b/internal/models/tariff.go index 8c7fe85..7d8e754 100644 --- a/internal/models/tariff.go +++ b/internal/models/tariff.go @@ -9,9 +9,9 @@ import ( type Tariff struct { ID string `json:"_id"` Name string `json:"name"` - Price int64 `json:"price,omitempty"` + Price uint64 `json:"price,omitempty"` IsCustom bool `json:"isCustom"` - Privileges []Privilege `json:"privilegies"` //nolint + Privileges []Privilege `json:"privileges"` Deleted bool `json:"isDeleted"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` diff --git a/internal/service/cart/cart.go b/internal/service/cart/cart.go index 261da0b..1d9b2ed 100644 --- a/internal/service/cart/cart.go +++ b/internal/service/cart/cart.go @@ -104,17 +104,17 @@ func New(deps Deps) *Service { } } -func (receiver *Service) Remove(ctx context.Context, userID, itemID string) ([]string, errors.Error) { +func (receiver *Service) Remove(ctx context.Context, userID, itemID string) (*models.Account, errors.Error) { account, err := receiver.repository.RemoveItemFromCart(ctx, userID, itemID) if err != nil { receiver.logger.Error("failed to remove item from cart on of ", zap.Error(err)) - return []string{}, err + return nil, err } - return account.Cart, nil + return account, nil } -func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart) ([]string, errors.Error) { +func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart) (*models.Account, errors.Error) { tariff, err := receiver.hubadminClient.GetTariff(ctx, request.AccessToken, request.TariffID) if err != nil { receiver.logger.Error("failed to get tariff on of ", @@ -123,11 +123,11 @@ func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart) zap.String("accessToken", request.AccessToken), ) - return []string{}, err + return nil, err } if tariff == nil { - return []string{}, errors.New( + return nil, errors.New( fmt.Errorf("failed to get tariff <%s> on of : tariff not found", request.TariffID), errors.ErrNotFound, ) @@ -136,60 +136,54 @@ func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart) account, err := receiver.repository.AddItemToCart(ctx, request.UserID, request.TariffID) if err != nil { receiver.logger.Error("failed to add item to cart on of ", zap.Error(err)) - return []string{}, err + return nil, err } - return account.Cart, nil + return account, nil } -func (receiver *Service) Pay(ctx context.Context, accessToken string, userID string) errors.Error { +func (receiver *Service) Pay(ctx context.Context, accessToken string, userID string) (*models.Account, errors.Error) { account, err := receiver.repository.FindByUserID(ctx, userID) if err != nil { receiver.logger.Error("failed to find account on of ", zap.String("userID", userID), zap.Error(err)) - return err + return nil, err } - receiver.logger.Info("account for buy cart", zap.Any("trtr", account)) - tariffs, err := receiver.hubadminClient.GetTariffs(ctx, accessToken, account.Cart) if err != nil { receiver.logger.Error("failed to get tarrifs on of ", zap.Strings("cart", account.Cart), zap.Error(err)) - return err + return nil, err } - receiver.logger.Info("tariffs for buy cart", zap.Any("trtr", tariffs)) - tariffsAmount := utils.CalculateCartPurchasesAmount(tariffs) - receiver.logger.Info("tariffsAmount for buy cart", zap.Any("trtr", tariffsAmount)) - response, err := receiver.discountClient.Apply(ctx, &discount.ApplyDiscountRequest{ + discountResponse, err := receiver.discountClient.Apply(ctx, &discount.ApplyDiscountRequest{ UserInformation: &discount.UserInformation{ ID: account.UserID, Type: string(account.Status), PurchasesAmount: uint64(account.Wallet.PurchasesAmount), - CartPurchasesAmount: uint64(tariffsAmount), + CartPurchasesAmount: tariffsAmount, }, Products: transfer.TariffsToProductInformations(tariffs), Date: timestamppb.New(time.Now()), }) if err != nil { receiver.logger.Error("failed to discount on of ", zap.Error(err)) - return err + return nil, err } - receiver.logger.Info("applyed discounts for buy cart", zap.Any("trtr", response)) - - if account.Wallet.Money < int64(response.Price) { + if account.Wallet.Money < int64(discountResponse.Price) { receiver.logger.Error("insufficient funds on of ") - return errors.New(fmt.Errorf("insufficient funds: %d", int64(response.Price)-account.Wallet.Money), errors.ErrInsufficientFunds) + return nil, errors.New(fmt.Errorf("insufficient funds: %d", int64(discountResponse.Price)-account.Wallet.Money), errors.ErrInsufficientFunds) } - if _, err := receiver.walletService.WithdrawAccountWalletMoney(ctx, &models.WithdrawAccountWallet{ - Money: int64(response.Price), + updatedAccount, err := receiver.walletService.WithdrawAccountWalletMoney(ctx, &models.WithdrawAccountWallet{ + Money: int64(discountResponse.Price), Account: account, - }); err != nil { + }) + if err != nil { receiver.logger.Error("failed to withdraw money on of ", zap.Error(err)) - return err + return nil, err } if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{ @@ -207,13 +201,15 @@ func (receiver *Service) Pay(ctx context.Context, accessToken string, userID str receiver.logger.Error("failed to send tariffs to broker on of ", zap.Error(err)) } - return errors.NewWithMessage("failed to send tariffs to broker", errors.ErrInternalError) + return nil, errors.NewWithMessage("failed to send tariffs to broker", errors.ErrInternalError) } if _, err := receiver.repository.ClearCart(ctx, account.UserID); err != nil { receiver.logger.Error("failed to clear cart on of ", zap.Error(err)) - return err + return nil, err } - return nil + updatedAccount.Cart = []string{} + + return updatedAccount, nil } diff --git a/internal/service/wallet/wallet.go b/internal/service/wallet/wallet.go index 9b6b8c9..19a89f3 100644 --- a/internal/service/wallet/wallet.go +++ b/internal/service/wallet/wallet.go @@ -10,8 +10,6 @@ import ( "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate" ) -const defaultCurrency = "RUB" - type accountRepository interface { ChangeWallet(ctx context.Context, userID string, wallet *models.Wallet) (*models.Account, errors.Error) FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error) @@ -66,7 +64,7 @@ func New(deps Deps) *Service { func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *models.ReplenishAccountWallet) (*models.Account, errors.Error) { if validate.IsStringEmpty(request.Account.Wallet.Currency) { - request.Account.Wallet.Currency = defaultCurrency + request.Account.Wallet.Currency = models.InternalCurrencyKey } cash := request.Cash @@ -159,7 +157,29 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo func (receiver *Service) WithdrawAccountWalletMoney(ctx context.Context, request *models.WithdrawAccountWallet) (*models.Account, errors.Error) { if validate.IsStringEmpty(request.Account.Wallet.Currency) { - request.Account.Wallet.Currency = defaultCurrency + request.Account.Wallet.Currency = models.InternalCurrencyKey + } + + if request.Account.Wallet.Currency == models.InternalCurrencyKey { + updatedAccount, err := receiver.repository.ChangeWallet(ctx, request.Account.UserID, &models.Wallet{ + Cash: request.Account.Wallet.Cash - request.Money, + Money: request.Account.Wallet.Money - request.Money, + Spent: request.Account.Wallet.Spent + request.Money, + PurchasesAmount: request.Account.Wallet.PurchasesAmount, + Currency: request.Account.Wallet.Currency, + }) + if err != nil { + receiver.logger.Error("failed to replenish wallet on of ", + zap.Error(err), + zap.String("Currency", request.Account.Wallet.Currency), + zap.Int64("Money", request.Account.Wallet.Money-request.Money), + zap.Int64("Cash", request.Account.Wallet.Cash+request.Money), + ) + + return nil, err + } + + return updatedAccount, nil } cash, err := receiver.currencyClient.Translate(ctx, &models.TranslateCurrency{ diff --git a/internal/utils/tariff.go b/internal/utils/tariff.go index 7c8173e..dbf904e 100644 --- a/internal/utils/tariff.go +++ b/internal/utils/tariff.go @@ -2,10 +2,22 @@ package utils import "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models" -func CalculateCartPurchasesAmount(tariffs []models.Tariff) int64 { - sum := int64(0) +func CalculateCartPurchasesAmount(tariffs []models.Tariff) uint64 { + sum := uint64(0) for _, tariff := range tariffs { + if tariff.Price == 0 { + privilegesSum := uint64(0) + + for _, privilege := range tariff.Privileges { + privilegesSum += privilege.Price + } + + sum += privilegesSum + + continue + } + sum += tariff.Price } diff --git a/internal/utils/tariff_test.go b/internal/utils/tariff_test.go index e92e3f0..9a74d65 100644 --- a/internal/utils/tariff_test.go +++ b/internal/utils/tariff_test.go @@ -10,7 +10,7 @@ import ( func TestCalculateCartPurchasesAmount(t *testing.T) { t.Run("Успешное вычиление суммы корзины", func(t *testing.T) { - assert.Equal(t, int64(200000), utils.CalculateCartPurchasesAmount([]models.Tariff{ + assert.Equal(t, uint64(200000), utils.CalculateCartPurchasesAmount([]models.Tariff{ {Price: 90000}, {Price: 110000}, })) diff --git a/internal/utils/transfer/tariff.go b/internal/utils/transfer/tariff.go index 958c5a3..603b4b6 100644 --- a/internal/utils/transfer/tariff.go +++ b/internal/utils/transfer/tariff.go @@ -19,7 +19,7 @@ func TariffsToProductInformations(tarrifs []models.Tariff) []*discount.ProductIn func TariffToProductInformation(tarrif models.Tariff) *discount.ProductInformation { return &discount.ProductInformation{ ID: tarrif.ID, - Price: uint64(tarrif.Price), + Price: tarrif.Price, } } diff --git a/migrations/test/001_accounts_insert.up.json b/migrations/test/001_accounts_insert.up.json index 9724208..4c182c7 100644 --- a/migrations/test/001_accounts_insert.up.json +++ b/migrations/test/001_accounts_insert.up.json @@ -22,6 +22,26 @@ "createdAt": "2023-06-16T08:15:30.336Z", "updatedAt": "2023-06-16T08:15:30.336Z", "deletedAt": "2023-06-16T08:15:30.336Z" + }, + { + "_id": { + "$oid": "64e4869f9fa60b9222bf4d84" + }, + "userId": "64e5d9830fcca0596d82c0c7", + "name": {}, + "cart": [], + "wallet": { + "currency": "RUB", + "cash": 10000, + "purchasesAmount": 0, + "spent": 0, + "money": 10000 + }, + "status": "no", + "isDeleted": false, + "createdAt": "2023-06-16T08:15:30.336Z", + "updatedAt": "2023-06-16T08:15:30.336Z", + "deletedAt": "2023-06-16T08:15:30.336Z" } ] } diff --git a/pkg/mongo/connection.go b/pkg/mongo/connection.go index 241b446..7cc9d58 100644 --- a/pkg/mongo/connection.go +++ b/pkg/mongo/connection.go @@ -8,7 +8,6 @@ import ( "net/url" "time" - "go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) @@ -28,18 +27,6 @@ func Connect(ctx context.Context, deps *ConnectDeps) (*mongo.Database, error) { Host: net.JoinHostPort(deps.Configuration.Host, deps.Configuration.Port), } - cmdMonitor := &event.CommandMonitor{ - Started: func(_ context.Context, evt *event.CommandStartedEvent) { - log.Println(evt.Command) - }, - Succeeded: func(_ context.Context, evt *event.CommandSucceededEvent) { - log.Println(evt.Reply) - }, - Failed: func(_ context.Context, evt *event.CommandFailedEvent) { - log.Println(evt.Failure) - }, - } - connectionOptions := options.Client(). ApplyURI(mongoURI.String()). SetAuth(options.Credential{ @@ -47,10 +34,7 @@ func Connect(ctx context.Context, deps *ConnectDeps) (*mongo.Database, error) { AuthSource: deps.Configuration.Auth, Username: deps.Configuration.User, Password: deps.Configuration.Password, - }). - SetMonitor(cmdMonitor) - - fmt.Println(connectionOptions.GetURI()) + }) ticker := time.NewTicker(1 * time.Second) timeoutExceeded := time.After(deps.Timeout) diff --git a/tests/e2e/buy_tariff_test.go b/tests/e2e/buy_tariff_test.go new file mode 100644 index 0000000..6f69353 --- /dev/null +++ b/tests/e2e/buy_tariff_test.go @@ -0,0 +1,65 @@ +package e2e_test + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models" + "penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client" + "penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers" +) + +func TestBuyTariff(t *testing.T) { + jwtUtil := helpers.InitializeJWT() + + t.Run("Успешная оплата корзины", func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + assert.NotPanics(t, func() { + token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7") + if isNoError := assert.NoError(t, tokenErr); !isNoError { + return + } + + responseAddCart, errAddCart := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{ + URL: "http://localhost:8082/cart", + Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)}, + QueryParams: map[string]string{"id": "64e6105384368b75221a5c3e"}, + }) + if isNoError := assert.NoError(t, errAddCart); !isNoError { + return + } + if isNoRequestError := assert.Nil(t, responseAddCart.Error); !isNoRequestError { + return + } + + isUserIDValid := assert.Equal(t, "64e5d9830fcca0596d82c0c7", responseAddCart.Body.UserID) + isCartLengthValid := assert.Equal(t, 1, len(responseAddCart.Body.Cart)) + isCartItemValid := assert.Equal(t, "64e6105384368b75221a5c3e", responseAddCart.Body.Cart[0]) + + if isUserIDValid && isCartItemValid && isCartLengthValid { + responsePay, errPay := client.Post[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{ + URL: "http://localhost:8082/cart/pay", + Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)}, + }) + if isNoError := assert.NoError(t, errPay); !isNoError { + return + } + if isNoRequestError := assert.Nil(t, responsePay.Error); !isNoRequestError { + return + } + + assert.Equal(t, "64e5d9830fcca0596d82c0c7", responsePay.Body.UserID) + assert.Equal(t, 0, len(responsePay.Body.Cart)) + assert.Equal(t, responseAddCart.Body.Wallet.Cash-5000, responsePay.Body.Wallet.Cash) + assert.Equal(t, responseAddCart.Body.Wallet.Money-5000, responsePay.Body.Wallet.Money) + assert.Equal(t, responseAddCart.Body.Wallet.Spent+5000, responsePay.Body.Wallet.Spent) + assert.Equal(t, responseAddCart.Body.Wallet.PurchasesAmount, responsePay.Body.Wallet.PurchasesAmount) + assert.Equal(t, "RUB", responsePay.Body.Wallet.Currency) + } + }) + }) +} diff --git a/tests/helpers/jwt.go b/tests/helpers/jwt.go index 5632bd7..d2c12dc 100644 --- a/tests/helpers/jwt.go +++ b/tests/helpers/jwt.go @@ -11,77 +11,32 @@ import ( func InitializeJWT() *utils.JWT { publicKey := strings.Replace(`-----BEGIN PUBLIC KEY----- - MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyt4XuLovUY7i12K2PIMb - QZOKn+wFFKUvxvKQDel049/+VMpHMx1FLolUKuyGp9zi6gOwjHsBPgc9oqr/eaXG - QSh7Ult7i9f+Ht563Y0er5UU9Zc5ZPSxf9O75KYD48ruGkqiFoncDqPENK4dtUa7 - w0OqlN4bwVBbmIsP8B3EDC5Dof+vtiNTSHSXPx+zifKeZGyknp+nyOHVrRDhPjOh - zQzCom0MSZA/sJYmps8QZgiPA0k4Z6jTupDymPOIwYeD2C57zSxnAv0AfC3/pZYJ - bZYH/0TszRzmy052DME3zMnhMK0ikdN4nzYqU0dkkA5kb5GtKDymspHIJ9eWbUuw - gtg8Rq/LrVBj1I3UFgs0ibio40k6gqinLKslc5Y1I5mro7J3OSEP5eO/XeDLOLlO - JjEqkrx4fviI1cL3m5L6QV905xmcoNZG1+RmOg7D7cZQUf27TXqM381jkbNdktm1 - JLTcMScxuo3vaRftnIVw70V8P8sIkaKY8S8HU1sQgE2LB9t04oog5u59htx2FHv4 - B13NEm8tt8Tv1PexpB4UVh7PIualF6SxdFBrKbraYej72wgjXVPQ0eGXtGGD57j8 - DUEzk7DK2OvIWhehlVqtiRnFdAvdBj2ynHT2/5FJ/Zpd4n5dKGJcQvy1U1qWMs+8 - M7AHfWyt2+nZ04s48+bK3yMCAwEAAQ== + MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69 + 80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B + dA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y + +3GyaOY536H47qyXAgMBAAE= -----END PUBLIC KEY-----`, "\t", "", -1) privateKey := strings.Replace(`-----BEGIN RSA PRIVATE KEY----- - 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 -----END RSA PRIVATE KEY-----`, "\t", "", -1) return utils.NewJWT(&models.JWTConfiguration{ PrivateKey: privateKey, PublicKey: publicKey, - Audience: "audience", - Issuer: "issuer", + Audience: "pena", + Issuer: "pena-auth-service", Algorithm: *jwt.SigningMethodRS256, ExpiresIn: 15 * time.Minute, }) diff --git a/tests/integration/set_account_verification_status_test copy.go b/tests/integration/set_account_verification_status_test.go similarity index 100% rename from tests/integration/set_account_verification_status_test copy.go rename to tests/integration/set_account_verification_status_test.go diff --git a/tests/integration/update_account_verification_status_test.go b/tests/integration/update_account_name_test.go similarity index 100% rename from tests/integration/update_account_verification_status_test.go rename to tests/integration/update_account_name_test.go diff --git a/tools/migrate b/tools/migrate new file mode 100644 index 0000000..573af5c Binary files /dev/null and b/tools/migrate differ