diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java index 07d45a6f1..3762b7b4c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java @@ -1,6 +1,5 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.ITargetable; import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; @@ -9,21 +8,12 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; @@ -137,7 +127,7 @@ public ResponseEntity getAll(@PathVariable String metadataResolverId) { @GetMapping("/Filters/{resourceId}") @Transactional(readOnly = true) public ResponseEntity getOne(@PathVariable String metadataResolverId, @PathVariable String resourceId) { - MetadataResolver resolver = findResolverOrThrowHttp404(metadataResolverId); + findResolverOrThrowHttp404(metadataResolverId); return ResponseEntity.ok(findFilterOrThrowHttp404(resourceId)); } @@ -199,7 +189,7 @@ public ResponseEntity update(@PathVariable String metadataResolverId, .stream() .filter(it -> it.getResourceId().equals(resourceId)) .findFirst(); - if (!filterTobeUpdatedOptional.isPresent()) { + if (filterTobeUpdatedOptional.isEmpty()) { return ResponseEntity.notFound().build(); } MetadataFilter filterTobeUpdated = filterTobeUpdatedOptional.get(); diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetup.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetup.groovy index 2fc57fe70..29f42d82e 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetup.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetup.groovy @@ -1,6 +1,5 @@ package edu.internet2.tier.shibboleth.admin.ui - import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository @@ -14,7 +13,6 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.test.context.ContextConfiguration import org.springframework.transaction.annotation.Transactional -import spock.lang.Shared import spock.lang.Specification @DataJpaTest @@ -22,8 +20,6 @@ import spock.lang.Specification @EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) @EntityScan("edu.internet2.tier.shibboleth.admin.ui") abstract class BaseDataJpaTestSetup extends Specification { - static boolean setupRun = false - @Autowired GroupServiceForTesting groupService @@ -39,15 +35,9 @@ abstract class BaseDataJpaTestSetup extends Specification { @Autowired UserService userService - def setup() { - runOnce() - } - - // One time setup to ensure roles are in a known good state and that we have an admin user and group + // ensure roles are in a known good state and that we have an admin user and group @Transactional - runOnce() { - if (setupRun) return - + def setup() { groupService.clearAllForTesting() userRepository.deleteAll() ownershipRepository.deleteAll() @@ -77,6 +67,5 @@ abstract class BaseDataJpaTestSetup extends Specification { User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo") userService.save(adminUser) } - setupRun = true } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetupConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetupConfiguration.groovy index 6316b9755..d8626a07a 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetupConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/BaseDataJpaTestSetupConfiguration.groovy @@ -1,5 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.security.model.listener.GroupUpdatedEntityListener @@ -8,6 +10,8 @@ import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsReposito import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceForTesting import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl +import edu.internet2.tier.shibboleth.admin.util.AttributeUtility +import io.micrometer.core.instrument.search.Search import org.springframework.context.annotation.Bean import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @@ -15,9 +19,14 @@ import org.springframework.context.annotation.Import import org.springframework.context.annotation.Primary @Configuration -@Import(ShibUIConfiguration.class) +@Import([ShibUIConfiguration.class, CustomPropertiesConfiguration.class, SearchConfiguration.class]) @ComponentScan(basePackages=[ "edu.internet2.tier.shibboleth.admin.ui.service", "edu.internet2.tier.shibboleth.admin.ui.security.service" ]) class BaseDataJpaTestSetupConfiguration { + @Bean + AttributeUtility attributeUtility(OpenSamlObjects openSamlObjects) { + return new AttributeUtility(openSamlObjects) + } + @Bean @Primary GroupServiceForTesting groupServiceForTesting(GroupsRepository groupRepo, OwnershipRepository ownershipRepository) { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy index 74ce22376..2c8440330 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy @@ -1,10 +1,8 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.AssertionConsumerServiceRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation @@ -18,109 +16,68 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownership import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceForTesting -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService import edu.internet2.tier.shibboleth.admin.ui.service.EntityService import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl +import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator +import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin +import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConversionUtils +import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Primary -import org.springframework.context.annotation.Profile -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.security.core.Authentication -import org.springframework.security.core.context.SecurityContext -import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration import org.springframework.test.web.servlet.setup.MockMvcBuilders import org.springframework.transaction.annotation.Transactional import org.springframework.web.client.RestTemplate import org.springframework.web.util.NestedServletException -import spock.lang.Specification import spock.lang.Subject import javax.persistence.EntityManager import static org.hamcrest.CoreMatchers.containsString -import static org.springframework.http.MediaType.* +import static org.springframework.http.MediaType.APPLICATION_JSON +import static org.springframework.http.MediaType.APPLICATION_XML import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, TestConfiguration, InternationalizationConfiguration, LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext -@ActiveProfiles(["edc-test"]) -class EntityDescriptorControllerTests extends Specification { +@ContextConfiguration(classes=[EDCLocalConfig]) +class EntityDescriptorControllerTests extends BaseDataJpaTestSetup { @Autowired EntityDescriptorRepository entityDescriptorRepository @Autowired EntityManager entityManager - + @Autowired EntityService entityService - - @Autowired - GroupServiceForTesting groupService - - @Autowired - OwnershipRepository ownershipRepository - - @Autowired - RoleRepository roleRepository @Autowired - JPAEntityDescriptorServiceImpl service - - @Autowired - UserRepository userRepository - + OpenSamlObjects openSamlObjects + @Autowired - UserService userService - + JPAEntityDescriptorServiceImpl jpaEntityDescriptorService + RandomGenerator randomGenerator TestObjectGenerator generator - def mapper - def mockRestTemplate = Mock(RestTemplate) - - def openSamlObjects = new OpenSamlObjects().with { - init() - it - } - def mockMvc @Subject def controller - Authentication authentication = Mock() - SecurityContext securityContext = Mock() EntityDescriptorVersionService versionService = Mock() @Transactional def setup() { - groupService.clearAllForTesting() - groupService.ensureAdminGroupExists() - - Group gb = new Group(); + openSamlObjects.init() + + Group gb = new Group() gb.setResourceId("testingGroupBBB") gb.setName("Group BBB") gb.setValidationRegex("^(?:https?:\\/\\/)?(?:[^.]+\\.)?shib\\.org(\\/.*)?\$") @@ -130,38 +87,12 @@ class EntityDescriptorControllerTests extends Specification { randomGenerator = new RandomGenerator() mapper = new ObjectMapper() - service.userService = userService - service.groupService = groupService - controller = new EntityDescriptorController(versionService) controller.openSamlObjects = openSamlObjects - controller.entityDescriptorService = service + controller.entityDescriptorService = jpaEntityDescriptorService controller.restTemplate = mockRestTemplate - mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); - - securityContext.getAuthentication() >> authentication - SecurityContextHolder.setContext(securityContext) - - if (roleRepository.count() == 0) { - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } - } - - Optional adminRole = roleRepository.findByName("ROLE_ADMIN") - User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo") - userService.save(adminUser) + mockMvc = MockMvcBuilders.standaloneSetup(controller).build() Optional userRole = roleRepository.findByName("ROLE_USER") User user = new User(username: "someUser", roles:[userRole.get()], password: "foo") @@ -172,11 +103,9 @@ class EntityDescriptorControllerTests extends Specification { EntityDescriptorConversionUtils.setEntityService(entityService) } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'DELETE as admin'() { given: - authentication.getName() >> 'admin' def entityDescriptor = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: false) entityDescriptorRepository.save(entityDescriptor) @@ -195,12 +124,9 @@ class EntityDescriptorControllerTests extends Specification { entityDescriptorRepository.findAll().size() == 0 } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptors with empty repository as admin'() { given: - authentication.getName() >> 'admin' - def expectedEmptyListResponseBody = '[]' def expectedResponseContentType = APPLICATION_JSON def expectedHttpResponseStatus = status().isOk() @@ -214,12 +140,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(content().json(expectedEmptyListResponseBody)) } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptors with 1 record in repository as admin'() { given: - authentication.getName() >> 'admin' - def entityDescriptor = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: "admingroup") entityDescriptorRepository.saveAndFlush(entityDescriptor) @@ -230,20 +153,16 @@ class EntityDescriptorControllerTests extends Specification { def result = mockMvc.perform(get('/api/EntityDescriptors')) then: - def mvcResult = result.andExpect(expectedHttpResponseStatus).andExpect(content().contentType(expectedResponseContentType)) - .andExpect(jsonPath("\$.[0].id").value("uuid-1")) - .andExpect(jsonPath("\$.[0].entityId").value("eid1")) - .andExpect(jsonPath("\$.[0].serviceEnabled").value(true)) - .andExpect(jsonPath("\$.[0].idOfOwner").value("admingroup")) + result.andExpect(expectedHttpResponseStatus).andExpect(content().contentType(expectedResponseContentType)) + .andExpect(jsonPath("\$.[0].id").value("uuid-1")) + .andExpect(jsonPath("\$.[0].entityId").value("eid1")) + .andExpect(jsonPath("\$.[0].serviceEnabled").value(true)) + .andExpect(jsonPath("\$.[0].idOfOwner").value("admingroup")) } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptors with 2 records in repository as admin'() { given: - authentication.getName() >> 'admin' - - def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: "admingroup") def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false, idOfOwner: "admingroup") @@ -269,12 +188,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(jsonPath("\$.[1].idOfOwner").value("admingroup")) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'POST create new - verifying validation on entityID and ACS locations'() { given: - authentication.getName() >> 'someUser' - def expectedEntityId = 'https://shib.org/blah/blah' EntityDescriptorRepresentation edRep = new EntityDescriptorRepresentation() edRep.setEntityId(expectedEntityId) @@ -322,12 +238,9 @@ class EntityDescriptorControllerTests extends Specification { } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'POST /EntityDescriptor and successfully create new record'() { given: - authentication.getName() >> 'admin' - def expectedEntityId = 'https://shib' def expectedSpName = 'sp1' def expectedResponseHeader = 'Location' @@ -361,12 +274,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(jsonPath("\$.idOfOwner").value("admingroup")) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'POST /EntityDescriptor as user disallows enabling'() { given: - authentication.getName() >> 'someUser' - def expectedEntityId = 'https://shib' def expectedSpName = 'sp1' @@ -393,19 +303,16 @@ class EntityDescriptorControllerTests extends Specification { then: try { - def exceptionExpected = mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody)) + mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody)) } catch (Exception e) { - e instanceof ForbiddenException == true + e instanceof ForbiddenException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'POST /EntityDescriptor record already exists'() { given: - authentication.getName() >> 'admin' - def postedJsonBody = """ { "serviceProviderName": "sp1", @@ -436,33 +343,27 @@ class EntityDescriptorControllerTests extends Specification { then: try { - def exceptionExpected = mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody)) + mockMvc.perform(post('/api/EntityDescriptor').contentType(APPLICATION_JSON).content(postedJsonBody)) } catch (Exception e) { - e instanceof EntityIdExistsException == true + e instanceof EntityIdExistsException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptor/{resourceId} non-existent'() { - when: - authentication.getName() >> 'admin' - - then: + expect: try { - def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/uuid-1")) + mockMvc.perform(get("/api/EntityDescriptor/uuid-1")) } catch (Exception e) { - e instanceof EntityNotFoundException == true + e instanceof EntityNotFoundException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptor/{resourceId} existing'() { given: - authentication.getName() >> 'admin' def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: "admingroup") entityDescriptorRepository.save(entityDescriptorOne) entityManager.flush() @@ -478,11 +379,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(jsonPath("\$.idOfOwner").value("admingroup")) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'GET /EntityDescriptor/{resourceId} existing, validate group access'() { given: - authentication.getName() >> 'someUser' Group g = userService.getCurrentUserGroup() def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: "someUser") @@ -494,7 +393,6 @@ class EntityDescriptorControllerTests extends Specification { ownershipRepository.saveAndFlush(new Ownership(g, entityDescriptorOne)) ownershipRepository.saveAndFlush(new Ownership(Group.ADMIN_GROUP, entityDescriptorTwo)) - when: def result = mockMvc.perform(get("/api/EntityDescriptor/uuid-1")) @@ -506,11 +404,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(jsonPath("\$.idOfOwner").value("someUser")) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'GET /EntityDescriptor/{resourceId} existing, owned by some other user'() { when: - authentication.getName() >> 'someUser' Group g = userService.getCurrentUserGroup() def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: g.getOwnerId()) @@ -524,18 +420,16 @@ class EntityDescriptorControllerTests extends Specification { then: try { - def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/uuid-2")) + mockMvc.perform(get("/api/EntityDescriptor/uuid-2")) } catch (Exception e) { - e instanceof ForbiddenException == true + e instanceof ForbiddenException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET /EntityDescriptor/{resourceId} existing (xml)'() { given: - authentication.getName() >> 'admin' def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true) entityDescriptorOne.setElementLocalName("EntityDescriptor") entityDescriptorOne.setNamespacePrefix("md") @@ -554,11 +448,9 @@ class EntityDescriptorControllerTests extends Specification { result.andExpect(status().isOk()).andExpect(content().xml(expectedXML)) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'GET /EntityDescriptor/{resourceId} existing (xml), user-owned'() { given: - authentication.getName() >> 'someUser' Group g = userService.getCurrentUserGroup() def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: g.getOwnerId()) @@ -579,11 +471,9 @@ class EntityDescriptorControllerTests extends Specification { result.andExpect(status().isOk()).andExpect(content().xml(expectedXML)) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def 'GET /EntityDescriptor/{resourceId} existing (xml), other user-owned'() { when: - authentication.getName() >> 'someUser' Group g = Group.ADMIN_GROUP def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: g.getOwnerId()) @@ -595,19 +485,16 @@ class EntityDescriptorControllerTests extends Specification { then: try { - def exceptionExpected = mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId").accept(APPLICATION_XML)) + mockMvc.perform(get("/api/EntityDescriptor/$providedResourceId").accept(APPLICATION_XML)) } catch (Exception e) { - e instanceof ForbiddenException == true + e instanceof ForbiddenException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "POST /EntityDescriptor handles XML happily"() { given: - authentication.getName() >> 'admin' - def postedBody = ''' @@ -648,11 +535,9 @@ class EntityDescriptorControllerTests extends Specification { } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "POST /EntityDescriptor returns error for duplicate entity id"() { when: - authentication.getName() >> 'admin' def postedBody = ''' @@ -682,26 +567,23 @@ class EntityDescriptorControllerTests extends Specification { then: try { - def exceptionExpected = mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName)) + mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName)) } catch (Exception e) { - e instanceof EntityIdExistsException == true + e instanceof EntityIdExistsException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "PUT /EntityDescriptor updates entity descriptors properly as admin"() { given: - authentication.getName() >> 'admin' - def entityDescriptorTwo = new EntityDescriptor(resourceId: 'uuid-2', entityID: 'eid2', serviceProviderName: 'sp2', serviceEnabled: false, idOfOwner: Group.ADMIN_GROUP.getOwnerId()) entityDescriptorTwo = entityDescriptorRepository.save(entityDescriptorTwo) entityManager.flush() entityManager.clear() - def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorTwo) + def updatedEntityDescriptorRepresentation = jpaEntityDescriptorService.createRepresentationFromDescriptor(entityDescriptorTwo) updatedEntityDescriptorRepresentation.setServiceProviderName("newName") def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation) @@ -716,11 +598,9 @@ class EntityDescriptorControllerTests extends Specification { .andExpect(jsonPath("\$.serviceProviderName").value("newName")) } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def "PUT /EntityDescriptor disallows non-admin user from enabling"() { given: - authentication.getName() >> 'someUser' Group g = userService.getCurrentUserGroup() def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: false, idOfOwner: g.getOwnerId()) @@ -730,24 +610,22 @@ class EntityDescriptorControllerTests extends Specification { when: entityDescriptorOne.serviceEnabled = true entityDescriptorOne.resourceId = 'uuid-1' - def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne) + def updatedEntityDescriptorRepresentation = jpaEntityDescriptorService.createRepresentationFromDescriptor(entityDescriptorOne) updatedEntityDescriptorRepresentation.version = entityDescriptorOne.hashCode() def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation) then: try { - def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody)) + mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody)) } catch (Exception e) { - e instanceof ForbiddenException == true + e instanceof ForbiddenException } } - @Rollback @WithMockUser(value = "someUser", roles = ["USER"]) def "PUT /EntityDescriptor denies the request if the PUTing user is not an ADMIN and not the createdBy user"() { given: - authentication.getName() >> 'someUser' Group g = userService.getCurrentUserGroup() def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: g.getOwnerId()) @@ -757,25 +635,22 @@ class EntityDescriptorControllerTests extends Specification { when: entityDescriptorOne.serviceProviderName = 'foo' entityDescriptorOne.resourceId = 'uuid-1' - def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne) + def updatedEntityDescriptorRepresentation = jpaEntityDescriptorService.createRepresentationFromDescriptor(entityDescriptorOne) updatedEntityDescriptorRepresentation.version = entityDescriptorOne.hashCode() def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation) then: try { - def exceptionExpected = mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody)) + mockMvc.perform(put("/api/EntityDescriptor/uuid-1").contentType(APPLICATION_JSON).content(postedJsonBody)) } catch (Exception e) { - e instanceof ForbiddenException == true + e instanceof ForbiddenException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "PUT /EntityDescriptor throws a concurrent mod exception if the version numbers don't match"() { - given: - authentication.getName() >> 'admin' - + given: def entityDescriptorOne = new EntityDescriptor(resourceId: 'uuid-1', entityID: 'eid1', serviceProviderName: 'sp1', serviceEnabled: true, idOfOwner: Group.ADMIN_GROUP.getOwnerId()) entityDescriptorOne = entityDescriptorRepository.save(entityDescriptorOne) entityManager.flush() @@ -783,32 +658,30 @@ class EntityDescriptorControllerTests extends Specification { when: entityDescriptorOne.serviceProviderName = 'foo' entityDescriptorOne.resourceId = 'uuid-1' - def updatedEntityDescriptorRepresentation = service.createRepresentationFromDescriptor(entityDescriptorOne) + def updatedEntityDescriptorRepresentation = jpaEntityDescriptorService.createRepresentationFromDescriptor(entityDescriptorOne) def postedJsonBody = mapper.writeValueAsString(updatedEntityDescriptorRepresentation) then: try { - def exception = mockMvc.perform(put("/api/EntityDescriptor/$resourceId").contentType(APPLICATION_JSON).content(postedJsonBody)) + mockMvc.perform(put("/api/EntityDescriptor/$resourceId").contentType(APPLICATION_JSON).content(postedJsonBody)) } catch (Exception e) { - e instanceof ConcurrentModificationException == true + e instanceof ConcurrentModificationException } } - - @org.springframework.boot.test.context.TestConfiguration - @Profile(value = "edc-test") - static class LocalConfig { + + @TestConfiguration + private static class EDCLocalConfig { + @Bean + JPAEntityServiceImpl jpaEntityService(OpenSamlObjects openSamlObjects, AttributeUtility attributeUtility, + CustomPropertiesConfiguration customPropertiesConfiguration) { + return new JPAEntityServiceImpl(openSamlObjects, attributeUtility, customPropertiesConfiguration) + } + @Bean - @Primary - GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { - GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - }) - result.ensureAdminGroupExists() - return result + ModelRepresentationConversions modelRepresentationConversions(CustomPropertiesConfiguration customPropertiesConfiguration) { + return new ModelRepresentationConversions(customPropertiesConfiguration) } } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy index d9fb504f8..0f29b12d2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersControllerTests.groovy @@ -2,39 +2,29 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration -import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository -import edu.internet2.tier.shibboleth.admin.ui.security.model.Role -import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService -import edu.internet2.tier.shibboleth.admin.ui.service.FilterService -import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService +import edu.internet2.tier.shibboleth.admin.ui.service.* import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator +import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin import edu.internet2.tier.shibboleth.admin.util.AttributeUtility +import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions import groovy.json.JsonOutput import groovy.json.JsonSlurper import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.security.test.context.support.WithMockUser +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean import org.springframework.test.context.ContextConfiguration import org.springframework.test.web.servlet.setup.MockMvcBuilders import org.springframework.transaction.annotation.Transactional import org.w3c.dom.Document -import spock.lang.Specification import spock.lang.Unroll import static org.hamcrest.CoreMatchers.containsString @@ -42,14 +32,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* -/** - * @author Bill Smith (wsmith@unicon.net) - */ -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, TestConfiguration, InternationalizationConfiguration]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -class MetadataFiltersControllerTests extends Specification { +@ContextConfiguration(classes=[MFCLocalConfig]) +class MetadataFiltersControllerTests extends BaseDataJpaTestSetup { @Autowired AttributeUtility attributeUtility @@ -60,15 +44,6 @@ class MetadataFiltersControllerTests extends Specification { @Autowired FilterService filterService - @Autowired - IGroupService groupService - - @Autowired - RoleRepository roleRepository - - @Autowired - UserService userService - TestObjectGenerator testObjectGenerator RandomGenerator randomGenerator ObjectMapper mapper @@ -85,7 +60,6 @@ class MetadataFiltersControllerTests extends Specification { @Transactional def setup() { - groupService.ensureAdminGroupExists() randomGenerator = new RandomGenerator() testObjectGenerator = new TestObjectGenerator(attributeUtility, customPropertiesConfiguration) mapper = new ObjectMapper() @@ -115,34 +89,9 @@ class MetadataFiltersControllerTests extends Specification { } ) mockMvc = MockMvcBuilders.standaloneSetup(controller).build() - - roleRepository.deleteAll() - roleRepository.flush() - if (roleRepository.count() == 0) { - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }] - roles.each { - roleRepository.save(it) - } - } - roleRepository.flush() - - def users = [new User().with { - username = 'admin' - password = '{noop}adminpass' - firstName = 'Joe' - lastName = 'Doe' - emailAddress = 'joe@institution.edu' - roles.add(roleRepository.findByName('ROLE_ADMIN').get()) - it - }] - users.each { - it = userService.save(it) - } } + @WithMockAdmin def "FilterController.getAll gets all available types of filters"() { given: def metadataResolver = new MetadataResolver() @@ -162,6 +111,7 @@ class MetadataFiltersControllerTests extends Specification { .andExpect(content().json(mapper.writeValueAsString(expectedContent))) } + @WithMockAdmin def "FilterController.getOne gets the desired filter"() { given: def metadataResolver = new MetadataResolver() @@ -184,7 +134,7 @@ class MetadataFiltersControllerTests extends Specification { } @Unroll - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "FilterController.create creates the desired filter (filterType: #filterType)"(String filterType) { given: def randomFilter = testObjectGenerator.buildRandomFilterOfType(filterType) @@ -227,14 +177,14 @@ class MetadataFiltersControllerTests extends Specification { } @Unroll - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def "FilterController.update updates the target #filterType filter as desired"(String filterType) { given: def originalFilter = testObjectGenerator.buildRandomFilterOfType(filterType) def updatedFilter = testObjectGenerator.copyOf(originalFilter) updatedFilter.name = 'Updated Filter' updatedFilter.version = originalFilter.hashCode() - def postedJsonBody = mapper.writeValueAsString(updatedFilter) + def updatedFilterJson = mapper.writeValueAsString(updatedFilter) def originalMetadataResolver = new MetadataResolver() originalMetadataResolver.setResourceId('foo') @@ -252,13 +202,11 @@ class MetadataFiltersControllerTests extends Specification { def filterUUID = updatedFilter.getResourceId() when: - def result = mockMvc.perform( - put("$BASE_URI/foo/Filters/$filterUUID") - .contentType(APPLICATION_JSON) - .content(postedJsonBody)) + def result = mockMvc.perform(put("$BASE_URI/foo/Filters/$filterUUID") + .contentType(APPLICATION_JSON).content(updatedFilterJson)) then: - def expectedJson = new JsonSlurper().parseText(postedJsonBody) + def expectedJson = new JsonSlurper().parseText(updatedFilterJson) expectedJson << [version: updatedFilter.getVersion()] result.andExpect(status().isOk()) .andExpect(content().json(JsonOutput.toJson(expectedJson), true)) @@ -272,6 +220,7 @@ class MetadataFiltersControllerTests extends Specification { 'nameIdFormat' | _ } + @WithMockAdmin def "FilterController.update filter 409's if the version numbers don't match"() { given: def randomFilter = testObjectGenerator.entityAttributesFilter() @@ -297,4 +246,34 @@ class MetadataFiltersControllerTests extends Specification { then: result.andExpect(status().is(409)) } + + @TestConfiguration + private static class MFCLocalConfig { + @Bean + JPAFilterTargetServiceImpl jpaFilterTargetService() { + return new JPAFilterTargetServiceImpl() + } + + @Bean + JPAEntityServiceImpl jpaEntityService(OpenSamlObjects openSamlObjects, AttributeUtility attributeUtility, + CustomPropertiesConfiguration customPropertiesConfiguration) { + return new JPAEntityServiceImpl(openSamlObjects, attributeUtility,customPropertiesConfiguration) + } + + @Bean + JPAFilterServiceImpl jpaFilterService(EntityDescriptorService entityDescriptorService, EntityService entityService, + FilterTargetService filterTargetService) { + return new JPAFilterServiceImpl().with { + it.entityDescriptorService = entityDescriptorService + it.entityService = entityService + it.filterTargetService = filterTargetService + it + } + } + + @Bean + ModelRepresentationConversions modelRepresentationConversions(CustomPropertiesConfiguration customPropertiesConfiguration) { + return new ModelRepresentationConversions(customPropertiesConfiguration) + } + } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy index 623f4717a..107675729 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy @@ -6,7 +6,11 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.* import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.* +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataQueryProtocolScheme +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.MetadataResolverValidationService import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository @@ -35,10 +39,9 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* @ContextConfiguration(classes=[MetadataResolverValidationConfiguration, MetadataResolverConverterConfiguration, - SearchConfiguration, MetadataResolverConfiguration, EntitiesVersioningConfiguration, + MetadataResolverConfiguration, EntitiesVersioningConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration, - PlaceholderResolverComponentsConfiguration, MRCILocalConfig, CustomPropertiesConfiguration]) -@ActiveProfiles(["no-auth"]) + PlaceholderResolverComponentsConfiguration, MRCILocalConfig]) class MetadataResolversControllerIntegrationTests extends BaseDataJpaTestSetup { @Autowired AttributeUtility attributeUtility @@ -351,11 +354,6 @@ class MetadataResolversControllerIntegrationTests extends BaseDataJpaTestSetup { @TestConfiguration private static class MRCILocalConfig { - @Bean - public AttributeUtility attributeUtility(OpenSamlObjects openSamlObjects) { - return new AttributeUtility(openSamlObjects); - } - @Bean DirectoryService directoryService() { return new DirectoryServiceImpl() @@ -395,14 +393,14 @@ class MetadataResolversControllerIntegrationTests extends BaseDataJpaTestSetup { } @Bean - public ModelRepresentationConversions modelRepresentationConversions(CustomPropertiesConfiguration customPropertiesConfiguration) { - return new ModelRepresentationConversions(customPropertiesConfiguration); + ModelRepresentationConversions modelRepresentationConversions(CustomPropertiesConfiguration customPropertiesConfiguration) { + return new ModelRepresentationConversions(customPropertiesConfiguration) } @Bean - public MetadataResolversPositionOrderContainerService metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository, - MetadataResolverRepository resolverRepository) { - return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository); + MetadataResolversPositionOrderContainerService metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository, + MetadataResolverRepository resolverRepository) { + return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository) } } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/filters/PolymorphicFiltersJacksonHandlingTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/filters/PolymorphicFiltersJacksonHandlingTests.groovy index 9c1ba5342..b995923f9 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/filters/PolymorphicFiltersJacksonHandlingTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/filters/PolymorphicFiltersJacksonHandlingTests.groovy @@ -2,6 +2,7 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.filters import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator @@ -10,26 +11,20 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import spock.lang.Specification -@SpringBootTest -class PolymorphicFiltersJacksonHandlingTests extends Specification { - - ObjectMapper mapper - +class PolymorphicFiltersJacksonHandlingTests extends BaseDataJpaTestSetup { + @Autowired AttributeUtility attributeUtility @Autowired CustomPropertiesConfiguration customPropertiesConfiguration + ObjectMapper mapper TestObjectGenerator testObjectGenerator def setup() { mapper = new ObjectMapper() mapper.enable(SerializationFeature.INDENT_OUTPUT) - attributeUtility = new AttributeUtility(new OpenSamlObjects().with { - it.init() - it - }) testObjectGenerator = new TestObjectGenerator(attributeUtility, customPropertiesConfiguration) } @@ -216,4 +211,4 @@ class PolymorphicFiltersJacksonHandlingTests extends Specification { deSerializedFilter instanceof NameIdFormatFilter roundTripFilter instanceof NameIdFormatFilter } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/PolymorphicResolversJacksonHandlingTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/PolymorphicResolversJacksonHandlingTests.groovy index f22c875aa..358e11f4c 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/PolymorphicResolversJacksonHandlingTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/PolymorphicResolversJacksonHandlingTests.groovy @@ -2,36 +2,28 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter -import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import spock.lang.Specification - -@SpringBootTest -class PolymorphicResolversJacksonHandlingTests extends Specification { - - ObjectMapper mapper +class PolymorphicResolversJacksonHandlingTests extends BaseDataJpaTestSetup { + @Autowired AttributeUtility attributeUtility @Autowired CustomPropertiesConfiguration customPropertiesConfiguration + ObjectMapper mapper TestObjectGenerator testObjectGenerator def setup() { mapper = new ObjectMapper() mapper.enable(SerializationFeature.INDENT_OUTPUT) - attributeUtility = new AttributeUtility(new OpenSamlObjects().with { - it.init() - it - }) testObjectGenerator = new TestObjectGenerator(attributeUtility, customPropertiesConfiguration) } @@ -361,4 +353,4 @@ class PolymorphicResolversJacksonHandlingTests extends Specification { deSerializedResolver.metadataFilters[0] instanceof EntityAttributesFilter deSerializedResolver.metadataFilters[1] instanceof EntityRoleWhiteListFilter } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy index 8f69e2424..b61566034 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/EntityDescriptorRepositoryTest.groovy @@ -1,76 +1,36 @@ package edu.internet2.tier.shibboleth.admin.ui.repository -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.security.model.Group -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionServiceImpl import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService -import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl import org.apache.lucene.analysis.Analyzer import org.apache.lucene.analysis.en.EnglishAnalyzer import org.opensaml.saml.metadata.resolver.MetadataResolver import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Profile -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -import java.util.stream.Stream import javax.persistence.EntityManager +import java.util.stream.Stream -/** - * A highly unnecessary test so that I can check to make sure that persistence is correct for the model - */ -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, InternationalizationConfiguration, LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) -@ActiveProfiles(value = "local") -class EntityDescriptorRepositoryTest extends Specification { +@ContextConfiguration(classes = [EDRLocalConfig]) +class EntityDescriptorRepositoryTest extends BaseDataJpaTestSetup { @Autowired EntityDescriptorRepository entityDescriptorRepository @Autowired - private CustomEntityAttributeDefinitionRepository repository; - - @Autowired - EntityManager entityManager - - @Autowired - RoleRepository roleRepository + EntityDescriptorService entityDescriptorService @Autowired - UserRepository userRepository - - @Autowired - GroupsRepository groupRepository - - OpenSamlObjects openSamlObjects = new OpenSamlObjects().with { - it.init() - it - } + EntityManager entityManager @Autowired - EntityDescriptorService service + OpenSamlObjects openSamlObjects def "SHIBUI-553.2"() { when: @@ -102,7 +62,7 @@ class EntityDescriptorRepositoryTest extends Specification { then: noExceptionThrown() } - + def "SHIBUI-1849 - extend data model for ownership"() { given: def group = new Group().with { @@ -110,39 +70,38 @@ class EntityDescriptorRepositoryTest extends Specification { it.description = "some description" it } - group = groupRepository.saveAndFlush(group) + group = groupService.createGroup(group) - def gList = groupRepository.findAll() + def gList = groupService.findAll() def groupFromDb = gList.get(0).asType(Group) - + def ed = openSamlObjects.unmarshalFromXml(this.class.getResource('/metadata/SHIBUI-553.2.xml').bytes) as EntityDescriptor ed.with { it.idOfOwner = groupFromDb.resourceId } entityDescriptorRepository.saveAndFlush(ed) - + when: - def edStreamFromDb = entityDescriptorRepository.findAllStreamByIdOfOwner(null); - + def edStreamFromDb = entityDescriptorRepository.findAllStreamByIdOfOwner(null) + then: - ((Stream)edStreamFromDb).count() == 0 - + ((Stream) edStreamFromDb).count() == 0 + when: - def edStreamFromDb2 = entityDescriptorRepository.findAllStreamByIdOfOwner("random value"); - + def edStreamFromDb2 = entityDescriptorRepository.findAllStreamByIdOfOwner("random value") + then: - ((Stream)edStreamFromDb2).count() == 0 - + ((Stream) edStreamFromDb2).count() == 0 + when: - def edStreamFromDb3 = entityDescriptorRepository.findAllStreamByIdOfOwner(groupFromDb.resourceId); - + def edStreamFromDb3 = entityDescriptorRepository.findAllStreamByIdOfOwner(groupFromDb.resourceId) + then: - ((Stream)edStreamFromDb3).count() == 1 + ((Stream) edStreamFromDb3).count() == 1 } @TestConfiguration - @Profile("local") - static class LocalConfig { + private static class EDRLocalConfig { @Bean MetadataResolver metadataResolver() { new OpenSamlChainingMetadataResolver().with { @@ -156,23 +115,14 @@ class EntityDescriptorRepositoryTest extends Specification { Analyzer analyzer() { return new EnglishAnalyzer() } - - @Bean - GroupServiceImpl groupService(GroupsRepository repo, OwnershipRepository ownershipRepository) { - new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - } - } - + @Bean - CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl() { + CustomEntityAttributesDefinitionServiceImpl customEntityAttributesDefinitionServiceImpl(EntityManager entityManager, CustomEntityAttributeDefinitionRepository customEntityAttributeDefinitionRepository) { new CustomEntityAttributesDefinitionServiceImpl().with { - it.entityManager = entityManager - it.repository = repository - return it + it.entityManager = entityManager + it.repository = customEntityAttributeDefinitionRepository + return it } } } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy index 0f1305c51..35bfe8e32 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy @@ -1,27 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.security.controller -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* - -import javax.persistence.EntityManager - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.http.HttpStatus -import org.springframework.http.MediaType -import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.setup.MockMvcBuilders - -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException @@ -29,79 +8,41 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService +import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin import groovy.json.JsonOutput -import spock.lang.Specification +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import org.springframework.transaction.annotation.Transactional -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, TestConfiguration, InternationalizationConfiguration, SearchConfiguration]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext -class GroupsControllerIntegrationTests extends Specification { - @Autowired - EntityManager entityManager +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* +class GroupsControllerIntegrationTests extends BaseDataJpaTestSetup { @Autowired GroupsRepository groupsRepository - - @Autowired - GroupServiceImpl groupService - - @Autowired - RoleRepository roleRepository - - @Autowired - UserRepository userRepository - - @Autowired - UserService userService - + static RESOURCE_URI = '/api/admin/groups' - def MockMvc mockMvc - + MockMvc mockMvc + + @Transactional def setup() { - groupService.ensureAdminGroupExists() - - def GroupController groupController = new GroupController().with ({ + GroupController groupController = new GroupController().with ({ it.groupService = this.groupService it }) - mockMvc = MockMvcBuilders.standaloneSetup(groupController).build(); - - if (roleRepository.count() == 0) { - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } + mockMvc = MockMvcBuilders.standaloneSetup(groupController).build() + + if (userRepository.findByUsername("someUser").isEmpty()) { + Optional userRole = roleRepository.findByName("ROLE_USER") + User user = new User(username: "someUser", roles: [userRole.get()], password: "foo") + userService.save(user) } - - Optional adminRole = roleRepository.findByName("ROLE_ADMIN") - User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo") - userService.save(adminUser) - - Optional userRole = roleRepository.findByName("ROLE_USER") - User user = new User(username: "someUser", roles:[userRole.get()], password: "foo") - user = userService.save(user) - entityManager.flush() } - - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'POST new group persists properly'() { given: def newGroup = [name: 'Foo', @@ -130,18 +71,17 @@ class GroupsControllerIntegrationTests extends Specification { mockMvc.perform(post(RESOURCE_URI).contentType(MediaType.APPLICATION_JSON) .content(JsonOutput.toJson(newGroup)) .accept(MediaType.APPLICATION_JSON)) - 1 == 2 + false } catch (Throwable expected) { expected instanceof GroupExistsConflictException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'PUT (update) existing group persists properly'() { given: groupsRepository.deleteByResourceId("AAA") - def Group groupAAA = new Group().with({ + Group groupAAA = new Group().with({ it.name = "AAA" it.description = "AAA" it.resourceId = "AAA" @@ -172,26 +112,25 @@ class GroupsControllerIntegrationTests extends Specification { mockMvc.perform(put(RESOURCE_URI).contentType(MediaType.APPLICATION_JSON) .content(JsonOutput.toJson(newGroup)) .accept(MediaType.APPLICATION_JSON)) - 1 == 2 + false } catch (Throwable expected) { expected instanceof EntityNotFoundException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET checks for groups (when there are existing groups)'() { given: groupsRepository.deleteByResourceId("AAA") groupsRepository.deleteByResourceId("BBB") - def Group groupAAA = new Group().with({ + Group groupAAA = new Group().with({ it.name = "AAA" it.description = "AAA" it.resourceId = "AAA" it }) groupsRepository.save(groupAAA) - def Group groupBBB = new Group().with({ + Group groupBBB = new Group().with({ it.name = "BBB" it.description = "BBB" it.resourceId = "BBB" @@ -214,32 +153,28 @@ class GroupsControllerIntegrationTests extends Specification { // 'GET request for a single non-existent group in a system that has groups' try { mockMvc.perform(get("$RESOURCE_URI/CCC")) - 1 == 2 + false } catch (Throwable expected) { expected instanceof EntityNotFoundException } } - @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'DELETE performs correctly when group attached to a user'() { // When the user is created in the setup method above, a new group "someUser" is created to be associated with that user // User user = new User(username: "someUser", roles:[userRole.get()], password: "foo") // userService.save(user) - - when: 'try to delete group that is attached to a user' - def nothingtodo - - then: + + expect: try { mockMvc.perform(delete("$RESOURCE_URI/someUser")) - 1 == 2 + false } catch(Throwable expected) { expected instanceof GroupDeleteException } when: - def Group groupAAA = new Group().with({ + Group groupAAA = new Group().with({ it.name = "AAA" it.description = "AAA" it.resourceId = "AAA" @@ -247,11 +182,11 @@ class GroupsControllerIntegrationTests extends Specification { }) groupAAA = groupsRepository.save(groupAAA) - def User user = userRepository.findByUsername("someUser").get() + User user = userRepository.findByUsername("someUser").get() user.setGroup(groupAAA) userService.save(user) then: mockMvc.perform(delete("$RESOURCE_URI/someUser")) } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy index f1bd5a591..fb4ad9a10 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersControllerIntegrationTests.groovy @@ -1,83 +1,44 @@ package edu.internet2.tier.shibboleth.admin.ui.security.controller -import java.time.LocalDateTime -import java.time.format.DateTimeFormatter - +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup +import edu.internet2.tier.shibboleth.admin.ui.controller.support.RestControllersSupport +import edu.internet2.tier.shibboleth.admin.ui.security.model.Group +import edu.internet2.tier.shibboleth.admin.ui.security.model.User +import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository +import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin +import groovy.json.JsonOutput import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Profile -import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.http.MediaType import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder -import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.setup.MockMvcBuilders import org.springframework.transaction.annotation.Transactional +import org.springframework.web.client.HttpClientErrorException +import org.springframework.web.util.NestedServletException -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.SerializationFeature -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer - -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration -import edu.internet2.tier.shibboleth.admin.ui.controller.support.RestControllersSupport -import edu.internet2.tier.shibboleth.admin.ui.security.model.Group -import edu.internet2.tier.shibboleth.admin.ui.security.model.Role -import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceForTesting -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService -import groovy.json.JsonOutput -import spock.lang.Specification +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter -import static org.springframework.http.MediaType.* import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.* -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, TestConfiguration, InternationalizationConfiguration, SearchConfiguration, LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext -@ActiveProfiles(["no-auth", "local"]) -@ComponentScan(basePackages="{ edu.internet2.tier.shibboleth.admin.ui.configuration }") -class UsersControllerIntegrationTests extends Specification { +@ContextConfiguration(classes=[UCILocalConfig]) +class UsersControllerIntegrationTests extends BaseDataJpaTestSetup { @Autowired GroupsRepository groupsRepository - - @Autowired - GroupServiceForTesting groupService - - @Autowired - def ObjectMapper mapper - - @Autowired - OwnershipRepository ownershipRepository - - @Autowired - RoleRepository roleRepository - - @Autowired - UserRepository userRepository - + @Autowired - UserService userService + ObjectMapper mapper - def MockMvc mockMvc + MockMvc mockMvc def users static RESOURCE_URI = '/api/admin/users' @@ -95,10 +56,6 @@ class UsersControllerIntegrationTests extends Specification { } userRepository.flush() - roleRepository.deleteAll() - roleRepository.flush() - groupService.clearAllForTesting() //leaves us just the admingroup - def groups = [ new Group().with { it.name = "A1" @@ -116,27 +73,11 @@ class UsersControllerIntegrationTests extends Specification { try { groupsRepository.save(it) } catch (Throwable e) { - // Must already exist (from a unit test) + // ??? } } groupsRepository.flush() - if (roleRepository.count() == 0) { - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } - } - roleRepository.flush() if (userRepository.count() == 0) { users = [new User().with { username = 'admin' @@ -172,12 +113,12 @@ class UsersControllerIntegrationTests extends Specification { it }] users.each { - it = userService.save(it) + userService.save(it) } } } - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET ALL users (when there are existing users)'() { // given: users created in setup @@ -204,7 +145,7 @@ class UsersControllerIntegrationTests extends Specification { .andExpect(jsonPath("\$.[3].groupId").value("admingroup")) } - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET ONE existing user'() { when: 'GET request is made for one existing user' def result = mockMvc.perform(get("$RESOURCE_URI/admin")) @@ -218,7 +159,7 @@ class UsersControllerIntegrationTests extends Specification { .andExpect(jsonPath("\$.groupId").value("admingroup")) } - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'GET ONE NON-existing user'() { when: 'GET request is made for one NON-existing user' def result = mockMvc.perform(get("$RESOURCE_URI/bogus")) @@ -228,7 +169,7 @@ class UsersControllerIntegrationTests extends Specification { } @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'DELETE ONE existing user'() { when: 'GET request is made for one existing user' def result = mockMvc.perform(get("$RESOURCE_URI/nonadmin")) @@ -244,16 +185,16 @@ class UsersControllerIntegrationTests extends Specification { // 'GET request is made for the deleted user' try { - result = mockMvc.perform(get("$RESOURCE_URI/nonadmin")) + mockMvc.perform(get("$RESOURCE_URI/nonadmin")) false } - catch (org.springframework.web.util.NestedServletException expectedResult) { - expectedResult.getCause() instanceof org.springframework.web.client.HttpClientErrorException + catch (NestedServletException expectedResult) { + expectedResult.getCause() instanceof HttpClientErrorException } } @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'POST new user persists properly'() { given: def newUser = [firstName: 'Foo', @@ -274,7 +215,7 @@ class UsersControllerIntegrationTests extends Specification { } @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'POST new duplicate username returns 409'() { given: def newUser = [firstName: 'Foo', @@ -299,11 +240,11 @@ class UsersControllerIntegrationTests extends Specification { } @Rollback - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'PATCH updates user properly'() { given: - def String userString = mockMvc.perform(get("$RESOURCE_URI/none")).andReturn().getResponse().getContentAsString() - def User user = mapper.readValue(userString, User.class); + String userString = mockMvc.perform(get("$RESOURCE_URI/none")).andReturn().getResponse().getContentAsString() + User user = mapper.readValue(userString, User.class) user.setFirstName("somethingnew") when: @@ -344,7 +285,7 @@ class UsersControllerIntegrationTests extends Specification { } - @WithMockUser(value = "admin", roles = ["ADMIN"]) + @WithMockAdmin def 'PATCH detects unknown username'() { given: def newUser = [firstName: 'Foo', @@ -363,26 +304,14 @@ class UsersControllerIntegrationTests extends Specification { result.andExpect(status().isNotFound()) } - @org.springframework.boot.test.context.TestConfiguration - @Profile(value = "local") - static class LocalConfig { - @Bean - GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { - GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - }) - result.ensureAdminGroupExists() - return result - } - + @TestConfiguration + private static class UCILocalConfig { @Bean ObjectMapper objectMapper() { JavaTimeModule module = new JavaTimeModule() LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")) module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer) - + return Jackson2ObjectMapperBuilder.json().modules(module).featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).build() } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepositoryTests.groovy index aba53121e..14f2f3911 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/GroupsRepositoryTests.groovy @@ -1,21 +1,11 @@ package edu.internet2.tier.shibboleth.admin.ui.security.repository -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownership -import edu.internet2.tier.shibboleth.admin.ui.security.model.listener.GroupUpdatedEntityListener import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.boot.test.context.TestConfiguration -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Profile import org.springframework.dao.DataIntegrityViolationException -import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification import javax.transaction.Transactional @@ -23,18 +13,10 @@ import javax.transaction.Transactional * Tests to validate the repo and model for groups * @author chasegawa */ -@DataJpaTest -@ContextConfiguration(classes=[InternationalizationConfiguration, LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@ActiveProfiles(["test","gr-tests"]) -class GroupsRepositoryTests extends Specification { +class GroupsRepositoryTests extends BaseDataJpaTestSetup { @Autowired GroupsRepository groupsRepo - - @Autowired - OwnershipRepository ownershipRepository - + @Transactional def setup() { groupsRepo.deleteAll() @@ -87,7 +69,7 @@ class GroupsRepositoryTests extends Specification { ownershipRepository.save(it) } } - + def "group ownership tests"() { when: "Simple create test" def group = new Group().with { @@ -107,7 +89,6 @@ class GroupsRepositoryTests extends Specification { } } - @Rollback def "simple create test"() { given: def group = new Group().with { @@ -131,12 +112,12 @@ class GroupsRepositoryTests extends Specification { // save check def gList = groupsRepo.findAll() gList.size() == 1 - def groupFromDb = gList.get(0).asType(Group) - groupFromDb.equals(group) + def groupFromDb = gList.get(0) as Group + groupFromDb == group // fetch checks groupsRepo.findByResourceId("not an id") == null - groupsRepo.findByResourceId(groupFromDb.resourceId).equals(group) + groupsRepo.findByResourceId(groupFromDb.resourceId) == group } def "expected error"() { @@ -155,14 +136,13 @@ class GroupsRepositoryTests extends Specification { // save check when: - def savedGroup = groupsRepo.save(group) + groupsRepo.save(group) then: // Missing non-nullable field (name) should thrown error - final def exception = thrown(DataIntegrityViolationException) + thrown(DataIntegrityViolationException) } - @Rollback def "basic CRUD operations validated"() { given: def group = new Group().with { @@ -186,8 +166,8 @@ class GroupsRepositoryTests extends Specification { // save check def gList = groupsRepo.findAll() gList.size() == 1 - def groupFromDb = gList.get(0).asType(Group) - groupFromDb.equals(group) == true + def groupFromDb = gList.get(0) as Group + groupFromDb == group // update check groupFromDb.with { @@ -201,9 +181,9 @@ class GroupsRepositoryTests extends Specification { then: def gList2 = groupsRepo.findAll() gList2.size() == 1 - def groupFromDb2 = gList2.get(0).asType(Group) + def groupFromDb2 = gList2.get(0) as Group groupFromDb2.equals(group) == false - groupFromDb2.equals(groupFromDb) == true + groupFromDb2 == groupFromDb // delete tests when: @@ -218,15 +198,4 @@ class GroupsRepositoryTests extends Specification { then: nothingThere == null } - - @TestConfiguration - @Profile("gr-tests") - static class LocalConfig { - @Bean - GroupUpdatedEntityListener groupUpdatedEntityListener(OwnershipRepository repo) { - GroupUpdatedEntityListener result = new GroupUpdatedEntityListener() - result.init(repo) - return result - } - } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/OwnershipRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/OwnershipRepositoryTests.groovy index 196dd29f4..6d3f49a2b 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/OwnershipRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/repository/OwnershipRepositoryTests.groovy @@ -1,36 +1,17 @@ package edu.internet2.tier.shibboleth.admin.ui.security.repository -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ContextConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup +import edu.internet2.tier.shibboleth.admin.ui.security.model.* import org.springframework.transaction.annotation.Transactional -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownable -import edu.internet2.tier.shibboleth.admin.ui.security.model.OwnableType -import edu.internet2.tier.shibboleth.admin.ui.security.model.Owner -import edu.internet2.tier.shibboleth.admin.ui.security.model.OwnerType -import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownership -import spock.lang.Specification - /** * Tests to validate the repo and model for groups * @author chasegawa */ -@DataJpaTest -@ContextConfiguration(classes=[InternationalizationConfiguration]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -class OwnershipRepositoryTests extends Specification { - @Autowired - OwnershipRepository repo - +class OwnershipRepositoryTests extends BaseDataJpaTestSetup { @Transactional def setup() { - repo.deleteAll() + ownershipRepository.deleteAll() def ownerships = [ new Ownership().with { it.ownedId = "aaa" @@ -76,21 +57,20 @@ class OwnershipRepositoryTests extends Specification { } ] ownerships.each { - repo.save(it) + ownershipRepository.save(it) } } - - @Rollback + def "test clearUsersGroups"() { when: "remove entries where the user is the owned object of a group" - repo.clearUsersGroups("aaa") - def result = repo.findAllGroupsForUser("aaa") + ownershipRepository.clearUsersGroups("aaa") + def result = ownershipRepository.findAllGroupsForUser("aaa") then: result.size() == 0 when: "find objects owned by user aaa has not changed" - result = repo.findOwnedByUser("aaa") + result = ownershipRepository.findOwnedByUser("aaa") then: result.size() == 1 @@ -102,27 +82,26 @@ class OwnershipRepositoryTests extends Specification { } when: "remove entries where the user is the owned object of groups" - repo.clearUsersGroups("ccc") - result = repo.findAllGroupsForUser("ccc") + ownershipRepository.clearUsersGroups("ccc") + result = ownershipRepository.findAllGroupsForUser("ccc") then: result.size() == 0 } - @Rollback def "test deleteEntriesForOwnedObject"() { when: "remove entries where the user is the owned object of a group" - repo.deleteEntriesForOwnedObject(new Ownable() { + ownershipRepository.deleteEntriesForOwnedObject(new Ownable() { String getObjectId() { return "aaa" } OwnableType getOwnableType() { OwnableType.USER } }) - def result = repo.findAllGroupsForUser("aaa") + def result = ownershipRepository.findAllGroupsForUser("aaa") then: result.size() == 0 when: "find objects owned by user aaa has not changed" - result = repo.findOwnedByUser("aaa") + result = ownershipRepository.findOwnedByUser("aaa") then: result.size() == 1 @@ -134,11 +113,11 @@ class OwnershipRepositoryTests extends Specification { } when: "remove entries where the user is the owned object of groups" - repo.deleteEntriesForOwnedObject(new Ownable() { + ownershipRepository.deleteEntriesForOwnedObject(new Ownable() { String getObjectId() { return "ccc" } OwnableType getOwnableType() { OwnableType.USER } }) - result = repo.findAllGroupsForUser("ccc") + result = ownershipRepository.findAllGroupsForUser("ccc") then: result.size() == 0 @@ -150,7 +129,7 @@ class OwnershipRepositoryTests extends Specification { userIds.add("aaa") userIds.add("bbb") userIds.add("ccc") - def result = repo.findUsersByOwner(new Owner() { + def result = ownershipRepository.findUsersByOwner(new Owner() { String getOwnerId() { return "g1" } OwnerType getOwnerType() { OwnerType.GROUP } }) @@ -163,7 +142,7 @@ class OwnershipRepositoryTests extends Specification { } when: - result = repo.findUsersByOwner(new Owner() { + result = ownershipRepository.findUsersByOwner(new Owner() { String getOwnerId() { return "aaa" } OwnerType getOwnerType() { return OwnerType.USER } }) @@ -174,7 +153,7 @@ class OwnershipRepositoryTests extends Specification { def "test findOwnedByUser"() { when: "find objects owned by user" - def result = repo.findOwnedByUser("aaa") + def result = ownershipRepository.findOwnedByUser("aaa") then: result.size() == 1 @@ -191,7 +170,7 @@ class OwnershipRepositoryTests extends Specification { ArrayList groupIds = new ArrayList<>() groupIds.add("g1") groupIds.add("g2") - def result = repo.findOwnableObjectOwners(new Ownable() { + def result = ownershipRepository.findOwnableObjectOwners(new Ownable() { String getObjectId() { return "ccc" } OwnableType getOwnableType() { return OwnableType.USER } }) @@ -207,7 +186,7 @@ class OwnershipRepositoryTests extends Specification { def "test findAllGroupsForUser"() { when: "find all groups for user aaa" - def result = repo.findAllGroupsForUser("aaa") + def result = ownershipRepository.findAllGroupsForUser("aaa") then: result.size() == 1 @@ -220,7 +199,7 @@ class OwnershipRepositoryTests extends Specification { ArrayList groupIds = new ArrayList<>() groupIds.add("g1") groupIds.add("g2") - result = repo.findAllGroupsForUser("ccc") + result = ownershipRepository.findAllGroupsForUser("ccc") then: result.size() == 2 @@ -237,7 +216,7 @@ class OwnershipRepositoryTests extends Specification { userIds.add("aaa") userIds.add("bbb") userIds.add("ccc") - def result = repo.findAllByOwner(new Owner() { + def result = ownershipRepository.findAllByOwner(new Owner() { String getOwnerId() { return "g1" } OwnerType getOwnerType() { return OwnerType.GROUP } }) @@ -250,7 +229,7 @@ class OwnershipRepositoryTests extends Specification { } when: "Find all items owned by user aaa" - result = repo.findAllByOwner(new Owner() { + result = ownershipRepository.findAllByOwner(new Owner() { String getOwnerId() { return "aaa" } OwnerType getOwnerType() { return OwnerType.USER } }) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy index a1a15cb56..20c575880 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy @@ -1,81 +1,11 @@ package edu.internet2.tier.shibboleth.admin.ui.security.service -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration -import edu.internet2.tier.shibboleth.admin.ui.security.controller.GroupController +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException import edu.internet2.tier.shibboleth.admin.ui.security.model.Group -import edu.internet2.tier.shibboleth.admin.ui.security.model.Role -import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.boot.test.context.TestConfiguration -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Primary -import org.springframework.context.annotation.Profile -import org.springframework.data.jpa.repository.config.EnableJpaRepositories -import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.ContextConfiguration -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.transaction.annotation.Transactional -import org.springframework.web.servlet.LocaleResolver -import org.springframework.web.servlet.i18n.SessionLocaleResolver -import spock.lang.Specification -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, InternationalizationConfiguration, SearchConfiguration, LocalConfig, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext -@ActiveProfiles(["gs-test"]) -class GroupServiceTests extends Specification { - @Autowired - GroupServiceForTesting groupService - - @Autowired - RoleRepository roleRepository - - @Autowired - UserService userService - - @Transactional - def setup() { - groupService.ensureAdminGroupExists() - - if (roleRepository.count() == 0) { - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } - } - - Optional adminRole = roleRepository.findByName("ROLE_ADMIN") - User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo") - userService.save(adminUser) - - Optional userRole = roleRepository.findByName("ROLE_USER") - User user = new User(username: "someUser", roles:[userRole.get()], password: "foo") - userService.save(user) - } - - def "Test the validation for regex works"() { +class GroupServiceTests extends BaseDataJpaTestSetup { + def "Test setting group regex works"() { given: Group g = new Group() g.setResourceId("twitter") @@ -119,26 +49,10 @@ class GroupServiceTests extends Specification { then: try { - g = groupService.updateGroup(g) + groupService.updateGroup(g) false } catch (InvalidGroupRegexException shouldOccur) { true } } - - @TestConfiguration - @Profile("gs-test") - static class LocalConfig { - @Bean - @Primary - GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { - GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - }) - result.ensureAdminGroupExists() - return result - } - } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy index f19049486..a2ba7051d 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/UserServiceTests.groovy @@ -4,91 +4,31 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Ownership import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Primary -import org.springframework.context.annotation.Profile -import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.ContextConfiguration import org.springframework.transaction.annotation.Transactional -import spock.lang.Specification -import javax.persistence.EntityManager import java.time.LocalDateTime import java.time.format.DateTimeFormatter -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, CustomPropertiesConfiguration, LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext -@ActiveProfiles(["test", "us-test"]) -@ComponentScan(basePackages="{ edu.internet2.tier.shibboleth.admin.ui.configuration }") -class UserServiceTests extends Specification { - - @Autowired - EntityManager entityManager - - @Autowired - GroupServiceForTesting groupService - - @Autowired - OwnershipRepository ownershipRepository - - @Autowired - RoleRepository roleRepository - - @Autowired - UserRepository userRepository - - @Autowired - UserService userService - +class UserServiceTests extends BaseDataJpaTestSetup { @Transactional def setup() { userRepository.findAll().forEach { userService.delete(it.getUsername()) } userRepository.flush() - - roleRepository.deleteAll() - roleRepository.flush() + groupService.clearAllForTesting() //leaves us just the admingroup - - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } } - @Rollback def "When creating user, user is set to the correct group"() { given: Group gb = new Group() @@ -118,7 +58,6 @@ class UserServiceTests extends Specification { g.ownedItems.size() == 1 } - @Rollback def "When updating user, user is set to the correct group"() { given: Group ga = new Group() @@ -162,7 +101,6 @@ class UserServiceTests extends Specification { g2.ownedItems.size() == 0 } - @Rollback def "logically try to match user controller test causing headaches"() { given: Group ga = new Group() @@ -189,7 +127,6 @@ class UserServiceTests extends Specification { result.firstName == "Wilma" } - @Rollback def "When creating user, user with multiple groups is saved correctly"() { given: Group ga = new Group() @@ -244,20 +181,7 @@ class UserServiceTests extends Specification { } @TestConfiguration - @Profile("us-test") static class LocalConfig { - @Bean - @Primary - GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { - GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - }) - result.ensureAdminGroupExists() - return result - } - @Bean ObjectMapper objectMapper() { JavaTimeModule module = new JavaTimeModule() diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy index 80b3fad04..d0de19fd8 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy @@ -1,8 +1,10 @@ package edu.internet2.tier.shibboleth.admin.ui.service +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.XSString import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget @@ -11,6 +13,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilF import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository +import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl @@ -34,20 +37,16 @@ import spock.lang.Specification import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.* -@DataJpaTest -@ContextConfiguration(classes = [CoreShibUiConfiguration, SearchConfiguration, InternationalizationConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration ,LocalConfig]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@ActiveProfiles(value = "local") -class IncommonJPAMetadataResolverServiceImplTests extends Specification { +@ContextConfiguration(classes = [IJPAMRSILocalConfig]) +class IncommonJPAMetadataResolverServiceImplTests extends BaseDataJpaTestSetup { @Autowired - MetadataResolverService metadataResolverService + AttributeUtility attributeUtility @Autowired - MetadataResolverRepository metadataResolverRepository + MetadataResolverService metadataResolverService @Autowired - AttributeUtility attributeUtility + MetadataResolverRepository metadataResolverRepository def cleanup() { metadataResolverRepository.deleteAll() @@ -111,19 +110,28 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { } @TestConfiguration - @Profile("local") - private static class LocalConfig { - @Autowired - OpenSamlObjects openSamlObjects - - @Autowired - MetadataResolverRepository metadataResolverRepository + private static class IJPAMRSILocalConfig { +// @Bean +// DirectoryService directoryService() { +// return new DirectoryServiceImpl() +// } - @Autowired - AttributeUtility attributeUtility + @Bean + JPAMetadataResolverServiceImpl jpaMetadataResolverService(MetadataResolver metadataResolver, MetadataResolverRepository metadataResolverRepository, + OpenSamlObjects openSamlObjects, MetadataResolversPositionOrderContainerService resolversPositionOrderContainerService, + ShibUIConfiguration shibUIConfiguration) { + return new JPAMetadataResolverServiceImpl().with { + it.metadataResolver = metadataResolver + it.metadataResolverRepository = metadataResolverRepository + it.openSamlObjects = openSamlObjects + it.resolversPositionOrderContainerService = resolversPositionOrderContainerService + it.shibUIConfiguration = shibUIConfiguration + it + } + } @Bean - MetadataResolver metadataResolver() { + MetadataResolver metadataResolver(AttributeUtility attributeUtility, MetadataResolverRepository metadataResolverRepository) { def resolver = new ChainingMetadataResolver().with { it.id = 'chain' @@ -153,14 +161,11 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { return resolver } - + @Bean - GroupServiceImpl groupService(GroupsRepository repo, OwnershipRepository ownershipRepository) { - new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - } + MetadataResolversPositionOrderContainerService metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository, + MetadataResolverRepository resolverRepository) { + return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository) } } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy index 63a5a133b..8d017b884 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests.groovy @@ -1,77 +1,53 @@ package edu.internet2.tier.shibboleth.admin.ui.service import com.fasterxml.jackson.databind.ObjectMapper -import edu.internet2.tier.shibboleth.admin.ui.ShibbolethUiApplication -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration -import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor -import edu.internet2.tier.shibboleth.admin.ui.domain.XSAny -import edu.internet2.tier.shibboleth.admin.ui.domain.XSAnyBuilder -import edu.internet2.tier.shibboleth.admin.ui.domain.XSBoolean -import edu.internet2.tier.shibboleth.admin.ui.domain.XSBooleanBuilder -import edu.internet2.tier.shibboleth.admin.ui.domain.XSStringBuilder -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.AssertionConsumerServiceRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ContactRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.LogoutEndpointRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.MduiRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.OrganizationRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.* import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import edu.internet2.tier.shibboleth.admin.util.EntityDescriptorConversionUtils - -import org.opensaml.saml.ext.saml2mdattr.EntityAttributes +import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions import org.skyscreamer.jsonassert.JSONAssert import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.TestConfiguration import org.springframework.boot.test.json.JacksonTester +import org.springframework.context.annotation.Bean import org.springframework.context.annotation.PropertySource -import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ContextConfiguration import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input import org.xmlunit.diff.DefaultNodeMatcher import org.xmlunit.diff.ElementSelectors -import spock.lang.Specification +import spock.lang.Ignore -@ContextConfiguration(classes=[CoreShibUiConfiguration, CustomPropertiesConfiguration]) -@SpringBootTest(classes = ShibbolethUiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) +@ContextConfiguration(classes=[JPAEDSILocalConfig]) @PropertySource("classpath:application.yml") -@DirtiesContext -class JPAEntityDescriptorServiceImplTests extends Specification { +class JPAEntityDescriptorServiceImplTests extends BaseDataJpaTestSetup { + @Autowired + EntityService entityService + @Autowired - EntityService entityService; - + OpenSamlObjects openSamlObjects + @Autowired JPAEntityDescriptorServiceImpl service - def testObjectGenerator - - OpenSamlObjects openSamlObjects = new OpenSamlObjects().with { - init() - it - } - - JacksonTester jacksonTester - ObjectMapper mapper RandomGenerator generator - + JacksonTester jacksonTester + ObjectMapper mapper = new ObjectMapper() + def testObjectGenerator + def setup() { - mapper = new ObjectMapper() JacksonTester.initFields(this, mapper) generator = new RandomGenerator() testObjectGenerator = new TestObjectGenerator() EntityDescriptorConversionUtils.openSamlObjects = openSamlObjects EntityDescriptorConversionUtils.entityService = entityService + openSamlObjects.init() } def "simple Entity Descriptor"() { @@ -627,7 +603,7 @@ class JPAEntityDescriptorServiceImplTests extends Specification { def output = service.createRepresentationFromDescriptor(service.createDescriptorFromRepresentation(representation)) then: - assert output.securityInfo?.authenticationRequestsSigned == true + assert output.securityInfo?.authenticationRequestsSigned } def "SHIBUI-219-3"() { @@ -651,6 +627,7 @@ class JPAEntityDescriptorServiceImplTests extends Specification { assert output.assertionConsumerServices[0].binding == 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post' } + @Ignore def "payload mapping round trip: JSON->FrontendModel->BackendModel->FrontendModel->JSON"() { when: EntityDescriptorRepresentation inputRepresentation = jacksonTester.readObject('/json/SHIBUI-219-3.json') @@ -783,4 +760,18 @@ class JPAEntityDescriptorServiceImplTests extends Specification { return ed } -} + + @TestConfiguration + private static class JPAEDSILocalConfig { + @Bean + JPAEntityServiceImpl jpaEntityService(OpenSamlObjects openSamlObjects, AttributeUtility attributeUtility, + CustomPropertiesConfiguration customPropertiesConfiguration) { + return new JPAEntityServiceImpl(openSamlObjects, attributeUtility, customPropertiesConfiguration) + } + + @Bean + ModelRepresentationConversions modelRepresentationConversions(CustomPropertiesConfiguration customPropertiesConfiguration) { + return new ModelRepresentationConversions(customPropertiesConfiguration) + } + } +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests2.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests2.groovy index 18532a57a..c4d8cfcab 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests2.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImplTests2.groovy @@ -1,107 +1,45 @@ package edu.internet2.tier.shibboleth.admin.ui.service -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.context.TestConfiguration -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Profile -import org.springframework.context.annotation.PropertySource -import org.springframework.security.test.context.support.WithMockUser -import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.annotation.Rollback -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.ContextConfiguration -import org.springframework.transaction.annotation.Transactional - -import edu.internet2.tier.shibboleth.admin.ui.ShibbolethUiApplication -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation +import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceForTesting -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl -import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService -import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService -import spock.lang.Specification - -@ContextConfiguration(classes=[CoreShibUiConfiguration, CustomPropertiesConfiguration, LocalConfig]) -@SpringBootTest(classes = ShibbolethUiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) -@PropertySource("classpath:application.yml") -@DirtiesContext -@ActiveProfiles(value="local") -class JPAEntityDescriptorServiceImplTests2 extends Specification { - - @Autowired - GroupServiceForTesting groupService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.security.test.context.support.WithMockUser +import org.springframework.test.annotation.Rollback +import org.springframework.transaction.annotation.Transactional +class JPAEntityDescriptorServiceImplTests2 extends BaseDataJpaTestSetup { @Autowired - RoleRepository roleRepository + EntityDescriptorRepository entityDescriptorRepository @Autowired JPAEntityDescriptorServiceImpl entityDescriptorService - @Autowired - UserRepository userRepository - - @Autowired - UserService userService - @Transactional def setup() { - // ensure we start fresh with only expected users and roles and groups - userRepository.deleteAll() - roleRepository.deleteAll() - groupService.clearAllForTesting() - - Group ga = new Group() - ga.setResourceId("testingGroup") - ga.setName("Group A") - groupService.createGroup(ga) - Group gb = new Group() gb.setResourceId("testingGroupBBB") gb.setName("Group BBB") gb.setValidationRegex("^(?:https?:\\/\\/)?(?:[^.]+\\.)?shib\\.org(\\/.*)?\$") gb = groupService.createGroup(gb) - def roles = [new Role().with { - name = 'ROLE_ADMIN' - it - }, new Role().with { - name = 'ROLE_USER' - it - }, new Role().with { - name = 'ROLE_NONE' - it - }] - roles.each { - roleRepository.save(it) - } - - Optional adminRole = roleRepository.findByName("ROLE_ADMIN") - User adminUser = new User(username: "admin", roles: [adminRole.get()], password: "foo") - userService.save(adminUser) - Optional userRole = roleRepository.findByName("ROLE_USER") - User user = new User(username: "someUser", roles:[userRole.get()], password: "foo", group: gb) + User user = new User(username: "someUser", roles: [userRole.get()], password: "foo", group: gb) userService.save(user) + + entityDescriptorRepository.deleteAll() } @WithMockUser(value = "someUser", roles = ["USER"]) - @Rollback def "When creating Entity Descriptor, ED is assigned to the user's group"() { given: User current = userService.getCurrentUser() - current.setGroupId("testingGroupBBB") - def expectedEntityId = 'https://shib.org/blah' + def expectedEntityId = 'https://shib.org/groupsomething' def expectedSpName = 'sp1' def expectedUUID = 'uuid-1' def entityDescriptor = new EntityDescriptor(resourceId: expectedUUID, entityID: expectedEntityId, serviceProviderName: expectedSpName, serviceEnabled: false) @@ -110,20 +48,6 @@ class JPAEntityDescriptorServiceImplTests2 extends Specification { def result = entityDescriptorService.createNew(entityDescriptor) then: - ((EntityDescriptorRepresentation)result).getIdOfOwner() == "testingGroupBBB" - } - - @TestConfiguration - @Profile("local") - static class LocalConfig { - @Bean - GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { - GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it - }) - return result - } + ((EntityDescriptorRepresentation) result).getIdOfOwner() == "testingGroupBBB" } } \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImplTests.groovy index df888a972..bf1e1a213 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityServiceImplTests.groovy @@ -1,10 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.service +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator @@ -13,41 +10,31 @@ import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import edu.internet2.tier.shibboleth.admin.util.MDDCConstants import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification /** * @author Bill Smith (wsmith@unicon.net) */ -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, TestConfiguration, InternationalizationConfiguration]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -class JPAEntityServiceImplTests extends Specification { +@ContextConfiguration(classes=[JPAESILocalConfig]) +class JPAEntityServiceImplTests extends BaseDataJpaTestSetup { +// @Autowired +// AttributeUtility attributeUtility +// +// @Autowired +// CustomPropertiesConfiguration customPropertiesConfiguration +// +// @Autowired +// OpenSamlObjects openSamlObjects @Autowired - OpenSamlObjects openSamlObjects + EntityService service @Autowired - AttributeUtility attributeUtility + TestObjectGenerator testObjectGenerator - @Autowired - CustomPropertiesConfiguration customPropertiesConfiguration - - def randomGenerator - def testObjectGenerator - - def service - - def setup() { - service = new JPAEntityServiceImpl(openSamlObjects, attributeUtility, customPropertiesConfiguration) - - randomGenerator = new RandomGenerator() - testObjectGenerator = new TestObjectGenerator(attributeUtility, customPropertiesConfiguration) - } + def randomGenerator = new RandomGenerator() def "getAttributeListFromEntityRepresentation builds an appropriate attribute list"() { given: @@ -91,4 +78,18 @@ class JPAEntityServiceImplTests extends Specification { it.schemaTypeNamespacePrefix == expectedSchemaTypeNamespacePrefix } } -} + + @TestConfiguration + private static class JPAESILocalConfig { + @Bean + JPAEntityServiceImpl jpaEntityService(OpenSamlObjects openSamlObjects, AttributeUtility attributeUtility, + CustomPropertiesConfiguration customPropertiesConfiguration) { + return new JPAEntityServiceImpl(openSamlObjects, attributeUtility, customPropertiesConfiguration) + } + + @Bean + TestObjectGenerator testObjectGenerator(AttributeUtility attributeUtility, CustomPropertiesConfiguration customPropertiesConfiguration) { + return new TestObjectGenerator(attributeUtility,customPropertiesConfiguration) + } + } +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index b6092c8e3..baf0173ab 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -1,32 +1,18 @@ package edu.internet2.tier.shibboleth.admin.ui.service -import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.MetadataResolverConverterConfiguration +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration -import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.configuration.ShibUIConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataQueryProtocolScheme -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.RegexScheme -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.SvnMetadataResource -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.TemplateScheme +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.* import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository -import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository -import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility -import edu.internet2.tier.shibboleth.admin.util.TokenPlaceholderResolvers import groovy.xml.DOMBuilder import groovy.xml.MarkupBuilder import net.shibboleth.ext.spring.resource.ResourceHelper @@ -37,67 +23,51 @@ import org.opensaml.saml.metadata.resolver.MetadataResolver import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.boot.test.context.TestConfiguration import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Profile import org.springframework.core.io.ClassPathResource -import org.springframework.data.jpa.repository.config.EnableJpaRepositories import org.springframework.test.annotation.DirtiesContext -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input import spock.lang.Ignore -import spock.lang.Specification import spock.lang.Unroll import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.generatedXmlIsTheSameAsExpectedXml -@DataJpaTest -@ContextConfiguration(classes=[CoreShibUiConfiguration, MetadataResolverConverterConfiguration, SearchConfiguration, InternationalizationConfiguration, PlaceholderResolverComponentsConfiguration, edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration ,Config]) -@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) -@EntityScan("edu.internet2.tier.shibboleth.admin.ui") -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -@ActiveProfiles(value = "local") -class JPAMetadataResolverServiceImplTests extends Specification { +@ContextConfiguration(classes=[PlaceholderResolverComponentsConfiguration]) +class JPAMetadataResolverServiceImplTests extends BaseDataJpaTestSetup { @Autowired - MetadataResolverRepository metadataResolverRepository + AttributeUtility attributeUtility @Autowired - MetadataResolverService metadataResolverService + EntityService entityService @Autowired MetadataResolver metadataResolver @Autowired - EntityService entityService + MetadataResolverRepository metadataResolverRepository @Autowired - OpenSamlObjects openSamlObjects + MetadataResolverConverterService mdrConverterService @Autowired - AttributeUtility attributeUtility + MetadataResolverService metadataResolverService @Autowired - MetadataResolverConverterService mdrConverterService + OpenSamlObjects openSamlObjects @Autowired ShibUIConfiguration shibUIConfiguration TestObjectGenerator testObjectGenerator - - DOMBuilder domBuilder - - StringWriter writer - + DOMBuilder domBuilder = DOMBuilder.newInstance() + StringWriter writer = new StringWriter() MarkupBuilder markupBuilder def setup() { testObjectGenerator = new TestObjectGenerator(attributeUtility) - domBuilder = DOMBuilder.newInstance() - writer = new StringWriter() markupBuilder = new MarkupBuilder(writer) markupBuilder.omitNullAttributes = true markupBuilder.omitEmptyAttributes = true @@ -485,13 +455,9 @@ class JPAMetadataResolverServiceImplTests extends Specification { } @TestConfiguration - @Profile("local") private static class Config { - @Autowired - OpenSamlObjects openSamlObjects - @Bean - MetadataResolver metadataResolver(TokenPlaceholderResolvers tokenPlaceholderResolvers) { + MetadataResolver metadataResolver(OpenSamlObjects openSamlObjects) { def resource = ResourceHelper.of(new ClassPathResource("/metadata/aggregate.xml")) def aggregate = new ResourceBackedMetadataResolver(resource){ @Override @@ -510,19 +476,17 @@ class JPAMetadataResolverServiceImplTests extends Specification { return new OpenSamlChainingMetadataResolver().with { it.id = 'chain' - //it.resolvers = [aggregate] -// it.resolvers = [] it.initialize() it } } - + @Bean - GroupServiceImpl groupService(GroupsRepository repo, OwnershipRepository ownershipRepository) { - new GroupServiceImpl().with { - it.groupRepository = repo - it.ownershipRepository = ownershipRepository - return it + MetadataResolverConverterServiceImpl metadataResolverConverterServiceImpl(IndexWriterService indexWriterService, OpenSamlObjects openSamlObjects) { + return new MetadataResolverConverterServiceImpl().with { + it.indexWriterService = indexWriterService + it.openSamlObjects = openSamlObjects + it } } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImplTests.groovy index 8a261565e..b7f4a9f7e 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImplTests.groovy @@ -1,14 +1,18 @@ package edu.internet2.tier.shibboleth.admin.ui.service +import edu.internet2.tier.shibboleth.admin.ui.BaseDataJpaTestSetup +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.PlaceholderResolverComponentsConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicMetadataResolverAttributes import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import spock.lang.Specification - -@SpringBootTest -class MetadataResolverConverterServiceImplTests extends Specification { +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.test.context.ContextConfiguration +@ContextConfiguration(classes=[MRCSILocalConfig, PlaceholderResolverComponentsConfiguration]) +class MetadataResolverConverterServiceImplTests extends BaseDataJpaTestSetup { @Autowired MetadataResolverConverterService mrConverterServiceUnderTest @@ -26,4 +30,21 @@ class MetadataResolverConverterServiceImplTests extends Specification { then: noExceptionThrown() } -} + + @TestConfiguration + private static class MRCSILocalConfig { + @Bean + DirectoryService directoryService() { + return new DirectoryServiceImpl() + } + + @Bean + MetadataResolverConverterServiceImpl metadataResolverConverterServiceImpl(IndexWriterService indexWriterService, OpenSamlObjects openSamlObjects) { + return new MetadataResolverConverterServiceImpl().with { + it.indexWriterService = indexWriterService + it.openSamlObjects = openSamlObjects + it + } + } + } +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy index a5c50cbb8..6f8f3f51f 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy @@ -223,12 +223,7 @@ class TestObjectGenerator { return new NameIdFormatFilter().with { it.name = "NameIDFormat" it.formats = ['urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'] - it.nameIdFormatFilterTarget = new NameIdFormatFilterTarget(nameIdFormatFilterTargetType: ENTITY, singleValue: 'https://sp1.example.org') - - /*it.name = "NameIDFormat" - it.formats = ['urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', 'urn:oasis:names:tc:SAML:2.0:nameid-format:email'] - it.nameIdFormatFilterTarget = new NameIdFormatFilterTarget(nameIdFormatFilterTargetType: CONDITION_SCRIPT, singleValue: 'eval(true);')*/ - + it.setNameIdFormatFilterTarget(new NameIdFormatFilterTarget(nameIdFormatFilterTargetType: ENTITY, singleValue: 'https://sp1.example.org')) it } } @@ -285,6 +280,7 @@ class TestObjectGenerator { it.resourceId = nameIdFormatFilter.resourceId it.removeExistingFormats = nameIdFormatFilter.removeExistingFormats it.formats = nameIdFormatFilter.formats + it.nameIdFormatFilterTarget = nameIdFormatFilter.nameIdFormatFilterTarget it } }