diff --git a/pom.xml b/pom.xml index bb75a33c1..211f269c9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 io.github.mathieusoysal - crous-artificat-collector + crous-assistant-collector 1.0 jar diff --git a/src/main/java/io/github/mathieusoysal/App.java b/src/main/java/io/github/mathieusoysal/App.java index 75496dc5d..933166f95 100644 --- a/src/main/java/io/github/mathieusoysal/App.java +++ b/src/main/java/io/github/mathieusoysal/App.java @@ -1,50 +1,64 @@ package io.github.mathieusoysal; import java.io.IOException; +import java.time.LocalDate; -import com.fasterxml.jackson.core.exc.StreamReadException; -import com.fasterxml.jackson.databind.DatabindException; import com.github.forax.beautifullogger.Logger; -import io.github.mathieusoysal.exceptions.ApiRequestFailedException; +import io.github.mathieusoysal.data.managment.collectors.DataCollectorFromArchive; +import io.github.mathieusoysal.data.managment.collectors.DataCollectorFromCrous; +import io.github.mathieusoysal.data.managment.savers.ArchiveName; +import io.github.mathieusoysal.data.managment.savers.DataSaver; import io.github.mathieusoysal.exceptions.PropertiesNotFoundRuntimeException; -import io.github.mathieusoysal.logement.data.DataCollector; -import io.github.mathieusoysal.logement.data.DataSaver; public class App { private static final Logger LOGGER = Logger.getLogger(); private static final String MAIL_PROPERTIES_NAME = "MAIL"; private static final String PASSWORD_PROPERTIES_NAME = "PASSWORD"; + private static final String LINK_TO_DATA_PROPERTIE_NAME = "LINK_TO_DATA"; public static void main(String[] args) - throws StreamReadException, DatabindException, ApiRequestFailedException, IOException, - InterruptedException { + throws IOException { LOGGER.info(() -> "Starting application"); - var logements = DataCollector.getAvailableLogementsWithConnection(getEmail(), getPassword()); - DataSaver.createArchiveLogements(logements); + if (sumupdayModIsActivated()) + createArchiveSumUpForThisDay(); + else + createArchiveForThisHour(); LOGGER.info(() -> "Application finished"); } - private static String getEmail() { - LOGGER.info(() -> "Getting email from environment variables"); - String email = System.getenv(MAIL_PROPERTIES_NAME); - if (email == null) - { - LOGGER.error(() -> "Email not found in environment variables"); - throw new PropertiesNotFoundRuntimeException(MAIL_PROPERTIES_NAME); + private static void createArchiveSumUpForThisDay() { + var dataCollector = new DataCollectorFromArchive(LINK_TO_DATA_PROPERTIE_NAME); + var sumUpOfTheDay = dataCollector.getSumUpOfDay(LocalDate.now()); + DataSaver.save(ArchiveName.DAY_SUM_UP, sumUpOfTheDay); + } + + private static boolean sumupdayModIsActivated() { + return System.getenv(LINK_TO_DATA_PROPERTIE_NAME) != null; + } + + private static void createArchiveForThisHour() + throws IOException { + var logements = DataCollectorFromCrous.getAvailableLogementsWithConnection(getEmail(), getPassword()); + DataSaver.save(ArchiveName.HOUR, logements); + } + + private static String getPropertie(final String propertieName) { + LOGGER.info(() -> "Getting " + propertieName + " from environment variables"); + String propertie = System.getenv(propertieName); + if (propertie == null) { + LOGGER.error(() -> propertieName + " not found in environment variables"); + throw new PropertiesNotFoundRuntimeException(propertieName); } - return email; + return propertie; + } + + private static String getEmail() { + return getPropertie(MAIL_PROPERTIES_NAME); } private static String getPassword() { - LOGGER.info(() -> "Getting password from environment variables"); - String password = System.getenv(PASSWORD_PROPERTIES_NAME); - if (password == null) - { - LOGGER.error(() -> "Password not found in environment variables"); - throw new PropertiesNotFoundRuntimeException(PASSWORD_PROPERTIES_NAME); - } - return password; + return getPropertie(PASSWORD_PROPERTIES_NAME); } } diff --git a/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromArchive.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromArchive.java new file mode 100644 index 000000000..a9e5124ec --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromArchive.java @@ -0,0 +1,16 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import java.time.LocalDate; + +public class DataCollectorFromArchive { + private final String archiveUrl; + + public DataCollectorFromArchive(String archiveUrl) { + this.archiveUrl = archiveUrl; + } + + public String getSumUpOfDay(LocalDate day) { + return new RequestorToGetSumUpOfDay(day).requestWitGet(archiveUrl); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromCrous.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromCrous.java new file mode 100644 index 000000000..ddb7ac3bb --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorFromCrous.java @@ -0,0 +1,39 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import java.io.IOException; +import java.util.List; + +import com.github.forax.beautifullogger.Logger; + +import io.github.mathieusoysal.logement.Logement; +import io.github.mathieusoysal.logement.pojo.Convertor; + +public class DataCollectorFromCrous { + private static final Logger LOGGER = Logger.getLogger(); + private static final String LINK_TO_GET_ALL_LOGEMENTS = "https://trouverunlogement.lescrous.fr/api/fr/search/32"; + + public static List getAvailableLogementsWithoutConnection() + throws IOException { + Requestor requestor = new RequestorWithoutConnection(); + String jsonLogements = requestor.requestWitGet(LINK_TO_GET_ALL_LOGEMENTS); + return Convertor.getLogementsFromBruteJsonString(jsonLogements); + } + + public static List getAllLogementsWithoutConnection() + throws IOException { + LOGGER.info(() -> "Getting all logements"); + Requestor requestor = new RequestorWithoutConnection(); + String jsonLogements = requestor.requestWitGet("https://trouverunlogement.lescrous.fr/api/fr/search/29"); + return Convertor.getLogementsFromBruteJsonString(jsonLogements); + } + + public static List getAvailableLogementsWithConnection(String email, String password) + throws IOException { + Requestor requestor = new RequestorWithConnection(email, password); + String jsonLogements = requestor.requestWitGet(LINK_TO_GET_ALL_LOGEMENTS); + return Convertor.getLogementsFromBruteJsonString(jsonLogements); + } + + private DataCollectorFromCrous() { + } +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/collectors/Requestor.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/Requestor.java new file mode 100644 index 000000000..1f91d5244 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/Requestor.java @@ -0,0 +1,14 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import com.microsoft.playwright.options.RequestOptions; + +interface Requestor { + static final String BODY_POST_TO_GET_LOGEMENTS = "{\r\n \"idTool\": 32,\r\n \"need_aggregation\": false,\r\n \"page\": 1,\r\n \"pageSize\": 2500,\r\n \"sector\": null,\r\n \"occupationModes\": [],\r\n \"location\": [\r\n {\r\n \"lon\": -9.9079,\r\n \"lat\": 51.7087\r\n },\r\n {\r\n \"lon\": 14.3224,\r\n \"lat\": 40.5721\r\n }\r\n ],\r\n \"residence\": null,\r\n \"precision\": 9,\r\n \"equipment\": [],\r\n \"price\": {\r\n \"min\": 0,\r\n \"max\": 10000000\r\n }\r\n}"; + + static final RequestOptions REQUEST_TO_GET_LOGEMENTS = RequestOptions.create() + .setMethod("POST") + .setHeader("Content-Type", "application/json") + .setData(BODY_POST_TO_GET_LOGEMENTS); + + String requestWitGet(String url); +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorToGetSumUpOfDay.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorToGetSumUpOfDay.java new file mode 100644 index 000000000..669e81257 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorToGetSumUpOfDay.java @@ -0,0 +1,59 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.stream.IntStream; + +import com.github.forax.beautifullogger.Logger; +import com.microsoft.playwright.APIRequestContext; +import com.microsoft.playwright.Playwright; + +import io.github.mathieusoysal.data.managment.convertors.Convertor; +import io.github.mathieusoysal.exceptions.ApiRequestErrorRuntimeException; +import io.github.mathieusoysal.logement.Logement; + +class RequestorToGetSumUpOfDay implements Requestor { + private static final Logger LOGGER = Logger.getLogger(); + private static final NumberFormat NUMBER_FORMAT = new DecimalFormat("00"); + + private final String date; + + public RequestorToGetSumUpOfDay(LocalDate date) { + this.date = date.format(DateTimeFormatter.ISO_LOCAL_DATE); + } + + public RequestorToGetSumUpOfDay(String date) { + this.date = date; + } + + @Override + public String requestWitGet(String url) { + LOGGER.info(() -> "Creating sum up of the day: " + date); + String linkToDataForTheDay = url + "/" + date; + Logement[][] sumUp; + LOGGER.info(() -> "Creating profil to request logements"); + try (Playwright playwright = Playwright.create()) { + LOGGER.info(() -> "profil created"); + var context = playwright.request().newContext(); + sumUp = IntStream.range(0, 24) + .mapToObj(hour -> linkToDataForTheDay + "/" + NUMBER_FORMAT.format(hour)) + .map(link -> getFromUrl(link, context)) + .toArray(Logement[][]::new); + LOGGER.info(() -> "Logements received"); + } + LOGGER.info(() -> "profil closed"); + return Convertor.convertLogementMatrixToJson(sumUp); + } + + private static Logement[] getFromUrl(String url, APIRequestContext context) { + LOGGER.info(() -> "Getting data from url: " + url); + var respons = context.get(url); + if (!respons.ok()) + throw new ApiRequestErrorRuntimeException(respons); + LOGGER.info(() -> "Data received"); + return Convertor.convertJsonToArrayOfLogements(respons.text()); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/logement/data/DataCollector.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithConnection.java similarity index 51% rename from src/main/java/io/github/mathieusoysal/logement/data/DataCollector.java rename to src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithConnection.java index 85154a3fd..9af9d446b 100644 --- a/src/main/java/io/github/mathieusoysal/logement/data/DataCollector.java +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithConnection.java @@ -1,11 +1,7 @@ -package io.github.mathieusoysal.logement.data; +package io.github.mathieusoysal.data.managment.collectors; -import java.io.IOException; import java.nio.file.Paths; -import java.util.List; -import com.fasterxml.jackson.core.exc.StreamReadException; -import com.fasterxml.jackson.databind.DatabindException; import com.github.forax.beautifullogger.Logger; import com.microsoft.playwright.Browser; import com.microsoft.playwright.Browser.NewContextOptions; @@ -18,94 +14,42 @@ import com.microsoft.playwright.Tracing; import com.microsoft.playwright.options.AriaRole; import com.microsoft.playwright.options.LoadState; -import com.microsoft.playwright.options.RequestOptions; -import io.github.mathieusoysal.exceptions.ApiRequestFailedException; +import io.github.mathieusoysal.exceptions.ApiRequestFailedRuntimeException; import io.github.mathieusoysal.exceptions.CannotBeConnectedError; import io.github.mathieusoysal.exceptions.LoginOptionCantBeSelectedError; -import io.github.mathieusoysal.logement.pojo.Convertor; -import io.github.mathieusoysal.logement.pojo.Logement; -public class DataCollector { - private static final Logger LOGGER = Logger.getLogger(); - private static final String LINK_TO_GET_ALL_LOGEMENTS = "https://trouverunlogement.lescrous.fr/api/fr/search/32"; - private static final String BODY_POST_TO_GET_LOGEMENTS = "{\r\n \"idTool\": 32,\r\n \"need_aggregation\": false,\r\n \"page\": 1,\r\n \"pageSize\": 2500,\r\n \"sector\": null,\r\n \"occupationModes\": [],\r\n \"location\": [\r\n {\r\n \"lon\": -9.9079,\r\n \"lat\": 51.7087\r\n },\r\n {\r\n \"lon\": 14.3224,\r\n \"lat\": 40.5721\r\n }\r\n ],\r\n \"residence\": null,\r\n \"precision\": 9,\r\n \"equipment\": [],\r\n \"price\": {\r\n \"min\": 0,\r\n \"max\": 10000000\r\n }\r\n}"; - private static final RequestOptions REQUEST_TO_GET_LOGEMENTS = RequestOptions.create() - .setMethod("POST") - .setHeader("Content-Type", "application/json") - .setData(BODY_POST_TO_GET_LOGEMENTS); - - public static List getAvailableLogementsWithoutConnection() - throws ApiRequestFailedException, StreamReadException, DatabindException, IOException { - List logements; - LOGGER.info(() -> "Creating profil to request logements"); - try (Playwright playwright = Playwright.create()) { - LOGGER.info(() -> "profil created"); - LOGGER.info(() -> "Requesting logements from " + LINK_TO_GET_ALL_LOGEMENTS); - var respons = playwright.request().newContext() - .head(LINK_TO_GET_ALL_LOGEMENTS, REQUEST_TO_GET_LOGEMENTS); - if (!respons.ok()) - throw new ApiRequestFailedException(respons); - LOGGER.info(() -> "Logements received"); - logements = Convertor.getLogementsFromBruteJsonString(respons.text()); - } - LOGGER.info(() -> "profil closed"); - return logements; - } +class RequestorWithConnection implements Requestor { - public static List getAllLogementsWithoutConnection() - throws ApiRequestFailedException, StreamReadException, DatabindException, IOException { - LOGGER.info(() -> "Getting all logements"); - List logements; - LOGGER.info(() -> "Creating profil to request logements"); - try (Playwright playwright = Playwright.create()) { - var respons = playwright.request().newContext() - .head("https://trouverunlogement.lescrous.fr/api/fr/search/29", REQUEST_TO_GET_LOGEMENTS); - if (!respons.ok()) { - LOGGER.error(() -> "Request failed"); - throw new ApiRequestFailedException(respons); - } - LOGGER.info(() -> "Request succeed"); - logements = Convertor.getLogementsFromBruteJsonString(respons.text()); - } - LOGGER.info(() -> "profil closed"); - LOGGER.info(() -> "All logements received"); - return logements; + private final String email; + private final String password; + + public RequestorWithConnection(final String email, final String password) { + this.email = email; + this.password = password; } - public static List getAvailableLogementsWithConnection(String email, String password) - throws ApiRequestFailedException, StreamReadException, DatabindException, IOException, - InterruptedException { + @Override + public String requestWitGet(String url) { LOGGER.info(() -> "Getting available logements"); LOGGER.info(() -> "Creating profil to request logements"); Playwright playwright = Playwright.create(); Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions()); BrowserContext context = browser.newContext(new NewContextOptions().setScreenSize(1920, 1080)); Page page = context.newPage(); - List logements; + String jsonLogements; try { - - context.tracing().start(new Tracing.StartOptions() - .setScreenshots(true) - .setSnapshots(true) - .setSources(true)); - goToLoginPage(page); - selectLoginOption(playwright, page); - connectToTheCrous(email, password, playwright, page); - LOGGER.info(() -> "Going to logements page"); - page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Lancer une recherche")) - .click(); - page.waitForLoadState(); - LOGGER.info(() -> "Requesting logements from " + LINK_TO_GET_ALL_LOGEMENTS); + etablishConnectionWithWebsite(playwright, context, page); + LOGGER.info(() -> "Requesting logements from " + url); var respons = page.request() - .head(LINK_TO_GET_ALL_LOGEMENTS, + .head(url, REQUEST_TO_GET_LOGEMENTS); if (!respons.ok()) { LOGGER.error(() -> "Request failed"); - throw new ApiRequestFailedException(respons); + throw new ApiRequestFailedRuntimeException(respons); } LOGGER.info(() -> "Logements received"); - logements = Convertor.getLogementsFromBruteJsonString(respons.text()); + jsonLogements = respons.text(); } catch (TimeoutError | LoginOptionCantBeSelectedError | CannotBeConnectedError e) { LOGGER.error("Request failed", e); context.tracing().stop(new Tracing.StopOptions() @@ -118,9 +62,30 @@ public static List getAvailableLogementsWithConnection(String email, S playwright.close(); LOGGER.info(() -> "profil closed"); } - return logements; + return jsonLogements; } + private void etablishConnectionWithWebsite(Playwright playwright, BrowserContext context, Page page) { + context.tracing().start(new Tracing.StartOptions() + .setScreenshots(true) + .setSnapshots(true) + .setSources(true)); + goToLoginPage(page); + try { + selectLoginOption(playwright, page); + } catch (LoginOptionCantBeSelectedError e) { + LOGGER.warning(() -> "Can't connect to the crous"); + selectLoginOption(playwright, page); + } + connectToTheCrous(email, password, playwright, page); + LOGGER.info(() -> "Going to logements page"); + page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Lancer une recherche")) + .click(); + page.waitForLoadState(); + } + + private static final Logger LOGGER = Logger.getLogger(); + private static void goToLoginPage(Page page) { LOGGER.info(() -> "Going to login page"); page.navigate("https://trouverunlogement.lescrous.fr/tools/32/search"); @@ -186,6 +151,4 @@ private static void waitForUrlChange(String currentUrl, Page page) { page.waitForCondition(() -> !page.url().equals(currentUrl)); } - private DataCollector() { - } } diff --git a/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithoutConnection.java b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithoutConnection.java new file mode 100644 index 000000000..3f6699b53 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/collectors/RequestorWithoutConnection.java @@ -0,0 +1,30 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import com.github.forax.beautifullogger.Logger; +import com.microsoft.playwright.Playwright; + +import io.github.mathieusoysal.exceptions.ApiRequestFailedRuntimeException; + +public class RequestorWithoutConnection implements Requestor { + + private static final Logger LOGGER = Logger.getLogger(); + + @Override + public String requestWitGet(String url) { + LOGGER.info(() -> "Creating profil to request logements"); + String result; + try (Playwright playwright = Playwright.create()) { + LOGGER.info(() -> "profil created"); + LOGGER.info(() -> "Requesting logements from " + url); + var respons = playwright.request().newContext() + .head(url, REQUEST_TO_GET_LOGEMENTS); + if (!respons.ok()) + throw new ApiRequestFailedRuntimeException(respons); + result = respons.text(); + LOGGER.info(() -> "Logements received"); + } + LOGGER.info(() -> "profil closed"); + return result; + } + +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/convertors/Convertor.java b/src/main/java/io/github/mathieusoysal/data/managment/convertors/Convertor.java new file mode 100644 index 000000000..97b48d7e7 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/convertors/Convertor.java @@ -0,0 +1,71 @@ +package io.github.mathieusoysal.data.managment.convertors; + +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.github.forax.beautifullogger.Logger; + +import io.github.mathieusoysal.exceptions.ConvertionErrorRuntimeException; +import io.github.mathieusoysal.logement.Logement; + +public class Convertor { + private static final Logger LOGGER = Logger.getLogger(); + + public static String convertLogementsToJson(List logements){ + LOGGER.info(() -> "Converting logements to json"); + ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); + String result = null; + try { + result = ow.writeValueAsString(logements); + } catch (JsonProcessingException e) { + LOGGER.error("Error while converting logements to json", e); + throw new ConvertionErrorRuntimeException("Error while converting logements to json", e); + } + LOGGER.info(() -> "Logements converted to json"); + return result; + } + + public static List convertJsonToListOfLogements(String jsonLogements) { + LOGGER.info(() -> "Converting json to List of logements"); + List logements = null; + try { + logements = new ObjectMapper().readValue(jsonLogements, new TypeReference>() { + }); + } catch (JsonProcessingException e) { + LOGGER.error("Error while converting json to List of logements", e); + throw new ConvertionErrorRuntimeException("Error while converting json to List of logements", e); + } + LOGGER.info(() -> "Json converted to logements"); + return logements; + } + + public static Logement[] convertJsonToArrayOfLogements(String jsonLogements) { + LOGGER.info(() -> "Converting json to Array of logements"); + Logement[] logements = null; + try { + logements = new ObjectMapper().readValue(jsonLogements, Logement[].class); + } catch (JsonProcessingException e) { + LOGGER.error("Error while converting json to Array of logements", e); + throw new ConvertionErrorRuntimeException("Error while converting json to Array of logements", e); + } + LOGGER.info(() -> "Json converted to logements"); + return logements; + } + + public static String convertLogementMatrixToJson(Logement[][] logements) { + LOGGER.info(() -> "Converting Matrix of logements to json"); + var objectMapper = new ObjectMapper(); + String result; + try { + result = objectMapper.writeValueAsString(logements); + } catch (JsonProcessingException e) { + LOGGER.error("Error while converting Matrix of logements to json", e); + throw new ConvertionErrorRuntimeException("Error while converting Matrix of logements to json", e); + } + LOGGER.info(() -> "Logements converted to json"); + return result; + } +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/savers/ArchiveName.java b/src/main/java/io/github/mathieusoysal/data/managment/savers/ArchiveName.java new file mode 100644 index 000000000..5f5e2e379 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/savers/ArchiveName.java @@ -0,0 +1,20 @@ +package io.github.mathieusoysal.data.managment.savers; + +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.function.Supplier; + +public enum ArchiveName { + DAY_SUM_UP(() -> "sum-up"), + HOUR(() -> OffsetDateTime.now().toLocalTime().format(DateTimeFormatter.ofPattern("HH"))); + + private final Supplier nameSupplier; + + ArchiveName(Supplier nameSupplier) { + this.nameSupplier = nameSupplier; + } + + public String getName() { + return nameSupplier.get(); + } +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/savers/DataSaver.java b/src/main/java/io/github/mathieusoysal/data/managment/savers/DataSaver.java new file mode 100644 index 000000000..27e416bc4 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/savers/DataSaver.java @@ -0,0 +1,39 @@ +package io.github.mathieusoysal.data.managment.savers; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +import com.github.forax.beautifullogger.Logger; + +import io.github.mathieusoysal.data.managment.convertors.Convertor; +import io.github.mathieusoysal.exceptions.ImpossibleWriteRuntimeException; +import io.github.mathieusoysal.logement.Logement; + +public class DataSaver { + private static final Logger LOGGER = Logger.getLogger(); + + public static File save(ArchiveName archiveName, String content) { + File archiveFile = FileManager.getOrCreateArchiveFile(archiveName); + writeDataInsideArchiveFile(content, archiveFile); + return archiveFile; + } + + public static File save(ArchiveName archiveName, List logements) { + String logementsJson = Convertor.convertLogementsToJson(logements); + return save(archiveName, logementsJson); + } + + private static void writeDataInsideArchiveFile(String logementsJson, File archiveFile) { + LOGGER.info(() -> "Writing logements to file"); + try (FileWriter fileWriter = new FileWriter(archiveFile)) { + fileWriter.write(logementsJson); + } catch (IOException e) { + LOGGER.error("Error while writing logements to file", e); + throw new ImpossibleWriteRuntimeException("Error while writing logements to file", e); + } + LOGGER.info(() -> "Logements written to file"); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/savers/FileManager.java b/src/main/java/io/github/mathieusoysal/data/managment/savers/FileManager.java new file mode 100644 index 000000000..d61a4c61a --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/savers/FileManager.java @@ -0,0 +1,39 @@ +package io.github.mathieusoysal.data.managment.savers; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.time.DateTimeException; +import java.util.stream.Stream; + +import com.github.forax.beautifullogger.Logger; + +class FileManager { + private static final Logger LOGGER = Logger.getLogger(); + + static File getOrCreateArchiveFile(ArchiveName archiveName) { + var archiveFolder = FolderManager.getOrCreateArchiveFolderWithCurrentDate(); + return getArchiveFile(archiveFolder, + archiveName.getName()); + } + + private static File getArchiveFile(File archiveFolder, String archiveFileName) throws DateTimeException { + LOGGER.info(() -> "Getting archive file"); + Stream.of(archiveFolder.listFiles()) + .filter(file -> file.getName().equals(archiveFileName)) + .findFirst() + .ifPresent(file -> { + LOGGER.warning(() -> "Archive file already exists"); + try { + Files.delete(file.toPath()); + } catch (IOException e) { + LOGGER.error("Error while deleting archive file", e); + e.printStackTrace(); + } + LOGGER.info(() -> "Archive file deleted"); + }); + var archiveFile = new File(archiveFolder, archiveFileName); + LOGGER.info(() -> "Archive file got"); + return archiveFile; + } +} diff --git a/src/main/java/io/github/mathieusoysal/data/managment/savers/FolderManager.java b/src/main/java/io/github/mathieusoysal/data/managment/savers/FolderManager.java new file mode 100644 index 000000000..b100f9d0c --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/data/managment/savers/FolderManager.java @@ -0,0 +1,31 @@ +package io.github.mathieusoysal.data.managment.savers; + +import java.io.File; +import java.time.OffsetDateTime; + +class FolderManager { + private static final java.util.logging.Logger LOGGER = java.util.logging.Logger + .getLogger(FolderManager.class.getName()); + + static File createArchiveFolder() { + LOGGER.info(() -> "getting archive folder"); + File archiveFolder = new File("archive"); + if (!archiveFolder.exists()) { + archiveFolder.mkdir(); + LOGGER.info(() -> "Archive folder created"); + } + return archiveFolder; + } + + static File getOrCreateArchiveFolderWithCurrentDate() { + LOGGER.info(() -> "Getting archive folder for current date"); + File archiveFolder = createArchiveFolder(); + String archiveFolderName = OffsetDateTime.now().toLocalDate().toString(); + File archiveFile = new File(archiveFolder, archiveFolderName); + if (!archiveFile.exists()) { + archiveFile.mkdir(); + LOGGER.info(() -> "Archive folder for current date created"); + } + return archiveFile; + } +} diff --git a/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestErrorRuntimeException.java b/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestErrorRuntimeException.java new file mode 100644 index 000000000..a45e30e84 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestErrorRuntimeException.java @@ -0,0 +1,22 @@ +package io.github.mathieusoysal.exceptions; + +import com.microsoft.playwright.APIResponse; + +public class ApiRequestErrorRuntimeException extends RuntimeException { + public ApiRequestErrorRuntimeException(String message) { + super("Api request failed: " + message); + } + + public ApiRequestErrorRuntimeException(String message, Throwable cause) { + super("Api request failed: " + message, cause); + } + + public ApiRequestErrorRuntimeException(APIResponse respons, Throwable cause) { + super("Api request failed with status code " + respons.status(), cause); + } + + public ApiRequestErrorRuntimeException(APIResponse respons) { + super("Api request failed with status code " + respons.status() + " : " + respons.url()); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestFailedRuntimeException.java b/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestFailedRuntimeException.java new file mode 100644 index 000000000..3d9ddbe6e --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/exceptions/ApiRequestFailedRuntimeException.java @@ -0,0 +1,11 @@ +package io.github.mathieusoysal.exceptions; + +import com.microsoft.playwright.APIResponse; + +public class ApiRequestFailedRuntimeException extends RuntimeException { + + public ApiRequestFailedRuntimeException(APIResponse respons) { + super("API request failed with status code " + respons.status() + " url " + respons.url()); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/exceptions/ConvertionErrorRuntimeException.java b/src/main/java/io/github/mathieusoysal/exceptions/ConvertionErrorRuntimeException.java new file mode 100644 index 000000000..28e7a8bbd --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/exceptions/ConvertionErrorRuntimeException.java @@ -0,0 +1,13 @@ +package io.github.mathieusoysal.exceptions; + +public class ConvertionErrorRuntimeException extends RuntimeException { + + public ConvertionErrorRuntimeException(String message) { + super("Convertion failed: " + message); + } + + public ConvertionErrorRuntimeException(String message, Throwable cause) { + super("Convertion failed: " + message, cause); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/exceptions/ImpossibleWriteRuntimeException.java b/src/main/java/io/github/mathieusoysal/exceptions/ImpossibleWriteRuntimeException.java new file mode 100644 index 000000000..cc4843815 --- /dev/null +++ b/src/main/java/io/github/mathieusoysal/exceptions/ImpossibleWriteRuntimeException.java @@ -0,0 +1,17 @@ +package io.github.mathieusoysal.exceptions; + +public class ImpossibleWriteRuntimeException extends RuntimeException { + + public ImpossibleWriteRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public ImpossibleWriteRuntimeException(String message) { + super(message); + } + + public ImpossibleWriteRuntimeException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/io/github/mathieusoysal/logement/Address.java b/src/main/java/io/github/mathieusoysal/logement/Address.java index 15a10ce5d..7f848f945 100644 --- a/src/main/java/io/github/mathieusoysal/logement/Address.java +++ b/src/main/java/io/github/mathieusoysal/logement/Address.java @@ -11,30 +11,32 @@ */ public class Address { + public Address(){} + /** * The full street address of the residence. */ - private final String fullAddress; + private String fullAddress; /** * The street of the address. */ - private final String street; + private String street; /** * The city of the address. */ - private final String city; + private String city; /** * The zip code of the address. */ - private final String zipCode; + private String zipCode; /** * The location of the address. */ - private final Location location; + private Location location; /** * Constructs an address object with the given street, city, zip code, and diff --git a/src/main/java/io/github/mathieusoysal/logement/Equipement.java b/src/main/java/io/github/mathieusoysal/logement/Equipment.java similarity index 95% rename from src/main/java/io/github/mathieusoysal/logement/Equipement.java rename to src/main/java/io/github/mathieusoysal/logement/Equipment.java index 6cb2cefa5..d250ed4c8 100644 --- a/src/main/java/io/github/mathieusoysal/logement/Equipement.java +++ b/src/main/java/io/github/mathieusoysal/logement/Equipment.java @@ -6,7 +6,7 @@ * * @author MathieuSoysal */ -public enum Equipement { +public enum Equipment { /** * A toilet */ @@ -63,7 +63,7 @@ public enum Equipement { * @param equipement the string representation of the equipment * @return the Equipement enum value corresponding to the given string */ - public static Equipement fromString(String equipement) { + public static Equipment fromString(String equipement) { if (equipement == null || equipement.isBlank() || equipement.equals("null")) return NONE; switch (equipement) { diff --git a/src/main/java/io/github/mathieusoysal/logement/pojo/Logement.java b/src/main/java/io/github/mathieusoysal/logement/Logement.java similarity index 84% rename from src/main/java/io/github/mathieusoysal/logement/pojo/Logement.java rename to src/main/java/io/github/mathieusoysal/logement/Logement.java index ceeef7826..8566558fd 100644 --- a/src/main/java/io/github/mathieusoysal/logement/pojo/Logement.java +++ b/src/main/java/io/github/mathieusoysal/logement/Logement.java @@ -1,11 +1,7 @@ -package io.github.mathieusoysal.logement.pojo; +package io.github.mathieusoysal.logement; import java.util.List; -import io.github.mathieusoysal.logement.Address; -import io.github.mathieusoysal.logement.BedKind; -import io.github.mathieusoysal.logement.Equipement; - /** * Logement * @@ -27,18 +23,23 @@ public class Logement { private boolean available; private boolean highDemand; private boolean lowStock; - private List equipements; + private List equipements; private double areaMin; private double areaMax; - private List occupationMods; + private List occupationMods; private List transports; + + // Create constructor + public Logement() + {} + /** * Constructs a new Logement object with the specified ID. * * @param id the ID of the Logement object */ - Logement(int id) { + public Logement(int id) { this.id = id; } @@ -185,7 +186,7 @@ public boolean isLowStock() { * * @return the list of equipment in this Logement object */ - public List getEquipements() { + public List getEquipements() { return equipements; } @@ -212,7 +213,7 @@ public double getAreaMax() { * * @return the list of occupation modifications for this Logement object */ - public List getOccupationMods() { + public List getOccupationMods() { return occupationMods; } @@ -235,71 +236,71 @@ public String toString() { + ", transports=" + transports + "]"; } - void setId(int id) { + public void setId(int id) { this.id = id; } - void setLabel(String label) { + public void setLabel(String label) { this.label = label; } - void setAddress(Address address) { + public void setAddress(Address address) { this.address = address; } - void setBedCount(int bedCount) { + public void setBedCount(int bedCount) { this.bedCount = bedCount; } - void setBedKind(BedKind bedKind) { + public void setBedKind(BedKind bedKind) { this.bedKind = bedKind; } - void setBedroomCount(int bedroomCount) { + public void setBedroomCount(int bedroomCount) { this.bedroomCount = bedroomCount; } - void setRoomCount(int roomCount) { + public void setRoomCount(int roomCount) { this.roomCount = roomCount; } - void setInUnavailabilityPeriod(boolean inUnavailabilityPeriod) { + public void setInUnavailabilityPeriod(boolean inUnavailabilityPeriod) { this.inUnavailabilityPeriod = inUnavailabilityPeriod; } - void setDescription(String description) { + public void setDescription(String description) { this.description = description; } - void setAvailable(boolean available) { + public void setAvailable(boolean available) { this.available = available; } - void setHighDemand(boolean highDemand) { + public void setHighDemand(boolean highDemand) { this.highDemand = highDemand; } - void setLowStock(boolean lowStock) { + public void setLowStock(boolean lowStock) { this.lowStock = lowStock; } - void setEquipements(List equipements) { + public void setEquipements(List equipements) { this.equipements = equipements; } - void setAreaMin(double areaMin) { + public void setAreaMin(double areaMin) { this.areaMin = areaMin; } - void setAreaMax(double areaMax) { + public void setAreaMax(double areaMax) { this.areaMax = areaMax; } - void setOccupationMods(List occupationMods) { + public void setOccupationMods(List occupationMods) { this.occupationMods = occupationMods; } - void setTransports(List transports) { + public void setTransports(List transports) { this.transports = transports; } diff --git a/src/main/java/io/github/mathieusoysal/logement/pojo/OccupationMod.java b/src/main/java/io/github/mathieusoysal/logement/OccupationMode.java similarity index 85% rename from src/main/java/io/github/mathieusoysal/logement/pojo/OccupationMod.java rename to src/main/java/io/github/mathieusoysal/logement/OccupationMode.java index 2502116d3..77ec30c70 100644 --- a/src/main/java/io/github/mathieusoysal/logement/pojo/OccupationMod.java +++ b/src/main/java/io/github/mathieusoysal/logement/OccupationMode.java @@ -1,11 +1,9 @@ -package io.github.mathieusoysal.logement.pojo; - -import io.github.mathieusoysal.logement.OccupationKind; +package io.github.mathieusoysal.logement; /** * This class represents a modification of the occupation of a housing unit. */ -public class OccupationMod { +public class OccupationMode { /** * The new kind of occupation. */ @@ -21,6 +19,10 @@ public class OccupationMod { */ private int rentMax; + + public OccupationMode() { + } + /** * Constructs a new OccupationMod object with the specified occupation kind, minimum rent, and maximum rent. * @@ -28,7 +30,7 @@ public class OccupationMod { * @param rentMin the new minimum rent * @param rentMax the new maximum rent */ - OccupationMod(OccupationKind occupationKind, int rentMin, int rentMax) { + public OccupationMode(OccupationKind occupationKind, int rentMin, int rentMax) { this.occupationKind = occupationKind; this.rentMin = rentMin; this.rentMax = rentMax; diff --git a/src/main/java/io/github/mathieusoysal/logement/Transport.java b/src/main/java/io/github/mathieusoysal/logement/Transport.java index 61208f1d6..55ad11a82 100644 --- a/src/main/java/io/github/mathieusoysal/logement/Transport.java +++ b/src/main/java/io/github/mathieusoysal/logement/Transport.java @@ -9,6 +9,9 @@ public class Transport { private int distance; private TransportUnitOfMeasure unitOfMeasure; + public Transport() { + } + /** * Constructs a new Transport object with the specified parameters. * diff --git a/src/main/java/io/github/mathieusoysal/logement/data/DataSaver.java b/src/main/java/io/github/mathieusoysal/logement/data/DataSaver.java deleted file mode 100644 index a04fdc530..000000000 --- a/src/main/java/io/github/mathieusoysal/logement/data/DataSaver.java +++ /dev/null @@ -1,94 +0,0 @@ -package io.github.mathieusoysal.logement.data; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.time.DateTimeException; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.stream.Stream; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.github.forax.beautifullogger.Logger; - -import io.github.mathieusoysal.logement.pojo.Logement; - -public class DataSaver { - private static final Logger LOGGER = Logger.getLogger(); - - public static File createArchiveFolder() { - LOGGER.info(() -> "getting archive folder"); - File archiveFolder = new File("archive"); - if (!archiveFolder.exists()) { - archiveFolder.mkdir(); - LOGGER.info(() -> "Archive folder created"); - } - - return archiveFolder; - } - - public static File createArchiveLogements(List logements) throws JsonProcessingException { - File archiveFolder = getArchiveFolderForCurrentDate(); - String logementsJson = convertLogementsToJson(logements); - File archiveFile = getArchiveFile(archiveFolder); - writeLogementsDataInsideArchiveFile(logementsJson, archiveFile); - return archiveFile; - } - - private static void writeLogementsDataInsideArchiveFile(String logementsJson, File archiveFile) { - LOGGER.info(() -> "Writing logements to file"); - try (FileWriter fileWriter = new FileWriter(archiveFile)) { - fileWriter.write(logementsJson); - } catch (IOException e) { - LOGGER.error("Error while writing logements to file", e); - throw new RuntimeException("Error while writing logements to file", e); - } - LOGGER.info(() -> "Logements written to file"); - } - - private static File getArchiveFile(File archiveFolder) throws DateTimeException { - LOGGER.info(() -> "Getting archive file"); - String archiveFileName = OffsetDateTime.now().toLocalTime().format(DateTimeFormatter.ofPattern("HH")); - Stream.of(archiveFolder.listFiles()) - .filter(file -> file.getName().equals(archiveFileName)) - .findFirst() - .ifPresent(file -> { - LOGGER.error(() -> "Archive file already exists"); - try { - Files.delete(file.toPath()); - } catch (IOException e) { - LOGGER.error("Error while deleting archive file", e); - e.printStackTrace(); - } - LOGGER.info(() -> "Archive file deleted"); - }); - var archiveFile = new File(archiveFolder, archiveFileName); - LOGGER.info(() -> "Archive file got"); - return archiveFile; - } - - private static String convertLogementsToJson(List logements) throws JsonProcessingException { - LOGGER.info(() -> "Converting logements to json"); - ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); - var result = ow.writeValueAsString(logements); - LOGGER.info(() -> "Logements converted to json"); - return result; - } - - private static File getArchiveFolderForCurrentDate() { - LOGGER.info(() -> "Getting archive folder for current date"); - File archiveFolder = createArchiveFolder(); - String archiveFolderName = OffsetDateTime.now().toLocalDate().toString(); - File archiveFile = new File(archiveFolder, archiveFolderName); - if (!archiveFile.exists()) { - archiveFile.mkdir(); - LOGGER.info(() -> "Archive folder for current date created"); - } - return archiveFile; - } - -} diff --git a/src/main/java/io/github/mathieusoysal/logement/pojo/Convertor.java b/src/main/java/io/github/mathieusoysal/logement/pojo/Convertor.java index ae80eac50..a9ed3d126 100644 --- a/src/main/java/io/github/mathieusoysal/logement/pojo/Convertor.java +++ b/src/main/java/io/github/mathieusoysal/logement/pojo/Convertor.java @@ -4,14 +4,13 @@ import java.io.IOException; import java.util.List; -import com.fasterxml.jackson.core.exc.StreamReadException; -import com.fasterxml.jackson.databind.DatabindException; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.forax.beautifullogger.Logger; import io.github.mathieusoysal.logement.Address; import io.github.mathieusoysal.logement.BedKind; import io.github.mathieusoysal.logement.Location; +import io.github.mathieusoysal.logement.Logement; import io.github.mathieusoysal.logement.OccupationKind; import io.github.mathieusoysal.logement.TransportKind; import io.github.mathieusoysal.logement.TransportUnitOfMeasure; @@ -22,7 +21,7 @@ public class Convertor { private Convertor() { } - static List getItemsFromJsonFile(File file) throws StreamReadException, DatabindException, IOException { + static List getItemsFromJsonFile(File file) throws IOException { LOGGER.info(() -> "Reading json file for convertion to java object"); ObjectMapper objectMapper = new ObjectMapper(); Input results = objectMapper.readValue(file, Input.class); @@ -30,7 +29,7 @@ static List getItemsFromJsonFile(File file) throws StreamReadException, Da return results.getResults().getItems(); } - static List getItemsFromJsonString(String json) throws StreamReadException, DatabindException, IOException { + static List getItemsFromJsonString(String json) throws IOException { LOGGER.info(() -> "Reading json string for convertion to java object"); ObjectMapper objectMapper = new ObjectMapper(); Input results = objectMapper.readValue(json, Input.class); @@ -46,13 +45,13 @@ static List convertItemsToLogements(List items) { } public static List getLogementsFromBruteJsonFile(File file) - throws StreamReadException, DatabindException, IOException { + throws IOException { List items = getItemsFromJsonFile(file); return convertItemsToLogements(items); } public static List getLogementsFromBruteJsonString(String json) - throws StreamReadException, DatabindException, IOException { + throws IOException { List items = getItemsFromJsonString(json); return convertItemsToLogements(items); } @@ -83,15 +82,15 @@ private static Address getAddress(Item item) { new Location(item.getResidence().getLocation().getLat(), item.getResidence().getLocation().getLon())); } - private static List getEquipements(Item item) { + private static List getEquipements(Item item) { return item.getEquipments().stream() - .map(equipment -> io.github.mathieusoysal.logement.Equipement.fromString((equipment.getLabel()))) + .map(equipment -> io.github.mathieusoysal.logement.Equipment.fromString((equipment.getLabel()))) .toList(); } - private static List getOccupationMods(Item item) { + private static List getOccupationMods(Item item) { return item.getOccupationModes().stream() - .map(occupationMod -> new OccupationMod( + .map(occupationMod -> new io.github.mathieusoysal.logement.OccupationMode( OccupationKind.fromString(occupationMod.getType()), occupationMod.getRent().getMin(), occupationMod.getRent().getMax())) diff --git a/src/main/java/io/github/mathieusoysal/logement/pojo/LogementBuilder.java b/src/main/java/io/github/mathieusoysal/logement/pojo/LogementBuilder.java index 00b529685..28e0464db 100644 --- a/src/main/java/io/github/mathieusoysal/logement/pojo/LogementBuilder.java +++ b/src/main/java/io/github/mathieusoysal/logement/pojo/LogementBuilder.java @@ -4,7 +4,9 @@ import io.github.mathieusoysal.logement.Address; import io.github.mathieusoysal.logement.BedKind; -import io.github.mathieusoysal.logement.Equipement; +import io.github.mathieusoysal.logement.Equipment; +import io.github.mathieusoysal.logement.Logement; +import io.github.mathieusoysal.logement.OccupationMode; class LogementBuilder { private Logement logement; @@ -68,7 +70,7 @@ LogementBuilder withLowStock(boolean hLowStock) { return this; } - LogementBuilder withEquipements(List hEquipements) { + LogementBuilder withEquipements(List hEquipements) { logement.setEquipements(hEquipements); return this; } @@ -83,7 +85,7 @@ LogementBuilder withAreaMax(double hAreaMax) { return this; } - LogementBuilder withOccupationMods(List hOccupationMods) { + LogementBuilder withOccupationMods(List hOccupationMods) { logement.setOccupationMods(hOccupationMods); return this; } diff --git a/src/test/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorTest.java b/src/test/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorTest.java new file mode 100644 index 000000000..ae2a7292d --- /dev/null +++ b/src/test/java/io/github/mathieusoysal/data/managment/collectors/DataCollectorTest.java @@ -0,0 +1,96 @@ +package io.github.mathieusoysal.data.managment.collectors; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.exc.StreamReadException; +import com.fasterxml.jackson.databind.DatabindException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.github.mathieusoysal.exceptions.ApiRequestFailedException; +import io.github.mathieusoysal.logement.Logement; + +class DataCollectorTest { + + @Test + void testGetLogementsWithoutConnection_returnsEmptyList() + throws StreamReadException, DatabindException, ApiRequestFailedException, IOException { + // Arrange + + // Act + List result = DataCollectorFromCrous.getAvailableLogementsWithoutConnection(); + + // Assert + Assertions.assertNotEquals(0, result.size()); + } + + @Test + void testGetAllLogementsWithoutConnection_returnsLogements() + throws StreamReadException, DatabindException, ApiRequestFailedException, IOException { + // Arrange + + // Act + List result = DataCollectorFromCrous.getAllLogementsWithoutConnection(); + + // Assert + Assertions.assertNotEquals(0, result.size()); + } + + @Test + void testConvertion() throws StreamReadException, DatabindException, ApiRequestFailedException, IOException { + List result = DataCollectorFromCrous.getAllLogementsWithoutConnection(); + + assertNotNull(result); + + ObjectMapper objectMapper = new ObjectMapper(); + + String json = objectMapper.writeValueAsString(result); + + assertNotNull(json); + + + assertDoesNotThrow(() -> objectMapper.readValue(json, + new com.fasterxml.jackson.core.type.TypeReference>() { + })); + } + + @Test + void testGetLogementsWithConnection_returnsLogements() + throws StreamReadException, DatabindException, ApiRequestFailedException, IOException, + InterruptedException { + // Arrange + String email = System.getenv("TEST_MAIL"); + String password = System.getenv("TEST_PASSWORD"); + + // Act + assertNotNull(email, "Please set TEST_MAIL environment variable"); + assertNotNull(password, "Please set TEST_PASSWORD environment variable"); + List result = DataCollectorFromCrous.getAvailableLogementsWithConnection( + email, + password); + + // Assert + Assertions.assertNotEquals(DataCollectorFromCrous.getAvailableLogementsWithoutConnection().size(), + result.size()); + } + + @Test + void testCreateSumUpOfTheDay() throws JsonProcessingException { + String linkToData = "https://mathieusoysal.github.io/CROUS-assistant-Collector/v1/logements-crous/available"; + LocalDate date = LocalDate.parse("2024-01-02", DateTimeFormatter.ISO_LOCAL_DATE); + assertDoesNotThrow( + () -> { + DataCollectorFromArchive dataCollectorFromArchive = new DataCollectorFromArchive(linkToData); + dataCollectorFromArchive.getSumUpOfDay(date);}); + } + +} \ No newline at end of file diff --git a/src/test/java/io/github/mathieusoysal/data/managment/savers/DataSaverTest.java b/src/test/java/io/github/mathieusoysal/data/managment/savers/DataSaverTest.java new file mode 100644 index 000000000..1a0c69855 --- /dev/null +++ b/src/test/java/io/github/mathieusoysal/data/managment/savers/DataSaverTest.java @@ -0,0 +1,41 @@ +package io.github.mathieusoysal.data.managment.savers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.io.File; +import java.io.IOException; +import java.time.LocalDate; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import io.github.mathieusoysal.data.managment.collectors.DataCollectorFromArchive; +import io.github.mathieusoysal.data.managment.collectors.DataCollectorFromCrous; +import io.github.mathieusoysal.exceptions.ApiRequestFailedException; +import io.github.mathieusoysal.logement.Logement; + +class DataSaverTest { + + @AfterEach + void tearDown() { + File archiveFolder = new File("archive"); + if (archiveFolder.exists()) + archiveFolder.delete(); + } + + + @Test + void testCreateArchiveLogements() throws ApiRequestFailedException, IOException { + List logements = DataCollectorFromCrous.getAllLogementsWithoutConnection().stream().limit(2).toList(); + var file = assertDoesNotThrow(() -> DataSaver.save(ArchiveName.HOUR, logements)); + file.delete(); + } + + @Test + void testCreateArchiveLogementsForDay() throws ApiRequestFailedException, IOException { + var dataCollector = new DataCollectorFromArchive("https://mathieusoysal.github.io/CROUS-assistant-Collector/v1/logements-crous/available/"); + assertDoesNotThrow(() -> dataCollector.getSumUpOfDay(LocalDate.of(2024, 1, 3))); + } + +} diff --git a/src/test/java/io/github/mathieusoysal/data/managment/savers/FolderManagerTest.java b/src/test/java/io/github/mathieusoysal/data/managment/savers/FolderManagerTest.java new file mode 100644 index 000000000..025e13346 --- /dev/null +++ b/src/test/java/io/github/mathieusoysal/data/managment/savers/FolderManagerTest.java @@ -0,0 +1,21 @@ +package io.github.mathieusoysal.data.managment.savers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; + +import org.junit.jupiter.api.Test; + +public class FolderManagerTest { + + @Test + void testCreateArchiveFolder() { + File archiveFolder = FolderManager.createArchiveFolder(); + + assertTrue(archiveFolder.exists()); + assertTrue(archiveFolder.isDirectory()); + assertEquals("archive", archiveFolder.getName()); + archiveFolder.delete(); + } +} diff --git a/src/test/java/io/github/mathieusoysal/logement/EquipementTest.java b/src/test/java/io/github/mathieusoysal/logement/EquipementTest.java index 85b393a60..941f0fca5 100644 --- a/src/test/java/io/github/mathieusoysal/logement/EquipementTest.java +++ b/src/test/java/io/github/mathieusoysal/logement/EquipementTest.java @@ -11,10 +11,10 @@ void testFromString_withValidInput_returnsEnumValue() { String input = "WC"; // Act - Equipement result = Equipement.fromString(input); + Equipment result = Equipment.fromString(input); // Assert - Assertions.assertEquals(Equipement.WC, result); + Assertions.assertEquals(Equipment.WC, result); } @Test @@ -23,10 +23,10 @@ void testFromString_withNullInput_returnsNone() { String input = null; // Act - Equipement result = Equipement.fromString(input); + Equipment result = Equipment.fromString(input); // Assert - Assertions.assertEquals(Equipement.NONE, result); + Assertions.assertEquals(Equipment.NONE, result); } @Test @@ -35,10 +35,10 @@ void testFromString_withBlankInput_returnsNone() { String input = ""; // Act - Equipement result = Equipement.fromString(input); + Equipment result = Equipment.fromString(input); // Assert - Assertions.assertEquals(Equipement.NONE, result); + Assertions.assertEquals(Equipment.NONE, result); } @Test @@ -47,10 +47,10 @@ void testFromString_withNullString_returnsNone() { String input = "null"; // Act - Equipement result = Equipement.fromString(input); + Equipment result = Equipment.fromString(input); // Assert - Assertions.assertEquals(Equipement.NONE, result); + Assertions.assertEquals(Equipment.NONE, result); } @Test @@ -59,9 +59,9 @@ void testFromString_withInvalidInput_returnUnknown() { String input = "InvalidEquipement"; // Act - Equipement result = Equipement.fromString(input); + Equipment result = Equipment.fromString(input); // Assert - Assertions.assertEquals(Equipement.UNKNOWN, result); + Assertions.assertEquals(Equipment.UNKNOWN, result); } } \ No newline at end of file diff --git a/src/test/java/io/github/mathieusoysal/logement/data/DataCollectorTest.java b/src/test/java/io/github/mathieusoysal/logement/data/DataCollectorTest.java deleted file mode 100644 index c3f8dffe1..000000000 --- a/src/test/java/io/github/mathieusoysal/logement/data/DataCollectorTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.github.mathieusoysal.logement.data; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.IOException; -import java.util.List; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.core.exc.StreamReadException; -import com.fasterxml.jackson.databind.DatabindException; - -import io.github.mathieusoysal.exceptions.ApiRequestFailedException; -import io.github.mathieusoysal.logement.pojo.Logement; - -class DataCollectorTest { - - @Test - void testGetLogementsWithoutConnection_returnsEmptyList() - throws StreamReadException, DatabindException, ApiRequestFailedException, IOException { - // Arrange - - // Act - List result = DataCollector.getAvailableLogementsWithoutConnection(); - - // Assert - Assertions.assertNotEquals(0, result.size()); - } - - @Test - void testGetAllLogementsWithoutConnection_returnsLogements() - throws StreamReadException, DatabindException, ApiRequestFailedException, IOException { - // Arrange - - // Act - List result = DataCollector.getAllLogementsWithoutConnection(); - - // Assert - Assertions.assertNotEquals(0, result.size()); - } - - @Test - void testGetLogementsWithConnection_returnsLogements() - throws StreamReadException, DatabindException, ApiRequestFailedException, IOException, - InterruptedException { - // Arrange - String email = System.getenv("TEST_MAIL"); - String password = System.getenv("TEST_PASSWORD"); - - // Act - assertNotNull(email, "Please set TEST_MAIL environment variable"); - assertNotNull(password, "Please set TEST_PASSWORD environment variable"); - List result = DataCollector.getAvailableLogementsWithConnection( - email, - password); - - // Assert - Assertions.assertNotEquals(DataCollector.getAvailableLogementsWithoutConnection().size(), result.size()); - } - -} \ No newline at end of file diff --git a/src/test/java/io/github/mathieusoysal/logement/data/DataSaverTest.java b/src/test/java/io/github/mathieusoysal/logement/data/DataSaverTest.java deleted file mode 100644 index 86a3352cb..000000000 --- a/src/test/java/io/github/mathieusoysal/logement/data/DataSaverTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.github.mathieusoysal.logement.data; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import io.github.mathieusoysal.exceptions.ApiRequestFailedException; -import io.github.mathieusoysal.logement.pojo.Logement; - -class DataSaverTest { - - @AfterEach - void tearDown() { - File archiveFolder = new File("archive"); - if (archiveFolder.exists()) - archiveFolder.delete(); - } - - @Test - void testCreateArchiveFolder() { - File archiveFolder = DataSaver.createArchiveFolder(); - - assertTrue(archiveFolder.exists()); - assertTrue(archiveFolder.isDirectory()); - assertEquals("archive", archiveFolder.getName()); - archiveFolder.delete(); - } - - @Test - void testCreateArchiveLogements() throws ApiRequestFailedException, IOException { - List logements = DataCollector.getAllLogementsWithoutConnection().stream().limit(2).toList(); - var file = assertDoesNotThrow(() -> DataSaver.createArchiveLogements(logements)); - file.delete(); - } - -} diff --git a/src/test/java/io/github/mathieusoysal/logement/pojo/ConvertorTest.java b/src/test/java/io/github/mathieusoysal/logement/pojo/ConvertorTest.java index a8331f42d..8cd98565c 100644 --- a/src/test/java/io/github/mathieusoysal/logement/pojo/ConvertorTest.java +++ b/src/test/java/io/github/mathieusoysal/logement/pojo/ConvertorTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; import io.github.mathieusoysal.logement.BedKind; +import io.github.mathieusoysal.logement.Logement; import io.github.mathieusoysal.logement.OccupationKind; import io.github.mathieusoysal.logement.TransportKind; import io.github.mathieusoysal.logement.TransportUnitOfMeasure; @@ -91,9 +92,9 @@ void testConvertItemsToLogements() throws IOException { assertEquals(12.5, logement.getAreaMin()); assertEquals(12.5, logement.getAreaMax()); assertEquals(2, logement.getEquipements().size()); - assertEquals(io.github.mathieusoysal.logement.Equipement.WC, + assertEquals(io.github.mathieusoysal.logement.Equipment.WC, logement.getEquipements().get(0)); - assertEquals(io.github.mathieusoysal.logement.Equipement.SHOWER, + assertEquals(io.github.mathieusoysal.logement.Equipment.SHOWER, logement.getEquipements().get(1)); assertEquals(1, logement.getOccupationMods().size()); assertEquals(OccupationKind.ALONE, logement.getOccupationMods().get(0).getOccupationKind()); @@ -101,4 +102,6 @@ void testConvertItemsToLogements() throws IOException { assertEquals(26780, logement.getOccupationMods().get(0).getRentMax()); } + + } \ No newline at end of file diff --git a/src/test/java/io/github/mathieusoysal/logement/pojo/OccupationModTest.java b/src/test/java/io/github/mathieusoysal/logement/pojo/OccupationModTest.java index 21a1cd287..58d4465bc 100644 --- a/src/test/java/io/github/mathieusoysal/logement/pojo/OccupationModTest.java +++ b/src/test/java/io/github/mathieusoysal/logement/pojo/OccupationModTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test; import io.github.mathieusoysal.logement.OccupationKind; -import io.github.mathieusoysal.logement.pojo.OccupationMod; +import io.github.mathieusoysal.logement.OccupationMode; class OccupationModTest { @Test @@ -13,7 +13,7 @@ void testGetOccupationKind_returnsCorrectValue() { OccupationKind expectedOccupationKind = OccupationKind.ALONE; int rentMin = 100; int rentMax = 200; - OccupationMod occupationMod = new OccupationMod(expectedOccupationKind, rentMin, rentMax); + OccupationMode occupationMod = new OccupationMode(expectedOccupationKind, rentMin, rentMax); // Act OccupationKind actualOccupationKind = occupationMod.getOccupationKind(); @@ -28,7 +28,7 @@ void testGetRentMin_returnsCorrectValue() { OccupationKind occupationKind = OccupationKind.ALONE; int expectedRentMin = 100; int rentMax = 200; - OccupationMod occupationMod = new OccupationMod(occupationKind, expectedRentMin, rentMax); + OccupationMode occupationMod = new OccupationMode(occupationKind, expectedRentMin, rentMax); // Act int actualRentMin = occupationMod.getRentMin(); @@ -43,7 +43,7 @@ void testGetRentMax_returnsCorrectValue() { OccupationKind occupationKind = OccupationKind.ALONE; int rentMin = 100; int expectedRentMax = 200; - OccupationMod occupationMod = new OccupationMod(occupationKind, rentMin, expectedRentMax); + OccupationMode occupationMod = new OccupationMode(occupationKind, rentMin, expectedRentMax); // Act int actualRentMax = occupationMod.getRentMax();