github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/repo/unsafe_create_test.go (about)

     1  package repo_test
     2  
     3  import (
     4  	"context"
     5  	"regexp"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    10  
    11  	"github.com/lib/pq"
    12  
    13  	"github.com/DATA-DOG/go-sqlmock"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  
    17  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    18  	"github.com/kyma-incubator/compass/components/director/internal/repo/testdb"
    19  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestUnsafeCreate(t *testing.T) {
    24  	expectedQuery := regexp.QuoteMeta(`INSERT INTO users ( id, tenant_id, first_name, last_name, age ) 
    25  		VALUES ( ?, ?, ?, ?, ? ) ON CONFLICT ( tenant_id, first_name, last_name ) DO NOTHING`)
    26  	sut := repo.NewUnsafeCreator(UserType, "users", []string{"id", "tenant_id", "first_name", "last_name", "age"}, []string{"tenant_id", "first_name", "last_name"})
    27  	t.Run("success", func(t *testing.T) {
    28  		// GIVEN
    29  		db, mock := testdb.MockDatabase(t)
    30  		ctx := persistence.SaveToContext(context.TODO(), db)
    31  		defer mock.AssertExpectations(t)
    32  		givenUser := User{
    33  			ID:        "given_id",
    34  			Tenant:    "given_tenant",
    35  			FirstName: "given_first_name",
    36  			LastName:  "given_last_name",
    37  			Age:       55,
    38  		}
    39  
    40  		mock.ExpectExec(expectedQuery).
    41  			WithArgs("given_id", "given_tenant", "given_first_name", "given_last_name", 55).WillReturnResult(sqlmock.NewResult(1, 1))
    42  		// WHEN
    43  		err := sut.UnsafeCreate(ctx, givenUser)
    44  		// THEN
    45  		require.NoError(t, err)
    46  	})
    47  
    48  	t.Run("returns error when operation on db failed", func(t *testing.T) {
    49  		// GIVEN
    50  		db, mock := testdb.MockDatabase(t)
    51  		ctx := persistence.SaveToContext(context.TODO(), db)
    52  		defer mock.AssertExpectations(t)
    53  		givenUser := User{}
    54  
    55  		mock.ExpectExec(expectedQuery).
    56  			WillReturnError(someError())
    57  		// WHEN
    58  		err := sut.UnsafeCreate(ctx, givenUser)
    59  		// THEN
    60  		require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
    61  	})
    62  
    63  	t.Run("context properly canceled", func(t *testing.T) {
    64  		db, mock := testdb.MockDatabase(t)
    65  		defer mock.AssertExpectations(t)
    66  		givenUser := User{}
    67  
    68  		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
    69  		defer cancel()
    70  
    71  		ctx = persistence.SaveToContext(ctx, db)
    72  
    73  		err := sut.UnsafeCreate(ctx, givenUser)
    74  
    75  		require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached")
    76  	})
    77  
    78  	t.Run("returns non unique error", func(t *testing.T) {
    79  		// GIVEN
    80  		db, mock := testdb.MockDatabase(t)
    81  		ctx := persistence.SaveToContext(context.TODO(), db)
    82  		defer mock.AssertExpectations(t)
    83  		givenUser := User{}
    84  
    85  		mock.ExpectExec(expectedQuery).
    86  			WillReturnError(&pq.Error{Code: persistence.UniqueViolation})
    87  		// WHEN
    88  		err := sut.UnsafeCreate(ctx, givenUser)
    89  		// THEN
    90  		require.True(t, apperrors.IsNotUniqueError(err))
    91  	})
    92  
    93  	t.Run("returns error if missing persistence context", func(t *testing.T) {
    94  		// WHEN
    95  		err := sut.UnsafeCreate(context.TODO(), User{})
    96  		// THEN
    97  		require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error())
    98  	})
    99  
   100  	t.Run("returns error if destination is nil", func(t *testing.T) {
   101  		// WHEN
   102  		err := sut.UnsafeCreate(context.TODO(), nil)
   103  		// THEN
   104  		require.EqualError(t, err, apperrors.NewInternalError("item cannot be nil").Error())
   105  	})
   106  }
   107  
   108  func TestUnsafeCreateWhenWrongConfiguration(t *testing.T) {
   109  	sut := repo.NewUnsafeCreator("users", "UserType", []string{"id", "tenant_id", "column_does_not_exist"}, []string{"id", "tenant_id"})
   110  	// GIVEN
   111  	db, mock := testdb.MockDatabase(t)
   112  	ctx := persistence.SaveToContext(context.TODO(), db)
   113  	defer mock.AssertExpectations(t)
   114  	// WHEN
   115  	err := sut.UnsafeCreate(ctx, User{})
   116  	// THEN
   117  	require.Error(t, err)
   118  	assert.Contains(t, err.Error(), "Unexpected error while executing SQL query")
   119  }