github.com/lovung/GoCleanArchitecture@v0.0.0-20210302152432-50d91fd29f9f/app/internal/interface/persistence/rdbms/gormrepo/user_repository_test.go (about)

     1  package gormrepo
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/DATA-DOG/go-sqlmock"
    10  	"github.com/google/go-cmp/cmp"
    11  	"github.com/lovung/GoCleanArchitecture/app/internal/appctx"
    12  	"github.com/lovung/GoCleanArchitecture/app/internal/domain/entity"
    13  	"github.com/lovung/GoCleanArchitecture/pkg/testhelper"
    14  	"gorm.io/gorm"
    15  )
    16  
    17  func TestNewUserRepository(t *testing.T) {
    18  	testCases := []struct {
    19  		name string
    20  		want *UserRepository
    21  	}{
    22  		{
    23  			want: &UserRepository{
    24  				baseRepository: baseRepository{},
    25  			},
    26  		},
    27  	}
    28  	for _, tt := range testCases {
    29  		t.Run(tt.name, func(t *testing.T) {
    30  			if got := NewUserRepository(); !reflect.DeepEqual(got, tt.want) {
    31  				t.Errorf("NewUserRepository() = %v, want %v", got, tt.want)
    32  			}
    33  		})
    34  	}
    35  }
    36  
    37  func TestUserRepository_Create(t *testing.T) {
    38  	gDB, mock, err := testhelper.OpenDBConnection()
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	type fields struct {
    43  		baseRepository baseRepository
    44  	}
    45  	type args struct {
    46  		ctx context.Context
    47  		ent entity.User
    48  	}
    49  	type wants struct {
    50  		wantCreated entity.User
    51  		wantErr     bool
    52  	}
    53  	runFunc := func(t *testing.T, fields fields, args args, w wants) {
    54  		r := &UserRepository{
    55  			baseRepository: fields.baseRepository,
    56  		}
    57  		gotCreated, err := r.Create(args.ctx, args.ent)
    58  		if (err != nil) != w.wantErr {
    59  			t.Errorf("UserRepository.Create() error = %v, wantErr %v", err, w.wantErr)
    60  			return
    61  		}
    62  		if diff := cmp.Diff(gotCreated, w.wantCreated); diff != "" {
    63  			t.Errorf("UserRepository.Create() = %v", diff)
    64  		}
    65  	}
    66  	t.Run("#1: Success", func(t *testing.T) {
    67  		ctx := context.WithValue(context.Background(), appctx.TransactionContextKey, gDB)
    68  		insertQuery := "INSERT INTO `users`(.*) VALUES (.*)"
    69  		mock.ExpectExec(insertQuery).WillReturnResult(
    70  			sqlmock.NewResult(1, 1),
    71  		)
    72  
    73  		query := regexp.QuoteMeta("SELECT * FROM `users` WHERE id = ? LIMIT 1")
    74  		mock.ExpectQuery(query).WillReturnRows(
    75  			sqlmock.NewRows([]string{"ID", "Username", "Password"}).
    76  				AddRow(
    77  					"01ENSP2J4H9QRMWYJ3ZQTYEGYJ",
    78  					"username",
    79  					"$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
    80  				),
    81  		)
    82  		runFunc(t,
    83  			fields{baseRepository{}},
    84  			args{
    85  				ctx: ctx,
    86  				ent: entity.User{
    87  					Username: "username",
    88  					Password: "$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
    89  				},
    90  			},
    91  			wants{
    92  				wantCreated: entity.User{
    93  					ID:       "01ENSP2J4H9QRMWYJ3ZQTYEGYJ",
    94  					Username: "username",
    95  					Password: "$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
    96  				},
    97  				wantErr: false,
    98  			},
    99  		)
   100  	})
   101  	t.Run("#2: Failed when creating", func(t *testing.T) {
   102  		ctx := context.WithValue(context.Background(), appctx.TransactionContextKey, gDB)
   103  		insertQuery := "INSERT INTO `users`(.*) VALUES (.*)"
   104  		mock.ExpectExec(insertQuery).WillReturnError(gorm.ErrInvalidData)
   105  
   106  		runFunc(t,
   107  			fields{baseRepository{}},
   108  			args{
   109  				ctx: ctx,
   110  				ent: entity.User{
   111  					Username: "username",
   112  					Password: "$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
   113  				},
   114  			},
   115  			wants{
   116  				wantCreated: entity.User{},
   117  				wantErr:     true,
   118  			},
   119  		)
   120  	})
   121  	t.Run("#3: Failed when select again", func(t *testing.T) {
   122  		ctx := context.WithValue(context.Background(), appctx.TransactionContextKey, gDB)
   123  		insertQuery := "INSERT INTO `users`(.*) VALUES (.*)"
   124  		mock.ExpectExec(insertQuery).WillReturnResult(
   125  			sqlmock.NewResult(1, 1),
   126  		)
   127  
   128  		query := regexp.QuoteMeta("SELECT * FROM `users` WHERE id = ? LIMIT 1")
   129  		mock.ExpectQuery(query).WillReturnError(gorm.ErrRecordNotFound)
   130  		runFunc(t,
   131  			fields{baseRepository{}},
   132  			args{
   133  				ctx: ctx,
   134  				ent: entity.User{
   135  					Username: "username",
   136  					Password: "$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
   137  				},
   138  			},
   139  			wants{
   140  				wantCreated: entity.User{},
   141  				wantErr:     true,
   142  			},
   143  		)
   144  	})
   145  	t.Run("#4: [ShouldPanic] Can not found DB in context", func(t *testing.T) {
   146  		testhelper.ShouldPanic(t, func() {
   147  			ctx := context.Background()
   148  			insertQuery := "INSERT INTO `users`(.*) VALUES (.*)"
   149  			mock.ExpectExec(insertQuery).WillReturnResult(
   150  				sqlmock.NewResult(1, 1),
   151  			)
   152  
   153  			query := regexp.QuoteMeta("SELECT * FROM `users` WHERE id = ? LIMIT 1")
   154  			mock.ExpectQuery(query).WillReturnRows(
   155  				sqlmock.NewRows([]string{"ID", "Username", "Password"}).
   156  					AddRow(
   157  						"01ENSP2J4H9QRMWYJ3ZQTYEGYJ",
   158  						"username",
   159  						"$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
   160  					),
   161  			)
   162  			runFunc(t,
   163  				fields{baseRepository{}},
   164  				args{
   165  					ctx: ctx,
   166  					ent: entity.User{
   167  						Username: "username",
   168  						Password: "$argon2id$v=19$m=65536,t=8,p=8$rWzlADlkY3v8OsLwVKYFGA$owGB0DwHIFywicD4Ydqz2FY5LT406eNUD7aCgMytqZlmuWnHWkNK3Nl5R+aAhV5tVWOqUObqZaO5+zsGwMNBAA",
   169  					},
   170  				},
   171  				wants{
   172  					wantCreated: entity.User{},
   173  					wantErr:     true,
   174  				},
   175  			)
   176  		})
   177  	})
   178  }