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  }