Private
Public Access
1
0

Add 'mock/' from commit '2041d3ce6377da091eca17cf9d8ad176a3024616'

git-subtree-dir: mock
git-subtree-mainline: 8216d7c706
git-subtree-split: 2041d3ce63
This commit is contained in:
2025-09-06 19:35:49 -07:00
20 changed files with 2661 additions and 0 deletions

57
mock/model/attachment.go Normal file
View File

@@ -0,0 +1,57 @@
package model
import (
"bufio"
"io"
"os"
"path"
"github.com/google/uuid"
)
type AttachmentStore struct {
basePath string
}
func NewAttachmentStore(basePath string) AttachmentStore {
_, err := os.Stat(basePath)
if os.IsNotExist(err) {
os.MkdirAll(basePath, 0755)
}
return AttachmentStore{
basePath: basePath,
}
}
func (s *AttachmentStore) FetchAttachment(guid string) (io.Reader, error) {
fullPath := path.Join(s.basePath, guid)
f, err := os.Open(fullPath)
if err != nil {
return nil, err
}
return bufio.NewReader(f), nil
}
func (s *AttachmentStore) StoreAttachment(filename string, reader io.Reader) (*string, error) {
// Generate GUID
guid := uuid.New().String()
fullPath := path.Join(s.basePath, guid)
f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return nil, err
}
r := bufio.NewReader(reader)
w := bufio.NewWriter(f)
_, err = w.ReadFrom(r)
return &guid, err
}
func (s *AttachmentStore) DeleteAttachment(guid string) error {
fullPath := path.Join(s.basePath, guid)
return os.Remove(fullPath)
}

59
mock/model/authtoken.go Normal file
View File

@@ -0,0 +1,59 @@
package model
import (
"encoding/base64"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/rs/zerolog/log"
)
type AuthToken struct {
SignedToken string `json:"jwt"`
token jwt.Token
}
type TokenGenerationError struct {
message string
}
func (e *TokenGenerationError) Error() string {
return e.message
}
// Create a struct to hold your custom claims
type customClaims struct {
Username string `json:"username"`
jwt.StandardClaims
}
const signingKey = "nDjYmTjoPrAGzuyhHz6Dq5bqcRrEZJc5Ls3SQcdylBI="
func NewAuthToken(username string) (*AuthToken, error) {
claims := customClaims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 24 * 5).Unix(), // 5 days
},
}
// Create a new JWT token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
if token == nil {
log.Error().Msg("Error creating Jwt Token")
return nil, &TokenGenerationError{"Error creating Jwt Token"}
}
// Sign the token with the specified signing key
decodedSigningKey, _ := base64.StdEncoding.DecodeString(signingKey)
signedToken, err := token.SignedString(decodedSigningKey)
if err != nil {
log.Error().Err(err).Msg("Error signing Jwt Token")
return nil, &TokenGenerationError{"Error signing Jwt Token"}
}
return &AuthToken{
SignedToken: signedToken,
token: *token,
}, nil
}

View File

@@ -0,0 +1,73 @@
package model
import (
"strings"
"time"
"github.com/rs/zerolog"
)
type Conversation struct {
Date Date `json:"date"`
Participants []string `json:"participantDisplayNames"`
DisplayName *string `json:"displayName,omitempty"` // Optional
UnreadCount int `json:"unreadCount"`
LastMessagePreview string `json:"lastMessagePreview"`
LastMessage Message `json:"lastMessage"`
Guid string `json:"guid"`
}
func (c *Conversation) GetDisplayName() string {
if c.DisplayName == nil {
return strings.Join(c.Participants, ",")
}
return *c.DisplayName
}
func (c *Conversation) MarshalZerologObject(e *zerolog.Event) {
e.Str("guid", c.Guid)
e.Time("date", time.Time(c.Date))
e.Int("unreadCount", c.UnreadCount)
e.Str("lastMessagePreview", c.LastMessagePreview)
e.Strs("participants", c.Participants)
if c.DisplayName != nil {
e.Str("displayName", *c.DisplayName)
}
}
func (c *Conversation) Equal(o *Conversation) bool {
if c.Guid != o.Guid {
return false
}
if !c.Date.Equal(o.Date) {
return false
}
if c.UnreadCount != o.UnreadCount {
return false
}
if c.LastMessagePreview != o.LastMessagePreview {
return false
}
if len(c.Participants) != len(o.Participants) {
return false
}
for i, p := range c.Participants {
if p != o.Participants[i] {
return false
}
}
if c.DisplayName != nil && o.DisplayName != nil {
if *c.DisplayName != *o.DisplayName {
return false
}
}
return true
}

