Skip to content

Commit

Permalink
feat(api/vote): add get vote status endpoint
Browse files Browse the repository at this point in the history
A new HTTP API endpoint `GET /votes/:target_name/:target_id` is now available.

Response example:

```
{"up":1,"down":1,"is_up":true,"is_down":false}
```

- Implement GET endpoint for retrieving vote status
- Add tests for vote functionality

Related to: PR#997

This is a prerequisite PR for #983.
  • Loading branch information
qwqcode committed Oct 6, 2024
1 parent 02a369f commit 129b120
Show file tree
Hide file tree
Showing 9 changed files with 559 additions and 1 deletion.
98 changes: 98 additions & 0 deletions docs/swagger/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3525,6 +3525,104 @@ const docTemplate = `{
}
}
},
"/votes/{target_name}/{target_id}": {
"get": {
"description": "Get vote status for a specific comment or page",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vote"
],
"summary": "Get Vote Status",
"operationId": "GetVote",
"parameters": [
{
"enum": [
"comment",
"page"
],
"type": "string",
"description": "The name of vote target",
"name": "target_name",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "The target comment or page ID",
"name": "target_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.ResponseVote"
}
},
"403": {
"description": "Forbidden",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Not Found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/votes/{target_name}/{target_id}/{choice}": {
"post": {
"description": "Create a new vote for a specific comment or page",
Expand Down
98 changes: 98 additions & 0 deletions docs/swagger/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3518,6 +3518,104 @@
}
}
},
"/votes/{target_name}/{target_id}": {
"get": {
"description": "Get vote status for a specific comment or page",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vote"
],
"summary": "Get Vote Status",
"operationId": "GetVote",
"parameters": [
{
"enum": [
"comment",
"page"
],
"type": "string",
"description": "The name of vote target",
"name": "target_name",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "The target comment or page ID",
"name": "target_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.ResponseVote"
}
},
"403": {
"description": "Forbidden",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Not Found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Map"
},
{
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/votes/{target_name}/{target_id}/{choice}": {
"post": {
"description": "Create a new vote for a specific comment or page",
Expand Down
57 changes: 57 additions & 0 deletions docs/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3284,6 +3284,63 @@ paths:
summary: Get Version Info
tags:
- System
/votes/{target_name}/{target_id}:
get:
consumes:
- application/json
description: Get vote status for a specific comment or page
operationId: GetVote
parameters:
- description: The name of vote target
enum:
- comment
- page
in: path
name: target_name
required: true
type: string
- description: The target comment or page ID
in: path
name: target_id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handler.ResponseVote'
"403":
description: Forbidden
schema:
allOf:
- $ref: '#/definitions/handler.Map'
- properties:
msg:
type: string
type: object
"404":
description: Not Found
schema:
allOf:
- $ref: '#/definitions/handler.Map'
- properties:
msg:
type: string
type: object
"500":
description: Internal Server Error
schema:
allOf:
- $ref: '#/definitions/handler.Map'
- properties:
msg:
type: string
type: object
summary: Get Vote Status
tags:
- Vote
/votes/{target_name}/{target_id}/{choice}:
post:
consumes:
Expand Down
4 changes: 3 additions & 1 deletion server/handler/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

func NewApiTestApp() (*test.TestApp, *fiber.App) {
app, _ := test.NewTestApp()
fiberApp := fiber.New()
fiberApp := fiber.New(fiber.Config{
ProxyHeader: "X-Forwarded-For",
})
return app, fiberApp
}
31 changes: 31 additions & 0 deletions server/handler/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,37 @@ type ResponseVote struct {
IsDown bool `json:"is_down"`
}

// @Id GetVote
// @Summary Get Vote Status
// @Description Get vote status for a specific comment or page
// @Tags Vote
// @Param target_name path string true "The name of vote target" Enums(comment, page)
// @Param target_id path int true "The target comment or page ID"
// @Accept json
// @Produce json
// @Success 200 {object} ResponseVote
// @Failure 403 {object} Map{msg=string}
// @Failure 404 {object} Map{msg=string}
// @Failure 500 {object} Map{msg=string}
// @Router /votes/{target_name}/{target_id} [get]
func VoteGet(app *core.App, router fiber.Router) {
router.Get("/votes/:target_name/:target_id", func(c *fiber.Ctx) error {
targetName := c.Params("target_name")
targetID, _ := c.ParamsInt("target_id")

var result ResponseVote
result.Up, result.Down = app.Dao().GetVoteNumUpDown(targetName, uint(targetID))
exitsVotes := getExistsVotesByIP(app.Dao(), c.IP(), targetName, uint(targetID))
if len(exitsVotes) > 0 {
choice := getVoteChoice(string(exitsVotes[0].Type))
result.IsUp = choice == "up"
result.IsDown = choice == "down"
}

return common.RespData(c, result)
})
}

type ParamsVoteCreate struct {
Name string `json:"name" validate:"optional"` // The username
Email string `json:"email" validate:"optional"` // The user email
Expand Down
Loading

0 comments on commit 129b120

Please sign in to comment.