treasurer/internal/service/mock/yoomoney.go

116 lines
3.4 KiB
Go

package mock
import (
"fmt"
"net/url"
"gitea.pena/PenaSide/treasurer/internal/errors"
"gitea.pena/PenaSide/treasurer/internal/models/yandex"
"github.com/walkerus/go-wiremock"
"go.uber.org/zap"
)
type YoomoneyMockServiceDeps struct {
Logger *zap.Logger
YooMoneyPaymentsURL string
}
type YoomoneyMockService struct {
logger *zap.Logger
yooMoneyPaymentsURL string
}
func NewYoomoneyMockService(deps YoomoneyMockServiceDeps) (*YoomoneyMockService, errors.Error) {
if deps.Logger == nil {
return nil, errors.NewWithMessage("logger is nil on <NewYoomoneyMockService>", errors.ErrInvalidArgs)
}
return &YoomoneyMockService{
logger: deps.Logger,
yooMoneyPaymentsURL: deps.YooMoneyPaymentsURL,
}, nil
}
func (s *YoomoneyMockService) Register(host string) errors.Error {
return s.RegisterPayments(host)
}
func (s *YoomoneyMockService) RegisterPayments(host string) errors.Error {
paymentsURL, parseErr := url.Parse(s.yooMoneyPaymentsURL)
if parseErr != nil {
s.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
zap.Error(parseErr),
zap.String("url", s.yooMoneyPaymentsURL),
)
return errors.NewWithError(fmt.Errorf("failed to parse payment url: %w", parseErr), errors.ErrInternalError)
}
hostURL, parseErr := url.Parse(host)
if parseErr != nil {
s.logger.Error("failed to parse payment url on <RegisterPayment> of <YoomoneyMockService>",
zap.Error(parseErr),
zap.String("url", s.yooMoneyPaymentsURL),
)
return errors.NewWithError(fmt.Errorf("failed to parse payment url: %w", parseErr), errors.ErrInternalError)
}
if hostURL.Host != paymentsURL.Host {
return errors.NewWithMessage("yoomoney hosts not equal", errors.ErrInternalError)
}
if hostURL.Scheme != paymentsURL.Scheme {
return errors.NewWithMessage("yoomoney scheme not equal", errors.ErrInternalError)
}
mockClient := wiremock.NewClient(host)
rule := wiremock.
Post(wiremock.URLPathEqualTo(paymentsURL.Path)).
WillReturnJSON(
&yandex.Payment{
ID: "f32d71f4-214b-464b-94bb-f7b4d5299af0",
Status: yandex.PaymentStatusPending,
Amount: yandex.Amount{
Value: "150.00",
Currency: "RUB",
},
Confirmation: &yandex.ConfirmationRedirect{
Type: yandex.ConfirmationTypeRedirect,
ConfirmationURL: "https://yandex-redirect-url.com",
},
},
map[string]string{"Content-Type": "application/json"},
200,
).
AtPriority(1)
if err := mockClient.StubFor(rule); err != nil {
s.logger.Error("failed to init payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
zap.Error(err),
zap.String("payments full url", s.yooMoneyPaymentsURL),
zap.String("payments path", paymentsURL.Path),
)
return errors.NewWithError(fmt.Errorf("failed to init payment mock handler: %w", err), errors.ErrInternalError)
}
isVerified, err := mockClient.Verify(wiremock.NewRequest("post", wiremock.URLPathEqualTo(paymentsURL.Path)), 0)
if err != nil {
s.logger.Error("failed to verify payment mock handler on <RegisterPayment> of <YoomoneyMockService>",
zap.Error(err),
zap.String("payments full url", s.yooMoneyPaymentsURL),
zap.String("payments path", paymentsURL.Path),
)
return errors.NewWithError(fmt.Errorf("failed to verify payment mock handler: %w", err), errors.ErrInternalError)
}
if !isVerified {
return errors.NewWithMessage("payment mock handler not verified", errors.ErrInternalError)
}
return nil
}