DefaultModelCriteriaTest.java
/*
* Copyright 2021 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.models.map.storage.criteria;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
import java.util.Arrays;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.nullValue;
import static org.keycloak.models.ClientModel.SearchableFields.*;
import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria;
/**
*
* @author hmlnarik
*/
public class DefaultModelCriteriaTest {
@Test
public void testSimpleCompare() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.compare(CLIENT_ID, Operator.EQ, 3), hasToString("clientId EQ [3]"));
assertThat(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5), hasToString("(clientId EQ [4] && id EQ [5])"));
}
@Test
public void testSimpleCompareAnd() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.and(), hasToString("__TRUE__"));
assertThat(v.and(v.or()), hasToString("__FALSE__"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 3)), hasToString("clientId EQ [3]"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 3), v.or()), hasToString("__FALSE__"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5)), hasToString("(clientId EQ [4] && id EQ [5])"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 4), v.compare(ID, Operator.EQ, 5)), hasToString("(clientId EQ [4] && id EQ [5])"));
}
@Test
public void testSimpleCompareOr() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.or(), hasToString("__FALSE__"));
assertThat(v.or(v.and()), hasToString("__TRUE__"));
assertThat(v.or(v.compare(CLIENT_ID, Operator.EQ, 3)), hasToString("clientId EQ [3]"));
assertThat(v.or(v.compare(CLIENT_ID, Operator.EQ, 3), v.and()), hasToString("__TRUE__"));
assertThat(v.or(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5)), hasToString("(clientId EQ [4] && id EQ [5])"));
assertThat(v.or(v.compare(CLIENT_ID, Operator.EQ, 4), v.compare(ID, Operator.EQ, 5)), hasToString("(clientId EQ [4] || id EQ [5])"));
assertThat(v.or(v.or(v.compare(CLIENT_ID, Operator.EQ, 4), v.compare(ID, Operator.EQ, 5))), hasToString("(clientId EQ [4] || id EQ [5])"));
assertThat(v.and(v.or(v.compare(CLIENT_ID, Operator.EQ, 4), v.compare(ID, Operator.EQ, 5))), hasToString("(clientId EQ [4] || id EQ [5])"));
}
@Test
public void testSimpleCompareAndOr() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(ID, Operator.EQ, 5)
),
v.not(v.not(v.compare(ATTRIBUTE, Operator.EQ, "city", "Ankh-Morpork")))
), hasToString("((clientId EQ [4] && id EQ [5]) || attribute EQ [city, Ankh-Morpork])"));
DefaultModelCriteria<RoleModel> mcb = criteria();
assertThat(mcb.and(
mcb.compare(RoleModel.SearchableFields.REALM_ID, Operator.EQ, "realmId"),
mcb.compare(RoleModel.SearchableFields.CLIENT_ID, Operator.EQ, "clientId"),
mcb.or(
mcb.compare(RoleModel.SearchableFields.NAME, Operator.ILIKE, "%search%"),
mcb.compare(RoleModel.SearchableFields.DESCRIPTION, Operator.ILIKE, "%search%")
)
), hasToString("(realmId EQ [realmId] && clientId EQ [clientId] && (name ILIKE [%search%] || description ILIKE [%search%]))"));
assertThat(mcb
.compare(RoleModel.SearchableFields.REALM_ID, Operator.EQ, "realmId")
.compare(RoleModel.SearchableFields.CLIENT_ID, Operator.EQ, "clientId")
.or(
mcb.compare(RoleModel.SearchableFields.NAME, Operator.ILIKE, "%search%"),
mcb.compare(RoleModel.SearchableFields.DESCRIPTION, Operator.ILIKE, "%search%")
),
hasToString("(realmId EQ [realmId] && clientId EQ [clientId] && (name ILIKE [%search%] || description ILIKE [%search%]))"));
}
@Test
public void testComplexCompareAndOr() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(v.compare(ID, Operator.EQ, 5))
),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || ! id EQ [5])")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(
v.compare(ID, Operator.EQ, 5)
).compare(ENABLED, Operator.EQ, "true")
),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || (! id EQ [5] && enabled EQ [true]))")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(
v.not(
v.compare(ID, Operator.EQ, 5)
).compare(ENABLED, Operator.EQ, "true")
)
),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || ! (! id EQ [5] && enabled EQ [true]))")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(
v.not(
v.and(
v.compare(ID, Operator.EQ, 5)
.compare(ENABLED, Operator.EQ, "true")
)
)
)
),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || (id EQ [5] && enabled EQ [true]))")
);
}
@Test
public void testFlashingToAnotherMCB() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(v.compare(ID, Operator.EQ, 5))
).flashToModelCriteriaBuilder(criteria()),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || ! id EQ [5])")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(
v.compare(ID, Operator.EQ, 5)
).compare(ENABLED, Operator.EQ, "true")
).flashToModelCriteriaBuilder(criteria()),
hasToString("((clientId EQ [4] && realmId EQ [aa]) || (! id EQ [5] && enabled EQ [true]))")
);
}
@Test
public void testCloning() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5))
.partiallyEvaluate((field, operator, operatorArguments) ->
(field == CLIENT_ID && operator == Operator.EQ && Arrays.asList(operatorArguments).contains(4))
|| (field == ID && operator == Operator.EQ && Arrays.asList(operatorArguments).contains(5))
? true
: null
),
hasToString("(__TRUE__ && __TRUE__)"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5))
.partiallyEvaluate((field, operator, operatorArguments) ->
(field == CLIENT_ID && operator == Operator.EQ && Arrays.asList(operatorArguments).contains(4))
|| (field == ID && operator == Operator.EQ && Arrays.asList(operatorArguments).contains(5))
? true
: null
).optimize(),
hasToString("__TRUE__"));
assertThat(v.and(v.compare(CLIENT_ID, Operator.EQ, 4).compare(ID, Operator.EQ, 5))
.partiallyEvaluate((field, operator, operatorArguments) -> field == CLIENT_ID && operator == Operator.EQ && Arrays.asList(operatorArguments).contains(6) ? true : null),
hasToString("(clientId EQ [4] && id EQ [5])"));
}
@Test
public void testGetFieldCriteriaSingleArgument() {
DefaultModelCriteria<ClientModel> v = criteria();
assertThat(
v.compare(REALM_ID, Operator.EQ, "aa")
.getSingleRestrictionArgument(REALM_ID.getName()),
hasToString("aa")
);
assertThat(
v.not(v.compare(REALM_ID, Operator.EQ, "aa"))
.getSingleRestrictionArgument(REALM_ID.getName()),
nullValue()
);
assertThat(
v.not(v.not(v.compare(REALM_ID, Operator.EQ, "aa")))
.getSingleRestrictionArgument(REALM_ID.getName()),
hasToString("aa")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
)
).getSingleRestrictionArgument(REALM_ID.getName()),
hasToString("aa")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.and(
v.compare(CLIENT_ID, Operator.EQ, 123),
v.compare(REALM_ID, Operator.EQ, "aa")
)
).getSingleRestrictionArgument(REALM_ID.getName()),
hasToString("aa")
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "bb")
)
).getSingleRestrictionArgument(REALM_ID.getName()),
nullValue()
);
assertThat(v.or(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(v.compare(ID, Operator.EQ, 5))
).getSingleRestrictionArgument(REALM_ID.getName()),
nullValue()
);
assertThat(v.and(
v.and(
v.compare(CLIENT_ID, Operator.EQ, 4),
v.compare(REALM_ID, Operator.EQ, "aa")
),
v.not(v.compare(ID, Operator.EQ, 5))
).getSingleRestrictionArgument(REALM_ID.getName()),
hasToString("aa")
);
}
}