Repository: maxime64100/sharePortfolio---VSCode
Pull request #42: 9 us connaitre la valeur dune action simple un jour donné
Author: login: Munozmu
Created: 2025-05-21T08:33:39Z | Merged: 2025-05-21T09:55:24Z

Implémentation des tests suivants : 

- valeurActionSimpleDatePrecise
- valeurActionSimpleJourFerieMarcheFerme
- dateFutureSansValeurDisponible


Diff:
diff --git a/src/main/java/fr/utc/miage/shares/ActionSimple.java b/src/main/java/fr/utc/miage/shares/ActionSimple.java
index 5a6497e..3fd1531 100644
--- a/src/main/java/fr/utc/miage/shares/ActionSimple.java
+++ b/src/main/java/fr/utc/miage/shares/ActionSimple.java
@@ -15,8 +15,11 @@
  */
 package fr.utc.miage.shares;
 
+import java.time.DayOfWeek;
+import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Allows the creation of simple Action objects.
@@ -47,10 +50,40 @@ public void enrgCours(final Jour j, final float v) {
 
     @Override
     public float valeur(final Jour j) {
-        if (this.mapCours.containsKey(j)) {
-            return this.mapCours.get(j);
+        Jour currentDay = j;
+
+        // Loop until the market is open
+        while (!isMarketOpen(currentDay)) {
+            LocalDate previousDate = currentDay.toDate().minusDays(1);
+            currentDay = new Jour(previousDate.getYear(), previousDate.getDayOfYear());
+        }
+
+        // Return the value for the first open market day
+        if (this.mapCours.containsKey(currentDay)) {
+            return this.mapCours.get(currentDay);
         } else {
             return DEFAULT_ACTION_VALUE;
         }
     }
+
+    /**
+     * Check if the market is open on a given day.
+     * @param j: the day to check
+     * @return true if the market is open, false otherwise
+     */
+    private boolean isMarketOpen(Jour j) {
+        LocalDate date = j.toDate();
+
+        if (date.getDayOfWeek() == DayOfWeek.SUNDAY) {
+            return false;
+        }
+
+        Set<LocalDate> holidays = Set.of(
+                LocalDate.of(j.getYear(), 1, 1),  // New Year's Day
+                LocalDate.of(j.getYear(), 12, 25), // Christmas
+                LocalDate.of(j.getYear(), 7, 14) // Bastille Day
+        );
+
+        return !holidays.contains(date);
+    }
 }
diff --git a/src/main/java/fr/utc/miage/shares/Jour.java b/src/main/java/fr/utc/miage/shares/Jour.java
index 45c45ee..57e48f4 100644
--- a/src/main/java/fr/utc/miage/shares/Jour.java
+++ b/src/main/java/fr/utc/miage/shares/Jour.java
@@ -15,6 +15,9 @@
  */
 package fr.utc.miage.shares;
 
+import java.time.LocalDate;
+import java.util.Date;
+
 /**
  * This class aims at describing a day based on a year and the day in this year.
  *
@@ -66,6 +69,10 @@ public int getDay() {
         return day;
     }
 
+    public LocalDate toDate() {
+        return LocalDate.ofYearDay(year, day);
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
diff --git a/src/test/java/fr/utc/miage/shares/ActionSimpleTest.java b/src/test/java/fr/utc/miage/shares/ActionSimpleTest.java
index 94e1dd1..2569550 100644
--- a/src/test/java/fr/utc/miage/shares/ActionSimpleTest.java
+++ b/src/test/java/fr/utc/miage/shares/ActionSimpleTest.java
@@ -14,15 +14,21 @@
  * limitations under the License.
  */
 package fr.utc.miage.shares;
-
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 class ActionSimpleTest {
+
+    private static final ActionSimple action = new ActionSimple("APPL");
     private static final String FOO_SHARE1 = "Foo Share 1";
     private static final String FOO_SHARE2 = "Foo Share 2";
+    private static final int LAST_YEAR = 2024;
     private static final int CURRENT_YEAR = 2025;
     private static final int CURRENT_DAY = 140;
+    private static final int LAST_DAY = 366;
+    private static final int FIRST_DAY = 1;
     private static final float SHARE_VALUE1 = 25.0f;
     private static final float SHARE_VALUE2 = 35.0f;
     private static final float SHARE_VALUE3 = 45.0f;
@@ -33,7 +39,6 @@ class ActionSimpleTest {
     private static final Jour jour2 = new Jour(CURRENT_YEAR, CURRENT_DAY+1);
     private static final Jour jour3 = new Jour(CURRENT_YEAR, CURRENT_DAY+2);
 
-
     private void setupActions() {
         actionSimple1 = new ActionSimple(FOO_SHARE1);
         actionSimple2 = new ActionSimple(FOO_SHARE2);
@@ -47,34 +52,64 @@ private void setupActions() {
     }
 
     @Test
-    public void testConstructorWithGoodValuesShouldWork() {
+    void valeurActionSimpleDatePrecise() {
+        // Arrange
+        action.enrgCours(new Jour(CURRENT_YEAR, CURRENT_DAY), SHARE_VALUE1);
+
+        // Assert
+        Assertions.assertEquals(SHARE_VALUE1, action.valeur(new Jour(CURRENT_YEAR, CURRENT_DAY)));
+    }
+
+    @Test
+    void valeurActionSimpleJourFerieMarcheFerme() {
+        // Arrange
+        action.enrgCours(new Jour(LAST_YEAR, LAST_DAY), SHARE_VALUE1); // December 31, 2024 (leap year)
+        action.enrgCours(new Jour(CURRENT_YEAR, FIRST_DAY), ActionSimple.DEFAULT_ACTION_VALUE);   // January 1, 2025
+
+        // Assert
+        Assertions.assertEquals(SHARE_VALUE1, action.valeur(new Jour(CURRENT_YEAR, FIRST_DAY)));
+    }
+
+    @Test
+    void valeurActionSimpleDateFutureSansValeurDisponible() {
+        // Arrange
+        action.enrgCours(new Jour(CURRENT_YEAR, CURRENT_DAY), SHARE_VALUE1);
+
+        // Assert
+        Assertions.assertEquals(ActionSimple.DEFAULT_ACTION_VALUE, action.valeur(new Jour(LAST_YEAR, FIRST_DAY)));
+    }
+
+    @Test
+    void testConstructorWithGoodValuesShouldWork() {
         Assertions.assertDoesNotThrow(() -> new ActionSimple(FOO_SHARE1));
     }
 
     @Test
-    public void testConstructorWithBadValuesShouldFail() {
+    void testConstructorWithBadValuesShouldFail() {
         Assertions.assertThrows(IllegalArgumentException.class, () -> new ActionSimple(null));
     }
 
     @Test
-    public void testEnrgCoursAlreadySet() {
+    void testEnrgCoursAlreadySet() {
         setupActions();
         actionSimple1.enrgCours(jour1, SHARE_VALUE2);
         Assertions.assertNotEquals(SHARE_VALUE2, actionSimple1.valeur(jour1));
     }
 
     @Test
-    public void testGetValeurWithGoodValue() {
+    void testGetValeurWithGoodValue() {
         setupActions();
         Assertions.assertAll(
-                ()-> Assertions.assertEquals(SHARE_VALUE1, actionSimple1.valeur(jour1)),
-                ()-> Assertions.assertEquals(SHARE_VALUE2, actionSimple2.valeur(jour2))
+                ()-> assertEquals(SHARE_VALUE1, actionSimple1.valeur(jour1)),
+                ()-> assertEquals(SHARE_VALUE2, actionSimple2.valeur(jour2))
         );
     }
 
     @Test
-    public void testGetValeurWithBadValue() {
+    void testGetValeurWithBadValue() {
         setupActions();
-        Assertions.assertEquals(ActionSimple.DEFAULT_ACTION_VALUE, actionSimple2.valeur(jour3));
+        assertEquals(ActionSimple.DEFAULT_ACTION_VALUE, actionSimple2.valeur(jour3));
     }
-}
\ No newline at end of file
+
+}
+


Reviews:
user: login: colasnaudi
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T09:32:57Z
user: login: colasnaudi
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T09:33:53Z
user: login: montbordino
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-21T09:59:59Z

Review comments:
diff_hunk: @@ -47,10 +50,49 @@ public void enrgCours(final Jour j, final float v) {
 
     @Override
     public float valeur(final Jour j) {
-        if (this.mapCours.containsKey(j)) {
-            return this.mapCours.get(j);
+        Jour currentDay = j;
+
+        // Loop until the market is open
+        while (!isMarketOpen(currentDay)) {
+            LocalDate previousDate = currentDay.toDate().minusDays(1);
+            currentDay = new Jour(previousDate.getYear(), previousDate.getDayOfYear());
+        }
+
+        // Return the value for the first open market day
+        if (this.mapCours.containsKey(currentDay)) {
+            return this.mapCours.get(currentDay);
         } else {
             return DEFAULT_ACTION_VALUE;
         }
     }
+
+    /**
+     * Check if the market is open on a given day.
+     * @param j: the day to check
+     * @return true if the market is open, false otherwise
+     */
+    private boolean isMarketOpen(Jour j) {
+        // Convert Jour to LocalDate
+        LocalDate date = j.toDate();
+
+        // Check if the day is a Sunday
+        if (date.getDayOfWeek() == DayOfWeek.SUNDAY) {
+            return false;
+        }
+
+        // Define a set of holidays (example: LocalDate objects)
path: src/main/java/fr/utc/miage/shares/ActionSimple.java
user: login: colasnaudi
body: Trop de commentaires
created_at: 2025-05-21T09:32:57Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,56 @@
+/*
+ * Copyright 2025 David Navarre &lt;David.Navarre at irit.fr&gt;.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package fr.utc.miage.shares;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ActionSimpleTest {
+
+    private static final ActionSimple action = new ActionSimple("APPL");
+
+    @Test
+    void valeurActionSimpleDatePrecise() {
+        // Arrange
+        action.enrgCours(new Jour(2023, 122), 150.0f);
+
+        // Assert
+        assertEquals(150.0f, action.valeur(new Jour(2023, 122)));
+    }
+
+    @Test
+    void valeurActionSimpleJourFerieMarcheFerme() {
+        // Arrange
+        action.enrgCours(new Jour(2024, 366), 200.0f); // December 31, 2024 (leap year)
+        action.enrgCours(new Jour(2025, 1), 0);   // January 1, 2025
+
+        // Assert
+        assertEquals(200.0f, action.valeur(new Jour(2025, 1)));
+    }
+
+    @Test
+    void dateFutureSansValeurDisponible() {
path: src/test/java/fr/utc/miage/shares/ActionSimpleTest.java
user: login: colasnaudi
body: valeurActionSimpleDateFutureSansValeurDisponible
created_at: 2025-05-21T09:33:53Z
author_association: COLLABORATOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-21T09:50:23Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=maxime64100_sharePortfolio---VSCode&pullRequest=42) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=maxime64100_sharePortfolio---VSCode&pullRequest=42&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=maxime64100_sharePortfolio---VSCode&pullRequest=42&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=maxime64100_sharePortfolio---VSCode&pullRequest=42&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=maxime64100_sharePortfolio---VSCode&pullRequest=42&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=maxime64100_sharePortfolio---VSCode&pullRequest=42&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=maxime64100_sharePortfolio---VSCode&pullRequest=42)


author_association: NONE