summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--go.mod2
-rw-r--r--internal/gtsmodel/account.go112
-rw-r--r--internal/gtsmodel/accountnote.go16
-rw-r--r--internal/gtsmodel/admin.go22
-rw-r--r--internal/gtsmodel/application.go18
-rw-r--r--internal/gtsmodel/block.go16
-rw-r--r--internal/gtsmodel/client.go12
-rw-r--r--internal/gtsmodel/domainblock.go20
-rw-r--r--internal/gtsmodel/emaildomainblock.go12
-rw-r--r--internal/gtsmodel/emoji.go44
-rw-r--r--internal/gtsmodel/emojicategory.go8
-rw-r--r--internal/gtsmodel/follow.go20
-rw-r--r--internal/gtsmodel/followrequest.go20
-rw-r--r--internal/gtsmodel/instance.go36
-rw-r--r--internal/gtsmodel/list.go28
-rw-r--r--internal/gtsmodel/marker.go10
-rw-r--r--internal/gtsmodel/mediaattachment.go84
-rw-r--r--internal/gtsmodel/mention.go28
-rw-r--r--internal/gtsmodel/notification.go22
-rw-r--r--internal/gtsmodel/report.go32
-rw-r--r--internal/gtsmodel/routersession.go10
-rw-r--r--internal/gtsmodel/status.go98
-rw-r--r--internal/gtsmodel/statusbookmark.go18
-rw-r--r--internal/gtsmodel/statusfave.go20
-rw-r--r--internal/gtsmodel/statusmute.go18
-rw-r--r--internal/gtsmodel/tag.go12
-rw-r--r--internal/gtsmodel/token.go36
-rw-r--r--internal/gtsmodel/tombstone.go10
-rw-r--r--internal/gtsmodel/user.go62
-rw-r--r--internal/validate/account_test.go343
-rw-r--r--internal/validate/application_test.go132
-rw-r--r--internal/validate/block_test.go115
-rw-r--r--internal/validate/client_test.go101
-rw-r--r--internal/validate/domainblock_test.go122
-rw-r--r--internal/validate/emaildomainblock_test.go96
-rw-r--r--internal/validate/emoji_test.go195
-rw-r--r--internal/validate/follow_test.go87
-rw-r--r--internal/validate/followrequest_test.go87
-rw-r--r--internal/validate/instance_test.go145
-rw-r--r--internal/validate/mediaattachment_test.go230
-rw-r--r--internal/validate/mention_test.go101
-rw-r--r--internal/validate/notification_test.go97
-rw-r--r--internal/validate/routersession_test.go87
-rw-r--r--internal/validate/status_test.go160
-rw-r--r--internal/validate/statusbookmark_test.go87
-rw-r--r--internal/validate/statusfave_test.go100
-rw-r--r--internal/validate/statusmute_test.go87
-rw-r--r--internal/validate/structvalidation.go67
-rw-r--r--internal/validate/structvalidation_test.go70
-rw-r--r--internal/validate/token_test.go98
-rw-r--r--internal/validate/user_test.go134
51 files changed, 423 insertions, 3164 deletions
diff --git a/go.mod b/go.mod
index 999068087..391d8c126 100644
--- a/go.mod
+++ b/go.mod
@@ -28,7 +28,6 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/go-fed/httpsig v1.1.0
github.com/go-playground/form/v4 v4.2.1
- github.com/go-playground/validator/v10 v10.14.1
github.com/google/uuid v1.3.0
github.com/gorilla/feeds v1.1.1
github.com/gorilla/websocket v1.5.0
@@ -108,6 +107,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
+ github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/go-xmlfmt/xmlfmt v0.0.0-20211206191508-7fd73a941850 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
diff --git a/internal/gtsmodel/account.go b/internal/gtsmodel/account.go
index bce9065c1..7b27f076a 100644
--- a/internal/gtsmodel/account.go
+++ b/internal/gtsmodel/account.go
@@ -32,55 +32,55 @@ import (
// Account represents either a local or a remote fediverse account, gotosocial or otherwise (mastodon, pleroma, etc).
type Account struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created.
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item was last updated.
- FetchedAt time.Time `validate:"required_with=Domain" bun:"type:timestamptz,nullzero"` // when was item (remote) last fetched.
- Username string `validate:"required" bun:",nullzero,notnull,unique:usernamedomain"` // Username of the account, should just be a string of [a-zA-Z0-9_]. Can be added to domain to create the full username in the form ``[username]@[domain]`` eg., ``user_96@example.org``. Username and domain should be unique *with* each other
- Domain string `validate:"omitempty,fqdn" bun:",nullzero,unique:usernamedomain"` // Domain of the account, will be null if this is a local account, otherwise something like ``example.org``. Should be unique with username.
- AvatarMediaAttachmentID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Database ID of the media attachment, if present
- AvatarMediaAttachment *MediaAttachment `validate:"-" bun:"rel:belongs-to"` // MediaAttachment corresponding to avatarMediaAttachmentID
- AvatarRemoteURL string `validate:"omitempty,url" bun:",nullzero"` // For a non-local account, where can the header be fetched?
- HeaderMediaAttachmentID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Database ID of the media attachment, if present
- HeaderMediaAttachment *MediaAttachment `validate:"-" bun:"rel:belongs-to"` // MediaAttachment corresponding to headerMediaAttachmentID
- HeaderRemoteURL string `validate:"omitempty,url" bun:",nullzero"` // For a non-local account, where can the header be fetched?
- DisplayName string `validate:"-" bun:""` // DisplayName for this account. Can be empty, then just the Username will be used for display purposes.
- EmojiIDs []string `validate:"dive,ulid" bun:"emojis,array"` // Database IDs of any emojis used in this account's bio, display name, etc
- Emojis []*Emoji `validate:"-" bun:"attached_emojis,m2m:account_to_emojis"` // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
- Fields []*Field `validate:"-"` // A slice of of fields that this account has added to their profile.
- FieldsRaw []*Field `validate:"-"` // The raw (unparsed) content of fields that this account has added to their profile, without conversion to HTML, only available when requester = target
- Note string `validate:"-" bun:""` // A note that this account has on their profile (ie., the account's bio/description of themselves)
- NoteRaw string `validate:"-" bun:""` // The raw contents of .Note without conversion to HTML, only available when requester = target
- Memorial *bool `validate:"-" bun:",default:false"` // Is this a memorial account, ie., has the user passed away?
- AlsoKnownAs string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // This account is associated with x account id (TODO: migrate to be AlsoKnownAsID)
- MovedToAccountID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // This account has moved this account id in the database
- Bot *bool `validate:"-" bun:",default:false"` // Does this account identify itself as a bot?
- Reason string `validate:"-" bun:""` // What reason was given for signing up when this account was created?
- Locked *bool `validate:"-" bun:",default:true"` // Does this account need an approval for new followers?
- Discoverable *bool `validate:"-" bun:",default:false"` // Should this account be shown in the instance's profile directory?
- Privacy Visibility `validate:"required_without=Domain,omitempty,oneof=public unlocked followers_only mutuals_only direct" bun:",nullzero"` // Default post privacy for this account
- Sensitive *bool `validate:"-" bun:",default:false"` // Set posts from this account to sensitive by default?
- Language string `validate:"omitempty,bcp47_language_tag" bun:",nullzero,notnull,default:'en'"` // What language does this account post in?
- StatusContentType string `validate:"required_without=Domain,omitempty,oneof=text/plain text/markdown" bun:",nullzero"` // What is the default format for statuses posted by this account (only for local accounts).
- CustomCSS string `validate:"-" bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
- URI string `validate:"required,url" bun:",nullzero,notnull,unique"` // ActivityPub URI for this account.
- URL string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // Web URL for this account's profile
- InboxURI string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // Address of this account's ActivityPub inbox, for sending activity to
- SharedInboxURI *string `validate:"-" bun:""` // Address of this account's ActivityPub sharedInbox. Gotcha warning: this is a string pointer because it has three possible states: 1. We don't know yet if the account has a shared inbox -- null. 2. We know it doesn't have a shared inbox -- empty string. 3. We know it does have a shared inbox -- url string.
- OutboxURI string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // Address of this account's activitypub outbox
- FollowingURI string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // URI for getting the following list of this account
- FollowersURI string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // URI for getting the followers list of this account
- FeaturedCollectionURI string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // URL for getting the featured collection list of this account
- ActorType string `validate:"oneof=Application Group Organization Person Service" bun:",nullzero,notnull"` // What type of activitypub actor is this account?
- PrivateKey *rsa.PrivateKey `validate:"required_without=Domain" bun:""` // Privatekey for validating activitypub requests, will only be defined for local accounts
- PublicKey *rsa.PublicKey `validate:"required" bun:",notnull"` // Publickey for encoding activitypub requests, will be defined for both local and remote accounts
- PublicKeyURI string `validate:"required,url" bun:",nullzero,notnull,unique"` // Web-reachable location of this account's public key
- SensitizedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When was this account set to have all its media shown as sensitive?
- SilencedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When was this account silenced (eg., statuses only visible to followers, not public)?
- SuspendedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When was this account suspended (eg., don't allow it to log in/post, don't accept media/posts from this account)
- HideCollections *bool `validate:"-" bun:",default:false"` // Hide this account's collections
- SuspensionOrigin string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the database entry that caused this account to become suspended -- can be an account ID or a domain block ID
- EnableRSS *bool `validate:"-" bun:",default:false"` // enable RSS feed subscription for this account's public posts at [URL]/feed
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created.
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item was last updated.
+ FetchedAt time.Time `bun:"type:timestamptz,nullzero"` // when was item (remote) last fetched.
+ Username string `bun:",nullzero,notnull,unique:usernamedomain"` // Username of the account, should just be a string of [a-zA-Z0-9_]. Can be added to domain to create the full username in the form ``[username]@[domain]`` eg., ``user_96@example.org``. Username and domain should be unique *with* each other
+ Domain string `bun:",nullzero,unique:usernamedomain"` // Domain of the account, will be null if this is a local account, otherwise something like ``example.org``. Should be unique with username.
+ AvatarMediaAttachmentID string `bun:"type:CHAR(26),nullzero"` // Database ID of the media attachment, if present
+ AvatarMediaAttachment *MediaAttachment `bun:"rel:belongs-to"` // MediaAttachment corresponding to avatarMediaAttachmentID
+ AvatarRemoteURL string `bun:",nullzero"` // For a non-local account, where can the header be fetched?
+ HeaderMediaAttachmentID string `bun:"type:CHAR(26),nullzero"` // Database ID of the media attachment, if present
+ HeaderMediaAttachment *MediaAttachment `bun:"rel:belongs-to"` // MediaAttachment corresponding to headerMediaAttachmentID
+ HeaderRemoteURL string `bun:",nullzero"` // For a non-local account, where can the header be fetched?
+ DisplayName string `bun:""` // DisplayName for this account. Can be empty, then just the Username will be used for display purposes.
+ EmojiIDs []string `bun:"emojis,array"` // Database IDs of any emojis used in this account's bio, display name, etc
+ Emojis []*Emoji `bun:"attached_emojis,m2m:account_to_emojis"` // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
+ Fields []*Field // A slice of of fields that this account has added to their profile.
+ FieldsRaw []*Field // The raw (unparsed) content of fields that this account has added to their profile, without conversion to HTML, only available when requester = target
+ Note string `bun:""` // A note that this account has on their profile (ie., the account's bio/description of themselves)
+ NoteRaw string `bun:""` // The raw contents of .Note without conversion to HTML, only available when requester = target
+ Memorial *bool `bun:",default:false"` // Is this a memorial account, ie., has the user passed away?
+ AlsoKnownAs string `bun:"type:CHAR(26),nullzero"` // This account is associated with x account id (TODO: migrate to be AlsoKnownAsID)
+ MovedToAccountID string `bun:"type:CHAR(26),nullzero"` // This account has moved this account id in the database
+ Bot *bool `bun:",default:false"` // Does this account identify itself as a bot?
+ Reason string `bun:""` // What reason was given for signing up when this account was created?
+ Locked *bool `bun:",default:true"` // Does this account need an approval for new followers?
+ Discoverable *bool `bun:",default:false"` // Should this account be shown in the instance's profile directory?
+ Privacy Visibility `bun:",nullzero"` // Default post privacy for this account
+ Sensitive *bool `bun:",default:false"` // Set posts from this account to sensitive by default?
+ Language string `bun:",nullzero,notnull,default:'en'"` // What language does this account post in?
+ StatusContentType string `bun:",nullzero"` // What is the default format for statuses posted by this account (only for local accounts).
+ CustomCSS string `bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
+ URI string `bun:",nullzero,notnull,unique"` // ActivityPub URI for this account.
+ URL string `bun:",nullzero,unique"` // Web URL for this account's profile
+ InboxURI string `bun:",nullzero,unique"` // Address of this account's ActivityPub inbox, for sending activity to
+ SharedInboxURI *string `bun:""` // Address of this account's ActivityPub sharedInbox. Gotcha warning: this is a string pointer because it has three possible states: 1. We don't know yet if the account has a shared inbox -- null. 2. We know it doesn't have a shared inbox -- empty string. 3. We know it does have a shared inbox -- url string.
+ OutboxURI string `bun:",nullzero,unique"` // Address of this account's activitypub outbox
+ FollowingURI string `bun:",nullzero,unique"` // URI for getting the following list of this account
+ FollowersURI string `bun:",nullzero,unique"` // URI for getting the followers list of this account
+ FeaturedCollectionURI string `bun:",nullzero,unique"` // URL for getting the featured collection list of this account
+ ActorType string `bun:",nullzero,notnull"` // What type of activitypub actor is this account?
+ PrivateKey *rsa.PrivateKey `bun:""` // Privatekey for validating activitypub requests, will only be defined for local accounts
+ PublicKey *rsa.PublicKey `bun:",notnull"` // Publickey for encoding activitypub requests, will be defined for both local and remote accounts
+ PublicKeyURI string `bun:",nullzero,notnull,unique"` // Web-reachable location of this account's public key
+ SensitizedAt time.Time `bun:"type:timestamptz,nullzero"` // When was this account set to have all its media shown as sensitive?
+ SilencedAt time.Time `bun:"type:timestamptz,nullzero"` // When was this account silenced (eg., statuses only visible to followers, not public)?
+ SuspendedAt time.Time `bun:"type:timestamptz,nullzero"` // When was this account suspended (eg., don't allow it to log in/post, don't accept media/posts from this account)
+ HideCollections *bool `bun:",default:false"` // Hide this account's collections
+ SuspensionOrigin string `bun:"type:CHAR(26),nullzero"` // id of the database entry that caused this account to become suspended -- can be an account ID or a domain block ID
+ EnableRSS *bool `bun:",default:false"` // enable RSS feed subscription for this account's public posts at [URL]/feed
}
// IsLocal returns whether account is a local user account.
@@ -131,19 +131,19 @@ func (a *Account) EmojisPopulated() bool {
// AccountToEmoji is an intermediate struct to facilitate the many2many relationship between an account and one or more emojis.
type AccountToEmoji struct {
- AccountID string `validate:"ulid,required" bun:"type:CHAR(26),unique:accountemoji,nullzero,notnull"`
- Account *Account `validate:"-" bun:"rel:belongs-to"`
- EmojiID string `validate:"ulid,required" bun:"type:CHAR(26),unique:accountemoji,nullzero,notnull"`
- Emoji *Emoji `validate:"-" bun:"rel:belongs-to"`
+ AccountID string `bun:"type:CHAR(26),unique:accountemoji,nullzero,notnull"`
+ Account *Account `bun:"rel:belongs-to"`
+ EmojiID string `bun:"type:CHAR(26),unique:accountemoji,nullzero,notnull"`
+ Emoji *Emoji `bun:"rel:belongs-to"`
}
// Field represents a key value field on an account, for things like pronouns, website, etc.
// VerifiedAt is optional, to be used only if Value is a URL to a webpage that contains the
// username of the user.
type Field struct {
- Name string `validate:"required"` // Name of this field.
- Value string `validate:"required"` // Value of this field.
- VerifiedAt time.Time `validate:"-" bun:",nullzero"` // This field was verified at (optional).
+ Name string // Name of this field.
+ Value string // Value of this field.
+ VerifiedAt time.Time `bun:",nullzero"` // This field was verified at (optional).
}
// Relationship describes a requester's relationship with another account.
diff --git a/internal/gtsmodel/accountnote.go b/internal/gtsmodel/accountnote.go
index 239ed6ce9..74b730eae 100644
--- a/internal/gtsmodel/accountnote.go
+++ b/internal/gtsmodel/accountnote.go
@@ -21,12 +21,12 @@ import "time"
// AccountNote stores a private note from a local account related to any account.
type AccountNote struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:account_notes_account_id_target_account_id_uniq,notnull,nullzero"` // ID of the local account that created the note
- Account *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:account_notes_account_id_target_account_id_uniq,notnull,nullzero"` // Who is the target of this note?
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to targetAccountID
- Comment string `validate:"-" bun:""` // The text of the note.
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ AccountID string `bun:"type:CHAR(26),unique:account_notes_account_id_target_account_id_uniq,notnull,nullzero"` // ID of the local account that created the note
+ Account *Account `bun:"rel:belongs-to"` // Account corresponding to accountID
+ TargetAccountID string `bun:"type:CHAR(26),unique:account_notes_account_id_target_account_id_uniq,notnull,nullzero"` // Who is the target of this note?
+ TargetAccount *Account `bun:"rel:belongs-to"` // Account corresponding to targetAccountID
+ Comment string `bun:""` // The text of the note.
}
diff --git a/internal/gtsmodel/admin.go b/internal/gtsmodel/admin.go
index 22a38f32c..f1f30db2d 100644
--- a/internal/gtsmodel/admin.go
+++ b/internal/gtsmodel/admin.go
@@ -24,17 +24,17 @@ import (
// AdminAccountAction models an action taken by an instance administrator on an account.
type AdminAccountAction struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero"` // Who performed this admin action.
- Account *Account `validate:"-" bun:"rel:has-one"` // Account corresponding to accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero"` // Who is the target of this action
- TargetAccount *Account `validate:"-" bun:"rel:has-one"` // Account corresponding to targetAccountID
- Text string `validate:"-" bun:""` // text explaining why this action was taken
- Type AdminActionType `validate:"oneof=disable silence suspend" bun:",nullzero,notnull"` // type of action that was taken
- SendEmail bool `validate:"-" bun:""` // should an email be sent to the account owner to explain what happened
- ReportID string `validate:",omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of a report connected to this action, if it exists
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ AccountID string `bun:"type:CHAR(26),notnull,nullzero"` // Who performed this admin action.
+ Account *Account `bun:"rel:has-one"` // Account corresponding to accountID
+ TargetAccountID string `bun:"type:CHAR(26),notnull,nullzero"` // Who is the target of this action
+ TargetAccount *Account `bun:"rel:has-one"` // Account corresponding to targetAccountID
+ Text string `bun:""` // text explaining why this action was taken
+ Type AdminActionType `bun:",nullzero,notnull"` // type of action that was taken
+ SendEmail bool `bun:""` // should an email be sent to the account owner to explain what happened
+ ReportID string `bun:"type:CHAR(26),nullzero"` // id of a report connected to this action, if it exists
}
// AdminActionType describes a type of action taken on an entity by an admin
diff --git a/internal/gtsmodel/application.go b/internal/gtsmodel/application.go
index a9057b558..5f2d4f4b1 100644
--- a/internal/gtsmodel/application.go
+++ b/internal/gtsmodel/application.go
@@ -22,13 +22,13 @@ import "time"
// Application represents an application that can perform actions on behalf of a user.
// It is used to authorize tokens etc, and is associated with an oauth client id in the database.
type Application struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Name string `validate:"required" bun:",notnull"` // name of the application given when it was created (eg., 'tusky')
- Website string `validate:"omitempty,url" bun:",nullzero"` // website for the application given when it was created (eg., 'https://tusky.app')
- RedirectURI string `validate:"required,uri" bun:",nullzero,notnull"` // redirect uri requested by the application for oauth2 flow
- ClientID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id of the associated oauth client entity in the db
- ClientSecret string `validate:"required,uuid" bun:",nullzero,notnull"` // secret of the associated oauth client entity in the db
- Scopes string `validate:"required" bun:",notnull"` // scopes requested when this app was created
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Name string `bun:",notnull"` // name of the application given when it was created (eg., 'tusky')
+ Website string `bun:",nullzero"` // website for the application given when it was created (eg., 'https://tusky.app')
+ RedirectURI string `bun:",nullzero,notnull"` // redirect uri requested by the application for oauth2 flow
+ ClientID string `bun:"type:CHAR(26),nullzero,notnull"` // id of the associated oauth client entity in the db
+ ClientSecret string `bun:",nullzero,notnull"` // secret of the associated oauth client entity in the db
+ Scopes string `bun:",notnull"` // scopes requested when this app was created
}
diff --git a/internal/gtsmodel/block.go b/internal/gtsmodel/block.go
index 98f68f451..1fcdb364a 100644
--- a/internal/gtsmodel/block.go
+++ b/internal/gtsmodel/block.go
@@ -21,12 +21,12 @@ import "time"
// Block refers to the blocking of one account by another.
type Block struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- URI string `validate:"required,url" bun:",notnull,nullzero,unique"` // ActivityPub uri of this block.
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:blocksrctarget,notnull,nullzero"` // Who does this block originate from?
- Account *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:blocksrctarget,notnull,nullzero"` // Who is the target of this block ?
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to targetAccountID
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ URI string `bun:",notnull,nullzero,unique"` // ActivityPub uri of this block.
+ AccountID string `bun:"type:CHAR(26),unique:blocksrctarget,notnull,nullzero"` // Who does this block originate from?
+ Account *Account `bun:"rel:belongs-to"` // Account corresponding to accountID
+ TargetAccountID string `bun:"type:CHAR(26),unique:blocksrctarget,notnull,nullzero"` // Who is the target of this block ?
+ TargetAccount *Account `bun:"rel:belongs-to"` // Account corresponding to targetAccountID
}
diff --git a/internal/gtsmodel/client.go b/internal/gtsmodel/client.go
index a712257e5..35a85fdbe 100644
--- a/internal/gtsmodel/client.go
+++ b/internal/gtsmodel/client.go
@@ -21,10 +21,10 @@ import "time"
// Client is a wrapper for OAuth client details.
type Client struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Secret string `validate:"required,uuid" bun:",nullzero,notnull"` // secret generated when client was created
- Domain string `validate:"required,uri" bun:",nullzero,notnull"` // domain requested for client
- UserID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the user that this client acts on behalf of
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Secret string `bun:",nullzero,notnull"` // secret generated when client was created
+ Domain string `bun:",nullzero,notnull"` // domain requested for client
+ UserID string `bun:"type:CHAR(26),nullzero"` // id of the user that this client acts on behalf of
}
diff --git a/internal/gtsmodel/domainblock.go b/internal/gtsmodel/domainblock.go
index 0d038d18c..dfe642ef5 100644
--- a/internal/gtsmodel/domainblock.go
+++ b/internal/gtsmodel/domainblock.go
@@ -21,14 +21,14 @@ import "time"
// DomainBlock represents a federation block against a particular domain
type DomainBlock struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Domain string `validate:"required,fqdn" bun:",nullzero,notnull"` // domain to block. Eg. 'whatever.com'
- CreatedByAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // Account ID of the creator of this block
- CreatedByAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to createdByAccountID
- PrivateComment string `validate:"-" bun:""` // Private comment on this block, viewable to admins
- PublicComment string `validate:"-" bun:""` // Public comment on this block, viewable (optionally) by everyone
- Obfuscate *bool `validate:"-" bun:",nullzero,notnull,default:false"` // whether the domain name should appear obfuscated when displaying it publicly
- SubscriptionID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // if this block was created through a subscription, what's the subscription ID?
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Domain string `bun:",nullzero,notnull"` // domain to block. Eg. 'whatever.com'
+ CreatedByAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // Account ID of the creator of this block
+ CreatedByAccount *Account `bun:"rel:belongs-to"` // Account corresponding to createdByAccountID
+ PrivateComment string `bun:""` // Private comment on this block, viewable to admins
+ PublicComment string `bun:""` // Public comment on this block, viewable (optionally) by everyone
+ Obfuscate *bool `bun:",nullzero,notnull,default:false"` // whether the domain name should appear obfuscated when displaying it publicly
+ SubscriptionID string `bun:"type:CHAR(26),nullzero"` // if this block was created through a subscription, what's the subscription ID?
}
diff --git a/internal/gtsmodel/emaildomainblock.go b/internal/gtsmodel/emaildomainblock.go
index 7258f64d7..c81eec365 100644
--- a/internal/gtsmodel/emaildomainblock.go
+++ b/internal/gtsmodel/emaildomainblock.go
@@ -21,10 +21,10 @@ import "time"
// EmailDomainBlock represents a domain that the server should automatically reject sign-up requests from.
type EmailDomainBlock struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Domain string `validate:"required,fqdn" bun:",nullzero,notnull"` // Email domain to block. Eg. 'gmail.com' or 'hotmail.com'
- CreatedByAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // Account ID of the creator of this block
- CreatedByAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to createdByAccountID
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Domain string `bun:",nullzero,notnull"` // Email domain to block. Eg. 'gmail.com' or 'hotmail.com'
+ CreatedByAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // Account ID of the creator of this block
+ CreatedByAccount *Account `bun:"rel:belongs-to"` // Account corresponding to createdByAccountID
}
diff --git a/internal/gtsmodel/emoji.go b/internal/gtsmodel/emoji.go
index 0fcc3247b..596a64110 100644
--- a/internal/gtsmodel/emoji.go
+++ b/internal/gtsmodel/emoji.go
@@ -21,26 +21,26 @@ import "time"
// Emoji represents a custom emoji that's been uploaded through the admin UI or downloaded from a remote instance.
type Emoji struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Shortcode string `validate:"required" bun:",nullzero,notnull,unique:domainshortcode"` // String shortcode for this emoji -- the part that's between colons. This should be a-zA-Z_ eg., 'blob_hug' 'purple_heart' 'Gay_Otter' Must be unique with domain.
- Domain string `validate:"omitempty,fqdn" bun:",nullzero,unique:domainshortcode"` // Origin domain of this emoji, eg 'example.org', 'queer.party'. empty string for local emojis.
- ImageRemoteURL string `validate:"required_without=ImageURL,omitempty,url" bun:",nullzero"` // Where can this emoji be retrieved remotely? Null for local emojis.
- ImageStaticRemoteURL string `validate:"required_without=ImageStaticURL,omitempty,url" bun:",nullzero"` // Where can a static / non-animated version of this emoji be retrieved remotely? Null for local emojis.
- ImageURL string `validate:"required_without=ImageRemoteURL,required_without=Domain,omitempty,url" bun:",nullzero"` // Where can this emoji be retrieved from the local server? Null for remote emojis.
- ImageStaticURL string `validate:"required_without=ImageStaticRemoteURL,required_without=Domain,omitempty,url" bun:",nullzero"` // Where can a static version of this emoji be retrieved from the local server? Null for remote emojis.
- ImagePath string `validate:"required,file" bun:",nullzero,notnull"` // Path of the emoji image in the server storage system.
- ImageStaticPath string `validate:"required,file" bun:",nullzero,notnull"` // Path of a static version of the emoji image in the server storage system
- ImageContentType string `validate:"required" bun:",nullzero,notnull"` // MIME content type of the emoji image
- ImageStaticContentType string `validate:"required" bun:",nullzero,notnull"` // MIME content type of the static version of the emoji image.
- ImageFileSize int `validate:"required,min=1" bun:",nullzero,notnull"` // Size of the emoji image file in bytes, for serving purposes.
- ImageStaticFileSize int `validate:"required,min=1" bun:",nullzero,notnull"` // Size of the static version of the emoji image file in bytes, for serving purposes.
- ImageUpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the emoji image last updated?
- Disabled *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Has a moderation action disabled this emoji from being shown?
- URI string `validate:"url" bun:",nullzero,notnull,unique"` // ActivityPub uri of this emoji. Something like 'https://example.org/emojis/1234'
- VisibleInPicker *bool `validate:"-" bun:",nullzero,notnull,default:true"` // Is this emoji visible in the admin emoji picker?
- Category *EmojiCategory `validate:"-" bun:"rel:belongs-to"` // In which emoji category is this emoji visible?
- CategoryID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // ID of the category this emoji belongs to.
- Cached *bool `validate:"-" bun:",nullzero,notnull,default:false"`
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Shortcode string `bun:",nullzero,notnull,unique:domainshortcode"` // String shortcode for this emoji -- the part that's between colons. This should be a-zA-Z_ eg., 'blob_hug' 'purple_heart' 'Gay_Otter' Must be unique with domain.
+ Domain string `bun:",nullzero,unique:domainshortcode"` // Origin domain of this emoji, eg 'example.org', 'queer.party'. empty string for local emojis.
+ ImageRemoteURL string `bun:",nullzero"` // Where can this emoji be retrieved remotely? Null for local emojis.
+ ImageStaticRemoteURL string `bun:",nullzero"` // Where can a static / non-animated version of this emoji be retrieved remotely? Null for local emojis.
+ ImageURL string `bun:",nullzero"` // Where can this emoji be retrieved from the local server? Null for remote emojis.
+ ImageStaticURL string `bun:",nullzero"` // Where can a static version of this emoji be retrieved from the local server? Null for remote emojis.
+ ImagePath string `bun:",nullzero,notnull"` // Path of the emoji image in the server storage system.
+ ImageStaticPath string `bun:",nullzero,notnull"` // Path of a static version of the emoji image in the server storage system
+ ImageContentType string `bun:",nullzero,notnull"` // MIME content type of the emoji image
+ ImageStaticContentType string `bun:",nullzero,notnull"` // MIME content type of the static version of the emoji image.
+ ImageFileSize int `bun:",nullzero,notnull"` // Size of the emoji image file in bytes, for serving purposes.
+ ImageStaticFileSize int `bun:",nullzero,notnull"` // Size of the static version of the emoji image file in bytes, for serving purposes.
+ ImageUpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the emoji image last updated?
+ Disabled *bool `bun:",nullzero,notnull,default:false"` // Has a moderation action disabled this emoji from being shown?
+ URI string `bun:",nullzero,notnull,unique"` // ActivityPub uri of this emoji. Something like 'https://example.org/emojis/1234'
+ VisibleInPicker *bool `bun:",nullzero,notnull,default:true"` // Is this emoji visible in the admin emoji picker?
+ Category *EmojiCategory `bun:"rel:belongs-to"` // In which emoji category is this emoji visible?
+ CategoryID string `bun:"type:CHAR(26),nullzero"` // ID of the category this emoji belongs to.
+ Cached *bool `bun:",nullzero,notnull,default:false"`
}
diff --git a/internal/gtsmodel/emojicategory.go b/internal/gtsmodel/emojicategory.go
index ad17a8600..80a448f3c 100644
--- a/internal/gtsmodel/emojicategory.go
+++ b/internal/gtsmodel/emojicategory.go
@@ -21,8 +21,8 @@ import "time"
// EmojiCategory represents a grouping of custom emojis.
type EmojiCategory struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Name string `validate:"required" bun:",nullzero,notnull,unique"` // name of this category
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Name string `bun:",nullzero,notnull,unique"` // name of this category
}
diff --git a/internal/gtsmodel/follow.go b/internal/gtsmodel/follow.go
index 871d01e20..f359a7bc4 100644
--- a/internal/gtsmodel/follow.go
+++ b/internal/gtsmodel/follow.go
@@ -21,14 +21,14 @@ import "time"
// Follow represents one account following another, and the metadata around that follow.
type Follow struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- URI string `validate:"required,url" bun:",notnull,nullzero,unique"` // ActivityPub uri of this follow.
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:srctarget,notnull,nullzero"` // Who does this follow originate from?
- Account *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:srctarget,notnull,nullzero"` // Who is the target of this follow ?
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to targetAccountID
- ShowReblogs *bool `validate:"-" bun:",nullzero,notnull,default:true"` // Does this follow also want to see reblogs and not just posts?
- Notify *bool `validate:"-" bun:",nullzero,notnull,default:false"` // does the following account want to be notified when the followed account posts?
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ URI string `bun:",notnull,nullzero,unique"` // ActivityPub uri of this follow.
+ AccountID string `bun:"type:CHAR(26),unique:srctarget,notnull,nullzero"` // Who does this follow originate from?
+ Account *Account `bun:"rel:belongs-to"` // Account corresponding to accountID
+ TargetAccountID string `bun:"type:CHAR(26),unique:srctarget,notnull,nullzero"` // Who is the target of this follow ?
+ TargetAccount *Account `bun:"rel:belongs-to"` // Account corresponding to targetAccountID
+ ShowReblogs *bool `bun:",nullzero,notnull,default:true"` // Does this follow also want to see reblogs and not just posts?
+ Notify *bool `bun:",nullzero,notnull,default:false"` // does the following account want to be notified when the followed account posts?
}
diff --git a/internal/gtsmodel/followrequest.go b/internal/gtsmodel/followrequest.go
index 3fc161af7..32eb13950 100644
--- a/internal/gtsmodel/followrequest.go
+++ b/internal/gtsmodel/followrequest.go
@@ -21,14 +21,14 @@ import "time"
// FollowRequest represents one account requesting to follow another, and the metadata around that request.
type FollowRequest struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- URI string `validate:"required,url" bun:",notnull,nullzero,unique"` // ActivityPub uri of this follow (request).
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:frsrctarget,notnull,nullzero"` // Who does this follow request originate from?
- Account *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:frsrctarget,notnull,nullzero"` // Who is the target of this follow request?
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // Account corresponding to targetAccountID
- ShowReblogs *bool `validate:"-" bun:",nullzero,notnull,default:true"` // Does this follow also want to see reblogs and not just posts?
- Notify *bool `validate:"-" bun:",nullzero,notnull,default:false"` // does the following account want to be notified when the followed account posts?
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ URI string `bun:",notnull,nullzero,unique"` // ActivityPub uri of this follow (request).
+ AccountID string `bun:"type:CHAR(26),unique:frsrctarget,notnull,nullzero"` // Who does this follow request originate from?
+ Account *Account `bun:"rel:belongs-to"` // Account corresponding to accountID
+ TargetAccountID string `bun:"type:CHAR(26),unique:frsrctarget,notnull,nullzero"` // Who is the target of this follow request?
+ TargetAccount *Account `bun:"rel:belongs-to"` // Account corresponding to targetAccountID
+ ShowReblogs *bool `bun:",nullzero,notnull,default:true"` // Does this follow also want to see reblogs and not just posts?
+ Notify *bool `bun:",nullzero,notnull,default:false"` // does the following account want to be notified when the followed account posts?
}
diff --git a/internal/gtsmodel/instance.go b/internal/gtsmodel/instance.go
index 3172726fd..388f0f4ed 100644
--- a/internal/gtsmodel/instance.go
+++ b/internal/gtsmodel/instance.go
@@ -21,22 +21,22 @@ import "time"
// Instance represents a federated instance, either local or remote.
type Instance struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Domain string `validate:"required,fqdn" bun:",nullzero,notnull,unique"` // Instance domain eg example.org
- Title string `validate:"-" bun:""` // Title of this instance as it would like to be displayed.
- URI string `validate:"required,url" bun:",nullzero,notnull,unique"` // base URI of this instance eg https://example.org
- SuspendedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When was this instance suspended, if at all?
- DomainBlockID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // ID of any existing domain block for this instance in the database
- DomainBlock *DomainBlock `validate:"-" bun:"rel:belongs-to"` // Domain block corresponding to domainBlockID
- ShortDescription string `validate:"-" bun:""` // Short description of this instance
- Description string `validate:"-" bun:""` // Longer description of this instance
- Terms string `validate:"-" bun:""` // Terms and conditions of this instance
- ContactEmail string `validate:"omitempty,email" bun:""` // Contact email address for this instance
- ContactAccountUsername string `validate:"required_with=ContactAccountID" bun:",nullzero"` // Username of the contact account for this instance
- ContactAccountID string `validate:"required_with=ContactAccountUsername,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Contact account ID in the database for this instance
- ContactAccount *Account `validate:"-" bun:"rel:belongs-to"` // account corresponding to contactAccountID
- Reputation int64 `validate:"-" bun:",notnull,default:0"` // Reputation score of this instance
- Version string `validate:"-" bun:",nullzero"` // Version of the software used on this instance
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Domain string `bun:",nullzero,notnull,unique"` // Instance domain eg example.org
+ Title string `bun:""` // Title of this instance as it would like to be displayed.
+ URI string `bun:",nullzero,notnull,unique"` // base URI of this instance eg https://example.org
+ SuspendedAt time.Time `bun:"type:timestamptz,nullzero"` // When was this instance suspended, if at all?
+ DomainBlockID string `bun:"type:CHAR(26),nullzero"` // ID of any existing domain block for this instance in the database
+ DomainBlock *DomainBlock `bun:"rel:belongs-to"` // Domain block corresponding to domainBlockID
+ ShortDescription string `bun:""` // Short description of this instance
+ Description string `bun:""` // Longer description of this instance
+ Terms string `bun:""` // Terms and conditions of this instance
+ ContactEmail string `bun:""` // Contact email address for this instance
+ ContactAccountUsername string `bun:",nullzero"` // Username of the contact account for this instance
+ ContactAccountID string `bun:"type:CHAR(26),nullzero"` // Contact account ID in the database for this instance
+ ContactAccount *Account `bun:"rel:belongs-to"` // account corresponding to contactAccountID
+ Reputation int64 `bun:",notnull,default:0"` // Reputation score of this instance
+ Version string `bun:",nullzero"` // Version of the software used on this instance
}
diff --git a/internal/gtsmodel/list.go b/internal/gtsmodel/list.go
index 98188b113..ea53df9b3 100644
--- a/internal/gtsmodel/list.go
+++ b/internal/gtsmodel/list.go
@@ -21,24 +21,24 @@ import "time"
// List refers to a list of follows for which the owning account wants to view a timeline of posts.
type List struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Title string `validate:"required" bun:",nullzero,notnull,unique:listaccounttitle"` // Title of this list.
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero,unique:listaccounttitle"` // Account that created/owns the list
- Account *Account `validate:"-" bun:"-"` // Account corresponding to accountID
- ListEntries []*ListEntry `validate:"-" bun:"-"` // Entries contained by this list.
- RepliesPolicy RepliesPolicy `validate:"-" bun:",nullzero,notnull,default:'followed'"` // RepliesPolicy for this list.
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Title string `bun:",nullzero,notnull,unique:listaccounttitle"` // Title of this list.
+ AccountID string `bun:"type:CHAR(26),notnull,nullzero,unique:listaccounttitle"` // Account that created/owns the list
+ Account *Account `bun:"-"` // Account corresponding to accountID
+ ListEntries []*ListEntry `bun:"-"` // Entries contained by this list.
+ RepliesPolicy RepliesPolicy `bun:",nullzero,notnull,default:'followed'"` // RepliesPolicy for this list.
}
// ListEntry refers to a single follow entry in a list.
type ListEntry struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- ListID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero,unique:listentrylistfollow"` // ID of the list that this entry belongs to.
- FollowID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero,unique:listentrylistfollow"` // Follow that the account owning this entry wants to see posts of in the timeline.
- Follow *Follow `validate:"-" bun:"-"` // Follow corresponding to followID.
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ ListID string `bun:"type:CHAR(26),notnull,nullzero,unique:listentrylistfollow"` // ID of the list that this entry belongs to.
+ FollowID string `bun:"type:CHAR(26),notnull,nullzero,unique:listentrylistfollow"` // Follow that the account owning this entry wants to see posts of in the timeline.
+ Follow *Follow `bun:"-"` // Follow corresponding to followID.
}
// RepliesPolicy denotes which replies should be shown in the list.
diff --git a/internal/gtsmodel/marker.go b/internal/gtsmodel/marker.go
index 3aeb376ff..93fbebfe0 100644
--- a/internal/gtsmodel/marker.go
+++ b/internal/gtsmodel/marker.go
@@ -21,11 +21,11 @@ import "time"
// Marker stores a local account's read position on a given timeline.
type Marker struct {
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),pk,unique:markers_account_id_timeline_uniq,notnull,nullzero"` // ID of the local account that owns the marker
- Name MarkerName `validate:"oneof=home notifications" bun:",nullzero,notnull,pk,unique:markers_account_id_timeline_uniq"` // Name of the marked timeline
- UpdatedAt time.Time `validate:"required" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When marker was last updated
- Version int `validate:"required,min=0" bun:",nullzero,notnull,default:0"` // For optimistic concurrency control
- LastReadID string `validate:"required,ulid" bun:"type:CHAR(26),notnull,nullzero"` // Last ID read on this timeline (status ID for home, notification ID for notifications)
+ AccountID string `bun:"type:CHAR(26),pk,unique:markers_account_id_timeline_uniq,notnull,nullzero"` // ID of the local account that owns the marker
+ Name MarkerName `bun:",nullzero,notnull,pk,unique:markers_account_id_timeline_uniq"` // Name of the marked timeline
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When marker was last updated
+ Version int `bun:",nullzero,notnull,default:0"` // For optimistic concurrency control
+ LastReadID string `bun:"type:CHAR(26),notnull,nullzero"` // Last ID read on this timeline (status ID for home, notification ID for notifications)
}
// MarkerName is the name of one of the timelines we can store markers for.
diff --git a/internal/gtsmodel/mediaattachment.go b/internal/gtsmodel/mediaattachment.go
index b8e8b57f7..e418de7d2 100644
--- a/internal/gtsmodel/mediaattachment.go
+++ b/internal/gtsmodel/mediaattachment.go
@@ -24,42 +24,42 @@ import (
// MediaAttachment represents a user-uploaded media attachment: an image/video/audio/gif that is
// somewhere in storage and that can be retrieved and served by the router.
type MediaAttachment struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- StatusID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // ID of the status to which this is attached
- URL string `validate:"required_without=RemoteURL,omitempty,url" bun:",nullzero"` // Where can the attachment be retrieved on *this* server
- RemoteURL string `validate:"required_without=URL,omitempty,url" bun:",nullzero"` // Where can the attachment be retrieved on a remote server (empty for local media)
- Type FileType `validate:"oneof=Image Gifv Audio Video Unknown" bun:",nullzero,notnull"` // Type of file (image/gifv/audio/video)
- FileMeta FileMeta `validate:"required" bun:",embed:,nullzero,notnull"` // Metadata about the file
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // To which account does this attachment belong
- Description string `validate:"-" bun:""` // Description of the attachment (for screenreaders)
- ScheduledStatusID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // To which scheduled status does this attachment belong
- Blurhash string `validate:"required_if=Type Image,required_if=Type Gif,required_if=Type Video" bun:",nullzero"` // What is the generated blurhash of this attachment
- Processing ProcessingStatus `validate:"oneof=0 1 2 666" bun:",notnull,default:2"` // What is the processing status of this attachment
- File File `validate:"required" bun:",embed:file_,notnull,nullzero"` // metadata for the whole file
- Thumbnail Thumbnail `validate:"required" bun:",embed:thumbnail_,notnull,nullzero"` // small image thumbnail derived from a larger image, video, or audio file.
- Avatar *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this attachment being used as an avatar?
- Header *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this attachment being used as a header?
- Cached *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this attachment currently cached by our instance?
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ StatusID string `bun:"type:CHAR(26),nullzero"` // ID of the status to which this is attached
+ URL string `bun:",nullzero"` // Where can the attachment be retrieved on *this* server
+ RemoteURL string `bun:",nullzero"` // Where can the attachment be retrieved on a remote server (empty for local media)
+ Type FileType `bun:",nullzero,notnull"` // Type of file (image/gifv/audio/video)
+ FileMeta FileMeta `bun:",embed:,nullzero,notnull"` // Metadata about the file
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull"` // To which account does this attachment belong
+ Description string `bun:""` // Description of the attachment (for screenreaders)
+ ScheduledStatusID string `bun:"type:CHAR(26),nullzero"` // To which scheduled status does this attachment belong
+ Blurhash string `bun:",nullzero"` // What is the generated blurhash of this attachment
+ Processing ProcessingStatus `bun:",notnull,default:2"` // What is the processing status of this attachment
+ File File `bun:",embed:file_,notnull,nullzero"` // metadata for the whole file
+ Thumbnail Thumbnail `bun:",embed:thumbnail_,notnull,nullzero"` // small image thumbnail derived from a larger image, video, or audio file.
+ Avatar *bool `bun:",nullzero,notnull,default:false"` // Is this attachment being used as an avatar?
+ Header *bool `bun:",nullzero,notnull,default:false"` // Is this attachment being used as a header?
+ Cached *bool `bun:",nullzero,notnull,default:false"` // Is this attachment currently cached by our instance?
}
// File refers to the metadata for the whole file
type File struct {
- Path string `validate:"required,file" bun:",nullzero,notnull"` // Path of the file in storage.
- ContentType string `validate:"required" bun:",nullzero,notnull"` // MIME content type of the file.
- FileSize int `validate:"required" bun:",notnull"` // File size in bytes
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the file last updated.
+ Path string `bun:",nullzero,notnull"` // Path of the file in storage.
+ ContentType string `bun:",nullzero,notnull"` // MIME content type of the file.
+ FileSize int `bun:",notnull"` // File size in bytes
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the file last updated.
}
// Thumbnail refers to a small image thumbnail derived from a larger image, video, or audio file.
type Thumbnail struct {
- Path string `validate:"required,file" bun:",nullzero,notnull"` // Path of the file in storage.
- ContentType string `validate:"required" bun:",nullzero,notnull"` // MIME content type of the file.
- FileSize int `validate:"required" bun:",notnull"` // File size in bytes
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the file last updated.
- URL string `validate:"required_without=RemoteURL,omitempty,url" bun:",nullzero"` // What is the URL of the thumbnail on the local server
- RemoteURL string `validate:"required_without=URL,omitempty,url" bun:",nullzero"` // What is the remote URL of the thumbnail (empty for local media)
+ Path string `bun:",nullzero,notnull"` // Path of the file in storage.
+ ContentType string `bun:",nullzero,notnull"` // MIME content type of the file.
+ FileSize int `bun:",notnull"` // File size in bytes
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // When was the file last updated.
+ URL string `bun:",nullzero"` // What is the URL of the thumbnail on the local server
+ RemoteURL string `bun:",nullzero"` // What is the remote URL of the thumbnail (empty for local media)
}
// ProcessingStatus refers to how far along in the processing stage the attachment is.
@@ -87,33 +87,33 @@ const (
// FileMeta describes metadata about the actual contents of the file.
type FileMeta struct {
- Original Original `validate:"required" bun:"embed:original_"`
+ Original Original `bun:"embed:original_"`
Small Small `bun:"embed:small_"`
Focus Focus `bun:"embed:focus_"`
}
// Small can be used for a thumbnail of any media type
type Small struct {
- Width int `validate:"required_with=Height Size Aspect"` // width in pixels
- Height int `validate:"required_with=Width Size Aspect"` // height in pixels
- Size int `validate:"required_with=Width Height Aspect"` // size in pixels (width * height)
- Aspect float32 `validate:"required_with=Width Height Size"` // aspect ratio (width / height)
+ Width int // width in pixels
+ Height int // height in pixels
+ Size int // size in pixels (width * height)
+ Aspect float32 // aspect ratio (width / height)
}
// Original can be used for original metadata for any media type
type Original struct {
- Width int `validate:"required_with=Height Size Aspect"` // width in pixels
- Height int `validate:"required_with=Width Size Aspect"` // height in pixels
- Size int `validate:"required_with=Width Height Aspect"` // size in pixels (width * height)
- Aspect float32 `validate:"required_with=Width Height Size"` // aspect ratio (width / height)
- Duration *float32 `validate:"-"` // video-specific: duration of the video in seconds
- Framerate *float32 `validate:"-"` // video-specific: fps
- Bitrate *uint64 `validate:"-"` // video-specific: bitrate
+ Width int // width in pixels
+ Height int // height in pixels
+ Size int // size in pixels (width * height)
+ Aspect float32 // aspect ratio (width / height)
+ Duration *float32 // video-specific: duration of the video in seconds
+ Framerate *float32 // video-specific: fps
+ Bitrate *uint64 // video-specific: bitrate
}
// Focus describes the 'center' of the image for display purposes.
// X and Y should each be between -1 and 1
type Focus struct {
- X float32 `validate:"omitempty,max=1,min=-1"`
- Y float32 `validate:"omitempty,max=1,min=-1"`
+ X float32
+ Y float32
}
diff --git a/internal/gtsmodel/mention.go b/internal/gtsmodel/mention.go
index 9ad9204eb..fb7f3b51a 100644
--- a/internal/gtsmodel/mention.go
+++ b/internal/gtsmodel/mention.go
@@ -24,17 +24,17 @@ import (
// Mention refers to the 'tagging' or 'mention' of a user within a status.
type Mention struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- StatusID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // ID of the status this mention originates from
- Status *Status `validate:"-" bun:"rel:belongs-to"` // status referred to by statusID
- OriginAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // ID of the mention creator account
- OriginAccountURI string `validate:"url" bun:",nullzero,notnull"` // ActivityPub URI of the originator/creator of the mention
- OriginAccount *Account `validate:"-" bun:"rel:belongs-to"` // account referred to by originAccountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // Mention target/receiver account ID
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // account referred to by targetAccountID
- Silent *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Prevent this mention from generating a notification?
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ StatusID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the status this mention originates from
+ Status *Status `bun:"rel:belongs-to"` // status referred to by statusID
+ OriginAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the mention creator account
+ OriginAccountURI string `bun:",nullzero,notnull"` // ActivityPub URI of the originator/creator of the mention
+ OriginAccount *Account `bun:"rel:belongs-to"` // account referred to by originAccountID
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // Mention target/receiver account ID
+ TargetAccount *Account `bun:"rel:belongs-to"` // account referred to by targetAccountID
+ Silent *bool `bun:",nullzero,notnull,default:false"` // Prevent this mention from generating a notification?
/*
NON-DATABASE CONVENIENCE FIELDS
@@ -48,15 +48,15 @@ type Mention struct {
// @whatever_username@example.org
//
// This will not be put in the database, it's just for convenience.
- NameString string `validate:"-" bun:"-"`
+ NameString string `bun:"-"`
// TargetAccountURI is the AP ID (uri) of the user mentioned.
//
// This will not be put in the database, it's just for convenience.
- TargetAccountURI string `validate:"-" bun:"-"`
+ TargetAccountURI string `bun:"-"`
// TargetAccountURL is the web url of the user mentioned.
//
// This will not be put in the database, it's just for convenience.
- TargetAccountURL string `validate:"-" bun:"-"`
+ TargetAccountURL string `bun:"-"`
// A pointer to the gtsmodel account of the mentioned account.
}
diff --git a/internal/gtsmodel/notification.go b/internal/gtsmodel/notification.go
index 7e8db7713..5e2eff167 100644
--- a/internal/gtsmodel/notification.go
+++ b/internal/gtsmodel/notification.go
@@ -21,17 +21,17 @@ import "time"
// Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc.
type Notification struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- NotificationType NotificationType `validate:"oneof=follow follow_request mention reblog favourite poll status" bun:",nullzero,notnull"` // Type of this notification
- TargetAccountID string `validate:"ulid" bun:"type:CHAR(26),nullzero,notnull"` // ID of the account targeted by the notification (ie., who will receive the notification?)
- TargetAccount *Account `validate:"-" bun:"-"` // Account corresponding to TargetAccountID. Can be nil, always check first + select using ID if necessary.
- OriginAccountID string `validate:"ulid" bun:"type:CHAR(26),nullzero,notnull"` // ID of the account that performed the action that created the notification.
- OriginAccount *Account `validate:"-" bun:"-"` // Account corresponding to OriginAccountID. Can be nil, always check first + select using ID if necessary.
- StatusID string `validate:"required_if=NotificationType mention,required_if=NotificationType reblog,required_if=NotificationType favourite,required_if=NotificationType status,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // If the notification pertains to a status, what is the database ID of that status?
- Status *Status `validate:"-" bun:"-"` // Status corresponding to StatusID. Can be nil, always check first + select using ID if necessary.
- Read *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Notification has been seen/read
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ NotificationType NotificationType `bun:",nullzero,notnull"` // Type of this notification
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the account targeted by the notification (ie., who will receive the notification?)
+ TargetAccount *Account `bun:"-"` // Account corresponding to TargetAccountID. Can be nil, always check first + select using ID if necessary.
+ OriginAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the account that performed the action that created the notification.
+ OriginAccount *Account `bun:"-"` // Account corresponding to OriginAccountID. Can be nil, always check first + select using ID if necessary.
+ StatusID string `bun:"type:CHAR(26),nullzero"` // If the notification pertains to a status, what is the database ID of that status?
+ Status *Status `bun:"-"` // Status corresponding to StatusID. Can be nil, always check first + select using ID if necessary.
+ Read *bool `bun:",nullzero,notnull,default:false"` // Notification has been seen/read
}
// NotificationType describes the reason/type of this notification.
diff --git a/internal/gtsmodel/report.go b/internal/gtsmodel/report.go
index eb45c820c..e5b942563 100644
--- a/internal/gtsmodel/report.go
+++ b/internal/gtsmodel/report.go
@@ -26,20 +26,20 @@ import "time"
// or another instance, OR a report that was created remotely (on another instance)
// about a user on this instance, and received via the federated (s2s) API.
type Report struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- URI string `validate:"required,url" bun:",unique,nullzero,notnull"` // activitypub URI of this report
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // which account created this report
- Account *Account `validate:"-" bun:"-"` // account corresponding to AccountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // which account is targeted by this report
- TargetAccount *Account `validate:"-" bun:"-"` // account corresponding to TargetAccountID
- Comment string `validate:"-" bun:",nullzero"` // comment / explanation for this report, by the reporter
- StatusIDs []string `validate:"dive,ulid" bun:"statuses,array"` // database IDs of any statuses referenced by this report
- Statuses []*Status `validate:"-" bun:"-"` // statuses corresponding to StatusIDs
- Forwarded *bool `validate:"-" bun:",nullzero,notnull,default:false"` // flag to indicate report should be forwarded to remote instance
- ActionTaken string `validate:"-" bun:",nullzero"` // string description of what action was taken in response to this report
- ActionTakenAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // time at which action was taken, if any
- ActionTakenByAccountID string `validate:",omitempty,ulid" bun:"type:CHAR(26),nullzero"` // database ID of account which took action, if any
- ActionTakenByAccount *Account `validate:"-" bun:"-"` // account corresponding to ActionTakenByID, if any
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ URI string `bun:",unique,nullzero,notnull"` // activitypub URI of this report
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull"` // which account created this report
+ Account *Account `bun:"-"` // account corresponding to AccountID
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // which account is targeted by this report
+ TargetAccount *Account `bun:"-"` // account corresponding to TargetAccountID
+ Comment string `bun:",nullzero"` // comment / explanation for this report, by the reporter
+ StatusIDs []string `bun:"statuses,array"` // database IDs of any statuses referenced by this report
+ Statuses []*Status `bun:"-"` // statuses corresponding to StatusIDs
+ Forwarded *bool `bun:",nullzero,notnull,default:false"` // flag to indicate report should be forwarded to remote instance
+ ActionTaken string `bun:",nullzero"` // string description of what action was taken in response to this report
+ ActionTakenAt time.Time `bun:"type:timestamptz,nullzero"` // time at which action was taken, if any
+ ActionTakenByAccountID string `bun:"type:CHAR(26),nullzero"` // database ID of account which took action, if any
+ ActionTakenByAccount *Account `bun:"-"` // account corresponding to ActionTakenByID, if any
}
diff --git a/internal/gtsmodel/routersession.go b/internal/gtsmodel/routersession.go
index 050c0715b..d51d93bca 100644
--- a/internal/gtsmodel/routersession.go
+++ b/internal/gtsmodel/routersession.go
@@ -21,9 +21,9 @@ import "time"
// RouterSession is used to store and retrieve settings for a router session.
type RouterSession struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Auth []byte `validate:"required,len=32" bun:"type:bytea,notnull,nullzero"`
- Crypt []byte `validate:"required,len=32" bun:"type:bytea,notnull,nullzero"`
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Auth []byte `bun:"type:bytea,notnull,nullzero"`
+ Crypt []byte `bun:"type:bytea,notnull,nullzero"`
}
diff --git a/internal/gtsmodel/status.go b/internal/gtsmodel/status.go
index 393bb1ac7..3e8880798 100644
--- a/internal/gtsmodel/status.go
+++ b/internal/gtsmodel/status.go
@@ -25,47 +25,47 @@ import (
// Status represents a user-created 'post' or 'status' in the database, either remote or local
type Status struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- FetchedAt time.Time `validate:"required_with=!Local" bun:"type:timestamptz,nullzero"` // when was item (remote) last fetched.
- PinnedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // Status was pinned by owning account at this time.
- URI string `validate:"required,url" bun:",unique,nullzero,notnull"` // activitypub URI of this status
- URL string `validate:"url" bun:",nullzero"` // web url for viewing this status
- Content string `validate:"-" bun:""` // content of this status; likely html-formatted but not guaranteed
- AttachmentIDs []string `validate:"dive,ulid" bun:"attachments,array"` // Database IDs of any media attachments associated with this status
- Attachments []*MediaAttachment `validate:"-" bun:"attached_media,rel:has-many"` // Attachments corresponding to attachmentIDs
- TagIDs []string `validate:"dive,ulid" bun:"tags,array"` // Database IDs of any tags used in this status
- Tags []*Tag `validate:"-" bun:"attached_tags,m2m:status_to_tags"` // Tags corresponding to tagIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
- MentionIDs []string `validate:"dive,ulid" bun:"mentions,array"` // Database IDs of any mentions in this status
- Mentions []*Mention `validate:"-" bun:"attached_mentions,rel:has-many"` // Mentions corresponding to mentionIDs
- EmojiIDs []string `validate:"dive,ulid" bun:"emojis,array"` // Database IDs of any emojis used in this status
- Emojis []*Emoji `validate:"-" bun:"attached_emojis,m2m:status_to_emojis"` // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
- Local *bool `validate:"-" bun:",nullzero,notnull,default:false"` // is this status from a local account?
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // which account posted this status?
- Account *Account `validate:"-" bun:"rel:belongs-to"` // account corresponding to accountID
- AccountURI string `validate:"required,url" bun:",nullzero,notnull"` // activitypub uri of the owner of this status
- InReplyToID string `validate:"required_with=InReplyToURI InReplyToAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the status this status replies to
- InReplyToURI string `validate:"required_with=InReplyToID InReplyToAccountID,omitempty,url" bun:",nullzero"` // activitypub uri of the status this status is a reply to
- InReplyToAccountID string `validate:"required_with=InReplyToID InReplyToURI,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the account that this status replies to
- InReplyTo *Status `validate:"-" bun:"-"` // status corresponding to inReplyToID
- InReplyToAccount *Account `validate:"-" bun:"rel:belongs-to"` // account corresponding to inReplyToAccountID
- BoostOfID string `validate:"required_with=BoostOfAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the status this status is a boost of
- BoostOfAccountID string `validate:"required_with=BoostOfID,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the account that owns the boosted status
- BoostOf *Status `validate:"-" bun:"-"` // status that corresponds to boostOfID
- BoostOfAccount *Account `validate:"-" bun:"rel:belongs-to"` // account that corresponds to boostOfAccountID
- ContentWarning string `validate:"-" bun:",nullzero"` // cw string for this status
- Visibility Visibility `validate:"oneof=public unlocked followers_only mutuals_only direct" bun:",nullzero,notnull"` // visibility entry for this status
- Sensitive *bool `validate:"-" bun:",nullzero,notnull,default:false"` // mark the status as sensitive?
- Language string `validate:"-" bun:",nullzero"` // what language is this status written in?
- CreatedWithApplicationID string `validate:"required_if=Local true,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Which application was used to create this status?
- CreatedWithApplication *Application `validate:"-" bun:"rel:belongs-to"` // application corresponding to createdWithApplicationID
- ActivityStreamsType string `validate:"required" bun:",nullzero,notnull"` // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types. Will probably almost always be Note but who knows!.
- Text string `validate:"-" bun:""` // Original text of the status without formatting
- Federated *bool `validate:"-" bun:",notnull"` // This status will be federated beyond the local timeline(s)
- Boostable *bool `validate:"-" bun:",notnull"` // This status can be boosted/reblogged
- Replyable *bool `validate:"-" bun:",notnull"` // This status can be replied to
- Likeable *bool `validate:"-" bun:",notnull"` // This status can be liked/faved
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ FetchedAt time.Time `bun:"type:timestamptz,nullzero"` // when was item (remote) last fetched.
+ PinnedAt time.Time `bun:"type:timestamptz,nullzero"` // Status was pinned by owning account at this time.
+ URI string `bun:",unique,nullzero,notnull"` // activitypub URI of this status
+ URL string `bun:",nullzero"` // web url for viewing this status
+ Content string `bun:""` // content of this status; likely html-formatted but not guaranteed
+ AttachmentIDs []string `bun:"attachments,array"` // Database IDs of any media attachments associated with this status
+ Attachments []*MediaAttachment `bun:"attached_media,rel:has-many"` // Attachments corresponding to attachmentIDs
+ TagIDs []string `bun:"tags,array"` // Database IDs of any tags used in this status
+ Tags []*Tag `bun:"attached_tags,m2m:status_to_tags"` // Tags corresponding to tagIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
+ MentionIDs []string `bun:"mentions,array"` // Database IDs of any mentions in this status
+ Mentions []*Mention `bun:"attached_mentions,rel:has-many"` // Mentions corresponding to mentionIDs
+ EmojiIDs []string `bun:"emojis,array"` // Database IDs of any emojis used in this status
+ Emojis []*Emoji `bun:"attached_emojis,m2m:status_to_emojis"` // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
+ Local *bool `bun:",nullzero,notnull,default:false"` // is this status from a local account?
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull"` // which account posted this status?
+ Account *Account `bun:"rel:belongs-to"` // account corresponding to accountID
+ AccountURI string `bun:",nullzero,notnull"` // activitypub uri of the owner of this status
+ InReplyToID string `bun:"type:CHAR(26),nullzero"` // id of the status this status replies to
+ InReplyToURI string `bun:",nullzero"` // activitypub uri of the status this status is a reply to
+ InReplyToAccountID string `bun:"type:CHAR(26),nullzero"` // id of the account that this status replies to
+ InReplyTo *Status `bun:"-"` // status corresponding to inReplyToID
+ InReplyToAccount *Account `bun:"rel:belongs-to"` // account corresponding to inReplyToAccountID
+ BoostOfID string `bun:"type:CHAR(26),nullzero"` // id of the status this status is a boost of
+ BoostOfAccountID string `bun:"type:CHAR(26),nullzero"` // id of the account that owns the boosted status
+ BoostOf *Status `bun:"-"` // status that corresponds to boostOfID
+ BoostOfAccount *Account `bun:"rel:belongs-to"` // account that corresponds to boostOfAccountID
+ ContentWarning string `bun:",nullzero"` // cw string for this status
+ Visibility Visibility `bun:",nullzero,notnull"` // visibility entry for this status
+ Sensitive *bool `bun:",nullzero,notnull,default:false"` // mark the status as sensitive?
+ Language string `bun:",nullzero"` // what language is this status written in?
+ CreatedWithApplicationID string `bun:"type:CHAR(26),nullzero"` // Which application was used to create this status?
+ CreatedWithApplication *Application `bun:"rel:belongs-to"` // application corresponding to createdWithApplicationID
+ ActivityStreamsType string `bun:",nullzero,notnull"` // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types. Will probably almost always be Note but who knows!.
+ Text string `bun:""` // Original text of the status without formatting
+ Federated *bool `bun:",notnull"` // This status will be federated beyond the local timeline(s)
+ Boostable *bool `bun:",notnull"` // This status can be boosted/reblogged
+ Replyable *bool `bun:",notnull"` // This status can be replied to
+ Likeable *bool `bun:",notnull"` // This status can be liked/faved
}
// GetID implements timeline.Timelineable{}.
@@ -252,18 +252,18 @@ func (s *Status) MentionsAccount(id string) bool {
// StatusToTag is an intermediate struct to facilitate the many2many relationship between a status and one or more tags.
type StatusToTag struct {
- StatusID string `validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull"`
- Status *Status `validate:"-" bun:"rel:belongs-to"`
- TagID string `validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull"`
- Tag *Tag `validate:"-" bun:"rel:belongs-to"`
+ StatusID string `bun:"type:CHAR(26),unique:statustag,nullzero,notnull"`
+ Status *Status `bun:"rel:belongs-to"`
+ TagID string `bun:"type:CHAR(26),unique:statustag,nullzero,notnull"`
+ Tag *Tag `bun:"rel:belongs-to"`
}
// StatusToEmoji is an intermediate struct to facilitate the many2many relationship between a status and one or more emojis.
type StatusToEmoji struct {
- StatusID string `validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"`
- Status *Status `validate:"-" bun:"rel:belongs-to"`
- EmojiID string `validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"`
- Emoji *Emoji `validate:"-" bun:"rel:belongs-to"`
+ StatusID string `bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"`
+ Status *Status `bun:"rel:belongs-to"`
+ EmojiID string `bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"`
+ Emoji *Emoji `bun:"rel:belongs-to"`
}
// Visibility represents the visibility granularity of a status.
diff --git a/internal/gtsmodel/statusbookmark.go b/internal/gtsmodel/statusbookmark.go
index 6141b6e34..c7590a5c3 100644
--- a/internal/gtsmodel/statusbookmark.go
+++ b/internal/gtsmodel/statusbookmark.go
@@ -21,13 +21,13 @@ import "time"
// StatusBookmark refers to one account having a 'bookmark' of the status of another account.
type StatusBookmark struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id of the account that created ('did') the bookmark
- Account *Account `validate:"-" bun:"rel:belongs-to"` // account that created the bookmark
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the bookmarked status
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // account owning the bookmarked status
- StatusID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // database id of the status that has been bookmarked
- Status *Status `validate:"-" bun:"rel:belongs-to"` // the bookmarked status
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull"` // id of the account that created ('did') the bookmark
+ Account *Account `bun:"rel:belongs-to"` // account that created the bookmark
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the bookmarked status
+ TargetAccount *Account `bun:"rel:belongs-to"` // account owning the bookmarked status
+ StatusID string `bun:"type:CHAR(26),nullzero,notnull"` // database id of the status that has been bookmarked
+ Status *Status `bun:"rel:belongs-to"` // the bookmarked status
}
diff --git a/internal/gtsmodel/statusfave.go b/internal/gtsmodel/statusfave.go
index 86096ef5e..f81226f8b 100644
--- a/internal/gtsmodel/statusfave.go
+++ b/internal/gtsmodel/statusfave.go
@@ -21,14 +21,14 @@ import "time"
// StatusFave refers to a 'fave' or 'like' in the database, from one account, targeting the status of another account
type StatusFave struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),unique:statusfaveaccountstatus,nullzero,notnull"` // id of the account that created ('did') the fave
- Account *Account `validate:"-" bun:"-"` // account that created the fave
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the faved status
- TargetAccount *Account `validate:"-" bun:"-"` // account owning the faved status
- StatusID string `validate:"required,ulid" bun:"type:CHAR(26),unique:statusfaveaccountstatus,nullzero,notnull"` // database id of the status that has been 'faved'
- Status *Status `validate:"-" bun:"-"` // the faved status
- URI string `validate:"required,url" bun:",nullzero,notnull,unique"` // ActivityPub URI of this fave
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ AccountID string `bun:"type:CHAR(26),unique:statusfaveaccountstatus,nullzero,notnull"` // id of the account that created ('did') the fave
+ Account *Account `bun:"-"` // account that created the fave
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the faved status
+ TargetAccount *Account `bun:"-"` // account owning the faved status
+ StatusID string `bun:"type:CHAR(26),unique:statusfaveaccountstatus,nullzero,notnull"` // database id of the status that has been 'faved'
+ Status *Status `bun:"-"` // the faved status
+ URI string `bun:",nullzero,notnull,unique"` // ActivityPub URI of this fave
}
diff --git a/internal/gtsmodel/statusmute.go b/internal/gtsmodel/statusmute.go
index 27af921e4..b8aca1c7a 100644
--- a/internal/gtsmodel/statusmute.go
+++ b/internal/gtsmodel/statusmute.go
@@ -21,13 +21,13 @@ import "time"
// StatusMute refers to one account having muted the status of another account or its own.
type StatusMute struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id of the account that created ('did') the mute
- Account *Account `validate:"-" bun:"rel:belongs-to"` // pointer to the account specified by accountID
- TargetAccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the muted status (can be the same as accountID)
- TargetAccount *Account `validate:"-" bun:"rel:belongs-to"` // pointer to the account specified by targetAccountID
- StatusID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // database id of the status that has been muted
- Status *Status `validate:"-" bun:"rel:belongs-to"` // pointer to the muted status specified by statusID
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull"` // id of the account that created ('did') the mute
+ Account *Account `bun:"rel:belongs-to"` // pointer to the account specified by accountID
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // id the account owning the muted status (can be the same as accountID)
+ TargetAccount *Account `bun:"rel:belongs-to"` // pointer to the account specified by targetAccountID
+ StatusID string `bun:"type:CHAR(26),nullzero,notnull"` // database id of the status that has been muted
+ Status *Status `bun:"rel:belongs-to"` // pointer to the muted status specified by statusID
}
diff --git a/internal/gtsmodel/tag.go b/internal/gtsmodel/tag.go
index a43c4a5ec..514389f23 100644
--- a/internal/gtsmodel/tag.go
+++ b/internal/gtsmodel/tag.go
@@ -21,10 +21,10 @@ import "time"
// Tag represents a hashtag for gathering public statuses together.
type Tag struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Name string `validate:"required" bun:",unique,nullzero,notnull"` // (lowercase) name of the tag without the hash prefix
- Useable *bool `validate:"-" bun:",nullzero,notnull,default:true"` // Tag is useable on this instance.
- Listable *bool `validate:"-" bun:",nullzero,notnull,default:true"` // Tagged statuses can be listed on this instance.
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Name string `bun:",unique,nullzero,notnull"` // (lowercase) name of the tag without the hash prefix
+ Useable *bool `bun:",nullzero,notnull,default:true"` // Tag is useable on this instance.
+ Listable *bool `bun:",nullzero,notnull,default:true"` // Tagged statuses can be listed on this instance.
}
diff --git a/internal/gtsmodel/token.go b/internal/gtsmodel/token.go
index 06db7e394..fd640abde 100644
--- a/internal/gtsmodel/token.go
+++ b/internal/gtsmodel/token.go
@@ -21,22 +21,22 @@ import "time"
// Token is a translation of the gotosocial token with the ExpiresIn fields replaced with ExpiresAt.
type Token struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- ClientID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"` // ID of the client who owns this token
- UserID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero"` // ID of the user who owns this token
- RedirectURI string `validate:"required,uri" bun:",nullzero,notnull"` // Oauth redirect URI for this token
- Scope string `validate:"required" bun:",notnull"` // Oauth scope
- Code string `validate:"-" bun:",pk,nullzero,notnull,default:''"` // Code, if present
- CodeChallenge string `validate:"-" bun:",nullzero"` // Code challenge, if code present
- CodeChallengeMethod string `validate:"-" bun:",nullzero"` // Code challenge method, if code present
- CodeCreateAt time.Time `validate:"required_with=Code" bun:"type:timestamptz,nullzero"` // Code created time, if code present
- CodeExpiresAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // Code expires at -- null means the code never expires
- Access string `validate:"-" bun:",pk,nullzero,notnull,default:''"` // User level access token, if present
- AccessCreateAt time.Time `validate:"required_with=Access" bun:"type:timestamptz,nullzero"` // User level access token created time, if access present
- AccessExpiresAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // User level access token expires at -- null means the token never expires
- Refresh string `validate:"-" bun:",pk,nullzero,notnull,default:''"` // Refresh token, if present
- RefreshCreateAt time.Time `validate:"required_with=Refresh" bun:"type:timestamptz,nullzero"` // Refresh created at, if refresh present
- RefreshExpiresAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // Refresh expires at -- null means the refresh token never expires
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ ClientID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the client who owns this token
+ UserID string `bun:"type:CHAR(26),nullzero"` // ID of the user who owns this token
+ RedirectURI string `bun:",nullzero,notnull"` // Oauth redirect URI for this token
+ Scope string `bun:",notnull"` // Oauth scope
+ Code string `bun:",pk,nullzero,notnull,default:''"` // Code, if present
+ CodeChallenge string `bun:",nullzero"` // Code challenge, if code present
+ CodeChallengeMethod string `bun:",nullzero"` // Code challenge method, if code present
+ CodeCreateAt time.Time `bun:"type:timestamptz,nullzero"` // Code created time, if code present
+ CodeExpiresAt time.Time `bun:"type:timestamptz,nullzero"` // Code expires at -- null means the code never expires
+ Access string `bun:",pk,nullzero,notnull,default:''"` // User level access token, if present
+ AccessCreateAt time.Time `bun:"type:timestamptz,nullzero"` // User level access token created time, if access present
+ AccessExpiresAt time.Time `bun:"type:timestamptz,nullzero"` // User level access token expires at -- null means the token never expires
+ Refresh string `bun:",pk,nullzero,notnull,default:''"` // Refresh token, if present
+ RefreshCreateAt time.Time `bun:"type:timestamptz,nullzero"` // Refresh created at, if refresh present
+ RefreshExpiresAt time.Time `bun:"type:timestamptz,nullzero"` // Refresh expires at -- null means the refresh token never expires
}
diff --git a/internal/gtsmodel/tombstone.go b/internal/gtsmodel/tombstone.go
index f7e1c2504..7c6af6de3 100644
--- a/internal/gtsmodel/tombstone.go
+++ b/internal/gtsmodel/tombstone.go
@@ -29,9 +29,9 @@ import (
// It's useful in cases where a remote account has been deleted, and we don't want to keep trying to process
// subsequent activities from that account, or deletes which target it.
type Tombstone struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Domain string `validate:"omitempty,fqdn" bun:",nullzero,notnull"` // Domain of the Object/Actor.
- URI string `validate:"required,url" bun:",nullzero,notnull,unique"` // ActivityPub URI for this Object/Actor.
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Domain string `bun:",nullzero,notnull"` // Domain of the Object/Actor.
+ URI string `bun:",nullzero,notnull,unique"` // ActivityPub URI for this Object/Actor.
}
diff --git a/internal/gtsmodel/user.go b/internal/gtsmodel/user.go
index 2f2029636..16c4d4ee2 100644
--- a/internal/gtsmodel/user.go
+++ b/internal/gtsmodel/user.go
@@ -25,35 +25,35 @@ import (
// User represents an actual human user of gotosocial. Note, this is a LOCAL gotosocial user, not a remote account.
// To cross reference this local user with their account (which can be local or remote), use the AccountID field.
type User struct {
- ID string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
- CreatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
- UpdatedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
- Email string `validate:"required_with=ConfirmedAt" bun:",nullzero,unique"` // confirmed email address for this user, this should be unique -- only one email address registered per instance, multiple users per email are not supported
- AccountID string `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull,unique"` // The id of the local gtsmodel.Account entry for this user.
- Account *Account `validate:"-" bun:"rel:belongs-to"` // Pointer to the account of this user that corresponds to AccountID.
- EncryptedPassword string `validate:"required" bun:",nullzero,notnull"` // The encrypted password of this user, generated using https://pkg.go.dev/golang.org/x/crypto/bcrypt#GenerateFromPassword. A salt is included so we're safe against 🌈 tables.
- SignUpIP net.IP `validate:"-" bun:",nullzero"` // From what IP was this user created?
- CurrentSignInAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When did the user sign in with their current session.
- CurrentSignInIP net.IP `validate:"-" bun:",nullzero"` // What's the most recent IP of this user
- LastSignInAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When did this user last sign in?
- LastSignInIP net.IP `validate:"-" bun:",nullzero"` // What's the previous IP of this user?
- SignInCount int `validate:"min=0" bun:",notnull,default:0"` // How many times has this user signed in?
- InviteID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the user who invited this user (who let this joker in?)
- ChosenLanguages []string `validate:"-" bun:",nullzero"` // What languages does this user want to see?
- FilteredLanguages []string `validate:"-" bun:",nullzero"` // What languages does this user not want to see?
- Locale string `validate:"-" bun:",nullzero"` // In what timezone/locale is this user located?
- CreatedByApplicationID string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Which application id created this user? See gtsmodel.Application
- CreatedByApplication *Application `validate:"-" bun:"rel:belongs-to"` // Pointer to the application corresponding to createdbyapplicationID.
- LastEmailedAt time.Time `validate:"-" bun:"type:timestamptz,nullzero"` // When was this user last contacted by email.
- ConfirmationToken string `validate:"required_with=ConfirmationSentAt" bun:",nullzero"` // What confirmation token did we send this user/what are we expecting back?
- ConfirmationSentAt time.Time `validate:"required_with=ConfirmationToken" bun:"type:timestamptz,nullzero"` // When did we send email confirmation to this user?
- ConfirmedAt time.Time `validate:"required_with=Email" bun:"type:timestamptz,nullzero"` // When did the user confirm their email address
- UnconfirmedEmail string `validate:"required_without=Email" bun:",nullzero"` // Email address that hasn't yet been confirmed
- Moderator *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this user a moderator?
- Admin *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this user an admin?
- Disabled *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Is this user disabled from posting?
- Approved *bool `validate:"-" bun:",nullzero,notnull,default:false"` // Has this user been approved by a moderator?
- ResetPasswordToken string `validate:"required_with=ResetPasswordSentAt" bun:",nullzero"` // The generated token that the user can use to reset their password
- ResetPasswordSentAt time.Time `validate:"required_with=ResetPasswordToken" bun:"type:timestamptz,nullzero"` // When did we email the user their reset-password email?
- ExternalID string `validate:"-" bun:",nullzero,unique"` // If the login for the user is managed externally (e.g OIDC), we need to keep a stable reference to the external object (e.g OIDC sub claim)
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item created
+ UpdatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"` // when was item last updated
+ Email string `bun:",nullzero,unique"` // confirmed email address for this user, this should be unique -- only one email address registered per instance, multiple users per email are not supported
+ AccountID string `bun:"type:CHAR(26),nullzero,notnull,unique"` // The id of the local gtsmodel.Account entry for this user.
+ Account *Account `bun:"rel:belongs-to"` // Pointer to the account of this user that corresponds to AccountID.
+ EncryptedPassword string `bun:",nullzero,notnull"` // The encrypted password of this user, generated using https://pkg.go.dev/golang.org/x/crypto/bcrypt#GenerateFromPassword. A salt is included so we're safe against 🌈 tables.
+ SignUpIP net.IP `bun:",nullzero"` // From what IP was this user created?
+ CurrentSignInAt time.Time `bun:"type:timestamptz,nullzero"` // When did the user sign in with their current session.
+ CurrentSignInIP net.IP `bun:",nullzero"` // What's the most recent IP of this user
+ LastSignInAt time.Time `bun:"type:timestamptz,nullzero"` // When did this user last sign in?
+ LastSignInIP net.IP `bun:",nullzero"` // What's the previous IP of this user?
+ SignInCount int `bun:",notnull,default:0"` // How many times has this user signed in?
+ InviteID string `bun:"type:CHAR(26),nullzero"` // id of the user who invited this user (who let this joker in?)
+ ChosenLanguages []string `bun:",nullzero"` // What languages does this user want to see?
+ FilteredLanguages []string `bun:",nullzero"` // What languages does this user not want to see?
+ Locale string `bun:",nullzero"` // In what timezone/locale is this user located?
+ CreatedByApplicationID string `bun:"type:CHAR(26),nullzero"` // Which application id created this user? See gtsmodel.Application
+ CreatedByApplication *Application `bun:"rel:belongs-to"` // Pointer to the application corresponding to createdbyapplicationID.
+ LastEmailedAt time.Time `bun:"type:timestamptz,nullzero"` // When was this user last contacted by email.
+ ConfirmationToken string `bun:",nullzero"` // What confirmation token did we send this user/what are we expecting back?
+ ConfirmationSentAt time.Time `bun:"type:timestamptz,nullzero"` // When did we send email confirmation to this user?
+ ConfirmedAt time.Time `bun:"type:timestamptz,nullzero"` // When did the user confirm their email address
+ UnconfirmedEmail string `bun:",nullzero"` // Email address that hasn't yet been confirmed
+ Moderator *bool `bun:",nullzero,notnull,default:false"` // Is this user a moderator?
+ Admin *bool `bun:",nullzero,notnull,default:false"` // Is this user an admin?
+ Disabled *bool `bun:",nullzero,notnull,default:false"` // Is this user disabled from posting?
+ Approved *bool `bun:",nullzero,notnull,default:false"` // Has this user been approved by a moderator?
+ ResetPasswordToken string `bun:",nullzero"` // The generated token that the user can use to reset their password
+ ResetPasswordSentAt time.Time `bun:"type:timestamptz,nullzero"` // When did we email the user their reset-password email?
+ ExternalID string `bun:",nullzero,unique"` // If the login for the user is managed externally (e.g OIDC), we need to keep a stable reference to the external object (e.g OIDC sub claim)
}
diff --git a/internal/validate/account_test.go b/internal/validate/account_test.go
deleted file mode 100644
index 57f0f4900..000000000
--- a/internal/validate/account_test.go
+++ /dev/null
@@ -1,343 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "crypto/rand"
- "crypto/rsa"
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/ap"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyAccount() *gtsmodel.Account {
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- panic(err)
- }
- pub := &priv.PublicKey
-
- return &gtsmodel.Account{
- ID: "01F8MH1H7YV1Z7D2C8K2730QBF",
- CreatedAt: time.Now().Add(-48 * time.Hour),
- UpdatedAt: time.Now().Add(-48 * time.Hour),
- Username: "the_mighty_zork",
- Domain: "",
- AvatarMediaAttachmentID: "01F8MH58A357CV5K7R7TJMSH6S",
- AvatarMediaAttachment: nil,
- AvatarRemoteURL: "",
- HeaderMediaAttachmentID: "01PFPMWK2FF0D9WMHEJHR07C3Q",
- HeaderMediaAttachment: nil,
- HeaderRemoteURL: "",
- DisplayName: "original zork (he/they)",
- Fields: []*gtsmodel.Field{},
- Note: "hey yo this is my profile!",
- Memorial: testrig.FalseBool(),
- AlsoKnownAs: "",
- MovedToAccountID: "",
- Bot: testrig.FalseBool(),
- Reason: "I wanna be on this damned webbed site so bad! Please! Wow",
- Locked: testrig.FalseBool(),
- Discoverable: testrig.TrueBool(),
- Privacy: gtsmodel.VisibilityPublic,
- Sensitive: testrig.FalseBool(),
- Language: "en",
- StatusContentType: "text/plain",
- URI: "http://localhost:8080/users/the_mighty_zork",
- URL: "http://localhost:8080/@the_mighty_zork",
- FetchedAt: time.Time{},
- InboxURI: "http://localhost:8080/users/the_mighty_zork/inbox",
- OutboxURI: "http://localhost:8080/users/the_mighty_zork/outbox",
- FollowersURI: "http://localhost:8080/users/the_mighty_zork/followers",
- FollowingURI: "http://localhost:8080/users/the_mighty_zork/following",
- FeaturedCollectionURI: "http://localhost:8080/users/the_mighty_zork/collections/featured",
- ActorType: ap.ActorPerson,
- PrivateKey: priv,
- PublicKey: pub,
- PublicKeyURI: "http://localhost:8080/users/the_mighty_zork#main-key",
- SensitizedAt: time.Time{},
- SilencedAt: time.Time{},
- SuspendedAt: time.Time{},
- HideCollections: testrig.FalseBool(),
- SuspensionOrigin: "",
- }
-}
-
-type AccountValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *AccountValidateTestSuite) TestValidateAccountHappyPath() {
- // no problem here
- a := happyAccount()
- err := validate.Struct(*a)
- suite.NoError(err)
-}
-
-// ID must be set and be valid ULID
-func (suite *AccountValidateTestSuite) TestValidateAccountBadID() {
- a := happyAccount()
-
- a.ID = ""
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- a.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-// CreatedAt can be set or not -- it will be set in the database anyway
-func (suite *AccountValidateTestSuite) TestValidateAccountNoCreatedAt() {
- a := happyAccount()
-
- a.CreatedAt = time.Time{}
- err := validate.Struct(*a)
- suite.NoError(err)
-}
-
-// FetchedAt must be defined if remote account
-func (suite *AccountValidateTestSuite) TestValidateAccountNoWebfingeredAt() {
- a := happyAccount()
-
- a.Domain = "example.org"
- a.FetchedAt = time.Time{}
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.FetchedAt' Error:Field validation for 'FetchedAt' failed on the 'required_with' tag")
-}
-
-// Username must be set
-func (suite *AccountValidateTestSuite) TestValidateAccountUsername() {
- a := happyAccount()
-
- a.Username = ""
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Username' Error:Field validation for 'Username' failed on the 'required' tag")
-}
-
-// Domain must be either empty (for local accounts) or proper fqdn (for remote accounts)
-func (suite *AccountValidateTestSuite) TestValidateAccountDomain() {
- a := happyAccount()
- a.FetchedAt = time.Now()
-
- a.Domain = ""
- err := validate.Struct(*a)
- suite.NoError(err)
-
- a.Domain = "localhost:8080"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-
- a.Domain = "ahhhhh"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-
- a.Domain = "https://www.example.org"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-
- a.Domain = "example.org:8080"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-
- a.Domain = "example.org"
- err = validate.Struct(*a)
- suite.NoError(err)
-}
-
-// Attachment IDs must either be not set, or must be valid ULID
-func (suite *AccountValidateTestSuite) TestValidateAttachmentIDs() {
- a := happyAccount()
-
- a.AvatarMediaAttachmentID = ""
- a.HeaderMediaAttachmentID = ""
- err := validate.Struct(*a)
- suite.NoError(err)
-
- a.AvatarMediaAttachmentID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- a.HeaderMediaAttachmentID = "aaaa"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.AvatarMediaAttachmentID' Error:Field validation for 'AvatarMediaAttachmentID' failed on the 'ulid' tag\nKey: 'Account.HeaderMediaAttachmentID' Error:Field validation for 'HeaderMediaAttachmentID' failed on the 'ulid' tag")
-}
-
-// Attachment remote URLs must either not be set, or be valid URLs
-func (suite *AccountValidateTestSuite) TestValidateAttachmentRemoteURLs() {
- a := happyAccount()
-
- a.AvatarRemoteURL = ""
- a.HeaderRemoteURL = ""
- err := validate.Struct(*a)
- suite.NoError(err)
-
- a.AvatarRemoteURL = "-------------"
- a.HeaderRemoteURL = "https://valid-url.com"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.AvatarRemoteURL' Error:Field validation for 'AvatarRemoteURL' failed on the 'url' tag")
-
- a.AvatarRemoteURL = "https://valid-url.com"
- a.HeaderRemoteURL = ""
- err = validate.Struct(*a)
- suite.NoError(err)
-}
-
-// Default privacy must be set if account is local
-func (suite *AccountValidateTestSuite) TestValidatePrivacy() {
- a := happyAccount()
- a.FetchedAt = time.Now()
-
- a.Privacy = ""
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Privacy' Error:Field validation for 'Privacy' failed on the 'required_without' tag")
-
- a.Privacy = "not valid"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Privacy' Error:Field validation for 'Privacy' failed on the 'oneof' tag")
-
- a.Privacy = gtsmodel.VisibilityFollowersOnly
- err = validate.Struct(*a)
- suite.NoError(err)
-
- a.Privacy = ""
- a.Domain = "example.org"
- err = validate.Struct(*a)
- suite.NoError(err)
-
- a.Privacy = "invalid"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Privacy' Error:Field validation for 'Privacy' failed on the 'oneof' tag")
-}
-
-// If set, language must be a valid language
-func (suite *AccountValidateTestSuite) TestValidateLanguage() {
- a := happyAccount()
-
- a.Language = ""
- err := validate.Struct(*a)
- suite.NoError(err)
-
- a.Language = "not valid"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.Language' Error:Field validation for 'Language' failed on the 'bcp47_language_tag' tag")
-
- a.Language = "en-uk"
- err = validate.Struct(*a)
- suite.NoError(err)
-}
-
-// Account URI must be set and must be valid
-func (suite *AccountValidateTestSuite) TestValidateAccountURI() {
- a := happyAccount()
-
- a.URI = "invalid-uri"
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-
- a.URI = ""
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-}
-
-// ActivityPub URIs must be set on account if it's local
-func (suite *AccountValidateTestSuite) TestValidateAccountURIs() {
- a := happyAccount()
- a.FetchedAt = time.Now()
-
- a.InboxURI = "invalid-uri"
- a.OutboxURI = "invalid-uri"
- a.FollowersURI = "invalid-uri"
- a.FollowingURI = "invalid-uri"
- a.FeaturedCollectionURI = "invalid-uri"
- a.PublicKeyURI = "invalid-uri"
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.InboxURI' Error:Field validation for 'InboxURI' failed on the 'url' tag\nKey: 'Account.OutboxURI' Error:Field validation for 'OutboxURI' failed on the 'url' tag\nKey: 'Account.FollowingURI' Error:Field validation for 'FollowingURI' failed on the 'url' tag\nKey: 'Account.FollowersURI' Error:Field validation for 'FollowersURI' failed on the 'url' tag\nKey: 'Account.FeaturedCollectionURI' Error:Field validation for 'FeaturedCollectionURI' failed on the 'url' tag\nKey: 'Account.PublicKeyURI' Error:Field validation for 'PublicKeyURI' failed on the 'url' tag")
-
- a.InboxURI = ""
- a.OutboxURI = ""
- a.FollowersURI = ""
- a.FollowingURI = ""
- a.FeaturedCollectionURI = ""
- a.PublicKeyURI = ""
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.InboxURI' Error:Field validation for 'InboxURI' failed on the 'required_without' tag\nKey: 'Account.OutboxURI' Error:Field validation for 'OutboxURI' failed on the 'required_without' tag\nKey: 'Account.FollowingURI' Error:Field validation for 'FollowingURI' failed on the 'required_without' tag\nKey: 'Account.FollowersURI' Error:Field validation for 'FollowersURI' failed on the 'required_without' tag\nKey: 'Account.FeaturedCollectionURI' Error:Field validation for 'FeaturedCollectionURI' failed on the 'required_without' tag\nKey: 'Account.PublicKeyURI' Error:Field validation for 'PublicKeyURI' failed on the 'required' tag")
-
- a.Domain = "example.org"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.PublicKeyURI' Error:Field validation for 'PublicKeyURI' failed on the 'required' tag")
-
- a.InboxURI = "invalid-uri"
- a.OutboxURI = "invalid-uri"
- a.FollowersURI = "invalid-uri"
- a.FollowingURI = "invalid-uri"
- a.FeaturedCollectionURI = "invalid-uri"
- a.PublicKeyURI = "invalid-uri"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.InboxURI' Error:Field validation for 'InboxURI' failed on the 'url' tag\nKey: 'Account.OutboxURI' Error:Field validation for 'OutboxURI' failed on the 'url' tag\nKey: 'Account.FollowingURI' Error:Field validation for 'FollowingURI' failed on the 'url' tag\nKey: 'Account.FollowersURI' Error:Field validation for 'FollowersURI' failed on the 'url' tag\nKey: 'Account.FeaturedCollectionURI' Error:Field validation for 'FeaturedCollectionURI' failed on the 'url' tag\nKey: 'Account.PublicKeyURI' Error:Field validation for 'PublicKeyURI' failed on the 'url' tag")
-}
-
-// Actor type must be set and valid
-func (suite *AccountValidateTestSuite) TestValidateActorType() {
- a := happyAccount()
-
- a.ActorType = ""
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.ActorType' Error:Field validation for 'ActorType' failed on the 'oneof' tag")
-
- a.ActorType = "not valid"
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.ActorType' Error:Field validation for 'ActorType' failed on the 'oneof' tag")
-
- a.ActorType = ap.ActivityArrive
- err = validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.ActorType' Error:Field validation for 'ActorType' failed on the 'oneof' tag")
-
- a.ActorType = ap.ActorOrganization
- err = validate.Struct(*a)
- suite.NoError(err)
-}
-
-// Private key must be set on local accounts
-func (suite *AccountValidateTestSuite) TestValidatePrivateKey() {
- a := happyAccount()
- a.FetchedAt = time.Now()
-
- a.PrivateKey = nil
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.PrivateKey' Error:Field validation for 'PrivateKey' failed on the 'required_without' tag")
-
- a.Domain = "example.org"
- err = validate.Struct(*a)
- suite.NoError(err)
-}
-
-// Public key must be set
-func (suite *AccountValidateTestSuite) TestValidatePublicKey() {
- a := happyAccount()
-
- a.PublicKey = nil
- err := validate.Struct(*a)
- suite.EqualError(err, "Key: 'Account.PublicKey' Error:Field validation for 'PublicKey' failed on the 'required' tag")
-}
-
-func TestAccountValidateTestSuite(t *testing.T) {
- suite.Run(t, new(AccountValidateTestSuite))
-}
diff --git a/internal/validate/application_test.go b/internal/validate/application_test.go
deleted file mode 100644
index 86c53a615..000000000
--- a/internal/validate/application_test.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyApplication() *gtsmodel.Application {
- return &gtsmodel.Application{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- Name: "Tusky",
- Website: "https://tusky.app",
- RedirectURI: "oauth2redirect://com.keylesspalace.tusky/",
- ClientID: "01FEEDMF6C0QD589MRK7919Z0R",
- ClientSecret: "bd740cf1-024a-4e4d-8c39-866538f52fe6",
- Scopes: "read write follow",
- }
-}
-
-type ApplicationValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationHappyPath() {
- // no problem here
- a := happyApplication()
- err := validate.Struct(a)
- suite.NoError(err)
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationBadID() {
- a := happyApplication()
-
- a.ID = ""
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- a.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationNoCreatedAt() {
- a := happyApplication()
-
- a.CreatedAt = time.Time{}
- err := validate.Struct(a)
- suite.NoError(err)
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationName() {
- a := happyApplication()
-
- a.Name = ""
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.Name' Error:Field validation for 'Name' failed on the 'required' tag")
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationWebsite() {
- a := happyApplication()
-
- a.Website = "invalid-website"
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.Website' Error:Field validation for 'Website' failed on the 'url' tag")
-
- a.Website = ""
- err = validate.Struct(a)
- suite.NoError(err)
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationRedirectURI() {
- a := happyApplication()
-
- a.RedirectURI = "invalid-uri"
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.RedirectURI' Error:Field validation for 'RedirectURI' failed on the 'uri' tag")
-
- a.RedirectURI = ""
- err = validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.RedirectURI' Error:Field validation for 'RedirectURI' failed on the 'required' tag")
-
- a.RedirectURI = "urn:ietf:wg:oauth:2.0:oob"
- err = validate.Struct(a)
- suite.NoError(err)
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationClientSecret() {
- a := happyApplication()
-
- a.ClientSecret = "invalid-uuid"
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.ClientSecret' Error:Field validation for 'ClientSecret' failed on the 'uuid' tag")
-
- a.ClientSecret = ""
- err = validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.ClientSecret' Error:Field validation for 'ClientSecret' failed on the 'required' tag")
-}
-
-func (suite *ApplicationValidateTestSuite) TestValidateApplicationScopes() {
- a := happyApplication()
-
- a.Scopes = ""
- err := validate.Struct(a)
- suite.EqualError(err, "Key: 'Application.Scopes' Error:Field validation for 'Scopes' failed on the 'required' tag")
-}
-
-func TestApplicationValidateTestSuite(t *testing.T) {
- suite.Run(t, new(ApplicationValidateTestSuite))
-}
diff --git a/internal/validate/block_test.go b/internal/validate/block_test.go
deleted file mode 100644
index 96e206140..000000000
--- a/internal/validate/block_test.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyBlock() *gtsmodel.Block {
- return &gtsmodel.Block{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- URI: "https://example.org/accounts/someone/blocks/01FE91RJR88PSEEE30EV35QR8N",
- AccountID: "01FEED79PRMVWPRMFHFQM8MJQN",
- Account: nil,
- TargetAccountID: "01FEEDMF6C0QD589MRK7919Z0R",
- TargetAccount: nil,
- }
-}
-
-type BlockValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockHappyPath() {
- // no problem here
- b := happyBlock()
- err := validate.Struct(b)
- suite.NoError(err)
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockBadID() {
- b := happyBlock()
-
- b.ID = ""
- err := validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- b.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockNoCreatedAt() {
- b := happyBlock()
-
- b.CreatedAt = time.Time{}
- err := validate.Struct(b)
- suite.NoError(err)
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockCreatedByAccountID() {
- b := happyBlock()
-
- b.AccountID = ""
- err := validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.AccountID' Error:Field validation for 'AccountID' failed on the 'required' tag")
-
- b.AccountID = "this-is-not-a-valid-ulid"
- err = validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.AccountID' Error:Field validation for 'AccountID' failed on the 'ulid' tag")
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockTargetAccountID() {
- b := happyBlock()
-
- b.TargetAccountID = "invalid-ulid"
- err := validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.TargetAccountID' Error:Field validation for 'TargetAccountID' failed on the 'ulid' tag")
-
- b.TargetAccountID = "01FEEDHX4G7EGHF5GD9E82Y51Q"
- err = validate.Struct(b)
- suite.NoError(err)
-
- b.TargetAccountID = ""
- err = validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.TargetAccountID' Error:Field validation for 'TargetAccountID' failed on the 'required' tag")
-}
-
-func (suite *BlockValidateTestSuite) TestValidateBlockURI() {
- b := happyBlock()
-
- b.URI = "invalid-uri"
- err := validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-
- b.URI = ""
- err = validate.Struct(b)
- suite.EqualError(err, "Key: 'Block.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-}
-
-func TestBlockValidateTestSuite(t *testing.T) {
- suite.Run(t, new(BlockValidateTestSuite))
-}
diff --git a/internal/validate/client_test.go b/internal/validate/client_test.go
deleted file mode 100644
index ee8f0e66e..000000000
--- a/internal/validate/client_test.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyClient() *gtsmodel.Client {
- return &gtsmodel.Client{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- Secret: "bd740cf1-024a-4e4d-8c39-866538f52fe6",
- Domain: "oauth2redirect://com.keylesspalace.tusky/",
- UserID: "01FEEDMF6C0QD589MRK7919Z0R",
- }
-}
-
-type ClientValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *ClientValidateTestSuite) TestValidateClientHappyPath() {
- // no problem here
- c := happyClient()
- err := validate.Struct(c)
- suite.NoError(err)
-}
-
-func (suite *ClientValidateTestSuite) TestValidateClientBadID() {
- c := happyClient()
-
- c.ID = ""
- err := validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- c.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *ClientValidateTestSuite) TestValidateClientNoCreatedAt() {
- c := happyClient()
-
- c.CreatedAt = time.Time{}
- err := validate.Struct(c)
- suite.NoError(err)
-}
-
-func (suite *ClientValidateTestSuite) TestValidateClientDomain() {
- c := happyClient()
-
- c.Domain = "invalid-uri"
- err := validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.Domain' Error:Field validation for 'Domain' failed on the 'uri' tag")
-
- c.Domain = ""
- err = validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.Domain' Error:Field validation for 'Domain' failed on the 'required' tag")
-
- c.Domain = "urn:ietf:wg:oauth:2.0:oob"
- err = validate.Struct(c)
- suite.NoError(err)
-}
-
-func (suite *ClientValidateTestSuite) TestValidateSecret() {
- c := happyClient()
-
- c.Secret = "invalid-uuid"
- err := validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.Secret' Error:Field validation for 'Secret' failed on the 'uuid' tag")
-
- c.Secret = ""
- err = validate.Struct(c)
- suite.EqualError(err, "Key: 'Client.Secret' Error:Field validation for 'Secret' failed on the 'required' tag")
-}
-
-func TestClientValidateTestSuite(t *testing.T) {
- suite.Run(t, new(ClientValidateTestSuite))
-}
diff --git a/internal/validate/domainblock_test.go b/internal/validate/domainblock_test.go
deleted file mode 100644
index f6504d1f3..000000000
--- a/internal/validate/domainblock_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyDomainBlock() *gtsmodel.DomainBlock {
- return &gtsmodel.DomainBlock{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- Domain: "baddudes.suck",
- CreatedByAccountID: "01FEED79PRMVWPRMFHFQM8MJQN",
- PrivateComment: "we don't like em",
- PublicComment: "poo poo dudes",
- Obfuscate: testrig.FalseBool(),
- SubscriptionID: "",
- }
-}
-
-type DomainBlockValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockHappyPath() {
- // no problem here
- d := happyDomainBlock()
- err := validate.Struct(d)
- suite.NoError(err)
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockBadID() {
- d := happyDomainBlock()
-
- d.ID = ""
- err := validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- d.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockNoCreatedAt() {
- d := happyDomainBlock()
-
- d.CreatedAt = time.Time{}
- err := validate.Struct(d)
- suite.NoError(err)
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockBadDomain() {
- d := happyDomainBlock()
-
- d.Domain = ""
- err := validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.Domain' Error:Field validation for 'Domain' failed on the 'required' tag")
-
- d.Domain = "this-is-not-a-valid-domain"
- err = validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockCreatedByAccountID() {
- d := happyDomainBlock()
-
- d.CreatedByAccountID = ""
- err := validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.CreatedByAccountID' Error:Field validation for 'CreatedByAccountID' failed on the 'required' tag")
-
- d.CreatedByAccountID = "this-is-not-a-valid-ulid"
- err = validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.CreatedByAccountID' Error:Field validation for 'CreatedByAccountID' failed on the 'ulid' tag")
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainBlockComments() {
- d := happyDomainBlock()
-
- d.PrivateComment = ""
- d.PublicComment = ""
- err := validate.Struct(d)
- suite.NoError(err)
-}
-
-func (suite *DomainBlockValidateTestSuite) TestValidateDomainSubscriptionID() {
- d := happyDomainBlock()
-
- d.SubscriptionID = "invalid-ulid"
- err := validate.Struct(d)
- suite.EqualError(err, "Key: 'DomainBlock.SubscriptionID' Error:Field validation for 'SubscriptionID' failed on the 'ulid' tag")
-
- d.SubscriptionID = "01FEEDHX4G7EGHF5GD9E82Y51Q"
- err = validate.Struct(d)
- suite.NoError(err)
-}
-
-func TestDomainBlockValidateTestSuite(t *testing.T) {
- suite.Run(t, new(DomainBlockValidateTestSuite))
-}
diff --git a/internal/validate/emaildomainblock_test.go b/internal/validate/emaildomainblock_test.go
deleted file mode 100644
index 2aac0d72c..000000000
--- a/internal/validate/emaildomainblock_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyEmailDomainBlock() *gtsmodel.EmailDomainBlock {
- return &gtsmodel.EmailDomainBlock{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- Domain: "baddudes.suck",
- CreatedByAccountID: "01FEED79PRMVWPRMFHFQM8MJQN",
- }
-}
-
-type EmailDomainBlockValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *EmailDomainBlockValidateTestSuite) TestValidateEmailDomainBlockHappyPath() {
- // no problem here
- e := happyEmailDomainBlock()
- err := validate.Struct(e)
- suite.NoError(err)
-}
-
-func (suite *EmailDomainBlockValidateTestSuite) TestValidateEmailDomainBlockBadID() {
- e := happyEmailDomainBlock()
-
- e.ID = ""
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- e.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *EmailDomainBlockValidateTestSuite) TestValidateEmailDomainBlockNoCreatedAt() {
- e := happyEmailDomainBlock()
-
- e.CreatedAt = time.Time{}
- err := validate.Struct(e)
- suite.NoError(err)
-}
-
-func (suite *EmailDomainBlockValidateTestSuite) TestValidateEmailDomainBlockBadDomain() {
- e := happyEmailDomainBlock()
-
- e.Domain = ""
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.Domain' Error:Field validation for 'Domain' failed on the 'required' tag")
-
- e.Domain = "this-is-not-a-valid-domain"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-}
-
-func (suite *EmailDomainBlockValidateTestSuite) TestValidateEmailDomainBlockCreatedByAccountID() {
- e := happyEmailDomainBlock()
-
- e.CreatedByAccountID = ""
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.CreatedByAccountID' Error:Field validation for 'CreatedByAccountID' failed on the 'required' tag")
-
- e.CreatedByAccountID = "this-is-not-a-valid-ulid"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'EmailDomainBlock.CreatedByAccountID' Error:Field validation for 'CreatedByAccountID' failed on the 'ulid' tag")
-}
-
-func TestEmailDomainBlockValidateTestSuite(t *testing.T) {
- suite.Run(t, new(EmailDomainBlockValidateTestSuite))
-}
diff --git a/internal/validate/emoji_test.go b/internal/validate/emoji_test.go
deleted file mode 100644
index 9192cb1fc..000000000
--- a/internal/validate/emoji_test.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyEmoji() *gtsmodel.Emoji {
- // the file validator actually runs os.Stat on given paths, so we need to just create small
- // temp files for both the main attachment file and the thumbnail
-
- imageFile, err := os.CreateTemp("", "gts_test_emoji")
- if err != nil {
- panic(err)
- }
- if _, err := imageFile.WriteString("main"); err != nil {
- panic(err)
- }
- imagePath := imageFile.Name()
- if err := imageFile.Close(); err != nil {
- panic(err)
- }
-
- staticFile, err := os.CreateTemp("", "gts_test_emoji_static")
- if err != nil {
- panic(err)
- }
- if _, err := staticFile.WriteString("thumbnail"); err != nil {
- panic(err)
- }
- imageStaticPath := staticFile.Name()
- if err := staticFile.Close(); err != nil {
- panic(err)
- }
-
- return &gtsmodel.Emoji{
- ID: "01F8MH6NEM8D7527KZAECTCR76",
- CreatedAt: time.Now().Add(-71 * time.Hour),
- UpdatedAt: time.Now().Add(-71 * time.Hour),
- Shortcode: "blob_test",
- Domain: "example.org",
- ImageRemoteURL: "https://example.org/emojis/blob_test.gif",
- ImageStaticRemoteURL: "https://example.org/emojis/blob_test.png",
- ImageURL: "",
- ImageStaticURL: "",
- ImagePath: imagePath,
- ImageStaticPath: imageStaticPath,
- ImageContentType: "image/gif",
- ImageStaticContentType: "image/png",
- ImageFileSize: 1024,
- ImageStaticFileSize: 256,
- ImageUpdatedAt: time.Now(),
- Disabled: testrig.FalseBool(),
- URI: "https://example.org/emojis/blob_test",
- VisibleInPicker: testrig.TrueBool(),
- CategoryID: "01FEE47ZH70PWDSEAVBRFNX325",
- }
-}
-
-type EmojiValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateEmojiHappyPath() {
- // no problem here
- m := happyEmoji()
- err := validate.Struct(*m)
- suite.NoError(err)
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateEmojiBadFilePaths() {
- e := happyEmoji()
-
- e.ImagePath = "/tmp/nonexistent/file/for/gotosocial/test"
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'file' tag")
-
- e.ImagePath = ""
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'required' tag")
-
- e.ImagePath = "???????????thisnot a valid path####"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'file' tag")
-
- e.ImageStaticPath = "/tmp/nonexistent/file/for/gotosocial/test"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'file' tag\nKey: 'Emoji.ImageStaticPath' Error:Field validation for 'ImageStaticPath' failed on the 'file' tag")
-
- e.ImageStaticPath = ""
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'file' tag\nKey: 'Emoji.ImageStaticPath' Error:Field validation for 'ImageStaticPath' failed on the 'required' tag")
-
- e.ImageStaticPath = "???????????thisnot a valid path####"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImagePath' Error:Field validation for 'ImagePath' failed on the 'file' tag\nKey: 'Emoji.ImageStaticPath' Error:Field validation for 'ImageStaticPath' failed on the 'file' tag")
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateEmojiURI() {
- e := happyEmoji()
-
- e.URI = "aaaaaaaaaa"
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-
- e.URI = ""
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateEmojiURLCombos() {
- e := happyEmoji()
-
- e.ImageRemoteURL = ""
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageRemoteURL' Error:Field validation for 'ImageRemoteURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageURL' Error:Field validation for 'ImageURL' failed on the 'required_without' tag")
-
- e.ImageURL = "https://whatever.org"
- err = validate.Struct(e)
- suite.NoError(err)
-
- e.ImageStaticRemoteURL = ""
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageStaticRemoteURL' Error:Field validation for 'ImageStaticRemoteURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageStaticURL' Error:Field validation for 'ImageStaticURL' failed on the 'required_without' tag")
-
- e.ImageStaticURL = "https://whatever.org"
- err = validate.Struct(e)
- suite.NoError(err)
-
- e.ImageURL = ""
- e.ImageStaticURL = ""
- e.ImageRemoteURL = ""
- e.ImageStaticRemoteURL = ""
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageRemoteURL' Error:Field validation for 'ImageRemoteURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageStaticRemoteURL' Error:Field validation for 'ImageStaticRemoteURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageURL' Error:Field validation for 'ImageURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageStaticURL' Error:Field validation for 'ImageStaticURL' failed on the 'required_without' tag")
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateFileSize() {
- e := happyEmoji()
-
- e.ImageFileSize = 0
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageFileSize' Error:Field validation for 'ImageFileSize' failed on the 'required' tag")
-
- e.ImageStaticFileSize = 0
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageFileSize' Error:Field validation for 'ImageFileSize' failed on the 'required' tag\nKey: 'Emoji.ImageStaticFileSize' Error:Field validation for 'ImageStaticFileSize' failed on the 'required' tag")
-
- e.ImageFileSize = -1
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageFileSize' Error:Field validation for 'ImageFileSize' failed on the 'min' tag\nKey: 'Emoji.ImageStaticFileSize' Error:Field validation for 'ImageStaticFileSize' failed on the 'required' tag")
-
- e.ImageStaticFileSize = -1
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageFileSize' Error:Field validation for 'ImageFileSize' failed on the 'min' tag\nKey: 'Emoji.ImageStaticFileSize' Error:Field validation for 'ImageStaticFileSize' failed on the 'min' tag")
-}
-
-func (suite *EmojiValidateTestSuite) TestValidateDomain() {
- e := happyEmoji()
-
- e.Domain = ""
- err := validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.ImageURL' Error:Field validation for 'ImageURL' failed on the 'required_without' tag\nKey: 'Emoji.ImageStaticURL' Error:Field validation for 'ImageStaticURL' failed on the 'required_without' tag")
-
- e.Domain = "aaaaaaaaa"
- err = validate.Struct(e)
- suite.EqualError(err, "Key: 'Emoji.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-}
-
-func TestEmojiValidateTestSuite(t *testing.T) {
- suite.Run(t, new(EmojiValidateTestSuite))
-}
diff --git a/internal/validate/follow_test.go b/internal/validate/follow_test.go
deleted file mode 100644
index 2128be4aa..000000000
--- a/internal/validate/follow_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyFollow() *gtsmodel.Follow {
- return &gtsmodel.Follow{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- AccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- Account: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- URI: "https://example.org/users/user1/activity/follow/01FE91RJR88PSEEE30EV35QR8N",
- }
-}
-
-type FollowValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *FollowValidateTestSuite) TestValidateFollowHappyPath() {
- // no problem here
- f := happyFollow()
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *FollowValidateTestSuite) TestValidateFollowBadID() {
- f := happyFollow()
-
- f.ID = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'Follow.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- f.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'Follow.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *FollowValidateTestSuite) TestValidateFollowNoCreatedAt() {
- f := happyFollow()
-
- f.CreatedAt = time.Time{}
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *FollowValidateTestSuite) TestValidateFollowNoURI() {
- f := happyFollow()
-
- f.URI = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'Follow.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-
- f.URI = "this-is-not-a-valid-url"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'Follow.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-}
-
-func TestFollowValidateTestSuite(t *testing.T) {
- suite.Run(t, new(FollowValidateTestSuite))
-}
diff --git a/internal/validate/followrequest_test.go b/internal/validate/followrequest_test.go
deleted file mode 100644
index 0c3d883bb..000000000
--- a/internal/validate/followrequest_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyFollowRequest() *gtsmodel.FollowRequest {
- return &gtsmodel.FollowRequest{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- AccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- Account: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- URI: "https://example.org/users/user1/activity/follow/01FE91RJR88PSEEE30EV35QR8N",
- }
-}
-
-type FollowRequestValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *FollowRequestValidateTestSuite) TestValidateFollowRequestHappyPath() {
- // no problem here
- f := happyFollowRequest()
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *FollowRequestValidateTestSuite) TestValidateFollowRequestBadID() {
- f := happyFollowRequest()
-
- f.ID = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'FollowRequest.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- f.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'FollowRequest.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *FollowRequestValidateTestSuite) TestValidateFollowRequestNoCreatedAt() {
- f := happyFollowRequest()
-
- f.CreatedAt = time.Time{}
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *FollowRequestValidateTestSuite) TestValidateFollowRequestNoURI() {
- f := happyFollowRequest()
-
- f.URI = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'FollowRequest.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-
- f.URI = "this-is-not-a-valid-url"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'FollowRequest.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-}
-
-func TestFollowRequestValidateTestSuite(t *testing.T) {
- suite.Run(t, new(FollowRequestValidateTestSuite))
-}
diff --git a/internal/validate/instance_test.go b/internal/validate/instance_test.go
deleted file mode 100644
index 38c68a616..000000000
--- a/internal/validate/instance_test.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyInstance() *gtsmodel.Instance {
- return &gtsmodel.Instance{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- Domain: "example.org",
- Title: "Example Instance",
- URI: "https://example.org",
- SuspendedAt: time.Time{},
- DomainBlockID: "",
- DomainBlock: nil,
- ShortDescription: "This is a description for the example/testing instance.",
- Description: "This is a way longer description for the example/testing instance!",
- Terms: "Don't be a knobhead.",
- ContactEmail: "admin@example.org",
- ContactAccountUsername: "admin",
- ContactAccountID: "01FEE20H5QWHJDEXAEE9G96PR0",
- ContactAccount: nil,
- Reputation: 420,
- Version: "gotosocial 0.1.0",
- }
-}
-
-type InstanceValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceHappyPath() {
- // no problem here
- m := happyInstance()
- err := validate.Struct(*m)
- suite.NoError(err)
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceBadID() {
- m := happyInstance()
-
- m.ID = ""
- err := validate.Struct(*m)
- suite.EqualError(err, "Key: 'Instance.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- m.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(*m)
- suite.EqualError(err, "Key: 'Instance.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceAccountURI() {
- i := happyInstance()
-
- i.URI = ""
- err := validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-
- i.URI = "---------------------------"
- err = validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceDodgyAccountID() {
- i := happyInstance()
-
- i.ContactAccountID = "9HZJ76B6VXSKF"
- err := validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.ContactAccountID' Error:Field validation for 'ContactAccountID' failed on the 'ulid' tag")
-
- i.ContactAccountID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.ContactAccountID' Error:Field validation for 'ContactAccountID' failed on the 'ulid' tag")
-
- i.ContactAccountID = ""
- err = validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.ContactAccountID' Error:Field validation for 'ContactAccountID' failed on the 'required_with' tag")
-
- i.ContactAccountUsername = ""
- err = validate.Struct(i)
- suite.NoError(err)
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceDomain() {
- i := happyInstance()
-
- i.Domain = "poopoo"
- err := validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-
- i.Domain = ""
- err = validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.Domain' Error:Field validation for 'Domain' failed on the 'required' tag")
-
- i.Domain = "https://aaaaaaaaaaaaah.org"
- err = validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.Domain' Error:Field validation for 'Domain' failed on the 'fqdn' tag")
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceContactEmail() {
- i := happyInstance()
-
- i.ContactEmail = "poopoo"
- err := validate.Struct(i)
- suite.EqualError(err, "Key: 'Instance.ContactEmail' Error:Field validation for 'ContactEmail' failed on the 'email' tag")
-
- i.ContactEmail = ""
- err = validate.Struct(i)
- suite.NoError(err)
-}
-
-func (suite *InstanceValidateTestSuite) TestValidateInstanceNoCreatedAt() {
- i := happyInstance()
-
- i.CreatedAt = time.Time{}
- err := validate.Struct(i)
- suite.NoError(err)
-}
-
-func TestInstanceValidateTestSuite(t *testing.T) {
- suite.Run(t, new(InstanceValidateTestSuite))
-}
diff --git a/internal/validate/mediaattachment_test.go b/internal/validate/mediaattachment_test.go
deleted file mode 100644
index 1021319f2..000000000
--- a/internal/validate/mediaattachment_test.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyMediaAttachment() *gtsmodel.MediaAttachment {
- // the file validator actually runs os.Stat on given paths, so we need to just create small
- // temp files for both the main attachment file and the thumbnail
-
- mainFile, err := os.CreateTemp("", "gts_test_mainfile")
- if err != nil {
- panic(err)
- }
- if _, err := mainFile.WriteString("main"); err != nil {
- panic(err)
- }
- mainPath := mainFile.Name()
- if err := mainFile.Close(); err != nil {
- panic(err)
- }
-
- thumbnailFile, err := os.CreateTemp("", "gts_test_thumbnail")
- if err != nil {
- panic(err)
- }
- if _, err := thumbnailFile.WriteString("thumbnail"); err != nil {
- panic(err)
- }
- thumbnailPath := thumbnailFile.Name()
- if err := thumbnailFile.Close(); err != nil {
- panic(err)
- }
-
- return &gtsmodel.MediaAttachment{
- ID: "01F8MH6NEM8D7527KZAECTCR76",
- CreatedAt: time.Now().Add(-71 * time.Hour),
- UpdatedAt: time.Now().Add(-71 * time.Hour),
- StatusID: "01F8MH75CBF9JFX4ZAD54N0W0R",
- URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/original/01F8MH6NEM8D7527KZAECTCR76.jpg",
- RemoteURL: "",
- Type: gtsmodel.FileTypeImage,
- FileMeta: gtsmodel.FileMeta{
- Original: gtsmodel.Original{
- Width: 1200,
- Height: 630,
- Size: 756000,
- Aspect: 1.9047619047619047,
- },
- Small: gtsmodel.Small{
- Width: 256,
- Height: 134,
- Size: 34304,
- Aspect: 1.9104477611940298,
- },
- },
- AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
- Description: "Black and white image of some 50's style text saying: Welcome On Board",
- ScheduledStatusID: "",
- Blurhash: "LNJRdVM{00Rj%Mayt7j[4nWBofRj",
- Processing: 2,
- File: gtsmodel.File{
- Path: mainPath,
- ContentType: "image/jpeg",
- FileSize: 62529,
- UpdatedAt: time.Now().Add(-71 * time.Hour),
- },
- Thumbnail: gtsmodel.Thumbnail{
- Path: thumbnailPath,
- ContentType: "image/jpeg",
- FileSize: 6872,
- UpdatedAt: time.Now().Add(-71 * time.Hour),
- URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.jpg",
- RemoteURL: "",
- },
- Avatar: testrig.FalseBool(),
- Header: testrig.FalseBool(),
- }
-}
-
-type MediaAttachmentValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentHappyPath() {
- // no problem here
- m := happyMediaAttachment()
- err := validate.Struct(m)
- suite.NoError(err)
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentBadFilePaths() {
- m := happyMediaAttachment()
-
- m.File.Path = "/tmp/nonexistent/file/for/gotosocial/test"
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'file' tag")
-
- m.File.Path = ""
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'required' tag")
-
- m.File.Path = "???????????thisnot a valid path####"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'file' tag")
-
- m.Thumbnail.Path = "/tmp/nonexistent/file/for/gotosocial/test"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'file' tag\nKey: 'MediaAttachment.Thumbnail.Path' Error:Field validation for 'Path' failed on the 'file' tag")
-
- m.Thumbnail.Path = ""
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'file' tag\nKey: 'MediaAttachment.Thumbnail.Path' Error:Field validation for 'Path' failed on the 'required' tag")
-
- m.Thumbnail.Path = "???????????thisnot a valid path####"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.File.Path' Error:Field validation for 'Path' failed on the 'file' tag\nKey: 'MediaAttachment.Thumbnail.Path' Error:Field validation for 'Path' failed on the 'file' tag")
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentBadType() {
- m := happyMediaAttachment()
-
- m.Type = ""
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.Type' Error:Field validation for 'Type' failed on the 'oneof' tag")
-
- m.Type = "Not Supported"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.Type' Error:Field validation for 'Type' failed on the 'oneof' tag")
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentBadFileMeta() {
- m := happyMediaAttachment()
-
- m.FileMeta.Original.Aspect = 0
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.FileMeta.Original.Aspect' Error:Field validation for 'Aspect' failed on the 'required_with' tag")
-
- m.FileMeta.Original.Height = 0
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.FileMeta.Original.Height' Error:Field validation for 'Height' failed on the 'required_with' tag\nKey: 'MediaAttachment.FileMeta.Original.Aspect' Error:Field validation for 'Aspect' failed on the 'required_with' tag")
-
- m.FileMeta.Original = gtsmodel.Original{}
- err = validate.Struct(m)
- suite.NoError(err)
-
- m.FileMeta.Focus.X = 3.6
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.FileMeta.Focus.X' Error:Field validation for 'X' failed on the 'max' tag")
-
- m.FileMeta.Focus.Y = -50
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.FileMeta.Focus.X' Error:Field validation for 'X' failed on the 'max' tag\nKey: 'MediaAttachment.FileMeta.Focus.Y' Error:Field validation for 'Y' failed on the 'min' tag")
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentBadURLCombos() {
- m := happyMediaAttachment()
-
- m.URL = "aaaaaaaaaa"
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.URL' Error:Field validation for 'URL' failed on the 'url' tag")
-
- m.URL = ""
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.URL' Error:Field validation for 'URL' failed on the 'required_without' tag\nKey: 'MediaAttachment.RemoteURL' Error:Field validation for 'RemoteURL' failed on the 'required_without' tag")
-
- m.RemoteURL = "oooooooooo"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.RemoteURL' Error:Field validation for 'RemoteURL' failed on the 'url' tag")
-
- m.RemoteURL = "https://a-valid-url.gay"
- err = validate.Struct(m)
- suite.NoError(err)
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentBlurhash() {
- m := happyMediaAttachment()
-
- m.Blurhash = ""
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.Blurhash' Error:Field validation for 'Blurhash' failed on the 'required_if' tag")
-
- m.Type = gtsmodel.FileTypeAudio
- err = validate.Struct(m)
- suite.NoError(err)
-
- m.Blurhash = "some_blurhash"
- err = validate.Struct(m)
- suite.NoError(err)
-}
-
-func (suite *MediaAttachmentValidateTestSuite) TestValidateMediaAttachmentProcessing() {
- m := happyMediaAttachment()
-
- m.Processing = 420
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.Processing' Error:Field validation for 'Processing' failed on the 'oneof' tag")
-
- m.Processing = -5
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'MediaAttachment.Processing' Error:Field validation for 'Processing' failed on the 'oneof' tag")
-}
-
-func TestMediaAttachmentValidateTestSuite(t *testing.T) {
- suite.Run(t, new(MediaAttachmentValidateTestSuite))
-}
diff --git a/internal/validate/mention_test.go b/internal/validate/mention_test.go
deleted file mode 100644
index 52513bd8c..000000000
--- a/internal/validate/mention_test.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyMention() *gtsmodel.Mention {
- return &gtsmodel.Mention{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- OriginAccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- OriginAccountURI: "https://some-instance/accounts/bleepbloop",
- OriginAccount: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- StatusID: "01FE96NBPNJNY26730FT6GZTFE",
- Status: nil,
- }
-}
-
-type MentionValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *MentionValidateTestSuite) TestValidateMentionHappyPath() {
- // no problem here
- m := happyMention()
- err := validate.Struct(m)
- suite.NoError(err)
-}
-
-func (suite *MentionValidateTestSuite) TestValidateMentionBadID() {
- m := happyMention()
-
- m.ID = ""
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- m.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *MentionValidateTestSuite) TestValidateMentionAccountURI() {
- m := happyMention()
-
- m.OriginAccountURI = ""
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.OriginAccountURI' Error:Field validation for 'OriginAccountURI' failed on the 'url' tag")
-
- m.OriginAccountURI = "---------------------------"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.OriginAccountURI' Error:Field validation for 'OriginAccountURI' failed on the 'url' tag")
-}
-
-func (suite *MentionValidateTestSuite) TestValidateMentionDodgyStatusID() {
- m := happyMention()
-
- m.StatusID = "9HZJ76B6VXSKF"
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- m.StatusID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'Mention.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-}
-
-func (suite *MentionValidateTestSuite) TestValidateMentionNoCreatedAt() {
- m := happyMention()
-
- m.CreatedAt = time.Time{}
- err := validate.Struct(m)
- suite.NoError(err)
-}
-
-func TestMentionValidateTestSuite(t *testing.T) {
- suite.Run(t, new(MentionValidateTestSuite))
-}
diff --git a/internal/validate/notification_test.go b/internal/validate/notification_test.go
deleted file mode 100644
index a76b8bf58..000000000
--- a/internal/validate/notification_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyNotification() *gtsmodel.Notification {
- return &gtsmodel.Notification{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- NotificationType: gtsmodel.NotificationFave,
- OriginAccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- OriginAccount: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- StatusID: "01FE96NBPNJNY26730FT6GZTFE",
- Status: nil,
- }
-}
-
-type NotificationValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *NotificationValidateTestSuite) TestValidateNotificationHappyPath() {
- // no problem here
- n := happyNotification()
- err := validate.Struct(n)
- suite.NoError(err)
-}
-
-func (suite *NotificationValidateTestSuite) TestValidateNotificationBadID() {
- n := happyNotification()
-
- n.ID = ""
- err := validate.Struct(n)
- suite.EqualError(err, "Key: 'Notification.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- n.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(n)
- suite.EqualError(err, "Key: 'Notification.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *NotificationValidateTestSuite) TestValidateNotificationStatusID() {
- n := happyNotification()
-
- n.StatusID = ""
- err := validate.Struct(n)
- suite.EqualError(err, "Key: 'Notification.StatusID' Error:Field validation for 'StatusID' failed on the 'required_if' tag")
-
- n.StatusID = "9HZJ76B6VXSKF"
- err = validate.Struct(n)
- suite.EqualError(err, "Key: 'Notification.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- n.StatusID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(n)
- suite.EqualError(err, "Key: 'Notification.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- n.StatusID = ""
- n.NotificationType = gtsmodel.NotificationFollowRequest
- err = validate.Struct(n)
- suite.NoError(err)
-}
-
-func (suite *NotificationValidateTestSuite) TestValidateNotificationNoCreatedAt() {
- n := happyNotification()
-
- n.CreatedAt = time.Time{}
- err := validate.Struct(n)
- suite.NoError(err)
-}
-
-func TestNotificationValidateTestSuite(t *testing.T) {
- suite.Run(t, new(NotificationValidateTestSuite))
-}
diff --git a/internal/validate/routersession_test.go b/internal/validate/routersession_test.go
deleted file mode 100644
index f9dc49e40..000000000
--- a/internal/validate/routersession_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyRouterSession() *gtsmodel.RouterSession {
- return &gtsmodel.RouterSession{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- Auth: []byte("12345678901234567890123456789012"),
- Crypt: []byte("12345678901234567890123456789012"),
- }
-}
-
-type RouterSessionValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *RouterSessionValidateTestSuite) TestValidateRouterSessionHappyPath() {
- // no problem here
- r := happyRouterSession()
- err := validate.Struct(r)
- suite.NoError(err)
-}
-
-func (suite *RouterSessionValidateTestSuite) TestValidateRouterSessionAuth() {
- r := happyRouterSession()
-
- // remove auth struct
- r.Auth = nil
- err := validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Auth' Error:Field validation for 'Auth' failed on the 'required' tag")
-
- // auth bytes too long
- r.Auth = []byte("1234567890123456789012345678901234567890")
- err = validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Auth' Error:Field validation for 'Auth' failed on the 'len' tag")
-
- // auth bytes too short
- r.Auth = []byte("12345678901")
- err = validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Auth' Error:Field validation for 'Auth' failed on the 'len' tag")
-}
-
-func (suite *RouterSessionValidateTestSuite) TestValidateRouterSessionCrypt() {
- r := happyRouterSession()
-
- // remove crypt struct
- r.Crypt = nil
- err := validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Crypt' Error:Field validation for 'Crypt' failed on the 'required' tag")
-
- // crypt bytes too long
- r.Crypt = []byte("1234567890123456789012345678901234567890")
- err = validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Crypt' Error:Field validation for 'Crypt' failed on the 'len' tag")
-
- // crypt bytes too short
- r.Crypt = []byte("12345678901")
- err = validate.Struct(r)
- suite.EqualError(err, "Key: 'RouterSession.Crypt' Error:Field validation for 'Crypt' failed on the 'len' tag")
-}
-
-func TestRouterSessionValidateTestSuite(t *testing.T) {
- suite.Run(t, new(RouterSessionValidateTestSuite))
-}
diff --git a/internal/validate/status_test.go b/internal/validate/status_test.go
deleted file mode 100644
index db0cd8fda..000000000
--- a/internal/validate/status_test.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/ap"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyStatus() *gtsmodel.Status {
- return &gtsmodel.Status{
- ID: "01FEBBH6NYDG87NK6A6EC543ED",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- URI: "https://example.org/users/test_user/statuses/01FEBBH6NYDG87NK6A6EC543ED",
- URL: "https://example.org/@test_user/01FEBBH6NYDG87NK6A6EC543ED",
- Content: "<p>Test status! #hello</p>",
- AttachmentIDs: []string{"01FEBBKZBY9H5FEP3PHVVAAGN1", "01FEBBM7S2R4WT6WWW22KN1PWE"},
- Attachments: nil,
- TagIDs: []string{"01FEBBNBMBSN1FESMZ1TCXNWYP"},
- Tags: nil,
- MentionIDs: nil,
- Mentions: nil,
- EmojiIDs: nil,
- Emojis: nil,
- Local: testrig.TrueBool(),
- AccountID: "01FEBBQ4KEP3824WW61MF52638",
- Account: nil,
- AccountURI: "https://example.org/users/test_user",
- InReplyToID: "",
- InReplyToURI: "",
- InReplyToAccountID: "",
- InReplyTo: nil,
- InReplyToAccount: nil,
- BoostOfID: "",
- BoostOfAccountID: "",
- BoostOf: nil,
- BoostOfAccount: nil,
- ContentWarning: "hello world test post",
- Visibility: gtsmodel.VisibilityPublic,
- Sensitive: testrig.FalseBool(),
- Language: "en",
- CreatedWithApplicationID: "01FEBBZHF4GFVRXSJVXD0JTZZ2",
- CreatedWithApplication: nil,
- Federated: testrig.TrueBool(),
- Boostable: testrig.TrueBool(),
- Replyable: testrig.TrueBool(),
- Likeable: testrig.TrueBool(),
- ActivityStreamsType: ap.ObjectNote,
- Text: "Test status! #hello",
- }
-}
-
-type StatusValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *StatusValidateTestSuite) TestValidateStatusHappyPath() {
- // no problem here
- s := happyStatus()
- err := validate.Struct(s)
- suite.NoError(err)
-}
-
-func (suite *StatusValidateTestSuite) TestValidateStatusBadID() {
- s := happyStatus()
-
- s.ID = ""
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- s.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusValidateTestSuite) TestValidateStatusAttachmentIDs() {
- s := happyStatus()
-
- s.AttachmentIDs[0] = ""
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.AttachmentIDs[0]' Error:Field validation for 'AttachmentIDs[0]' failed on the 'ulid' tag")
-
- s.AttachmentIDs[0] = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.AttachmentIDs[0]' Error:Field validation for 'AttachmentIDs[0]' failed on the 'ulid' tag")
-
- s.AttachmentIDs[1] = ""
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.AttachmentIDs[0]' Error:Field validation for 'AttachmentIDs[0]' failed on the 'ulid' tag\nKey: 'Status.AttachmentIDs[1]' Error:Field validation for 'AttachmentIDs[1]' failed on the 'ulid' tag")
-
- s.AttachmentIDs = []string{}
- err = validate.Struct(s)
- suite.NoError(err)
-
- s.AttachmentIDs = nil
- err = validate.Struct(s)
- suite.NoError(err)
-}
-
-func (suite *StatusValidateTestSuite) TestStatusApplicationID() {
- s := happyStatus()
-
- s.CreatedWithApplicationID = ""
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.CreatedWithApplicationID' Error:Field validation for 'CreatedWithApplicationID' failed on the 'required_if' tag")
-
- s.Local = testrig.FalseBool()
- err = validate.Struct(s)
- suite.NoError(err)
-}
-
-func (suite *StatusValidateTestSuite) TestValidateStatusReplyFields() {
- s := happyStatus()
-
- s.InReplyToAccountID = "01FEBCTP6DN7961PN81C3DVM4N "
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.InReplyToID' Error:Field validation for 'InReplyToID' failed on the 'required_with' tag\nKey: 'Status.InReplyToURI' Error:Field validation for 'InReplyToURI' failed on the 'required_with' tag\nKey: 'Status.InReplyToAccountID' Error:Field validation for 'InReplyToAccountID' failed on the 'ulid' tag")
-
- s.InReplyToAccountID = "01FEBCTP6DN7961PN81C3DVM4N"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.InReplyToID' Error:Field validation for 'InReplyToID' failed on the 'required_with' tag\nKey: 'Status.InReplyToURI' Error:Field validation for 'InReplyToURI' failed on the 'required_with' tag")
-
- s.InReplyToURI = "https://example.org/users/mmbop/statuses/aaaaaaaa"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.InReplyToID' Error:Field validation for 'InReplyToID' failed on the 'required_with' tag")
-
- s.InReplyToID = "not a valid ulid"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'Status.InReplyToID' Error:Field validation for 'InReplyToID' failed on the 'ulid' tag")
-
- s.InReplyToID = "01FEBD07E72DEY6YB9K10ZA6ST"
- err = validate.Struct(s)
- suite.NoError(err)
-}
-
-func TestStatusValidateTestSuite(t *testing.T) {
- suite.Run(t, new(StatusValidateTestSuite))
-}
diff --git a/internal/validate/statusbookmark_test.go b/internal/validate/statusbookmark_test.go
deleted file mode 100644
index 3be9e56ed..000000000
--- a/internal/validate/statusbookmark_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyStatusBookmark() *gtsmodel.StatusBookmark {
- return &gtsmodel.StatusBookmark{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- AccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- Account: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- StatusID: "01FE96NBPNJNY26730FT6GZTFE",
- Status: nil,
- }
-}
-
-type StatusBookmarkValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *StatusBookmarkValidateTestSuite) TestValidateStatusBookmarkHappyPath() {
- // no problem here
- s := happyStatusBookmark()
- err := validate.Struct(s)
- suite.NoError(err)
-}
-
-func (suite *StatusBookmarkValidateTestSuite) TestValidateStatusBookmarkBadID() {
- s := happyStatusBookmark()
-
- s.ID = ""
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'StatusBookmark.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- s.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'StatusBookmark.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusBookmarkValidateTestSuite) TestValidateStatusBookmarkDodgyStatusID() {
- s := happyStatusBookmark()
-
- s.StatusID = "9HZJ76B6VXSKF"
- err := validate.Struct(s)
- suite.EqualError(err, "Key: 'StatusBookmark.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- s.StatusID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(s)
- suite.EqualError(err, "Key: 'StatusBookmark.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusBookmarkValidateTestSuite) TestValidateStatusBookmarkNoCreatedAt() {
- s := happyStatusBookmark()
-
- s.CreatedAt = time.Time{}
- err := validate.Struct(s)
- suite.NoError(err)
-}
-
-func TestStatusBookmarkValidateTestSuite(t *testing.T) {
- suite.Run(t, new(StatusBookmarkValidateTestSuite))
-}
diff --git a/internal/validate/statusfave_test.go b/internal/validate/statusfave_test.go
deleted file mode 100644
index e864e39f2..000000000
--- a/internal/validate/statusfave_test.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyStatusFave() *gtsmodel.StatusFave {
- return &gtsmodel.StatusFave{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- AccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- Account: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- StatusID: "01FE96NBPNJNY26730FT6GZTFE",
- Status: nil,
- URI: "https://example.org/users/user1/activity/faves/01FE91RJR88PSEEE30EV35QR8N",
- }
-}
-
-type StatusFaveValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *StatusFaveValidateTestSuite) TestValidateStatusFaveHappyPath() {
- // no problem here
- f := happyStatusFave()
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *StatusFaveValidateTestSuite) TestValidateStatusFaveBadID() {
- f := happyStatusFave()
-
- f.ID = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- f.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusFaveValidateTestSuite) TestValidateStatusFaveDodgyStatusID() {
- f := happyStatusFave()
-
- f.StatusID = "9HZJ76B6VXSKF"
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- f.StatusID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusFaveValidateTestSuite) TestValidateStatusFaveNoCreatedAt() {
- f := happyStatusFave()
-
- f.CreatedAt = time.Time{}
- err := validate.Struct(f)
- suite.NoError(err)
-}
-
-func (suite *StatusFaveValidateTestSuite) TestValidateStatusFaveNoURI() {
- f := happyStatusFave()
-
- f.URI = ""
- err := validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.URI' Error:Field validation for 'URI' failed on the 'required' tag")
-
- f.URI = "this-is-not-a-valid-url"
- err = validate.Struct(f)
- suite.EqualError(err, "Key: 'StatusFave.URI' Error:Field validation for 'URI' failed on the 'url' tag")
-}
-
-func TestStatusFaveValidateTestSuite(t *testing.T) {
- suite.Run(t, new(StatusFaveValidateTestSuite))
-}
diff --git a/internal/validate/statusmute_test.go b/internal/validate/statusmute_test.go
deleted file mode 100644
index 20358bb23..000000000
--- a/internal/validate/statusmute_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyStatusMute() *gtsmodel.StatusMute {
- return &gtsmodel.StatusMute{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- AccountID: "01FE96MAE58MXCE5C4SSMEMCEK",
- Account: nil,
- TargetAccountID: "01FE96MXRHWZHKC0WH5FT82H1A",
- TargetAccount: nil,
- StatusID: "01FE96NBPNJNY26730FT6GZTFE",
- Status: nil,
- }
-}
-
-type StatusMuteValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *StatusMuteValidateTestSuite) TestValidateStatusMuteHappyPath() {
- // no problem here
- m := happyStatusMute()
- err := validate.Struct(m)
- suite.NoError(err)
-}
-
-func (suite *StatusMuteValidateTestSuite) TestValidateStatusMuteBadID() {
- m := happyStatusMute()
-
- m.ID = ""
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'StatusMute.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- m.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'StatusMute.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusMuteValidateTestSuite) TestValidateStatusMuteDodgyStatusID() {
- m := happyStatusMute()
-
- m.StatusID = "9HZJ76B6VXSKF"
- err := validate.Struct(m)
- suite.EqualError(err, "Key: 'StatusMute.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-
- m.StatusID = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!"
- err = validate.Struct(m)
- suite.EqualError(err, "Key: 'StatusMute.StatusID' Error:Field validation for 'StatusID' failed on the 'ulid' tag")
-}
-
-func (suite *StatusMuteValidateTestSuite) TestValidateStatusMuteNoCreatedAt() {
- m := happyStatusMute()
-
- m.CreatedAt = time.Time{}
- err := validate.Struct(m)
- suite.NoError(err)
-}
-
-func TestStatusMuteValidateTestSuite(t *testing.T) {
- suite.Run(t, new(StatusMuteValidateTestSuite))
-}
diff --git a/internal/validate/structvalidation.go b/internal/validate/structvalidation.go
deleted file mode 100644
index 573e79fd2..000000000
--- a/internal/validate/structvalidation.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate
-
-import (
- "reflect"
-
- "github.com/go-playground/validator/v10"
- "github.com/superseriousbusiness/gotosocial/internal/regexes"
-)
-
-var v *validator.Validate
-
-func ulidValidator(fl validator.FieldLevel) bool {
- field := fl.Field()
-
- switch field.Kind() {
- case reflect.String:
- return regexes.ULID.MatchString(field.String())
- default:
- return false
- }
-}
-
-func init() {
- v = validator.New()
- if err := v.RegisterValidation("ulid", ulidValidator); err != nil {
- panic(err)
- }
-}
-
-// Struct validates the passed struct, returning validator.ValidationErrors if invalid, or nil if OK.
-func Struct(s interface{}) error {
- return processValidationError(v.Struct(s))
-}
-
-func processValidationError(err error) error {
- if err == nil {
- return nil
- }
-
- if ive, ok := err.(*validator.InvalidValidationError); ok {
- panic(ive)
- }
-
- valErr, ok := err.(validator.ValidationErrors)
- if !ok {
- panic("*validator.InvalidValidationError could not be coerced to validator.ValidationErrors")
- }
-
- return valErr
-}
diff --git a/internal/validate/structvalidation_test.go b/internal/validate/structvalidation_test.go
deleted file mode 100644
index f8ad514cf..000000000
--- a/internal/validate/structvalidation_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-type ValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *ValidateTestSuite) TestValidateNilPointer() {
- var nilUser *gtsmodel.User
- suite.Panics(func() {
- validate.Struct(nilUser)
- })
-}
-
-func (suite *ValidateTestSuite) TestValidatePointer() {
- user := &gtsmodel.User{}
- err := validate.Struct(user)
- suite.EqualError(err, "Key: 'User.ID' Error:Field validation for 'ID' failed on the 'required' tag\nKey: 'User.AccountID' Error:Field validation for 'AccountID' failed on the 'required' tag\nKey: 'User.EncryptedPassword' Error:Field validation for 'EncryptedPassword' failed on the 'required' tag\nKey: 'User.UnconfirmedEmail' Error:Field validation for 'UnconfirmedEmail' failed on the 'required_without' tag")
-}
-
-func (suite *ValidateTestSuite) TestValidateNil() {
- suite.Panics(func() {
- validate.Struct(nil)
- })
-}
-
-func (suite *ValidateTestSuite) TestValidateWeirdULID() {
- type a struct {
- ID bool `validate:"required,ulid"`
- }
-
- err := validate.Struct(a{ID: true})
- suite.Error(err)
-}
-
-func (suite *ValidateTestSuite) TestValidateNotStruct() {
- type aaaaaaa string
- aaaaaa := aaaaaaa("aaaa")
- suite.Panics(func() {
- validate.Struct(aaaaaa)
- })
-}
-
-func TestValidateTestSuite(t *testing.T) {
- suite.Run(t, new(ValidateTestSuite))
-}
diff --git a/internal/validate/token_test.go b/internal/validate/token_test.go
deleted file mode 100644
index 2ff0e0721..000000000
--- a/internal/validate/token_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
-)
-
-func happyToken() *gtsmodel.Token {
- return &gtsmodel.Token{
- ID: "01FE91RJR88PSEEE30EV35QR8N",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- ClientID: "01FEEDMF6C0QD589MRK7919Z0R",
- UserID: "01FEK0BFJKYXB4Y51RBQ7P5P79",
- RedirectURI: "oauth2redirect://com.keylesspalace.tusky/",
- Scope: "read write follow",
- }
-}
-
-type TokenValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *TokenValidateTestSuite) TestValidateTokenHappyPath() {
- // no problem here
- t := happyToken()
- err := validate.Struct(t)
- suite.NoError(err)
-}
-
-func (suite *TokenValidateTestSuite) TestValidateTokenBadID() {
- t := happyToken()
-
- t.ID = ""
- err := validate.Struct(t)
- suite.EqualError(err, "Key: 'Token.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-
- t.ID = "01FE96W293ZPRG9FQQP48HK8N001FE96W32AT24VYBGM12WN3GKB"
- err = validate.Struct(t)
- suite.EqualError(err, "Key: 'Token.ID' Error:Field validation for 'ID' failed on the 'ulid' tag")
-}
-
-func (suite *TokenValidateTestSuite) TestValidateTokenNoCreatedAt() {
- t := happyToken()
-
- t.CreatedAt = time.Time{}
- err := validate.Struct(t)
- suite.NoError(err)
-}
-
-func (suite *TokenValidateTestSuite) TestValidateTokenRedirectURI() {
- t := happyToken()
-
- t.RedirectURI = "invalid-uri"
- err := validate.Struct(t)
- suite.EqualError(err, "Key: 'Token.RedirectURI' Error:Field validation for 'RedirectURI' failed on the 'uri' tag")
-
- t.RedirectURI = ""
- err = validate.Struct(t)
- suite.EqualError(err, "Key: 'Token.RedirectURI' Error:Field validation for 'RedirectURI' failed on the 'required' tag")
-
- t.RedirectURI = "urn:ietf:wg:oauth:2.0:oob"
- err = validate.Struct(t)
- suite.NoError(err)
-}
-
-func (suite *TokenValidateTestSuite) TestValidateTokenScope() {
- t := happyToken()
-
- t.Scope = ""
- err := validate.Struct(t)
- suite.EqualError(err, "Key: 'Token.Scope' Error:Field validation for 'Scope' failed on the 'required' tag")
-}
-
-func TestTokenValidateTestSuite(t *testing.T) {
- suite.Run(t, new(TokenValidateTestSuite))
-}
diff --git a/internal/validate/user_test.go b/internal/validate/user_test.go
deleted file mode 100644
index f61ff6e2f..000000000
--- a/internal/validate/user_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// GoToSocial
-// Copyright (C) GoToSocial Authors admin@gotosocial.org
-// SPDX-License-Identifier: AGPL-3.0-or-later
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package validate_test
-
-import (
- "net"
- "testing"
- "time"
-
- "github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/validate"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-func happyUser() *gtsmodel.User {
- return &gtsmodel.User{
- ID: "01FE8TTK9F34BR0KG7639AJQTX",
- Email: "whatever@example.org",
- AccountID: "01FE8TWA7CN8J7237K5DFS1RY5",
- Account: nil,
- EncryptedPassword: "$2y$10$tkRapNGW.RWkEuCMWdgArunABFvsPGRvFQY3OibfSJo0RDL3z8WfC",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- SignUpIP: net.ParseIP("128.64.32.16"),
- CurrentSignInAt: time.Now(),
- CurrentSignInIP: net.ParseIP("128.64.32.16"),
- LastSignInAt: time.Now(),
- LastSignInIP: net.ParseIP("128.64.32.16"),
- SignInCount: 0,
- InviteID: "",
- ChosenLanguages: []string{},
- FilteredLanguages: []string{},
- Locale: "en",
- CreatedByApplicationID: "01FE8Y5EHMWCA1MHMTNHRVZ1X4",
- CreatedByApplication: nil,
- LastEmailedAt: time.Now(),
- ConfirmationToken: "",
- ConfirmedAt: time.Now(),
- ConfirmationSentAt: time.Time{},
- UnconfirmedEmail: "",
- Moderator: testrig.FalseBool(),
- Admin: testrig.FalseBool(),
- Disabled: testrig.FalseBool(),
- Approved: testrig.TrueBool(),
- }
-}
-
-type UserValidateTestSuite struct {
- suite.Suite
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserHappyPath() {
- // no problem here
- u := happyUser()
- err := validate.Struct(u)
- suite.NoError(err)
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserNoID() {
- // user has no id set
- u := happyUser()
- u.ID = ""
-
- err := validate.Struct(u)
- suite.EqualError(err, "Key: 'User.ID' Error:Field validation for 'ID' failed on the 'required' tag")
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserNoEmail() {
- // user has no email or unconfirmed email set
- u := happyUser()
- u.Email = ""
-
- err := validate.Struct(u)
- suite.EqualError(err, "Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required_with' tag\nKey: 'User.UnconfirmedEmail' Error:Field validation for 'UnconfirmedEmail' failed on the 'required_without' tag")
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserOnlyUnconfirmedEmail() {
- // user has only UnconfirmedEmail but ConfirmedAt is set
- u := happyUser()
- u.Email = ""
- u.UnconfirmedEmail = "whatever@example.org"
-
- err := validate.Struct(u)
- suite.EqualError(err, "Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required_with' tag")
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserOnlyUnconfirmedEmailOK() {
- // user has only UnconfirmedEmail and ConfirmedAt is not set
- u := happyUser()
- u.Email = ""
- u.UnconfirmedEmail = "whatever@example.org"
- u.ConfirmedAt = time.Time{}
-
- err := validate.Struct(u)
- suite.NoError(err)
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserNoConfirmedAt() {
- // user has Email but no ConfirmedAt
- u := happyUser()
- u.ConfirmedAt = time.Time{}
-
- err := validate.Struct(u)
- suite.EqualError(err, "Key: 'User.ConfirmedAt' Error:Field validation for 'ConfirmedAt' failed on the 'required_with' tag")
-}
-
-func (suite *UserValidateTestSuite) TestValidateUserUnlikelySignInCount() {
- // user has Email but no ConfirmedAt
- u := happyUser()
- u.SignInCount = -69
-
- err := validate.Struct(u)
- suite.EqualError(err, "Key: 'User.SignInCount' Error:Field validation for 'SignInCount' failed on the 'min' tag")
-}
-
-func TestUserValidateTestSuite(t *testing.T) {
- suite.Run(t, new(UserValidateTestSuite))
-}