Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bugfix/docs] Poll api fixups + swagger docs #2345

Merged
merged 2 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 54 additions & 3 deletions docs/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2020,14 +2020,21 @@ definitions:
type: array
x-go-name: Options
own_votes:
description: When called with a user token, which options has the authorized user chosen? Contains an array of index values for options.
description: |-
When called with a user token, which options has the authorized
user chosen? Contains an array of index values for options.
Omitted when no user token provided.
items:
format: int64
type: integer
type: array
x-go-name: OwnVotes
voted:
description: When called with a user token, has the authorized user voted?
description: |-
When called with a user token, has the authorized user voted?
Omitted when no user token provided.
type: boolean
x-go-name: Voted
voters_count:
Expand Down Expand Up @@ -2059,6 +2066,36 @@ definitions:
type: object
x-go-name: PollOption
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
pollRequest:
properties:
expires_in:
description: |-
Duration the poll should be open, in seconds.
If provided, media_ids cannot be used, and poll[options] must be provided.
format: int64
type: integer
x-go-name: ExpiresIn
hide_totals:
description: Hide vote counts until the poll ends.
type: boolean
x-go-name: HideTotals
multiple:
description: Allow multiple choices on this poll.
type: boolean
x-go-name: Multiple
options:
description: |-
Array of possible answers.
If provided, media_ids cannot be used, and poll[expires_in] must be provided.
name: poll[options]
items:
type: string
type: array
x-go-name: Options
title: PollRequest models a request to create a poll.
type: object
x-go-name: PollRequest
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
report:
properties:
action_taken:
Expand Down Expand Up @@ -2346,6 +2383,8 @@ definitions:
type: string
type: array
x-go-name: MediaIDs
poll:
$ref: '#/definitions/pollRequest'
scheduled_at:
description: |-
ISO 8601 Datetime at which to schedule a status.
Expand Down Expand Up @@ -6028,13 +6067,20 @@ paths:
- polls
/api/v1/polls/{id}/vote:
post:
operationId: poll
operationId: pollVote
parameters:
- description: Target poll ID.
in: path
name: id
required: true
type: string
- description: Poll choice indices on which to vote.
in: formData
items:
type: integer
name: choices
required: true
type: array
produces:
- application/json
responses:
Expand Down Expand Up @@ -6309,6 +6355,11 @@ paths:
name: media_ids
type: array
x-go-name: MediaIDs
- $ref: '#/definitions/pollRequest'
description: Poll to include with this status.
in: formData
name: poll
x-go-name: Poll
- description: ID of the status being replied to, if status is a reply.
in: formData
name: in_reply_to_id
Expand Down
10 changes: 9 additions & 1 deletion internal/api/client/polls/polls_vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)

// PollVotePOSTHandler swagger:operation POST /api/v1/polls/{id}/vote poll
// PollVotePOSTHandler swagger:operation POST /api/v1/polls/{id}/vote pollVote
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that'll do it 🤦‍♀️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easy thing to overlook when you've been juggling the PR for over a month tbf :P

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR for a month, and the branch + code itself for 2 🥲

//
// Vote with choices in the given poll.
//
Expand All @@ -45,6 +45,14 @@ import (
// description: Target poll ID.
// in: path
// required: true
// -
// name: choices
// type: array
// items:
// type: integer
// description: Poll choice indices on which to vote.
// in: formData
// required: true
//
// security:
// - OAuth2 Bearer:
Expand Down
15 changes: 10 additions & 5 deletions internal/api/model/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@ type Poll struct {
VotersCount int `json:"voters_count"`

// When called with a user token, has the authorized user voted?
Voted bool `json:"voted,omitempty"`
//
// Omitted when no user token provided.
Voted *bool `json:"voted,omitempty"`

// When called with a user token, which options has the authorized user chosen? Contains an array of index values for options.
OwnVotes []int `json:"own_votes,omitempty"`
// When called with a user token, which options has the authorized
// user chosen? Contains an array of index values for options.
//
// Omitted when no user token provided.
OwnVotes *[]int `json:"own_votes,omitempty"`

// Possible answers for the poll.
Options []PollOption `json:"options"`
Expand All @@ -66,7 +71,7 @@ type PollOption struct {

// PollRequest models a request to create a poll.
//
// swagger:parameters createStatus
// swagger:model pollRequest
type PollRequest struct {
// Array of possible answers.
// If provided, media_ids cannot be used, and poll[expires_in] must be provided.
Expand All @@ -86,7 +91,7 @@ type PollRequest struct {

// PollVoteRequest models a request to vote in a poll.
//
// swagger:parameters pollVote
// swagger:ignore
type PollVoteRequest struct {
// Choices contains poll vote choice indices. Note that form
// uses a different key than the JSON, i.e. the '[]' suffix.
Expand Down
2 changes: 1 addition & 1 deletion internal/api/model/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ type StatusCreateRequest struct {
// in: formData
MediaIDs []string `form:"media_ids[]" json:"media_ids" xml:"media_ids"`
// Poll to include with this status.
// swagger:ignore
// in: formData
Poll *PollRequest `form:"poll" json:"poll" xml:"poll"`
// ID of the status being replied to, if status is a reply.
// in: formData
Expand Down
23 changes: 19 additions & 4 deletions internal/typeutils/internaltofrontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,10 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
options []apimodel.PollOption
totalVotes int
totalVoters int
ownChoices []int
voted *bool
ownChoices *[]int
isAuthor bool
emojis []apimodel.Emoji
)

// Preallocate a slice of frontend model poll choices.
Expand All @@ -1337,19 +1339,26 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou

if vote != nil {
// Set choices by requester.
ownChoices = vote.Choices
ownChoices = &vote.Choices

// Update default totals in the
// case that counts are hidden.
totalVotes = len(vote.Choices)
totalVoters = 1
for _, choice := range ownChoices {
for _, choice := range *ownChoices {
options[choice].VotesCount++
}
} else {
// Requester is defined but hasn't made
// a choice. Init slice to serialize as `[]`.
ownChoices = util.Ptr(make([]int, 0))
}

// Check if requester is author of source status.
isAuthor = (requester.ID == poll.Status.AccountID)

// Requester is defined so voted should be defined too.
voted = util.Ptr((isAuthor || len(*ownChoices) > 0))
}

if isAuthor || !*poll.HideCounts {
Expand All @@ -1368,16 +1377,22 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
}
}

// TODO: emojis used in poll options.
// For now init to empty slice to serialize as `[]`.
// In future inherit from parent status.
emojis = make([]apimodel.Emoji, 0)

return &apimodel.Poll{
ID: poll.ID,
ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
Expired: poll.Closed(),
Multiple: (*poll.Multiple),
VotesCount: totalVotes,
VotersCount: totalVoters,
Voted: (isAuthor || len(ownChoices) > 0),
Voted: voted,
OwnVotes: ownChoices,
Options: options,
Emojis: emojis,
}, nil
}

Expand Down