diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a0e9ba1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,55 @@ +name: Build + +on: + workflow_dispatch: + push: + branches: + - main + - beta + - dev + - master + +env: + IMAGE_NAME: ghcr.io/${{ github.repository }} + IMAGE_TAG: ${{ github.sha }} + +jobs: + build: + name: Build + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + outputs: + BRANCH: ${{ steps.branch.outputs.BRANCH }} + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Set branch + id: branch + run: | + echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + + - name: Log in to the Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push Docker Image + uses: docker/build-push-action@v2 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }},${{ env.IMAGE_NAME }}:latest + cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max \ No newline at end of file diff --git a/Makefile b/Makefile index 6e0a369..e54dade 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ 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/like/like.service.go -destination ./src/mocks/service/like/like.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/README.md b/README.md index dbcdec0..9507431 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Johnjud-gateway +Johnjud-gateway is a routing and request handling service for the Johnjud project. + +### What is Johnjud? +Johnjud is a pet adoption web application of the [CUVET For Animal Welfare Club](https://www.facebook.com/CUVETforAnimalWelfareClub) + ## Stack - golang @@ -17,7 +22,7 @@ ### Installation 1. Clone this repo -2. Copy `config.example.yaml` in `config` and paste it in the same directory with `.example` removed from its name. +2. Copy every `config.example.yaml` in `config` and paste it in the same directory with `.example` removed from its name. 3. Run `go mod download` to download all the dependencies. @@ -27,3 +32,12 @@ ### Testing 1. Run `make test` or `go test -v -coverpkg ./... -coverprofile coverage.out -covermode count ./...` + +## Other microservices/repositories of Johnjud +- [Johnjud-gateway](https://github.com/isd-sgcu/johnjud-gateway): Routing and request handling +- [Johnjud-auth](https://github.com/isd-sgcu/johnjud-auth): Authentication and authorization +- [Johnjud-backend](https://github.com/isd-sgcu/johnjud-backend): Main business logic +- [Johnjud-file](https://github.com/isd-sgcu/johnjud-file): File management service +- [Johnjud-proto](https://github.com/isd-sgcu/johnjud-proto): Protobuf files generator +- [Johnjud-go-proto](https://github.com/isd-sgcu/johnjud-go-proto): Generated protobuf files for golang +- [Johnjud-frontend](https://github.com/isd-sgcu/johnjud-frontend): Frontend web application diff --git a/config/auth/config.example.yaml b/config/auth/config.example.yaml new file mode 100644 index 0000000..ad75341 --- /dev/null +++ b/config/auth/config.example.yaml @@ -0,0 +1,23 @@ +app: + port: 3002 + debug: true + secret: + +database: + host: localhost + port: 5432 + name: johnjud_db + username: root + password: root + +jwt: + secret: + expires_in: 3600 + refresh_token_ttl: 604800 + issuer: + +redis: + host: localhost + port: 6379 + password: "" + dbnum: 0 \ No newline at end of file diff --git a/config/backend/config.example.yaml b/config/backend/config.example.yaml new file mode 100644 index 0000000..e39ad3a --- /dev/null +++ b/config/backend/config.example.yaml @@ -0,0 +1,13 @@ +app: + port: 3003 + debug: true + +database: + host: local-db + port: 5432 + name: johnjud_db + username: root + password: root + +service: + file: file:3004 \ No newline at end of file diff --git a/config/file/config.example.yaml b/config/file/config.example.yaml new file mode 100644 index 0000000..f1ecd10 --- /dev/null +++ b/config/file/config.example.yaml @@ -0,0 +1,14 @@ +app: + port: 3004 + debug: true + +database: + host: local-db + port: 5432 + name: johnjud_db + username: root + password: root + +s3: + bucket_name: + region: \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d911259 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,80 @@ +version: "3.9" + +services: + local-auth: + image: ghcr.io/isd-sgcu/johnjud-auth + container_name: auth + depends_on: + - local-db + - local-cache + restart: unless-stopped + networks: + - johnjud-local + - database + volumes: + - ./config/auth:/app/config + ports: + - "3002:3002" + + local-backend: + image: ghcr.io/isd-sgcu/johnjud-backend + container_name: backend + depends_on: + - local-db + - local-cache + restart: unless-stopped + networks: + - johnjud-local + - database + volumes: + - ./config/backend:/app/config + ports: + - "3003:3003" + + local-file: + image: ghcr.io/isd-sgcu/johnjud-file + container_name: file + depends_on: + - local-db + - local-cache + restart: unless-stopped + networks: + - johnjud-local + - database + volumes: + - ./config/file:/app/config + ports: + - "3004:3004" + + local-db: + image: postgres:15.1-alpine3.17 + container_name: local-db + restart: unless-stopped + environment: + POSTGRES_USER: root + POSTGRES_PASSWORD: root + POSTGRES_DB: johnjud_db + networks: + - database + volumes: + - ./volumes/postgres:/var/lib/postgresql/data + ports: + - "5432:5432" + + local-cache: + image: redis:7.2.3-alpine + container_name: local-cache + restart: unless-stopped + environment: + REDIS_HOST: localhost + ALLOW_EMPTY_PASSWORD: "yes" + networks: + - database + ports: + - "6379:6379" + +networks: + johnjud-local: + name: johnjud-local + database: + name: database diff --git a/go.mod b/go.mod index cbd3c05..c0a6d31 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( 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/gofiber/fiber/v2 v2.52.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 @@ -23,18 +23,18 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect + github.com/andybalholm/brotli v1.0.6 // 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-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/go-openapi/swag v0.22.7 // 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 - github.com/klauspost/compress v1.17.0 // indirect + github.com/klauspost/compress v1.17.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -44,7 +44,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -53,16 +53,16 @@ require ( github.com/spf13/pflag v1.0.5 // indirect 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/files v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.50.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.9.0 // indirect 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/net v0.19.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect diff --git a/go.sum b/go.sum index 69ab4da..d5858c6 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 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/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= +github.com/andybalholm/brotli v1.0.6/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= @@ -39,8 +39,8 @@ github.com/go-openapi/spec v0.20.13 h1:XJDIN+dLH6vqXgafnl5SUIMnzaChQ6QTo0/UPMbkI 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/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= +github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8= +github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -51,8 +51,8 @@ github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqR github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4= -github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ= -github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U= +github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE= +github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= 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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -72,8 +72,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -113,8 +113,9 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 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/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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= @@ -152,8 +153,9 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= 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= @@ -161,38 +163,45 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= -github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= -github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 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= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -204,17 +213,22 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/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= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -222,6 +236,7 @@ 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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= diff --git a/src/app/constant/error.constant.go b/src/app/constant/error.constant.go index cf607bc..6b9a24a 100644 --- a/src/app/constant/error.constant.go +++ b/src/app/constant/error.constant.go @@ -8,6 +8,8 @@ const UnauthorizedMessage = "Unauthorized" const DuplicateEmailMessage = "Duplicate Email" const InternalErrorMessage = "Internal Error" const UnavailableServiceMessage = "Unavailable Service" +const InvalidIDMessage = "Invalid ID" +const InvalidArgumentMessage = "Invalid Argument" const PetNotFoundMessage = "Pet not found" -const InvalidArgument = "Invalid Argument" +const UserNotFoundMessage = "User not found" diff --git a/src/app/dto/like.dto.go b/src/app/dto/like.dto.go index 3caf974..9a1002f 100644 --- a/src/app/dto/like.dto.go +++ b/src/app/dto/like.dto.go @@ -1,10 +1,23 @@ package dto -import ( - "github.com/google/uuid" -) +type LikeResponse struct { + UserID string `json:"user_id"` + PetID string `json:"pet_id"` +} + +type FindLikeRequest struct { + UserID string `json:"user_id" validate:"required"` +} + +type CreateLikeRequest struct { + UserID string `json:"user_id" validate:"required"` + PetID string `json:"pet_id" validate:"required"` +} + +type DeleteLikeRequest struct { + Id string `json:"id" validate:"required"` +} -type LikeDto struct { - UserID uuid.UUID `json:"user_id" validate:"required"` - PetID uuid.UUID `json:"pet_id" validate:"required"` +type DeleteLikeResponse struct { + Success bool `json:"success"` } diff --git a/src/app/handler/auth/auth.handler_test.go b/src/app/handler/auth/auth.handler_test.go index 979aa9e..3a73e40 100644 --- a/src/app/handler/auth/auth.handler_test.go +++ b/src/app/handler/auth/auth.handler_test.go @@ -2,17 +2,18 @@ package auth import ( "errors" + "net/http" + "testing" + "github.com/go-faker/faker/v4" "github.com/golang/mock/gomock" "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - mock_router "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" - mock_auth "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/auth" - mock_user "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/user" - mock_validator "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" + authMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/auth" + userMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/user" + validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" "github.com/stretchr/testify/suite" - "net/http" - "testing" ) type AuthHandlerTest struct { @@ -62,10 +63,10 @@ func (t *AuthHandlerTest) TestSignupSuccess() { } controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signupRequest).Return(nil) validator.EXPECT().Validate(t.signupRequest).Return(nil) @@ -86,10 +87,10 @@ func (t *AuthHandlerTest) TestSignupBindFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signupRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) @@ -108,10 +109,10 @@ func (t *AuthHandlerTest) TestSignupValidateFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signupRequest).Return(nil) validator.EXPECT().Validate(t.signupRequest).Return(t.validateErr) @@ -131,10 +132,10 @@ func (t *AuthHandlerTest) TestSignupServiceError() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signupRequest).Return(nil) validator.EXPECT().Validate(t.signupRequest).Return(nil) @@ -155,10 +156,10 @@ func (t *AuthHandlerTest) TestSignInSuccess() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signInRequest).Return(nil) validator.EXPECT().Validate(t.signInRequest).Return(nil) @@ -179,10 +180,10 @@ func (t *AuthHandlerTest) TestSignInBindFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signInRequest).Return(t.bindErr) context.EXPECT().JSON(http.StatusBadRequest, errResponse) @@ -201,10 +202,10 @@ func (t *AuthHandlerTest) TestSignInValidateFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signInRequest).Return(nil) validator.EXPECT().Validate(t.signInRequest).Return(t.validateErr) @@ -224,10 +225,10 @@ func (t *AuthHandlerTest) TestSignInServiceError() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.signInRequest).Return(nil) validator.EXPECT().Validate(t.signInRequest).Return(nil) @@ -247,10 +248,10 @@ func (t *AuthHandlerTest) TestSignOutSuccess() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Token().Return(token) authSvc.EXPECT().SignOut(token).Return(signOutResponse, nil) @@ -271,10 +272,10 @@ func (t *AuthHandlerTest) TestSignOutServiceError() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) handler := NewHandler(authSvc, userSvc, validator) @@ -294,10 +295,10 @@ func (t *AuthHandlerTest) TestRefreshTokenSuccess() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) handler := NewHandler(authSvc, userSvc, validator) @@ -318,10 +319,10 @@ func (t *AuthHandlerTest) TestRefreshTokenBindFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) handler := NewHandler(authSvc, userSvc, validator) @@ -340,10 +341,10 @@ func (t *AuthHandlerTest) TestRefreshTokenValidateFailed() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) handler := NewHandler(authSvc, userSvc, validator) @@ -363,10 +364,10 @@ func (t *AuthHandlerTest) TestRefreshTokenServiceError() { controller := gomock.NewController(t.T()) - authSvc := mock_auth.NewMockService(controller) - userSvc := mock_user.NewMockService(controller) - validator := mock_validator.NewMockIDtoValidator(controller) - context := mock_router.NewMockIContext(controller) + authSvc := authMock.NewMockService(controller) + userSvc := userMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) handler := NewHandler(authSvc, userSvc, validator) diff --git a/src/app/handler/health-check/health-check.handler.go b/src/app/handler/healthcheck/healthcheck.handler.go similarity index 93% rename from src/app/handler/health-check/health-check.handler.go rename to src/app/handler/healthcheck/healthcheck.handler.go index 8685808..25dd99c 100644 --- a/src/app/handler/health-check/health-check.handler.go +++ b/src/app/handler/healthcheck/healthcheck.handler.go @@ -1,4 +1,4 @@ -package health_check +package healthcheck import ( "net/http" diff --git a/src/app/handler/image/image.handler.go b/src/app/handler/image/image.handler.go index 552498b..7e496cb 100644 --- a/src/app/handler/image/image.handler.go +++ b/src/app/handler/image/image.handler.go @@ -1,24 +1,17 @@ package auth import ( - "github.com/isd-sgcu/johnjud-gateway/src/app/dto" "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/file/image/v1" + imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" ) type Handler struct { - service Service + service imageSvc.Service validate *validator.DtoValidator } -type Service interface { - FindByPetId(string) ([]*proto.Image, *dto.ResponseErr) - Upload(*dto.ImageDto) (*proto.Image, *dto.ResponseErr) - Delete(string) (bool, *dto.ResponseErr) -} - -func NewHandler(service Service, validate *validator.DtoValidator) *Handler { +func NewHandler(service imageSvc.Service, validate *validator.DtoValidator) *Handler { return &Handler{service, validate} } diff --git a/src/app/handler/like/like.handler.go b/src/app/handler/like/like.handler.go index d01bf03..ab57fd8 100644 --- a/src/app/handler/like/like.handler.go +++ b/src/app/handler/like/like.handler.go @@ -1,35 +1,111 @@ package auth import ( + "net/http" + "strings" + + "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/app/router" "github.com/isd-sgcu/johnjud-gateway/src/app/validator" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + likeConst "github.com/isd-sgcu/johnjud-gateway/src/constant/like" + likeSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/like" ) type Handler struct { - service Service - validate *validator.DtoValidator -} - -type Service interface { - FindByUserId(string) ([]*proto.Like, *dto.ResponseErr) - Create(*dto.LikeDto) (*proto.Like, *dto.ResponseErr) - Delete(string) (bool, *dto.ResponseErr) + service likeSvc.Service + validate validator.IDtoValidator } -func NewHandler(service Service, validate *validator.DtoValidator) *Handler { +func NewHandler(service likeSvc.Service, validate validator.IDtoValidator) *Handler { return &Handler{service, validate} } -func (h *Handler) FindByUserId(c *router.FiberCtx) { +func (h *Handler) FindByUserId(c router.IContext) { + id, err := c.Param("id") + if err != nil { + c.JSON(http.StatusBadRequest, dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InvalidIDMessage, + Data: nil, + }) + return + } + + response, respErr := h.service.FindByUserId(id) + if respErr != nil { + c.JSON(respErr.StatusCode, respErr) + return + } + c.JSON(http.StatusOK, dto.ResponseSuccess{ + StatusCode: http.StatusOK, + Message: likeConst.FindLikeSuccessMessage, + Data: response, + }) + return } -func (h *Handler) Create(c *router.FiberCtx) { +func (h *Handler) Create(c router.IContext) { + request := &dto.CreateLikeRequest{} + 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, dto.ResponseSuccess{ + StatusCode: http.StatusCreated, + Message: likeConst.CreateLikeSuccessMessage, + Data: response, + }) + return } -func (h *Handler) Delete(c *router.FiberCtx) { +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, dto.ResponseSuccess{ + StatusCode: http.StatusOK, + Message: likeConst.DelteLikeSuccessMessage, + Data: res, + }) + return } diff --git a/src/app/handler/like/like.handler_test.go b/src/app/handler/like/like.handler_test.go new file mode 100644 index 0000000..db72655 --- /dev/null +++ b/src/app/handler/like/like.handler_test.go @@ -0,0 +1,280 @@ +package auth + +import ( + "net/http" + "testing" + + "github.com/bxcodec/faker/v4" + "github.com/golang/mock/gomock" + errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" + likeConst "github.com/isd-sgcu/johnjud-gateway/src/constant/like" + routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" + likeMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/like" + validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + "github.com/stretchr/testify/suite" +) + +type LikeHandlerTest struct { + suite.Suite + Likes []*likeProto.Like + Like *likeProto.Like + LikeResponse *dto.LikeResponse + CreateLikeRequest *dto.CreateLikeRequest + DeleteLikeRequest *dto.DeleteLikeRequest + NotFoundErr *dto.ResponseErr + + UnavailableServiceErr *dto.ResponseErr + InvalidArgumentErr *dto.ResponseErr + BindErr *dto.ResponseErr + InternalErr *dto.ResponseErr +} + +func TestLikeHandler(t *testing.T) { + suite.Run(t, new(LikeHandlerTest)) +} + +func (t *LikeHandlerTest) SetupTest() { + var likes []*likeProto.Like + for i := 0; i <= 3; i++ { + like := &likeProto.Like{ + Id: faker.UUIDDigit(), + UserId: faker.UUIDDigit(), + PetId: faker.UUIDDigit(), + } + likes = append(likes, like) + } + + t.Likes = likes + t.Like = likes[0] + + t.CreateLikeRequest = &dto.CreateLikeRequest{} + t.DeleteLikeRequest = &dto.DeleteLikeRequest{} + + t.NotFoundErr = &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: errConst.UserNotFoundMessage, + Data: nil, + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: errConst.InternalErrorMessage, + Data: nil, + } + + t.UnavailableServiceErr = &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: errConst.UnavailableServiceMessage, + Data: nil, + } +} + +func (t *LikeHandlerTest) TestFindLikesSuccess() { + findLikeResponse := utils.ProtoToDtoList(t.Likes) + expectedResponse := dto.ResponseSuccess{ + StatusCode: http.StatusOK, + Message: likeConst.FindLikeSuccessMessage, + Data: findLikeResponse, + } + + controller := gomock.NewController(t.T()) + + likeSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + likeSvc.EXPECT().FindByUserId(t.Like.UserId).Return(utils.ProtoToDtoList(t.Likes), nil) + context.EXPECT().JSON(http.StatusOK, expectedResponse) + + handler := NewHandler(likeSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestFindLikeNotFoundError() { + findLikeErrorResponse := t.NotFoundErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) + context.EXPECT().JSON(http.StatusNotFound, findLikeErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestFindLikeServiceUnavailableError() { + findLikeErrorResponse := t.UnavailableServiceErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, findLikeErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestFindLikeInternalError() { + findLikeErrorResponse := t.InternalErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, findLikeErrorResponse) + context.EXPECT().JSON(http.StatusInternalServerError, findLikeErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestCreateSuccess() { + createLikeResponse := utils.ProtoToDto(t.Like) + expectedResponse := dto.ResponseSuccess{ + StatusCode: http.StatusCreated, + Message: likeConst.CreateLikeSuccessMessage, + Data: createLikeResponse, + } + + controller := gomock.NewController(t.T()) + + likeSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) + validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) + likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(createLikeResponse, nil) + context.EXPECT().JSON(http.StatusCreated, expectedResponse) + + handler := NewHandler(likeSvc, validator) + handler.Create(context) +} + +func (t *LikeHandlerTest) TestCreateUnavailableServiceError() { + createLikeErrorResponse := t.UnavailableServiceErr + + controller := gomock.NewController(t.T()) + + likeSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) + validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) + likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(nil, createLikeErrorResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, createLikeErrorResponse) + + handler := NewHandler(likeSvc, validator) + handler.Create(context) +} + +func (t *LikeHandlerTest) TestCreateInternalError() { + createLikeErrorResponse := t.InternalErr + + controller := gomock.NewController(t.T()) + + likeSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Bind(t.CreateLikeRequest).Return(nil) + validator.EXPECT().Validate(t.CreateLikeRequest).Return(nil) + likeSvc.EXPECT().Create(t.CreateLikeRequest).Return(nil, createLikeErrorResponse) + context.EXPECT().JSON(http.StatusInternalServerError, createLikeErrorResponse) + + handler := NewHandler(likeSvc, validator) + handler.Create(context) +} + +func (t *LikeHandlerTest) TestDeleteSuccess() { + deleteResponse := &dto.DeleteLikeResponse{ + Success: true, + } + expectedResponse := dto.ResponseSuccess{ + StatusCode: http.StatusOK, + Message: likeConst.DelteLikeSuccessMessage, + Data: deleteResponse, + } + + controller := gomock.NewController(t.T()) + + likeSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + likeSvc.EXPECT().Delete(t.Like.UserId).Return(deleteResponse, nil) + context.EXPECT().JSON(http.StatusOK, expectedResponse) + + handler := NewHandler(likeSvc, validator) + handler.Delete(context) +} + +func (t *LikeHandlerTest) TestDeleteNotFoundError() { + deleteErrorResponse := t.NotFoundErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) + context.EXPECT().JSON(http.StatusNotFound, deleteErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestDeleteServiceUnavailableError() { + deleteErrorResponse := t.UnavailableServiceErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) + context.EXPECT().JSON(http.StatusServiceUnavailable, deleteErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} + +func (t *LikeHandlerTest) TestDeleteInternalError() { + deleteErrorResponse := t.InternalErr + + controller := gomock.NewController(t.T()) + + petSvc := likeMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) + + context.EXPECT().Param("id").Return(t.Like.UserId, nil) + petSvc.EXPECT().FindByUserId(t.Like.UserId).Return(nil, deleteErrorResponse) + context.EXPECT().JSON(http.StatusInternalServerError, deleteErrorResponse) + + handler := NewHandler(petSvc, validator) + handler.FindByUserId(context) +} diff --git a/src/app/handler/pet/pet.handler.go b/src/app/handler/pet/pet.handler.go index eff98c0..7dae48c 100644 --- a/src/app/handler/pet/pet.handler.go +++ b/src/app/handler/pet/pet.handler.go @@ -6,29 +6,20 @@ import ( "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" petconst "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + imageSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/image" + petSvc "github.com/isd-sgcu/johnjud-gateway/src/pkg/service/pet" ) type Handler struct { - service Service - imageService imageSrv.Service + service petSvc.Service + imageService imageSvc.Service validate validator.IDtoValidator } -type Service interface { - FindAll() ([]*dto.PetResponse, *dto.ResponseErr) - FindOne(string) (*dto.PetResponse, *dto.ResponseErr) - Create(*dto.CreatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - Update(string, *dto.UpdatePetRequest) (*dto.PetResponse, *dto.ResponseErr) - ChangeView(string, *dto.ChangeViewPetRequest) (*dto.ChangeViewPetResponse, *dto.ResponseErr) - Delete(string) (*dto.DeleteResponse, *dto.ResponseErr) - Adopt(string, *dto.AdoptByRequest) (*dto.AdoptByResponse, *dto.ResponseErr) -} - -func NewHandler(service Service, imageService imageSrv.Service, validate validator.IDtoValidator) *Handler { +func NewHandler(service petSvc.Service, imageService imageSvc.Service, validate validator.IDtoValidator) *Handler { return &Handler{service, imageService, validate} } @@ -74,7 +65,7 @@ func (h *Handler) FindOne(c router.IContext) { if err != nil { c.JSON(http.StatusInternalServerError, dto.ResponseErr{ StatusCode: http.StatusInternalServerError, - Message: "Invalid ID", + Message: constant.InvalidIDMessage, Data: nil, }) return diff --git a/src/app/handler/pet/pet.handler_test.go b/src/app/handler/pet/pet.handler_test.go index 152626b..ad5e326 100644 --- a/src/app/handler/pet/pet.handler_test.go +++ b/src/app/handler/pet/pet.handler_test.go @@ -9,22 +9,24 @@ import ( "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" + routerMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/router" + imageMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/image" + petMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/service/pet" + validatorMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/validator" + errConst "github.com/isd-sgcu/johnjud-gateway/src/app/constant" utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/pet" - petconst "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" - 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" + petConst "github.com/isd-sgcu/johnjud-gateway/src/constant/pet" + petProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/pet/v1" + imgProto "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 + Pet *petProto.Pet + Pets []*petProto.Pet PetDto *dto.PetResponse CreatePetRequest *dto.CreatePetRequest ChangeViewPetRequest *dto.ChangeViewPetRequest @@ -34,8 +36,8 @@ type PetHandlerTest struct { NotFoundErr *dto.ResponseErr ServiceDownErr *dto.ResponseErr InternalErr *dto.ResponseErr - Images []*image_proto.Image - ImagesList [][]*image_proto.Image + Images []*imgProto.Image + ImagesList [][]*imgProto.Image } func TestPetHandler(t *testing.T) { @@ -46,19 +48,19 @@ func (t *PetHandlerTest) SetupTest() { imagesList := utils.MockImageList(3) t.ImagesList = imagesList t.Images = imagesList[0] - var pets []*pet_proto.Pet + var pets []*petProto.Pet for i := 0; i <= 3; i++ { - pet := &pet_proto.Pet{ + pet := &petProto.Pet{ Id: faker.UUIDDigit(), Type: faker.Word(), Species: faker.Word(), Name: faker.Name(), Birthdate: faker.Word(), - Gender: pet_proto.Gender(rand.Intn(1) + 1), + Gender: petProto.Gender(rand.Intn(1) + 1), Habit: faker.Paragraph(), Caption: faker.Paragraph(), - Images: []*image_proto.Image{}, - Status: pet_proto.PetStatus(rand.Intn(1) + 1), + Images: []*imgProto.Image{}, + Status: petProto.PetStatus(rand.Intn(1) + 1), IsSterile: true, IsVaccinated: true, IsVisible: true, @@ -111,36 +113,36 @@ func (t *PetHandlerTest) SetupTest() { t.NotFoundErr = &dto.ResponseErr{ StatusCode: http.StatusNotFound, - Message: "Pet not found", + Message: errConst.PetNotFoundMessage, Data: nil, } t.BindErr = &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: "Invalid ID", + Message: errConst.InvalidIDMessage, } t.InternalErr = &dto.ResponseErr{ StatusCode: http.StatusInternalServerError, - Message: "Internal Server Error", + Message: errConst.InternalErrorMessage, Data: nil, } } func (t *PetHandlerTest) TestFindAllSuccess() { - findAllResponse := utils.RawToDtoList(t.Pets, t.ImagesList) + findAllResponse := utils.ProtoToDtoList(t.Pets, t.ImagesList) expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.FindAllPetSuccessMessage, + Message: petConst.FindAllPetSuccessMessage, Data: findAllResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) petSvc.EXPECT().FindAll().Return(findAllResponse, nil) context.EXPECT().JSON(http.StatusOK, expectedResponse) @@ -153,16 +155,16 @@ func (t *PetHandlerTest) TestFindOneSuccess() { findOneResponse := utils.ProtoToDto(t.Pet, t.Images) expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.FindOnePetSuccessMessage, + Message: petConst.FindOnePetSuccessMessage, Data: findOneResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().FindOne(t.Pet.Id).Return(findOneResponse, nil) @@ -177,10 +179,10 @@ func (t *PetHandlerTest) TestFindOneNotFoundErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) @@ -195,10 +197,10 @@ func (t *PetHandlerTest) TestFindOneGrpcErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().FindOne(t.Pet.Id).Return(nil, findOneResponse) @@ -212,16 +214,16 @@ func (t *PetHandlerTest) TestCreateSuccess() { createResponse := utils.ProtoToDto(t.Pet, t.Images) expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusCreated, - Message: petconst.CreatePetSuccessMessage, + Message: petConst.CreatePetSuccessMessage, Data: createResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.CreatePetRequest).Return(nil) validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) @@ -237,10 +239,10 @@ func (t *PetHandlerTest) TestCreateGrpcErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Bind(t.CreatePetRequest).Return(nil) validator.EXPECT().Validate(t.CreatePetRequest).Return(nil) @@ -255,16 +257,16 @@ func (t *PetHandlerTest) TestUpdateSuccess() { updateResponse := utils.ProtoToDto(t.Pet, t.Images) expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.UpdatePetSuccessMessage, + Message: petConst.UpdatePetSuccessMessage, Data: updateResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) @@ -281,10 +283,10 @@ func (t *PetHandlerTest) TestUpdateNotFound() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) @@ -301,10 +303,10 @@ func (t *PetHandlerTest) TestUpdateGrpcErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.UpdatePetRequest).Return(nil) @@ -322,16 +324,16 @@ func (t *PetHandlerTest) TestDeleteSuccess() { } expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.DeletePetSuccessMessage, + Message: petConst.DeletePetSuccessMessage, Data: deleteResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, nil) @@ -347,10 +349,10 @@ func (t *PetHandlerTest) TestDeleteNotFound() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.NotFoundErr) @@ -367,10 +369,10 @@ func (t *PetHandlerTest) TestDeleteGrpcErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) petSvc.EXPECT().Delete(t.Pet.Id).Return(deleteResponse, t.ServiceDownErr) @@ -386,16 +388,16 @@ func (t *PetHandlerTest) TestChangeViewSuccess() { } expectedResponse := dto.ResponseSuccess{ StatusCode: http.StatusOK, - Message: petconst.ChangeViewPetSuccessMessage, + Message: petConst.ChangeViewPetSuccessMessage, Data: changeViewResponse, } 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.ChangeViewPetRequest).Return(nil) @@ -414,10 +416,10 @@ func (t *PetHandlerTest) TestChangeViewNotFound() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.ChangeViewPetRequest).Return(nil) @@ -436,10 +438,10 @@ func (t *PetHandlerTest) TestChangeViewGrpcErr() { 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 := petMock.NewMockService(controller) + imageSvc := imageMock.NewMockService(controller) + validator := validatorMock.NewMockIDtoValidator(controller) + context := routerMock.NewMockIContext(controller) context.EXPECT().Param("id").Return(t.Pet.Id, nil) context.EXPECT().Bind(t.ChangeViewPetRequest).Return(nil) diff --git a/src/app/router/health-check.router.go b/src/app/router/healthcheck.router.go similarity index 100% rename from src/app/router/health-check.router.go rename to src/app/router/healthcheck.router.go diff --git a/src/app/router/like.router.go b/src/app/router/like.router.go index 094d032..08395c4 100644 --- a/src/app/router/like.router.go +++ b/src/app/router/like.router.go @@ -2,21 +2,21 @@ package router import "github.com/gofiber/fiber/v2" -func (r *FiberRouter) GetLike(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) GetLike(path string, h func(ctx IContext)) { r.like.Get(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) PostLike(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) PostLike(path string, h func(ctx IContext)) { r.like.Post(path, func(c *fiber.Ctx) error { h(NewFiberCtx(c)) return nil }) } -func (r *FiberRouter) DeleteLike(path string, h func(ctx *FiberCtx)) { +func (r *FiberRouter) DeleteLike(path string, h func(ctx IContext)) { r.like.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 0c2716b..2a2bb91 100644 --- a/src/app/router/router.go +++ b/src/app/router/router.go @@ -52,7 +52,7 @@ func NewFiberRouter(authGuard IGuard, conf config.App) *FiberRouter { pet := GroupWithAuthMiddleware(r, "/pets", authGuard.Use) image := GroupWithAuthMiddleware(r, "/image", authGuard.Use) - like := GroupWithAuthMiddleware(r, "/like", authGuard.Use) + like := GroupWithAuthMiddleware(r, "/likes", authGuard.Use) return &FiberRouter{r, auth, user, pet, image, like} } diff --git a/src/app/service/auth/auth.service.go b/src/app/service/auth/auth.service.go index 7a435f4..2f33c62 100644 --- a/src/app/service/auth/auth.service.go +++ b/src/app/service/auth/auth.service.go @@ -2,21 +2,22 @@ package auth import ( "context" + "net/http" + "time" + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - auth_proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "net/http" - "time" ) type Service struct { - client auth_proto.AuthServiceClient + client authProto.AuthServiceClient } -func NewService(client auth_proto.AuthServiceClient) *Service { +func NewService(client authProto.AuthServiceClient) *Service { return &Service{ client: client, } @@ -26,7 +27,7 @@ func (s *Service) Signup(request *dto.SignupRequest) (*dto.SignupResponse, *dto. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - resp, err := s.client.SignUp(ctx, &auth_proto.SignUpRequest{ + resp, err := s.client.SignUp(ctx, &authProto.SignUpRequest{ FirstName: request.Firstname, LastName: request.Lastname, Email: request.Email, @@ -85,7 +86,7 @@ func (s *Service) SignIn(request *dto.SignInRequest) (*dto.Credential, *dto.Resp ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - resp, err := s.client.SignIn(ctx, &auth_proto.SignInRequest{ + resp, err := s.client.SignIn(ctx, &authProto.SignInRequest{ Email: request.Email, Password: request.Password, }) @@ -141,7 +142,7 @@ func (s *Service) SignOut(token string) (*dto.SignOutResponse, *dto.ResponseErr) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - response, err := s.client.SignOut(ctx, &auth_proto.SignOutRequest{ + response, err := s.client.SignOut(ctx, &authProto.SignOutRequest{ Token: token, }) if err != nil { @@ -188,7 +189,7 @@ func (s *Service) Validate(token string) (*dto.TokenPayloadAuth, *dto.ResponseEr ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - response, err := s.client.Validate(ctx, &auth_proto.ValidateRequest{ + response, err := s.client.Validate(ctx, &authProto.ValidateRequest{ Token: token, }) if err != nil { @@ -236,7 +237,7 @@ func (s *Service) RefreshToken(request *dto.RefreshTokenRequest) (*dto.Credentia ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - response, err := s.client.RefreshToken(ctx, &auth_proto.RefreshTokenRequest{ + response, err := s.client.RefreshToken(ctx, &authProto.RefreshTokenRequest{ RefreshToken: request.RefreshToken, }) if err != nil { diff --git a/src/app/service/auth/auth.service_test.go b/src/app/service/auth/auth.service_test.go index 08fc0f9..c041928 100644 --- a/src/app/service/auth/auth.service_test.go +++ b/src/app/service/auth/auth.service_test.go @@ -2,6 +2,9 @@ package auth import ( "errors" + "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" @@ -11,8 +14,6 @@ import ( "github.com/stretchr/testify/suite" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "net/http" - "testing" ) type AuthServiceTest struct { diff --git a/src/app/service/like/like.service.go b/src/app/service/like/like.service.go index ef610f6..b966ae3 100644 --- a/src/app/service/like/like.service.go +++ b/src/app/service/like/like.service.go @@ -1,28 +1,139 @@ package like import ( + "context" + "net/http" + "time" + + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" "github.com/isd-sgcu/johnjud-gateway/src/app/dto" - proto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + "github.com/rs/zerolog/log" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type Service struct { - client proto.LikeServiceClient + client likeProto.LikeServiceClient } -func NewService(client proto.LikeServiceClient) *Service { +func NewService(client likeProto.LikeServiceClient) *Service { return &Service{ client: client, } } -func (s *Service) FindByUserId(userId string) ([]*proto.Like, *dto.ResponseErr) { - return nil, nil +func (s *Service) FindByUserId(userId string) ([]*dto.LikeResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + res, errRes := s.client.FindByUserId(ctx, &likeProto.FindLikeByUserIdRequest{UserId: userId}) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Str("service", "like"). + Str("module", "find by user id"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.UserNotFoundMessage, + 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 utils.ProtoToDtoList(res.Likes), nil } -func (s *Service) Create(in *dto.LikeDto) (*proto.Like, *dto.ResponseErr) { - return nil, nil +func (s *Service) Create(in *dto.CreateLikeRequest) (*dto.LikeResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := utils.CreateDtoToProto(in) + res, errRes := s.client.Create(ctx, request) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "like"). + Str("module", "create"). + Msg(st.Message()) + switch st.Code() { + case codes.InvalidArgument: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgumentMessage, + 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 utils.ProtoToDto(res.Like), nil } -func (s *Service) Delete(id string) (bool, *dto.ResponseErr) { - return false, nil +func (s *Service) Delete(id string) (*dto.DeleteLikeResponse, *dto.ResponseErr) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + request := &likeProto.DeleteLikeRequest{ + Id: id, + } + + res, errRes := s.client.Delete(ctx, request) + if errRes != nil { + st, _ := status.FromError(errRes) + log.Error(). + Err(errRes). + Str("service", "like"). + Str("module", "delete"). + Msg(st.Message()) + switch st.Code() { + case codes.NotFound: + return nil, &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.UserNotFoundMessage, + 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 &dto.DeleteLikeResponse{ + Success: res.Success, + }, nil } diff --git a/src/app/service/like/like.service_test.go b/src/app/service/like/like.service_test.go new file mode 100644 index 0000000..c76c74c --- /dev/null +++ b/src/app/service/like/like.service_test.go @@ -0,0 +1,315 @@ +package like + +import ( + "net/http" + "testing" + + "github.com/bxcodec/faker/v4" + "github.com/isd-sgcu/johnjud-gateway/src/app/constant" + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + utils "github.com/isd-sgcu/johnjud-gateway/src/app/utils/like" + likeMock "github.com/isd-sgcu/johnjud-gateway/src/mocks/client/like" + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type LikeServiceTest struct { + suite.Suite + Likes []*likeProto.Like + Like *likeProto.Like + LikeResponse *dto.LikeResponse + CreateLikeProtoReq *likeProto.CreateLikeRequest + CreateLikeDtoReq *dto.CreateLikeRequest + DeleteLikeProtoReq *likeProto.DeleteLikeRequest + DeleteLikeDtoReq *dto.DeleteLikeRequest + NotFoundErr *dto.ResponseErr + + UnavailableServiceErr *dto.ResponseErr + InvalidArgumentErr *dto.ResponseErr + InternalErr *dto.ResponseErr +} + +func TestLikeService(t *testing.T) { + suite.Run(t, new(LikeServiceTest)) +} + +func (t *LikeServiceTest) SetupTest() { + var likes []*likeProto.Like + for i := 0; i <= 3; i++ { + like := &likeProto.Like{ + Id: faker.UUIDDigit(), + UserId: faker.UUIDDigit(), + PetId: faker.UUIDDigit(), + } + likes = append(likes, like) + } + + t.Likes = likes + t.Like = likes[0] + + t.CreateLikeProtoReq = &likeProto.CreateLikeRequest{ + Like: &likeProto.Like{ + UserId: t.Like.UserId, + PetId: t.Like.PetId, + }, + } + + t.CreateLikeDtoReq = &dto.CreateLikeRequest{ + UserID: t.Like.UserId, + PetID: t.Like.PetId, + } + + t.DeleteLikeProtoReq = &likeProto.DeleteLikeRequest{ + Id: t.Like.Id, + } + + t.UnavailableServiceErr = &dto.ResponseErr{ + StatusCode: http.StatusServiceUnavailable, + Message: constant.UnavailableServiceMessage, + Data: nil, + } + + t.NotFoundErr = &dto.ResponseErr{ + StatusCode: http.StatusNotFound, + Message: constant.UserNotFoundMessage, + Data: nil, + } + + t.InternalErr = &dto.ResponseErr{ + StatusCode: http.StatusInternalServerError, + Message: constant.InternalErrorMessage, + Data: nil, + } + + t.InvalidArgumentErr = &dto.ResponseErr{ + StatusCode: http.StatusBadRequest, + Message: constant.InvalidArgumentMessage, + Data: nil, + } +} + +func (t *LikeServiceTest) TestFindByUserIdSuccess() { + protoReq := &likeProto.FindLikeByUserIdRequest{ + UserId: t.Like.UserId, + } + protoResp := &likeProto.FindLikeByUserIdResponse{ + Likes: t.Likes, + } + + expected := utils.ProtoToDtoList(t.Likes) + + client := likeMock.LikeClientMock{} + client.On("FindByUserId", protoReq).Return(protoResp, nil) + + svc := NewService(&client) + actual, err := svc.FindByUserId(t.Like.UserId) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *LikeServiceTest) TestFindByUserIdNotFoundError() { + protoReq := &likeProto.FindLikeByUserIdRequest{ + UserId: t.Like.UserId, + } + + clientErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) + + expected := t.NotFoundErr + + client := likeMock.LikeClientMock{} + client.On("FindByUserId", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindByUserId(t.Like.UserId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestFindByUserIdUnavailableServiceError() { + protoReq := &likeProto.FindLikeByUserIdRequest{ + UserId: t.Like.UserId, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := likeMock.LikeClientMock{} + client.On("FindByUserId", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindByUserId(t.Like.UserId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestFindByUserIdInternalError() { + protoReq := &likeProto.FindLikeByUserIdRequest{ + UserId: t.Like.UserId, + } + + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + + expected := t.InternalErr + + client := likeMock.LikeClientMock{} + client.On("FindByUserId", protoReq).Return(nil, clientErr) + + svc := NewService(&client) + actual, err := svc.FindByUserId(t.Like.UserId) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestCreateSuccess() { + protoReq := t.CreateLikeProtoReq + protoResp := &likeProto.CreateLikeResponse{ + Like: t.Like, + } + + expected := utils.ProtoToDto(t.Like) + + client := &likeMock.LikeClientMock{} + client.On("Create", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Create(t.CreateLikeDtoReq) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *LikeServiceTest) TestCreateInvalidArgumentError() { + protoReq := t.CreateLikeProtoReq + + expected := t.InvalidArgumentErr + + clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) + + client := &likeMock.LikeClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreateLikeDtoReq) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestCreateInternalError() { + protoReq := t.CreateLikeProtoReq + + expected := t.InvalidArgumentErr + + clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) + + client := &likeMock.LikeClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreateLikeDtoReq) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestCreateUnavailableServiceError() { + protoReq := t.CreateLikeProtoReq + + expected := t.UnavailableServiceErr + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + client := &likeMock.LikeClientMock{} + client.On("Create", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Create(t.CreateLikeDtoReq) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestDeleteSuccess() { + protoReq := &likeProto.DeleteLikeRequest{ + Id: t.Like.Id, + } + protoResp := &likeProto.DeleteLikeResponse{ + Success: true, + } + + expected := &dto.DeleteLikeResponse{Success: true} + + client := &likeMock.LikeClientMock{} + client.On("Delete", protoReq).Return(protoResp, nil) + + svc := NewService(client) + actual, err := svc.Delete(t.Like.Id) + + assert.Nil(t.T(), err) + assert.Equal(t.T(), expected, actual) +} + +func (t *LikeServiceTest) TestDeleteNotFoundError() { + protoReq := &likeProto.DeleteLikeRequest{ + Id: t.Like.Id, + } + + clientErr := status.Error(codes.NotFound, constant.UserNotFoundMessage) + + expected := t.NotFoundErr + + client := &likeMock.LikeClientMock{} + client.On("Delete", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Delete(t.Like.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestDeleteUnavailableServiceError() { + protoReq := &likeProto.DeleteLikeRequest{ + Id: t.Like.Id, + } + + clientErr := status.Error(codes.Unavailable, constant.UnavailableServiceMessage) + + expected := t.UnavailableServiceErr + + client := &likeMock.LikeClientMock{} + client.On("Delete", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Delete(t.Like.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} + +func (t *LikeServiceTest) TestDeleteInternalError() { + protoReq := &likeProto.DeleteLikeRequest{ + Id: t.Like.Id, + } + + clientErr := status.Error(codes.Internal, constant.InternalErrorMessage) + + expected := t.InternalErr + + client := &likeMock.LikeClientMock{} + client.On("Delete", protoReq).Return(nil, clientErr) + + svc := NewService(client) + actual, err := svc.Delete(t.Like.Id) + + assert.Nil(t.T(), actual) + assert.Equal(t.T(), expected, err) +} diff --git a/src/app/service/pet/pet.service.go b/src/app/service/pet/pet.service.go index 0ce4dd6..d8e8cf1 100644 --- a/src/app/service/pet/pet.service.go +++ b/src/app/service/pet/pet.service.go @@ -18,6 +18,11 @@ type Service struct { petClient petproto.PetServiceClient } +// Adopt implements pet.Service. +func (*Service) Adopt(*dto.AdoptDto) (bool, *dto.ResponseErr) { + panic("unimplemented") +} + func NewService(petClient petproto.PetServiceClient) *Service { return &Service{ petClient: petClient, @@ -51,7 +56,7 @@ func (s *Service) FindAll() (result []*dto.PetResponse, err *dto.ResponseErr) { } } imagesList := utils.MockImageList(len(res.Pets)) - findAllResponse := utils.RawToDtoList(res.Pets, imagesList) + findAllResponse := utils.ProtoToDtoList(res.Pets, imagesList) return findAllResponse, nil } @@ -94,7 +99,7 @@ func (s *Service) FindOne(id string) (result *dto.PetResponse, err *dto.Response return findOneResponse, nil } -func (s *Service) Create(in *dto.CreatePetRequest) (ressult *dto.PetResponse, err *dto.ResponseErr) { +func (s *Service) Create(in *dto.CreatePetRequest) (result *dto.PetResponse, err *dto.ResponseErr) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -112,7 +117,7 @@ func (s *Service) Create(in *dto.CreatePetRequest) (ressult *dto.PetResponse, er case codes.InvalidArgument: return nil, &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgument, + Message: constant.InvalidArgumentMessage, Data: nil, } case codes.Unavailable: @@ -158,7 +163,7 @@ func (s *Service) Update(id string, in *dto.UpdatePetRequest) (result *dto.PetRe case codes.InvalidArgument: return nil, &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgument, + Message: constant.InvalidArgumentMessage, Data: nil, } case codes.Unavailable: diff --git a/src/app/service/pet/pet.service_test.go b/src/app/service/pet/pet.service_test.go index 07fecd1..797af40 100644 --- a/src/app/service/pet/pet.service_test.go +++ b/src/app/service/pet/pet.service_test.go @@ -186,7 +186,7 @@ func (t *PetServiceTest) SetupTest() { t.InvalidArgumentErr = &dto.ResponseErr{ StatusCode: http.StatusBadRequest, - Message: constant.InvalidArgument, + Message: constant.InvalidArgumentMessage, Data: nil, } } @@ -197,7 +197,7 @@ func (t *PetServiceTest) TestFindAllSuccess() { Pets: t.Pets, } - expected := utils.RawToDtoList(t.Pets, t.ImagesList) + expected := utils.ProtoToDtoList(t.Pets, t.ImagesList) client := petmock.PetClientMock{} client.On("FindAll", protoReq).Return(protoResp, nil) @@ -307,7 +307,7 @@ func (t *PetServiceTest) TestCreateInvalidArgumentError() { expected := t.InvalidArgumentErr - clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgument) + clientErr := status.Error(codes.InvalidArgument, constant.InvalidArgumentMessage) client := &petmock.PetClientMock{} client.On("Create", protoReq).Return(nil, clientErr) diff --git a/src/app/utils/like/like.utils.go b/src/app/utils/like/like.utils.go new file mode 100644 index 0000000..1349010 --- /dev/null +++ b/src/app/utils/like/like.utils.go @@ -0,0 +1,33 @@ +package like + +import ( + "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" +) + +func ProtoToDto(in *likeProto.Like) *dto.LikeResponse { + return &dto.LikeResponse{ + UserID: in.UserId, + PetID: in.PetId, + } +} + +func ProtoToDtoList(in []*likeProto.Like) []*dto.LikeResponse { + var res []*dto.LikeResponse + for _, i := range in { + res = append(res, &dto.LikeResponse{ + UserID: i.UserId, + PetID: i.PetId, + }) + } + return res +} + +func CreateDtoToProto(in *dto.CreateLikeRequest) *likeProto.CreateLikeRequest { + return &likeProto.CreateLikeRequest{ + Like: &likeProto.Like{ + UserId: in.UserID, + PetId: in.PetID, + }, + } +} diff --git a/src/app/utils/pet/pet.utils.go b/src/app/utils/pet/pet.utils.go index 0ed39e3..1f68987 100644 --- a/src/app/utils/pet/pet.utils.go +++ b/src/app/utils/pet/pet.utils.go @@ -122,7 +122,7 @@ func UpdateDtoToProto(id string, in *dto.UpdatePetRequest) *petproto.UpdatePetRe return req } -func RawToDtoList(in []*petproto.Pet, imagesList [][]*imgproto.Image) []*dto.PetResponse { +func ProtoToDtoList(in []*petproto.Pet, imagesList [][]*imgproto.Image) []*dto.PetResponse { var resp []*dto.PetResponse for i, p := range in { pet := &dto.PetResponse{ diff --git a/src/constant/like/like.constant.go b/src/constant/like/like.constant.go new file mode 100644 index 0000000..35960ae --- /dev/null +++ b/src/constant/like/like.constant.go @@ -0,0 +1,5 @@ +package like + +const FindLikeSuccessMessage = "find likes success" +const CreateLikeSuccessMessage = "create like success" +const DelteLikeSuccessMessage = "delete like success" diff --git a/src/main.go b/src/main.go index f267195..2d354c7 100644 --- a/src/main.go +++ b/src/main.go @@ -11,22 +11,25 @@ import ( "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" + healthcheck "github.com/isd-sgcu/johnjud-gateway/src/app/handler/healthcheck" + likeHdr "github.com/isd-sgcu/johnjud-gateway/src/app/handler/like" 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" + authSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/auth" + imageSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/image" + likeSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/like" + petSvc "github.com/isd-sgcu/johnjud-gateway/src/app/service/pet" + userSvc "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" + authProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/auth/v1" + userProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/auth/user/v1" + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + 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/rs/zerolog/log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -90,25 +93,29 @@ func main() { Msg("Cannot connect to service") } - hc := health_check.NewHandler() + hc := healthcheck.NewHandler() - userClient := user_proto.NewUserServiceClient(authConn) - userService := userSrv.NewService(userClient) + userClient := userProto.NewUserServiceClient(authConn) + userService := userSvc.NewService(userClient) userHandler := userHdr.NewHandler(userService, v) - authClient := auth_proto.NewAuthServiceClient(authConn) - authService := authSrv.NewService(authClient) + authClient := authProto.NewAuthServiceClient(authConn) + authService := authSvc.NewService(authClient) authHandler := authHdr.NewHandler(authService, userService, v) authGuard := guard.NewAuthGuard(authService, auth.ExcludePath, conf.App, auth.VersionList) - imageClient := image_proto.NewImageServiceClient(fileConn) - imageService := imageSrv.NewService(imageClient) + imageClient := imageProto.NewImageServiceClient(fileConn) + imageService := imageSvc.NewService(imageClient) - petClient := pet_proto.NewPetServiceClient(backendConn) - petService := petSrv.NewService(petClient) + petClient := petProto.NewPetServiceClient(backendConn) + petService := petSvc.NewService(petClient) petHandler := petHdr.NewHandler(petService, imageService, v) + likeClient := likeProto.NewLikeServiceClient(backendConn) + likeService := likeSvc.NewService(likeClient) + likeHandler := likeHdr.NewHandler(likeService, v) + r := router.NewFiberRouter(&authGuard, conf.App) r.GetUser("/:id", userHandler.FindOne) @@ -130,6 +137,10 @@ func main() { r.PutPet("/:id/visible", petHandler.ChangeView) r.DeletePet("/:id", petHandler.Delete) + r.GetLike("/:id", likeHandler.FindByUserId) + r.PostLike("/", likeHandler.Create) + r.DeleteLike("/:id", likeHandler.Delete) + v1 := router.NewAPIv1(r, conf.App) go func() { diff --git a/src/mocks/client/like/like.mock.go b/src/mocks/client/like/like.mock.go new file mode 100644 index 0000000..0bb7bd8 --- /dev/null +++ b/src/mocks/client/like/like.mock.go @@ -0,0 +1,38 @@ +package like + +import ( + "context" + + likeProto "github.com/isd-sgcu/johnjud-go-proto/johnjud/backend/like/v1" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" +) + +type LikeClientMock struct { + mock.Mock +} + +func (c *LikeClientMock) FindByUserId(_ context.Context, in *likeProto.FindLikeByUserIdRequest, _ ...grpc.CallOption) (res *likeProto.FindLikeByUserIdResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*likeProto.FindLikeByUserIdResponse) + } + return res, args.Error(1) +} +func (c *LikeClientMock) Create(_ context.Context, in *likeProto.CreateLikeRequest, _ ...grpc.CallOption) (res *likeProto.CreateLikeResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*likeProto.CreateLikeResponse) + } + return res, args.Error(1) +} +func (c *LikeClientMock) Delete(_ context.Context, in *likeProto.DeleteLikeRequest, _ ...grpc.CallOption) (res *likeProto.DeleteLikeResponse, err error) { + args := c.Called(in) + + if args.Get(0) != nil { + res = args.Get(0).(*likeProto.DeleteLikeResponse) + } + return res, args.Error(1) +} diff --git a/src/mocks/client/pet/pet.mock.go b/src/mocks/client/pet/pet.mock.go index 5148750..10554c2 100644 --- a/src/mocks/client/pet/pet.mock.go +++ b/src/mocks/client/pet/pet.mock.go @@ -12,7 +12,7 @@ type PetClientMock struct { mock.Mock } -func (c *PetClientMock) AdoptPet(ctx context.Context, in *petProto.AdoptPetRequest, opts ...grpc.CallOption) (res *petProto.AdoptPetResponse, err error) { +func (c *PetClientMock) AdoptPet(_ context.Context, in *petProto.AdoptPetRequest, _ ...grpc.CallOption) (res *petProto.AdoptPetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -21,7 +21,7 @@ func (c *PetClientMock) AdoptPet(ctx context.Context, in *petProto.AdoptPetReque return res, args.Error(1) } -func (c *PetClientMock) FindAll(ctx context.Context, in *petProto.FindAllPetRequest, opts ...grpc.CallOption) (res *petProto.FindAllPetResponse, err error) { +func (c *PetClientMock) FindAll(_ context.Context, in *petProto.FindAllPetRequest, _ ...grpc.CallOption) (res *petProto.FindAllPetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -30,7 +30,7 @@ func (c *PetClientMock) FindAll(ctx context.Context, in *petProto.FindAllPetRequ return res, args.Error(1) } -func (c *PetClientMock) FindOne(ctx context.Context, in *petProto.FindOnePetRequest, opts ...grpc.CallOption) (res *petProto.FindOnePetResponse, err error) { +func (c *PetClientMock) FindOne(_ context.Context, in *petProto.FindOnePetRequest, _ ...grpc.CallOption) (res *petProto.FindOnePetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -39,7 +39,7 @@ func (c *PetClientMock) FindOne(ctx context.Context, in *petProto.FindOnePetRequ return res, args.Error(1) } -func (c *PetClientMock) Create(ctx context.Context, in *petProto.CreatePetRequest, opts ...grpc.CallOption) (res *petProto.CreatePetResponse, err error) { +func (c *PetClientMock) Create(_ context.Context, in *petProto.CreatePetRequest, _ ...grpc.CallOption) (res *petProto.CreatePetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -49,7 +49,7 @@ func (c *PetClientMock) Create(ctx context.Context, in *petProto.CreatePetReques return res, args.Error(1) } -func (c *PetClientMock) Update(ctx context.Context, in *petProto.UpdatePetRequest, opts ...grpc.CallOption) (res *petProto.UpdatePetResponse, err error) { +func (c *PetClientMock) Update(_ context.Context, in *petProto.UpdatePetRequest, _ ...grpc.CallOption) (res *petProto.UpdatePetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -59,7 +59,7 @@ func (c *PetClientMock) Update(ctx context.Context, in *petProto.UpdatePetReques return res, args.Error(1) } -func (c *PetClientMock) ChangeView(ctx context.Context, in *petProto.ChangeViewPetRequest, opts ...grpc.CallOption) (res *petProto.ChangeViewPetResponse, err error) { +func (c *PetClientMock) ChangeView(_ context.Context, in *petProto.ChangeViewPetRequest, _ ...grpc.CallOption) (res *petProto.ChangeViewPetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { @@ -69,7 +69,7 @@ func (c *PetClientMock) ChangeView(ctx context.Context, in *petProto.ChangeViewP return res, args.Error(1) } -func (c *PetClientMock) Delete(ctx context.Context, in *petProto.DeletePetRequest, opts ...grpc.CallOption) (res *petProto.DeletePetResponse, err error) { +func (c *PetClientMock) Delete(_ context.Context, in *petProto.DeletePetRequest, _ ...grpc.CallOption) (res *petProto.DeletePetResponse, err error) { args := c.Called(in) if args.Get(0) != nil { diff --git a/src/mocks/service/like/like.mock.go b/src/mocks/service/like/like.mock.go new file mode 100644 index 0000000..a40c24a --- /dev/null +++ b/src/mocks/service/like/like.mock.go @@ -0,0 +1,85 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./src/pkg/service/like/like.service.go +// +// Generated by this command: +// +// mockgen -source ./src/pkg/service/like/like.service.go -destination ./src/mocks/service/like/like.mock.go +// + +// Package mock_like is a generated GoMock package. +package mock_like + +import ( + reflect "reflect" + + dto "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + 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 +} + +// Create mocks base method. +func (m *MockService) Create(arg0 *dto.CreateLikeRequest) (*dto.LikeResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(*dto.LikeResponse) + 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) (*dto.DeleteLikeResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(*dto.DeleteLikeResponse) + 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) +} + +// FindByUserId mocks base method. +func (m *MockService) FindByUserId(arg0 string) ([]*dto.LikeResponse, *dto.ResponseErr) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindByUserId", arg0) + ret0, _ := ret[0].([]*dto.LikeResponse) + ret1, _ := ret[1].(*dto.ResponseErr) + return ret0, ret1 +} + +// FindByUserId indicates an expected call of FindByUserId. +func (mr *MockServiceMockRecorder) FindByUserId(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByUserId", reflect.TypeOf((*MockService)(nil).FindByUserId), arg0) +} diff --git a/src/pkg/service/like/like.service.go b/src/pkg/service/like/like.service.go new file mode 100644 index 0000000..e260a4b --- /dev/null +++ b/src/pkg/service/like/like.service.go @@ -0,0 +1,9 @@ +package like + +import "github.com/isd-sgcu/johnjud-gateway/src/app/dto" + +type Service interface { + FindByUserId(string) ([]*dto.LikeResponse, *dto.ResponseErr) + Create(*dto.CreateLikeRequest) (*dto.LikeResponse, *dto.ResponseErr) + Delete(string) (*dto.DeleteLikeResponse, *dto.ResponseErr) +}