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 }