From 202825548178e61e2abc0d956ae386bb250cc919 Mon Sep 17 00:00:00 2001 From: Tobias Brox Date: Fri, 5 Jun 2020 01:15:38 +0200 Subject: make it possible to create a calendar, resolves https://github.com/tobixen/calendar-cli/issues/69 - automated tests towards radicale, ref https://github.com/tobixen/calendar-cli/issues/68 --- README.md | 2 +- calendar-cli.py | 26 +++++++++- tests/README | 7 +++ tests/script_test.sh | 116 ------------------------------------------- tests/test_calendar-cli.sh | 29 +++++++++++ tests/tests.sh | 120 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 119 deletions(-) create mode 100644 tests/README delete mode 100755 tests/script_test.sh create mode 100755 tests/test_calendar-cli.sh create mode 100755 tests/tests.sh diff --git a/README.md b/README.md index f4e2b8b..9a09585 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Other tools There is another project out there, "Command-line Interface for Google Calendar", previously located at pypi under the calendar-cli name. It has now been renamed to gcalendar-cli to avoid name conflict, and is available at https://pypi.python.org/pypi/gcalendar-cli/ -There is a "competing" project at https://github.com/geier/khal - you may want to check it out - it's more mature but probably more complex. It's using a "vsyncdir" backend - if I've understood it correctly, that involves building a local copy of the calendar. The philosophy behind calendar-cli is slightly different, calendar-cli is supposed to be a simple cli-based caldav+ical client. No synchronization, no local storage. +There is a "competing" project at https://github.com/geier/khal - you may want to check it out - it's more mature but probably more complex. It's using a "vsyncdir" backend - if I've understood it correctly, that involves building a local copy of the calendar. The philosophy behind calendar-cli is slightly different, calendar-cli is supposed to be a simple cli-based caldav+ical client. No synchronization, no local storage, just client-side operations. Installation ------------ diff --git a/calendar-cli.py b/calendar-cli.py index b08eb19..d138fd1 100755 --- a/calendar-cli.py +++ b/calendar-cli.py @@ -2,7 +2,7 @@ """ calendar-cli.py - high-level cli against caldav servers -Copyright (C) 2013-2019 Tobias Brox and other contributors +Copyright (C) 2013-2020 Tobias Brox and other contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -149,9 +149,12 @@ def find_calendar(caldav_conn, args): if '/' in args.calendar_url: return caldav.Calendar(client=caldav_conn, url=args.calendar_url) else: - return caldav.Principal(caldav_conn).calendar(name=args.calendar_url) + return caldav.Principal(caldav_conn).calendar(cal_id=args.calendar_url) else: ## Find default calendar + calendars = caldav.Principal(caldav_conn).calendars() + if not calendars: + sys.stderr.write("no calendar url given and no default calendar found - can't proceed. You will need to create a calendar first") return caldav.Principal(caldav_conn).calendars()[0] def _calendar_addics(caldav_conn, ics, uid, args): @@ -523,6 +526,16 @@ def calendar_agenda(caldav_conn, args): event[attr] = to_normal_str(event[attr]) print(args.event_template.format(**event)) +def create_calendar(caldav_conn, args): + cal_obj = caldav.Principal(caldav_conn).make_calendar(cal_id=args.cal_id) + if cal_obj: + print("Created a calendar with id " + args.cal_id) + +def create_tasklist(caldav_conn, args): + cal_obj = caldav.Principal(caldav_conn).make_calendar(cal_id=args.cal_id, supported_calendar_component_set=['VTODO']) + if cal_obj: + print("Created a task list with id " + args.tasklist_id) + def todo_select(caldav_conn, args): if args.top+args.limit+args.offset+args.offsetn and args.todo_uid: raise ValueError("It doesn't make sense to combine --todo-uid with --top/--limit/--offset/--offsetn") @@ -832,6 +845,10 @@ def main(): #todo_parser.add_argument('--due-before', ....) todo_parser.set_defaults(print_help=todo_parser.print_help) todo_subparsers = todo_parser.add_subparsers(title='tasks subcommand') + todo_create_parser = todo_subparsers.add_parser('createlist') + todo_create_parser.add_argument('tasklist_id') + todo_create_parser.set_defaults(func=create_tasklist) + todo_add_parser = todo_subparsers.add_parser('add') todo_add_parser.add_argument('summaryline', nargs='+') todo_add_parser.add_argument('--set-dtstart', default=date.today()+timedelta(1)) @@ -883,6 +900,11 @@ def main(): calendar_parser = subparsers.add_parser('calendar') calendar_parser.set_defaults(print_help=calendar_parser.print_help) calendar_subparsers = calendar_parser.add_subparsers(title='cal subcommand') + + calendar_create_parser = calendar_subparsers.add_parser('create') + calendar_create_parser.add_argument('cal_id') + calendar_create_parser.set_defaults(func=create_calendar) + calendar_add_parser = calendar_subparsers.add_parser('add') calendar_add_parser.add_argument('event_time', help="Timestamp and duration of the event. See the documentation for event_time specifications") calendar_add_parser.add_argument('summary', nargs='+') diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..406ea8e --- /dev/null +++ b/tests/README @@ -0,0 +1,7 @@ +TL;DR: run test_calendar-cli.sh, don't run tests.sh. + +Probably we should add some standard python test code here that can be run through nose or tox, but after all this is a command line utility - hence I found it appropriate to start with functional tests written to be executed from through a shell. + +The file tests.sh will run towards whatever calendar server is configured in .config/calendar.conf, and it has potential side effects, it will wipe out any prior events within the time range 2010-10-10 and 2010-10-14. + +The file test_calendar-cli.sh will set up a radicale calendar server, run the tests.sh towards radicale, then set up xandikos and run tests.sh towards xandikos. diff --git a/tests/script_test.sh b/tests/script_test.sh deleted file mode 100755 index 3a3f91a..0000000 --- a/tests/script_test.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -## Sorry - I have no idea how much of this script is compatible with -## POSIX shell and how much is bashisms ... been using bash for too -## long. - -set -e - -## SETUP - -error() { - echo "$1" - exit 255 -} - -[ -x ./calendar-cli.py ] && calendar_cli=./calendar-cli.py -[ -x ../calendar-cli.py ] && calendar_cli=../calendar-cli.py -[ -z "$calendar_cli" ] && error "couldn't find ./calendar_cli.py nor ../calendar_cli.py" - -calendar_cli() { - echo " $calendar_cli $@" - output=$($calendar_cli "$@") - [ -z "$output" ] || echo $output -} - -## CLEANUP from earlier failed test runs - -for uid in $($calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=4 --event-template='{uid}') ; do calendar_cli calendar delete --event-uid=$uid ; done -calendar_cli todo --categories scripttest delete - -## TESTING - -## EVENTS - -echo "## testing $calendar_cli" -echo "## this is a very simple test script without advanced error handling" -echo "## if this test script doesn't output 'all tests completed' in the end, something went wrong" - -echo "## Attempting to add a past event at 2010-10-09 20:00:00, 2 hours duration" -calendar_cli calendar add '2010-10-09 20:00:00+2h' 'testing testing' -uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -echo "## Attempting to add a past event at 2010-10-10 20:00:00, CET (1 hour duration is default)" -calendar_cli calendar add '2010-10-10 20:00:00+01:00' 'testing testing' --set-description='this is a test calendar event' --set-location='Москва' -uid2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -echo "## Attempting to add a past event at 2010-10-11 20:00:00, CET, 3h duration" -calendar_cli calendar add '2010-10-11 20:00:00+01:00+3h' 'testing testing' -uid3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -echo "## OK: Added the event, uid is $uid" - -echo "## Taking out the agenda for 2010-10-09 + four days" -calendar_cli calendar agenda --from-time=2010-10-09 --agenda-days=4 --event-template='{description} {location}' -echo $output | { grep -q 'this is a test calendar event Москва' && echo "## OK: found the event" ; } || echo "## FAIL: didn't find the event" - -echo "## Taking out the agenda for 2010-10-10, with uid" -calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=1 --event-template='{dtstart} {uid}' -echo $output | { grep -q $uid2 && echo "## OK: found the UID" ; } || echo "## FAIL: didn't find the UID" - -echo "## Deleting events with uid $uid $uid1 $uid2" -calendar_cli calendar delete --event-uid=$uid -calendar_cli calendar delete --event-uid=$uid2 -calendar_cli calendar delete --event-uid=$uid3 -echo "## Searching again for the deleted event" -calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=1 -echo $output | { grep -q 'testing testing' && echo "## FAIL: still found the event" ; } || echo "## OK: didn't find the event" - -## TODOS / TASK LISTS - -echo "## Attempting to add a task with category 'scripttest'" -calendar_cli todo add --set-categories scripttest "edit this task" -uidtodo1=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') - -echo "## Listing out all tasks with category set to 'scripttest'" -calendar_cli todo --categories scripttest list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just added and nothing more" - -echo "## Editing the task" -calendar_cli todo --categories scripttest edit --set-summary "editing" --add-categories "scripttest2" - -echo "## Verifying that the edits got through" -calendar_cli todo --categories scripttest list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" -calendar_cli todo --categories scripttest2 list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" -calendar_cli todo --comment editing list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" - -echo "## Complete the task" -calendar_cli todo --categories scripttest complete -calendar_cli todo --categories scripttest list -[ -z "$output" ] && echo "## OK: todo-item is done" -calendar_cli todo --todo-uid $uidtodo1 delete - -## parent-child relationships -echo "## Going to add three todo-items with children/parent relationships" -calendar_cli todo add --set-categories scripttest "this is a grandparent" -uidtodo2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this is a parent and a child" -uidtodo3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this task has two parents" -uidtodo4=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') -calendar_cli todo --categories scripttest list -[ $(echo "$output" | wc -l) == 3 ] && echo "## OK: found three tasks" -calendar_cli todo --hide-parents --categories scripttest list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" -echo "## Going to complete the children task" -calendar_cli todo --hide-parents --categories scripttest complete -calendar_cli todo --hide-parents --categories scripttest list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" -calendar_cli todo --hide-parents --categories scripttest complete -calendar_cli todo --hide-parents --categories scripttest list -[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" -calendar_cli todo --hide-parents --categories scripttest complete -calendar_cli todo --hide-parents --categories scripttest list -[ -z "$output" ] && echo "## OK: found no tasks now" - -echo "## all tests completed" diff --git a/tests/test_calendar-cli.sh b/tests/test_calendar-cli.sh new file mode 100755 index 0000000..be2717e --- /dev/null +++ b/tests/test_calendar-cli.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +######################################################################## +## RADICALE +######################################################################## +storage=$(mktemp -d) +python3 -m radicale --storage-filesystem-folder=$storage & +sleep 0.3 +jobs -l +radicale_pid=$(jobs -l | perl -ne '/^\[\d+\]\+\s+(\d+)\s+Running/ && print $1') +if [ -n "$radicale_pid" ] +then + echo "## Radicale now running on pid $radicale_pid" + calendar_cli="../calendar-cli --caldav-url=http://localhost:5232/ --caldav-user=testuser --calendar-url=/testuser/calendar-cli-test-calendar" + $calendar_cli calendar create calendar-cli-test-calendar + export calendar_cli + ./tests.sh + kill $radicale_pid + rm -rf $storage +else + echo "## Could not start up radicale (is it installed?). Will skip running tests towards radicale" +fi + + +######################################################################## +## XANDIKOS +######################################################################## +## TODO! work in progress + diff --git a/tests/tests.sh b/tests/tests.sh new file mode 100755 index 0000000..d496d8a --- /dev/null +++ b/tests/tests.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +set -e + +######################################################################## +## SETUP +######################################################################## + +error() { + echo "$1" + exit 255 +} + +[ -z "$calendar_cli" ] && [ -x ./calendar-cli.py ] && calendar_cli=./calendar-cli.py +[ -z "$calendar_cli" ] && [ -x ../calendar-cli.py ] && calendar_cli=../calendar-cli.py +[ -z "$calendar_cli" ] && error "couldn't find ./calendar_cli.py nor ../calendar_cli.py" + +calendar_cli() { + echo " $calendar_cli $@" + output=$($calendar_cli "$@") + [ -z "$output" ] || echo $output +} + +## CLEANUP from earlier failed test runs + +for uid in $($calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=4 --event-template='{uid}') ; do calendar_cli calendar delete --event-uid=$uid ; done +calendar_cli todo --categories scripttest delete + +######################################################################## +## TEST CODE FOLLOWS +######################################################################## + +## EVENTS + +echo "## testing $calendar_cli" +echo "## this is a very simple test script without advanced error handling" +echo "## if this test script doesn't output 'all tests completed' in the end, something went wrong" + +echo "## Attempting to add an event at 2010-10-09 20:00:00, 2 hours duration" +calendar_cli calendar add '2010-10-09 20:00:00+2h' 'testing testing' +uid=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid" ] || error "got no UID back" + +echo "## Attempting to add an event at 2010-10-10 20:00:00, CET (1 hour duration is default), with description and non-ascii location" +calendar_cli calendar add '2010-10-10 20:00:00+01:00' 'testing testing' --set-description='this is a test calendar event' --set-location='Москва' +uid2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +[ -n "$uid2" ] || error "got no UID back" + +echo "## Attempting to add a past event at 2010-10-11 20:00:00, CET, 3h duration" +calendar_cli calendar add '2010-10-11 20:00:00+01:00+3h' 'testing testing' +uid3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +echo "## OK: Added the event, uid is $uid" + +echo "## Taking out the agenda for 2010-10-09 + four days" +calendar_cli calendar agenda --from-time=2010-10-09 --agenda-days=4 --event-template='{description} {location}' +echo $output | { grep -q 'this is a test calendar event Москва' && echo "## OK: found the event" ; } || echo "## FAIL: didn't find the event" + +echo "## Taking out the agenda for 2010-10-10, with uid" +calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=1 --event-template='{dtstart} {uid}' +echo $output | { grep -q $uid2 && echo "## OK: found the UID" ; } || echo "## FAIL: didn't find the UID" + +echo "## Deleting events with uid $uid $uid1 $uid2" +calendar_cli calendar delete --event-uid=$uid +calendar_cli calendar delete --event-uid=$uid2 +calendar_cli calendar delete --event-uid=$uid3 +echo "## Searching again for the deleted event" +calendar_cli calendar agenda --from-time=2010-10-10 --agenda-days=1 +echo $output | { grep -q 'testing testing' && echo "## FAIL: still found the event" ; } || echo "## OK: didn't find the event" + +## TODOS / TASK LISTS + +echo "## Attempting to add a task with category 'scripttest'" +calendar_cli todo add --set-categories scripttest "edit this task" +uidtodo1=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') + +echo "## Listing out all tasks with category set to 'scripttest'" +calendar_cli todo --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just added and nothing more" + +echo "## Editing the task" +calendar_cli todo --categories scripttest edit --set-summary "editing" --add-categories "scripttest2" + +echo "## Verifying that the edits got through" +calendar_cli todo --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" +calendar_cli todo --categories scripttest2 list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" +calendar_cli todo --comment editing list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found the todo item we just edited and nothing more" + +echo "## Complete the task" +calendar_cli todo --categories scripttest complete +calendar_cli todo --categories scripttest list +[ -z "$output" ] && echo "## OK: todo-item is done" +calendar_cli todo --todo-uid $uidtodo1 delete + +## parent-child relationships +echo "## Going to add three todo-items with children/parent relationships" +calendar_cli todo add --set-categories scripttest "this is a grandparent" +uidtodo2=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this is a parent and a child" +uidtodo3=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories=scripttest add --set-categories scripttest --is-child "this task has two parents" +uidtodo4=$(echo $output | perl -ne '/uid=(.*)$/ && print $1') +calendar_cli todo --categories scripttest list +[ $(echo "$output" | wc -l) == 3 ] && echo "## OK: found three tasks" +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +echo "## Going to complete the children task" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ $(echo "$output" | wc -l) == 1 ] && echo "## OK: found only one task now" +calendar_cli todo --hide-parents --categories scripttest complete +calendar_cli todo --hide-parents --categories scripttest list +[ -z "$output" ] && echo "## OK: found no tasks now" + +echo "## all tests completed" -- cgit v1.2.3