Compare commits

...

2 Commits

Author SHA1 Message Date
Adrian Stephens 5b8d24f2a6 added day name to sidebar listing 2026-04-29 09:16:46 +01:00
Adrian Stephens 39d5570d37 Tests updated for v1.0.1 2026-04-03 13:09:40 +01:00
11 changed files with 97 additions and 8 deletions

View File

@ -1,6 +1,6 @@
# Calendar plugin for wordpress site # Calendar plugin for wordpress site
Status as of 2026-03-31 when codex credit ran out: ## Bugs
1. Removal of plugin did not work. Need to set all files owner to www-data. - done 1. Removal of plugin did not work. Need to set all files owner to www-data. - done
2. Deletion of event in ui doesn't delete event in thunderbird - done 2. Deletion of event in ui doesn't delete event in thunderbird - done
@ -10,4 +10,11 @@ Status as of 2026-03-31 when codex credit ran out:
6. Updating an events description via caldav creates weird sequences, e.g. 6. Updating an events description via caldav creates weird sequences, e.g.
a space ends up as: text/html,%C2%A0": a space ends up as: text/html,%C2%A0":
7. In a private window, Click on event from not-logged-in calendar page shows event as a dialog box, it should show it as a panel with a subset of the edit event panel - i.e. the title, category, location, start and end and description. - 7. In a private window, Click on event from not-logged-in calendar page shows event as a dialog box, it should show it as a panel with a subset of the edit event panel - i.e. the title, category, location, start and end and description. -
8. 8. Thunderbird cutting/pasting/moving events is - TBD.#
## Enhancements
Calendar sidebar, hide description if there is one, but present an expansion "caret".
List mode view, list or configure data range of display.

View File

@ -3,7 +3,7 @@
* Plugin Name: Calendar Plugin * Plugin Name: Calendar Plugin
* Plugin URI: https://chezstephens.org.uk * Plugin URI: https://chezstephens.org.uk
* Description: Provides a single shared calendar for WordPress with public display, authenticated event editing, user approval workflow, ICS publishing, and CalDAV read/write sync. Supports recurring events, single-occurrence exceptions, admin setup and diagnostics pages, and shortcode rendering for full calendar and upcoming-events sidebar views. * Description: Provides a single shared calendar for WordPress with public display, authenticated event editing, user approval workflow, ICS publishing, and CalDAV read/write sync. Supports recurring events, single-occurrence exceptions, admin setup and diagnostics pages, and shortcode rendering for full calendar and upcoming-events sidebar views.
* Version: 1.0.1 * Version: 1.0.2
* Requires at least: 6.0 * Requires at least: 6.0
* Requires PHP: 8.1 * Requires PHP: 8.1
* Author: Adrian Stephens (with AI assistance) * Author: Adrian Stephens (with AI assistance)

View File

@ -1019,7 +1019,7 @@ HTML
$end = (string) ($item['occurrence_end'] ?? ''); $end = (string) ($item['occurrence_end'] ?? '');
$startDt = $this->toSidebarDateTime($start, $sidebarTz); $startDt = $this->toSidebarDateTime($start, $sidebarTz);
$endDt = $this->toSidebarDateTime($end, $sidebarTz); $endDt = $this->toSidebarDateTime($end, $sidebarTz);
$dateLabel = $startDt !== null ? $startDt->format('j F Y') : substr($start, 0, 10); $dateLabel = $startDt !== null ? $startDt->format('l j F Y') : substr($start, 0, 10);
$timeLabel = ''; $timeLabel = '';
if ($startDt !== null && $endDt !== null) { if ($startDt !== null && $endDt !== null) {
$startTime = $startDt->format('H:i'); $startTime = $startDt->format('H:i');
@ -1422,7 +1422,7 @@ HTML
return [ return [
'status' => 'ok', 'status' => 'ok',
'plugin' => 'calendar-plugin', 'plugin' => 'calendar-plugin',
'version' => '1.0.1', 'version' => '1.0.2',
'db_prefix' => $this->db->getPrefix(), 'db_prefix' => $this->db->getPrefix(),
]; ];
}, },

View File

