diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc5627a88f..7d95e1c565 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,8 +25,9 @@ planned for 2025-04-01
 
 ### Fixed
 
-- [calendar] Fix clipping events being broadcast (#3678)
+- [calendar] fix clipping events being broadcast (#3678)
 - [tests] Electron tests: Fixes for running under new github image ubuntu-24.04, replace xserver with labwc (#3676)
+- [calendar] fix arrayed symbols, #3267, again, add testcase, add testcase for #3678
 
 ## [2.30.0] - 2025-01-01
 
diff --git a/js/app.js b/js/app.js
index 020139439a..ffe3616df8 100644
--- a/js/app.js
+++ b/js/app.js
@@ -177,7 +177,7 @@ function App () {
 				moduleFolder = defaultModuleFolder;
 			} else {
 				// running in Jest, allow defaultModules placed under moduleDir for testing
-				if (env.modulesDir === "modules") {
+				if (env.modulesDir === "modules" || env.modulesDir === "tests/mocks") {
 					moduleFolder = defaultModuleFolder;
 				}
 			}
diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js
index 2610b23939..e2f921db28 100644
--- a/modules/default/calendar/calendar.js
+++ b/modules/default/calendar/calendar.js
@@ -689,10 +689,11 @@ Module.register("calendar", {
 					by_url_calevents.push(event);
 				}
 			}
-			by_url_calevents.sort(function (a, b) {
-				return a.startDate - b.startDate;
-			});
 			if (limitNumberOfEntries) {
+				// sort entries before clipping
+				by_url_calevents.sort(function (a, b) {
+					return a.startDate - b.startDate;
+				});
 				Log.debug(`pushing ${by_url_calevents.length} events to total with room for ${remainingEntries}`);
 				events = events.concat(by_url_calevents.slice(0, remainingEntries));
 				Log.debug(`events for calendar=${events.length}`);
@@ -911,7 +912,11 @@ Module.register("calendar", {
 		let p = this.getCalendarProperty(url, property, defaultValue);
 		if (property === "symbol" || property === "recurringSymbol" || property === "fullDaySymbol") {
 			const className = this.getCalendarProperty(url, "symbolClassName", this.config.defaultSymbolClassName);
-			if (p instanceof Array) p.push(className);
+			if (p instanceof Array) {
+				let t = [];
+				p.forEach((n) => { t.push(className + n); });
+				p = t;
+			}
 			else p = className + p;
 		}
 		if (!(p instanceof Array)) p = [p];
diff --git a/tests/configs/modules/calendar/countCalendarEvents.js b/tests/configs/modules/calendar/countCalendarEvents.js
new file mode 100644
index 0000000000..ea3244b96d
--- /dev/null
+++ b/tests/configs/modules/calendar/countCalendarEvents.js
@@ -0,0 +1,39 @@
+let config = {
+	address: "0.0.0.0",
+	ipWhitelist: [],
+	timeFormat: 12,
+	foreignModulesDir: "tests/mocks",
+	modules: [
+		{
+			module: "calendar",
+			position: "bottom_bar",
+
+			config: {
+				maximumEntries: 1,
+				calendars: [
+					{
+						fetchInterval: 10000, //7 * 24 * 60 * 60 * 1000,
+						symbol: ["calendar-check", "google"],
+						url: "http://localhost:8080/tests/mocks/12_events.ics"
+					}
+				]
+			}
+		},
+		{
+			module: "testNotification",
+			position: "bottom_bar",
+			config: {
+				debug: true,
+				match: {
+					matchtype: "count",
+					notificationID: "CALENDAR_EVENTS"
+				}
+			}
+		}
+	]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {
+	module.exports = config;
+}
diff --git a/tests/configs/modules/calendar/symboltest.js b/tests/configs/modules/calendar/symboltest.js
new file mode 100644
index 0000000000..f31c54d84b
--- /dev/null
+++ b/tests/configs/modules/calendar/symboltest.js
@@ -0,0 +1,28 @@
+
+let config = {
+	address: "0.0.0.0",
+	ipWhitelist: [],
+	timeFormat: 12,
+
+	modules: [
+		{
+			module: "calendar",
+			position: "bottom_bar",
+			config: {
+				maximumEntries: 1,
+				calendars: [
+					{
+						fetchInterval: 7 * 24 * 60 * 60 * 1000,
+						symbol: ["calendar-check", "google"],
+						url: "https://ics.calendarlabs.com/76/mm3137/US_Holidays.ics"
+					}
+				]
+			}
+		}
+	]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {
+	module.exports = config;
+}
diff --git a/tests/electron/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js
index f73d673489..0cf9bec5a9 100644
--- a/tests/electron/modules/calendar_spec.js
+++ b/tests/electron/modules/calendar_spec.js
@@ -13,9 +13,9 @@ describe("Calendar module", () => {
 		return true;
 	};
 
-	const doTestCount = async () => {
+	const doTestCount = async (locator = ".calendar .event") => {
 		expect(global.page).not.toBeNull();
-		const loc = await global.page.locator(".calendar .event");
+		const loc = await global.page.locator(locator);
 		const elem = loc.first();
 		await elem.waitFor();
 		expect(elem).not.toBeNull();
@@ -32,8 +32,8 @@ describe("Calendar module", () => {
 	// uses playwright nth locator syntax
 	const doTestTableContent = async (table_row, table_column, content, row = first) => {
 		const elem = await global.page.locator(table_row);
-		const date = await global.page.locator(table_column).locator(`nth=${row}`);
-		await expect(date.textContent()).resolves.toContain(content);
+		const column = await elem.locator(table_column).locator(`nth=${row}`);
+		await expect(column.textContent()).resolves.toContain(content);
 		return true;
 	};
 
@@ -279,4 +279,21 @@ describe("Calendar module", () => {
 		});
 	});
 
+	describe("count and check symbols", () => {
+		it("in array", async () => {
+			await helpers.startApplication("tests/configs/modules/calendar/symboltest.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Chicago");
+			// just
+			await expect(doTestCount(".calendar .event .symbol .fa-fw")).resolves.toBe(2);
+			await expect(doTestCount(".calendar .event .symbol .fa-calendar-check")).resolves.toBe(1);
+			await expect(doTestCount(".calendar .event .symbol .fa-google")).resolves.toBe(1);
+
+		});
+	});
+
+	describe("count events broadcast", () => {
+		it("get 12 with maxentries set to 1", async () => {
+			await helpers.startApplication("tests/configs/modules/calendar/countCalendarEvents.js", "01 Jan 2024 12:30:00 GMT-076:00", ["js/electron.js"], "America/Chicago");
+			await expect(doTestTableContent(".testNotification", ".elementCount", "12", first)).resolves.toBe(true);
+		});
+	});
 });
diff --git a/tests/mocks/12_events.ics b/tests/mocks/12_events.ics
new file mode 100644
index 0000000000..f89c938129
--- /dev/null
+++ b/tests/mocks/12_events.ics
@@ -0,0 +1,164 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Calendar Labs//Calendar 1.0//EN
+CALSCALE:GREGORIAN
+METHOD:PUBLISH
+X-WR-CALNAME:US Holidays
+X-WR-TIMEZONE:Etc/GMT
+BEGIN:VEVENT
+SUMMARY:Start of Month 1
+DTSTART:20190101
+DTEND:20190101
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949sada28d231582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 2
+DTSTART:20190201
+DTEND:20190201
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2wds8d231582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 3
+DTSTART:20190301
+DTEND:20190301
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2SDD8d231582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 4
+DTSTART:20190401
+DTEND:20190401
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2SDD8d231582FDSFD470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 5
+DTSTART:20190501
+DTEND:20190501
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2SDD8d2DD315824702598@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 6
+DTSTART:20190601
+DTEND:20190601
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2SDD8d2DD31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 7
+DTSTART:20190701
+DTEND:20190701
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52942SDD8d2DD31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 8
+DTSTART:20190801
+DTEND:20190801
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e52949a2SDD8d2DDt31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 9
+DTSTART:20190901
+DTEND:20190901
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e529449a2SDD8d2DDt315824702798@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 10
+DTSTART:20191001
+DTEND:20191001
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e529449a2SDD8d2DDt31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 11
+DTSTART:20191101
+DTEND:20191101
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e5294449a2SDD8d2DDt31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:Start of Month 12
+DTSTART:20191201
+DTEND:20191201
+RRULE:FREQ=YEARLY;WKST=SU;INTERVAL=1
+LOCATION:United States
+DESCRIPTION:Visit https://calendarlabs.com/holidays/us/new-years-day.php to know more about New Year's Day. \n\n Like us on Facebook: http://fb.com/calendarlabs to get updates
+UID:5e5294a2SDD8d2DDt31582470298@calendarlabs.com
+DTSTAMP:20200223T150458Z
+STATUS:CONFIRMED
+TRANSP:TRANSPARENT
+SEQUENCE:0
+END:VEVENT
+END:VCALENDAR
diff --git a/tests/mocks/testNotification/testNotification.js b/tests/mocks/testNotification/testNotification.js
new file mode 100644
index 0000000000..735af025a3
--- /dev/null
+++ b/tests/mocks/testNotification/testNotification.js
@@ -0,0 +1,59 @@
+Module.register("testNotification", {
+	defaults: {
+		debug: false,
+		match: {
+			notificationID: "",
+			matchtype: "count"
+			//or
+			// type: 'contents' // look for item in field of content
+		}
+	},
+	count: 0,
+	table: null,
+	notificationReceived (notification, payload) {
+		if (notification === this.config.match.notificationID) {
+			if (this.config.match.matchtype === "count") {
+				this.count = payload.length;
+				if (this.count) {
+					this.table = document.createElement("table");
+					this.addTableRow(this.table, null, `${this.count}:elementCount`);
+					if (this.config.debug) {
+						payload.forEach((e, i) => {
+							this.addTableRow(this.table, i, e.title);
+						});
+					}
+				}
+
+				this.updateDom();
+			}
+		}
+	},
+	maketd (row, info) {
+		let td = document.createElement("td");
+		row.appendChild(td);
+		if (info !== null) {
+			let colinfo = info.toString().split(":");
+			if (colinfo.length === 2) td.className = colinfo[1];
+			td.innerText = colinfo[0];
+		}
+		return td;
+	},
+	addTableRow (table, col1 = null, col2 = null, col3 = null) {
+		let tableRow = document.createElement("tr");
+		table.appendChild(tableRow);
+
+		let tablecol1 = this.maketd(tableRow, col1);
+		let tablecol2 = this.maketd(tableRow, col2);
+		let tablecol3 = this.maketd(tableRow, col3);
+
+		return tableRow;
+	},
+	getDom () {
+		let wrapper = document.createElement("div");
+		if (this.table) {
+			wrapper.appendChild(this.table);
+		}
+		return wrapper;
+	}
+
+});