Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ff95ab0
Add tests with mocked server responses
tobixen Nov 23, 2025
4b04278
Fix test_calendar_auto_creation_detected mock
tobixen Nov 23, 2025
2a1b907
New checks save-load.task.recurrences
tobixen Nov 23, 2025
26531d8
Expand search tests and remove fragile mocked tests
tobixen Nov 27, 2025
1ee4f55
Expand search tests and remove fragile mocked tests
tobixen Nov 27, 2025
76657ec
Add sync token support detection
tobixen Nov 29, 2025
483863b
Fix CheckSyncToken API usage and add comprehensive tests
tobixen Nov 29, 2025
4d40571
Add proper cleanup for sync token test event
tobixen Nov 29, 2025
bcdf933
Add alarm time-range search support detection
tobixen Nov 30, 2025
8a6e890
Add principal search support detection
tobixen Nov 30, 2025
39d46a5
Add duplicate UID cross-calendar support detection
tobixen Nov 30, 2025
16c40f4
Rename duplicate-uid.cross-calendar to save.duplicate-uid.cross-calendar
tobixen Nov 30, 2025
e434760
Add search.time-range.accurate compatibility check
tobixen Dec 2, 2025
4fe9c7e
Add freebusy-query.rfc4791 feature check and fix checker bugs
tobixen Dec 2, 2025
37f8109
Simplify CheckDuplicateUID to reuse event from PrepareCalendar
tobixen Dec 2, 2025
9868286
Working with Bedework
tobixen Dec 3, 2025
728f5ab
Add search.text.by-uid feature detection in caldav-server-tester
tobixen Dec 3, 2025
2fa38c3
Add timezone test for GitHub issue #372 and fix syntax error
tobixen Dec 3, 2025
8ace88d
Detect and handle Zimbra moving events instead of copying
tobixen Dec 3, 2025
2b0c9cb
Use disable_fallback parameter in CheckSyncToken
tobixen Dec 3, 2025
77d083b
some refacotrings
tobixen Dec 14, 2025
3e48ce5
don't catch every exception
tobixen Dec 14, 2025
ba1ecbf
Fix alarm search test to reuse persistent events
tobixen Dec 14, 2025
b297cbe
Improve alarm test to handle duplicate UID errors gracefully
tobixen Dec 14, 2025
f688958
Add workaround for broken caldav search parameters
tobixen Dec 14, 2025
69c16e7
Fix CheckAlarmSearch to use proper UID search
tobixen Dec 15, 2025
58da704
Move alarm test event creation to PrepareCalendar
tobixen Dec 15, 2025
38ecdb7
Add CI/CD infrastructure: pre-commit hooks, GitHub Actions workflows
tobixen Dec 17, 2025
04a5569
Add lychee link checker: GitHub workflow and pre-commit hook
tobixen Dec 18, 2025
d48cbe0
Fix UID reuse bug for tests that delete events
tobixen Dec 19, 2025
1e46a85
Add deptry for dependency verification
tobixen Dec 21, 2025
4ade0e5
breaking: adjusting API usage from caldav v2 to caldav v3
tobixen Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: CI

on: [push, pull_request]

jobs:
lint-and-test:
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install --with dev

- name: Run Ruff linter
uses: astral-sh/ruff-action@v3
with:
args: check .

- name: Check dependencies with deptry
if: matrix.python-version != '3.9'
run: |
poetry run deptry src

- name: Run tests
run: |
poetry run pytest
18 changes: 18 additions & 0 deletions .github/workflows/linkcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Link check

on: [push, pull_request]

jobs:
linkcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check links with Lychee
uses: lycheeverse/lychee-action@v2
with:
fail: true
args: >-
--timeout 10
--max-retries 2
'**/*.md'
'**/*.rst'
86 changes: 86 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Publish to PyPI

on:
push:
tags:
- 'v*.*.*' # Triggers on version tags like v0.1.0, v1.2.3, etc.

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for poetry-dynamic-versioning

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install

- name: Run Ruff linter
uses: astral-sh/ruff-action@v3
with:
args: check .

- name: Run tests
run: |
poetry run pytest