@ -340,7 +340,20 @@ $sluggedCalendarHtml = do_shortcode('[calendar]');
assert_true(str_contains($sluggedCalendarHtml, 'href="/events/calendar.ics"'), 'calendar shortcode should use slugged ICS path'); assert_true(str_contains($sluggedCalendarHtml, 'href="/events/calendar.ics"'), 'calendar shortcode should use slugged ICS path');
assert_true(str_contains($sluggedCalendarHtml, 'href="/events/caldav/"'), 'calendar shortcode should use slugged CalDAV path'); assert_true(str_contains($sluggedCalendarHtml, 'href="/events/caldav/"'), 'calendar shortcode should use slugged CalDAV path');
unwrap(
request('POST', '/calendar/v1/events', [
'title' => 'Sidebar Weekday Event',
'description' => 'sidebar date label',
'start_datetime' => '2026-05-03T09:00:00+01:00',
'end_datetime' => '2026-05-03T10:00:00+01:00',
'repeat_type' => 'none',
'repeat_interval' => 1,
'repeat_range_mode' => 'none',
]),
'create sidebar weekday event'
);
$sidebarHtml = do_shortcode('[calendar_sidebar_upcoming]'); $sidebarHtml = do_shortcode('[calendar_sidebar_upcoming]');
assert_true(str_contains($sidebarHtml, '<div class="calendar-plugin-shell"'), 'sidebar shortcode should render'); assert_true(str_contains($sidebarHtml, '<div class="calendar-plugin-shell"'), 'sidebar shortcode should render');
assert_true(str_contains($sidebarHtml, 'Sunday 3 May 2026'), 'sidebar shortcode should include weekday in event date');
echo "[PASS] compatibility-layer e2e wp emulation\n"; echo "[PASS] compatibility-layer e2e wp emulation\n";

View File

@ -0,0 +1,20 @@
56ab7dd012a380edcc982c7c04f0f8dcb97ab0e0b4625349e2651c270949205e ./calendar-plugin.php
4e6930c79d9ce1045be6863ddd7546e19f7ef7e839d41a41014a3efb3183eaf0 ./src/bootstrap.php
1daa5861c0d10258c0d16c5c88c1a18fb3c8df7b590f7facfe7c28f678643bdb ./src/Contracts/AuthAdapterInterface.php
25cff4b0fc2ee292b53c152edd083c6af66200a25eec28f8dfce37d126a8892d ./src/Contracts/DatabaseAdapterInterface.php
4f0f4caa5ac98499854336f5b74af55ce889653f3956e5df10910f869a23fdba ./src/Contracts/HttpAdapterInterface.php
15e8f58c7360d6cd0c76c945abfeb026f8278d40b330e99b67955eb2f85f5563 ./src/Contracts/OptionsAdapterInterface.php
da068811cd923bd6cf04a209b9b4eec55fa57aeedfccaa3250ebd37b906c6d04 ./src/Domain/CalDavService.php
c8ab00f23e7cd198228734515c3ce9a2589b1ab6cb815307f3b8f7a3051e04d2 ./src/Domain/EventService.php
37b8f3077dcf9c0eb40dbcfefa7a5d8cebfe616051d827ad6ae3bb5a5fbccec7 ./src/Domain/IcsService.php
fd5377f7852b0f35550a453451d98882b8488b332d9a051dac603851c7b586d1 ./src/Domain/RecurrenceExpander.php
20ee26671fd934f36e97606cfd2ec1d5101ac8064594989bc955bf805fae2502 ./src/Domain/SettingsService.php
9956790a5d62f5798f3ec15fc507fb04f33e01fd27969db09e91a6d1b41cd33f ./src/Domain/UserService.php
5aaac066919b60461bde2e96cbfb4de66a5a28e89d2a61b78f0e2d346f23395b ./src/Infrastructure/ServiceContainer.php
e65577c707c5a66e2097faa7720170180c79a9d9df219f0e1061fdcec55be744 ./src/Infrastructure/WordPress/MigrationManager.php
8e6c95e9e1c051606e66d95cf0bcf92b2ca087bc491f32ab4921e0898cf77b81 ./src/Infrastructure/WordPress/WordPressAuthAdapter.php
68c0ca15ad2c8b6363a2578b85f8daf0d3a094e612a120a2cdd2a2bfd8fe5e3c ./src/Infrastructure/WordPress/WordPressDatabaseAdapter.php
8da85db3c1e69c2c5f01aaa2f558aa8f0323446d8af0aec5b34d4607cd4afe1b ./src/Infrastructure/WordPress/WordPressHttpAdapter.php
cf9fddcecb07af2c03ad2c0e448be12a6b45dd936efc8bc1fd46a52b4af864ea ./src/Infrastructure/WordPress/WordPressOptionsAdapter.php
e47590f2f092cfdd3c1245cd7ea392c5d91135f6ee5d468b533969f7c7c94c6b ./src/Plugin.php
893c6df62beed87a981d372c473e5012d1b5d1c254d23b39cda44ae8a08cd16c ./uninstall.php

