Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,16 @@ public interface AccessFormRepository extends JpaRepository<AccessForm, Long> {
+ ")",
nativeQuery = true)
boolean isElementPartOfSectionOfAccessForm(Long accessFormId, Long sectionId, Long elementId);

@Query(
value =
"SELECT a.* "
+ "FROM resource r "
+ " INNER JOIN access_form a on a.id = r.access_form_id "
+ "WHERE r.organization_id = :organizationId "
+ "GROUP BY a.id "
+ "ORDER BY COUNT(r.id) DESC "
+ "LIMIT 1",
nativeQuery = true)
Optional<AccessForm> findFirstMostCommonAccessFormByOrganization(Long organizationId);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some unit tests for the repository to test more cases then covered in the integration test would be great, but not a blocker.

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class ResourceServiceImpl implements ResourceService {
private final OrganizationRepository organizationRepository;
private final NegotiationAccessManager negotiationAccessManager;

private static final long DEFAULT_ACCESS_FORM_ID = 1L;

public ResourceServiceImpl(
NetworkRepository networkRepository,
ResourceRepository repository,
Expand Down Expand Up @@ -222,10 +224,7 @@ public List<ResourceResponseModel> addResources(List<ResourceCreateDTO> resource
.findById(resDTO.getDiscoveryServiceId())
.orElseThrow(
() -> new DiscoveryServiceNotFoundException(resDTO.getDiscoveryServiceId()));
AccessForm accessForm =
accessFormRepository
.findById(resDTO.getAccessFormId())
.orElseThrow(() -> new AccessFormNotFoundException(resDTO.getAccessFormId()));
AccessForm accessForm = getAccessForm(resDTO.getAccessFormId(), resDTO.getOrganizationId());
Organization organization =
organizationRepository
.findById(resDTO.getOrganizationId())
Expand Down Expand Up @@ -261,4 +260,19 @@ private Negotiation fetchNegotiationFromDB(String negotiationId) {
.findById(negotiationId)
.orElseThrow(() -> new EntityNotFoundException(negotiationId));
}

private AccessForm getAccessForm(Long accessFormId, Long organizationId) {
if (accessFormId == null) {
return accessFormRepository
.findFirstMostCommonAccessFormByOrganization(organizationId)
.orElseGet(
() ->
accessFormRepository
.findById(DEFAULT_ACCESS_FORM_ID)
.orElseThrow(() -> new AccessFormNotFoundException(DEFAULT_ACCESS_FORM_ID)));
}
return accessFormRepository
.findById(accessFormId)
.orElseThrow(() -> new AccessFormNotFoundException(accessFormId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ public class ResourceCreateDTO {
@Schema(description = "ID of the associated organization", example = "1")
private Long organizationId;

@NotNull
@Schema(description = "ID of the access form related to the resource", example = "42")
@Schema(description = "Optional ID of the access form related to the resource", example = "42")
private Long accessFormId;

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.bbmri_eric.negotiator.governance.resource.dto;

import eu.bbmri_eric.negotiator.form.dto.AccessFormDTO;
import eu.bbmri_eric.negotiator.user.UserDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.Set;
Expand All @@ -14,4 +15,7 @@ public class ResourceWithRepsDTO extends ResourceResponseModel {
example =
"[{\"id\": \"123\", \"name\": \"Sarah Rep\", \"email\": \"sarah@example.com\"}, {\"id\": \"456\", \"name\": \"Adam Rep\", \"email\": \"adam@example.com\"}]")
private Set<UserDTO> representatives;

@Schema(description = "Access form associated with this resource")
private AccessFormDTO accessForm;
Comment thread
stetsche marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
Expand Down Expand Up @@ -55,6 +56,10 @@ public class ResourceControllerTests {

private static final String RESOURCES_ENDPOINT = "/v3/resources";

private static final long DEFAULT_ACCESS_FORM_ID = 1L;

private static final long DEFAULT_DISCOVERY_SERVICE_ID = 1L;

@Autowired private WebApplicationContext context;
@Autowired private ResourceRepository repository;
@Autowired private OrganizationRepository organizationRepository;
Expand All @@ -71,6 +76,36 @@ public void before() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
}

private Organization createOrganization(String suffix) {
return Organization.builder()
.name("Organization " + suffix)
.description("Organization " + suffix)
.externalId("test_organization_" + suffix)
.build();
}

private ResourceCreateDTO createResource(
String name, String sourceId, Long organizationId, Long accessFormId) {
return ResourceCreateDTO.builder()
.name(name)
.description(name)
.contactEmail(name.toLowerCase().replace(" ", "") + "@test.org")
.uri("https://" + name.toLowerCase().replace(" ", "") + ".test.org")
.sourceId(sourceId)
.organizationId(organizationId)
.accessFormId(accessFormId)
.discoveryServiceId(DEFAULT_DISCOVERY_SERVICE_ID)
.build();
}

private DiscoveryService createDiscoveryService(long id) {
return DiscoveryService.builder()
.name("test_discovery_service")
.id(id)
.url("http://discoveryservice.net")
.build();
}

@Test
@WithMockUser("researcher")
void getResourceById_validId_ok() throws Exception {
Expand Down Expand Up @@ -427,6 +462,133 @@ void addResource_batchOfResources_ok() throws Exception {
assertEquals(resourceDTO2.getUri(), resource2.get().getUri());
}

@Test
@WithUserDetails("admin")
void addResource_noAccessFormSelected_ok() throws Exception {
Organization org1 = createOrganization("10");
organizationRepository.save(org1);
Long org1Id = organizationRepository.findByExternalId("test_organization_10").get().getId();

ResourceCreateDTO resourceDTO1 = createResource("Resource 10", "resource_10", org1Id, null);

discoveryServiceRepository
.findById(DEFAULT_DISCOVERY_SERVICE_ID)
.orElseGet(
() ->
discoveryServiceRepository.save(
createDiscoveryService(DEFAULT_DISCOVERY_SERVICE_ID)));

String requestBody = TestUtils.jsonFromRequest(Arrays.asList(resourceDTO1));
MvcResult result =
mockMvc
.perform(
MockMvcRequestBuilders.post(RESOURCES_ENDPOINT)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpect(status().isCreated())
.andExpect(content().contentType("application/hal+json"))
.andExpect(jsonPath("$._embedded.resources[0].name", is(resourceDTO1.getName())))
.andExpect(
jsonPath("$._embedded.resources[0].sourceId", is(resourceDTO1.getSourceId())))
.andExpect(
jsonPath("$._embedded.resources[0].description", is(resourceDTO1.getDescription())))
.andExpect(
jsonPath(
"$._embedded.resources[0].contactEmail", is(resourceDTO1.getContactEmail())))
.andExpect(jsonPath("$._embedded.resources[0].uri", is(resourceDTO1.getUri())))
.andReturn();

String id1 =
JsonPath.parse(result.getResponse().getContentAsString())
.read("$._embedded.resources[0].sourceId");
Optional<Resource> resource1 = repository.findBySourceId(id1);
assertTrue(resource1.isPresent());
assertEquals(resourceDTO1.getName(), resource1.get().getName());
assertEquals(resourceDTO1.getDescription(), resource1.get().getDescription());
Comment thread
stetsche marked this conversation as resolved.
assertEquals(resourceDTO1.getContactEmail(), resource1.get().getContactEmail());
assertEquals(resourceDTO1.getUri(), resource1.get().getUri());
assertEquals(DEFAULT_ACCESS_FORM_ID, resource1.get().getAccessForm().getId());
}

@Test
@WithUserDetails("admin")
void addResource_useOrganizationDefaultAccessForm_ok() throws Exception {
Organization org1 = createOrganization("11");
organizationRepository.save(org1);
Long org1Id = organizationRepository.findByExternalId("test_organization_11").get().getId();

ResourceCreateDTO resourceDTO1 = createResource("Resource 11", "resource_11", org1Id, 2L);
ResourceCreateDTO resourceDTO2 = createResource("Resource 12", "resource_12", org1Id, null);

discoveryServiceRepository
.findById(DEFAULT_DISCOVERY_SERVICE_ID)
.orElseGet(
() ->
discoveryServiceRepository.save(
createDiscoveryService(DEFAULT_DISCOVERY_SERVICE_ID)));

String requestBody1 = TestUtils.jsonFromRequest(Arrays.asList(resourceDTO1));
MvcResult result1 =
mockMvc
.perform(
MockMvcRequestBuilders.post(RESOURCES_ENDPOINT)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody1))
.andExpect(status().isCreated())
.andExpect(content().contentType("application/hal+json"))
.andExpect(jsonPath("$._embedded.resources[0].name", is(resourceDTO1.getName())))
.andExpect(
jsonPath("$._embedded.resources[0].sourceId", is(resourceDTO1.getSourceId())))
.andExpect(
jsonPath("$._embedded.resources[0].description", is(resourceDTO1.getDescription())))
.andExpect(
jsonPath(
"$._embedded.resources[0].contactEmail", is(resourceDTO1.getContactEmail())))
.andExpect(jsonPath("$._embedded.resources[0].uri", is(resourceDTO1.getUri())))
.andReturn();

String requestBody2 = TestUtils.jsonFromRequest(Arrays.asList(resourceDTO2));
MvcResult result2 =
mockMvc
.perform(
MockMvcRequestBuilders.post(RESOURCES_ENDPOINT)
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody2))
.andExpect(status().isCreated())
.andExpect(content().contentType("application/hal+json"))
.andExpect(jsonPath("$._embedded.resources[0].name", is(resourceDTO2.getName())))
.andExpect(
jsonPath("$._embedded.resources[0].sourceId", is(resourceDTO2.getSourceId())))
.andExpect(
jsonPath("$._embedded.resources[0].description", is(resourceDTO2.getDescription())))
.andExpect(
jsonPath(
"$._embedded.resources[0].contactEmail", is(resourceDTO2.getContactEmail())))
.andExpect(jsonPath("$._embedded.resources[0].uri", is(resourceDTO2.getUri())))
.andReturn();

String id1 =
JsonPath.parse(result1.getResponse().getContentAsString())
.read("$._embedded.resources[0].sourceId");
Optional<Resource> resource1 = repository.findBySourceId(id1);
assertTrue(resource1.isPresent());
assertEquals(resourceDTO1.getName(), resource1.get().getName());
assertEquals(resourceDTO1.getDescription(), resource1.get().getDescription());
assertEquals(resourceDTO1.getContactEmail(), resource1.get().getContactEmail());
assertEquals(resourceDTO1.getUri(), resource1.get().getUri());

Long id2 =
JsonPath.parse(result2.getResponse().getContentAsString())
.read("$._embedded.resources[0].id", Long.class);
Optional<Resource> resource2 = repository.findById(id2);
assertTrue(resource2.isPresent());
assertEquals(resourceDTO2.getName(), resource2.get().getName());
assertEquals(resourceDTO2.getDescription(), resource2.get().getDescription());
Comment thread
stetsche marked this conversation as resolved.
assertEquals(resourceDTO2.getContactEmail(), resource2.get().getContactEmail());
assertEquals(resourceDTO2.getUri(), resource2.get().getUri());
assertEquals(2L, resource2.get().getAccessForm().getId());
}

@Test
@WithUserDetails("admin")
void updateResource_singleResource_ok() throws Exception {
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/components/OrganizationListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@
</span>
</small>
</div>

<!-- Access Form -->
<div class="access-form">
<small class="text-muted">
<strong>Access Form: </strong>
<span v-if="resource.accessForm">
{{ resource.accessForm.name }}
</span>
<span v-else class="text-warning">
None assigned
</span>
</small>
</div>
</div>

<!-- Resource Status Icon -->
Expand Down
Loading