publish:
needs: test # Only publish if tests pass
runs-on: ubuntu-latest
environment: main # Uses the "main" environment for deployment protection
permissions:
id-token: write # Required for trusted publishing
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for poetry-dynamic-versioning

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install build

- name: Verify version from git tags
run: |
git describe --tags --long
echo "Git tag detected above ^"

- name: Build package
run: |
# Build using PEP 517 with poetry-dynamic-versioning backend
python -m build --sdist --wheel

- name: Display built packages
run: |
ls -lh dist/
echo "Verifying version in wheel metadata:"
unzip -p dist/*.whl */METADATA | grep "^Version:"

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
# Uses PyPI Trusted Publishers (no token needed if configured)
# See: https://docs.pypi.org/trusted-publishers/
146 changes: 146 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
Pipfile.lock

# poetry
poetry.lock

# pdm
.pdm.toml

# PEP 582
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# Editor backup files
*~
.*.swp
.*.swo

# IDE
.vscode/
.idea/
*.iml
55 changes: 55 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.4
hooks:
# Run the linter with auto-fix on commit
- id: ruff
args:
- "--fix"
stages: [pre-commit]
# Run the formatter on commit
- id: ruff-format
stages: [pre-commit]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
stages: [pre-commit]
- id: end-of-file-fixer
stages: [pre-commit]
- id: check-yaml
stages: [pre-commit]
- id: check-toml
stages: [pre-commit]
- id: check-ast
stages: [pre-commit]
- id: mixed-line-ending
args: [--fix=lf]
stages: [pre-commit]

- repo: local
hooks:
# Run ruff check without fixes on push (to catch any issues)
- id: ruff-check-push
name: Ruff check (no fixes)
entry: poetry run ruff check
language: system
types: [python]
pass_filenames: false
stages: [pre-push]
# Run full test suite on push
- id: pytest-push
name: Run pytest
entry: poetry run pytest
language: system
pass_filenames: false
always_run: true
stages: [pre-push]

- repo: https://github.com/lycheeverse/lychee
rev: lychee-v0.22.0
hooks:
- id: lychee-docker
args: ["--no-progress", "--timeout", "10"]
types: [markdown, rst]
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,42 @@ This file should adhere to [Keep a Changelog](https://keepachangelog.com/en/1.1.

This project should adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), though some earlier releases may be incompatible with the SemVer standard.

## [Unreleased]

### Added
- Expanded search feature coverage with new feature flags:
- `search.text` - Basic text/summary search
- `search.text.case-sensitive` - Case-sensitive text matching (default behavior)
- `search.text.case-insensitive` - Case-insensitive text matching via CalDAVSearcher
- `search.text.substring` - Substring matching for text searches
- `search.is-not-defined` - Property filter with is-not-defined operator
- `search.text.category` - Category search support
- `search.text.category.substring` - Substring matching for category searches
- `post_filter=False` parameter to all server behavior tests to ensure testing actual server responses
- New `CheckSyncToken` check class for RFC6578 sync-collection reports:
- Tests for sync token support (full/fragile/unsupported)
- Detects time-based sync tokens (second-precision, requires sleep(1) between operations)
- Detects fragile sync tokens (occasionally returns extra content due to race conditions)
- Tests sync-collection reports after object deletion
- New `CheckAlarmSearch` check class for alarm time-range searches (RFC4791 section 9.9):
- Tests if server supports searching for events based on when their alarms trigger
- Verifies correct filtering of alarm times vs event times
- New `CheckPrincipalSearch` check class for principal search operations:
- Tests basic principal access
- Tests searching for own principal by display name (`principal-search.by-name.self`)
- Tests listing all principals (`principal-search.list-all`)
- Note: Full `principal-search.by-name` testing requires multiple users and is not yet implemented
- New `CheckDuplicateUID` check class for duplicate UID handling:
- Tests if server allows events with same UID in different calendars (`save.duplicate-uid.cross-calendar`)
- Detects if duplicates are silently ignored or rejected with errors
- Verifies events are treated as separate entities when allowed

### Changed
- Improved `search.comp-type-optional` test with additional text search validation

### Fixed
- `create-calendar` feature detection to not incorrectly mark mkcol method as standard calendar creation

## [0.1] - [2025-11-08]

This release corresponds with the caldav version 2.1.2
Expand Down
Loading
Loading