Binary file not shown.

View File

@ -3,7 +3,7 @@
* Plugin Name: Calendar Plugin * Plugin Name: Calendar Plugin
* Plugin URI: https://chezstephens.org.uk * Plugin URI: https://chezstephens.org.uk
* Description: Provides a single shared calendar for WordPress with public display, authenticated event editing, user approval workflow, ICS publishing, and CalDAV read/write sync. Supports recurring events, single-occurrence exceptions, admin setup and diagnostics pages, and shortcode rendering for full calendar and upcoming-events sidebar views. * Description: Provides a single shared calendar for WordPress with public display, authenticated event editing, user approval workflow, ICS publishing, and CalDAV read/write sync. Supports recurring events, single-occurrence exceptions, admin setup and diagnostics pages, and shortcode rendering for full calendar and upcoming-events sidebar views.
* Version: 1.0.1 * Version: 1.0.2
* Requires at least: 6.0 * Requires at least: 6.0
* Requires PHP: 8.1 * Requires PHP: 8.1
* Author: Adrian Stephens (with AI assistance) * Author: Adrian Stephens (with AI assistance)

View File

@ -1019,7 +1019,7 @@ HTML
$end = (string) ($item['occurrence_end'] ?? ''); $end = (string) ($item['occurrence_end'] ?? '');
$startDt = $this->toSidebarDateTime($start, $sidebarTz); $startDt = $this->toSidebarDateTime($start, $sidebarTz);
$endDt = $this->toSidebarDateTime($end, $sidebarTz); $endDt = $this->toSidebarDateTime($end, $sidebarTz);
$dateLabel = $startDt !== null ? $startDt->format('j F Y') : substr($start, 0, 10); $dateLabel = $startDt !== null ? $startDt->format('l j F Y') : substr($start, 0, 10);
$timeLabel = ''; $timeLabel = '';
if ($startDt !== null && $endDt !== null) { if ($startDt !== null && $endDt !== null) {
$startTime = $startDt->format('H:i'); $startTime = $startDt->format('H:i');
@ -1422,7 +1422,7 @@ HTML
return [ return [
'status' => 'ok', 'status' => 'ok',
'plugin' => 'calendar-plugin', 'plugin' => 'calendar-plugin',
'version' => '1.0.1', 'version' => '1.0.2',
'db_prefix' => $this->db->getPrefix(), 'db_prefix' => $this->db->getPrefix(),
]; ];
}, },

View File

