1
0

fixtures.go 8.3 KB

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