fixtures_integration_test.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. //go:build integration
  2. package repository
  3. import (
  4. "context"
  5. "testing"
  6. "time"
  7. dbent "github.com/Wei-Shaw/sub2api/ent"
  8. dbaccount "github.com/Wei-Shaw/sub2api/ent/account"
  9. "github.com/Wei-Shaw/sub2api/internal/service"
  10. "github.com/stretchr/testify/require"
  11. )
  12. func mustCreateUser(t *testing.T, client *dbent.Client, u *service.User) *service.User {
  13. t.Helper()
  14. ctx := context.Background()
  15. if u.Email == "" {
  16. u.Email = "user-" + time.Now().Format(time.RFC3339Nano) + "@example.com"
  17. }
  18. if u.PasswordHash == "" {
  19. u.PasswordHash = "test-password-hash"
  20. }
  21. if u.Role == "" {
  22. u.Role = service.RoleUser
  23. }
  24. if u.Status == "" {
  25. u.Status = service.StatusActive
  26. }
  27. if u.Concurrency == 0 {
  28. u.Concurrency = 5
  29. }
  30. create := client.User.Create().
  31. SetEmail(u.Email).
  32. SetPasswordHash(u.PasswordHash).
  33. SetRole(u.Role).
  34. SetStatus(u.Status).
  35. SetBalance(u.Balance).
  36. SetConcurrency(u.Concurrency).
  37. SetUsername(u.Username).
  38. SetNotes(u.Notes)
  39. if !u.CreatedAt.IsZero() {
  40. create.SetCreatedAt(u.CreatedAt)
  41. }
  42. if !u.UpdatedAt.IsZero() {
  43. create.SetUpdatedAt(u.UpdatedAt)
  44. }
  45. created, err := create.Save(ctx)
  46. require.NoError(t, err, "create user")
  47. u.ID = created.ID
  48. u.CreatedAt = created.CreatedAt
  49. u.UpdatedAt = created.UpdatedAt
  50. if len(u.AllowedGroups) > 0 {
  51. for _, groupID := range u.AllowedGroups {
  52. _, err := client.UserAllowedGroup.Create().
  53. SetUserID(u.ID).
  54. SetGroupID(groupID).
  55. Save(ctx)
  56. require.NoError(t, err, "create user_allowed_groups row")
  57. }
  58. }
  59. return u
  60. }
  61. func mustCreateGroup(t *testing.T, client *dbent.Client, g *service.Group) *service.Group {
  62. t.Helper()
  63. ctx := context.Background()
  64. if g.Platform == "" {
  65. g.Platform = service.PlatformAnthropic
  66. }
  67. if g.Status == "" {
  68. g.Status = service.StatusActive
  69. }
  70. if g.SubscriptionType == "" {
  71. g.SubscriptionType = service.SubscriptionTypeStandard
  72. }
  73. create := client.Group.Create().
  74. SetName(g.Name).
  75. SetPlatform(g.Platform).
  76. SetStatus(g.Status).
  77. SetSubscriptionType(g.SubscriptionType).
  78. SetRateMultiplier(g.RateMultiplier).
  79. SetIsExclusive(g.IsExclusive).
  80. SetForceOpenaiFast(g.ForceOpenAIFast).
  81. SetFreeOpenaiFast(g.FreeOpenAIFast).
  82. SetModelAllowlist(service.DomainGroupModelAllowlist(g.ModelAllowlist)).
  83. SetCodexModelsManifestConfig(g.CodexModelsManifestConfig).
  84. SetProfitControlEnabled(g.ProfitControlEnabled).
  85. SetProfitMinMargin(g.ProfitMinMargin).
  86. SetProfitSafetyBuffer(g.ProfitSafetyBuffer)
  87. if g.Description != "" {
  88. create.SetDescription(g.Description)
  89. }
  90. if g.DailyLimitUSD != nil {
  91. create.SetDailyLimitUsd(*g.DailyLimitUSD)
  92. }
  93. if g.WeeklyLimitUSD != nil {
  94. create.SetWeeklyLimitUsd(*g.WeeklyLimitUSD)
  95. }
  96. if g.MonthlyLimitUSD != nil {
  97. create.SetMonthlyLimitUsd(*g.MonthlyLimitUSD)
  98. }
  99. if !g.CreatedAt.IsZero() {
  100. create.SetCreatedAt(g.CreatedAt)
  101. }
  102. if !g.UpdatedAt.IsZero() {
  103. create.SetUpdatedAt(g.UpdatedAt)
  104. }
  105. created, err := create.Save(ctx)
  106. require.NoError(t, err, "create group")
  107. g.ID = created.ID
  108. g.CreatedAt = created.CreatedAt
  109. g.UpdatedAt = created.UpdatedAt
  110. return g
  111. }
  112. func mustCreateProxy(t *testing.T, client *dbent.Client, p *service.Proxy) *service.Proxy {
  113. t.Helper()
  114. ctx := context.Background()
  115. if p.Protocol == "" {
  116. p.Protocol = "http"
  117. }
  118. if p.Host == "" {
  119. p.Host = "127.0.0.1"
  120. }
  121. if p.Port == 0 {
  122. p.Port = 8080
  123. }
  124. if p.Status == "" {
  125. p.Status = service.StatusActive
  126. }
  127. create := client.Proxy.Create().
  128. SetName(p.Name).
  129. SetProtocol(p.Protocol).
  130. SetHost(p.Host).
  131. SetPort(p.Port).
  132. SetStatus(p.Status)
  133. if p.Username != "" {
  134. create.SetUsername(p.Username)
  135. }
  136. if p.Password != "" {
  137. create.SetPassword(p.Password)
  138. }
  139. if !p.CreatedAt.IsZero() {
  140. create.SetCreatedAt(p.CreatedAt)
  141. }
  142. if !p.UpdatedAt.IsZero() {
  143. create.SetUpdatedAt(p.UpdatedAt)
  144. }
  145. created, err := create.Save(ctx)
  146. require.NoError(t, err, "create proxy")
  147. p.ID = created.ID
  148. p.CreatedAt = created.CreatedAt
  149. p.UpdatedAt = created.UpdatedAt
  150. return p
  151. }
  152. func mustCreateAccount(t *testing.T, client *dbent.Client, a *service.Account) *service.Account {
  153. t.Helper()
  154. ctx := context.Background()
  155. if a.Platform == "" {
  156. a.Platform = service.PlatformAnthropic
  157. }
  158. if a.Type == "" {
  159. a.Type = service.AccountTypeOAuth
  160. }
  161. if a.Status == "" {
  162. a.Status = service.StatusActive
  163. }
  164. if a.Concurrency == 0 {
  165. a.Concurrency = 3
  166. }
  167. if a.Priority == 0 {
  168. a.Priority = 50
  169. }
  170. if !a.Schedulable {
  171. a.Schedulable = true
  172. }
  173. if a.Credentials == nil {
  174. a.Credentials = map[string]any{}
  175. }
  176. if a.Extra == nil {
  177. a.Extra = map[string]any{}
  178. }
  179. create := client.Account.Create().
  180. SetName(a.Name).
  181. SetPlatform(a.Platform).
  182. SetType(a.Type).
  183. SetCredentials(a.Credentials).
  184. SetExtra(a.Extra).
  185. SetConcurrency(a.Concurrency).
  186. SetPriority(a.Priority).
  187. SetStatus(a.Status).
  188. SetSchedulable(a.Schedulable).
  189. SetErrorMessage(a.ErrorMessage)
  190. if a.ProxyID != nil {
  191. create.SetProxyID(*a.ProxyID)
  192. }
  193. if a.LastUsedAt != nil {
  194. create.SetLastUsedAt(*a.LastUsedAt)
  195. }
  196. if a.RateLimitedAt != nil {
  197. create.SetRateLimitedAt(*a.RateLimitedAt)
  198. }
  199. if a.RateLimitResetAt != nil {
  200. create.SetRateLimitResetAt(*a.RateLimitResetAt)
  201. }
  202. if a.OverloadUntil != nil {
  203. create.SetOverloadUntil(*a.OverloadUntil)
  204. }
  205. if a.SessionWindowStart != nil {
  206. create.SetSessionWindowStart(*a.SessionWindowStart)
  207. }
  208. if a.SessionWindowEnd != nil {
  209. create.SetSessionWindowEnd(*a.SessionWindowEnd)
  210. }
  211. if a.SessionWindowStatus != "" {
  212. create.SetSessionWindowStatus(a.SessionWindowStatus)
  213. }
  214. if !a.CreatedAt.IsZero() {
  215. create.SetCreatedAt(a.CreatedAt)
  216. }
  217. if !a.UpdatedAt.IsZero() {
  218. create.SetUpdatedAt(a.UpdatedAt)
  219. }
  220. if a.ParentAccountID != nil {
  221. create.SetParentAccountID(*a.ParentAccountID)
  222. }
  223. if a.QuotaDimension != "" {
  224. create.SetQuotaDimension(dbaccount.QuotaDimension(a.QuotaDimension))
  225. }
  226. created, err := create.Save(ctx)
  227. require.NoError(t, err, "create account")
  228. a.ID = created.ID
  229. a.CreatedAt = created.CreatedAt
  230. a.UpdatedAt = created.UpdatedAt
  231. return a
  232. }
  233. func mustCreateApiKey(t *testing.T, client *dbent.Client, k *service.APIKey) *service.APIKey {
  234. t.Helper()
  235. ctx := context.Background()
  236. if k.Status == "" {
  237. k.Status = service.StatusActive
  238. }
  239. if k.Key == "" {
  240. k.Key = "sk-" + time.Now().Format("150405.000000")
  241. }
  242. if k.Name == "" {
  243. k.Name = "default"
  244. }
  245. create := client.APIKey.Create().
  246. SetUserID(k.UserID).
  247. SetKey(k.Key).
  248. SetName(k.Name).
  249. SetStatus(k.Status)
  250. if k.Quota != 0 {
  251. create.SetQuota(k.Quota)
  252. }
  253. if k.QuotaUsed != 0 {
  254. create.SetQuotaUsed(k.QuotaUsed)
  255. }
  256. if k.RateLimit5h != 0 {
  257. create.SetRateLimit5h(k.RateLimit5h)
  258. }
  259. if k.RateLimit1d != 0 {
  260. create.SetRateLimit1d(k.RateLimit1d)
  261. }
  262. if k.RateLimit7d != 0 {
  263. create.SetRateLimit7d(k.RateLimit7d)
  264. }
  265. if k.Usage5h != 0 {
  266. create.SetUsage5h(k.Usage5h)
  267. }
  268. if k.Usage1d != 0 {
  269. create.SetUsage1d(k.Usage1d)
  270. }
  271. if k.Usage7d != 0 {
  272. create.SetUsage7d(k.Usage7d)
  273. }
  274. if k.Window5hStart != nil {
  275. create.SetWindow5hStart(*k.Window5hStart)
  276. }
  277. if k.Window1dStart != nil {
  278. create.SetWindow1dStart(*k.Window1dStart)
  279. }
  280. if k.Window7dStart != nil {
  281. create.SetWindow7dStart(*k.Window7dStart)
  282. }
  283. if k.ExpiresAt != nil {
  284. create.SetExpiresAt(*k.ExpiresAt)
  285. }
  286. if k.GroupID != nil {
  287. create.SetGroupID(*k.GroupID)
  288. }
  289. if !k.CreatedAt.IsZero() {
  290. create.SetCreatedAt(k.CreatedAt)
  291. }
  292. if !k.UpdatedAt.IsZero() {
  293. create.SetUpdatedAt(k.UpdatedAt)
  294. }
  295. created, err := create.Save(ctx)
  296. require.NoError(t, err, "create api key")
  297. k.ID = created.ID
  298. k.CreatedAt = created.CreatedAt
  299. k.UpdatedAt = created.UpdatedAt
  300. return k
  301. }
  302. func mustCreateRedeemCode(t *testing.T, client *dbent.Client, c *service.RedeemCode) *service.RedeemCode {
  303. t.Helper()
  304. ctx := context.Background()
  305. if c.Status == "" {
  306. c.Status = service.StatusUnused
  307. }
  308. if c.Type == "" {
  309. c.Type = service.RedeemTypeBalance
  310. }
  311. if c.Code == "" {
  312. c.Code = "rc-" + time.Now().Format("150405.000000")
  313. }
  314. create := client.RedeemCode.Create().
  315. SetCode(c.Code).
  316. SetType(c.Type).
  317. SetValue(c.Value).
  318. SetStatus(c.Status).
  319. SetNotes(c.Notes).
  320. SetValidityDays(c.ValidityDays)
  321. if c.UsedBy != nil {
  322. create.SetUsedBy(*c.UsedBy)
  323. }
  324. if c.UsedAt != nil {
  325. create.SetUsedAt(*c.UsedAt)
  326. }
  327. if c.GroupID != nil {
  328. create.SetGroupID(*c.GroupID)
  329. }
  330. if !c.CreatedAt.IsZero() {
  331. create.SetCreatedAt(c.CreatedAt)
  332. }
  333. created, err := create.Save(ctx)
  334. require.NoError(t, err, "create redeem code")
  335. c.ID = created.ID
  336. c.CreatedAt = created.CreatedAt
  337. return c
  338. }
  339. func mustCreateSubscription(t *testing.T, client *dbent.Client, s *service.UserSubscription) *service.UserSubscription {
  340. t.Helper()
  341. ctx := context.Background()
  342. if s.Status == "" {
  343. s.Status = service.SubscriptionStatusActive
  344. }
  345. now := time.Now()
  346. if s.StartsAt.IsZero() {
  347. s.StartsAt = now.Add(-1 * time.Hour)
  348. }
  349. if s.ExpiresAt.IsZero() {
  350. s.ExpiresAt = now.Add(24 * time.Hour)
  351. }
  352. if s.AssignedAt.IsZero() {
  353. s.AssignedAt = now
  354. }
  355. if s.CreatedAt.IsZero() {
  356. s.CreatedAt = now
  357. }
  358. if s.UpdatedAt.IsZero() {
  359. s.UpdatedAt = now
  360. }
  361. create := client.UserSubscription.Create().
  362. SetUserID(s.UserID).
  363. SetGroupID(s.GroupID).
  364. SetStartsAt(s.StartsAt).
  365. SetExpiresAt(s.ExpiresAt).
  366. SetStatus(s.Status).
  367. SetAssignedAt(s.AssignedAt).
  368. SetNotes(s.Notes).
  369. SetDailyUsageUsd(s.DailyUsageUSD).
  370. SetWeeklyUsageUsd(s.WeeklyUsageUSD).
  371. SetMonthlyUsageUsd(s.MonthlyUsageUSD)
  372. if s.AssignedBy != nil {
  373. create.SetAssignedBy(*s.AssignedBy)
  374. }
  375. if !s.CreatedAt.IsZero() {
  376. create.SetCreatedAt(s.CreatedAt)
  377. }
  378. if !s.UpdatedAt.IsZero() {
  379. create.SetUpdatedAt(s.UpdatedAt)
  380. }
  381. created, err := create.Save(ctx)
  382. require.NoError(t, err, "create user subscription")
  383. s.ID = created.ID
  384. s.CreatedAt = created.CreatedAt
  385. s.UpdatedAt = created.UpdatedAt
  386. return s
  387. }
  388. func mustBindAccountToGroup(t *testing.T, client *dbent.Client, accountID, groupID int64, priority int) {
  389. t.Helper()
  390. ctx := context.Background()
  391. _, err := client.AccountGroup.Create().
  392. SetAccountID(accountID).
  393. SetGroupID(groupID).
  394. SetPriority(priority).
  395. Save(ctx)
  396. require.NoError(t, err, "create account_group")
  397. }