@ -27,6 +27,7 @@ CREATED_EVENT_ID=""
CREATED_REC_EVENT_ID="" CREATED_REC_EVENT_ID=""
CREATED_PRIVATE_EVENT_ID="" CREATED_PRIVATE_EVENT_ID=""
CREATED_SYNC_DELETE_EVENT_ID="" CREATED_SYNC_DELETE_EVENT_ID=""
CREATED_SIDEBAR_EVENT_ID=""
DETECTED_URL_SLUG="" DETECTED_URL_SLUG=""
SSH_OK=0 SSH_OK=0
@ -124,6 +125,10 @@ cleanup() {
curl -sS -u "${AUTH_USER}:${AUTH_PASS}" -X DELETE \ curl -sS -u "${AUTH_USER}:${AUTH_PASS}" -X DELETE \
"${BASE_URL}/wp-json/calendar/v1/events/${CREATED_SYNC_DELETE_EVENT_ID}" >/dev/null || true "${BASE_URL}/wp-json/calendar/v1/events/${CREATED_SYNC_DELETE_EVENT_ID}" >/dev/null || true
fi fi
if [[ -n "${CREATED_SIDEBAR_EVENT_ID}" ]]; then
curl -sS -u "${AUTH_USER}:${AUTH_PASS}" -X DELETE \
"${BASE_URL}/wp-json/calendar/v1/events/${CREATED_SIDEBAR_EVENT_ID}" >/dev/null || true
fi
} }
trap cleanup EXIT trap cleanup EXIT
@ -343,6 +348,46 @@ PY
fi fi
fi fi
step "sidebar timezone rendering (Europe/London)"
SIDEBAR_UID="remote-sidebar-tz-$(date +%s)@calendar-plugin"
SIDEBAR_TITLE="Remote Sidebar TZ Check"
SIDEBAR_JSON=$(cat <<JSON
{"uid":"${SIDEBAR_UID}","title":"${SIDEBAR_TITLE}","description":"timezone regression","location":"Remote","category":"QA","start_datetime":"2026-04-10T09:00:00+00:00","end_datetime":"2026-04-10T10:00:00+00:00","repeat_type":"none","repeat_interval":1,"repeat_range_mode":"none"}
JSON
)
SIDEBAR_CREATE_HTTP="$(curl -sS -u "${AUTH_USER}:${AUTH_PASS}" -H 'Content-Type: application/json' \
-d "${SIDEBAR_JSON}" -o /tmp/remote_test_sidebar_create.json -w '%{http_code}' \
"${BASE_URL}/wp-json/calendar/v1/events" || true)"
if [[ "${SIDEBAR_CREATE_HTTP}" != "200" ]]; then
record_fail "sidebar timezone setup create failed (http ${SIDEBAR_CREATE_HTTP})"
else
CREATED_SIDEBAR_EVENT_ID="$(python3 - <<'PY'
import json
p=json.load(open('/tmp/remote_test_sidebar_create.json'))
print(p.get('data', {}).get('id', ''))
PY
)"
if [[ -z "${CREATED_SIDEBAR_EVENT_ID}" ]]; then
record_fail "sidebar timezone setup returned no id"
elif [[ "${SSH_OK}" != "1" ]]; then
echo "[remote-tests] WARN: SSH unavailable, skipping sidebar shortcode rendering check"
else
if ! "${SSH_PREFIX[@]}" "cd ${REMOTE_WP_PATH} && ${REMOTE_WP_CLI} eval 'echo do_shortcode(\"[calendar_sidebar_upcoming]\");' --allow-root" >/tmp/remote_test_sidebar_render.html 2>/tmp/remote_test_sidebar_render.err; then
record_fail "sidebar shortcode render check failed"
else
if ! python3 - <<'PY'
import re
html=open('/tmp/remote_test_sidebar_render.html', encoding='utf-8', errors='ignore').read()
assert 'Remote Sidebar TZ Check' in html
assert re.search(r'10(?:\.00)?(?:|-|&ndash;)11am', html), html
PY
then
record_fail "sidebar shortcode did not render expected Europe/London time range (expected 1011am for 09:00Z input)"
fi
fi
fi
fi
step "caldav discovery compatibility" step "caldav discovery compatibility"
CALDAV_ROOT_URL="" CALDAV_ROOT_URL=""
if [[ -n "${CAL_CALDAV_PATH}" ]]; then if [[ -n "${CAL_CALDAV_PATH}" ]]; then

View File

@ -35,6 +35,7 @@ Use a minimal subset:
### SMK-004 Public UI Rendering ### SMK-004 Public UI Rendering
- Render shortcode page with CE-002 and CE-003 present. - Render shortcode page with CE-002 and CE-003 present.
- Assert no runtime error and event data is visible in default view. - Assert no runtime error and event data is visible in default view.
- Sidebar shortcode (`[calendar_sidebar_upcoming]`) renders event date/time in `Europe/London` timezone semantics.
### SMK-005 ICS Endpoint ### SMK-005 ICS Endpoint
- Fetch ICS link. - Fetch ICS link.

View File

@ -60,6 +60,9 @@ Exercise the highest-value user flows across web UI, admin setup/users pages, re
- Open Diagnostics page: - Open Diagnostics page:
- verify diagnostics snapshot renders. - verify diagnostics snapshot renders.
- click `Download Diagnostics` and confirm JSON file downloads. - click `Download Diagnostics` and confirm JSON file downloads.
- Render/check page area using `[calendar_sidebar_upcoming]`:
- confirm human-readable date/time format.
- confirm displayed times match `Europe/London` (not server UTC) for near-term timed events.
## Pass Criteria ## Pass Criteria
- No fatal errors. - No fatal errors.