Skip to content
This repository has been archived by the owner on Mar 7, 2024. It is now read-only.

Commit

Permalink
Feat/increase coverage (#11)
Browse files Browse the repository at this point in the history
* feat: first tests added

* feat: all missing tests added

* feat: last fixes added

* feat: last small increase
  • Loading branch information
jobulcke authored Sep 21, 2023
1 parent cd24787 commit 405f806
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 17 deletions.
8 changes: 8 additions & 0 deletions spring-boot-backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<jupiter.version>5.10.0</jupiter.version>
<mockito.version>5.4.0</mockito.version>
<cucumber.version>7.13.0</cucumber.version>
<wiremock.version>2.35.0</wiremock.version>
<!-- RDF4j -->
<rdf4j.version>4.3.3</rdf4j.version>

Expand Down Expand Up @@ -147,6 +148,13 @@
<artifactId>junit-platform-suite</artifactId>
<version>${junit-platform-suite.version}</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<version>${wiremock.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ public Triple(String subject, String predicate, String object) {
this.object = object;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Triple triple = (Triple) o;

if (!subject.equals(triple.subject)) return false;
if (!predicate.equals(triple.predicate)) return false;
return object.equals(triple.object);
}

@Override
public int hashCode() {
int result = subject.hashCode();
result = 31 * result + predicate.hashCode();
result = 31 * result + object.hashCode();
return result;
}

public String getSubject() {
return subject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.impl.TreeModelFactory;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Repository
public class TripleRepositoryImpl implements TripleRepository {
Expand All @@ -42,13 +42,10 @@ public MemberDescription getById(String id) {

//Execute and get the response.
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
HttpEntity entity = Objects.requireNonNull(response.getEntity());

if (entity != null) {
Model model = Rio.parse(entity.getContent(), RDFFormat.NTRIPLES);
return new MemberDescription(id, model);
}
return new MemberDescription(id, new TreeModelFactory().createEmptyModel());
Model model = Rio.parse(entity.getContent(), RDFFormat.NTRIPLES);
return new MemberDescription(id, model);
} catch (Exception e) {
throw new TripleFetchFailedException(id, e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package be.informatievlaanderen.vsds.demonstrator.triple.rest;

import be.informatievlaanderen.vsds.demonstrator.triple.infra.exceptions.TripleFetchFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class TripleExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(TripleExceptionHandler.class);

@ExceptionHandler(value = TripleFetchFailedException.class)
protected ResponseEntity<Object> handleNotFound(RuntimeException e, WebRequest request) {
log.error(e.getMessage());
return handleExceptionInternal(e, e.getMessage(), new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ public TriplesController(TripleService tripleService) {
@CrossOrigin(origins = "*", allowedHeaders = "*")
public List<Triple> retrieveTriplesOfNode(HttpServletRequest request) {
String requestURL = request.getRequestURL().toString();

String memberId = requestURL.split("/triples/")[1];
return tripleService.getTriplesById(memberId);
}
}
}
22 changes: 22 additions & 0 deletions spring-boot-backend/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
spring:
datasource:
url: jdbc:postgresql://localhost:25432/test
username: postgres
password: test
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: update

ldes:
streams:
-
member-type: "https://data.vlaanderen.be/ns/mobiliteit#Mobiliteitshinder"
timestamp-path: "http://www.w3.org/ns/prov#generatedAtTime"
graphdb:
url: "http://localhost:8080/rdf4j-server/repositories/"
repositoryId: "test"
server:
port: 8084
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package be.informatievlaanderen.vsds.demonstrator.triple.application.services;

import be.informatievlaanderen.vsds.demonstrator.triple.application.valueobjects.Triple;
import be.informatievlaanderen.vsds.demonstrator.triple.domain.entities.MemberDescription;
import be.informatievlaanderen.vsds.demonstrator.triple.domain.repositories.TripleRepository;
import be.informatievlaanderen.vsds.demonstrator.triple.infra.exceptions.TripleFetchFailedException;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.impl.TreeModelFactory;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.util.ResourceUtils;
import wiremock.com.google.common.io.Files;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class TripleServiceImplTest {
private static final String MEMBER_ID = "https://private-api.gipod.beta-vlaanderen.be/api/v1/mobility-hindrances/10810464/#ID";
@Mock
private TripleRepository repository;
private TripleService service;

@BeforeEach
void setUp() {
service = new TripleServiceImpl(repository);
}

@Test
void when_MemberIsPresent_then_RetrieveTriples() throws IOException {
when(repository.getById(MEMBER_ID)).thenReturn(new MemberDescription(MEMBER_ID, readModelFromFile()));

var triples = readTriplesFromFile();
var fetchedTriples = service.getTriplesById(MEMBER_ID);

Predicate<Triple> subjectPredicate = triple -> triple.getSubject().equals(MEMBER_ID);
assertEquals(triples.size(), fetchedTriples.size());
assertEquals(triples.stream().filter(subjectPredicate).count(), fetchedTriples.stream().filter(subjectPredicate).count());
verify(repository).getById(MEMBER_ID);
}

@Test
void when_MemberHasEmptyModel_then_RetrieveEmptyList() {
when(repository.getById(MEMBER_ID)).thenReturn(new MemberDescription(MEMBER_ID, new TreeModelFactory().createEmptyModel()));

var fetchedTriples = service.getTriplesById(MEMBER_ID);

assertEquals(0, fetchedTriples.size());
verify(repository).getById(MEMBER_ID);
}

@Test
void when_MemberCannotBeFetched_then_RetrieveEmptyList() {
when(repository.getById(MEMBER_ID)).thenThrow(new TripleFetchFailedException(MEMBER_ID, new RuntimeException()));

assertThrows(TripleFetchFailedException.class, () -> service.getTriplesById(MEMBER_ID));
verify(repository).getById(MEMBER_ID);
}


private Model readModelFromFile() throws IOException {
File file = ResourceUtils.getFile("classpath:members/mobility-hindrance.nq");
return Rio.parse(new FileInputStream(file), RDFFormat.NQUADS);
}

private List<Triple> readTriplesFromFile() throws IOException {
File file = ResourceUtils.getFile("classpath:members/mobility-hindrance.nq");
Function<String, String> transformer = str -> str.length() > 1 ? str.substring(1, str.length() - 1) : str;
return Files.readLines(file, Charset.defaultCharset()).stream()
.map(line -> line.split(" "))
.map(strings -> Arrays.stream(strings).map(transformer).toList())
.map(strings -> new Triple(strings.get(0), strings.get(1), strings.get(2)))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package be.informatievlaanderen.vsds.demonstrator.triple.application.valueobjects;

import org.antlr.v4.runtime.tree.Tree;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;

class TripleTest {
private static final String SUBJECT = "my-subject";
private static final String PREDICATE = "my-predicate";
private static final String OBJECT = "my-object";
private static final Triple triple = new Triple(SUBJECT, PREDICATE, OBJECT);

@Test
void test_equality() {
final Triple other = new Triple(SUBJECT, PREDICATE, OBJECT);

assertEquals(triple.hashCode(), triple.hashCode());
assertEquals(triple.hashCode(), other.hashCode());

assertEquals(triple, triple);
assertEquals(triple, other);
assertEquals(other, triple);
}

@ParameterizedTest
@ArgumentsSource(TripleArgumentsProvider.class)
void test_inequality(Object other) {
assertNotEquals(triple, other);
}

static class TripleArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
return Stream.of(
new Triple("false-subject", "false-predicate", "false-object"),
new Triple("other-subject", PREDICATE, OBJECT),
new Triple(SUBJECT, "other-predicate", OBJECT),
new Triple(SUBJECT, PREDICATE, "other-object"),
null,
new Object()
).map(Arguments::of);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package be.informatievlaanderen.vsds.demonstrator.triple.infra;

import be.informatievlaanderen.vsds.demonstrator.triple.domain.entities.MemberDescription;
import be.informatievlaanderen.vsds.demonstrator.triple.domain.repositories.TripleRepository;
import be.informatievlaanderen.vsds.demonstrator.triple.infra.exceptions.TripleFetchFailedException;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.util.ResourceUtils;
import wiremock.com.fasterxml.jackson.databind.JsonNode;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.*;

@WireMockTest(httpPort = 8080)
class TripleRepositoryImplTest {
private static final String MEMBER_ID = "https://private-api.gipod.beta-vlaanderen.be/api/v1/mobility-hindrances/10810464/#ID";
private static final String ENDPOINT = "/rdf4j-server/repositories/test";
private static final GraphDBConfig graphDbConfig = new GraphDBConfig();
private TripleRepository repo;

@BeforeAll
static void beforeAll() {
graphDbConfig.setUrl("http://localhost:8080/rdf4j-server/repositories/");
graphDbConfig.setRepositoryId("test");
}

@BeforeEach
void setUp() {
repo = new TripleRepositoryImpl(graphDbConfig);
}

@Test
void when_ExistingTriplesAreRequested_then_MemberDescriptionIsExpected() throws IOException {
stubFor(post(ENDPOINT).willReturn(ok().withBody(readDataFromFile())));

MemberDescription memberDescription = repo.getById(MEMBER_ID);

assertEquals(MEMBER_ID, memberDescription.getMemberId());
assertFalse(memberDescription.getModel().isEmpty());
verify(postRequestedFor(urlEqualTo(ENDPOINT)));
}

@Test
void when_BadRequestIsSent_then_EmptyModelIsExpected() {
stubFor(post(ENDPOINT).willReturn(badRequest()));

MemberDescription memberDescription = repo.getById(MEMBER_ID);

assertEquals(MEMBER_ID, memberDescription.getMemberId());
assertTrue(memberDescription.getModel().isEmpty());
verify(postRequestedFor(urlEqualTo(ENDPOINT)));
}

@Test
void when_RequestFails_then_ExceptionIsExpected() {
stubFor(post(ENDPOINT).willReturn(badRequest().withFault(Fault.EMPTY_RESPONSE)));

assertThrows(TripleFetchFailedException.class, () -> repo.getById(MEMBER_ID));
verify(postRequestedFor(urlEqualTo(ENDPOINT)));
}

private byte[] readDataFromFile() throws IOException {
Path path = ResourceUtils.getFile("classpath:members/mobility-hindrance.nq").toPath();
return Files.readAllBytes(path);
}
}
Loading

0 comments on commit 405f806

Please sign in to comment.