Add user profile management for smoking data
- Introduced new API endpoints `GET /api/v1/smoke/profile` and `PUT /api/v1/smoke/profile` for retrieving and updating user smoking profiles. - Added a new database table `fa_smoke_user_profile` to store user-specific smoking data, including daily smoking habits and motivations. - Updated the smoke handler and service to integrate user profile data into AI advice generation. - Enhanced documentation to reflect the new user profile features and their usage.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
smokemodel "wx_service/internal/smoke/model"
|
||||
)
|
||||
|
||||
func TestParseHHMMToMinutes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
in string
|
||||
want int
|
||||
wantErr bool
|
||||
}{
|
||||
{"00:00", 0, false},
|
||||
{"07:30", 450, false},
|
||||
{"23:59", 23*60 + 59, false},
|
||||
{"7:30", 0, true},
|
||||
{"24:00", 0, true},
|
||||
{"12:60", 0, true},
|
||||
{"ab:cd", 0, true},
|
||||
{"", 0, true},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
got, err := parseHHMMToMinutes(c.in)
|
||||
if c.wantErr {
|
||||
if err == nil {
|
||||
t.Fatalf("parseHHMMToMinutes(%q): expected error", c.in)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("parseHHMMToMinutes(%q): unexpected error: %v", c.in, err)
|
||||
}
|
||||
if got != c.want {
|
||||
t.Fatalf("parseHHMMToMinutes(%q): got %d, want %d", c.in, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAwakeMinutesWithFallback(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got, err := awakeMinutesWithFallback("07:00", "23:00")
|
||||
if err != nil {
|
||||
t.Fatalf("awakeMinutesWithFallback: %v", err)
|
||||
}
|
||||
if got != 16*60 {
|
||||
t.Fatalf("awakeMinutesWithFallback: got %d, want %d", got, 16*60)
|
||||
}
|
||||
|
||||
got, err = awakeMinutesWithFallback("08:00", "01:00")
|
||||
if err != nil {
|
||||
t.Fatalf("awakeMinutesWithFallback (cross midnight): %v", err)
|
||||
}
|
||||
if got != 17*60 {
|
||||
t.Fatalf("awakeMinutesWithFallback (cross midnight): got %d, want %d", got, 17*60)
|
||||
}
|
||||
|
||||
got, err = awakeMinutesWithFallback("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("awakeMinutesWithFallback (empty): %v", err)
|
||||
}
|
||||
if got != defaultAwakeMinutes {
|
||||
t.Fatalf("awakeMinutesWithFallback (empty): got %d, want %d", got, defaultAwakeMinutes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaselineIntervalMinutes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if got := baselineIntervalMinutes(960, 20); got != 48 {
|
||||
t.Fatalf("baselineIntervalMinutes: got %d, want %d", got, 48)
|
||||
}
|
||||
if got := baselineIntervalMinutes(10, 100); got != 1 {
|
||||
t.Fatalf("baselineIntervalMinutes: got %d, want %d", got, 1)
|
||||
}
|
||||
if got := baselineIntervalMinutes(0, 20); got != 0 {
|
||||
t.Fatalf("baselineIntervalMinutes: got %d, want %d", got, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSmokeProfileCompleted(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := smokemodel.SmokeUserProfile{
|
||||
BaselineCigsPerDay: 20,
|
||||
PackPriceCent: 2500,
|
||||
SmokeMotivations: smokemodel.StringSlice{"压力大"},
|
||||
QuitMotivations: smokemodel.StringSlice{"身体健康"},
|
||||
WakeUpTime: "07:30",
|
||||
SleepTime: "23:30",
|
||||
}
|
||||
if !isSmokeProfileCompleted(p) {
|
||||
t.Fatalf("isSmokeProfileCompleted: expected true")
|
||||
}
|
||||
p.SmokeMotivations = nil
|
||||
if isSmokeProfileCompleted(p) {
|
||||
t.Fatalf("isSmokeProfileCompleted: expected false when motivations missing")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user