diff --git a/Makefile b/Makefile index 971b8d9..6e0a369 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ server: mock-gen: mockgen -source ./src/pkg/service/auth/auth.service.go -destination ./src/mocks/service/auth/auth.mock.go mockgen -source ./src/pkg/service/user/user.service.go -destination ./src/mocks/service/user/user.mock.go + mockgen -source ./src/pkg/service/pet/pet.service.go -destination ./src/mocks/service/pet/pet.mock.go + mockgen -source ./src/pkg/service/image/image.service.go -destination ./src/mocks/service/image/image.mock.go mockgen -source ./src/app/validator/validator.go -destination ./src/mocks/validator/validator.mock.go mockgen -source ./src/app/router/context.go -destination ./src/mocks/router/context.mock.go diff --git a/go.mod b/go.mod index 92d5b76..cbd3c05 100644 --- a/go.mod +++ b/go.mod @@ -4,33 +4,33 @@ go 1.21.3 require ( github.com/arsmn/fiber-swagger/v2 v2.31.1 + github.com/bxcodec/faker/v4 v4.0.0-beta.3 + github.com/go-faker/faker/v4 v4.2.0 github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.16.0 github.com/gofiber/fiber/v2 v2.51.0 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.5.0 github.com/isd-sgcu/johnjud-go-proto v0.2.2 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.31.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 + github.com/swaggo/swag v1.16.2 google.golang.org/grpc v1.60.1 ) require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/PuerkitoBio/purell v1.2.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/andybalholm/brotli v1.0.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/go-faker/faker/v4 v4.2.0 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.13 // indirect github.com/go-openapi/swag v0.22.6 // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -54,7 +54,6 @@ require ( github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 // indirect - github.com/swaggo/swag v1.16.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.50.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect @@ -62,7 +61,6 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.16.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect @@ -70,6 +68,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f31fc77..69ab4da 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.2.1 h1:QsZ4TjvwiMpat6gBCBxEQI0rcS9ehtkKtSpiUnd9N28= -github.com/PuerkitoBio/purell v1.2.1/go.mod h1:ZwHcC/82TOaovDi//J/804umJFFmbOHPngi8iYYv/Eo= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/arsmn/fiber-swagger/v2 v2.31.1 h1:VmX+flXiGGNqLX3loMEEzL3BMOZFSPwBEWR04GA6Mco= github.com/arsmn/fiber-swagger/v2 v2.31.1/go.mod h1:ZHhMprtB3M6jd2mleG03lPGhHH0lk9u3PtfWS1cBhMA= +github.com/bxcodec/faker/v4 v4.0.0-beta.3 h1:gqYNBvN72QtzKkYohNDKQlm+pg+uwBDVMN28nWHS18k= +github.com/bxcodec/faker/v4 v4.0.0-beta.3/go.mod h1:m6+Ch1Lj3fqW/unZmvkXIdxWS5+XQWPWxcbbQW2X+Ho= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -31,20 +28,16 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-faker/faker/v4 v4.2.0 h1:dGebOupKwssrODV51E0zbMrv5e2gO9VWSLNC1WDCpWg= github.com/go-faker/faker/v4 v4.2.0/go.mod h1:F/bBy8GH9NxOxMInug5Gx4WYeG6fHJZ8Ol/dhcpRub4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkIaE= github.com/go-openapi/spec v0.20.13/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.6 h1:dnqg1XfHXL9aBxSbktBqFR5CxVyVI+7fYWhAf1JOeTw= github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= @@ -73,8 +66,6 @@ github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/isd-sgcu/johnjud-go-proto v0.0.8 h1:nIQBZgK2OFVrLjVtpeDgwows8poA7LhsIVE4hlbBC1o= -github.com/isd-sgcu/johnjud-go-proto v0.0.8/go.mod h1:HP0w9gC30b5WNnqeFBM9JJZud+pvyikz0+pGFSI/Wjw= github.com/isd-sgcu/johnjud-go-proto v0.2.2 h1:TOAmbwy/I+8/J5LPZH0ZN7lSLczBiZe1fs88gH8XrhY= github.com/isd-sgcu/johnjud-go-proto v0.2.2/go.mod h1:1OK6aiCgtXQiLhxp0r6iLEejYIRpckWQZDrCZ9Trbo4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -96,7 +87,6 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -110,9 +100,7 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= @@ -127,8 +115,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -166,7 +154,6 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM= github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= -github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI= github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ= github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= @@ -192,8 +179,7 @@ golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -236,8 +222,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -250,19 +234,17 @@ google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/app/constant/error.constant.go b/src/app/constant/error.constant.go index 670c9bb..f91d9d8 100644 --- a/src/app/constant/error.constant.go +++ b/src/app/constant/error.constant.go @@ -6,3 +6,6 @@ const IncorrectEmailPasswordMessage = "Incorrect Email or Password" const DuplicateEmailMessage = "Duplicate Email" const InternalErrorMessage = "Internal Error" const UnavailableServiceMessage = "Unavailable Service" + +const PetNotFoundMessage = "Pet not found" +const InvalidArgument = "Invalid Argument" diff --git a/src/app/dto/pet.dto.go b/src/app/dto/pet.dto.go index 92f964f..cf2fd94 100644 --- a/src/app/dto/pet.dto.go +++ b/src/app/dto/pet.dto.go @@ -5,6 +5,7 @@ import ( ) type PetDto struct { + Id string `json:"id"` Type string `json:"type" validate:"required"` Species string `json:"species" validate:"required"` Name string `json:"name" validate:"required"` @@ -13,11 +14,28 @@ type PetDto struct { Habit string `json:"habit" validate:"required"` Caption string `json:"caption"` Status pet.Status `json:"status" validate:"required" example:"findhome"` - IsSterile bool `json:"is_sterile" validate:"required"` - IsVaccinated bool `json:"is_vaccine" validate:"required"` - IsVisible bool `json:"is_visible" validate:"required"` - IsClubPet bool `json:"is_club_pet" validate:"required"` + IsSterile *bool `json:"is_sterile" validate:"required"` + IsVaccinated *bool `json:"is_vaccinated" validate:"required"` + IsVisible *bool `json:"is_visible" validate:"required"` + IsClubPet *bool `json:"is_club_pet" validate:"required"` Background string `json:"background"` Address string `json:"address"` Contact string `json:"contact"` + AdoptBy string `json:"adopt_by"` +} + +type CreatePetRequest struct { + Pet *PetDto `json:"pet" validate:"required"` +} + +type ChangeViewPetRequest struct { + Visible bool `json:"visible" validate:"required"` +} + +type UpdatePetRequest struct { + Pet *PetDto `json:"pet" validate:"required"` +} + +type DeleteRequest struct { + Id string `json:"id" validate:"required"` } diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 442ac38..552498b 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -13,7 +13,7 @@ type Handler struct { } type Service interface { - FindByPetId() ([]*proto.Image, *dto.ResponseErr) + FindByPetId(string) ([]*proto.Image, *dto.ResponseErr) Upload(*dto.ImageDto) (*proto.Image, *dto.ResponseErr) Delete(string) (bool, *dto.ResponseErr) } diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index 752b9ca..66e179d 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -1,56 +1,288 @@ -package auth +package pet import ( + "net/http" + "strings" + + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + imageSrv "github.com/isd-sgcu/johnjud-gateway/src/app/handler/image" "github.com/isd-sgcu/johnjud-gateway/src/app/router" "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" - image_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + pet_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" ) type Handler struct { service Service - imageService ImageService - validate *validator.DtoValidator + imageService imageSrv.Service + validate validator.IDtoValidator } type Service interface { - FindAll() ([]*proto.Pet, *dto.ResponseErr) - FindOne(string) (*proto.Pet, *dto.ResponseErr) - Create(*dto.PetDto) (*proto.Pet, *dto.ResponseErr) - Update(string, *dto.PetDto) (*proto.Pet, *dto.ResponseErr) - ChangeView(string) (*proto.Pet, *dto.ResponseErr) + FindAll() ([]*pet_proto.Pet, *dto.ResponseErr) + FindOne(string) (*pet_proto.Pet, *dto.ResponseErr) + Create(*dto.CreatePetRequest) (*pet_proto.Pet, *dto.ResponseErr) + Update(string, *dto.UpdatePetRequest) (*pet_proto.Pet, *dto.ResponseErr) + ChangeView(string, *dto.ChangeViewPetRequest) (bool, *dto.ResponseErr) Delete(string) (bool, *dto.ResponseErr) } -type ImageService interface { - FindByPetId(string) (*image_proto.Image, *dto.ResponseErr) -} - -func NewHandler(service Service, imageService ImageService, validate *validator.DtoValidator) *Handler { +func NewHandler(service Service, imageService imageSrv.Service, validate validator.IDtoValidator) *Handler { return &Handler{service, imageService, validate} } -func (h *Handler) FindAll(c *router.FiberCtx) { +// FindAll is a function that return all pets in database +// @Summary find all pets +// @Description Return the data of pets if successfully +// @Tags auth +// @Accept json +// @Produce json +// @Success 200 {object} dto.PetDto +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/ [get] +func (h *Handler) FindAll(c router.IContext) { + response, respErr := h.service.FindAll() + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + c.JSON(http.StatusOK, response) + return } -func (h *Handler) FindOne(c *router.FiberCtx) { +// FindOne is a function that return all pet in database +// @Summary find one pet +// @Description Return the data of pets if successfully +// @Param id path string true "pet id" +// @Tags auth +// @Accept json +// @Produce json +// @Success 200 {object} dto.PetDto +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/{id} [get] +func (h *Handler) FindOne(c router.IContext) { + id, err := c.Param("id") + if err != nil { + c.JSON(http.StatusInternalServerError, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Invalid ID", + Data: nil, + }) + return + } + + response, respErr := h.service.FindOne(id) + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + c.JSON(http.StatusOK, response) + return } -func (h *Handler) Create(c *router.FiberCtx) { +// Create is a function that create pet in database +// @Summary create pet +// @Description Return the data of pet if successfully +// @Param create body dto.CreatePetRequest true "pet dto" +// @Tags auth +// @Accept json +// @Produce json +// @Success 201 {object} dto.PetDto +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/create [post] +func (h *Handler) Create(c router.IContext) { + request := &dto.CreatePetRequest{ + Pet: &dto.PetDto{}, + } + err := c.Bind(request) + if err != nil { + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + err.Error(), + Data: nil, + }) + return + } + if err := h.validate.Validate(request); err != nil { + var errorMessage []string + for _, reqErr := range err { + errorMessage = append(errorMessage, reqErr.Message) + } + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + strings.Join(errorMessage, ", "), + Data: nil, + }) + return + } + + response, respErr := h.service.Create(request) + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + + c.JSON(http.StatusCreated, response) + return } -func (h *Handler) Update(c *router.FiberCtx) { +// Update is a function that update pet in database +// @Summary update pet +// @Description Return the data of pet if successfully +// @Param update body dto.UpdatePetRequest true "update pet dto" +// @Param id path stirng true "pet id" +// @Tags auth +// @Accept json +// @Produce json +// @Success 201 {object} dto.PetDto +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/{id} [put] +func (h *Handler) Update(c router.IContext) { + petId, err := c.Param("id") + if err != nil { + c.JSON(http.StatusInternalServerError, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Invalid ID", + Data: nil, + }) + return + } + + request := &dto.UpdatePetRequest{ + Pet: &dto.PetDto{}, + } + + err = c.Bind(request) + if err != nil { + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + err.Error(), + Data: nil, + }) + return + } + if err := h.validate.Validate(request); err != nil { + var errorMessage []string + for _, reqErr := range err { + errorMessage = append(errorMessage, reqErr.Message) + } + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + strings.Join(errorMessage, ", "), + Data: nil, + }) + return + } + + pet, errRes := h.service.Update(petId, request) + if errRes != nil { + c.JSON(errRes.StatusCode, errRes) + return + } + + c.JSON(http.StatusOK, pet) + return } -func (h *Handler) ChangeView(c *router.FiberCtx) { +// Change is a function that change visibility of pet in database +// @Summary change view pet +// @Description Return the status true of pet if successfully else false +// @Param change view body dto.ChangeViewPetRequest true "change view pet dto" +// @Param id string true "pet id" +// @Tags auth +// @Accept json +// @Produce json +// @Success 201 {object} bool +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/ [put] +func (h *Handler) ChangeView(c router.IContext) { + id, err := c.Param("id") + if err != nil { + c.JSON(http.StatusBadRequest, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: err.Error(), + Data: nil, + }) + return + } + + request := &dto.ChangeViewPetRequest{} + + err = c.Bind(request) + if err != nil { + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.BindingRequestErrorMessage + err.Error(), + Data: nil, + }) + return + } + if err := h.validate.Validate(request); err != nil { + var errorMessage []string + for _, reqErr := range err { + errorMessage = append(errorMessage, reqErr.Message) + } + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidRequestBodyMessage + strings.Join(errorMessage, ", "), + Data: nil, + }) + return + } + + res, errRes := h.service.ChangeView(id, request) + if errRes != nil { + c.JSON(errRes.StatusCode, errRes) + return + } + + c.JSON(http.StatusOK, res) + return } -func (h *Handler) Delete(c *router.FiberCtx) { +// Delete is a function that delete pet in database +// @Summary delete pet +// @Description Return the status true of pet if successfully else false +// @Param id string true "pet id" +// @Tags auth +// @Accept json +// @Produce json +// @Success 201 {object} bool +// @Failure 400 {object} dto.ResponseBadRequestErr "Invalid request body" +// @Failure 500 {object} dto.ResponseInternalErr "Internal service error" +// @Failure 503 {object} dto.ResponseServiceDownErr "Service is down" +// @Router /v1/pets/ [delete] +func (h *Handler) Delete(c router.IContext) { + id, err := c.Param("id") + if err != nil { + c.JSON(http.StatusBadRequest, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: err.Error(), + Data: nil, + }) + return + } + + res, errRes := h.service.Delete(id) + if errRes != nil { + c.JSON(errRes.StatusCode, errRes) + return + } + c.JSON(http.StatusOK, res) + return } diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go new file mode 100644 index 0000000..a971caa --- /dev/null +++ b/src/app/handler/pet/pet.handler_test.go @@ -0,0 +1,398 @@ +package pet + +import ( + "math/rand" + "net/http" + "testing" + + "github.com/bxcodec/faker/v4" + "github.com/golang/mock/gomock" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + mock_router "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" + mock_image "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/image" + mock_pet "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/pet" + mock_validator "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + + pet_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + image_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/stretchr/testify/suite" +) + +type PetHandlerTest struct { + suite.Suite + Pet *pet_proto.Pet + Pets []*pet_proto.Pet + PetDto *dto.PetDto + CreatePetRequest *dto.CreatePetRequest + ChangeViewPetRequest *dto.ChangeViewPetRequest + UpdatePetRequest *dto.UpdatePetRequest + BindErr *dto.ResponseErr + NotFoundErr *dto.ResponseErr + ServiceDownErr *dto.ResponseErr + InternalErr *dto.ResponseErr +} + +func TestPetHandler(t *testing.T) { + suite.Run(t, new(PetHandlerTest)) +} + +func (t *PetHandlerTest) SetupTest() { + var pets []*pet_proto.Pet + for i := 0; i <= 3; i++ { + pet := &pet_proto.Pet{ + Id: faker.UUIDDigit(), + Type: faker.Word(), + Species: faker.Word(), + Name: faker.Name(), + Birthdate: faker.Word(), + Gender: pet_proto.Gender(rand.Intn(1) + 1), + Habit: faker.Paragraph(), + Caption: faker.Paragraph(), + Images: []*image_proto.Image{}, + Status: pet_proto.PetStatus(rand.Intn(1) + 1), + IsSterile: true, + IsVaccinated: true, + IsVisible: true, + IsClubPet: true, + Background: faker.Paragraph(), + Address: faker.Paragraph(), + Contact: faker.Paragraph(), + AdoptBy: "", + } + + pets = append(pets, pet) + } + + t.Pets = pets + t.Pet = t.Pets[0] + + t.PetDto = &dto.PetDto{ + Id: t.Pet.Id, + Type: t.Pet.Type, + Species: t.Pet.Species, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: pet.Gender(t.Pet.Gender), + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Status: pet.Status(t.Pet.Status), + IsSterile: &t.Pet.IsSterile, + IsVaccinated: &t.Pet.IsVaccinated, + IsVisible: &t.Pet.IsVisible, + IsClubPet: &t.Pet.IsClubPet, + Background: t.Pet.Background, + Address: t.Pet.Address, + Contact: t.Pet.Contact, + AdoptBy: t.Pet.AdoptBy, + } + + t.CreatePetRequest = &dto.CreatePetRequest{ + Pet: &dto.PetDto{}, + } + + t.UpdatePetRequest = &dto.UpdatePetRequest{ + Pet: &dto.PetDto{}, + } + + t.ChangeViewPetRequest = &dto.ChangeViewPetRequest{} + + t.ServiceDownErr = &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: "Service is down", + Data: nil, + } + + t.NotFoundErr = &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: "Pet not found", + Data: nil, + } + + t.BindErr = &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: "Invalid ID", + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: "Internal Server Error", + Data: nil, + } +} + +func (t *PetHandlerTest) TestFindAllSuccess() { + findAllResponse := t.Pets + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + petSvc.EXPECT().FindAll().Return(findAllResponse, nil) + context.EXPECT().JSON(http.StatusOK, findAllResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.FindAll(context) +} + +func (t *PetHandlerTest) TestFindOneSuccess() { + findOneResponse := t.Pet + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().FindOne(t.Pet.Id).Return(findOneResponse, nil) + context.EXPECT().JSON(http.StatusOK, findOneResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.FindOne(context) +} + +func (t *PetHandlerTest) TestFindOneNotFoundErr() { + findOneResponse := t.NotFoundErr + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) + context.EXPECT().JSON(http.StatusNotFound, findOneResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.FindOne(context) +} + +func (t *PetHandlerTest) TestFindOneGrpcErr() { + findOneResponse := t.ServiceDownErr + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, findOneResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.FindOne(context) +} + +func (t *PetHandlerTest) TestCreateSuccess() { + createErrorResponse := t.Pet + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Bind(t.CreatePetRequest).Return(nil) + validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) + petSvc.EXPECT().Create(t.CreatePetRequest).Return(createErrorResponse, nil) + context.EXPECT().JSON(http.StatusCreated, createErrorResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Create(context) +} + +func (t *PetHandlerTest) TestCreateGrpcErr() { + createErrorResponse := t.ServiceDownErr + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Bind(t.CreatePetRequest).Return(nil) + validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) + petSvc.EXPECT().Create(t.CreatePetRequest).Return(nil, createErrorResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, createErrorResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Create(context) +} + +func (t *PetHandlerTest) TestUpdateSuccess() { + updateResponse := t.Pet + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) + validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) + petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(updateResponse, nil) + context.EXPECT().JSON(http.StatusOK, updateResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Update(context) +} + +func (t *PetHandlerTest) TestUpdateNotFound() { + updateResponse := t.NotFoundErr + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) + validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) + petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) + context.EXPECT().JSON(http.StatusNotFound, updateResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Update(context) +} + +func (t *PetHandlerTest) TestUpdateGrpcErr() { + updateResponse := t.ServiceDownErr + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) + validator.EXPECT().Validate(t.UpdatePetRequest).Return(nil) + petSvc.EXPECT().Update(t.Pet.Id, t.UpdatePetRequest).Return(nil, updateResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, updateResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Update(context) +} + +func (t *PetHandlerTest) TestDeleteSuccess() { + deleteResponse := true + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, nil) + context.EXPECT().JSON(http.StatusOK, deleteResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} +func (t *PetHandlerTest) TestDeleteNotFound() { + deleteResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.NotFoundErr) + context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestDeleteGrpcErr() { + deleteResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.ServiceDownErr) + context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestChangeViewSuccess() { + changeViewResponse := true + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(changeViewResponse, nil) + context.EXPECT().JSON(http.StatusOK, changeViewResponse) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestChangeViewNotFound() { + changeViewResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(changeViewResponse, t.NotFoundErr) + context.EXPECT().JSON(http.StatusNotFound, t.NotFoundErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} + +func (t *PetHandlerTest) TestChangeViewGrpcErr() { + changeViewResponse := false + + controller := gomock.NewController(t.T()) + + petSvc := mock_pet.NewMockService(controller) + imageSvc := mock_image.NewMockService(controller) + validator := mock_validator.NewMockIDtoValidator(controller) + context := mock_router.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Pet.Id, nil) + petSvc.EXPECT().Delete(t.Pet.Id).Return(changeViewResponse, t.ServiceDownErr) + context.EXPECT().JSON(http.StatusServiceUnavailable, t.ServiceDownErr) + + handler := NewHandler(petSvc, imageSvc, validator) + handler.Delete(context) +} diff --git a/src/app/router/pet.router.go b/src/app/router/pet.router.go index 19a5195..b3e054e 100644 --- a/src/app/router/pet.router.go +++ b/src/app/router/pet.router.go @@ -2,28 +2,28 @@ package router import "github.com/gofiber/fiber/v2" -func (r *FiberRouter) GetPet(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) GetPet(path string, h func(ctx IContext)) { r.pet.Get(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) PostPet(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) PostPet(path string, h func(ctx IContext)) { r.pet.Post(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) PutPet(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) PutPet(path string, h func(ctx IContext)) { r.pet.Put(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) DeletePet(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) DeletePet(path string, h func(ctx IContext)) { r.pet.Delete(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil diff --git a/src/app/router/router.go b/src/app/router/router.go index ea19491..0c2716b 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -49,7 +49,8 @@ func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { auth := GroupWithAuthMiddleware(r, "/auth", authGuard.Use) user := GroupWithAuthMiddleware(r, "/user", authGuard.Use) - pet := GroupWithAuthMiddleware(r, "/pet", authGuard.Use) + pet := GroupWithAuthMiddleware(r, "/pets", authGuard.Use) + image := GroupWithAuthMiddleware(r, "/image", authGuard.Use) like := GroupWithAuthMiddleware(r, "/like", authGuard.Use) diff --git a/src/app/service/image/image.service.go b/src/app/service/image/image.service.go index 87bbfc8..6ff8668 100644 --- a/src/app/service/image/image.service.go +++ b/src/app/service/image/image.service.go @@ -15,7 +15,7 @@ func NewService(client proto.ImageServiceClient) *Service { } } -func (s *Service) FindByPetId() ([]*proto.Image, *dto.ResponseErr) { +func (s *Service) FindByPetId(string) ([]*proto.Image, *dto.ResponseErr) { return nil, nil } diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go new file mode 100644 index 0000000..7ada5ff --- /dev/null +++ b/src/app/service/pet/pet.service.go @@ -0,0 +1,317 @@ +package pet + +import ( + "context" + "net/http" + "time" + + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + image_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/rs/zerolog/log" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type Service struct { + petClient proto.PetServiceClient +} + +func NewService(petClient proto.PetServiceClient) *Service { + return &Service{ + petClient: petClient, + } +} + +func (s *Service) FindAll() (result []*proto.Pet, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.petClient.FindAll(ctx, &proto.FindAllPetRequest{}) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "find all"). + Msg(st.Message()) + switch st.Code() { + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + } + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + _ = &image_proto.Image{} + return res.Pets, nil +} + +func (s *Service) FindOne(id string) (result *proto.Pet, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.petClient.FindOne(ctx, &proto.FindOnePetRequest{Id: id}) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "find one"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return res.Pet, nil +} + +func (s *Service) Create(in *dto.CreatePetRequest) (ressult *proto.Pet, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := DtoToRaw(in.Pet) + + res, errRes := s.petClient.Create(ctx, &proto.CreatePetRequest{Pet: request}) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "create"). + Msg(st.Message()) + switch st.Code() { + case codes.InvalidArgument: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgument, + Data: nil, + } + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return res.Pet, nil +} + +func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *proto.Pet, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := &proto.UpdatePetRequest{ + Pet: &proto.Pet{ + Id: id, + Type: in.Pet.Type, + Species: in.Pet.Species, + Name: in.Pet.Name, + Birthdate: in.Pet.Birthdate, + Gender: proto.Gender(in.Pet.Gender), + Habit: in.Pet.Habit, + Caption: in.Pet.Caption, + Images: []*image_proto.Image{}, + Status: proto.PetStatus(in.Pet.Status), + IsSterile: *in.Pet.IsSterile, + IsVaccinated: *in.Pet.IsSterile, + IsVisible: *in.Pet.IsVaccinated, + IsClubPet: *in.Pet.IsClubPet, + Background: in.Pet.Background, + Address: in.Pet.Address, + Contact: in.Pet.Contact, + AdoptBy: in.Pet.AdoptBy, + }, + } + + res, errRes := s.petClient.Update(ctx, request) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "update"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + case codes.InvalidArgument: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgument, + Data: nil, + } + case codes.Unavailable: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return res.Pet, nil +} + +func (s *Service) Delete(id string) (result bool, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.petClient.Delete(ctx, &proto.DeletePetRequest{ + Id: id, + }) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "delete"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return false, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + case codes.Unavailable: + return false, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + } + return false, &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + return res.Success, nil +} + +func (s *Service) ChangeView(id string, in *dto.ChangeViewPetRequest) (result bool, err *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.petClient.ChangeView(ctx, &proto.ChangeViewPetRequest{ + Id: id, + Visible: in.Visible, + }) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "pet"). + Str("module", "change view"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return false, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + case codes.Unavailable: + return false, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + default: + return false, &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.InternalErrorMessage, + Data: nil, + } + } + } + return res.Success, nil +} + +func DtoToRaw(in *dto.PetDto) *proto.Pet { + return &proto.Pet{ + Id: in.Id, + Type: in.Type, + Species: in.Species, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: proto.Gender(in.Gender), + Habit: in.Habit, + Caption: in.Caption, + Images: []*image_proto.Image{}, + Status: proto.PetStatus(in.Status), + IsSterile: *in.IsSterile, + IsVaccinated: *in.IsVaccinated, + IsVisible: *in.IsVisible, + IsClubPet: *in.IsClubPet, + Background: in.Background, + Address: in.Address, + Contact: in.Contact, + AdoptBy: in.AdoptBy, + } +} + +func RawToDto(in *proto.Pet) *dto.PetDto { + return &dto.PetDto{ + Id: in.Id, + Type: in.Type, + Species: in.Species, + Name: in.Name, + Birthdate: in.Birthdate, + Gender: pet.Gender(in.Gender), + Habit: in.Habit, + Caption: in.Caption, + Status: pet.Status(in.Status), + IsSterile: &in.IsSterile, + IsVaccinated: &in.IsVaccinated, + IsVisible: &in.IsVisible, + IsClubPet: &in.IsClubPet, + Background: in.Background, + Address: in.Address, + Contact: in.Contact, + AdoptBy: in.AdoptBy, + } +} diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go new file mode 100644 index 0000000..7700da4 --- /dev/null +++ b/src/app/service/pet/pet.service_test.go @@ -0,0 +1,508 @@ +package pet + +import ( + "math/rand" + "net/http" + "testing" + + "github.com/go-faker/faker/v4" + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + petMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/pet" + petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + imageProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type PetServiceTest struct { + suite.Suite + Pets []*petProto.Pet + Pet *petProto.Pet + PetReq *petProto.Pet + PetNotVisible *petProto.Pet + UpdatePetReq *petProto.UpdatePetRequest + ChangeViewPetReq *petProto.ChangeViewPetRequest + AdoptReq *petProto.AdoptPetRequest + PetDto *dto.PetDto + CreatePetDto *dto.CreatePetRequest + UpdatePetDto *dto.UpdatePetRequest + NotFoundErr *dto.ResponseErr + UnavailableServiceErr *dto.ResponseErr + InvalidArgumentErr *dto.ResponseErr + InternalErr *dto.ResponseErr + ChangeViewedPetDto *dto.ChangeViewPetRequest + + Images []*imageProto.Image + ImageUrls []string + ImagesList [][]*imageProto.Image + ImageUrlsList [][]string +} + +func TestPetService(t *testing.T) { + suite.Run(t, new(PetServiceTest)) +} + +func (t *PetServiceTest) SetupTest() { + var pets []*petProto.Pet + for i := 0; i <= 3; i++ { + pet := &petProto.Pet{ + Id: faker.UUIDDigit(), + Type: faker.Word(), + Species: faker.Word(), + Name: faker.Name(), + Birthdate: faker.Word(), + Gender: petProto.Gender(rand.Intn(1) + 1), + Habit: faker.Paragraph(), + Caption: faker.Paragraph(), + Images: []*imageProto.Image{}, + Status: petProto.PetStatus(rand.Intn(1) + 1), + IsSterile: true, + IsVaccinated: true, + IsVisible: true, + IsClubPet: true, + Background: faker.Paragraph(), + Address: faker.Paragraph(), + Contact: faker.Paragraph(), + AdoptBy: faker.UUIDDigit(), + } + + pets = append(pets, pet) + } + + t.Pets = pets + t.Pet = t.Pets[0] + + t.PetReq = &petProto.Pet{ + Type: t.Pet.Type, + Species: t.Pet.Species, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Images: t.Pet.Images, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: t.Pet.IsVisible, + IsClubPet: t.Pet.IsClubPet, + Background: t.Pet.Background, + Address: t.Pet.Address, + Contact: t.Pet.Contact, + AdoptBy: t.Pet.AdoptBy, + } + + t.PetNotVisible = &petProto.Pet{ + Id: t.Pet.Id, + Type: t.Pet.Type, + Species: t.Pet.Species, + Name: t.Pet.Name, + Birthdate: t.Pet.Birthdate, + Gender: t.Pet.Gender, + Habit: t.Pet.Habit, + Caption: t.Pet.Caption, + Images: t.Pet.Images, + Status: t.Pet.Status, + IsSterile: t.Pet.IsSterile, + IsVaccinated: t.Pet.IsVaccinated, + IsVisible: false, + IsClubPet: t.Pet.IsClubPet, + Background: t.Pet.Background, + Address: t.Pet.Address, + Contact: t.Pet.Contact, + AdoptBy: t.Pet.AdoptBy, + } + + t.PetDto = RawToDto(t.Pet) + + t.CreatePetDto = &dto.CreatePetRequest{ + Pet: RawToDto(t.PetReq), + } + + t.UpdatePetDto = &dto.UpdatePetRequest{ + Pet: RawToDto(t.PetReq), + } + + t.UpdatePetReq = &petProto.UpdatePetRequest{ + Pet: t.Pet, + } + + t.ChangeViewedPetDto = &dto.ChangeViewPetRequest{ + Visible: false, + } + + t.ChangeViewPetReq = &petProto.ChangeViewPetRequest{ + Id: t.Pet.Id, + Visible: false, + } + + t.AdoptReq = &petProto.AdoptPetRequest{ + PetId: t.Pet.Id, + UserId: t.Pet.AdoptBy, + } + + t.UnavailableServiceErr = &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + + t.NotFoundErr = &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.PetNotFoundMessage, + Data: nil, + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + t.InvalidArgumentErr = &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgument, + Data: nil, + } +} + +func (t *PetServiceTest) TestFindAllSuccess() { + protoReq := &petProto.FindAllPetRequest{} + protoResp := &petProto.FindAllPetResponse{ + Pets: t.Pets, + } + + expected := t.Pets + + client := petMock.PetClientMock{} + client.On("FindAll", protoReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.FindAll() + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *PetServiceTest) TestFindAllUnavailableServiceError() { + protoReq := &petProto.FindAllPetRequest{} + + expected := t.UnavailableServiceErr + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + client := petMock.PetClientMock{} + client.On("FindAll", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindAll() + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestFindOneSuccess() { + protoReq := &petProto.FindOnePetRequest{ + Id: t.Pet.Id, + } + protoResp := &petProto.FindOnePetResponse{ + Pet: t.Pet, + } + + expected := t.Pet + + client := petMock.PetClientMock{} + client.On("FindOne", protoReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.FindOne(t.Pet.Id) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *PetServiceTest) TestFindOneNotFoundError() { + protoReq := &petProto.FindOnePetRequest{ + Id: t.Pet.Id, + } + + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + + expected := t.NotFoundErr + + client := petMock.PetClientMock{} + client.On("FindOne", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindOne(t.Pet.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestFindOneUnavailableServiceError() { + protoReq := &petProto.FindOnePetRequest{ + Id: t.Pet.Id, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := petMock.PetClientMock{} + client.On("FindOne", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindOne(t.Pet.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestCreateSuccess() { + protoReq := &petProto.CreatePetRequest{ + Pet: t.PetReq, + } + protoResp := &petProto.CreatePetResponse{ + Pet: t.Pet, + } + + expected := t.Pet + + client := &petMock.PetClientMock{} + client.On("Create", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Create(t.CreatePetDto) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *PetServiceTest) TestCreateInvalidArgumentError() { + protoReq := &petProto.CreatePetRequest{ + Pet: t.PetReq, + } + + expected := t.InvalidArgumentErr + + clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgument) + + client := &petMock.PetClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreatePetDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestCreateInternalError() { + protoReq := &petProto.CreatePetRequest{ + Pet: t.PetReq, + } + + expected := t.InternalErr + + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + + client := &petMock.PetClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreatePetDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestCreateUnavailableServiceError() { + protoReq := &petProto.CreatePetRequest{ + Pet: t.PetReq, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &petMock.PetClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreatePetDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestUpdateSuccess() { + protoReq := t.UpdatePetReq + protoResp := &petProto.UpdatePetResponse{ + Pet: t.Pet, + } + + expected := t.Pet + + client := &petMock.PetClientMock{} + client.On("Update", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *PetServiceTest) TestUpdateNotFound() { + protoReq := t.UpdatePetReq + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + + expected := t.NotFoundErr + + client := &petMock.PetClientMock{} + client.On("Update", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestUpdateUnavailableServiceError() { + protoReq := t.UpdatePetReq + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &petMock.PetClientMock{} + client.On("Update", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Update(t.Pet.Id, t.UpdatePetDto) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestDeleteSuccess() { + protoReq := &petProto.DeletePetRequest{ + Id: t.Pet.Id, + } + protoResp := &petProto.DeletePetResponse{ + Success: true, + } + + expected := true + + client := &petMock.PetClientMock{} + client.On("Delete", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Delete(t.Pet.Id) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *PetServiceTest) TestDeleteNotFound() { + protoReq := &petProto.DeletePetRequest{ + Id: t.Pet.Id, + } + protoResp := &petProto.DeletePetResponse{ + Success: false, + } + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + + expected := t.NotFoundErr + + client := &petMock.PetClientMock{} + client.On("Delete", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.Delete(t.Pet.Id) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestDeleteServiceUnavailableError() { + protoReq := &petProto.DeletePetRequest{ + Id: t.Pet.Id, + } + protoResp := &petProto.DeletePetResponse{ + Success: false, + } + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &petMock.PetClientMock{} + client.On("Delete", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.Delete(t.Pet.Id) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestChangeViewSuccess() { + protoReq := t.ChangeViewPetReq + protoResp := &petProto.ChangeViewPetResponse{ + Success: true, + } + + client := &petMock.PetClientMock{} + client.On("ChangeView", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + + assert.Nil(t.T(), err) + assert.True(t.T(), actual) +} + +func (t *PetServiceTest) TestChangeViewNotFoundError() { + protoReq := t.ChangeViewPetReq + protoResp := &petProto.ChangeViewPetResponse{ + Success: false, + } + + clientErr := status.Error(codes.NotFound, constant.PetNotFoundMessage) + + expected := t.NotFoundErr + + client := &petMock.PetClientMock{} + client.On("ChangeView", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *PetServiceTest) TestChangeViewUnavailableServiceError() { + protoReq := t.ChangeViewPetReq + protoResp := &petProto.ChangeViewPetResponse{ + Success: false, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &petMock.PetClientMock{} + client.On("ChangeView", protoReq).Return(protoResp, clientErr) + + svc := NewService(client) + actual, err := svc.ChangeView(t.Pet.Id, t.ChangeViewedPetDto) + + assert.False(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/constant/pet/pet.constant.go b/src/constant/pet/pet.constant.go index 34f4dc4..d8914fb 100644 --- a/src/constant/pet/pet.constant.go +++ b/src/constant/pet/pet.constant.go @@ -1,5 +1,11 @@ package pet +import ( + "encoding/json" + "errors" + "strings" +) + type Gender int const ( @@ -13,3 +19,41 @@ const ( ADOPTED = 1 FINDHOME = 2 ) + +func (g *Gender) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + s = strings.ToUpper(s) + switch s { + case "MALE": + *g = Gender(1) + return nil + case "FEMALE": + *g = Gender(2) + return nil + + default: + return errors.New("invalid gender") + } +} + +func (st *Status) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + s = strings.ToUpper(s) + switch s { + case "ADOPTED": + *st = Status(1) + return nil + case "FINDHOME": + *st = Status(2) + return nil + + default: + return errors.New("invalid gender") + } +} diff --git a/src/docs/docs.go b/src/docs/docs.go index 844894b..f838a43 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -1,4 +1,5 @@ -// Package docs Code generated by swaggo/swag. DO NOT EDIT +// Code generated by swaggo/swag. DO NOT EDIT. + package docs import "github.com/swaggo/swag" @@ -168,6 +169,64 @@ const docTemplate = `{ } } } + }, + "/v1/pet/": { + "get": { + "description": "Return the data of pets if successfully", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "find all pets", + "parameters": [ + { + "description": "pet dto", + "name": "signup", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PetDto" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.PetDto" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "409": { + "description": "Duplicate email", + "schema": { + "$ref": "#/definitions/dto.ResponseConflictErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } } }, "definitions": { @@ -200,6 +259,9 @@ const docTemplate = `{ } } }, + "dto.PetDto": { + "type": "object" + }, "dto.ResponseBadRequestErr": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index df757f4..f053b90 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -164,6 +164,64 @@ } } } + }, + "/v1/pet/": { + "get": { + "description": "Return the data of pets if successfully", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "auth" + ], + "summary": "find all pets", + "parameters": [ + { + "description": "pet dto", + "name": "signup", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.PetDto" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/dto.PetDto" + } + }, + "400": { + "description": "Invalid request body", + "schema": { + "$ref": "#/definitions/dto.ResponseBadRequestErr" + } + }, + "409": { + "description": "Duplicate email", + "schema": { + "$ref": "#/definitions/dto.ResponseConflictErr" + } + }, + "500": { + "description": "Internal service error", + "schema": { + "$ref": "#/definitions/dto.ResponseInternalErr" + } + }, + "503": { + "description": "Service is down", + "schema": { + "$ref": "#/definitions/dto.ResponseServiceDownErr" + } + } + } + } } }, "definitions": { @@ -196,6 +254,9 @@ } } }, + "dto.PetDto": { + "type": "object" + }, "dto.ResponseBadRequestErr": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index e4b0423..547d30d 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -19,6 +19,8 @@ definitions: example: e7e84d54-7518-4... type: string type: object + dto.PetDto: + type: object dto.ResponseBadRequestErr: properties: data: @@ -226,6 +228,44 @@ paths: summary: Signup user tags: - auth + /v1/pet/: + get: + consumes: + - application/json + description: Return the data of pets if successfully + parameters: + - description: pet dto + in: body + name: signup + required: true + schema: + $ref: '#/definitions/dto.PetDto' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/dto.PetDto' + "400": + description: Invalid request body + schema: + $ref: '#/definitions/dto.ResponseBadRequestErr' + "409": + description: Duplicate email + schema: + $ref: '#/definitions/dto.ResponseConflictErr' + "500": + description: Internal service error + schema: + $ref: '#/definitions/dto.ResponseInternalErr' + "503": + description: Service is down + schema: + $ref: '#/definitions/dto.ResponseServiceDownErr' + summary: find all pets + tags: + - auth schemes: - https - http diff --git a/src/main.go b/src/main.go index c0f0bc7..7d41818 100644 --- a/src/main.go +++ b/src/main.go @@ -3,27 +3,33 @@ package main import ( "context" "fmt" + "net/http" + "os" + "os/signal" + "sync" + "syscall" + "time" + authHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/auth" health_check "github.com/isd-sgcu/johnjud-gateway/src/app/handler/health-check" + petHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/pet" userHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/user" guard "github.com/isd-sgcu/johnjud-gateway/src/app/middleware/auth" "github.com/isd-sgcu/johnjud-gateway/src/app/router" authSrv "github.com/isd-sgcu/johnjud-gateway/src/app/service/auth" + imageSrv "github.com/isd-sgcu/johnjud-gateway/src/app/service/image" + petSrv "github.com/isd-sgcu/johnjud-gateway/src/app/service/pet" userSrv "github.com/isd-sgcu/johnjud-gateway/src/app/service/user" "github.com/isd-sgcu/johnjud-gateway/src/app/validator" "github.com/isd-sgcu/johnjud-gateway/src/config" "github.com/isd-sgcu/johnjud-gateway/src/constant/auth" auth_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" user_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" + pet_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + image_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "net/http" - "os" - "os/signal" - "sync" - "syscall" - "time" ) // @title JohnJud API @@ -60,13 +66,13 @@ func main() { Msg("Failed to start service") } - // backendConn, err := grpc.Dial(conf.Service.Backend, grpc.WithTransportCredentials(insecure.NewCredentials())) - // if err != nil { - // log.Fatal(). - // Err(err). - // Str("service", "johnjud-backend"). - // Msg("Cannot connect to service") - // } + backendConn, err := grpc.Dial(conf.Service.Backend, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + log.Fatal(). + Err(err). + Str("service", "johnjud-backend"). + Msg("Cannot connect to service") + } authConn, err := grpc.Dial(conf.Service.Auth, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { @@ -76,13 +82,13 @@ func main() { Msg("Cannot connect to service") } - // fileConn, err := grpc.Dial(conf.Service.File, grpc.WithTransportCredentials(insecure.NewCredentials())) - // if err != nil { - // log.Fatal(). - // Err(err). - // Str("service", "johnjud-file"). - // Msg("Cannot connect to service") - // } + fileConn, err := grpc.Dial(conf.Service.File, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + log.Fatal(). + Err(err). + Str("service", "johnjud-file"). + Msg("Cannot connect to service") + } hc := health_check.NewHandler() @@ -96,6 +102,13 @@ func main() { authGuard := guard.NewAuthGuard(authService, auth.ExcludePath, conf.App) + imageClient := image_proto.NewImageServiceClient(fileConn) + imageService := imageSrv.NewService(imageClient) + + petClient := pet_proto.NewPetServiceClient(backendConn) + petService := petSrv.NewService(petClient) + petHandler := petHdr.NewHandler(petService, imageService, v) + r := router.NewFiberRouter(&authGuard, conf.App) r.GetUser("/:id", userHandler.FindOne) @@ -109,6 +122,13 @@ func main() { r.GetHealthCheck("/", hc.HealthCheck) + r.GetPet("/", petHandler.FindAll) + r.GetPet("/:id", petHandler.FindOne) + r.PostPet("/create", petHandler.Create) + r.PutPet("/:id", petHandler.Update) + r.PutPet("/:id/visible", petHandler.ChangeView) + r.DeletePet("/:id", petHandler.Delete) + v1 := router.NewAPIv1(r, conf.App) go func() { diff --git a/src/mocks/client/pet/pet.mock.go b/src/mocks/client/pet/pet.mock.go new file mode 100644 index 0000000..5148750 --- /dev/null +++ b/src/mocks/client/pet/pet.mock.go @@ -0,0 +1,80 @@ +package pet + +import ( + "context" + + petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" +) + +type PetClientMock struct { + mock.Mock +} + +func (c *PetClientMock) AdoptPet(ctx context.Context, in *petProto.AdoptPetRequest, opts ...grpc.CallOption) (res *petProto.AdoptPetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.AdoptPetResponse) + } + return res, args.Error(1) +} + +func (c *PetClientMock) FindAll(ctx context.Context, in *petProto.FindAllPetRequest, opts ...grpc.CallOption) (res *petProto.FindAllPetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.FindAllPetResponse) + } + return res, args.Error(1) +} + +func (c *PetClientMock) FindOne(ctx context.Context, in *petProto.FindOnePetRequest, opts ...grpc.CallOption) (res *petProto.FindOnePetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.FindOnePetResponse) + } + return res, args.Error(1) +} + +func (c *PetClientMock) Create(ctx context.Context, in *petProto.CreatePetRequest, opts ...grpc.CallOption) (res *petProto.CreatePetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.CreatePetResponse) + } + + return res, args.Error(1) +} + +func (c *PetClientMock) Update(ctx context.Context, in *petProto.UpdatePetRequest, opts ...grpc.CallOption) (res *petProto.UpdatePetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.UpdatePetResponse) + } + + return res, args.Error(1) +} + +func (c *PetClientMock) ChangeView(ctx context.Context, in *petProto.ChangeViewPetRequest, opts ...grpc.CallOption) (res *petProto.ChangeViewPetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.ChangeViewPetResponse) + } + + return res, args.Error(1) +} + +func (c *PetClientMock) Delete(ctx context.Context, in *petProto.DeletePetRequest, opts ...grpc.CallOption) (res *petProto.DeletePetResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*petProto.DeletePetResponse) + } + + return res, args.Error(1) +} diff --git a/src/mocks/service/image/image.mock.go b/src/mocks/service/image/image.mock.go new file mode 100644 index 0000000..09a1ae0 --- /dev/null +++ b/src/mocks/service/image/image.mock.go @@ -0,0 +1,81 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./src/pkg/service/image/image.service.go + +// Package mock_image is a generated GoMock package. +package mock_image + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + v1 "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// MockServiceMockRecorder is the mock recorder for MockService. +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance. +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// Delete mocks base method. +func (m *MockService) Delete(id string) (bool, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", id) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockServiceMockRecorder) Delete(id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), id) +} + +// FindByPetId mocks base method. +func (m *MockService) FindByPetId(id string) ([]*v1.Image, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindByPetId", id) + ret0, _ := ret[0].([]*v1.Image) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// FindByPetId indicates an expected call of FindByPetId. +func (mr *MockServiceMockRecorder) FindByPetId(id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByPetId", reflect.TypeOf((*MockService)(nil).FindByPetId), id) +} + +// Upload mocks base method. +func (m *MockService) Upload(in *dto.ImageDto) (*v1.Image, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Upload", in) + ret0, _ := ret[0].(*v1.Image) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Upload indicates an expected call of Upload. +func (mr *MockServiceMockRecorder) Upload(in interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upload", reflect.TypeOf((*MockService)(nil).Upload), in) +} diff --git a/src/mocks/service/pet/pet.mock.go b/src/mocks/service/pet/pet.mock.go new file mode 100644 index 0000000..617c149 --- /dev/null +++ b/src/mocks/service/pet/pet.mock.go @@ -0,0 +1,141 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./src/pkg/service/pet/pet.service.go + +// Package mock_pet is a generated GoMock package. +package mock_pet + +import ( + reflect "reflect" + + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + v1 "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + gomock "github.com/golang/mock/gomock" +) + +// MockService is a mock of Service interface. +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// MockServiceMockRecorder is the mock recorder for MockService. +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance. +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// Adopt mocks base method. +func (m *MockService) Adopt(arg0 *dto.AdoptDto) (bool, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Adopt", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Adopt indicates an expected call of Adopt. +func (mr *MockServiceMockRecorder) Adopt(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Adopt", reflect.TypeOf((*MockService)(nil).Adopt), arg0) +} + +// ChangeView mocks base method. +func (m *MockService) ChangeView(arg0 string, arg1 *dto.ChangeViewPetRequest) (bool, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChangeView", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// ChangeView indicates an expected call of ChangeView. +func (mr *MockServiceMockRecorder) ChangeView(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeView", reflect.TypeOf((*MockService)(nil).ChangeView), arg0, arg1) +} + +// Create mocks base method. +func (m *MockService) Create(arg0 *dto.CreatePetRequest) (*v1.Pet, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(*v1.Pet) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockServiceMockRecorder) Create(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockService)(nil).Create), arg0) +} + +// Delete mocks base method. +func (m *MockService) Delete(arg0 string) (bool, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockServiceMockRecorder) Delete(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockService)(nil).Delete), arg0) +} + +// FindAll mocks base method. +func (m *MockService) FindAll() ([]*v1.Pet, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindAll") + ret0, _ := ret[0].([]*v1.Pet) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// FindAll indicates an expected call of FindAll. +func (mr *MockServiceMockRecorder) FindAll() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAll", reflect.TypeOf((*MockService)(nil).FindAll)) +} + +// FindOne mocks base method. +func (m *MockService) FindOne(arg0 string) (*v1.Pet, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindOne", arg0) + ret0, _ := ret[0].(*v1.Pet) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// FindOne indicates an expected call of FindOne. +func (mr *MockServiceMockRecorder) FindOne(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockService)(nil).FindOne), arg0) +} + +// Update mocks base method. +func (m *MockService) Update(arg0 string, arg1 *dto.UpdatePetRequest) (*v1.Pet, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0, arg1) + ret0, _ := ret[0].(*v1.Pet) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockServiceMockRecorder) Update(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockService)(nil).Update), arg0, arg1) +} diff --git a/src/pkg/service/image/image.service.go b/src/pkg/service/image/image.service.go new file mode 100644 index 0000000..4b68d29 --- /dev/null +++ b/src/pkg/service/image/image.service.go @@ -0,0 +1,12 @@ +package image + +import ( + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1" +) + +type Service interface { + FindByPetId(string) ([]*proto.Image, *dto.ResponseErr) + Upload(*dto.ImageDto) (*proto.Image, *dto.ResponseErr) + Delete(string) (bool, *dto.ResponseErr) +} diff --git a/src/pkg/service/pet/pet.service.go b/src/pkg/service/pet/pet.service.go new file mode 100644 index 0000000..adc60a8 --- /dev/null +++ b/src/pkg/service/pet/pet.service.go @@ -0,0 +1,17 @@ +package pet + +import ( + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + + proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" +) + +type Service interface { + FindAll() ([]*proto.Pet, *dto.ResponseErr) + FindOne(string) (*proto.Pet, *dto.ResponseErr) + Create(*dto.CreatePetRequest) (*proto.Pet, *dto.ResponseErr) + Update(string, *dto.UpdatePetRequest) (*proto.Pet, *dto.ResponseErr) + Delete(string) (bool, *dto.ResponseErr) + ChangeView(string, *dto.ChangeViewPetRequest) (bool, *dto.ResponseErr) + Adopt(*dto.AdoptDto) (bool, *dto.ResponseErr) +}