[3rdparty][messages] skip phone validation option

This commit is contained in:
Aleksandr Soloshenko 2024-02-11 20:55:51 +07:00
parent 3f359b010a
commit bca16d8d71
8 changed files with 81 additions and 12 deletions

View File

@ -3,7 +3,7 @@
@phone={{$dotenv PHONE}}
###
POST {{localUrl}}/message HTTP/1.1
POST {{localUrl}}/message?skipPhoneValidation=true HTTP/1.1
Content-Type: application/json
Authorization: Basic {{localCredentials}}

View File

@ -13,7 +13,7 @@ Content-Type: application/json
}
###
POST {{baseUrl}}/api/3rdparty/v1/message HTTP/1.1
POST {{baseUrl}}/api/3rdparty/v1/message?skipPhoneValidation=false HTTP/1.1
Content-Type: application/json
Authorization: Basic {{credentials}}

View File

@ -86,6 +86,12 @@
],
"summary": "Поставить сообщение в очередь",
"parameters": [
{
"type": "boolean",
"description": "Пропустить проверку номеров телефона",
"name": "skipPhoneValidation",
"in": "query"
},
{
"description": "Сообщение",
"name": "request",

View File

@ -219,6 +219,10 @@ paths:
description: Ставит сообщение в очередь на отправку. Если идентификатор не указан,
то он будет сгенерирован автоматически
parameters:
- description: Пропустить проверку номеров телефона
in: query
name: skipPhoneValidation
type: boolean
- description: Сообщение
in: body
name: request

View File

@ -30,12 +30,13 @@ type thirdPartyHandler struct {
// @Tags Пользователь, Сообщения
// @Accept json
// @Produce json
// @Param request body smsgateway.Message true "Сообщение"
// @Success 202 {object} smsgateway.MessageState "Сообщение поставлено в очередь"
// @Failure 401 {object} smsgateway.ErrorResponse "Ошибка авторизации"
// @Failure 400 {object} smsgateway.ErrorResponse "Некорректный запрос"
// @Failure 500 {object} smsgateway.ErrorResponse "Внутренняя ошибка сервера"
// @Header 202 {string} Location "URL для получения состояния сообщения"
// @Param skipPhoneValidation query bool false "Пропустить проверку номеров телефона"
// @Param request body smsgateway.Message true "Сообщение"
// @Success 202 {object} smsgateway.MessageState "Сообщение поставлено в очередь"
// @Failure 401 {object} smsgateway.ErrorResponse "Ошибка авторизации"
// @Failure 400 {object} smsgateway.ErrorResponse "Некорректный запрос"
// @Failure 500 {object} smsgateway.ErrorResponse "Внутренняя ошибка сервера"
// @Header 202 {string} Location "URL для получения состояния сообщения"
// @Router /3rdparty/v1/message [post]
//
// Поставить сообщение в очередь
@ -45,12 +46,14 @@ func (h *thirdPartyHandler) postMessage(user models.User, c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
skipPhoneValidation := c.QueryBool("skipPhoneValidation", false)
if len(user.Devices) < 1 {
return fiber.NewError(fiber.StatusBadRequest, "Нет ни одного устройства в учетной записи")
}
device := user.Devices[0]
state, err := h.messagesSvc.Enqeue(device, req)
state, err := h.messagesSvc.Enqeue(device, req, services.MessagesEnqueueOptions{SkipPhoneValidation: skipPhoneValidation})
if err != nil {
var err400 services.ErrValidation
if errors.As(err, &err400) {

View File

@ -50,7 +50,7 @@ func (r *MessagesRepository) Get(ID string, filter MessagesSelectFilter, options
}
func (r *MessagesRepository) Insert(message *models.Message) error {
return r.db.Create(message).Error
return r.db.Omit("Device").Create(message).Error
}
func (r *MessagesRepository) UpdateState(message *models.Message) error {

View File

@ -27,6 +27,10 @@ func (e ErrValidation) Error() string {
return string(e)
}
type MessagesEnqueueOptions struct {
SkipPhoneValidation bool
}
type MessagesServiceParams struct {
fx.In
@ -119,7 +123,7 @@ func (s *MessagesService) GetState(user models.User, ID string) (smsgateway.Mess
return modelToMessageState(message), nil
}
func (s *MessagesService) Enqeue(device models.Device, message smsgateway.Message) (smsgateway.MessageState, error) {
func (s *MessagesService) Enqeue(device models.Device, message smsgateway.Message, opts MessagesEnqueueOptions) (smsgateway.MessageState, error) {
state := smsgateway.MessageState{
ID: "",
State: smsgateway.MessageStatePending,
@ -129,7 +133,7 @@ func (s *MessagesService) Enqeue(device models.Device, message smsgateway.Messag
var phone string
var err error
for i, v := range message.PhoneNumbers {
if message.IsEncrypted {
if message.IsEncrypted || opts.SkipPhoneValidation {
phone = v
} else {
if phone, err = cleanPhoneNumber(v); err != nil {

View File

@ -105,3 +105,55 @@ func TestMessagesService_recipientsStateToModel(t *testing.T) {
})
}
}
func TestCleanPhoneNumber(t *testing.T) {
tests := []struct {
name string
input string
expected string
expectError bool
}{
{
name: "Valid number with validation",
input: "+79161234567",
expected: "+79161234567",
expectError: false,
},
{
name: "Invalid number with validation",
input: "+123!@#",
expected: "",
expectError: true,
},
{
name: "Empty input with validation",
input: "",
expected: "",
expectError: true,
},
{
name: "Long number with validation",
input: "+345906566798696",
expected: "",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := cleanPhoneNumber(tt.input)
if tt.expectError {
if err == nil {
t.Errorf("Expected error, got nil")
}
} else {
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if result != tt.expected {
t.Errorf("Expected %s, got %s", tt.expected, result)
}
}
})
}
}