forked from ebhomengo/niki
				
			feat(niki): add test for add benefactor kind_box_req
This commit is contained in:
		
							parent
							
								
									748dee60e2
								
							
						
					
					
						commit
						58c48dfccc
					
				| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
debug: false
 | 
			
		||||
multi_word_var: "I'm complex in config.yml"
 | 
			
		||||
db:
 | 
			
		||||
  host: "localhost"
 | 
			
		||||
  username: "ali"
 | 
			
		||||
  password: "passwd"
 | 
			
		||||
  multi_word_nested_var: "WHAT??"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,28 +1,36 @@
 | 
			
		|||
package benefactorkindboxreqhandler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/pkg/claim"
 | 
			
		||||
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
 | 
			
		||||
	httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
 | 
			
		||||
	echo "github.com/labstack/echo/v4"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (h Handler) Add(c echo.Context) error {
 | 
			
		||||
	req := param.KindBoxReqAddRequest{}
 | 
			
		||||
	if bErr := c.Bind(&req); bErr != nil {
 | 
			
		||||
		return echo.NewHTTPError(http.StatusBadRequest)
 | 
			
		||||
	if err := c.Bind(&req); err != nil {
 | 
			
		||||
		fmt.Println("err", err, req)
 | 
			
		||||
 | 
			
		||||
		return c.JSON(http.StatusBadRequest, echo.Map{
 | 
			
		||||
			"message": errmsg.ErrBadRequest,
 | 
			
		||||
		})
 | 
			
		||||
		// TODO: return echo.NewHTTPError(http.StatusBadRequest, errmsg.ErrBadRequest) ؟؟؟
 | 
			
		||||
	}
 | 
			
		||||
	claims := claim.GetClaimsFromEchoContext(c)
 | 
			
		||||
	req.BenefactorID = claims.UserID
 | 
			
		||||
 | 
			
		||||
	if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateAddRequest(req); err != nil {
 | 
			
		||||
		msg, code := httpmsg.Error(err)
 | 
			
		||||
	result := h.benefactorKindBoxReqVld.ValidateAddRequest(req)
 | 
			
		||||
	if result != nil {
 | 
			
		||||
		msg, code := httpmsg.Error(result.Err)
 | 
			
		||||
 | 
			
		||||
		return c.JSON(code, echo.Map{
 | 
			
		||||
			"message": msg,
 | 
			
		||||
			"errors":  fieldErrors,
 | 
			
		||||
			"errors":  result.Fields,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	resp, sErr := h.benefactorKindBoxReqSvc.Add(c.Request().Context(), req)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
package benefactorkindboxreqhandler_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httptest"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	benefactoreparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
 | 
			
		||||
	benefactorkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
	testutils "git.gocasts.ir/ebhomengo/niki/test"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/test/seed"
 | 
			
		||||
	"github.com/brianvoe/gofakeit/v6"
 | 
			
		||||
	"github.com/labstack/echo/v4"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestAdd(t *testing.T) {
 | 
			
		||||
	testutils.SetupEnd2EndTest(t)
 | 
			
		||||
	respSendOTP := testutils.SendOTP(t)
 | 
			
		||||
 | 
			
		||||
	loginOrRegisterRequest := benefactoreparam.LoginOrRegisterRequest{
 | 
			
		||||
		PhoneNumber:      respSendOTP.PhoneNumber,
 | 
			
		||||
		VerificationCode: respSendOTP.Code,
 | 
			
		||||
	}
 | 
			
		||||
	benefactor, cleanupBenefactor := testutils.CreateBenefactorWithSvc(t, loginOrRegisterRequest)
 | 
			
		||||
	defer cleanupBenefactor()
 | 
			
		||||
	benefactorAddAddressRequest := addressparam.BenefactorAddAddressRequest{
 | 
			
		||||
		PostalCode:   gofakeit.Address().Zip,
 | 
			
		||||
		Address:      gofakeit.Address().Address,
 | 
			
		||||
		Lat:          float32(gofakeit.Address().Latitude),
 | 
			
		||||
		Lon:          float32(gofakeit.Address().Longitude),
 | 
			
		||||
		CityID:       gofakeit.UintRange(1, 100),
 | 
			
		||||
		ProvinceID:   gofakeit.UintRange(1, 31),
 | 
			
		||||
		BenefactorID: benefactor.BenefactorInfo.ID,
 | 
			
		||||
	}
 | 
			
		||||
	address, cleanupAddress := testutils.CreateAddressWithSvc(t, benefactorAddAddressRequest)
 | 
			
		||||
	defer cleanupAddress()
 | 
			
		||||
	kindboxreqResponse, _ := json.Marshal(entity.KindBoxReq{
 | 
			
		||||
		ID:             1,
 | 
			
		||||
		KindBoxType:    entity.KindBoxCylindrical,
 | 
			
		||||
		CountRequested: gofakeit.UintRange(1, 100),
 | 
			
		||||
		CountAccepted:  0,
 | 
			
		||||
		BenefactorID:   benefactor.BenefactorInfo.ID,
 | 
			
		||||
		Status:         entity.KindBoxReqPendingStatus,
 | 
			
		||||
		Description:    "",
 | 
			
		||||
		ReferDate:      time.Time{},
 | 
			
		||||
		AddressID:      address.Address.ID,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	type testCase struct {
 | 
			
		||||
		name           string
 | 
			
		||||
		requestBody    interface{}
 | 
			
		||||
		expectedStatus int
 | 
			
		||||
		expectedBody   string
 | 
			
		||||
		err            bool
 | 
			
		||||
		token          string
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	testCases := []testCase{
 | 
			
		||||
		{
 | 
			
		||||
			name:           "invalid payload",
 | 
			
		||||
			requestBody:    `invalid payload`,
 | 
			
		||||
			expectedStatus: http.StatusBadRequest,
 | 
			
		||||
			expectedBody:   `{"message": "Bad request"}`,
 | 
			
		||||
			err:            true,
 | 
			
		||||
			token:          "Bearer " + benefactor.Tokens.AccessToken,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "invalid or expired jwt",
 | 
			
		||||
			requestBody: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				AddressID:      address.Address.ID,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
			},
 | 
			
		||||
			token:          "Bearer 12" + benefactor.Tokens.AccessToken,
 | 
			
		||||
			expectedStatus: http.StatusUnauthorized,
 | 
			
		||||
			err:            true,
 | 
			
		||||
			expectedBody:   `{"message":"invalid or expired jwt"}`,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Validation Failed",
 | 
			
		||||
			requestBody: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      address.Address.ID,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
				CountRequested: 2,
 | 
			
		||||
			},
 | 
			
		||||
			err:            true,
 | 
			
		||||
			token:          "Bearer " + benefactor.Tokens.AccessToken,
 | 
			
		||||
			expectedStatus: http.StatusUnprocessableEntity,
 | 
			
		||||
			expectedBody: `{
 | 
			
		||||
				"errors":{
 | 
			
		||||
					"type_id":"cannot be blank"
 | 
			
		||||
				},
 | 
			
		||||
				"message":"invalid input"
 | 
			
		||||
			}`,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Added successfully",
 | 
			
		||||
			requestBody: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				TypeID:         2,
 | 
			
		||||
				AddressID:      address.Address.ID,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
				CountRequested: 2,
 | 
			
		||||
			},
 | 
			
		||||
			token:          "Bearer " + benefactor.Tokens.AccessToken,
 | 
			
		||||
			expectedStatus: http.StatusCreated,
 | 
			
		||||
			expectedBody:   string(kindboxreqResponse),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	e := echo.New()
 | 
			
		||||
	r := e.Group("/benefactor/kindboxreqs")
 | 
			
		||||
 | 
			
		||||
	r.POST("/", testutils.BenefactorkindBoxReqHandler.Add, middleware.Auth(testutils.AuthSvc, testutils.AuthConfig),
 | 
			
		||||
		middleware.BenefactorAuthorization(entity.UserBenefactorRole))
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			requestBody, _ := json.Marshal(tc.requestBody)
 | 
			
		||||
			req := httptest.NewRequest(http.MethodPost, "/benefactor/kindboxreqs/", bytes.NewBuffer(requestBody))
 | 
			
		||||
 | 
			
		||||
			req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
 | 
			
		||||
			req.Header.Set(echo.HeaderAuthorization, tc.token)
 | 
			
		||||
 | 
			
		||||
			rec := httptest.NewRecorder()
 | 
			
		||||
 | 
			
		||||
			e.ServeHTTP(rec, req)
 | 
			
		||||
 | 
			
		||||
			// Assertion
 | 
			
		||||
			assert.Equal(t, tc.expectedStatus, rec.Code)
 | 
			
		||||
 | 
			
		||||
			if tc.err {
 | 
			
		||||
				assert.JSONEq(t, tc.expectedBody, rec.Body.String())
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			response := &benefactorkindboxreqparam.KindBoxReqAddResponse{}
 | 
			
		||||
			err := json.Unmarshal(
 | 
			
		||||
				rec.Body.Bytes(),
 | 
			
		||||
				response,
 | 
			
		||||
			)
 | 
			
		||||
			assert.Nil(t, err, "error in deserializing the request")
 | 
			
		||||
			seed.DeleteBenefactor(t, testutils.MysqlRepo, response.KindBoxReq.ID)
 | 
			
		||||
			assert.NotEmpty(t, response.KindBoxReq)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
version: '3.9'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  mysqltest:
 | 
			
		||||
    image: mysql:8.0
 | 
			
		||||
    ports:
 | 
			
		||||
      - "3305:3306"
 | 
			
		||||
    container_name: niki-database-test
 | 
			
		||||
    volumes:
 | 
			
		||||
      - dbdatatest:/var/lib/mysql
 | 
			
		||||
    restart: always
 | 
			
		||||
    command: [ 'mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci' ]
 | 
			
		||||
    environment:
 | 
			
		||||
      MYSQL_ROOT_PASSWORD: 123456
 | 
			
		||||
      MYSQL_DATABASE: test_db
 | 
			
		||||
      MYSQL_USER: testuser
 | 
			
		||||
      MYSQL_PASSWORD: test1234
 | 
			
		||||
 | 
			
		||||
  niki-redis-test:
 | 
			
		||||
    image: bitnami/redis:6.2
 | 
			
		||||
    container_name: niki-redis-test
 | 
			
		||||
    restart: always
 | 
			
		||||
    ports:
 | 
			
		||||
      - '6381:6379'
 | 
			
		||||
    # TODO - remove `--save "" --appendonly no` from command to persist data
 | 
			
		||||
    command: redis-server --loglevel warning --protected-mode no --save "" --appendonly no
 | 
			
		||||
    environment:
 | 
			
		||||
      - ALLOW_EMPTY_PASSWORD=yes
 | 
			
		||||
    volumes:
 | 
			
		||||
      - niki-redis-data-test:/data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  dbdatatest:
 | 
			
		||||
  niki-redis-data-test:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#    docker-compose -f docker-compose.dev.yaml up -d
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
version: '3.9'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  mysql:
 | 
			
		||||
    platform: linux/amd64
 | 
			
		||||
    image: mysql:8.0
 | 
			
		||||
    ports:
 | 
			
		||||
      - 3305:3305
 | 
			
		||||
    volumes:
 | 
			
		||||
      - ~/apps/mysql:/var/lib/mysql
 | 
			
		||||
    restart: always
 | 
			
		||||
    hostname: mysql
 | 
			
		||||
    container_name: niki_mysql
 | 
			
		||||
    environment:
 | 
			
		||||
      - MYSQL_ROOT_PASSWORD=root
 | 
			
		||||
      - MYSQL_USER=niki_user
 | 
			
		||||
      - MYSQL_PASSWORD=NIKI_user@123
 | 
			
		||||
      - MYSQL_DATABASE=niki_db
 | 
			
		||||
 | 
			
		||||
  niki-redis:
 | 
			
		||||
    image: bitnami/redis:6.2
 | 
			
		||||
    container_name: niki-redis
 | 
			
		||||
    restart: always
 | 
			
		||||
    ports:
 | 
			
		||||
      - '6380:6379'
 | 
			
		||||
    # TODO - remove `--save "" --appendonly no` from command to persist data
 | 
			
		||||
    command: redis-server --loglevel warning --protected-mode no --save "" --appendonly no
 | 
			
		||||
    environment:
 | 
			
		||||
      - ALLOW_EMPTY_PASSWORD=yes
 | 
			
		||||
    volumes:
 | 
			
		||||
      - niki-redis-data:/data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  dbdata:
 | 
			
		||||
  niki-redis-data:
 | 
			
		||||
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -3,6 +3,7 @@ module git.gocasts.ir/ebhomengo/niki
 | 
			
		|||
go 1.21.3
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/brianvoe/gofakeit/v6 v6.28.0
 | 
			
		||||
	github.com/go-ozzo/ozzo-validation v3.6.0+incompatible
 | 
			
		||||
	github.com/go-ozzo/ozzo-validation/v4 v4.3.0
 | 
			
		||||
	github.com/go-sql-driver/mysql v1.6.0
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ require (
 | 
			
		|||
	github.com/oklog/ulid/v2 v2.1.0
 | 
			
		||||
	github.com/redis/go-redis/v9 v9.4.0
 | 
			
		||||
	github.com/rubenv/sql-migrate v1.6.0
 | 
			
		||||
	github.com/stretchr/testify v1.8.4
 | 
			
		||||
	golang.org/x/crypto v0.17.0
 | 
			
		||||
	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +23,7 @@ require (
 | 
			
		|||
require (
 | 
			
		||||
	github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect
 | 
			
		||||
	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 | 
			
		||||
	github.com/davecgh/go-spew v1.1.1 // indirect
 | 
			
		||||
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 | 
			
		||||
	github.com/fatih/structs v1.1.0 // indirect
 | 
			
		||||
	github.com/fsnotify/fsnotify v1.7.0 // indirect
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +36,7 @@ require (
 | 
			
		|||
	github.com/mitchellh/copystructure v1.2.0 // indirect
 | 
			
		||||
	github.com/mitchellh/mapstructure v1.5.0 // indirect
 | 
			
		||||
	github.com/mitchellh/reflectwalk v1.0.2 // indirect
 | 
			
		||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/bytebufferpool v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/fasttemplate v1.2.2 // indirect
 | 
			
		||||
	golang.org/x/net v0.19.0 // indirect
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -27,6 +27,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
 | 
			
		|||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 | 
			
		||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 | 
			
		||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 | 
			
		||||
github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4=
 | 
			
		||||
github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs=
 | 
			
		||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
 | 
			
		||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 | 
			
		||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@ import (
 | 
			
		|||
	"git.gocasts.ir/ebhomengo/niki/adapter/redis"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/config"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
 | 
			
		||||
	mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
 | 
			
		||||
	adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
 | 
			
		||||
	adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
 | 
			
		||||
	benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +33,6 @@ func InitBenefactorValidator() benefactorvalidator.Validator {
 | 
			
		|||
 | 
			
		||||
func InitBenefactorKindBoxReqValidator(cfg config.Config, redisAdapter redis.Adapter, db *mysql.DB) benefactorkindboxreqvalidator.Validator {
 | 
			
		||||
	return benefactorkindboxreqvalidator.New(
 | 
			
		||||
		mysqlkindboxreq.New(db),
 | 
			
		||||
		InitBenefactorService(cfg, redisAdapter, db),
 | 
			
		||||
		InitBenefactorAddressService(db),
 | 
			
		||||
	)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
package benefactorkindboxreqparam
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	entity "git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +10,7 @@ type KindBoxReqAddRequest struct {
 | 
			
		|||
	BenefactorID   uint               `json:"benefactor_id"`
 | 
			
		||||
	TypeID         entity.KindBoxType `json:"type_id"`
 | 
			
		||||
	AddressID      uint               `json:"address_id"`
 | 
			
		||||
	ReferDate      string             `json:"refer_date"`
 | 
			
		||||
	ReferDate      time.Time          `json:"refer_date"`
 | 
			
		||||
	CountRequested uint               `json:"count_requested"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ const (
 | 
			
		|||
	ErrorMsgOtpCodeIsNotValid            = "verification code is not valid"
 | 
			
		||||
	ErrorMsgCantScanQueryResult          = "can't scan query result"
 | 
			
		||||
	ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect"
 | 
			
		||||
	ErrBadRequest                        = "Bad request"
 | 
			
		||||
	ErrorMsgAcceptKindBoxReqStatus       = "only pending requests will have the ability to be confirmed"
 | 
			
		||||
	ErrorMsgRejectKindBoxReqStatus       = "only pending requests will have the ability to be rejected"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
package mysqlkindboxreq_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
 | 
			
		||||
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
 | 
			
		||||
	mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
 | 
			
		||||
	testutils "git.gocasts.ir/ebhomengo/niki/test"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/test/seed"
 | 
			
		||||
	"github.com/brianvoe/gofakeit/v6"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestAddKindBoxReq(t *testing.T) {
 | 
			
		||||
	mysqlRepo := testutils.Setup(t)
 | 
			
		||||
	mysqlKindboxReq := mysqlkindboxreq.New(mysqlRepo)
 | 
			
		||||
 | 
			
		||||
	benefactor, cleanupBenefactor := seed.CreateBenefactor(t, mysqlRepo)
 | 
			
		||||
	defer cleanupBenefactor()
 | 
			
		||||
	address, cleanupAddress := seed.CreateAddress(t, mysqlRepo, benefactor.ID)
 | 
			
		||||
	defer cleanupAddress()
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		repoErr     bool
 | 
			
		||||
		expectedErr error
 | 
			
		||||
		kindBoxReq  entity.KindBoxReq
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:        "repo fails",
 | 
			
		||||
			repoErr:     true,
 | 
			
		||||
			expectedErr: richerror.New("mysqlkindboxreq.AddKindBoxReq").WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindUnexpected),
 | 
			
		||||
			kindBoxReq: entity.KindBoxReq{
 | 
			
		||||
				KindBoxType:    entity.KindBoxStandUp,
 | 
			
		||||
				AddressID:      address.ID,
 | 
			
		||||
				CountRequested: gofakeit.UintRange(1, 100),
 | 
			
		||||
				ReferDate:      gofakeit.Date(),
 | 
			
		||||
				Status:         entity.KindBoxReqPendingStatus,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "ordinary",
 | 
			
		||||
			kindBoxReq: entity.KindBoxReq{
 | 
			
		||||
				BenefactorID:   benefactor.ID,
 | 
			
		||||
				KindBoxType:    entity.KindBoxStandUp,
 | 
			
		||||
				AddressID:      address.ID,
 | 
			
		||||
				CountRequested: gofakeit.UintRange(1, 100),
 | 
			
		||||
				ReferDate:      gofakeit.Date(),
 | 
			
		||||
				Status:         entity.KindBoxReqPendingStatus,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			ctx := context.Background()
 | 
			
		||||
			kindBoxReq, err := mysqlKindboxReq.AddKindBoxReq(ctx, tc.kindBoxReq)
 | 
			
		||||
 | 
			
		||||
			if tc.expectedErr != nil {
 | 
			
		||||
				assert.Equal(t, tc.expectedErr.Error(), err.Error())
 | 
			
		||||
				assert.Empty(t, kindBoxReq)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			assert.NoError(t, err)
 | 
			
		||||
			assert.NotEmpty(t, kindBoxReq)
 | 
			
		||||
			seed.DeleteBenefactor(t, mysqlRepo, kindBoxReq.ID)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ package benefactorkindboxreqservice
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	entity "git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
| 
						 | 
				
			
			@ -11,15 +10,11 @@ import (
 | 
			
		|||
 | 
			
		||||
func (s Service) Add(ctx context.Context, req param.KindBoxReqAddRequest) (param.KindBoxReqAddResponse, error) {
 | 
			
		||||
	const op = "userkindboxreqservice.Add"
 | 
			
		||||
	t, tErr := time.Parse(time.DateTime, req.ReferDate)
 | 
			
		||||
	if tErr != nil {
 | 
			
		||||
		return param.KindBoxReqAddResponse{}, richerror.New(op).WithErr(tErr).WithKind(richerror.KindInvalid)
 | 
			
		||||
	}
 | 
			
		||||
	kindBoxReq, err := s.repo.AddKindBoxReq(ctx, entity.KindBoxReq{
 | 
			
		||||
		BenefactorID:   req.BenefactorID,
 | 
			
		||||
		KindBoxType:    req.TypeID,
 | 
			
		||||
		AddressID:      req.AddressID,
 | 
			
		||||
		ReferDate:      t,
 | 
			
		||||
		ReferDate:      req.ReferDate,
 | 
			
		||||
		CountRequested: req.CountRequested,
 | 
			
		||||
		Status:         entity.KindBoxReqPendingStatus,
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
package benefactorkindboxreqservice_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	benefactorkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
 | 
			
		||||
	benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/test/mock"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestAdd(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name        string
 | 
			
		||||
		repoErr     bool
 | 
			
		||||
		expectedErr error
 | 
			
		||||
		req         benefactorkindboxreqparam.KindBoxReqAddRequest
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:        "repo fails",
 | 
			
		||||
			repoErr:     true,
 | 
			
		||||
			expectedErr: richerror.New("userkindboxreqservice.Add").WithErr(fmt.Errorf(benefactorkindboxreqmock.RepoErr)).WithKind(richerror.KindUnexpected),
 | 
			
		||||
			req: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "ordinary",
 | 
			
		||||
			req: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			repo := benefactorkindboxreqmock.NewMockRepository(tc.repoErr)
 | 
			
		||||
			svc := benefactorkindboxreqservice.New(repo)
 | 
			
		||||
			ctx := context.Background()
 | 
			
		||||
 | 
			
		||||
			kindBoxreq, err := svc.Add(ctx, tc.req)
 | 
			
		||||
 | 
			
		||||
			if tc.expectedErr != nil {
 | 
			
		||||
				assert.Equal(t, tc.expectedErr.Error(), err.Error())
 | 
			
		||||
				assert.Empty(t, kindBoxreq)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			assert.NoError(t, err)
 | 
			
		||||
			assert.NotEmpty(t, kindBoxreq)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
package testutils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/repository/migrator"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
 | 
			
		||||
 | 
			
		||||
	//nolint
 | 
			
		||||
	_ "github.com/go-sql-driver/mysql"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var once = sync.Once{}
 | 
			
		||||
 | 
			
		||||
const port = 3305
 | 
			
		||||
 | 
			
		||||
func MySQLTestConfig() mysql.Config {
 | 
			
		||||
	return mysql.Config{
 | 
			
		||||
		Username: "testuser",
 | 
			
		||||
		Password: "test1234",
 | 
			
		||||
		Port:     port,
 | 
			
		||||
		Host:     "localhost",
 | 
			
		||||
		DBName:   "test_db",
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Setup(t *testing.T) *mysql.DB {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	// connect to mysql database
 | 
			
		||||
	config := MySQLTestConfig()
 | 
			
		||||
	once.Do(func() {
 | 
			
		||||
		mgr := migrator.New(config)
 | 
			
		||||
		mgr.Up()
 | 
			
		||||
	})
 | 
			
		||||
	mysqlRepo := mysql.New(config)
 | 
			
		||||
 | 
			
		||||
	return mysqlRepo
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
package testutils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	smsprovider "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar"
 | 
			
		||||
	kavenegarotp "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar/otp"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/config"
 | 
			
		||||
	benefactorkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box_req"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/internal/initial"
 | 
			
		||||
	addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	benefactoreparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
 | 
			
		||||
	mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
 | 
			
		||||
	mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor"
 | 
			
		||||
	mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
 | 
			
		||||
	redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/redis_otp"
 | 
			
		||||
	authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
 | 
			
		||||
	benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
 | 
			
		||||
	benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
 | 
			
		||||
	benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
 | 
			
		||||
	benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
 | 
			
		||||
	"github.com/brianvoe/gofakeit/v6"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	benefactorSvc               benefactorservice.Service
 | 
			
		||||
	benefactorAddressSvc        benefactoraddressservice.Service
 | 
			
		||||
	BenefactorkindBoxReqHandler benefactorkindboxreqhandler.Handler
 | 
			
		||||
	AuthSvc                     authservice.Service
 | 
			
		||||
	MysqlRepo                   *mysql.DB
 | 
			
		||||
	AuthConfig                  authservice.Config
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func SetupEnd2EndTest(t *testing.T) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	cfg := config.C()
 | 
			
		||||
 | 
			
		||||
	MysqlRepo = Setup(t)
 | 
			
		||||
	redisAdapter := SetupRedis(t)
 | 
			
		||||
 | 
			
		||||
	AuthSvc = initial.InitBenefactorAuthService(cfg)
 | 
			
		||||
 | 
			
		||||
	RedisOtp := redisotp.New(redisAdapter)
 | 
			
		||||
	benefactorMysql := mysqlbenefactor.New(MysqlRepo)
 | 
			
		||||
	kavenegarSmsProvider := smsprovider.New(cfg.KavenegarSmsProvider)
 | 
			
		||||
	otpSmsProvider := kavenegarotp.New(kavenegarSmsProvider)
 | 
			
		||||
	benefactorSvc = benefactorservice.New(cfg.BenefactorSvc, RedisOtp, otpSmsProvider, AuthSvc, benefactorMysql)
 | 
			
		||||
	benefactorAddressMysql := mysqladdress.New(MysqlRepo)
 | 
			
		||||
	benefactorAddressSvc = benefactoraddressservice.New(benefactorAddressMysql)
 | 
			
		||||
	benefactorKindBoxReqMysql := mysqlkindboxreq.New(MysqlRepo)
 | 
			
		||||
	benefactorKindBoxReqSvc := benefactorkindboxreqservice.New(benefactorKindBoxReqMysql)
 | 
			
		||||
	benefactorKindBoxReqVld := benefactorkindboxreqvalidator.New(benefactorSvc, benefactorAddressSvc)
 | 
			
		||||
 | 
			
		||||
	BenefactorkindBoxReqHandler = benefactorkindboxreqhandler.New(cfg.Auth, AuthSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld)
 | 
			
		||||
 | 
			
		||||
	//nolint
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SendOTP(t *testing.T) benefactoreparam.SendOtpResponse {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	req := benefactoreparam.SendOtpRequest{PhoneNumber: gofakeit.Phone()}
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	resp, err := benefactorSvc.SendOtp(ctx, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Logf(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//nolint
 | 
			
		||||
func CreateBenefactorWithSvc(t *testing.T, req benefactoreparam.LoginOrRegisterRequest) (benefactoreparam.LoginOrRegisterResponse, func()) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	resp, err := benefactorSvc.LoginOrRegister(ctx, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Logf(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, func() {
 | 
			
		||||
		_, err := MysqlRepo.Conn().ExecContext(ctx, `delete from benefactors where id=?`,
 | 
			
		||||
			resp.BenefactorInfo.ID)
 | 
			
		||||
		assert.Nil(t, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//nolint
 | 
			
		||||
func CreateAddressWithSvc(t *testing.T, req addressparam.BenefactorAddAddressRequest) (addressparam.BenefactorAddAddressResponse, func()) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	resp, err := benefactorAddressSvc.Add(ctx, req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Logf(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return resp, func() {
 | 
			
		||||
		_, err := MysqlRepo.Conn().ExecContext(ctx, `delete from addresses where id=?`,
 | 
			
		||||
			resp.Address.ID)
 | 
			
		||||
		assert.Nil(t, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
package benefactorkindboxreqmock
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const RepoErr = "repository error"
 | 
			
		||||
 | 
			
		||||
type DefaultKindBoxReqTest struct {
 | 
			
		||||
	BenefactorID   uint
 | 
			
		||||
	TypeID         entity.KindBoxType
 | 
			
		||||
	AddressID      uint
 | 
			
		||||
	ReferDate      time.Time
 | 
			
		||||
	CountRequested uint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DefaultKindBoxReq() DefaultKindBoxReqTest {
 | 
			
		||||
	return DefaultKindBoxReqTest{
 | 
			
		||||
		BenefactorID:   1,
 | 
			
		||||
		TypeID:         1,
 | 
			
		||||
		AddressID:      1,
 | 
			
		||||
		ReferDate:      time.Now(),
 | 
			
		||||
		CountRequested: 1,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MockRepository struct {
 | 
			
		||||
	kindBoxReqs []entity.KindBoxReq
 | 
			
		||||
	hasErr      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMockRepository(hasErr bool) *MockRepository {
 | 
			
		||||
	var kindBoxReqs []entity.KindBoxReq
 | 
			
		||||
	DefaultKindBoxReq := DefaultKindBoxReq()
 | 
			
		||||
 | 
			
		||||
	kindBoxReqs = append(kindBoxReqs, entity.KindBoxReq{
 | 
			
		||||
		BenefactorID:   DefaultKindBoxReq.BenefactorID,
 | 
			
		||||
		AddressID:      DefaultKindBoxReq.AddressID,
 | 
			
		||||
		KindBoxType:    DefaultKindBoxReq.TypeID,
 | 
			
		||||
		ReferDate:      DefaultKindBoxReq.ReferDate,
 | 
			
		||||
		CountRequested: DefaultKindBoxReq.CountRequested,
 | 
			
		||||
		Status:         entity.KindBoxReqPendingStatus,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &MockRepository{
 | 
			
		||||
		kindBoxReqs: kindBoxReqs,
 | 
			
		||||
		hasErr:      hasErr,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//nolint
 | 
			
		||||
func (m *MockRepository) AddKindBoxReq(ctx context.Context, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error) {
 | 
			
		||||
	if m.hasErr {
 | 
			
		||||
		return entity.KindBoxReq{}, fmt.Errorf(RepoErr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kindBoxReq.ID = 1
 | 
			
		||||
	m.kindBoxReqs = append(m.kindBoxReqs, kindBoxReq)
 | 
			
		||||
 | 
			
		||||
	return kindBoxReq, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
package testutils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/adapter/redis"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const portRedis = 6381
 | 
			
		||||
 | 
			
		||||
func RedisTestConfig() redis.Config {
 | 
			
		||||
	return redis.Config{
 | 
			
		||||
		Host:     "localhost",
 | 
			
		||||
		Port:     portRedis,
 | 
			
		||||
		Password: "",
 | 
			
		||||
		DB:       0,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetupRedis(t *testing.T) redis.Adapter {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	config := RedisTestConfig()
 | 
			
		||||
	redisAdapter := redis.New(config)
 | 
			
		||||
 | 
			
		||||
	return redisAdapter
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
package seed
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
 | 
			
		||||
	"github.com/brianvoe/gofakeit/v6"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//nolint
 | 
			
		||||
func CreateBenefactor(t *testing.T, db *mysql.DB) (*entity.Benefactor, func()) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	benefactor := &entity.Benefactor{
 | 
			
		||||
		FirstName:   gofakeit.FirstName(),
 | 
			
		||||
		LastName:    gofakeit.LastName(),
 | 
			
		||||
		PhoneNumber: gofakeit.Phone(),
 | 
			
		||||
		Address:     gofakeit.Address().Address,
 | 
			
		||||
		Description: "",
 | 
			
		||||
		Email:       gofakeit.Email(),
 | 
			
		||||
		City:        gofakeit.City(),
 | 
			
		||||
		Gender:      0,
 | 
			
		||||
		Status:      entity.BenefactorActiveStatus,
 | 
			
		||||
		Birthdate:   time.Time{},
 | 
			
		||||
		Role:        entity.UserBenefactorRole,
 | 
			
		||||
	}
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	res, err := db.Conn().ExecContext(ctx, `insert into benefactors(phone_number, status, role) values(?, ?, ?)`,
 | 
			
		||||
		benefactor.PhoneNumber, benefactor.Status.String(), benefactor.Role.String())
 | 
			
		||||
	assert.Nil(t, err)
 | 
			
		||||
	//nolint
 | 
			
		||||
	id, _ := res.LastInsertId()
 | 
			
		||||
	benefactor.ID = uint(id)
 | 
			
		||||
 | 
			
		||||
	return benefactor, func() {
 | 
			
		||||
		_, err := db.Conn().ExecContext(ctx, `delete from benefactors where id=?`,
 | 
			
		||||
			id)
 | 
			
		||||
		assert.Nil(t, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//nolint
 | 
			
		||||
func CreateAddress(t *testing.T, db *mysql.DB, benfactorID uint) (*entity.Address, func()) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	address := &entity.Address{
 | 
			
		||||
		PostalCode: gofakeit.Address().Zip,
 | 
			
		||||
		Address:    gofakeit.Address().Address,
 | 
			
		||||
		Lat:        float32(gofakeit.Address().Latitude),
 | 
			
		||||
		Lon:        float32(gofakeit.Address().Longitude),
 | 
			
		||||
		//nolint
 | 
			
		||||
		CityID: 1,
 | 
			
		||||
		//nolint
 | 
			
		||||
		ProvinceID:   15,
 | 
			
		||||
		BenefactorID: benfactorID,
 | 
			
		||||
	}
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	res, err := db.Conn().ExecContext(ctx, `insert into addresses(postal_code, address, lat, lon,province_id,city_id,benefactor_id) values(?, ?, ?,?,?,?,?)`,
 | 
			
		||||
		address.PostalCode, address.Address, address.Lat, address.Lon, address.ProvinceID, address.CityID, address.BenefactorID)
 | 
			
		||||
	assert.Nil(t, err)
 | 
			
		||||
	//nolint
 | 
			
		||||
	// error is always nil
 | 
			
		||||
	id, _ := res.LastInsertId()
 | 
			
		||||
	address.ID = uint(id)
 | 
			
		||||
 | 
			
		||||
	return address, func() {
 | 
			
		||||
		_, err := db.Conn().ExecContext(ctx, `delete from addresses where id=?`,
 | 
			
		||||
			id)
 | 
			
		||||
		assert.Nil(t, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DeleteBenefactor(t *testing.T, db *mysql.DB, kindBoxReqID uint) {
 | 
			
		||||
	t.Helper()
 | 
			
		||||
	_, mErr := db.Conn().Exec(`delete from kind_box_reqs where id=?`, kindBoxReqID)
 | 
			
		||||
	assert.Nil(t, mErr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,6 @@ package benefactorkindboxreqvalidator
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +9,7 @@ import (
 | 
			
		|||
	validation "github.com/go-ozzo/ozzo-validation/v4"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (v Validator) ValidateAddRequest(req param.KindBoxReqAddRequest) (map[string]string, error) {
 | 
			
		||||
func (v Validator) ValidateAddRequest(req param.KindBoxReqAddRequest) *ValidatorError {
 | 
			
		||||
	const op = "userkindboxreqvalidator.ValidateAddRequest"
 | 
			
		||||
 | 
			
		||||
	if err := validation.ValidateStruct(&req,
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +30,6 @@ func (v Validator) ValidateAddRequest(req param.KindBoxReqAddRequest) (map[strin
 | 
			
		|||
 | 
			
		||||
		validation.Field(&req.ReferDate,
 | 
			
		||||
			validation.Required,
 | 
			
		||||
			validation.Date(time.DateTime),
 | 
			
		||||
		),
 | 
			
		||||
	); err != nil {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,12 +44,16 @@ func (v Validator) ValidateAddRequest(req param.KindBoxReqAddRequest) (map[strin
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return fieldErrors, richerror.New(op).
 | 
			
		||||
			WithMessage(errmsg.ErrorMsgInvalidInput).
 | 
			
		||||
			WithKind(richerror.KindInvalid).
 | 
			
		||||
			WithMeta(map[string]interface{}{"req": req}).
 | 
			
		||||
			WithErr(err)
 | 
			
		||||
		return &ValidatorError{
 | 
			
		||||
			Fields: fieldErrors,
 | 
			
		||||
			Err: richerror.New(op).
 | 
			
		||||
				WithMessage(errmsg.ErrorMsgInvalidInput).
 | 
			
		||||
				WithKind(richerror.KindInvalid).
 | 
			
		||||
				WithMeta(map[string]interface{}{"req": req}).
 | 
			
		||||
				WithErr(err),
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return map[string]string{}, nil
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,214 @@
 | 
			
		|||
package benefactorkindboxreqvalidator_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/entity"
 | 
			
		||||
	addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
 | 
			
		||||
	benefactorkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
 | 
			
		||||
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
 | 
			
		||||
	benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const RepoErr = "repository error"
 | 
			
		||||
 | 
			
		||||
type StubService struct {
 | 
			
		||||
	addresses   []entity.Address
 | 
			
		||||
	benefactors []entity.Benefactor
 | 
			
		||||
	haveError   bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMock(haveError bool) *StubService {
 | 
			
		||||
	var addresses []entity.Address
 | 
			
		||||
	var benefactors []entity.Benefactor
 | 
			
		||||
 | 
			
		||||
	addresses = append(addresses, entity.Address{
 | 
			
		||||
		ID:           1,
 | 
			
		||||
		PostalCode:   "123456789",
 | 
			
		||||
		Address:      "tehran",
 | 
			
		||||
		Lat:          25.25,
 | 
			
		||||
		Lon:          25.26,
 | 
			
		||||
		CityID:       1,
 | 
			
		||||
		ProvinceID:   1,
 | 
			
		||||
		BenefactorID: 1,
 | 
			
		||||
	})
 | 
			
		||||
	benefactors = append(benefactors, entity.Benefactor{
 | 
			
		||||
		ID:          1,
 | 
			
		||||
		FirstName:   "mehdi",
 | 
			
		||||
		LastName:    "rez",
 | 
			
		||||
		PhoneNumber: "09191234556",
 | 
			
		||||
		Address:     "tehran",
 | 
			
		||||
		Description: "",
 | 
			
		||||
		Email:       "example@gmail.com",
 | 
			
		||||
		City:        "teran",
 | 
			
		||||
		Gender:      0,
 | 
			
		||||
		Status:      0,
 | 
			
		||||
		Birthdate:   time.Time{},
 | 
			
		||||
		Role:        1,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return &StubService{
 | 
			
		||||
		addresses:   addresses,
 | 
			
		||||
		benefactors: benefactors,
 | 
			
		||||
		haveError:   haveError,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s StubService) BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error) {
 | 
			
		||||
	if s.haveError {
 | 
			
		||||
		// error response
 | 
			
		||||
		return param.BenefactorExistByIDResponse{Existed: false}, fmt.Errorf(RepoErr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, benefactor := range s.benefactors {
 | 
			
		||||
		if benefactor.ID == request.ID {
 | 
			
		||||
			return param.BenefactorExistByIDResponse{Existed: true}, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return param.BenefactorExistByIDResponse{Existed: false}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s StubService) AddressExistByID(ctx context.Context, request addressparam.GetAddressByIDRequest) (addressparam.GetAddressByIDResponse, error) {
 | 
			
		||||
	if s.haveError {
 | 
			
		||||
		// error response
 | 
			
		||||
		return addressparam.GetAddressByIDResponse{Address: nil}, fmt.Errorf(RepoErr)
 | 
			
		||||
	}
 | 
			
		||||
	for _, address := range s.addresses {
 | 
			
		||||
		if address.ID == request.ID {
 | 
			
		||||
			return addressparam.GetAddressByIDResponse{Address: &address}, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return addressparam.GetAddressByIDResponse{Address: nil}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestValidateAddRequest(t *testing.T) {
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name    string
 | 
			
		||||
		params  benefactorkindboxreqparam.KindBoxReqAddRequest
 | 
			
		||||
		repoErr bool
 | 
			
		||||
		error   error
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "ordinary add",
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				CountRequested: 2,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:    "repo error",
 | 
			
		||||
			repoErr: true,
 | 
			
		||||
			error:   fmt.Errorf("benefactor_id: record not found\naddress_id: something went wrong\n"),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "Count Requested cannot be empty",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("count_requested: cannot be blank\n")),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				CountRequested: 0,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "TypeID cannot be empty",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("type_id: cannot be blank\n")),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				TypeID:         0,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "type with ID does exists",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("type_id: %s\n", errmsg.ErrorMsgNotFound)),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				TypeID:         5,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "AddressID cannot be empty",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("address_id: cannot be blank\n")),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      0,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "address with ID does exists",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("address_id: %s\n", errmsg.ErrorMsgNotFound)),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      5000,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "ReferDate should not be empty",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("refer_date: cannot be blank\n")),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				BenefactorID:   1,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:  "This address does not belong to this benefactor",
 | 
			
		||||
			error: fmt.Errorf(fmt.Sprintf("address_id: %s\n", errmsg.ErrorMsgNotFound)),
 | 
			
		||||
			params: benefactorkindboxreqparam.KindBoxReqAddRequest{
 | 
			
		||||
				AddressID:      1,
 | 
			
		||||
				BenefactorID:   100,
 | 
			
		||||
				TypeID:         1,
 | 
			
		||||
				CountRequested: 1,
 | 
			
		||||
				ReferDate:      time.Now(),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			// 1. setup
 | 
			
		||||
			repo := NewMock(tc.repoErr)
 | 
			
		||||
			vld := benefactorkindboxreqvalidator.New(repo, repo)
 | 
			
		||||
 | 
			
		||||
			// 2. execution
 | 
			
		||||
			res := vld.ValidateAddRequest(tc.params)
 | 
			
		||||
 | 
			
		||||
			// 3. assertion
 | 
			
		||||
			if tc.error == nil {
 | 
			
		||||
				assert.Nil(t, res)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			assert.Equal(t, tc.error.Error(), res.Error())
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -16,12 +16,6 @@ const (
 | 
			
		|||
	MaxKindBoxReq uint = 100
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Repository interface {
 | 
			
		||||
	// KindBoxReqExist(id uint) (bool, error)
 | 
			
		||||
	// KindBoxBelongToBenefactor(bID uint, kbID uint) (bool, error)
 | 
			
		||||
	// PendingStatus(id uint) (bool, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BenefactorSvc interface {
 | 
			
		||||
	BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -31,13 +25,27 @@ type AddressSvc interface {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
type Validator struct {
 | 
			
		||||
	repo          Repository
 | 
			
		||||
	benefactorSvc BenefactorSvc
 | 
			
		||||
	addressSvc    AddressSvc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(repo Repository, benefactorSvc BenefactorSvc, addressSvc AddressSvc) Validator {
 | 
			
		||||
	return Validator{repo: repo, benefactorSvc: benefactorSvc, addressSvc: addressSvc}
 | 
			
		||||
type ValidatorError struct {
 | 
			
		||||
	Fields map[string]string `json:"error"`
 | 
			
		||||
	Err    error             `json:"message"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v ValidatorError) Error() string {
 | 
			
		||||
	var err string
 | 
			
		||||
 | 
			
		||||
	for key, value := range v.Fields {
 | 
			
		||||
		err += fmt.Sprintf("%s: %s\n", key, value)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New(benefactorSvc BenefactorSvc, addressSvc AddressSvc) Validator {
 | 
			
		||||
	return Validator{benefactorSvc: benefactorSvc, addressSvc: addressSvc}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v Validator) doesBenefactorExist(value interface{}) error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue