node-ical 0.25.x added `expandRecurringEvent()` — a proper API for
expanding both recurring and non-recurring events, including EXDATE
filtering and RECURRENCE-ID overrides. This PR replaces our hand-rolled
equivalent with it.
`calendarfetcherutils.js` loses ~125 lines of code. What's left only
deals with MagicMirror-specific concerns: timezone conversion,
config-based filtering, and output formatting. The extra lines in the
diff come from new tests.
## What was removed
- `getMomentsFromRecurringEvent()` — manual rrule.js wrapping with
custom date extraction
- `isFullDayEvent()` — heuristic with multiple fallback checks
- `isFacebookBirthday` workaround — patched years < 1900 and
special-cased `@facebook.com` UIDs
- The `if (event.rrule) / else` split — all events now go through a
single code path
## Bugs fixed along the way
Both were subtle enough to go unnoticed before:
- **`[object Object]` in event titles/description/location** — node-ical
represents ICS properties with parameters (e.g.
`DESCRIPTION;LANGUAGE=de:Text`) as `{val, params}` objects. The old code
passed them straight through. Mainly affected multilingual Exchange/O365
setups. Fixed with `unwrapParameterValue()`.
- **`excludedEvents` with `until` never worked** —
`shouldEventBeExcluded()` returned `{ excluded, until }` but the caller
destructured it as `{ excluded, eventFilterUntil }`, so the until date
was always `undefined` and events were never hidden. Fixed by correcting
the destructuring key.
The expansion loop also gets error isolation: a single broken event is
logged and skipped instead of aborting the whole feed.
## Other clean-ups
- Replaced `this.shouldEventBeExcluded` with
`CalendarFetcherUtils.shouldEventBeExcluded` — avoids context-loss bugs
when the method is destructured or called indirectly.
- Replaced deprecated `substr()` with `slice()`.
- Replaced `now < filterUntil` (operator overloading) with
`now.isBefore(filterUntil)` — idiomatic Moment.js comparison.
- Fixed `@returns` JSDoc: `string[]` → `object[]`.
- Moved verbose `Log.debug("Processing entry...")` after the `VEVENT`
type guard to reduce log noise from non-event entries.
- Replaced `JSON.stringify(event)` debug log with a lightweight summary
to avoid unnecessary serialization cost.
- Added comment explaining the 0-duration → end-of-day fallback for
events without DTEND.
## Tests
24 unit tests, all passing (`npx vitest run
tests/unit/modules/default/calendar/`).
New coverage: `excludedEvents` with/without `until`, Facebook birthday
year expansion, output object shape, no-DTEND fallback, error isolation,
`unwrapParameterValue`, `getTitleFromEvent`, ParameterValue properties,
RECURRENCE-ID overrides, DURATION (single and recurring).
I was playing around with the newsfeed notification system
(`ARTICLE_MORE_DETAILS`, `ARTICLE_TOGGLE_FULL`, …) and discovered some
issues with the full article view:
The iframe was loading the CORS proxy URL instead of the actual article
URL, which could cause blank screens depending on the feed. Also, many
news sites block iframes entirely (`X-Frame-Options: DENY`) and the user
got no feedback at all — just an empty page. On top of that, scrolling
used `window.scrollTo()` which moved the entire MagicMirror page instead
of just the article.
This PR cleans that up:
- Use the raw article URL for the iframe (CORS proxy is only needed for
server-side feed fetching)
- Check `X-Frame-Options` / `Content-Security-Policy` headers
server-side before showing the iframe — if the site blocks it, show a
brief "Article cannot be displayed here." message and return to normal
view
- Show the iframe as a fixed full-screen overlay so other modules aren't
affected, scroll via `container.scrollTop`
- Keep the progressive disclosure behavior for `ARTICLE_MORE_DETAILS`
(title → description → iframe → scroll)
- Delete `fullarticle.njk`, replace with `getDom()` override
- Fix `ARTICLE_INFO_RESPONSE` returning proxy URL instead of real URL
- A few smaller fixes (negative scroll, null guard)
- Add `NEWSFEED_ARTICLE_UNAVAILABLE` translation to all 47 language
files
- Add e2e tests for the notification handlers (`ARTICLE_NEXT`,
`ARTICLE_PREVIOUS`, `ARTICLE_INFO_REQUEST`, `ARTICLE_LESS_DETAILS`)
## What this means for users
- The full article view now works reliably across different feeds
- If a news site blocks iframes, the user sees a brief message instead
of a blank screen
- Additional e2e tests make the module more robust and less likely to
break silently in future MagicMirror versions
Enable the `require-await` ESLint rule. Async functions without `await`
are just regular functions with extra overhead — marking them `async`
adds implicit Promise wrapping, can hide missing `return` statements,
and misleads readers into expecting asynchronous behavior where there is
none.
While fixing the violations, I removed unnecessary `async` keywords from
source files and from various test callbacks that never used `await`.
This migrates the Weather module from client-side fetching to use the
server-side centralized HTTPFetcher (introduced in #4016), following the
same pattern as the Calendar and Newsfeed modules.
## Motivation
This brings consistent error handling and better maintainability and
completes the refactoring effort to centralize HTTP error handling
across all default modules.
Migrating to server-side providers with HTTPFetcher brings:
- **Centralized error handling**: Inherits smart retry strategies
(401/403, 429, 5xx backoff) and timeout handling (30s)
- **Consistency**: Same architecture as Calendar and Newsfeed modules
- **Security**: Possibility to hide API keys/secrets from client-side
- **Performance**: Reduced API calls in multi-client setups - one server
fetch instead of one per client
- **Enabling possible future features**: e.g. server-side caching, rate
limit monitoring, and data sharing with third-party modules
## Changes
- All 10 weather providers now use HTTPFetcher for server-side fetching
- Consistent error handling like Calendar and Newsfeed modules
## Breaking Changes
None. Existing configurations continue to work.
## Testing
To ensure proper functionality, I obtained API keys and credentials for
all providers that require them. I configured all 10 providers in a
carousel setup and tested each one individually. Screenshots for each
provider are attached below demonstrating their working state.
I even requested developer access from the Tempest/WeatherFlow team to
properly test this provider.
**Comprehensive test coverage**: A major advantage of the server-side
architecture is the ability to thoroughly test providers with unit tests
using real API response snapshots. Don't be alarmed by the many lines
added in this PR - they are primarily test files and real-data mocks
that ensure provider reliability.
## Review Notes
I know this is an enormous change - I've been working on this for quite
some time. Unfortunately, breaking it into smaller incremental PRs
wasn't feasible due to the interdependencies between providers and the
shared architecture.
Given the scope, it's nearly impossible to manually review every change.
To ensure quality, I've used both CodeRabbit and GitHub Copilot to
review the code multiple times in my fork, and both provided extensive
and valuable feedback. Most importantly, my test setup with all 10
providers working successfully is very encouraging.
## Related
Part of the HTTPFetcher migration #4016.
## Screenshots
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-06-54"
src="https://github.com/user-attachments/assets/2139f4d2-2a9b-4e49-8d0a-e4436983ed6e"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-02"
src="https://github.com/user-attachments/assets/880f7ce2-4e44-42d5-bfe4-5ce475cca7c2"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-07"
src="https://github.com/user-attachments/assets/abd89933-fe03-40ab-8a7c-41ae1ff99255"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-12"
src="https://github.com/user-attachments/assets/22225852-f0a9-4d33-87ab-0733ba30fad3"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-17"
src="https://github.com/user-attachments/assets/7a7192a5-f237-4060-85d7-6f50b9bef5af"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-22"
src="https://github.com/user-attachments/assets/df84d9f1-e531-4995-8da8-d6f2601b6a08"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-27"
src="https://github.com/user-attachments/assets/4cf391ac-db43-4b52-95f4-f5eadc5ea34d"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-32"
src="https://github.com/user-attachments/assets/8dd8e688-d47f-4815-87f6-7f2630f15d58"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-37"
src="https://github.com/user-attachments/assets/ee84a8bc-6b35-405a-b311-88658d9268dd"
/>
<img width="1920" height="1080" alt="Ekrankopio de 2026-02-08 13-07-42"
src="https://github.com/user-attachments/assets/f941f341-453f-4d4d-a8d9-6b9158eb2681"
/>
Provider "Weather API" added later:
<img width="1910" height="1080" alt="Ekrankopio de 2026-02-15 19-39-06"
src="https://github.com/user-attachments/assets/3f0c8ba3-105c-4f90-8b2e-3a1be543d3d2"
/>
and centralize and optimize replace regex.
Another follow up to #4029
With this PR you can use secrets in urls in browser modules if you use
the cors proxy.
## Loading `config.js`
### Previously
Loaded on server-side in `app.js` and in the browser by including
`config.js` in `index.html`. The web server has an endpoint `/config`
providing the content of server loaded `config.js`.
### Now
Loaded only on server-side in `app.js`. The browser loads the content
using the web server endpoint `/config`. So the server has control what
to provide to the clients.
Loading the `config.js` was moved to `Utils.js` so that
`check_config.js` can use the same functions.
## Using environment variables in `config.js`
### Previously
Environment variables were not allowed in `config.js`. The workaround
was to create a `config.js.template` with curly braced bash variables
allowed. While starting the app the `config.js.template` was converted
via `envsub` into a `config.js`.
### Now
Curly braced bash variables are allowed in `config.js`. Because only the
server loads `config.js` he can substitute the variables while loading.
## Secrets in MagicMirror²
To be honest, this is a mess.
### Previously
All content defined in the `config` directory was reachable from the
browser. Everyone with access to the site could see all stuff defined in
the configuration e.g. using the url http://ip:8080/config. This
included api keys and other secrets.
So sharing a MagicMirror² url to others or running MagicMirror² without
authentication as public website was not possible.
### Now
With this PR we add (beta) functionality to protect sensitive data. This
is only possible for modules running with a `node_helper`. For modules
running in the browser only (e.g. default `weather` module), there is no
way to hide data (per construction). This does not mean, that every
module with `node_helper` is safe, e.g. the default `calendar` module is
not safe because it uses the calendar url's as sort of id and sends them
to the client.
For adding more security you have to set `hideConfigSecrets: true` in
`config.js`. With this:
- `config/config.env` is not deliverd to the browser
- the contents of environment variables beginning with `SECRET_` are not
published to the clients
This is a first step to protect sensitive data and you can at least
protect some secrets.
This PR improves `clientonly` start option with better code structure,
validation, and comprehensive test coverage.
### Changes
**Refactoring:**
- Improved parameter handling with explicit function parameter passing
instead of closure
- Added port validation (1-65535) with proper NaN handling
- Removed unnecessary IIFE wrapper (Node.js modules are already scoped)
- Extracted `getCommandLineParameter` as a reusable top-level function
- Enhanced error reporting with better error messages
- Added connection logging for debugging
**Testing:**
- Added comprehensive e2e tests for parameter validation
- Test coverage for missing/incomplete parameters
- Test coverage for local address rejection (localhost, 127.0.0.1, ::1,
::ffff:127.0.0.1)
- Test coverage for port validation (invalid ranges, non-numeric values)
- Test coverage for TLS flag parsing
- Integration test with running server
### Testing
All tests pass:
```bash
npm test -- tests/e2e/clientonly_spec.js
# ✓ 18 tests passed
This is another change to cleanup structure, already mentioned in
https://github.com/MagicMirrorOrg/MagicMirror/pull/4019#issuecomment-3792953018
After separating default and 3rd-party modules this PR moves the
`custom.css` from the mm-owned directory `css` into user owned directory
`config`.
It has a built-in function which moves the `css/custom.css` to the new
location `config/custom.css` (if the target not exists).
Let me know if there's a majority in favor of this change.
Since the project's inception, I've missed a clear separation between
default and third-party modules.
This increases complexity within the project (exclude `modules`, but not
`modules/default`), but the mixed use is particularly problematic in
Docker setups.
Therefore, with this pull request, I'm moving the default modules to a
different directory.
~~I've chosen `default/modules`, but I'm not bothered about it;
`defaultmodules` or something similar would work just as well.~~
Changed to `defaultmodules`.
Let me know if there's a majority in favor of this change.
- remove param `--enable-features=UseOzonePlatform` in start electron
tests (as we did already in `package.json`)
- update node versions in github workflows, remove `22.21.1`, add `25.x`
- fix formatting in tests
- update dependencies including electron to v40
This is still a draft PR because most calendar electron tests are not
running which is caused by the electron update from `v39.3.0` to
`v40.0.0`. Maybe @KristjanESPERANTO has an idea ...
---------
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
## Summary
PR [#3976](https://github.com/MagicMirrorOrg/MagicMirror/pull/3976)
introduced smart HTTP error handling for the Calendar module. This PR
extracts that HTTP logic into a central `HTTPFetcher` class.
Calendar is the first module to use it. Follow-up PRs would migrate
Newsfeed and maybe even Weather.
**Before this change:**
- ❌ Each module had to implemented its own `fetch()` calls
- ❌ No centralized retry logic or backoff strategies
- ❌ No timeout handling for hanging requests
- ❌ Error detection relied on fragile string parsing
**What this PR adds:**
- ✅ Unified HTTPFetcher class with intelligent retry strategies
- ✅ Modern AbortController with configurable timeout (default 30s)
- ✅ Proper undici Agent for self-signed certificates
- ✅ Structured error objects with translation keys
- ✅ Calendar module migrated as first consumer
- ✅ Comprehensive unit tests with msw (Mock Service Worker)
## Architecture
**Before - Decentralized HTTP handling:**
```
Calendar Module Newsfeed Module Weather Module
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ fetch() own │ │ fetch() own │ │ fetch() own │
│ retry logic │ │ basic error │ │ no retry │
│ error parse │ │ handling │ │ client-side │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└───────────────────────┴───────────────────────┘
▼
External APIs
```
**After - Centralized with HTTPFetcher:**
```
┌─────────────────────────────────────────────────────┐
│ HTTPFetcher │
│ • Unified retry strategies (401/403, 429, 5xx) │
│ • AbortController timeout (30s) │
│ • Structured errors with translation keys │
│ • undici Agent for self-signed certs │
└────────────┬──────────────┬──────────────┬──────────┘
│ │ │
┌───────▼───────┐ ┌────▼─────┐ ┌──────▼──────┐
│ Calendar │ │ Newsfeed │ │ Weather │
│ ✅ This PR │ │ future │ │ future │
└───────────────┘ └──────────┘ └─────────────┘
│ │ │
└──────────────┴──────────────┘
▼
External APIs
```
## Complexity Considerations
**Does HTTPFetcher add complexity?**
Even if it may look more complex, it actually **reduces overall
complexity**:
- **Calendar already has this logic** (PR #3976) - we're extracting, not
adding
- **Alternative is worse:** Each module implementing own logic = 3× the
code
- **Better testability:** 443 lines of tests once vs. duplicating tests
for each module
- **Standards-based:** Retry-After is RFC 7231, not custom logic
## Future Benefits
**Weather migration (future PR):**
Moving Weather from client-side to server-side will enable:
- **Same robust error handling** - Weather gets 429 rate-limiting, 5xx
backoff for free
- **Simpler architecture** - No proxy layer needed
Moving the weather modules from client-side to server-side will be a big
undertaking, but I think it's a good strategy. Even if we only move the
calendar and newsfeed to the new HTTP fetcher and leave the weather as
it is, this PR still makes sense, I think.
## Breaking Changes
**None**
----
I am eager to hear your opinion on this 🙂
Fixes **full-day recurring events showing on wrong day** in timezones
west of UTC (reported in #4003).
**Root cause**: `moment.tz(date, eventTimezone).startOf("day")`
interprets UTC midnight as local time:
- `2025-11-03T00:00:00.000Z` in America/Chicago (UTC-6)
- → Converts to `2025-11-02 18:00:00` (6 hours back)
- → `.startOf("day")` → `2025-11-02 00:00:00` ❌ **Wrong day!**
**Impact**: The bug affects:
- All timezones west of UTC (UTC-1 through UTC-12): Americas, Pacific
- Timezones east of UTC (UTC+1 through UTC+12): Europe, Asia, Africa -
work correctly
- UTC itself - works correctly
The issue was introduced with commit c2ec6fc2 (#3976), which fixed the
time but broke the date. This PR fixes both.
| | Result | Day | Time | Notes |
|----------|--------|-----|------|-------|
| **Before c2ec6fc2** | `2025-11-03 05:00:00 Monday` | ✅ | ❌ | Wrong
time, but correct day |
| **Current (c2ec6fc2)** | `2025-11-02 00:00:00 Sunday` | ❌ (west of
UTC)<br>✅ (east of UTC) | ✅ | Wrong day - visible bug! |
| **This fix** | `2025-11-03 00:00:00 Monday` | ✅ | ✅ | Correct in all
timezones |
Note: While the old logic had incorrect timing, it produced the correct
calendar day due to how it handled UTC offsets. The current logic fixed
the timing issue but introduced the more visible calendar day bug.
### Solution
Extract UTC date components and interpret as local calendar dates:
```javascript
const utcYear = date.getUTCFullYear();
const utcMonth = date.getUTCMonth();
const utcDate = date.getUTCDate();
return moment.tz([utcYear, utcMonth, utcDate], eventTimezone);
```
### Testing
To prevent this from happening again in future refactorings, I wrote a
test for it.
```bash
npm test -- tests/unit/modules/default/calendar/calendar_fetcher_utils_spec.js
```
If an error occurs during startup, we request system information from
the user. The problem is that this information is displayed too late,
for example, if the configuration check fails.
My initial idea was to use `await
Utils.logSystemInformation(global.version);`, but this increased the
startup time.
Therefore, the function is now called in a subprocess. This approach
provides the information in all cases and does not increase the startup
time.
The bottom line of this PR is, that it fixes an issue and simplifies the
code by dealing with the TODOs in the code.
For review, I suggest looking at each commit individually. If there are
too many changes for a PR, let me know and I'll split it up
🙂
## 1. [fix(calendar): prevent excessive fetching with smart refresh
strategy](8892cd3d5a)
- Add lastFetch timestamp tracking to CalendarFetcher
- Add shouldRefetch() method with configurable minimum interval
(default: 3 minutes)
- When reusing existing fetcher: fetch if data is stale (>3 min),
otherwise broadcast cached events
- Prevents double broadcasts to consuming modules while maintaining
fresh data
- Balances rate limit prevention (Issue
https://github.com/MagicMirrorOrg/MagicMirror/issues/3971) with data
freshness on user reload
- Prevents excessive fetching during rapid reloads (e.g., Fully Kiosk
screensaver use case)
- Allows fresh calendar data when enough time has passed since last
fetch
## 2. [refactor(calendar): simplify event exclusion
logic](d507aba82d)
- Extract filtering logic from `shouldEventBeExcluded` into new helper
`checkEventAgainstFilter`
- Simplify the main loop in `shouldEventBeExcluded
It resolves a TODO from the comments in the code:
* `This seems like an overly complicated way to exclude events based on
the title.`
## 3. [refactor(calendar): extract recurring event expansion
logic](d510160bd2)
This change separates the expansion of recurring events from the main
filtering loop into a new helper function 'expandRecurringEvent'.
It resolves two TODOs from the comments in the code:
- `This should be a separate function`
- `This should create an event per moment so we can change anything we
want`
This improves code readability, reduces complexity in 'filterEvents',
and allows for cleaner handling of individual recurrence instances.
## 4. [refactor(calendar): simplify recurring event
handling](b04f716cc0)
- Simplify 'getMomentsFromRecurringEvent' using modern syntax
- Improve handling of full-day events across different timezones
## 5. [test(calendar): fix UNTIL date in fullday_until.ics
fixture](1d762b2ade)
The issue was with the UNTIL date being May 4th while DTSTART was May
5th. This created an invalid recurrence rule where the end date came
before the start date.
The fix only adjusts the UNTIL date from May 4th to May 5th, so it
matches the start date.
## Changes
- Replace `indexOf()` with `startsWith()` for cleaner protocol detection
- Use `URL` API for robust cache-busting parameter handling
- Add HTTP response validation and improved error logging
- Add JSDoc type annotations for better documentation
- Remove unused `urlSuffix` instance variable
- Add unit tests
- Fix `.gitignore` pattern
## Motivation
After merging #3967, I noticed some potential for improving reliability
and user experience related to the method `loadComplimentFile`. With
these changes the method now validates URLs upfront to catch
configuration errors early, checks HTTP status codes to detect server
issues (404/500), and provides specific error messages that help users
troubleshoot problems.
The complexity of the code does not really increase with the changes. On
the contrary, the method should now be more intuitive to understand.
## Testing
Added unit tests for `loadComplimentFile()` to validate the
improvements:
- HTTP error handling
- Cache-busting
Since E2E tests already cover the happy path, these unit tests focus on
error cases and edge cases.
## Additional Fix
While adding the test file, I discovered that the `.gitignore` pattern
`modules` was incorrectly matching `tests/unit/modules/`, preventing
test files from being tracked. Changed to `/modules` to only match the
root directory.
### 1. Replace `XMLHttpRequest` with the modern `fetch` API for loading
translation files
#### Changes
- **translator.js**: Use `fetch` with `async/await` instead of XHR
callbacks
- **loader.js**: Align URL handling and add error handling (follow-up to
fetch migration)
- **Tests**: Update infrastructure for `fetch` compatibility
#### Benefits
- Modern standard API
- Cleaner, more readable code
- Better error handling and fallback mechanisms
### 2. Migrate e2e tests to Playwright
This wasn't originally planned for this PR, but is related. While
investigating suspicious log entries which surfaced after the fetch
migration I kept running into JSDOM’s limitations. That pushed me to
migrate the E2E suite to Playwright instead.
#### Changes
- switch e2e harness to Playwright (`tests/e2e/helpers/global-setup.js`)
- rewrite specs to use Playwright locators + shared `expectTextContent`
- install Chromium via `npx playwright install --with-deps` in CI
#### Benefits
- much closer to real browser behaviour
- and no more fighting JSDOM’s quirks
## CI Log Suppression
**Two-level approach for clean test output:**
1. **Suppress debug/info logs**: Call `logger.setLogLevel("ERROR")` in
CI to hide verbose logging
2. **Suppress intentional error logs**: Set `mmTestMode` flag and check
it before logging errors that are part of test assertions (e.g., testing
error handling in `git_helper.js` and `server_functions.js`)
This keeps CI output clean and makes genuine failures immediately
visible, while preserving full logging for local development.
**Before:** 1348 log lines with verbose debug/info output
**After:** 168 log clean lines with only test results
## Calendar Symbol Test Stability
Convert the calendar symbol test from external URL (`calendarlabs.com`)
to existing local mock file (`12_events.ics`). This eliminates CI
timeouts caused by external dependencies and improves test reliability.
The test still validates the same symbol array feature but now runs
faster and deterministically without network dependencies.
This is a big change, but I think it's a good move, as `vitest` is much
more modern than `jest`.
I'm excited about the UI watch feature (run `npm run test:ui`), for
example - it's really helpful and saves time when debugging tests. I had
to adjust a few tests because they had time related issues, but
basically we are now testing the same things - even a bit better and
less flaky (I hope).
What do you think?
Remove the "Recurring event per timezone" test that manipulated
Date.prototype.getTimezoneOffset to simulate 24 different timezones for
testing all-day recurring events.
Reasons for removal:
1. The test approach is incompatible with node-ical 0.22.0's Intl-based
timezone handling (which replaced moment-timezone). Manipulating
Date.prototype.getTimezoneOffset no longer affects Intl.DateTimeFormat,
which reads the system timezone directly.
2. node-ical 0.22.0 handles all-day events (VALUE=DATE) correctly by
preserving the calendar date without timezone conversions, making
cross-timezone testing unnecessary. The library includes comprehensive
tests for this behavior, particularly "keeps whole-day recurrence across
DST" in
[test/advanced.test.js](https://github.com/jens-maus/node-ical/blob/master/test/advanced.test.js).
3. The existing "Recurring event" test already verifies that recurring
events from the same ICS file are displayed correctly, so a simplified
version of "Recurring event per timezone" is not necessary.
The old test attempted to work around timezone conversion issues in
node-ical 0.21.0 that are now properly resolved upstream.
Closes#3928
This fixes security issue
[CVE-2023-42282](https://github.com/advisories/GHSA-78xj-cgh5-2h22),
which is not very likely to be exploitable in MagicMirror² setups, but
still should be fixed.
The [express-ipfilter](https://www.npmjs.com/package/express-ipfilter)
package depends on the obviously unmaintained
[ip](https://github.com/indutny/node-ip) package, which has known
security vulnerabilities. Since no fix is available, this commit
replaces both dependencies with a custom middleware using the better
maintained [ipaddr.js](https://www.npmjs.com/package/ipaddr.js) library.
Changes:
- Add new `js/ip_access_control.js` with lightweight middleware
- Remove `express-ipfilter` dependency, add `ipaddr.js`
- Update `js/server.js` to use new middleware
- In addition, I have formulated the descriptions of the corresponding
tests a little more clearly.
The current logic never showed any different temperature than the
current one, so I looked into a more "explained" formula and found one
in the HomeAssistant forums.
- Remove `sinon` dependency in favor of Jest native mocking
- Unify test helper functions across translation test suites
- Rename `setupDOMEnvironment` to `createTranslationTestEnvironment` for
consistency
- Simplify DOM setup by removing unnecessary Promise/async patterns
- Avoid potential port conflicts by using port 3001 for translator unit
tests
- Improve test reliability and maintainability
This is not a cosmetic change because jest errors when run with
`CI=true`.
I got this error when running unit tests in gitlab:
```bash
FAIL unit tests/unit/functions/updatenotification_spec.js
● Test suite failed to run
Outdated guide link: The snapshot guide link is outdated.Please update all snapshots while upgrading of Jest
Expected: https://jestjs.io/docs/snapshot-testing
Received: https://goo.gl/fbAQLP
at validateSnapshotHeader (node_modules/@jest/snapshot-utils/build/index.js:104:12)
at getSnapshotData (node_modules/@jest/snapshot-utils/build/index.js:156:28)
```
If you run the test without `CI=true` jest will update the file.
Fixes#3253
Adds a configuration option to overwrite the default `User-Agent` header
that is send at least by the calendar and news module. Allows other
modules to use the individual user agent as well.
The configuration accepts either a string or a function:
```
var config =
{
...
userAgent: 'Mozilla/5.0 (My User Agent)',
...
}
```
or
```
var config =
{
...
userAgent: () => 'Mozilla/5.0 (My User Agent)',
...
}
```
---------
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <gitkraken@veeck.de>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
The weather e2e tests are failing sometimes, failing is not really
reproducable.
After changing `updateDom(0)` to `updateDom(300)` in `weather.js` it
seems to work (we will se if it really works in the long term).
This PR contains some other weather e2e changes/cleanups/simplifying.
- fix newsfeed and calendar e2e tests so they don't need `--forceExit`
anymore
- `--forceExit` should stay in test runs to avoid running until test
limit in case of errors
- remove mocking console, not needed anymore
- configFactory-stuff should not run in browser (otherwise we get errors
`[ReferenceError: exports is not defined]`)
e2e:
- needed window.close(), otherwise the objects are not destroyed
- add missing `await` in clock test
- set maxListeners for all tests
remaining todo (comes with another PR if I find the problem):
- calendar e2e is now the only test which still needs `--forceExit`