Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
89d09838
Commit
89d09838
authored
Apr 21, 2026
by
IanShaw027
Browse files
Return bad request for invalid announcements
parent
0d87f94c
Changes
3
Show whitespace changes
Inline
Side-by-side
backend/internal/service/announcement.go
View file @
89d09838
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"time"
"time"
"github.com/Wei-Shaw/sub2api/internal/domain"
"github.com/Wei-Shaw/sub2api/internal/domain"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/pkg/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
@@ -36,6 +37,21 @@ const (
...
@@ -36,6 +37,21 @@ const (
var
(
var
(
ErrAnnouncementNotFound
=
domain
.
ErrAnnouncementNotFound
ErrAnnouncementNotFound
=
domain
.
ErrAnnouncementNotFound
ErrAnnouncementInvalidTarget
=
domain
.
ErrAnnouncementInvalidTarget
ErrAnnouncementInvalidTarget
=
domain
.
ErrAnnouncementInvalidTarget
ErrAnnouncementNilInput
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_INPUT_REQUIRED"
,
"announcement input is required"
)
ErrAnnouncementInvalidTitle
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_TITLE_INVALID"
,
"announcement title is invalid"
)
ErrAnnouncementContentRequired
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_CONTENT_REQUIRED"
,
"announcement content is required"
,
)
ErrAnnouncementInvalidStatus
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_STATUS_INVALID"
,
"announcement status is invalid"
)
ErrAnnouncementInvalidNotifyMode
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_NOTIFY_MODE_INVALID"
,
"announcement notify_mode is invalid"
,
)
ErrAnnouncementInvalidSchedule
=
infraerrors
.
BadRequest
(
"ANNOUNCEMENT_TIME_RANGE_INVALID"
,
"starts_at must be before ends_at"
,
)
)
)
type
AnnouncementTargeting
=
domain
.
AnnouncementTargeting
type
AnnouncementTargeting
=
domain
.
AnnouncementTargeting
...
...
backend/internal/service/announcement_service.go
View file @
89d09838
...
@@ -70,16 +70,16 @@ type AnnouncementUserReadStatus struct {
...
@@ -70,16 +70,16 @@ type AnnouncementUserReadStatus struct {
func
(
s
*
AnnouncementService
)
Create
(
ctx
context
.
Context
,
input
*
CreateAnnouncementInput
)
(
*
Announcement
,
error
)
{
func
(
s
*
AnnouncementService
)
Create
(
ctx
context
.
Context
,
input
*
CreateAnnouncementInput
)
(
*
Announcement
,
error
)
{
if
input
==
nil
{
if
input
==
nil
{
return
nil
,
fmt
.
Errorf
(
"create a
nnouncement
: nil i
nput
"
)
return
nil
,
ErrA
nnouncement
NilI
nput
}
}
title
:=
strings
.
TrimSpace
(
input
.
Title
)
title
:=
strings
.
TrimSpace
(
input
.
Title
)
content
:=
strings
.
TrimSpace
(
input
.
Content
)
content
:=
strings
.
TrimSpace
(
input
.
Content
)
if
title
==
""
||
len
(
title
)
>
200
{
if
title
==
""
||
len
(
title
)
>
200
{
return
nil
,
fmt
.
Errorf
(
"create a
nnouncement
: i
nvalid
t
itle
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
T
itle
}
}
if
content
==
""
{
if
content
==
""
{
return
nil
,
fmt
.
Errorf
(
"create a
nnouncement
: c
ontent
is r
equired
"
)
return
nil
,
ErrA
nnouncement
C
ontent
R
equired
}
}
status
:=
strings
.
TrimSpace
(
input
.
Status
)
status
:=
strings
.
TrimSpace
(
input
.
Status
)
...
@@ -87,7 +87,7 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
...
@@ -87,7 +87,7 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
status
=
AnnouncementStatusDraft
status
=
AnnouncementStatusDraft
}
}
if
!
isValidAnnouncementStatus
(
status
)
{
if
!
isValidAnnouncementStatus
(
status
)
{
return
nil
,
fmt
.
Errorf
(
"create a
nnouncement
: i
nvalid
s
tatus
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
S
tatus
}
}
targeting
,
err
:=
domain
.
AnnouncementTargeting
(
input
.
Targeting
)
.
NormalizeAndValidate
()
targeting
,
err
:=
domain
.
AnnouncementTargeting
(
input
.
Targeting
)
.
NormalizeAndValidate
()
...
@@ -100,12 +100,12 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
...
@@ -100,12 +100,12 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
notifyMode
=
AnnouncementNotifyModeSilent
notifyMode
=
AnnouncementNotifyModeSilent
}
}
if
!
isValidAnnouncementNotifyMode
(
notifyMode
)
{
if
!
isValidAnnouncementNotifyMode
(
notifyMode
)
{
return
nil
,
fmt
.
Errorf
(
"create a
nnouncement
: i
nvalid
n
otify
_m
ode
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
N
otify
M
ode
}
}
if
input
.
StartsAt
!=
nil
&&
input
.
EndsAt
!=
nil
{
if
input
.
StartsAt
!=
nil
&&
input
.
EndsAt
!=
nil
{
if
!
input
.
StartsAt
.
Before
(
*
input
.
EndsAt
)
{
if
!
input
.
StartsAt
.
Before
(
*
input
.
EndsAt
)
{
return
nil
,
fmt
.
Errorf
(
"create announcement: starts_at must be before ends_at"
)
return
nil
,
ErrAnnouncementInvalidSchedule
}
}
}
}
...
@@ -131,7 +131,7 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
...
@@ -131,7 +131,7 @@ func (s *AnnouncementService) Create(ctx context.Context, input *CreateAnnouncem
func
(
s
*
AnnouncementService
)
Update
(
ctx
context
.
Context
,
id
int64
,
input
*
UpdateAnnouncementInput
)
(
*
Announcement
,
error
)
{
func
(
s
*
AnnouncementService
)
Update
(
ctx
context
.
Context
,
id
int64
,
input
*
UpdateAnnouncementInput
)
(
*
Announcement
,
error
)
{
if
input
==
nil
{
if
input
==
nil
{
return
nil
,
fmt
.
Errorf
(
"update a
nnouncement
: nil i
nput
"
)
return
nil
,
ErrA
nnouncement
NilI
nput
}
}
a
,
err
:=
s
.
announcementRepo
.
GetByID
(
ctx
,
id
)
a
,
err
:=
s
.
announcementRepo
.
GetByID
(
ctx
,
id
)
...
@@ -142,21 +142,21 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
...
@@ -142,21 +142,21 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
if
input
.
Title
!=
nil
{
if
input
.
Title
!=
nil
{
title
:=
strings
.
TrimSpace
(
*
input
.
Title
)
title
:=
strings
.
TrimSpace
(
*
input
.
Title
)
if
title
==
""
||
len
(
title
)
>
200
{
if
title
==
""
||
len
(
title
)
>
200
{
return
nil
,
fmt
.
Errorf
(
"update a
nnouncement
: i
nvalid
t
itle
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
T
itle
}
}
a
.
Title
=
title
a
.
Title
=
title
}
}
if
input
.
Content
!=
nil
{
if
input
.
Content
!=
nil
{
content
:=
strings
.
TrimSpace
(
*
input
.
Content
)
content
:=
strings
.
TrimSpace
(
*
input
.
Content
)
if
content
==
""
{
if
content
==
""
{
return
nil
,
fmt
.
Errorf
(
"update a
nnouncement
: c
ontent
is r
equired
"
)
return
nil
,
ErrA
nnouncement
C
ontent
R
equired
}
}
a
.
Content
=
content
a
.
Content
=
content
}
}
if
input
.
Status
!=
nil
{
if
input
.
Status
!=
nil
{
status
:=
strings
.
TrimSpace
(
*
input
.
Status
)
status
:=
strings
.
TrimSpace
(
*
input
.
Status
)
if
!
isValidAnnouncementStatus
(
status
)
{
if
!
isValidAnnouncementStatus
(
status
)
{
return
nil
,
fmt
.
Errorf
(
"update a
nnouncement
: i
nvalid
s
tatus
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
S
tatus
}
}
a
.
Status
=
status
a
.
Status
=
status
}
}
...
@@ -164,7 +164,7 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
...
@@ -164,7 +164,7 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
if
input
.
NotifyMode
!=
nil
{
if
input
.
NotifyMode
!=
nil
{
notifyMode
:=
strings
.
TrimSpace
(
*
input
.
NotifyMode
)
notifyMode
:=
strings
.
TrimSpace
(
*
input
.
NotifyMode
)
if
!
isValidAnnouncementNotifyMode
(
notifyMode
)
{
if
!
isValidAnnouncementNotifyMode
(
notifyMode
)
{
return
nil
,
fmt
.
Errorf
(
"update a
nnouncement
: i
nvalid
n
otify
_m
ode
"
)
return
nil
,
ErrA
nnouncement
I
nvalid
N
otify
M
ode
}
}
a
.
NotifyMode
=
notifyMode
a
.
NotifyMode
=
notifyMode
}
}
...
@@ -186,7 +186,7 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
...
@@ -186,7 +186,7 @@ func (s *AnnouncementService) Update(ctx context.Context, id int64, input *Updat
if
a
.
StartsAt
!=
nil
&&
a
.
EndsAt
!=
nil
{
if
a
.
StartsAt
!=
nil
&&
a
.
EndsAt
!=
nil
{
if
!
a
.
StartsAt
.
Before
(
*
a
.
EndsAt
)
{
if
!
a
.
StartsAt
.
Before
(
*
a
.
EndsAt
)
{
return
nil
,
fmt
.
Errorf
(
"update announcement: starts_at must be before ends_at"
)
return
nil
,
ErrAnnouncementInvalidSchedule
}
}
}
}
...
...
backend/internal/service/announcement_service_test.go
0 → 100644
View file @
89d09838
package
service
import
(
"context"
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/stretchr/testify/require"
)
type
announcementRepoStub
struct
{
item
*
Announcement
}
func
(
s
*
announcementRepoStub
)
Create
(
_
context
.
Context
,
a
*
Announcement
)
error
{
s
.
item
=
a
return
nil
}
func
(
s
*
announcementRepoStub
)
GetByID
(
_
context
.
Context
,
_
int64
)
(
*
Announcement
,
error
)
{
if
s
.
item
==
nil
{
return
nil
,
ErrAnnouncementNotFound
}
return
s
.
item
,
nil
}
func
(
s
*
announcementRepoStub
)
Update
(
_
context
.
Context
,
a
*
Announcement
)
error
{
s
.
item
=
a
return
nil
}
func
(
*
announcementRepoStub
)
Delete
(
context
.
Context
,
int64
)
error
{
return
nil
}
func
(
*
announcementRepoStub
)
List
(
context
.
Context
,
pagination
.
PaginationParams
,
AnnouncementListFilters
)
([]
Announcement
,
*
pagination
.
PaginationResult
,
error
)
{
return
nil
,
nil
,
nil
}
func
(
*
announcementRepoStub
)
ListActive
(
context
.
Context
,
time
.
Time
)
([]
Announcement
,
error
)
{
return
nil
,
nil
}
func
TestAnnouncementServiceCreateRejectsEqualStartEndTimes
(
t
*
testing
.
T
)
{
repo
:=
&
announcementRepoStub
{}
svc
:=
NewAnnouncementService
(
repo
,
nil
,
nil
,
nil
)
now
:=
time
.
Unix
(
1776790020
,
0
)
_
,
err
:=
svc
.
Create
(
context
.
Background
(),
&
CreateAnnouncementInput
{
Title
:
"公告"
,
Content
:
"内容"
,
Status
:
AnnouncementStatusActive
,
NotifyMode
:
AnnouncementNotifyModePopup
,
StartsAt
:
&
now
,
EndsAt
:
&
now
,
})
require
.
ErrorIs
(
t
,
err
,
ErrAnnouncementInvalidSchedule
)
}
func
TestAnnouncementServiceUpdateRejectsEqualStartEndTimes
(
t
*
testing
.
T
)
{
repo
:=
&
announcementRepoStub
{
item
:
&
Announcement
{
ID
:
1
,
Title
:
"公告"
,
Content
:
"内容"
,
Status
:
AnnouncementStatusActive
,
NotifyMode
:
AnnouncementNotifyModePopup
,
},
}
svc
:=
NewAnnouncementService
(
repo
,
nil
,
nil
,
nil
)
now
:=
time
.
Unix
(
1776790020
,
0
)
startsAt
:=
&
now
endsAt
:=
&
now
_
,
err
:=
svc
.
Update
(
context
.
Background
(),
1
,
&
UpdateAnnouncementInput
{
StartsAt
:
&
startsAt
,
EndsAt
:
&
endsAt
,
})
require
.
ErrorIs
(
t
,
err
,
ErrAnnouncementInvalidSchedule
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment