github.com/adharshmk96/stk@v1.2.3/pkg/sqlMigrator/migrate_test.go (about) 1 package sqlmigrator_test 2 3 import ( 4 "os" 5 "path" 6 "testing" 7 8 "github.com/adharshmk96/stk/mocks" 9 sqlmigrator "github.com/adharshmk96/stk/pkg/sqlMigrator" 10 "github.com/adharshmk96/stk/testutils" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/mock" 13 ) 14 15 func checkUnappliedMigrations(t *testing.T, ctx *sqlmigrator.Context, expected int) { 16 unappliedMigrations := sqlmigrator.LoadUnappliedMigrations(ctx) 17 assert.Equal(t, expected, len(unappliedMigrations)) 18 } 19 20 func TestMigrateUp(t *testing.T) { 21 22 var LOG_FILE_CONTENT = `1_create_users_table_up 23 2_create_posts_table_up 24 3_create_comments_table_up 25 4_create_likes_table_down 26 5_create_followers_table_down 27 6_create_messages_table_down 28 ` 29 30 t.Run("migrate up default all unapplied migrations", func(t *testing.T) { 31 tempDir, removeDir := testutils.CreateTempDirectory(t) 32 33 defer removeDir() 34 35 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 36 37 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 38 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 39 assert.NoError(t, err) 40 err = ctx.LoadMigrationEntries() 41 assert.NoError(t, err) 42 checkUnappliedMigrations(t, ctx, 3) 43 44 dbMock := mocks.NewDBRepo(t) 45 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 46 dbMock.On("PushHistory", mock.Anything).Return(nil) 47 48 migrator := sqlmigrator.NewMigrator(dbMock) 49 appliedMigrations, err := migrator.MigrateUp(ctx, 0) 50 assert.NoError(t, err) 51 assert.Equal(t, 3, len(appliedMigrations)) 52 53 expected := []string{ 54 "4_create_likes_table_up", 55 "5_create_followers_table_up", 56 "6_create_messages_table_up", 57 } 58 59 for i, migration := range appliedMigrations { 60 assert.True(t, migration.Committed) 61 assert.Equal(t, expected[i], migration.EntryString()) 62 } 63 64 checkUnappliedMigrations(t, ctx, 0) 65 }) 66 67 t.Run("migrate up given number of unapplied migration", func(t *testing.T) { 68 tempDir, removeDir := testutils.CreateTempDirectory(t) 69 70 defer removeDir() 71 72 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 73 74 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 75 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 76 assert.NoError(t, err) 77 err = ctx.LoadMigrationEntries() 78 assert.NoError(t, err) 79 checkUnappliedMigrations(t, ctx, 3) 80 81 dbMock := mocks.NewDBRepo(t) 82 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 83 dbMock.On("PushHistory", mock.Anything).Return(nil) 84 85 migrator := sqlmigrator.NewMigrator(dbMock) 86 appliedMigrations, err := migrator.MigrateUp(ctx, 1) 87 assert.NoError(t, err) 88 89 assert.Equal(t, 1, len(appliedMigrations)) 90 91 expected := []string{ 92 "4_create_likes_table_up", 93 } 94 95 for i, migration := range appliedMigrations { 96 assert.True(t, migration.Committed) 97 assert.Equal(t, expected[i], migration.EntryString()) 98 } 99 100 // Check unapplied migrations 101 checkUnappliedMigrations(t, ctx, 2) 102 }) 103 104 t.Run("migrate up won't update commit for dry run", func(t *testing.T) { 105 tempDir, removeDir := testutils.CreateTempDirectory(t) 106 107 defer removeDir() 108 109 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", true) 110 111 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 112 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 113 assert.NoError(t, err) 114 err = ctx.LoadMigrationEntries() 115 assert.NoError(t, err) 116 checkUnappliedMigrations(t, ctx, 3) 117 118 dbMock := mocks.NewDBRepo(t) 119 120 migrator := sqlmigrator.NewMigrator(dbMock) 121 appliedMigrations, err := migrator.MigrateUp(ctx, 0) 122 assert.NoError(t, err) 123 124 assert.Equal(t, 0, len(appliedMigrations)) 125 126 checkUnappliedMigrations(t, ctx, 3) 127 128 }) 129 130 t.Run("migrate up runs fine with outof bound values", func(t *testing.T) { 131 tempDir, removeDir := testutils.CreateTempDirectory(t) 132 133 defer removeDir() 134 135 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 136 137 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 138 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 139 assert.NoError(t, err) 140 err = ctx.LoadMigrationEntries() 141 assert.NoError(t, err) 142 checkUnappliedMigrations(t, ctx, 3) 143 144 dbMock := mocks.NewDBRepo(t) 145 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 146 dbMock.On("PushHistory", mock.Anything).Return(nil) 147 148 migrator := sqlmigrator.NewMigrator(dbMock) 149 appliedMigrations, err := migrator.MigrateUp(ctx, 0) 150 assert.NoError(t, err) 151 152 assert.Equal(t, 3, len(appliedMigrations)) 153 154 checkUnappliedMigrations(t, ctx, 0) 155 }) 156 157 t.Run("migrate up runs fine with no unapplied migrations", func(t *testing.T) { 158 tempDir, removeDir := testutils.CreateTempDirectory(t) 159 160 defer removeDir() 161 162 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 163 164 checkUnappliedMigrations(t, ctx, 0) 165 166 dbMock := mocks.NewDBRepo(t) 167 168 migrator := sqlmigrator.NewMigrator(dbMock) 169 appliedMigrations, err := migrator.MigrateUp(ctx, 0) 170 assert.NoError(t, err) 171 172 assert.Equal(t, 0, len(appliedMigrations)) 173 174 checkUnappliedMigrations(t, ctx, 0) 175 }) 176 } 177 178 func TestMigrateDown(t *testing.T) { 179 180 var LOG_FILE_CONTENT = `1_create_users_table_up 181 2_create_posts_table_up 182 3_create_comments_table_up 183 4_create_likes_table_down 184 5_create_followers_table_down 185 6_create_messages_table_down 186 ` 187 188 t.Run("migrate down default all unapplied migrations", func(t *testing.T) { 189 tempDir, removeDir := testutils.CreateTempDirectory(t) 190 191 defer removeDir() 192 193 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 194 195 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 196 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 197 assert.NoError(t, err) 198 199 err = ctx.LoadMigrationEntries() 200 assert.NoError(t, err) 201 202 checkUnappliedMigrations(t, ctx, 3) 203 204 dbMock := mocks.NewDBRepo(t) 205 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 206 dbMock.On("PushHistory", mock.Anything).Return(nil) 207 208 migrator := sqlmigrator.NewMigrator(dbMock) 209 appliedMigrations, err := migrator.MigrateDown(ctx, 0) 210 assert.NoError(t, err) 211 assert.Equal(t, 3, len(appliedMigrations)) 212 213 expected := []string{ 214 "3_create_comments_table_down", 215 "2_create_posts_table_down", 216 "1_create_users_table_down", 217 } 218 219 for i, migration := range appliedMigrations { 220 assert.False(t, migration.Committed) 221 assert.Equal(t, expected[i], migration.EntryString()) 222 } 223 224 checkUnappliedMigrations(t, ctx, 6) 225 }) 226 227 t.Run("migrate down given number of unapplied migration", func(t *testing.T) { 228 tempDir, removeDir := testutils.CreateTempDirectory(t) 229 230 defer removeDir() 231 232 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 233 234 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 235 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 236 assert.NoError(t, err) 237 238 err = ctx.LoadMigrationEntries() 239 assert.NoError(t, err) 240 241 checkUnappliedMigrations(t, ctx, 3) 242 243 dbMock := mocks.NewDBRepo(t) 244 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 245 dbMock.On("PushHistory", mock.Anything).Return(nil) 246 247 migrator := sqlmigrator.NewMigrator(dbMock) 248 appliedMigrations, err := migrator.MigrateDown(ctx, 1) 249 assert.NoError(t, err) 250 251 assert.Equal(t, 1, len(appliedMigrations)) 252 253 expected := []string{ 254 "3_create_comments_table_down", 255 } 256 257 for i, migration := range appliedMigrations { 258 assert.False(t, migration.Committed) 259 assert.Equal(t, expected[i], migration.EntryString()) 260 } 261 262 // Check unapplied migrations 263 checkUnappliedMigrations(t, ctx, 4) 264 }) 265 266 t.Run("migrate down won't update commit for dry run", func(t *testing.T) { 267 tempDir, removeDir := testutils.CreateTempDirectory(t) 268 269 defer removeDir() 270 271 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", true) 272 273 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 274 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 275 assert.NoError(t, err) 276 277 err = ctx.LoadMigrationEntries() 278 assert.NoError(t, err) 279 280 checkUnappliedMigrations(t, ctx, 3) 281 282 dbMock := mocks.NewDBRepo(t) 283 284 migrator := sqlmigrator.NewMigrator(dbMock) 285 appliedMigrations, err := migrator.MigrateDown(ctx, 0) 286 assert.NoError(t, err) 287 288 assert.Equal(t, 0, len(appliedMigrations)) 289 290 checkUnappliedMigrations(t, ctx, 3) 291 }) 292 293 t.Run("migrate down runs fine with outof bound values", func(t *testing.T) { 294 tempDir, removeDir := testutils.CreateTempDirectory(t) 295 296 defer removeDir() 297 298 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 299 300 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 301 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 302 assert.NoError(t, err) 303 304 err = ctx.LoadMigrationEntries() 305 assert.NoError(t, err) 306 307 checkUnappliedMigrations(t, ctx, 3) 308 309 dbMock := mocks.NewDBRepo(t) 310 dbMock.On("Exec", mock.AnythingOfType("string")).Return(nil) 311 dbMock.On("PushHistory", mock.Anything).Return(nil) 312 313 migrator := sqlmigrator.NewMigrator(dbMock) 314 appliedMigrations, err := migrator.MigrateDown(ctx, 0) 315 assert.NoError(t, err) 316 317 assert.Equal(t, 3, len(appliedMigrations)) 318 319 checkUnappliedMigrations(t, ctx, 6) 320 }) 321 322 t.Run("migrate down runs fine with no unapplied migrations", func(t *testing.T) { 323 tempDir, removeDir := testutils.CreateTempDirectory(t) 324 325 defer removeDir() 326 327 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 328 329 checkUnappliedMigrations(t, ctx, 0) 330 331 dbMock := mocks.NewDBRepo(t) 332 333 migrator := sqlmigrator.NewMigrator(dbMock) 334 appliedMigrations, err := migrator.MigrateDown(ctx, 0) 335 assert.NoError(t, err) 336 337 assert.Equal(t, 0, len(appliedMigrations)) 338 339 checkUnappliedMigrations(t, ctx, 0) 340 }) 341 }