fixtures.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package testutil
  2. import (
  3. "embed"
  4. "gogs.dmsc.dev/arp/models"
  5. "gorm.io/driver/sqlite"
  6. "gorm.io/gorm"
  7. )
  8. //go:embed init_tests.sql
  9. var initSQLFS embed.FS
  10. // SetupTestDB creates an in-memory SQLite database for testing
  11. func SetupTestDB() (*gorm.DB, error) {
  12. db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
  13. if err != nil {
  14. return nil, err
  15. }
  16. // Run auto-migration for all models
  17. err = db.AutoMigrate(
  18. &models.User{},
  19. &models.Role{},
  20. &models.Permission{},
  21. &models.Service{},
  22. &models.Task{},
  23. &models.TaskStatus{},
  24. &models.Message{},
  25. &models.Note{},
  26. )
  27. if err != nil {
  28. return nil, err
  29. }
  30. return db, nil
  31. }
  32. // BootstrapTestDB initializes the database with initial data from init_tests.sql
  33. func BootstrapTestDB(db *gorm.DB) error {
  34. // Read the init SQL file
  35. sqlContent, err := initSQLFS.ReadFile("init_tests.sql")
  36. if err != nil {
  37. return err
  38. }
  39. // Execute the SQL
  40. return db.Exec(string(sqlContent)).Error
  41. }
  42. // SetupAndBootstrapTestDB creates an in-memory database and bootstraps it with initial data
  43. func SetupAndBootstrapTestDB() (*gorm.DB, error) {
  44. db, err := SetupTestDB()
  45. if err != nil {
  46. return nil, err
  47. }
  48. if err := BootstrapTestDB(db); err != nil {
  49. return nil, err
  50. }
  51. return db, nil
  52. }
  53. // SeedData contains all hardcoded test fixtures
  54. type SeedData struct {
  55. Permissions []PermissionFixture
  56. Roles []RoleFixture
  57. Users []UserFixture
  58. TaskStatuses []TaskStatusFixture
  59. Services []ServiceFixture
  60. Tasks []TaskFixture
  61. Notes []NoteFixture
  62. Messages []MessageFixture
  63. }
  64. // PermissionFixture represents test permission data
  65. type PermissionFixture struct {
  66. Code string
  67. Description string
  68. }
  69. // RoleFixture represents test role data
  70. type RoleFixture struct {
  71. Name string
  72. Description string
  73. PermissionCodes []string
  74. }
  75. // UserFixture represents test user data
  76. type UserFixture struct {
  77. Email string
  78. Password string
  79. RoleNames []string
  80. }
  81. // TaskStatusFixture represents test task status data
  82. type TaskStatusFixture struct {
  83. Code string
  84. Label string
  85. }
  86. // ServiceFixture represents test service data
  87. type ServiceFixture struct {
  88. Name string
  89. Description string
  90. CreatorEmail string
  91. ParticipantEmails []string
  92. }
  93. // TaskFixture represents test task data
  94. type TaskFixture struct {
  95. Title string
  96. Content string
  97. CreatorEmail string
  98. AssigneeEmail string
  99. StatusCode string
  100. Priority string
  101. }
  102. // NoteFixture represents test note data
  103. type NoteFixture struct {
  104. Title string
  105. Content string
  106. UserEmail string
  107. ServiceName string
  108. }
  109. // MessageFixture represents test message data
  110. type MessageFixture struct {
  111. SenderEmail string
  112. Content string
  113. ReceiverEmails []string
  114. }
  115. // GetSeedData returns the hardcoded seed data for testing
  116. func GetSeedData() SeedData {
  117. return SeedData{
  118. Permissions: []PermissionFixture{
  119. {Code: "user:read", Description: "Read user information"},
  120. {Code: "user:write", Description: "Create and update users"},
  121. {Code: "task:read", Description: "Read task information"},
  122. {Code: "task:write", Description: "Create and update tasks"},
  123. {Code: "service:read", Description: "Read service information"},
  124. {Code: "service:write", Description: "Create and update services"},
  125. {Code: "note:read", Description: "Read notes"},
  126. {Code: "note:write", Description: "Create and update notes"},
  127. },
  128. Roles: []RoleFixture{
  129. {
  130. Name: "admin",
  131. Description: "Administrator with full access",
  132. PermissionCodes: []string{"user:read", "user:write", "task:read", "task:write", "service:read", "service:write", "note:read", "note:write"},
  133. },
  134. {
  135. Name: "member",
  136. Description: "Team member with read access and limited write access",
  137. PermissionCodes: []string{"user:read", "task:read", "task:write", "service:read", "note:read", "note:write"},
  138. },
  139. {
  140. Name: "viewer",
  141. Description: "Read-only access",
  142. PermissionCodes: []string{"user:read", "task:read", "service:read", "note:read"},
  143. },
  144. },
  145. Users: []UserFixture{
  146. // Note: admin@example.com is bootstrapped via init_tests.sql
  147. {
  148. Email: "member1@example.com",
  149. Password: "member1-hashed-password",
  150. RoleNames: []string{"member"},
  151. },
  152. {
  153. Email: "member2@example.com",
  154. Password: "member2-hashed-password",
  155. RoleNames: []string{"member"},
  156. },
  157. {
  158. Email: "viewer@example.com",
  159. Password: "viewer-hashed-password",
  160. RoleNames: []string{"viewer"},
  161. },
  162. },
  163. TaskStatuses: []TaskStatusFixture{
  164. {Code: "open", Label: "Open"},
  165. {Code: "in_progress", Label: "In Progress"},
  166. {Code: "review", Label: "Under Review"},
  167. {Code: "done", Label: "Completed"},
  168. },
  169. Services: []ServiceFixture{
  170. {
  171. Name: "Project Alpha",
  172. Description: "Main project for alpha development",
  173. CreatorEmail: "admin@example.com",
  174. ParticipantEmails: []string{"admin@example.com", "member1@example.com", "member2@example.com"},
  175. },
  176. {
  177. Name: "Project Beta",
  178. Description: "Secondary project for beta testing",
  179. CreatorEmail: "admin@example.com",
  180. ParticipantEmails: []string{"member1@example.com", "viewer@example.com"},
  181. },
  182. },
  183. Tasks: []TaskFixture{
  184. {
  185. Title: "Setup development environment",
  186. Content: "Initialize the development environment with all required tools and dependencies",
  187. CreatorEmail: "admin@example.com",
  188. AssigneeEmail: "member1@example.com",
  189. StatusCode: "done",
  190. Priority: "high",
  191. },
  192. {
  193. Title: "Implement user authentication",
  194. Content: "Create the authentication module with login, logout, and password reset functionality",
  195. CreatorEmail: "admin@example.com",
  196. AssigneeEmail: "member1@example.com",
  197. StatusCode: "in_progress",
  198. Priority: "high",
  199. },
  200. {
  201. Title: "Write API documentation",
  202. Content: "Document all API endpoints with request/response examples",
  203. CreatorEmail: "member1@example.com",
  204. AssigneeEmail: "member2@example.com",
  205. StatusCode: "review",
  206. Priority: "medium",
  207. },
  208. {
  209. Title: "Setup CI/CD pipeline",
  210. Content: "Configure continuous integration and deployment pipeline",
  211. CreatorEmail: "admin@example.com",
  212. AssigneeEmail: "",
  213. StatusCode: "open",
  214. Priority: "medium",
  215. },
  216. {
  217. Title: "Performance optimization",
  218. Content: "Optimize database queries and implement caching",
  219. CreatorEmail: "member2@example.com",
  220. AssigneeEmail: "",
  221. StatusCode: "open",
  222. Priority: "low",
  223. },
  224. },
  225. Notes: []NoteFixture{
  226. {
  227. Title: "Architecture decisions",
  228. Content: "Document key architectural decisions and their rationale",
  229. UserEmail: "admin@example.com",
  230. ServiceName: "Project Alpha",
  231. },
  232. {
  233. Title: "Meeting notes - Sprint 1",
  234. Content: "Notes from the first sprint planning meeting",
  235. UserEmail: "member1@example.com",
  236. ServiceName: "Project Alpha",
  237. },
  238. {
  239. Title: "Testing strategy",
  240. Content: "Outline the testing approach for the beta release",
  241. UserEmail: "member1@example.com",
  242. ServiceName: "Project Beta",
  243. },
  244. },
  245. Messages: []MessageFixture{
  246. {
  247. SenderEmail: "admin@example.com",
  248. Content: "Welcome to the project channel!",
  249. ReceiverEmails: []string{"member1@example.com"},
  250. },
  251. {
  252. SenderEmail: "member1@example.com",
  253. Content: "Thanks! Excited to get started.",
  254. ReceiverEmails: []string{"admin@example.com"},
  255. },
  256. {
  257. SenderEmail: "member1@example.com",
  258. Content: "Hey, let us discuss the API documentation.",
  259. ReceiverEmails: []string{"member2@example.com"},
  260. },
  261. {
  262. SenderEmail: "member2@example.com",
  263. Content: "Sure, I will start drafting it today.",
  264. ReceiverEmails: []string{"member1@example.com"},
  265. },
  266. {
  267. SenderEmail: "admin@example.com",
  268. Content: "Team announcement: Sprint review tomorrow at 2pm.",
  269. ReceiverEmails: []string{"member1@example.com", "member2@example.com", "viewer@example.com"},
  270. },
  271. },
  272. }
  273. }