Skip to content

Commit

Permalink
fix: MAJ Campagne Nantes Métropole (#2699)
Browse files Browse the repository at this point in the history
* fix PDLL 2024 limits

* make mode() accept more than 3 params

* refactor and add tests for outside rules

* improvements

* improvements

* add booster to PDLL

* improvements

* remove console.log

* fix range
  • Loading branch information
jonathanfallon authored Nov 26, 2024
1 parent 5e4aa33 commit 5ea734d
Show file tree
Hide file tree
Showing 9 changed files with 1,096 additions and 743 deletions.
56 changes: 56 additions & 0 deletions api/src/pdc/services/policy/engine/helpers/dateRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Generate a list of dates between two dates
*
* @example
* const boosterDates = [
* ...dateRange("2022-01-01", "2022-01-03"),
* ];
*
* @param dates
* @returns
*/
export function dateRange(...dates: Array<Date | string>): string[] {
if (dates.length === 0) {
throw new Error("At least one date is required");
}

const [first, ...rest] = castAndSort(dates);
const last = rest.pop();

return last ? fill(first, last) : [format(first)];
}

function castAndSort(range: Array<Date | string>): Set<Date> {
return range
.map((d) => {
const date = typeof d === "string" ? new Date(d) : d;
if (Number.isNaN(date.getTime())) {
throw new Error(`Invalid Date`);
}
date.setHours(0, 0, 0, 0);
return date;
})
.sort((a, b) => a.getTime() - b.getTime())
.reduce((acc, d) => {
acc.add(d);
return acc;
}, new Set<Date>());
}

function format(d: Date): string {
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}

function fill(first: Date, last: Date): Array<string> {
const dates = new Set<string>();
const current = new Date(first);
while (current <= last) {
dates.add(format(current));
current.setDate(current.getDate() + 1);
}

return [...dates];
}
98 changes: 98 additions & 0 deletions api/src/pdc/services/policy/engine/helpers/dateRange.unit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { assertEquals, describe, it } from "@/dev_deps.ts";
import { dateRange } from "./dateRange.ts";

describe("dateRange", () => {
it("should return a range of dates", () => {
const start = new Date("2022-01-01");
const end = new Date("2022-01-03");
const result = dateRange(start, end);
assertEquals(result, ["2022-01-01", "2022-01-02", "2022-01-03"]);
});

it("should return a range of dates when given strings", () => {
const start = "2022-01-01";
const end = "2022-01-03";
const result = dateRange(start, end);
assertEquals(result, ["2022-01-01", "2022-01-02", "2022-01-03"]);
});

it("should return a range over several months", () => {
const start = "2022-01-30";
const end = "2022-02-02";
const result = dateRange(start, end);
assertEquals(result, ["2022-01-30", "2022-01-31", "2022-02-01", "2022-02-02"]);
});

it("should sort input dates", () => {
const start = "2022-01-03";
const end = "2022-01-01";
const result = dateRange(start, end);
assertEquals(result, ["2022-01-01", "2022-01-02", "2022-01-03"]);
});

it("should sort more than two dates", () => {
const start = "2022-01-03";
const middle = "2022-01-02";
const end = "2022-01-01";
const result = dateRange(start, middle, end);
assertEquals(result, ["2022-01-01", "2022-01-02", "2022-01-03"]);
});

it("should handle no input", () => {
try {
dateRange();
} catch (e) {
assertEquals(e.message, "At least one date is required");
}
});

it("should handle invalid date format", () => {
const start = "2022-13-45";
const end = "2022-01-03";
try {
dateRange(start, end);
} catch (e) {
assertEquals(e.message, "Invalid Date");
}
});

it("should handle malformed date strings", () => {
const start = "not-a-date";
const end = "2022-01-03";
try {
dateRange(start, end);
} catch (e) {
assertEquals(e.message, "Invalid Date");
}
});

it("should handle empty string input", () => {
const start = "";
const end = "2022-01-03";
try {
dateRange(start, end);
} catch (e) {
assertEquals(e.message, "Invalid Date");
}
});

it("should handle single date input", () => {
const date = "2022-01-01";
const result = dateRange(date);
assertEquals(result, ["2022-01-01"]);
});

it("should handle same date for start and end", () => {
const start = "2022-01-01";
const end = "2022-01-01";
const result = dateRange(start, end);
assertEquals(result, ["2022-01-01"]);
});

it("should handle large date ranges", () => {
const start = "2022-01-01";
const end = "2022-12-31";
const result = dateRange(start, end);
assertEquals(result.length, 365);
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const description =
`<div _ngcontent-fyn-c231="" id="summary" class="campaignSummaryText-content-text">
export const description = `<div _ngcontent-fyn-c231="" id="summary" class="campaignSummaryText-content-text">
<p>Campagne d'incitation au covoiturage du <b> 01 janvier 2024 au 31 Décembre 2025</b></p>
Expand All @@ -26,7 +25,25 @@ export const description =
<li><b>De 17 à 29,5 km : 0.10 € par trajet par km par passager avec un maximum de 2,90 €</b></li>
<li><b>De 29,5 à 60 km : 2,90 € par passager transporté</b></li>
</ul>
<p>
Les trajets au départ OU à l'arrivée dans Nantes Métropôle effectués au sein
des Pays de la Loire sont incités selon les règles suivantes dans les conditions
"booster" uniquement :
</p>
<ul>
<li><b>De 5 à 60 km : 0,90 € par passager transporté</b></li>
</ul>
<p>
Les mois déclarés comme <b>"booster"</b> sont les suivants :
</p>
<ul>
<li>Décembre 2024</li>
</ul>
<p>Les restrictions suivantes seront appliquées :</p>
<ul>
Expand Down
Loading

0 comments on commit 5ea734d

Please sign in to comment.