53
mock/model/date.go Normal file
View File

@@ -0,0 +1,53 @@
package model
import (
"errors"
"fmt"
"time"
)
type Date time.Time
func (d Date) Equal(other Date) bool {
// usec and nsec are lost in ISO8601 conversion
dr := time.Time(d).Round(time.Minute)
or := time.Time(other).Round(time.Minute)
return dr.Equal(or)
}
func (d Date) After(other Date) bool {
return time.Time(d).After(time.Time(other))
}
func (d Date) Before(other Date) bool {
return time.Time(d).Before(time.Time(other))
}
func (d Date) Format(layout string) string {
return time.Time(d).Format(layout)
}
func (d Date) MarshalJSON() ([]byte, error) {
// Must use ISO8601
formatted := fmt.Sprintf("\"%s\"", time.Time(d).Format("2006-01-02T15:04:05+00:00"))
return []byte(formatted), nil
}
func (d *Date) UnmarshalJSON(data []byte) error {
if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
return errors.New("Time.UnmarshalJSON: input is not a JSON string")
}
data = data[len(`"`) : len(data)-len(`"`)]
var err error
var t time.Time
t, err = time.ParseInLocation("2006-01-02T15:04:05+00:00", string(data), time.Now().Location())
if err != nil {
return err
}
*d = Date(t)
return nil
}

35
mock/model/message.go Normal file
View File

@@ -0,0 +1,35 @@
package model
import (
"time"
"github.com/rs/zerolog"
)
type Message struct {
Text string `json:"text"`
Guid string `json:"guid"`
Sender *string `json:"sender,omitempty"` // Optional: nil means from "me"
Date Date `json:"date"`
// Map of attachment GUID to attachment metadata
AttachmentGUIDs []string `json:"fileTransferGUIDs,omitempty"`
AttachmentMetadata *map[string]AttributionInfo `json:"attachmentMetadata,omitempty"` // Optional
}
type AttributionInfo struct {
ThumbnailWidth int `json:"pgensw"`
ThumbnailHeight int `json:"pgensh"`
}
func (c Message) MarshalZerologObject(e *zerolog.Event) {
e.Str("guid", c.Guid)
e.Str("text", c.Text)
e.Time("date", time.Time(c.Date))
if c.Sender != nil {
e.Str("sender", *c.Sender)
} else {
e.Str("sender", "(Me)")
}
}

26
mock/model/update.go Normal file
View File

@@ -0,0 +1,26 @@
package model
import "github.com/rs/zerolog"
type UpdateItem struct {
MessageSequenceNumber int `json:"messageSequenceNumber"`
Conversation *Conversation `json:"conversation,omitempty"`
Message *Message `json:"message,omitempty"`
}
func New(conversation *Conversation, message *Message) *UpdateItem {
return &UpdateItem{
Conversation: conversation,
Message: message,
}
}
func (i *UpdateItem) MarshalZerologObject(e *zerolog.Event) {
e.Int("messageSequenceNumber", i.MessageSequenceNumber)
if i.Conversation != nil {
e.Object("conversation", i.Conversation)
}
if i.Message != nil {
e.Object("message", i.Message)
}
}