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

     1  package repo_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"regexp"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    11  	"github.com/kyma-incubator/compass/components/director/internal/repo/testdb"
    12  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    14  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestExist(t *testing.T) {
    19  	sut := repo.NewExistQuerier(appTableName)
    20  	resourceType := resource.Application
    21  	m2mTable, ok := resourceType.TenantAccessTable()
    22  	require.True(t, ok)
    23  
    24  	t.Run("success when exist", func(t *testing.T) {
    25  		// GIVEN
    26  		expectedQuery := regexp.QuoteMeta(fmt.Sprintf("SELECT 1 FROM %s WHERE id = $1 AND %s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$2")))
    27  		db, mock := testdb.MockDatabase(t)
    28  		ctx := persistence.SaveToContext(context.TODO(), db)
    29  		defer mock.AssertExpectations(t)
    30  		mock.ExpectQuery(expectedQuery).WithArgs(appID, tenantID).WillReturnRows(testdb.RowWhenObjectExist())
    31  		// WHEN
    32  		ex, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("id", appID)})
    33  		// THEN
    34  		require.NoError(t, err)
    35  		require.True(t, ex)
    36  	})
    37  
    38  	t.Run("success when does not exist", func(t *testing.T) {
    39  		// GIVEN
    40  		expectedQuery := regexp.QuoteMeta(fmt.Sprintf("SELECT 1 FROM %s WHERE id = $1 AND %s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$2")))
    41  		db, mock := testdb.MockDatabase(t)
    42  		ctx := persistence.SaveToContext(context.TODO(), db)
    43  		defer mock.AssertExpectations(t)
    44  		mock.ExpectQuery(expectedQuery).WithArgs(appID, tenantID).WillReturnRows(testdb.RowWhenObjectDoesNotExist())
    45  		// WHEN
    46  		ex, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("id", appID)})
    47  		// THEN
    48  		require.NoError(t, err)
    49  		require.False(t, ex)
    50  	})
    51  
    52  	t.Run("success when no conditions", func(t *testing.T) {
    53  		// GIVEN
    54  		expectedQuery := regexp.QuoteMeta(fmt.Sprintf("SELECT 1 FROM %s WHERE %s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$1")))
    55  		db, mock := testdb.MockDatabase(t)
    56  		ctx := persistence.SaveToContext(context.TODO(), db)
    57  		defer mock.AssertExpectations(t)
    58  		mock.ExpectQuery(expectedQuery).WillReturnRows(testdb.RowWhenObjectExist())
    59  		// WHEN
    60  		ex, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{})
    61  		// THEN
    62  		require.NoError(t, err)
    63  		require.True(t, ex)
    64  	})
    65  
    66  	t.Run("success when more conditions", func(t *testing.T) {
    67  		// GIVEN
    68  		expectedQuery := regexp.QuoteMeta(fmt.Sprintf("SELECT 1 FROM %s WHERE first_name = $1 AND last_name = $2 AND %s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$3")))
    69  		db, mock := testdb.MockDatabase(t)
    70  		ctx := persistence.SaveToContext(context.TODO(), db)
    71  		defer mock.AssertExpectations(t)
    72  		mock.ExpectQuery(expectedQuery).WithArgs("john", "doe", tenantID).WillReturnRows(testdb.RowWhenObjectDoesNotExist())
    73  		// WHEN
    74  		_, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("first_name", "john"), repo.NewEqualCondition("last_name", "doe")})
    75  		// THEN
    76  		require.NoError(t, err)
    77  	})
    78  
    79  	t.Run("returns error when operation on db failed", func(t *testing.T) {
    80  		// GIVEN
    81  		expectedQuery := regexp.QuoteMeta(fmt.Sprintf("SELECT 1 FROM %s WHERE id = $1 AND %s", appTableName, fmt.Sprintf(tenantIsolationConditionWithoutOwnerCheckFmt, m2mTable, "$2")))
    82  		db, mock := testdb.MockDatabase(t)
    83  		ctx := persistence.SaveToContext(context.TODO(), db)
    84  		defer mock.AssertExpectations(t)
    85  		mock.ExpectQuery(expectedQuery).WithArgs(appID, tenantID).WillReturnError(someError())
    86  		// WHEN
    87  		_, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("id", appID)})
    88  		// THEN
    89  		require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
    90  	})
    91  
    92  	t.Run("context properly canceled", func(t *testing.T) {
    93  		db, mock := testdb.MockDatabase(t)
    94  		defer mock.AssertExpectations(t)
    95  
    96  		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
    97  		defer cancel()
    98  
    99  		ctx = persistence.SaveToContext(ctx, db)
   100  
   101  		_, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("id", appID)})
   102  
   103  		require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached")
   104  	})
   105  
   106  	t.Run("returns error if empty tenant", func(t *testing.T) {
   107  		db, mock := testdb.MockDatabase(t)
   108  		ctx := persistence.SaveToContext(context.TODO(), db)
   109  		defer mock.AssertExpectations(t)
   110  
   111  		_, err := sut.Exists(ctx, resourceType, "", repo.Conditions{repo.NewEqualCondition("id", appID)})
   112  		require.EqualError(t, err, apperrors.NewTenantRequiredError().Error())
   113  	})
   114  
   115  	t.Run("returns error if missing persistence context", func(t *testing.T) {
   116  		ctx := context.TODO()
   117  		_, err := sut.Exists(ctx, resourceType, tenantID, repo.Conditions{repo.NewEqualCondition("id", appID)})
   118  		require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error())
   119  	})
   120  }
   121  
   122  func TestExistWithEmbeddedTenant(t *testing.T) {
   123  	givenID := "id"
   124  	sut := repo.NewExistQuerierWithEmbeddedTenant(userTableName, "tenant_id")
   125  
   126  	t.Run("success when exist", func(t *testing.T) {
   127  		// GIVEN
   128  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE tenant_id = $1 AND id = $2")
   129  		db, mock := testdb.MockDatabase(t)
   130  		ctx := persistence.SaveToContext(context.TODO(), db)
   131  		defer mock.AssertExpectations(t)
   132  		mock.ExpectQuery(expectedQuery).WithArgs(tenantID, givenID).WillReturnRows(testdb.RowWhenObjectExist())
   133  		// WHEN
   134  		ex, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   135  		// THEN
   136  		require.NoError(t, err)
   137  		require.True(t, ex)
   138  	})
   139  
   140  	t.Run("success when does not exist", func(t *testing.T) {
   141  		// GIVEN
   142  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE tenant_id = $1 AND id = $2")
   143  		db, mock := testdb.MockDatabase(t)
   144  		ctx := persistence.SaveToContext(context.TODO(), db)
   145  		defer mock.AssertExpectations(t)
   146  		mock.ExpectQuery(expectedQuery).WithArgs(tenantID, givenID).WillReturnRows(testdb.RowWhenObjectDoesNotExist())
   147  		// WHEN
   148  		ex, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   149  		// THEN
   150  		require.NoError(t, err)
   151  		require.False(t, ex)
   152  	})
   153  
   154  	t.Run("success when no conditions", func(t *testing.T) {
   155  		// GIVEN
   156  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE tenant_id = $1")
   157  		db, mock := testdb.MockDatabase(t)
   158  		ctx := persistence.SaveToContext(context.TODO(), db)
   159  		defer mock.AssertExpectations(t)
   160  		mock.ExpectQuery(expectedQuery).WillReturnRows(testdb.RowWhenObjectExist())
   161  		// WHEN
   162  		ex, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{})
   163  		// THEN
   164  		require.NoError(t, err)
   165  		require.True(t, ex)
   166  	})
   167  
   168  	t.Run("success when more conditions", func(t *testing.T) {
   169  		// GIVEN
   170  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE tenant_id = $1 AND first_name = $2 AND last_name = $3")
   171  		db, mock := testdb.MockDatabase(t)
   172  		ctx := persistence.SaveToContext(context.TODO(), db)
   173  		defer mock.AssertExpectations(t)
   174  		mock.ExpectQuery(expectedQuery).WithArgs(tenantID, "john", "doe").WillReturnRows(testdb.RowWhenObjectDoesNotExist())
   175  		// WHEN
   176  		_, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("first_name", "john"), repo.NewEqualCondition("last_name", "doe")})
   177  		// THEN
   178  		require.NoError(t, err)
   179  	})
   180  
   181  	t.Run("returns error when operation on db failed", func(t *testing.T) {
   182  		// GIVEN
   183  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE tenant_id = $1 AND id = $2")
   184  		db, mock := testdb.MockDatabase(t)
   185  		ctx := persistence.SaveToContext(context.TODO(), db)
   186  		defer mock.AssertExpectations(t)
   187  		mock.ExpectQuery(expectedQuery).WithArgs(tenantID, givenID).WillReturnError(someError())
   188  		// WHEN
   189  		_, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   190  		// THEN
   191  		require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   192  	})
   193  
   194  	t.Run("context properly canceled", func(t *testing.T) {
   195  		db, mock := testdb.MockDatabase(t)
   196  		defer mock.AssertExpectations(t)
   197  
   198  		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
   199  		defer cancel()
   200  
   201  		ctx = persistence.SaveToContext(ctx, db)
   202  
   203  		_, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   204  
   205  		require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached")
   206  	})
   207  
   208  	t.Run("returns error if missing persistence context", func(t *testing.T) {
   209  		ctx := context.TODO()
   210  		_, err := sut.Exists(ctx, UserType, tenantID, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   211  		require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error())
   212  	})
   213  }
   214  
   215  func TestExistGlobal(t *testing.T) {
   216  	givenID := "id"
   217  	sut := repo.NewExistQuerierGlobal(UserType, "users")
   218  
   219  	t.Run("success when exist", func(t *testing.T) {
   220  		// GIVEN
   221  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE id = $1")
   222  		db, mock := testdb.MockDatabase(t)
   223  		ctx := persistence.SaveToContext(context.TODO(), db)
   224  		defer mock.AssertExpectations(t)
   225  		mock.ExpectQuery(expectedQuery).WithArgs(givenID).WillReturnRows(testdb.RowWhenObjectExist())
   226  		// WHEN
   227  		ex, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   228  		// THEN
   229  		require.NoError(t, err)
   230  		require.True(t, ex)
   231  	})
   232  
   233  	t.Run("success when does not exist", func(t *testing.T) {
   234  		// GIVEN
   235  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE id = $1")
   236  		db, mock := testdb.MockDatabase(t)
   237  		ctx := persistence.SaveToContext(context.TODO(), db)
   238  		defer mock.AssertExpectations(t)
   239  		mock.ExpectQuery(expectedQuery).WithArgs(givenID).WillReturnRows(testdb.RowWhenObjectDoesNotExist())
   240  		// WHEN
   241  		ex, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   242  		// THEN
   243  		require.NoError(t, err)
   244  		require.False(t, ex)
   245  	})
   246  
   247  	t.Run("success when no conditions", func(t *testing.T) {
   248  		// GIVEN
   249  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users")
   250  		db, mock := testdb.MockDatabase(t)
   251  		ctx := persistence.SaveToContext(context.TODO(), db)
   252  		defer mock.AssertExpectations(t)
   253  		mock.ExpectQuery(expectedQuery).WillReturnRows(testdb.RowWhenObjectExist())
   254  		// WHEN
   255  		ex, err := sut.ExistsGlobal(ctx, repo.Conditions{})
   256  		// THEN
   257  		require.NoError(t, err)
   258  		require.True(t, ex)
   259  	})
   260  
   261  	t.Run("success when more conditions", func(t *testing.T) {
   262  		// GIVEN
   263  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE first_name = $1 AND last_name = $2")
   264  		db, mock := testdb.MockDatabase(t)
   265  		ctx := persistence.SaveToContext(context.TODO(), db)
   266  		defer mock.AssertExpectations(t)
   267  		mock.ExpectQuery(expectedQuery).WithArgs("john", "doe").WillReturnRows(testdb.RowWhenObjectDoesNotExist())
   268  		// WHEN
   269  		_, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("first_name", "john"), repo.NewEqualCondition("last_name", "doe")})
   270  		// THEN
   271  		require.NoError(t, err)
   272  	})
   273  
   274  	t.Run("returns error when operation on db failed", func(t *testing.T) {
   275  		// GIVEN
   276  		expectedQuery := regexp.QuoteMeta("SELECT 1 FROM users WHERE id = $1")
   277  		db, mock := testdb.MockDatabase(t)
   278  		ctx := persistence.SaveToContext(context.TODO(), db)
   279  		defer mock.AssertExpectations(t)
   280  		mock.ExpectQuery(expectedQuery).WithArgs(givenID).WillReturnError(someError())
   281  		// WHEN
   282  		_, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   283  		// THEN
   284  		require.EqualError(t, err, "Internal Server Error: Unexpected error while executing SQL query")
   285  	})
   286  
   287  	t.Run("context properly canceled", func(t *testing.T) {
   288  		db, mock := testdb.MockDatabase(t)
   289  		defer mock.AssertExpectations(t)
   290  
   291  		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
   292  		defer cancel()
   293  
   294  		ctx = persistence.SaveToContext(ctx, db)
   295  
   296  		_, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   297  
   298  		require.EqualError(t, err, "Internal Server Error: Maximum processing timeout reached")
   299  	})
   300  
   301  	t.Run("returns error if missing persistence context", func(t *testing.T) {
   302  		ctx := context.TODO()
   303  		_, err := sut.ExistsGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", givenID)})
   304  		require.EqualError(t, err, apperrors.NewInternalError("unable to fetch database from context").Error())
   305  	})
   306  }