Skip to content

Commit

Permalink
Добавил unit тесты, моки, интерфейсы
Browse files Browse the repository at this point in the history
  • Loading branch information
Пешков Дмитрий committed Sep 24, 2024
1 parent fca4882 commit 4b5dd29
Show file tree
Hide file tree
Showing 27 changed files with 805 additions and 26 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
Expand Down Expand Up @@ -224,6 +226,7 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
Expand Down Expand Up @@ -252,6 +255,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -262,6 +266,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
Expand All @@ -284,7 +289,9 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -310,6 +317,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
5 changes: 5 additions & 0 deletions internal/authenticate/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ type ContextKey string

var ContextUserID ContextKey = "UserID"

type Auth interface {
GetUserIDFromCookie(tokenString string) (uuid.UUID, error)
SetCookie(rw http.ResponseWriter, UserID uuid.UUID)
}

type Authenticate struct {
logger *zap.Logger
secretKey string
Expand Down
63 changes: 63 additions & 0 deletions internal/authenticate/mocks/authenticate.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/handlers/add_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func AddOrdersHandler(o *services.OrderService) http.HandlerFunc {
func AddOrdersHandler(o services.Order) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
orderNum, err := utils.FromPostPlain(req)
if err != nil {
Expand Down
75 changes: 75 additions & 0 deletions internal/handlers/add_orders_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package handlers

import (
"bytes"
"context"
"github.com/golang/mock/gomock"
"github.com/spqrcor/gofermart/internal/services"
"github.com/spqrcor/gofermart/internal/services/mocks"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

func TestAddOrdersHandler(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

order := mocks.NewMockOrder(mockCtrl)
order.EXPECT().Add(context.Background(), "333").Return(services.ErrOrderInvalidFormat).AnyTimes()
order.EXPECT().Add(context.Background(), "9278923470").Return(nil).MaxTimes(1)
order.EXPECT().Add(context.Background(), "9278923470").Return(services.ErrOrderUserExists).MinTimes(1)
order.EXPECT().Add(context.Background(), "12345678903").Return(services.ErrOrderAnotherUserExists).AnyTimes()

tests := []struct {
name string
contentType string
body []byte
statusCode int
}{
{
name: "content type error",
contentType: "application/json",
body: []byte(`<num>3333</num>`),
statusCode: http.StatusBadRequest,
},
{
name: "format number error",
contentType: "text/plain",
body: []byte(`333`),
statusCode: http.StatusUnprocessableEntity,
},
{
name: "success",
contentType: "text/plain",
body: []byte(`9278923470`),
statusCode: http.StatusAccepted,
},
{
name: "order user exists",
contentType: "text/plain",
body: []byte(`9278923470`),
statusCode: http.StatusOK,
},
{
name: "order another user exists",
contentType: "text/plain",
body: []byte(`12345678903`),
statusCode: http.StatusConflict,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rw := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/api/user/orders", bytes.NewReader(tt.body))
req.Header.Add("Content-Type", tt.contentType)
AddOrdersHandler(order)(rw, req)

resp := rw.Result()
assert.Equal(t, tt.statusCode, resp.StatusCode, "Error http status code")
_ = req.Body.Close()
})
}
}
2 changes: 1 addition & 1 deletion internal/handlers/add_withdrawals.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func AddWithdrawalHandler(w *services.WithdrawalService) http.HandlerFunc {
func AddWithdrawalHandler(w services.Withdrawal) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
var input services.InputWithdrawal
if err := utils.FromPostJSON(req, &input); err != nil {
Expand Down
68 changes: 68 additions & 0 deletions internal/handlers/add_withdrawals_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package handlers

import (
"bytes"
"context"
"github.com/golang/mock/gomock"
"github.com/spqrcor/gofermart/internal/services"
"github.com/spqrcor/gofermart/internal/services/mocks"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

func TestAddWithdrawalHandler(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

withdrawal := mocks.NewMockWithdrawal(mockCtrl)
withdrawal.EXPECT().Add(context.Background(), services.InputWithdrawal{OrderNum: "333", Sum: 100}).Return(services.ErrOrderInvalidFormat).AnyTimes()
withdrawal.EXPECT().Add(context.Background(), services.InputWithdrawal{OrderNum: "9278923470", Sum: 100}).Return(nil).AnyTimes()
withdrawal.EXPECT().Add(context.Background(), services.InputWithdrawal{OrderNum: "12345678903", Sum: 100}).Return(services.ErrBalance).AnyTimes()

tests := []struct {
name string
contentType string
body []byte
statusCode int
}{
{
name: "content type error",
contentType: "text/plain",
body: []byte(`1111`),
statusCode: http.StatusInternalServerError,
},
{
name: "format order error",
contentType: "application/json",
body: []byte(`{"order":"333","sum":100}`),
statusCode: http.StatusUnprocessableEntity,
},
{
name: "success",
contentType: "application/json",
body: []byte(`{"order":"9278923470","sum":100}`),
statusCode: http.StatusOK,
},
{
name: "balance error",
contentType: "application/json",
body: []byte(`{"order":"12345678903","sum":100}`),
statusCode: http.StatusPaymentRequired,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rw := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/api/user/balance/withdraw", bytes.NewReader(tt.body))
req.Header.Add("Content-Type", tt.contentType)
AddWithdrawalHandler(withdrawal)(rw, req)

resp := rw.Result()
assert.Equal(t, tt.statusCode, resp.StatusCode, "Error http status code")
_ = req.Body.Close()
})
}
}
2 changes: 1 addition & 1 deletion internal/handlers/get_balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"
)

func GetBalanceHandler(w *services.WithdrawalService) http.HandlerFunc {
func GetBalanceHandler(w services.Withdrawal) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
balance, err := w.GetBalance(req.Context())
if err != nil {
Expand Down
48 changes: 48 additions & 0 deletions internal/handlers/get_balance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package handlers

import (
"context"
"errors"
"github.com/golang/mock/gomock"
"github.com/spqrcor/gofermart/internal/services"
"github.com/spqrcor/gofermart/internal/services/mocks"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"testing"
)

func TestGetBalanceHandler(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

withdrawal := mocks.NewMockWithdrawal(mockCtrl)
withdrawal.EXPECT().GetBalance(context.Background()).Return(services.BalanceInfo{}, errors.New("user not found")).MaxTimes(1)
withdrawal.EXPECT().GetBalance(context.Background()).Return(services.BalanceInfo{Current: 100, Withdrawn: 100}, nil).MinTimes(1)
tests := []struct {
name string
statusCode int
}{
{
name: "no content error",
statusCode: http.StatusInternalServerError,
},
{
name: "success",
statusCode: http.StatusOK,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rw := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/api/user/balance", nil)
GetBalanceHandler(withdrawal)(rw, req)

resp := rw.Result()
assert.Equal(t, tt.statusCode, resp.StatusCode, "Error http status code")
_ = req.Body.Close()
})
}

}
2 changes: 1 addition & 1 deletion internal/handlers/get_orders.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/http"
)

func GetOrdersHandler(o *services.OrderService) http.HandlerFunc {
func GetOrdersHandler(o services.Order) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
orders, err := o.GetAll(req.Context())
if errors.Is(err, services.ErrOrdersNotFound) {
Expand Down
Loading

0 comments on commit 4b5dd29

Please sign in to comment.