keycloak-aplcache

Merge pull request #2655 from mposolda/1.9.x KEYCLOAK-2849

4/19/2016 10:22:14 AM

Details

diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/AbstractProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/AbstractProtocolMapperTest.java
new file mode 100644
index 0000000..6fc8f4f
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/AbstractProtocolMapperTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 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.testsuite.endpoint.client;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public abstract class AbstractProtocolMapperTest extends AbstractClientTest {
+
+    protected Map<String, List<ProtocolMapperRepresentation>> builtinMappers = null;
+
+    protected void initBuiltinMappers() {
+        builtinMappers = adminClient.serverInfo().getInfo().getBuiltinProtocolMappers();
+    }
+
+    protected ProtocolMapperRepresentation makeMapper(String protocol, String name, String mapperType, Map<String, String> config) {
+        ProtocolMapperRepresentation rep = new ProtocolMapperRepresentation();
+        rep.setProtocol(protocol);
+        rep.setName(name);
+        rep.setProtocolMapper(mapperType);
+        rep.setConfig(config);
+        rep.setConsentRequired(true);
+        rep.setConsentText("Test Consent Text");
+        return rep;
+    }
+
+    protected ProtocolMapperRepresentation makeSamlMapper(String name) {
+        Map<String, String> config = new HashMap<>();
+        config.put("role", "account.view-profile");
+        config.put("new.role.name", "new-role-name");
+        return makeMapper("saml", name, "saml-role-name-mapper", config);
+    }
+
+    protected ProtocolMapperRepresentation makeOidcMapper(String name) {
+        Map<String, String> config = new HashMap<>();
+        config.put("role", "myrole");
+        return makeMapper("openid-connect", name, "oidc-hardcoded-role-mapper", config);
+    }
+
+    protected void assertEqualMappers(ProtocolMapperRepresentation original, ProtocolMapperRepresentation created) {
+        assertNotNull(created);
+        assertEquals(original.getName(), created.getName());
+        assertEquals(original.getConfig(), created.getConfig());
+        assertEquals(original.getConsentText(), created.getConsentText());
+        assertEquals(original.isConsentRequired(), created.isConsentRequired());
+        assertEquals(original.getProtocol(), created.getProtocol());
+        assertEquals(original.getProtocolMapper(), created.getProtocolMapper());
+    }
+
+    protected boolean containsMapper(List<ProtocolMapperRepresentation> mappers, ProtocolMapperRepresentation mapper) {
+        for (ProtocolMapperRepresentation listedMapper : mappers) {
+            if (listedMapper.getName().equals(mapper.getName())) return true;
+        }
+
+        return false;
+    }
+
+    protected List<ProtocolMapperRepresentation> mappersToAdd(List<ProtocolMapperRepresentation> oldMappers,
+                                                            List<ProtocolMapperRepresentation> builtins) {
+        List<ProtocolMapperRepresentation> mappersToAdd = new ArrayList<>();
+        for (ProtocolMapperRepresentation builtin : builtins) {
+            if (!containsMapper(oldMappers, builtin)) mappersToAdd.add(builtin);
+        }
+
+        return mappersToAdd;
+    }
+
+    protected void testAddAllBuiltinMappers(ProtocolMappersResource resource, String resourceName) {
+        List<ProtocolMapperRepresentation> oldMappers = resource.getMappersPerProtocol(resourceName);
+        List<ProtocolMapperRepresentation> builtins = builtinMappers.get(resourceName);
+
+        List<ProtocolMapperRepresentation> mappersToAdd = mappersToAdd(oldMappers, builtins);
+
+        // This is used by admin console to add builtin mappers
+        resource.createMapper(mappersToAdd);
+
+        List<ProtocolMapperRepresentation> newMappers = resource.getMappersPerProtocol(resourceName);
+        assertEquals(oldMappers.size() + mappersToAdd.size(), newMappers.size());
+
+        for (ProtocolMapperRepresentation rep : mappersToAdd) {
+            assertTrue(containsMapper(newMappers, rep));
+        }
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientProtocolMapperTest.java
index f7db1e2..441ef4f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientProtocolMapperTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientProtocolMapperTest.java
@@ -17,10 +17,6 @@
 
 package org.keycloak.testsuite.endpoint.client;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
 import org.junit.After;
@@ -33,23 +29,18 @@ import org.keycloak.testsuite.admin.ApiUtil;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
 
 /**
  *
  * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
  */
-public class ClientProtocolMapperTest extends AbstractClientTest {
+public class ClientProtocolMapperTest extends AbstractProtocolMapperTest {
 
     private ClientResource oidcClientRsc;
     private ProtocolMappersResource oidcMappersRsc;
     private ClientResource samlClientRsc;
     private ProtocolMappersResource samlMappersRsc;
 
-    private Map<String, List<ProtocolMapperRepresentation>> builtinMappers = null;
-
     @Before
     public void init() {
         createOidcClient("oidcMapperClient");
@@ -60,7 +51,7 @@ public class ClientProtocolMapperTest extends AbstractClientTest {
         samlClientRsc = findClientResource("samlMapperClient");
         samlMappersRsc = samlClientRsc.getProtocolMappers();
 
-        builtinMappers = adminClient.serverInfo().getInfo().getBuiltinProtocolMappers();
+        super.initBuiltinMappers();
     }
 
     @After
@@ -69,81 +60,12 @@ public class ClientProtocolMapperTest extends AbstractClientTest {
         samlClientRsc.remove();
     }
 
-    private ProtocolMapperRepresentation makeMapper(String protocol, String name, String mapperType, Map<String, String> config) {
-        ProtocolMapperRepresentation rep = new ProtocolMapperRepresentation();
-        rep.setProtocol(protocol);
-        rep.setName(name);
-        rep.setProtocolMapper(mapperType);
-        rep.setConfig(config);
-        rep.setConsentRequired(true);
-        rep.setConsentText("Test Consent Text");
-        return rep;
-    }
-
-    private ProtocolMapperRepresentation makeSamlMapper(String name) {
-        Map<String, String> config = new HashMap<>();
-        config.put("role", "account.view-profile");
-        config.put("new.role.name", "new-role-name");
-        return makeMapper("saml", name, "saml-role-name-mapper", config);
-    }
-
-    private ProtocolMapperRepresentation makeOidcMapper(String name) {
-        Map<String, String> config = new HashMap<>();
-        config.put("role", "myrole");
-        return makeMapper("openid-connect", name, "oidc-hardcoded-role-mapper", config);
-    }
-
-    private void assertEqualMappers(ProtocolMapperRepresentation original, ProtocolMapperRepresentation created) {
-        assertNotNull(created);
-        assertEquals(original.getName(), created.getName());
-        assertEquals(original.getConfig(), created.getConfig());
-        assertEquals(original.getConsentText(), created.getConsentText());
-        assertEquals(original.isConsentRequired(), created.isConsentRequired());
-        assertEquals(original.getProtocol(), created.getProtocol());
-        assertEquals(original.getProtocolMapper(), created.getProtocolMapper());
-    }
-
     @Test
     public void testGetMappersList() {
         assertFalse(oidcMappersRsc.getMappers().isEmpty());
         assertFalse(samlMappersRsc.getMappers().isEmpty());
     }
 
-    private boolean containsMapper(List<ProtocolMapperRepresentation> mappers, ProtocolMapperRepresentation mapper) {
-        for (ProtocolMapperRepresentation listedMapper : mappers) {
-            if (listedMapper.getName().equals(mapper.getName())) return true;
-        }
-
-        return false;
-    }
-
-    private List<ProtocolMapperRepresentation> mappersToAdd(List<ProtocolMapperRepresentation> oldMappers,
-                                                            List<ProtocolMapperRepresentation> builtins) {
-        List<ProtocolMapperRepresentation> mappersToAdd = new ArrayList<>();
-        for (ProtocolMapperRepresentation builtin : builtins) {
-            if (!containsMapper(oldMappers, builtin)) mappersToAdd.add(builtin);
-        }
-
-        return mappersToAdd;
-    }
-
-    private void testAddAllBuiltinMappers(ProtocolMappersResource resource, String resourceName) {
-        List<ProtocolMapperRepresentation> oldMappers = resource.getMappersPerProtocol(resourceName);
-        List<ProtocolMapperRepresentation> builtins = builtinMappers.get(resourceName);
-
-        List<ProtocolMapperRepresentation> mappersToAdd = mappersToAdd(oldMappers, builtins);
-
-        // This is used by admin console to add builtin mappers
-        resource.createMapper(mappersToAdd);
-
-        List<ProtocolMapperRepresentation> newMappers = resource.getMappersPerProtocol(resourceName);
-        assertEquals(oldMappers.size() + mappersToAdd.size(), newMappers.size());
-
-        for (ProtocolMapperRepresentation rep : mappersToAdd) {
-            assertTrue(containsMapper(newMappers, rep));
-        }
-    }
-
     @Test
     public void testCreateOidcMappersFromList() {
         testAddAllBuiltinMappers(oidcMappersRsc, "openid-connect");
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateProtocolMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateProtocolMapperTest.java
new file mode 100644
index 0000000..6a2a660
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateProtocolMapperTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2016 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.testsuite.endpoint.client;
+
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.keycloak.admin.client.resource.ClientTemplateResource;
+import org.keycloak.admin.client.resource.ClientTemplatesResource;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.saml.SamlProtocol;
+import org.keycloak.representations.idm.ClientTemplateRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.testsuite.admin.ApiUtil;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ClientTemplateProtocolMapperTest extends AbstractProtocolMapperTest {
+
+    private ClientTemplateResource oidcClientTemplateRsc;
+    private ProtocolMappersResource oidcMappersRsc;
+    private ClientTemplateResource samlClientTemplateRsc;
+    private ProtocolMappersResource samlMappersRsc;
+
+    @Before
+    public void init() {
+        oidcClientTemplateRsc = createTemplate("oidcMapperClient-template", OIDCLoginProtocol.LOGIN_PROTOCOL);
+        oidcMappersRsc = oidcClientTemplateRsc.getProtocolMappers();
+
+        samlClientTemplateRsc = createTemplate("samlMapperClient-template", SamlProtocol.LOGIN_PROTOCOL);
+        samlMappersRsc = samlClientTemplateRsc.getProtocolMappers();
+
+        super.initBuiltinMappers();
+    }
+
+    @After
+    public void tearDown() {
+        oidcClientTemplateRsc.remove();
+        samlClientTemplateRsc.remove();
+    }
+
+    @Test
+    public void test01GetMappersList() {
+        assertTrue(oidcMappersRsc.getMappers().isEmpty());
+        assertTrue(samlMappersRsc.getMappers().isEmpty());
+    }
+
+    @Test
+    public void test02CreateOidcMappersFromList() {
+        testAddAllBuiltinMappers(oidcMappersRsc, "openid-connect");
+    }
+
+    @Test
+    public void test03CreateSamlMappersFromList() {
+        testAddAllBuiltinMappers(samlMappersRsc, "saml");
+    }
+
+    @Test
+    public void test04CreateSamlProtocolMapper() {
+
+        //{"protocol":"saml",
+        // "config":{"role":"account.view-profile","new.role.name":"new-role-name"},
+        // "consentRequired":true,
+        // "consentText":"My consent text",
+        // "name":"saml-role-name-maper",
+        // "protocolMapper":"saml-role-name-mapper"}
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper");
+
+        int totalMappers = samlMappersRsc.getMappers().size();
+        int totalSamlMappers = samlMappersRsc.getMappersPerProtocol("saml").size();
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+        assertEquals(totalMappers + 1, samlMappersRsc.getMappers().size());
+        assertEquals(totalSamlMappers + 1, samlMappersRsc.getMappersPerProtocol("saml").size());
+
+        String createdId = ApiUtil.getCreatedId(resp);
+        ProtocolMapperRepresentation created = samlMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, created);
+    }
+
+    @Test
+    public void test05CreateOidcProtocolMapper() {
+        //{"protocol":"openid-connect",
+        // "config":{"role":"myrole"},
+        // "consentRequired":true,
+        // "consentText":"My consent text",
+        // "name":"oidc-hardcoded-role-mapper",
+        // "protocolMapper":"oidc-hardcoded-role-mapper"}
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper");
+
+        int totalMappers = oidcMappersRsc.getMappers().size();
+        int totalOidcMappers = oidcMappersRsc.getMappersPerProtocol("openid-connect").size();
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+        assertEquals(totalMappers + 1, oidcMappersRsc.getMappers().size());
+        assertEquals(totalOidcMappers + 1, oidcMappersRsc.getMappersPerProtocol("openid-connect").size());
+
+        String createdId = ApiUtil.getCreatedId(resp);
+        ProtocolMapperRepresentation created = oidcMappersRsc.getMapperById(createdId);//findByName(samlMappersRsc, "saml-role-name-mapper");
+        assertEqualMappers(rep, created);
+    }
+
+    @Test
+    public void test06UpdateSamlMapper() {
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper2");
+
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        rep.getConfig().put("role", "account.manage-account");
+        rep.setId(createdId);
+        rep.setConsentRequired(false);
+        samlMappersRsc.update(createdId, rep);
+
+        ProtocolMapperRepresentation updated = samlMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, updated);
+    }
+
+    @Test
+    public void test07UpdateOidcMapper() {
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper2");
+
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        rep.getConfig().put("role", "myotherrole");
+        rep.setId(createdId);
+        rep.setConsentRequired(false);
+        oidcMappersRsc.update(createdId, rep);
+
+        ProtocolMapperRepresentation updated = oidcMappersRsc.getMapperById(createdId);
+        assertEqualMappers(rep, updated);
+    }
+
+    @Test (expected = NotFoundException.class)
+    public void testDeleteSamlMapper() {
+        ProtocolMapperRepresentation rep = makeSamlMapper("saml-role-name-mapper3");
+
+        Response resp = samlMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        samlMappersRsc.delete(createdId);
+
+        samlMappersRsc.getMapperById(createdId);
+    }
+
+    @Test (expected = NotFoundException.class)
+    public void testDeleteOidcMapper() {
+        ProtocolMapperRepresentation rep = makeOidcMapper("oidc-hardcoded-role-mapper3");
+
+        Response resp = oidcMappersRsc.createMapper(rep);
+        resp.close();
+
+        String createdId = ApiUtil.getCreatedId(resp);
+
+        oidcMappersRsc.delete(createdId);
+
+        oidcMappersRsc.getMapperById(createdId);
+    }
+
+
+    private ClientTemplatesResource clientTemplates() {
+        return testRealmResource().clientTemplates();
+    }
+
+    private ClientTemplateResource createTemplate(String templateName, String protocol) {
+        ClientTemplateRepresentation rep = new ClientTemplateRepresentation();
+        rep.setName(templateName);
+        rep.setFullScopeAllowed(false);
+        rep.setProtocol(protocol);
+        Response resp = clientTemplates().create(rep);
+        Assert.assertEquals(201, resp.getStatus());
+        resp.close();
+        String clientTemplateId = ApiUtil.getCreatedId(resp);
+        return clientTemplates().get(clientTemplateId);
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateTest.java
index 8fd43fd..25e287d 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/endpoint/client/ClientTemplateTest.java
@@ -17,22 +17,224 @@
 
 package org.keycloak.testsuite.endpoint.client;
 
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.keycloak.admin.client.resource.ClientTemplatesResource;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
+import org.keycloak.admin.client.resource.RoleMappingResource;
+import org.keycloak.models.AccountRoles;
+import org.keycloak.models.Constants;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.saml.SamlProtocol;
 import org.keycloak.representations.idm.ClientTemplateRepresentation;
+import org.keycloak.representations.idm.ErrorRepresentation;
+import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.testsuite.admin.ApiUtil;
 
+import static org.junit.Assert.assertEquals;
+
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
  */
 public class ClientTemplateTest extends AbstractClientTest {
 
+    @Test
+    public void testAddDuplicatedTemplate() {
+        ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("template1");
+        String templateId = createTemplate(templateRep);
+
+        templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("template1");
+        Response response = clientTemplates().create(templateRep);
+        assertEquals(409, response.getStatus());
+
+        ErrorRepresentation error = response.readEntity(ErrorRepresentation.class);
+        Assert.assertEquals("Client Template template1 already exists", error.getErrorMessage());
+
+        // Cleanup
+        clientTemplates().get(templateId).remove();
+    }
+
+
+    @Test (expected = NotFoundException.class)
+    public void testGetUnknownTemplate() {
+        clientTemplates().get("unknown-id").toRepresentation();
+    }
+
+
+    @Test
+    public void testRemoveTemplate() {
+        // Create template1
+        ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("template1");
+        String template1Id = createTemplate(templateRep);
+
+        List<ClientTemplateRepresentation> clientTemplates = clientTemplates().findAll();
+        Assert.assertEquals(1, clientTemplates.size());
+        Assert.assertEquals("template1", clientTemplates.get(0).getName());
+
+        // Create template2
+        templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("template2");
+        String template2Id = createTemplate(templateRep);
+
+        clientTemplates = clientTemplates().findAll();
+        Assert.assertEquals(2, clientTemplates.size());
+
+        // Remove template1
+        clientTemplates().get(template1Id).remove();
+
+        clientTemplates = clientTemplates().findAll();
+        Assert.assertEquals(1, clientTemplates.size());
+        Assert.assertEquals("template2", clientTemplates.get(0).getName());
+
+
+        // Remove template2
+        clientTemplates().get(template2Id).remove();
+
+        clientTemplates = clientTemplates().findAll();
+        Assert.assertEquals(0, clientTemplates.size());
+    }
+
+
+    @Test
+    public void testUpdateTemplate() {
+        // Test creating
+        ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("template1");
+        templateRep.setDescription("template1-desc");
+        templateRep.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
+        templateRep.setFullScopeAllowed(true);
+        String template1Id = createTemplate(templateRep);
+
+        // Assert created attributes
+        templateRep = clientTemplates().get(template1Id).toRepresentation();
+        Assert.assertEquals("template1", templateRep.getName());
+        Assert.assertEquals("template1-desc", templateRep.getDescription());
+        Assert.assertEquals(OIDCLoginProtocol.LOGIN_PROTOCOL, templateRep.getProtocol());
+        Assert.assertEquals(true, templateRep.isFullScopeAllowed());
+
+
+        // Test updating
+        templateRep.setName("template1-updated");
+        templateRep.setDescription("template1-desc-updated");
+        templateRep.setProtocol(SamlProtocol.LOGIN_PROTOCOL);
+        templateRep.setFullScopeAllowed(false);
+
+        clientTemplates().get(template1Id).update(templateRep);
+
+        // Assert updated attributes
+        templateRep = clientTemplates().get(template1Id).toRepresentation();
+        Assert.assertEquals("template1-updated", templateRep.getName());
+        Assert.assertEquals("template1-desc-updated", templateRep.getDescription());
+        Assert.assertEquals(SamlProtocol.LOGIN_PROTOCOL, templateRep.getProtocol());
+        Assert.assertEquals(false, templateRep.isFullScopeAllowed());
+
+        // Remove template1
+        clientTemplates().get(template1Id).remove();
+    }
+
+
+    @Test
+    public void testScopes() {
+        // Add realm role1
+        RoleRepresentation roleRep1 = new RoleRepresentation();
+        roleRep1.setName("role1");
+        testRealmResource().roles().create(roleRep1);
+        roleRep1 = testRealmResource().roles().get("role1").toRepresentation();
+
+        // Add realm role2
+        RoleRepresentation roleRep2 = roleRep2 = new RoleRepresentation();
+        roleRep2.setName("role2");
+        testRealmResource().roles().create(roleRep2);
+        roleRep2 = testRealmResource().roles().get("role2").toRepresentation();
+
+        // Add role2 as composite to role1
+        testRealmResource().roles().get("role1").addChildren(Collections.singletonList(roleRep2));
+
+
+        // create client template
+        ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
+        templateRep.setName("bar-template");
+        templateRep.setFullScopeAllowed(false);
+        String templateId = createTemplate(templateRep);
+
+        // update with some scopes
+        String accountMgmtId = testRealmResource().clients().findByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId();
+        RoleRepresentation viewAccountRoleRep = testRealmResource().clients().get(accountMgmtId).roles().get(AccountRoles.VIEW_PROFILE).toRepresentation();
+        RoleMappingResource scopesResource = clientTemplates().get(templateId).getScopeMappings();
+
+        scopesResource.realmLevel().add(Collections.singletonList(roleRep1));
+        scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep));
+
+        // test that scopes are available (also through composite role)
+        List<RoleRepresentation> allRealm = scopesResource.realmLevel().listAll();
+        List<RoleRepresentation> availableRealm = scopesResource.realmLevel().listAvailable();
+        List<RoleRepresentation> effectiveRealm = scopesResource.realmLevel().listEffective();
+        List<RoleRepresentation> accountRoles = scopesResource.clientLevel(accountMgmtId).listAll();
+
+        assertRolesPresent(allRealm, "role1");
+        assertRolesNotPresent(availableRealm, "role1", "role2");
+        assertRolesPresent(effectiveRealm, "role1", "role2");
+        assertRolesPresent(accountRoles, AccountRoles.VIEW_PROFILE);
+        MappingsRepresentation mappingsRep = clientTemplates().get(templateId).getScopeMappings().getAll();
+        assertRolesPresent(mappingsRep.getRealmMappings(), "role1");
+        assertRolesPresent(mappingsRep.getClientMappings().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getMappings(), AccountRoles.VIEW_PROFILE);
+
+
+        // remove scopes
+        scopesResource.realmLevel().remove(Collections.singletonList(roleRep1));
+        scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep));
+
+        // assert scopes are removed
+        allRealm = scopesResource.realmLevel().listAll();
+        availableRealm = scopesResource.realmLevel().listAvailable();
+        effectiveRealm = scopesResource.realmLevel().listEffective();
+        accountRoles = scopesResource.clientLevel(accountMgmtId).listAll();
+        assertRolesNotPresent(allRealm, "role1");
+        assertRolesPresent(availableRealm, "role1", "role2");
+        assertRolesNotPresent(effectiveRealm, "role1", "role2");
+        assertRolesNotPresent(accountRoles, AccountRoles.VIEW_PROFILE);
+
+        // remove template
+        clientTemplates().get(templateId).remove();
+    }
+
+    private void assertRolesPresent(List<RoleRepresentation> roles, String... expectedRoleNames) {
+        List<String> expectedList = Arrays.asList(expectedRoleNames);
+
+        Set<String> presentRoles = new HashSet<>();
+        for (RoleRepresentation roleRep : roles) {
+            presentRoles.add(roleRep.getName());
+        }
+
+        for (String expected : expectedList) {
+            if (!presentRoles.contains(expected)) {
+                Assert.fail("Expected role " + expected + " not available");
+            }
+        }
+    }
+
+    private void assertRolesNotPresent(List<RoleRepresentation> roles, String... notExpectedRoleNames) {
+        List<String> notExpectedList = Arrays.asList(notExpectedRoleNames);
+        for (RoleRepresentation roleRep : roles) {
+            if (notExpectedList.contains(roleRep.getName())) {
+                Assert.fail("Role " + roleRep.getName() + " wasn't expected to be available");
+            }
+        }
+    }
+
 
     // KEYCLOAK-2809
     @Test
@@ -47,14 +249,12 @@ public class ClientTemplateTest extends AbstractClientTest {
         ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
         templateRep.setName("bar-template");
         templateRep.setFullScopeAllowed(false);
-        Response resp = testRealmResource().clientTemplates().create(templateRep);
-        resp.close();
-        String clientTemplateId = ApiUtil.getCreatedId(resp);
+        String templateId = createTemplate(templateRep);
 
         // Add realm role to scopes of clientTemplate
-        testRealmResource().clientTemplates().get(clientTemplateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep));
+        clientTemplates().get(templateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep));
 
-        List<RoleRepresentation> roleReps = testRealmResource().clientTemplates().get(clientTemplateId).getScopeMappings().realmLevel().listAll();
+        List<RoleRepresentation> roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll();
         Assert.assertEquals(1, roleReps.size());
         Assert.assertEquals("foo-role", roleReps.get(0).getName());
 
@@ -62,8 +262,23 @@ public class ClientTemplateTest extends AbstractClientTest {
         testRealmResource().roles().deleteRole("foo-role");
 
         // Get scope mappings
-        roleReps = testRealmResource().clientTemplates().get(clientTemplateId).getScopeMappings().realmLevel().listAll();
+        roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll();
         Assert.assertEquals(0, roleReps.size());
+
+        // Cleanup
+        clientTemplates().get(templateId).remove();
+    }
+
+
+    private ClientTemplatesResource clientTemplates() {
+        return testRealmResource().clientTemplates();
+    }
+
+    private String createTemplate(ClientTemplateRepresentation templateRep) {
+        Response resp = clientTemplates().create(templateRep);
+        Assert.assertEquals(201, resp.getStatus());
+        resp.close();
+        return ApiUtil.getCreatedId(resp);
     }
 
 }