Merge remote-tracking branch 'upstream/develop' into 14a28

This commit is contained in:
Alexandre SPANGARO 2021-03-21 22:59:41 +01:00
commit 17e0cc4bad
478 changed files with 589 additions and 88522 deletions

View File

@ -1,68 +1,6 @@
# HOW TO BUILD
Take a look at the dolibarr wiki page of Zapier module:
## ENABLE MODULE ZAPIER ON DOLIBARR
This should also enable the module API (required for authentication by Zapier service and to execute action in Dolibarr by Zapier).
Create the Dolibarr login that will be used by Zapier to call APIs. Give the login the permissions on the action you plan to automate.
## CREATE A ZAPIER DEVELOPPER ACCOUNT
At first, you need to have a Zapier developper acoount, create it here [Zapier Platform](https://developer.zapier.com/)
## INSTALL ZAPIER COMMAND LINE TOOLS WITH LINK TO ZAPIER ONLINE ACCOUNT
### Install Node.js
An easy option to get set up with Node.js is to visit [https://nodejs.org/en/download/](https://nodejs.org/en/download/) and download the official installer for your OS. If you're installing with a package manager it's even easier.
After installation, confirm that Node.js is ready to use:
`node --version`
### Install the Zapier CLI
Next let's install the Zapier CLI tools. The CLI will allow you to build your app, deploy it to the Zapier platform, do local testing, manage users and testers, view remote logs, collaborate with your team, and more:
`cd dev/examples/zapier`
`npm install -g zapier-platform-cli` to install the CLI globally
`zapier --version` to return version of the CLI
### Run Zapier Login
Let's configure authentication between your dev environment and the Zapier platform. You'll use the email address and password you use to log in to the Zapier application.
`zapier login`
This command will set up a .zapierrc file in your home directory.
### Install the Project
In zapier example directory, run:
`cd dev/examples/zapier`
`npm install`
### Deploying your App
Let's deploy it! When you're ready to try your code out on the Zapier platform use the push command. Only you will be able to see the app until you invite testers.
`zapier register` (the first time, choose name for example "Dolibarr")
`zapier push`
After a push, the Application, with the name you defined during the register step, is available when creating a Zap.
You will find original tutorial here : [https://zapier.com/developer/start/introduction](https://zapier.com/developer/start/introduction)
### Create a Zap
Create a ZAP that use the application you registered.
For authentication, you must enter the login / pass of account used by Zapier to call APIs.
https://wiki.dolibarr.org/index.php?title=Module_Zapier

View File

@ -55,6 +55,7 @@ $constantes = array(
'ADHERENT_EMAIL_TEMPLATE_MEMBER_VALIDATION' =>'emailtemplate:member', /* old was ADHERENT_MAIL_VALID */
'ADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION' =>'emailtemplate:member', /* old was ADHERENT_MAIL_COTIS */
'ADHERENT_EMAIL_TEMPLATE_CANCELATION' =>'emailtemplate:member', /* old was ADHERENT_MAIL_RESIL */
'ADHERENT_EMAIL_TEMPLATE_EXCLUSION' =>'emailtemplate:member',
'ADHERENT_MAIL_FROM'=>'string',
'ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT'=>'string',
'ADHERENT_AUTOREGISTER_NOTIF_MAIL'=>'html',

View File

@ -178,7 +178,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print '</td><td class="right">';
$listofval = array();
$listofval += $adht->liste_array();
$forcetype = $conf->global->MEMBER_NEWFORM_FORCETYPE ?: -1;
$forcetype = empty($conf->global->MEMBER_NEWFORM_FORCETYPE) ? -1 : $conf->global->MEMBER_NEWFORM_FORCETYPE;
print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0);
print "</td></tr>\n";
@ -232,7 +232,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print '<br>';
//print $langs->trans('FollowingLinksArePublic').'<br>';
print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').':<br>';
if ($conf->multicompany->enabled) {
if (!empty($conf->multicompany->enabled)) {
$entity_qr = '?entity='.$conf->entity;
} else {
$entity_qr = '';

View File

@ -655,7 +655,7 @@ if (empty($reshook)) {
$action = '';
}
if ($user->rights->adherent->supprimer && $action == 'confirm_resign') {
if ($user->rights->adherent->supprimer && $action == 'confirm_resiliate') {
$error = 0;
if ($confirm == 'yes') {
@ -726,6 +726,77 @@ if (empty($reshook)) {
}
}
if ($user->rights->adherent->supprimer && $action == 'confirm_exclude') {
$error = 0;
if ($confirm == 'yes') {
$adht = new AdherentType($db);
$adht->fetch($object->typeid);
$result = $object->exclude($user);
if ($result >= 0 && !count($object->errors)) {
if ($object->email && GETPOST("send_mail")) {
$subject = '';
$msg = '';
// Send subscription email
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
$formmail = new FormMail($db);
// Set output language
$outputlangs = new Translate('', $conf);
$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
// Load traductions files required by page
$outputlangs->loadLangs(array("main", "members"));
// Get email content from template
$arraydefaultmessage = null;
$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_EXCLUSION;
if (!empty($labeltouse)) {
$arraydefaultmessage = $formmail->getEMailTemplate($db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
}
if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
$subject = $arraydefaultmessage->topic;
$msg = $arraydefaultmessage->content;
}
if (empty($labeltouse) || (int) $labeltouse === -1) {
//fallback on the old configuration.
setEventMessages('WarningMandatorySetupNotComplete', null, 'errors');
$error++;
} else {
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
complete_substitutions_array($substitutionarray, $outputlangs, $object);
$subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
$texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnExclude()), $substitutionarray, $outputlangs);
$moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
if ($result < 0) {
$error++;
setEventMessages($object->error, $object->errors, 'errors');
}
}
}
} else {
$error++;
if ($object->error) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
$action = '';
}
}
if (!empty($backtopage) && !$error) {
header("Location: ".$backtopage);
exit;
}
}
// SPIP Management
if ($user->rights->adherent->supprimer && $action == 'confirm_del_spip' && $confirm == 'yes') {
if (!count($object->errors)) {
@ -1434,8 +1505,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ValidateMember"), $langs->trans("ConfirmValidateMember"), "confirm_valid", $formquestion, 'yes', 1, 220);
}
// Confirm terminate
if ($action == 'resign') {
// Confirm resiliate
if ($action == 'resiliate') {
$langs->load("mails");
$adht = new AdherentType($db);
@ -1491,7 +1562,67 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if ($backtopage) {
$formquestion[] = array('type' => 'hidden', 'name' => 'backtopage', 'value' => ($backtopage != '1' ? $backtopage : $_SERVER["HTTP_REFERER"]));
}
print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ResiliateMember"), $langs->trans("ConfirmResiliateMember"), "confirm_resign", $formquestion, 'no', 1, 240);
print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ResiliateMember"), $langs->trans("ConfirmResiliateMember"), "confirm_resiliate", $formquestion, 'no', 1, 240);
}
// Confirm exclude
if ($action == 'exclude') {
$langs->load("mails");
$adht = new AdherentType($db);
$adht->fetch($object->typeid);
$subject = '';
$msg = '';
// Send subscription email
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
$formmail = new FormMail($db);
// Set output language
$outputlangs = new Translate('', $conf);
$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
// Load traductions files required by page
$outputlangs->loadLangs(array("main", "members"));
// Get email content from template
$arraydefaultmessage = null;
$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_EXCLUSION;
if (!empty($labeltouse)) {
$arraydefaultmessage = $formmail->getEMailTemplate($db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
}
if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
$subject = $arraydefaultmessage->topic;
$msg = $arraydefaultmessage->content;
}
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
complete_substitutions_array($substitutionarray, $outputlangs, $object);
$subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
$texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnExclude()), $substitutionarray, $outputlangs);
$tmp = $langs->trans("SendingAnEMailToMember");
$tmp .= '<br>('.$langs->trans("MailFrom").': <b>'.$conf->global->ADHERENT_MAIL_FROM.'</b>, ';
$tmp .= $langs->trans("MailRecipient").': <b>'.$object->email.'</b>)';
$helpcontent = '';
$helpcontent .= '<b>'.$langs->trans("MailFrom").'</b>: '.$conf->global->ADHERENT_MAIL_FROM.'<br>'."\n";
$helpcontent .= '<b>'.$langs->trans("MailRecipient").'</b>: '.$object->email.'<br>'."\n";
$helpcontent .= '<b>'.$langs->trans("Subject").'</b>:<br>'."\n";
$helpcontent .= $subjecttosend."\n";
$helpcontent .= "<br>";
$helpcontent .= '<b>'.$langs->trans("Content").'</b>:<br>';
$helpcontent .= dol_htmlentitiesbr($texttosend)."\n";
$label = $form->textwithpicto($tmp, $helpcontent, 1, 'help');
// Create an array
$formquestion = array();
if ($object->email) {
$formquestion[] = array('type' => 'checkbox', 'name' => 'send_mail', 'label' => $label, 'value' => (!empty($conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL) ? 'true' : 'false'));
}
if ($backtopage) {
$formquestion[] = array('type' => 'hidden', 'name' => 'backtopage', 'value' => ($backtopage != '1' ? $backtopage : $_SERVER["HTTP_REFERER"]));
}
print $form->formconfirm("card.php?rowid=".$id, $langs->trans("ExcludeMember"), $langs->trans("ConfirmExcludeMember"), "confirm_exclude", $formquestion, 'no', 1, 240);
}
// Confirm remove member
@ -1584,12 +1715,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
} elseif (!$adht->subscription) {
print $langs->trans("SubscriptionNotRecorded");
if ($object->statut > 0) {
print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated
print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated
}
} else {
print $langs->trans("SubscriptionNotReceived");
if ($object->statut > 0) {
print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated
print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft, not excluded and not resiliated
}
}
}
@ -1740,7 +1871,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
}
// Reactivate
if ($object->statut == 0) {
if ($object->statut == 0 || $object->statut == -2) {
if ($user->rights->adherent->creer) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?rowid='.$id.'&action=valid">'.$langs->trans("Reenable")."</a></div>\n";
} else {
@ -1748,15 +1879,24 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
}
}
// Terminate
// Resiliate
if ($object->statut >= 1) {
if ($user->rights->adherent->supprimer) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?rowid='.$id.'&action=resign">'.$langs->trans("Resiliate")."</a></div>\n";
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?rowid='.$id.'&action=resiliate">'.$langs->trans("Resiliate")."</a></div>\n";
} else {
print '<div class="inline-block divButAction"><font class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("Resiliate")."</font></div>";
}
}
// Exclude
if ($object->statut >= 1) {
if ($user->rights->adherent->supprimer) {
print '<div class="inline-block divButAction"><a class="butAction" href="card.php?rowid='.$id.'&action=exclude">'.$langs->trans("Exclude")."</a></div>\n";
} else {
print '<div class="inline-block divButAction"><font class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("Exclude")."</font></div>";
}
}
// Create third party
if (!empty($conf->societe->enabled) && !$object->socid) {
if ($user->rights->societe->creer) {

View File

@ -206,7 +206,7 @@ class Adherent extends CommonObject
public $public;
// -1:brouillon, 0:resilie, >=1:valide,paye
// -2:exclu, -1:brouillon, 0:resilie, >=1:valide,paye
// def in common object
//public $status;
@ -326,7 +326,7 @@ class Adherent extends CommonObject
'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 190),
'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 195),
'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 500,
'arrayofkeyval' => array(0 => 'Draft', 1 => 'Validated', -1 => 'MemberStatusResiliatedShort')),
'arrayofkeyval' => array(0 => 'Draft', 1 => 'Validated', -1 => 'MemberStatusResiliatedShort', -2 => 'MemberStatusExcludedShort')),
'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805)
);
@ -1917,6 +1917,55 @@ class Adherent extends CommonObject
}
}
/**
* Functiun to exlude (set adherent.status to -2) a member
* TODO
* A private note should be added to know why the member has been excluded
* For historical purpose it add an "extra-subscription" type excluded
*
* @param User $user User making change
* @return int <0 if KO, >0 if OK
*/
public function exclude($user)
{
global $langs, $conf;
$error = 0;
// Check parameters
if ($this->statut == 0) {
dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
return 0;
}
$this->db->begin();
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
$sql .= " statut = -2";
$sql .= ", fk_user_valid=".$user->id;
$sql .= " WHERE rowid = ".$this->id;
$result = $this->db->query($sql);
if ($result) {
$this->statut = 0;
// Call trigger
$result = $this->call_trigger('MEMBER_EXCLUDE', $user);
if ($result < 0) {
$error++;
$this->db->rollback();
return -1;
}
// End call triggers
$this->db->commit();
return 1;
} else {
$this->error = $this->db->error();
$this->db->rollback();
return -1;
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
@ -2173,7 +2222,7 @@ class Adherent extends CommonObject
}
/**
* Retourne le libelle du statut d'un adherent (brouillon, valide, resilie)
* Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
*
* @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
* @return string Label
@ -2229,6 +2278,10 @@ class Adherent extends CommonObject
$statusType = 'status6';
$labelStatus = $langs->trans("MemberStatusResiliated");
$labelStatusShort = $langs->trans("MemberStatusResiliatedShort");
} elseif ($status == -2) {
$statusType = 'status8';
$labelStatus = $langs->trans("MemberStatusExcluded");
$labelStatusShort = $langs->trans("MemberStatusExcludedShort");
}
return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);

View File

@ -103,6 +103,9 @@ class AdherentType extends CommonObject
/** @var string Email sent after resiliation */
public $mail_resiliate = '';
/** @var string Email sent after exclude */
public $mail_exclude = '';
/** @var array Array of members */
public $members = array();
@ -820,4 +823,19 @@ class AdherentType extends CommonObject
return '';
}
/**
* getMailOnExclude
*
* @return string Return mail model content of type or empty
*/
public function getMailOnExclude()
{
// NOTE mail_exclude not defined so never used
if (!empty($this->mail_exclude) && trim(dol_htmlentitiesbr_decode($this->mail_exclude))) { // Property not yet defined
return $this->mail_exclude;
}
return '';
}
}

View File

@ -329,7 +329,7 @@ class Members extends DolibarrApi
continue;
}
// Process the status separately because it must be updated using
// the validate() and resiliate() methods of the class Adherent.
// the validate(), resiliate() and exclude() methods of the class Adherent.
if ($field == 'statut') {
if ($value == '0') {
$result = $member->resiliate(DolibarrApiAccess::$user);
@ -341,6 +341,11 @@ class Members extends DolibarrApi
if ($result < 0) {
throw new RestException(500, 'Error when validating member: '.$member->error);
}
} elseif ($value == '-2') {
$result = $member->exclude(DolibarrApiAccess::$user);
if ($result < 0) {
throw new RestException(500, 'Error when excluding member: '.$member->error);
}
}
} else {
$member->$field = $value;

View File

@ -194,7 +194,7 @@ class MembersTypes extends DolibarrApi
continue;
}
// Process the status separately because it must be updated using
// the validate() and resiliate() methods of the class AdherentType.
// the validate(), resiliate() and exclude() methods of the class AdherentType.
$membertype->$field = $value;
}

View File

@ -1,8 +1,8 @@
<?php
/* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
* Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
* Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2021 Frédéric France <frederic.france@netlgic.fr>
*
@ -82,6 +82,7 @@ print load_fiche_titre($langs->trans("MembersArea"), $resultboxes['selectboxlist
$MembersValidated = array();
$MembersToValidate = array();
$MembersUpToDate = array();
$MembersExcluded = array();
$MembersResiliated = array();
$AdherentType = array();
@ -116,6 +117,9 @@ if ($result) {
if ($objp->statut == 1) {
$MembersValidated[$objp->rowid] = $objp->somme;
}
if ($objp->statut == -2) {
$MembersExcluded[$objp->rowid] = $objp->somme;
}
if ($objp->statut == 0) {
$MembersResiliated[$objp->rowid] = $objp->somme;
}
@ -195,9 +199,10 @@ if ($conf->use_javascript_ajax) {
$SumToValidate = 0;
$SumValidated = 0;
$SumUpToDate = 0;
$SumResiliated = 0;
$SumExcluded = 0;
$total = 0;
$dataval = array();
$i = 0;
@ -205,17 +210,21 @@ if ($conf->use_javascript_ajax) {
$dataval['draft'][] = array($i, isset($MembersToValidate[$key]) ? $MembersToValidate[$key] : 0);
$dataval['notuptodate'][] = array($i, isset($MembersValidated[$key]) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : 0);
$dataval['uptodate'][] = array($i, isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0);
$dataval['excluded'][] = array($i, isset($MembersExcluded[$key]) ? $MembersExcluded[$key] : 0);
$dataval['resiliated'][] = array($i, isset($MembersResiliated[$key]) ? $MembersResiliated[$key] : 0);
$SumToValidate += isset($MembersToValidate[$key]) ? $MembersToValidate[$key] : 0;
$SumValidated += isset($MembersValidated[$key]) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : 0;
$SumUpToDate += isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0;
$SumExcluded += isset($MembersExcluded[$key]) ? $MembersExcluded [$key] : 0;
$SumResiliated += isset($MembersResiliated[$key]) ? $MembersResiliated[$key] : 0;
$i++;
}
$total = $SumToValidate + $SumValidated + $SumUpToDate + $SumResiliated;
$total = $SumToValidate + $SumValidated + $SumUpToDate + $SumExcluded + $SumResiliated;
$dataseries = array();
$dataseries[] = array($langs->transnoentitiesnoconv("OutOfDate"), round($SumValidated));
$dataseries[] = array($langs->transnoentitiesnoconv("UpToDate"), round($SumUpToDate));
$dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusExcluded"), round($SumExcluded));
$dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusResiliated"), round($SumResiliated));
$dataseries[] = array($langs->transnoentitiesnoconv("MembersStatusToValid"), round($SumToValidate));
@ -224,7 +233,7 @@ if ($conf->use_javascript_ajax) {
include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$dolgraph = new DolGraph();
$dolgraph->SetData($dataseries);
$dolgraph->SetDataColor(array($badgeStatus1, $badgeStatus4, $badgeStatus6, '-'.$badgeStatus0));
$dolgraph->SetDataColor(array($badgeStatus1, $badgeStatus4, $badgeStatus8, $badgeStatus6, '-'.$badgeStatus0));
$dolgraph->setShowLegend(2);
$dolgraph->setShowPercent(1);
$dolgraph->SetType(array('pie'));
@ -234,7 +243,7 @@ if ($conf->use_javascript_ajax) {
$boxgraph .= '</td></tr>';
$boxgraph .= '<tr class="liste_total"><td>'.$langs->trans("Total").'</td><td class="right">';
$boxgraph .= $SumToValidate + $SumValidated + $SumUpToDate + $SumResiliated;
$boxgraph .= $SumToValidate + $SumValidated + $SumUpToDate + $SumExcluded + $SumResiliated;
$boxgraph .= '</td></tr>';
$boxgraph .= '</table>';
$boxgraph .= '</div>';
@ -251,250 +260,12 @@ print '<div class="firstcolumn fichehalfleft boxhalfleft" id="boxhalfleft">';
print $searchbox;
print $boxgraph;
// List of subscription by year
$Total = array();
$Number = array();
$tot = 0;
$numb = 0;
$sql = "SELECT c.subscription, c.dateadh as dateh";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."subscription as c";
$sql .= " WHERE d.entity IN (".getEntity('adherent').")";
$sql .= " AND d.rowid = c.fk_adherent";
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
$i = 0;
while ($i < $num) {
$objp = $db->fetch_object($result);
$year = dol_print_date($db->jdate($objp->dateh), "%Y");
$Total[$year] = (isset($Total[$year]) ? $Total[$year] : 0) + $objp->subscription;
$Number[$year] = (isset($Number[$year]) ? $Number[$year] : 0) + 1;
$tot += $objp->subscription;
$numb += 1;
$i++;
}
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("Year").'</th>';
print '<th class="right">'.$langs->trans("Subscriptions").'</th>';
print '<th class="right">'.$langs->trans("AmountTotal").'</th>';
print '<th class="right">'.$langs->trans("AmountAverage").'</th>';
print "</tr>\n";
krsort($Total);
$i = 0;
foreach ($Total as $key=>$value) {
if ($i >= 8) {
print '<tr class="oddeven">';
print "<td>...</td>";
print "<td class=\"right\"></td>";
print "<td class=\"right\"></td>";
print "<td class=\"right\"></td>";
print "</tr>\n";
break;
}
print '<tr class="oddeven">';
print "<td><a href=\"./subscription/list.php?date_select=$key\">$key</a></td>";
print "<td class=\"right\">".$Number[$key]."</td>";
print "<td class=\"right\">".price($value)."</td>";
print "<td class=\"right\">".price(price2num($value / $Number[$key], 'MT'))."</td>";
print "</tr>\n";
$i++;
}
// Total
print '<tr class="liste_total">';
print '<td>'.$langs->trans("Total").'</td>';
print "<td class=\"right\">".$numb."</td>";
print '<td class="right">'.price($tot)."</td>";
print "<td class=\"right\">".price(price2num($numb > 0 ? ($tot / $numb) : 0, 'MT'))."</td>";
print "</tr>\n";
print "</table></div>";
print "<br>\n";
print $resultboxes['boxlista'];
print '</div>'."\n";
print '<div class="secondcolumn fichehalfright boxhalfright" id="boxhalfright">';
/*
* Latest modified members
*/
$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
$sql = "SELECT a.rowid, a.statut as status, a.lastname, a.firstname, a.societe as company, a.fk_soc,";
$sql .= " a.gender, a.email, a.photo, a.morphy,";
$sql .= " a.tms as datem, a.datefin as date_end_subscription,";
$sql .= " ta.rowid as typeid, ta.libelle as label, ta.subscription as need_subscription";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta";
$sql .= " WHERE a.entity IN (".getEntity('adherent').")";
$sql .= " AND a.fk_adherent_type = ta.rowid";
$sql .= $db->order("a.tms", "DESC");
$sql .= $db->plimit($max, 0);
$resql = $db->query($sql);
if ($resql) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="4">'.$langs->trans("LastMembersModified", $max).'</th></tr>';
$num = $db->num_rows($resql);
if ($num) {
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
$staticmember->id = $obj->rowid;
$staticmember->ref = $obj->rowid;
$staticmember->lastname = $obj->lastname;
$staticmember->firstname = $obj->firstname;
$staticmember->gender = $obj->gender;
$staticmember->email = $obj->email;
$staticmember->photo = $obj->photo;
$staticmember->morphy = $obj->morphy;
$staticmember->statut = $obj->status;
$staticmember->need_subscription = $obj->need_subscription;
$staticmember->datefin = $db->jdate($obj->date_end_subscription);
if (!empty($obj->fk_soc)) {
$staticmember->fk_soc = $obj->fk_soc;
$staticmember->fetch_thirdparty();
$staticmember->name = $staticmember->thirdparty->name;
} else {
$staticmember->name = $obj->company;
}
$statictype->id = $obj->typeid;
$statictype->label = $obj->label;
$statictype->subscription = $obj->need_subscription;
print '<tr class="oddeven">';
print '<td class="nowraponall">'.$staticmember->getNomUrl(-1, 32).'</td>';
print '<td>'.$statictype->getNomUrl(1, 32).'</td>';
print '<td>'.dol_print_date($db->jdate($obj->datem), 'dayhour').'</td>';
print '<td class="right">'.$staticmember->getLibStatut(3).'</td>';
print '</tr>';
$i++;
}
}
print "</table></div>";
print "<br>";
} else {
dol_print_error($db);
}
/*
* Last modified subscriptions
*/
$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
$sql = "SELECT a.rowid, a.statut as status, a.lastname, a.firstname, a.societe as company, a.fk_soc,";
$sql .= " a.gender, a.email, a.photo, a.morphy,";
$sql .= " a.datefin as date_end_subscription,";
$sql .= " ta.rowid as typeid, ta.libelle as label, ta.subscription as need_subscription,";
$sql .= " c.rowid as cid, c.tms as datem, c.datec as datec, c.dateadh as date_start, c.datef as date_end, c.subscription";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta, ".MAIN_DB_PREFIX."subscription as c";
$sql .= " WHERE a.entity IN (".getEntity('adherent').")";
$sql .= " AND a.fk_adherent_type = ta.rowid";
$sql .= " AND c.fk_adherent = a.rowid";
$sql .= $db->order("c.tms", "DESC");
$sql .= $db->plimit($max, 0);
$resql = $db->query($sql);
if ($resql) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th colspan="5">'.$langs->trans("LastSubscriptionsModified", $max).'</th></tr>';
$num = $db->num_rows($resql);
if ($num) {
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
$staticmember->id = $obj->rowid;
$staticmember->ref = $obj->rowid;
$staticmember->lastname = $obj->lastname;
$staticmember->firstname = $obj->firstname;
$staticmember->gender = $obj->gender;
$staticmember->email = $obj->email;
$staticmember->photo = $obj->photo;
$staticmember->morphy = $obj->morphy;
$staticmember->statut = $obj->status;
$staticmember->need_subscription = $obj->need_subscription;
$staticmember->datefin = $db->jdate($obj->date_end_subscription);
if (!empty($obj->fk_soc)) {
$staticmember->fk_soc = $obj->fk_soc;
$staticmember->fetch_thirdparty();
$staticmember->name = $staticmember->thirdparty->name;
} else {
$staticmember->name = $obj->company;
}
$subscriptionstatic->id = $obj->cid;
$subscriptionstatic->ref = $obj->cid;
print '<tr class="oddeven">';
print '<td class="nowraponall">'.$subscriptionstatic->getNomUrl(1).'</td>';
print '<td class="nowraponall">'.$staticmember->getNomUrl(-1, 32, 'subscription').'</td>';
print '<td class="nowraponall">'.get_date_range($db->jdate($obj->date_start), $db->jdate($obj->date_end)).'</td>';
print '<td class="right">'.price($obj->subscription).'</td>';
//print '<td class="right">'.$staticmember->LibStatut($obj->statut,($obj->subscription=='yes'?1:0),$db->jdate($obj->date_end_subscription),5).'</td>';
print '<td class="right nowraponall">'.dol_print_date($db->jdate($obj->datem ? $obj->datem : $obj->datec), 'dayhour').'</td>';
print '</tr>';
$i++;
}
}
print "</table></div>";
print "<br>";
} else {
dol_print_error($db);
}
// Summary of members by type
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("MembersTypes").'</th>';
print '<th class=right>'.$langs->trans("MembersStatusToValid").'</th>';
print '<th class=right>'.$langs->trans("OutOfDate").'</th>';
print '<th class=right>'.$langs->trans("UpToDate").'</th>';
print '<th class=right>'.$langs->trans("MembersStatusResiliated").'</th>';
print "</tr>\n";
foreach ($AdherentType as $key => $adhtype) {
print '<tr class="oddeven">';
print '<td>'.$adhtype->getNomUrl(1, dol_size(32)).'</td>';
print '<td class="right">'.(isset($MembersToValidate[$key]) && $MembersToValidate[$key] > 0 ? $MembersToValidate[$key] : '').' '.$staticmember->LibStatut(-1, $adhtype->subscription, 0, 3).'</td>';
print '<td class="right">'.(isset($MembersValidated[$key]) && ($MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) > 0) ? $MembersValidated[$key] - (isset($MembersUpToDate[$key]) ? $MembersUpToDate[$key] : 0) : '').' '.$staticmember->LibStatut(1, $adhtype->subscription, 0, 3).'</td>';
print '<td class="right">'.(isset($MembersUpToDate[$key]) && $MembersUpToDate[$key] > 0 ? $MembersUpToDate[$key] : '').' '.$staticmember->LibStatut(1, $adhtype->subscription, $now, 3).'</td>';
print '<td class="right">'.(isset($MembersResiliated[$key]) && $MembersResiliated[$key] > 0 ? $MembersResiliated[$key] : '').' '.$staticmember->LibStatut(0, $adhtype->subscription, 0, 3).'</td>';
print "</tr>\n";
}
print '<tr class="liste_total">';
print '<td class="liste_total">'.$langs->trans("Total").'</td>';
print '<td class="liste_total right">'.$SumToValidate.' '.$staticmember->LibStatut(-1, $adhtype->subscription, 0, 3).'</td>';
print '<td class="liste_total right">'.$SumValidated.' '.$staticmember->LibStatut(1, $adhtype->subscription, 0, 3).'</td>';
print '<td class="liste_total right">'.$SumUpToDate.' '.$staticmember->LibStatut(1, $adhtype->subscription, $now, 3).'</td>';
print '<td class="liste_total right">'.$SumResiliated.' '.$staticmember->LibStatut(0, $adhtype->subscription, 0, 3).'</td>';
print '</tr>';
print "</table>\n";
print "</div>";
print '<br>';
print $resultboxes['boxlistb'];
print '</div>'."\n";

View File

@ -76,7 +76,7 @@ if ($statut != '') {
$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
if ($search_status < -1) {
if ($search_status < -2) {
$search_status = '';
}
@ -452,6 +452,9 @@ if (GETPOSTISSET("search_status")) {
if ($search_status == '0') {
$titre = $langs->trans("MembersListResiliated");
}
if ($search_status == '-2') {
$titre = $langs->trans("MembersListExcluded");
}
} elseif ($action == 'search') {
$titre = $langs->trans("MembersListQualified");
}
@ -750,9 +753,10 @@ if (!empty($arrayfields['d.statut']['checked'])) {
$liststatus = array(
'-1'=>$langs->trans("Draft"),
'1'=>$langs->trans("Validated"),
'0'=>$langs->trans("Resiliated")
'0'=>$langs->trans("Resiliated"),
'-2'=>$langs->trans("Excluded")
);
print $form->selectarray('search_status', $liststatus, $search_status, -2);
print $form->selectarray('search_status', $liststatus, $search_status, -3);
print '</td>';
}
// Action column

View File

@ -645,7 +645,7 @@ if ($rowid > 0) {
* Action bar
*/
// Button to create a new subscription if member no draft neither resiliated
// Button to create a new subscription if member no draft (-1) neither resiliated (0) neither excluded (-2)
if ($user->rights->adherent->cotisation->creer) {
if ($action != 'addsubscription' && $action != 'create_thirdparty') {
print '<div class="tabsAction">';

View File

@ -566,6 +566,8 @@ if ($rowid > 0) {
$titre = $langs->trans("MembersListNotUpToDate");
} elseif ($status == '0') {
$titre = $langs->trans("MembersListResiliated");
} elseif ($status == '-2') {
$titre = $langs->trans("MembersListExcluded");
}
} elseif ($action == 'search') {
$titre = $langs->trans("MembersListQualified");

View File

@ -468,7 +468,7 @@ if ($action == 'create') {
print '</table>';
dol_fiche_end();
print dol_get_fiche_end();
print '<div class="center">';
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
@ -710,7 +710,7 @@ if ($id) {
print '<div class="clearboth"></div>';
dol_fiche_end();
print dol_get_fiche_end();
if ($action == 'edit') {
print '<div align="center">';

View File

@ -166,7 +166,7 @@ class box_members_by_type extends ModeleBoxes
$line = 0;
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_titre"',
'td' => 'class=""',
'text' => $langs->trans("MembersTypes"),
);
$this->info_box_contents[$line][] = array(
@ -198,22 +198,22 @@ class box_members_by_type extends ModeleBoxes
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'text' => (isset($MembersToValidate[$key]) && $MembersToValidate[$key] > 0 ? $MembersToValidate[$key] : '') . ' ' . $staticmember->LibStatut(-1, $adhtype->subscription, 0, 3),
'text' => (isset($MembersToValidate[$key]) && $MembersToValidate[$key] > 0 ? $MembersToValidate[$key] : '') . ' ' . $staticmember->LibStatut(-1, 1, 0, 3),
'asis' => 1,
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'text' => (isset($MembersValidated[$key]) && ($MembersValidated[$key] - (isset($MemberUpToDate[$key]) ? $MemberUpToDate[$key] : 0) > 0) ? $MembersValidated[$key] - (isset($MemberUpToDate[$key]) ? $MemberUpToDate[$key] : 0) : '') . ' ' . $staticmember->LibStatut(1, $adhtype->subscription, 0, 3),
'text' => (isset($MembersValidated[$key]) && ($MembersValidated[$key] - (isset($MemberUpToDate[$key]) ? $MemberUpToDate[$key] : 0) > 0) ? $MembersValidated[$key] - (isset($MemberUpToDate[$key]) ? $MemberUpToDate[$key] : 0) : '') . ' ' . $staticmember->LibStatut(1, 1, 0, 3),
'asis' => 1,
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'text' => (isset($MemberUpToDate[$key]) && $MemberUpToDate[$key] > 0 ? $MemberUpToDate[$key] : '') . ' ' . $staticmember->LibStatut(1, $adhtype->subscription, $now, 3),
'text' => (isset($MemberUpToDate[$key]) && $MemberUpToDate[$key] > 0 ? $MemberUpToDate[$key] : '') . ' ' . $staticmember->LibStatut(1, 1, $now, 3),
'asis' => 1,
);
$this->info_box_contents[$line][] = array(
'td' => 'class="right"',
'text' => (isset($MembersResiliated[$key]) && $MembersResiliated[$key] > 0 ? $MembersResiliated[$key] : '') . ' ' . $staticmember->LibStatut(0, $adhtype->subscription, 0, 3),
'text' => (isset($MembersResiliated[$key]) && $MembersResiliated[$key] > 0 ? $MembersResiliated[$key] : '') . ' ' . $staticmember->LibStatut(0, 1, 0, 3),
'asis' => 1,
);
@ -223,35 +223,39 @@ class box_members_by_type extends ModeleBoxes
if ($num == 0) {
$this->info_box_contents[$line][0] = array(
'td' => 'class="center"',
'text' => $langs->trans("NoRecordedMembersByType"),
'text' => $langs->trans("NoRecordedMembersByType")
);
} else {
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_total"',
'text' => $langs->trans("Total"),
'text' => $langs->trans("Total")
);
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_total right"',
'text' => $SommeA.' '.$staticmember->LibStatut(-1, $adhtype->subscription, 0, 3),
'text' => $SommeA.' '.$staticmember->LibStatut(-1, 1, 0, 3),
'asis' => 1
);
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_total right"',
'text' => $SommeB.' '.$staticmember->LibStatut(1, $adhtype->subscription, 0, 3),
'text' => $SommeB.' '.$staticmember->LibStatut(1, 1, 0, 3),
'asis' => 1
);
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_total right"',
'text' => $SommeC.' '.$staticmember->LibStatut(1, $adhtype->subscription, $now, 3),
'text' => $SommeC.' '.$staticmember->LibStatut(1, 1, $now, 3),
'asis' => 1
);
$this->info_box_contents[$line][] = array(
'td' => 'class="liste_total right"',
'text' => $SommeD.' '.$staticmember->LibStatut(0, $adhtype->subscription, 0, 3),
'text' => $SommeD.' '.$staticmember->LibStatut(0, 1, 0, 3),
'asis' => 1
);
}
} else {
$this->info_box_contents[0][0] = array(
'td' => '',
'maxlength' => 500,
'text' => ($this->db->error() . ' sql=' . $sql),
'text' => ($this->db->error() . ' sql=' . $sql)
);
}
} else {

View File

@ -2577,7 +2577,7 @@ class Form
}
}
if ($showempty) {
$out .= '<option value="0" selected>'.$textifempty.'</option>';
$out .= '<option value="0" selected>'.($textifempty ? $textifempty : '&nbsp;').'</option>';
}
$i = 0;

View File

@ -346,7 +346,7 @@ class Interfaces
}
// We set info of modules
$triggers[$j]['picto'] = $objMod->picto ?img_object('', $objMod->picto, 'class="valignmiddle pictomodule "') : img_object('', 'generic', 'class="valignmiddle pictomodule "');
$triggers[$j]['picto'] = (!empty($objMod->picto)) ? img_object('', $objMod->picto, 'class="valignmiddle pictomodule "') : img_object('', 'generic', 'class="valignmiddle pictomodule "');
$triggers[$j]['file'] = $files[$key];
$triggers[$j]['fullpath'] = $fullpath[$key];
$triggers[$j]['relpath'] = $relpath[$key];
@ -377,7 +377,14 @@ class Interfaces
}
}
} else {
print 'Error: Trigger '.$modName.' does not extends DolibarrTriggers<br>';
$triggers[$j]['picto'] = (!empty($objMod->picto)) ? img_object('', $objMod->picto, 'class="valignmiddle pictomodule "') : img_object('', 'generic', 'class="valignmiddle pictomodule "');
$triggers[$j]['file'] = $files[$key];
$triggers[$j]['fullpath'] = $fullpath[$key];
$triggers[$j]['relpath'] = $relpath[$key];
$triggers[$j]['status'] = img_picto('Error: Trigger '.$modName.' does not extends DolibarrTriggers', 'warning');
//print 'Error: Trigger '.$modName.' does not extends DolibarrTriggers<br>';
$text = 'Error: Trigger '.$modName.' does not extends DolibarrTriggers';
}
} catch (Exception $e) {
print $e->getMessage();

View File

@ -0,0 +1 @@

View File

@ -6322,7 +6322,7 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1,
*/
function dol_string_onlythesehtmlattributes($stringtoclean, $allowed_attributes = array("alt", "class", "contenteditable", "data-html", "href", "id", "name", "src", "style", "target", "title"))
{
if (class_exists('DOMDocument')) {
if (class_exists('DOMDocument') && !empty($stringtoclean)) {
$dom = new DOMDocument();
$dom->loadHTML($stringtoclean, LIBXML_ERR_NONE|LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOXMLDECL);
if (is_object($dom)) {

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -110,7 +110,7 @@ class modZapier extends DolibarrModules
$this->dirs = array("/zapier/temp");
// Config pages. Put here list of php page, stored into zapier/admin directory, to use to setup module.
$this->config_page_url = array(
// "setup.php@zapier"
"setup.php@zapier"
);
// Dependencies
// A condition to hide module
@ -269,53 +269,6 @@ class modZapier extends DolibarrModules
// Main menu entries
$this->menu = array(); // List of menus to add
$r = 0;
// Add here entries to declare new menus
// $this->menu[$r++]=array(
// 'fk_menu' => '', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
// 'type' => 'top', // This is a Top menu entry
// 'titre' => 'Zapier',
// 'mainmenu' => 'zapier',
// 'leftmenu' => '',
// 'url' => '/zapier/zapierindex.php',
// 'langs' => 'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
// 'position' => 1000+$r,
// 'enabled' => '$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled.
// 'perms' => '1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
// 'target' => '',
// 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
// );
/*
$this->menu[$r++]=array(
'fk_menu'=>'fk_mainmenu=zapier', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'type'=>'left', // This is a Left menu entry
'titre'=>'List MyObject',
'mainmenu'=>'zapier',
'leftmenu'=>'zapier_myobject_list',
'url'=>'/zapier/myobject_list.php',
'langs'=>'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>1000+$r,
'enabled'=>'$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
'perms'=>'1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
);
$this->menu[$r++]=array(
'fk_menu'=>'fk_mainmenu=zapier,fk_leftmenu=zapier', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'type'=>'left', // This is a Left menu entry
'titre'=>'New MyObject',
'mainmenu'=>'zapier',
'leftmenu'=>'zapier_myobject_new',
'url'=>'/zapier/myobject_page.php?action=create',
'langs'=>'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>1000+$r,
'enabled'=>'$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
'perms'=>'1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
);
*/
}
/**

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -19,7 +19,7 @@ Module4100Name = Data Privacy Policy
Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR)
#
# Page d'administration
# Administration page
#
datapolicySetup = Module Data Privacy Policy Setup
Deletion = Deletion of data
@ -39,21 +39,21 @@ DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
DATAPOLICY_CONTACT_FOURNISSEUR = Supplier
DATAPOLICY_ADHERENT = Member
DATAPOLICY_Tooltip_SETUP = Type of contact - Indicate your choices for each type.
DATAPOLICYMail=Emails Setup
DATAPOLICYSUBJECTMAIL=Subject of email
DATAPOLICYCONTENTMAIL=Content of the email
DATAPOLICYSUBSITUTION=You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
DATAPOLICYACCEPT=Message after agreement
DATAPOLICYREFUSE=Message after desagreement
SendAgreementText=You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
SendAgreement=Send emails
DATAPOLICYMail = Emails Setup
DATAPOLICYSUBJECTMAIL = Subject of email
DATAPOLICYCONTENTMAIL = Content of the email
DATAPOLICYSUBSITUTION = You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
DATAPOLICYACCEPT = Message after agreement
DATAPOLICYREFUSE = Message after desagreement
SendAgreementText = You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
SendAgreement = Send emails
AllAgreementSend = All emails have been sent
TXTLINKDATAPOLICYACCEPT= Text for the link "agreement"
TXTLINKDATAPOLICYREFUSE= Text for the link "desagreement"
TXTLINKDATAPOLICYACCEPT = Text for the link "agreement"
TXTLINKDATAPOLICYREFUSE = Text for the link "desagreement"
#
# Extrafield
# Extrafields
#
DATAPOLICY_BLOCKCHECKBOX = GDPR : Processing of personal data
DATAPOLICY_consentement = Consent obtained for the processing of personal data
@ -67,26 +67,26 @@ DATAPOLICY_POPUP_ANONYME_TITLE = Anonymize a thirdparty
DATAPOLICY_POPUP_ANONYME_TEXTE = You can not delete this contact from Dolibarr because there are related items. In accordance with the GDPR, you will make all this data anonymous to respect your obligations. Would you like to continue ?
#
# Bouton portabilité
# Button for portability
#
DATAPOLICY_PORTABILITE = Portability GDPR
DATAPOLICY_PORTABILITE_TITLE = Export of personal data
DATAPOLICY_PORTABILITE_CONFIRMATION = You want to export the personal data of this contact. Are you sure ?
#
# Note ajoutés lors d'une anonymisation
# Notes added during an anonymization
#
ANONYMISER_AT = Anonymised the %s
#V2
DATAPOLICYReturn=GDPR Validation
# V2
DATAPOLICYReturn = GDPR Validation
DATAPOLICY_date = Date of agreement/desagreement GDPR
DATAPOLICY_send = Date sending agreement email
DATAPOLICYReturn = GDPR Return
DATAPOLICY_SEND = Send GDPR email
MailSent = Email has been sent
#ERROR
ErrorSubjectIsRequired= Error : The subject of email is required. Indicate it in the module setup
# ERROR
ErrorSubjectIsRequired = Error : The subject of email is required. Indicate it in the module setup
=Due to a technical problem, we were unable to register your choice. We apologize for that. Contact us to send us your choice.
NUMBER_MONTH_BEFORE_DELETION = Number of month before deletion

View File

@ -126,6 +126,12 @@ $permissiondellink = $user->rights->expedition->delivery->creer; // Used by the
$date_delivery = dol_mktime(GETPOST('date_deliveryhour', 'int'), GETPOST('date_deliverymin', 'int'), 0, GETPOST('date_deliverymonth', 'int'), GETPOST('date_deliveryday', 'int'), GETPOST('date_deliveryyear', 'int'));
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
/*
* Actions

View File

@ -41,12 +41,6 @@ $id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $id, '');
$object = new Expedition($db);
if ($id > 0 || !empty($ref)) {
$object->fetch($id, $ref);
@ -69,6 +63,12 @@ if ($id > 0 || !empty($ref)) {
}
}
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
/*
* Actions

View File

@ -45,12 +45,6 @@ $confirm = GETPOST('confirm');
$id = GETPOST('id', 'int');
$ref = GETPOST('ref');
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $id, '');
// Get parameters
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
@ -71,14 +65,21 @@ if (!$sortfield) {
$object = new Expedition($db);
if ($object->fetch($id, $ref)) {
$object->fetch_thirdparty();
$upload_dir = $conf->expedition->dir_output."/sending/".dol_sanitizeFileName($object->ref);
}
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
/*
* Actions
*/
if ($object->fetch($id)) {
$object->fetch_thirdparty();
$upload_dir = $conf->expedition->dir_output."/sending/".dol_sanitizeFileName($object->ref);
}
include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';

View File

@ -39,13 +39,6 @@ $id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); //
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
// Security check
$socid = '';
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, $origin, $origin_id);
$object = new Expedition($db);
if ($id > 0 || !empty($ref)) {
$object->fetch($id, $ref);
@ -66,10 +59,18 @@ if ($id > 0 || !empty($ref)) {
$objectsrc = new Propal($db);
$objectsrc->fetch($object->$typeobject->id);
}
$upload_dir = $conf->expedition->dir_output."/sending/".dol_sanitizeFileName($object->ref);
}
$permissionnote = $user->rights->expedition->creer; // Used by the include of actions_setnotes.inc.php
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
/*
* Actions

View File

@ -73,6 +73,11 @@ $extrafields->fetch_name_optionals_label($object->table_element);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');

View File

@ -39,7 +39,7 @@ if ($user->socid > 0) {
$socid = $user->socid;
}
$nowyear = strftime("%Y", dol_now());
$nowyear = dol_print_date(dol_now(), "%Y");
$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear;
//$startyear=$year-2;
$startyear = $year - 1;
@ -48,6 +48,12 @@ $endyear = $year;
// Load translation files required by the page
$langs->loadLangs(array('sendings', 'other', 'companies'));
// Security check
if ($user->socid) {
$socid = $user->socid;
}
restrictedArea($user, 'expedition');
/*
* View

View File

@ -29,6 +29,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
$year = GETPOST('year', 'int');
// Security check
if ($user->socid) {
$socid = $user->socid;
}
restrictedArea($user, 'expedition');
/*
* View

View File

@ -1,178 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
use
Sabre\DAV\PropPatch;
class AbstractTest extends \PHPUnit_Framework_TestCase {
function testUpdateCalendar() {
$abstract = new AbstractMock();
$propPatch = new PropPatch(['{DAV:}displayname' => 'anything']);
$abstract->updateCalendar('randomid', $propPatch);
$result = $propPatch->commit();
$this->assertFalse($result);
}
function testCalendarQuery() {
$abstract = new AbstractMock();
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
'event1.ics',
], $abstract->calendarQuery(1, $filters));
}
function testGetCalendarObjectByUID() {
$abstract = new AbstractMock();
$this->assertNull(
$abstract->getCalendarObjectByUID('principal1', 'zim')
);
$this->assertEquals(
'cal1/event1.ics',
$abstract->getCalendarObjectByUID('principal1', 'foo')
);
$this->assertNull(
$abstract->getCalendarObjectByUID('principal3', 'foo')
);
$this->assertNull(
$abstract->getCalendarObjectByUID('principal1', 'shared')
);
}
function testGetMultipleCalendarObjects() {
$abstract = new AbstractMock();
$result = $abstract->getMultipleCalendarObjects(1, [
'event1.ics',
'task1.ics',
]);
$expected = [
[
'id' => 1,
'calendarid' => 1,
'uri' => 'event1.ics',
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
],
[
'id' => 2,
'calendarid' => 1,
'uri' => 'task1.ics',
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n",
],
];
$this->assertEquals($expected, $result);
}
}
class AbstractMock extends AbstractBackend {
function getCalendarsForUser($principalUri) {
return [
[
'id' => 1,
'principaluri' => 'principal1',
'uri' => 'cal1',
],
[
'id' => 2,
'principaluri' => 'principal1',
'{http://sabredav.org/ns}owner-principal' => 'principal2',
'uri' => 'cal1',
],
];
}
function createCalendar($principalUri, $calendarUri, array $properties) { }
function deleteCalendar($calendarId) { }
function getCalendarObjects($calendarId) {
switch ($calendarId) {
case 1:
return [
[
'id' => 1,
'calendarid' => 1,
'uri' => 'event1.ics',
],
[
'id' => 2,
'calendarid' => 1,
'uri' => 'task1.ics',
],
];
case 2:
return [
[
'id' => 3,
'calendarid' => 2,
'uri' => 'shared-event.ics',
]
];
}
}
function getCalendarObject($calendarId, $objectUri) {
switch ($objectUri) {
case 'event1.ics' :
return [
'id' => 1,
'calendarid' => 1,
'uri' => 'event1.ics',
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
];
case 'task1.ics' :
return [
'id' => 2,
'calendarid' => 1,
'uri' => 'task1.ics',
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n",
];
case 'shared-event.ics' :
return [
'id' => 3,
'calendarid' => 2,
'uri' => 'event1.ics',
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:shared\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
];
}
}
function createCalendarObject($calendarId, $objectUri, $calendarData) { }
function updateCalendarObject($calendarId, $objectUri, $calendarData) { }
function deleteCalendarObject($calendarId, $objectUri) { }
}

View File

@ -1,258 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV;
use Sabre\DAV;
class Mock extends AbstractBackend {
protected $calendarData;
protected $calendars;
function __construct(array $calendars = [], array $calendarData = []) {
foreach ($calendars as &$calendar) {
if (!isset($calendar['id'])) {
$calendar['id'] = DAV\UUIDUtil::getUUID();
}
}
$this->calendars = $calendars;
$this->calendarData = $calendarData;
}
/**
* Returns a list of calendars for a principal.
*
* Every project is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* calendar. This can be the same as the uri or a database key.
* * uri, which the basename of the uri with which the calendar is
* accessed.
* * principalUri. The owner of the calendar. Almost always the same as
* principalUri passed to this method.
*
* Furthermore it can contain webdav properties in clark notation. A very
* common one is '{DAV:}displayname'.
*
* @param string $principalUri
* @return array
*/
function getCalendarsForUser($principalUri) {
$r = [];
foreach ($this->calendars as $row) {
if ($row['principaluri'] == $principalUri) {
$r[] = $row;
}
}
return $r;
}
/**
* Creates a new calendar for a principal.
*
* If the creation was a success, an id must be returned that can be used to reference
* this calendar in other methods, such as updateCalendar.
*
* This function must return a server-wide unique id that can be used
* later to reference the calendar.
*
* @param string $principalUri
* @param string $calendarUri
* @param array $properties
* @return string|int
*/
function createCalendar($principalUri, $calendarUri, array $properties) {
$id = DAV\UUIDUtil::getUUID();
$this->calendars[] = array_merge([
'id' => $id,
'principaluri' => $principalUri,
'uri' => $calendarUri,
'{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO']),
], $properties);
return $id;
}
/**
* Updates properties for a calendar.
*
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
* To do the actual updates, you must tell this object which properties
* you're going to process with the handle() method.
*
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
* Read the PropPatch documentation for more info and examples.
*
* @param mixed $calendarId
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
$propPatch->handleRemaining(function($props) use ($calendarId) {
foreach ($this->calendars as $k => $calendar) {
if ($calendar['id'] === $calendarId) {
foreach ($props as $propName => $propValue) {
if (is_null($propValue)) {
unset($this->calendars[$k][$propName]);
} else {
$this->calendars[$k][$propName] = $propValue;
}
}
return true;
}
}
});
}
/**
* Delete a calendar and all it's objects
*
* @param string $calendarId
* @return void
*/
function deleteCalendar($calendarId) {
foreach ($this->calendars as $k => $calendar) {
if ($calendar['id'] === $calendarId) {
unset($this->calendars[$k]);
}
}
}
/**
* Returns all calendar objects within a calendar object.
*
* Every item contains an array with the following keys:
* * id - unique identifier which will be used for subsequent updates
* * calendardata - The iCalendar-compatible calendar data
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
* * lastmodified - a timestamp of the last modification time
* * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
* ' "abcdef"')
* * calendarid - The calendarid as it was passed to this function.
*
* Note that the etag is optional, but it's highly encouraged to return for
* speed reasons.
*
* The calendardata is also optional. If it's not returned
* 'getCalendarObject' will be called later, which *is* expected to return
* calendardata.
*
* @param string $calendarId
* @return array
*/
function getCalendarObjects($calendarId) {
if (!isset($this->calendarData[$calendarId]))
return [];
$objects = $this->calendarData[$calendarId];
foreach ($objects as $uri => &$object) {
$object['calendarid'] = $calendarId;
$object['uri'] = $uri;
$object['lastmodified'] = null;
}
return $objects;
}
/**
* Returns information from a single calendar object, based on it's object
* uri.
*
* The object uri is only the basename, or filename and not a full path.
*
* The returned array must have the same keys as getCalendarObjects. The
* 'calendardata' object is required here though, while it's not required
* for getCalendarObjects.
*
* This method must return null if the object did not exist.
*
* @param mixed $calendarId
* @param string $objectUri
* @return array|null
*/
function getCalendarObject($calendarId, $objectUri) {
if (!isset($this->calendarData[$calendarId][$objectUri])) {
return null;
}
$object = $this->calendarData[$calendarId][$objectUri];
$object['calendarid'] = $calendarId;
$object['uri'] = $objectUri;
$object['lastmodified'] = null;
return $object;
}
/**
* Creates a new calendar object.
*
* @param string $calendarId
* @param string $objectUri
* @param string $calendarData
* @return void
*/
function createCalendarObject($calendarId, $objectUri, $calendarData) {
$this->calendarData[$calendarId][$objectUri] = [
'calendardata' => $calendarData,
'calendarid' => $calendarId,
'uri' => $objectUri,
];
return '"' . md5($calendarData) . '"';
}
/**
* Updates an existing calendarobject, based on it's uri.
*
* @param string $calendarId
* @param string $objectUri
* @param string $calendarData
* @return void
*/
function updateCalendarObject($calendarId, $objectUri, $calendarData) {
$this->calendarData[$calendarId][$objectUri] = [
'calendardata' => $calendarData,
'calendarid' => $calendarId,
'uri' => $objectUri,
];
return '"' . md5($calendarData) . '"';
}
/**
* Deletes an existing calendar object.
*
* @param string $calendarId
* @param string $objectUri
* @return void
*/
function deleteCalendarObject($calendarId, $objectUri) {
unset($this->calendarData[$calendarId][$objectUri]);
}
}

View File

@ -1,91 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
class MockScheduling extends Mock implements SchedulingSupport {
public $schedulingObjects = [];
/**
* Returns a single scheduling object.
*
* The returned array should contain the following elements:
* * uri - A unique basename for the object. This will be used to
* construct a full uri.
* * calendardata - The iCalendar object
* * lastmodified - The last modification date. Can be an int for a unix
* timestamp, or a PHP DateTime object.
* * etag - A unique token that must change if the object changed.
* * size - The size of the object, in bytes.
*
* @param string $principalUri
* @param string $objectUri
* @return array
*/
function getSchedulingObject($principalUri, $objectUri) {
if (isset($this->schedulingObjects[$principalUri][$objectUri])) {
return $this->schedulingObjects[$principalUri][$objectUri];
}
}
/**
* Returns all scheduling objects for the inbox collection.
*
* These objects should be returned as an array. Every item in the array
* should follow the same structure as returned from getSchedulingObject.
*
* The main difference is that 'calendardata' is optional.
*
* @param string $principalUri
* @return array
*/
function getSchedulingObjects($principalUri) {
if (isset($this->schedulingObjects[$principalUri])) {
return array_values($this->schedulingObjects[$principalUri]);
}
return [];
}
/**
* Deletes a scheduling object
*
* @param string $principalUri
* @param string $objectUri
* @return void
*/
function deleteSchedulingObject($principalUri, $objectUri) {
if (isset($this->schedulingObjects[$principalUri][$objectUri])) {
unset($this->schedulingObjects[$principalUri][$objectUri]);
}
}
/**
* Creates a new scheduling object. This should land in a users' inbox.
*
* @param string $principalUri
* @param string $objectUri
* @param string $objectData;
* @return void
*/
function createSchedulingObject($principalUri, $objectUri, $objectData) {
if (!isset($this->schedulingObjects[$principalUri])) {
$this->schedulingObjects[$principalUri] = [];
}
$this->schedulingObjects[$principalUri][$objectUri] = [
'uri' => $objectUri,
'calendardata' => $objectData,
'lastmodified' => null,
'etag' => '"' . md5($objectData) . '"',
'size' => strlen($objectData)
];
}
}

View File

@ -1,204 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
use Sabre\DAV;
class MockSharing extends Mock implements NotificationSupport, SharingSupport {
private $shares = [];
private $notifications;
function __construct(array $calendars = [], array $calendarData = [], array $notifications = []) {
parent::__construct($calendars, $calendarData);
$this->notifications = $notifications;
}
/**
* Returns a list of calendars for a principal.
*
* Every project is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* calendar. This can be the same as the uri or a database key.
* * uri, which the basename of the uri with which the calendar is
* accessed.
* * principalUri. The owner of the calendar. Almost always the same as
* principalUri passed to this method.
*
* Furthermore it can contain webdav properties in clark notation. A very
* common one is '{DAV:}displayname'.
*
* @param string $principalUri
* @return array
*/
function getCalendarsForUser($principalUri) {
$calendars = parent::getCalendarsForUser($principalUri);
foreach ($calendars as $k => $calendar) {
if (isset($calendar['share-access'])) {
continue;
}
if (!empty($this->shares[$calendar['id']])) {
$calendar['share-access'] = DAV\Sharing\Plugin::ACCESS_SHAREDOWNER;
} else {
$calendar['share-access'] = DAV\Sharing\Plugin::ACCESS_NOTSHARED;
}
$calendars[$k] = $calendar;
}
return $calendars;
}
/**
* Returns a list of notifications for a given principal url.
*
* The returned array should only consist of implementations of
* Sabre\CalDAV\Notifications\INotificationType.
*
* @param string $principalUri
* @return array
*/
function getNotificationsForPrincipal($principalUri) {
if (isset($this->notifications[$principalUri])) {
return $this->notifications[$principalUri];
}
return [];
}
/**
* This deletes a specific notifcation.
*
* This may be called by a client once it deems a notification handled.
*
* @param string $principalUri
* @param NotificationInterface $notification
* @return void
*/
function deleteNotification($principalUri, NotificationInterface $notification) {
foreach ($this->notifications[$principalUri] as $key => $value) {
if ($notification === $value) {
unset($this->notifications[$principalUri][$key]);
}
}
}
/**
* Updates the list of shares.
*
* @param mixed $calendarId
* @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
* @return void
*/
function updateInvites($calendarId, array $sharees) {
if (!isset($this->shares[$calendarId])) {
$this->shares[$calendarId] = [];
}
foreach ($sharees as $sharee) {
$existingKey = null;
foreach ($this->shares[$calendarId] as $k => $existingSharee) {
if ($sharee->href === $existingSharee->href) {
$existingKey = $k;
}
}
// Just making sure we're not affecting an existing copy.
$sharee = clone $sharee;
$sharee->inviteStatus = DAV\Sharing\Plugin::INVITE_NORESPONSE;
if ($sharee->access === DAV\Sharing\Plugin::ACCESS_NOACCESS) {
// It's a removal
unset($this->shares[$calendarId][$existingKey]);
} elseif ($existingKey) {
// It's an update
$this->shares[$calendarId][$existingKey] = $sharee;
} else {
// It's an addition
$this->shares[$calendarId][] = $sharee;
}
}
// Re-numbering keys
$this->shares[$calendarId] = array_values($this->shares[$calendarId]);
}
/**
* Returns the list of people whom this calendar is shared with.
*
* Every item in the returned list must be a Sharee object with at
* least the following properties set:
* $href
* $shareAccess
* $inviteStatus
*
* and optionally:
* $properties
*
* @param mixed $calendarId
* @return \Sabre\DAV\Xml\Element\Sharee[]
*/
function getInvites($calendarId) {
if (!isset($this->shares[$calendarId])) {
return [];
}
return $this->shares[$calendarId];
}
/**
* This method is called when a user replied to a request to share.
*
* @param string href The sharee who is replying (often a mailto: address)
* @param int status One of the \Sabre\DAV\Sharing\Plugin::INVITE_* constants
* @param string $calendarUri The url to the calendar thats being shared
* @param string $inReplyTo The unique id this message is a response to
* @param string $summary A description of the reply
* @return void
*/
function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {
// This operation basically doesn't do anything yet
if ($status === DAV\Sharing\Plugin::INVITE_ACCEPTED) {
return 'calendars/blabla/calendar';
}
}
/**
* Publishes a calendar
*
* @param mixed $calendarId
* @param bool $value
* @return void
*/
function setPublishStatus($calendarId, $value) {
foreach ($this->calendars as $k => $cal) {
if ($cal['id'] === $calendarId) {
if (!$value) {
unset($cal['{http://calendarserver.org/ns/}publish-url']);
} else {
$cal['{http://calendarserver.org/ns/}publish-url'] = 'http://example.org/public/ ' . $calendarId . '.ics';
}
return;
}
}
throw new DAV\Exception('Calendar with id "' . $calendarId . '" not found');
}
}

View File

@ -1,156 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV;
use Sabre\DAV;
/**
* This is a mock CalDAV backend that supports subscriptions.
*
* All data is retained in memory temporarily. It's primary purpose is
* unit-tests.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class MockSubscriptionSupport extends Mock implements SubscriptionSupport {
/**
* Subscription list
*
* @var array
*/
protected $subs = [];
/**
* Returns a list of subscriptions for a principal.
*
* Every subscription is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* subscription. This can be the same as the uri or a database key.
* * uri. This is just the 'base uri' or 'filename' of the subscription.
* * principaluri. The owner of the subscription. Almost always the same as
* principalUri passed to this method.
* * source. Url to the actual feed
*
* Furthermore, all the subscription info must be returned too:
*
* 1. {DAV:}displayname
* 2. {http://apple.com/ns/ical/}refreshrate
* 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos
* should not be stripped).
* 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms
* should not be stripped).
* 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if
* attachments should not be stripped).
* 7. {http://apple.com/ns/ical/}calendar-color
* 8. {http://apple.com/ns/ical/}calendar-order
*
* @param string $principalUri
* @return array
*/
function getSubscriptionsForUser($principalUri) {
if (isset($this->subs[$principalUri])) {
return $this->subs[$principalUri];
}
return [];
}
/**
* Creates a new subscription for a principal.
*
* If the creation was a success, an id must be returned that can be used to reference
* this subscription in other methods, such as updateSubscription.
*
* @param string $principalUri
* @param string $uri
* @param array $properties
* @return mixed
*/
function createSubscription($principalUri, $uri, array $properties) {
$properties['uri'] = $uri;
$properties['principaluri'] = $principalUri;
$properties['source'] = $properties['{http://calendarserver.org/ns/}source']->getHref();
if (!isset($this->subs[$principalUri])) {
$this->subs[$principalUri] = [];
}
$id = [$principalUri, count($this->subs[$principalUri]) + 1];
$properties['id'] = $id;
$this->subs[$principalUri][] = array_merge($properties, [
'id' => $id,
]);
return $id;
}
/**
* Updates a subscription
*
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
* To do the actual updates, you must tell this object which properties
* you're going to process with the handle() method.
*
* Calling the handle method is like telling the PropPatch object "I
* promise I can handle updating this property".
*
* Read the PropPatch documentation for more info and examples.
*
* @param mixed $subscriptionId
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) {
$found = null;
foreach ($this->subs[$subscriptionId[0]] as &$sub) {
if ($sub['id'][1] === $subscriptionId[1]) {
$found = & $sub;
break;
}
}
if (!$found) return;
$propPatch->handleRemaining(function($mutations) use (&$found) {
foreach ($mutations as $k => $v) {
$found[$k] = $v;
}
return true;
});
}
/**
* Deletes a subscription
*
* @param mixed $subscriptionId
* @return void
*/
function deleteSubscription($subscriptionId) {
foreach ($this->subs[$subscriptionId[0]] as $index => $sub) {
if ($sub['id'][1] === $subscriptionId[1]) {
unset($this->subs[$subscriptionId[0]][$index]);
return true;
}
}
return false;
}
}

View File

@ -1,9 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
class PDOMySQLTest extends AbstractPDOTest {
public $driver = 'mysql';
}

View File

@ -1,9 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
class PDOPgSqlTest extends AbstractPDOTest {
public $driver = 'pgsql';
}

View File

@ -1,9 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
class PDOSqliteTest extends AbstractPDOTest {
public $driver = 'sqlite';
}

View File

@ -1,445 +0,0 @@
<?php
namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\PropPatch;
class SimplePDOTest extends \PHPUnit_Framework_TestCase {
protected $pdo;
function setUp() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
unlink(SABRE_TEMPDIR . '/testdb.sqlite');
$pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->exec(<<<SQL
CREATE TABLE simple_calendars (
id INTEGER PRIMARY KEY ASC NOT NULL,
uri TEXT NOT NULL,
principaluri TEXT NOT NULL
)
SQL
);
$pdo->exec(<<<SQL
CREATE TABLE simple_calendarobjects (
id INTEGER PRIMARY KEY ASC NOT NULL,
calendarid INT UNSIGNED NOT NULL,
uri TEXT NOT NULL,
calendardata TEXT
);
SQL
);
$this->pdo = $pdo;
}
function testConstruct() {
$backend = new SimplePDO($this->pdo);
$this->assertTrue($backend instanceof SimplePDO);
}
/**
* @depends testConstruct
*/
function testGetCalendarsForUserNoCalendars() {
$backend = new SimplePDO($this->pdo);
$calendars = $backend->getCalendarsForUser('principals/user2');
$this->assertEquals([], $calendars);
}
/**
* @depends testConstruct
*/
function testCreateCalendarAndFetch() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
'{DAV:}displayname' => 'Hello!',
'{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
]);
$calendars = $backend->getCalendarsForUser('principals/user2');
$elementCheck = [
'uri' => 'somerandomid',
];
$this->assertInternalType('array', $calendars);
$this->assertEquals(1, count($calendars));
foreach ($elementCheck as $name => $value) {
$this->assertArrayHasKey($name, $calendars[0]);
$this->assertEquals($value, $calendars[0][$name]);
}
}
/**
* @depends testConstruct
*/
function testUpdateCalendarAndFetch() {
$backend = new SimplePDO($this->pdo);
//Creating a new calendar
$newId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$propPatch = new PropPatch([
'{DAV:}displayname' => 'myCalendar',
'{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
]);
// Updating the calendar
$backend->updateCalendar($newId, $propPatch);
$result = $propPatch->commit();
// Verifying the result of the update
$this->assertFalse($result);
}
/**
* @depends testCreateCalendarAndFetch
*/
function testDeleteCalendar() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
'{DAV:}displayname' => 'Hello!',
]);
$backend->deleteCalendar($returnedId);
$calendars = $backend->getCalendarsForUser('principals/user2');
$this->assertEquals([], $calendars);
}
function testCreateCalendarObject() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
$result = $this->pdo->query('SELECT calendardata FROM simple_calendarobjects WHERE uri = "random-id"');
$this->assertEquals([
'calendardata' => $object,
], $result->fetch(\PDO::FETCH_ASSOC));
}
function testGetMultipleObjects() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'id-1', $object);
$backend->createCalendarObject($returnedId, 'id-2', $object);
$check = [
[
'id' => 1,
'etag' => '"' . md5($object) . '"',
'uri' => 'id-1',
'size' => strlen($object),
'calendardata' => $object,
],
[
'id' => 2,
'etag' => '"' . md5($object) . '"',
'uri' => 'id-2',
'size' => strlen($object),
'calendardata' => $object,
],
];
$result = $backend->getMultipleCalendarObjects($returnedId, ['id-1', 'id-2']);
foreach ($check as $index => $props) {
foreach ($props as $key => $value) {
if ($key !== 'lastmodified') {
$this->assertEquals($value, $result[$index][$key]);
} else {
$this->assertTrue(isset($result[$index][$key]));
}
}
}
}
/**
* @depends testCreateCalendarObject
*/
function testGetCalendarObjects() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
$data = $backend->getCalendarObjects($returnedId);
$this->assertEquals(1, count($data));
$data = $data[0];
$this->assertEquals('random-id', $data['uri']);
$this->assertEquals(strlen($object), $data['size']);
}
/**
* @depends testCreateCalendarObject
*/
function testGetCalendarObjectByUID() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
$this->assertNull(
$backend->getCalendarObjectByUID('principals/user2', 'bar')
);
$this->assertEquals(
'somerandomid/random-id',
$backend->getCalendarObjectByUID('principals/user2', 'foo')
);
}
/**
* @depends testCreateCalendarObject
*/
function testUpdateCalendarObject() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$object2 = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20130101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
$backend->updateCalendarObject($returnedId, 'random-id', $object2);
$data = $backend->getCalendarObject($returnedId, 'random-id');
$this->assertEquals($object2, $data['calendardata']);
$this->assertEquals('random-id', $data['uri']);
}
/**
* @depends testCreateCalendarObject
*/
function testDeleteCalendarObject() {
$backend = new SimplePDO($this->pdo);
$returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
$backend->deleteCalendarObject($returnedId, 'random-id');
$data = $backend->getCalendarObject($returnedId, 'random-id');
$this->assertNull($data);
}
function testCalendarQueryNoResult() {
$abstract = new SimplePDO($this->pdo);
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VJOURNAL',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
], $abstract->calendarQuery(1, $filters));
}
function testCalendarQueryTodo() {
$backend = new SimplePDO($this->pdo);
$backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VTODO',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
"todo",
], $backend->calendarQuery(1, $filters));
}
function testCalendarQueryTodoNotMatch() {
$backend = new SimplePDO($this->pdo);
$backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VTODO',
'comp-filters' => [],
'prop-filters' => [
[
'name' => 'summary',
'text-match' => null,
'time-range' => null,
'param-filters' => [],
'is-not-defined' => false,
],
],
'is-not-defined' => false,
'time-range' => null,
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
], $backend->calendarQuery(1, $filters));
}
function testCalendarQueryNoFilter() {
$backend = new SimplePDO($this->pdo);
$backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$result = $backend->calendarQuery(1, $filters);
$this->assertTrue(in_array('todo', $result));
$this->assertTrue(in_array('event', $result));
}
function testCalendarQueryTimeRange() {
$backend = new SimplePDO($this->pdo);
$backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('20120103'),
'end' => new \DateTime('20120104'),
],
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
"event2",
], $backend->calendarQuery(1, $filters));
}
function testCalendarQueryTimeRangeNoEnd() {
$backend = new SimplePDO($this->pdo);
$backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('20120102'),
'end' => null,
],
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$this->assertEquals([
"event2",
], $backend->calendarQuery(1, $filters));
}
}

View File

@ -1,49 +0,0 @@
<?php
namespace Sabre\CalDAV;
class CalendarHomeNotificationsTest extends \PHPUnit_Framework_TestCase {
function testGetChildrenNoSupport() {
$backend = new Backend\Mock();
$calendarHome = new CalendarHome($backend, ['uri' => 'principals/user']);
$this->assertEquals(
[],
$calendarHome->getChildren()
);
}
/**
* @expectedException \Sabre\DAV\Exception\NotFound
*/
function testGetChildNoSupport() {
$backend = new Backend\Mock();
$calendarHome = new CalendarHome($backend, ['uri' => 'principals/user']);
$calendarHome->getChild('notifications');
}
function testGetChildren() {
$backend = new Backend\MockSharing();
$calendarHome = new CalendarHome($backend, ['uri' => 'principals/user']);
$result = $calendarHome->getChildren();
$this->assertEquals('notifications', $result[0]->getName());
}
function testGetChild() {
$backend = new Backend\MockSharing();
$calendarHome = new CalendarHome($backend, ['uri' => 'principals/user']);
$result = $calendarHome->getChild('notifications');
$this->assertEquals('notifications', $result->getName());
}
}

View File

@ -1,80 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV;
class CalendarHomeSharedCalendarsTest extends \PHPUnit_Framework_TestCase {
protected $backend;
function getInstance() {
$calendars = [
[
'id' => 1,
'principaluri' => 'principals/user1',
],
[
'id' => 2,
'{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/cal1',
'{http://sabredav.org/ns}owner-principal' => 'principal/owner',
'{http://sabredav.org/ns}read-only' => false,
'principaluri' => 'principals/user1',
],
];
$this->backend = new Backend\MockSharing(
$calendars,
[],
[]
);
return new CalendarHome($this->backend, [
'uri' => 'principals/user1'
]);
}
function testSimple() {
$instance = $this->getInstance();
$this->assertEquals('user1', $instance->getName());
}
function testGetChildren() {
$instance = $this->getInstance();
$children = $instance->getChildren();
$this->assertEquals(3, count($children));
// Testing if we got all the objects back.
$sharedCalendars = 0;
$hasOutbox = false;
$hasNotifications = false;
foreach ($children as $child) {
if ($child instanceof ISharedCalendar) {
$sharedCalendars++;
}
if ($child instanceof Notifications\ICollection) {
$hasNotifications = true;
}
}
$this->assertEquals(2, $sharedCalendars);
$this->assertTrue($hasNotifications);
}
function testShareReply() {
$instance = $this->getInstance();
$result = $instance->shareReply('uri', DAV\Sharing\Plugin::INVITE_DECLINED, 'curi', '1');
$this->assertNull($result);
}
}

View File

@ -1,85 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV\MkCol;
class CalendarHomeSubscriptionsTest extends \PHPUnit_Framework_TestCase {
protected $backend;
function getInstance() {
$props = [
'{DAV:}displayname' => 'baz',
'{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/test.ics'),
];
$principal = [
'uri' => 'principals/user1'
];
$this->backend = new Backend\MockSubscriptionSupport([], []);
$this->backend->createSubscription('principals/user1', 'uri', $props);
return new CalendarHome($this->backend, $principal);
}
function testSimple() {
$instance = $this->getInstance();
$this->assertEquals('user1', $instance->getName());
}
function testGetChildren() {
$instance = $this->getInstance();
$children = $instance->getChildren();
$this->assertEquals(1, count($children));
foreach ($children as $child) {
if ($child instanceof Subscriptions\Subscription) {
return;
}
}
$this->fail('There were no subscription nodes in the calendar home');
}
function testCreateSubscription() {
$instance = $this->getInstance();
$rt = ['{DAV:}collection', '{http://calendarserver.org/ns/}subscribed'];
$props = [
'{DAV:}displayname' => 'baz',
'{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/test2.ics'),
];
$instance->createExtendedCollection('sub2', new MkCol($rt, $props));
$children = $instance->getChildren();
$this->assertEquals(2, count($children));
}
/**
* @expectedException \Sabre\DAV\Exception\InvalidResourceType
*/
function testNoSubscriptionSupport() {
$principal = [
'uri' => 'principals/user1'
];
$backend = new Backend\Mock([], []);
$uC = new CalendarHome($backend, $principal);
$rt = ['{DAV:}collection', '{http://calendarserver.org/ns/}subscribed'];
$props = [
'{DAV:}displayname' => 'baz',
'{http://calendarserver.org/ns/}source' => new \Sabre\DAV\Xml\Property\Href('http://example.org/test2.ics'),
];
$uC->createExtendedCollection('sub2', new MkCol($rt, $props));
}
}

View File

@ -1,215 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\MkCol;
class CalendarHomeTest extends \PHPUnit_Framework_TestCase {
/**
* @var Sabre\CalDAV\CalendarHome
*/
protected $usercalendars;
/**
* @var Backend\BackendInterface
*/
protected $backend;
function setup() {
$this->backend = TestUtil::getBackend();
$this->usercalendars = new CalendarHome($this->backend, [
'uri' => 'principals/user1'
]);
}
function testSimple() {
$this->assertEquals('user1', $this->usercalendars->getName());
}
/**
* @expectedException Sabre\DAV\Exception\NotFound
* @depends testSimple
*/
function testGetChildNotFound() {
$this->usercalendars->getChild('randomname');
}
function testChildExists() {
$this->assertFalse($this->usercalendars->childExists('foo'));
$this->assertTrue($this->usercalendars->childExists('UUID-123467'));
}
function testGetOwner() {
$this->assertEquals('principals/user1', $this->usercalendars->getOwner());
}
function testGetGroup() {
$this->assertNull($this->usercalendars->getGroup());
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
];
$this->assertEquals($expected, $this->usercalendars->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$this->usercalendars->setACL([]);
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
* @depends testSimple
*/
function testSetName() {
$this->usercalendars->setName('bla');
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
* @depends testSimple
*/
function testDelete() {
$this->usercalendars->delete();
}
/**
* @depends testSimple
*/
function testGetLastModified() {
$this->assertNull($this->usercalendars->getLastModified());
}
/**
* @expectedException \Sabre\DAV\Exception\MethodNotAllowed
* @depends testSimple
*/
function testCreateFile() {
$this->usercalendars->createFile('bla');
}
/**
* @expectedException Sabre\DAV\Exception\MethodNotAllowed
* @depends testSimple
*/
function testCreateDirectory() {
$this->usercalendars->createDirectory('bla');
}
/**
* @depends testSimple
*/
function testCreateExtendedCollection() {
$mkCol = new MkCol(
['{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar'],
[]
);
$result = $this->usercalendars->createExtendedCollection('newcalendar', $mkCol);
$this->assertNull($result);
$cals = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(3, count($cals));
}
/**
* @expectedException Sabre\DAV\Exception\InvalidResourceType
* @depends testSimple
*/
function testCreateExtendedCollectionBadResourceType() {
$mkCol = new MkCol(
['{DAV:}collection', '{DAV:}blabla'],
[]
);
$this->usercalendars->createExtendedCollection('newcalendar', $mkCol);
}
/**
* @expectedException Sabre\DAV\Exception\InvalidResourceType
* @depends testSimple
*/
function testCreateExtendedCollectionNotACalendar() {
$mkCol = new MkCol(
['{DAV:}collection'],
[]
);
$this->usercalendars->createExtendedCollection('newcalendar', $mkCol);
}
function testGetSupportedPrivilegesSet() {
$this->assertNull($this->usercalendars->getSupportedPrivilegeSet());
}
/**
* @expectedException Sabre\DAV\Exception\NotImplemented
*/
function testShareReplyFail() {
$this->usercalendars->shareReply('uri', DAV\Sharing\Plugin::INVITE_DECLINED, 'curi', '1');
}
}

View File

@ -1,383 +0,0 @@
<?php
namespace Sabre\CalDAV;
require_once 'Sabre/CalDAV/TestUtil.php';
class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
/**
* @var Sabre\CalDAV\Backend_PDO
*/
protected $backend;
/**
* @var Sabre\CalDAV\Calendar
*/
protected $calendar;
protected $principalBackend;
function setup() {
$this->backend = TestUtil::getBackend();
$calendars = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(2, count($calendars));
$this->calendar = new Calendar($this->backend, $calendars[0]);
}
function teardown() {
unset($this->calendar);
unset($this->backend);
}
function testSetup() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$this->assertInternalType('string', $children[0]->getName());
$this->assertInternalType('string', $children[0]->get());
$this->assertInternalType('string', $children[0]->getETag());
$this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType());
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg1() {
$obj = new CalendarObject(
new Backend\Mock([], []),
[],
[]
);
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg2() {
$obj = new CalendarObject(
new Backend\Mock([], []),
[],
['calendarid' => '1']
);
}
/**
* @depends testSetup
*/
function testPut() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$newData = TestUtil::getTestCalendarData();
$children[0]->put($newData);
$this->assertEquals($newData, $children[0]->get());
}
/**
* @depends testSetup
*/
function testPutStream() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$newData = TestUtil::getTestCalendarData();
$stream = fopen('php://temp', 'r+');
fwrite($stream, $newData);
rewind($stream);
$children[0]->put($stream);
$this->assertEquals($newData, $children[0]->get());
}
/**
* @depends testSetup
*/
function testDelete() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$obj->delete();
$children2 = $this->calendar->getChildren();
$this->assertEquals(count($children) - 1, count($children2));
}
/**
* @depends testSetup
*/
function testGetLastModified() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$lastMod = $obj->getLastModified();
$this->assertTrue(is_int($lastMod) || ctype_digit($lastMod) || is_null($lastMod));
}
/**
* @depends testSetup
*/
function testGetSize() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$size = $obj->getSize();
$this->assertInternalType('int', $size);
}
function testGetOwner() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$this->assertEquals('principals/user1', $obj->getOwner());
}
function testGetGroup() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$this->assertNull($obj->getGroup());
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
];
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$this->assertEquals($expected, $obj->getACL());
}
function testDefaultACL() {
$backend = new Backend\Mock([], []);
$calendarObject = new CalendarObject($backend, ['principaluri' => 'principals/user1'], ['calendarid' => 1, 'uri' => 'foo']);
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}all',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
];
$this->assertEquals($expected, $calendarObject->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$obj->setACL([]);
}
function testGet() {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
$expected = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//iCal 4.0.1//EN
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Asia/Seoul
BEGIN:DAYLIGHT
TZOFFSETFROM:+0900
RRULE:FREQ=YEARLY;UNTIL=19880507T150000Z;BYMONTH=5;BYDAY=2SU
DTSTART:19870510T000000
TZNAME:GMT+09:00
TZOFFSETTO:+1000
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+1000
DTSTART:19881009T000000
TZNAME:GMT+09:00
TZOFFSETTO:+0900
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20100225T154229Z
UID:39A6B5ED-DD51-4AFE-A683-C35EE3749627
TRANSP:TRANSPARENT
SUMMARY:Something here
DTSTAMP:20100228T130202Z
DTSTART;TZID=Asia/Seoul:20100223T060000
DTEND;TZID=Asia/Seoul:20100223T070000
ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
SEQUENCE:2
END:VEVENT
END:VCALENDAR";
$this->assertEquals($expected, $obj->get());
}
function testGetRefetch() {
$backend = new Backend\Mock([], [
1 => [
'foo' => [
'calendardata' => 'foo',
'uri' => 'foo'
],
]
]);
$obj = new CalendarObject($backend, ['id' => 1], ['uri' => 'foo']);
$this->assertEquals('foo', $obj->get());
}
function testGetEtag1() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'etag' => 'bar',
'calendarid' => 1
];
$backend = new Backend\Mock([], []);
$obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals('bar', $obj->getETag());
}
function testGetEtag2() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\Mock([], []);
$obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
}
function testGetSupportedPrivilegesSet() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\Mock([], []);
$obj = new CalendarObject($backend, [], $objectInfo);
$this->assertNull($obj->getSupportedPrivilegeSet());
}
function testGetSize1() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\Mock([], []);
$obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals(3, $obj->getSize());
}
function testGetSize2() {
$objectInfo = [
'uri' => 'foo',
'calendarid' => 1,
'size' => 4,
];
$backend = new Backend\Mock([], []);
$obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals(4, $obj->getSize());
}
}

View File

@ -1,122 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\VObject;
class CalendarQueryVAlarmTest extends \PHPUnit_Framework_TestCase {
/**
* This test is specifically for a time-range query on a VALARM, contained
* in a VEVENT that's recurring
*/
function testValarm() {
$vcalendar = new VObject\Component\VCalendar();
$vevent = $vcalendar->createComponent('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = $vcalendar->createComponent('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar->add($vevent);
$filter = [
'name' => 'VCALENDAR',
'is-not-defined' => false,
'time-range' => null,
'prop-filters' => [],
'comp-filters' => [
[
'name' => 'VEVENT',
'is-not-defined' => false,
'time-range' => null,
'prop-filters' => [],
'comp-filters' => [
[
'name' => 'VALARM',
'is-not-defined' => false,
'prop-filters' => [],
'comp-filters' => [],
'time-range' => [
'start' => new \DateTime('2012-05-10'),
'end' => new \DateTime('2012-05-20'),
],
],
],
],
],
];
$validator = new CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
$vcalendar = new VObject\Component\VCalendar();
// A limited recurrence rule, should return false
$vevent = $vcalendar->createComponent('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY;COUNT=1';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = $vcalendar->createComponent('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar->add($vevent);
$this->assertFalse($validator->validate($vcalendar, $filter));
}
function testAlarmWayBefore() {
$vcalendar = new VObject\Component\VCalendar();
$vevent = $vcalendar->createComponent('VEVENT');
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = $vcalendar->createComponent('VALARM');
$valarm->TRIGGER = '-P2W1D';
$vevent->add($valarm);
$vcalendar->add($vevent);
$filter = [
'name' => 'VCALENDAR',
'is-not-defined' => false,
'time-range' => null,
'prop-filters' => [],
'comp-filters' => [
[
'name' => 'VEVENT',
'is-not-defined' => false,
'time-range' => null,
'prop-filters' => [],
'comp-filters' => [
[
'name' => 'VALARM',
'is-not-defined' => false,
'prop-filters' => [],
'comp-filters' => [],
'time-range' => [
'start' => new \DateTime('2011-12-10'),
'end' => new \DateTime('2011-12-20'),
],
],
],
],
],
];
$validator = new CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
}
}

View File

@ -1,829 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\VObject;
class CalendarQueryValidatorTest extends \PHPUnit_Framework_TestCase {
function testTopLevelFail() {
$validator = new CalendarQueryValidator();
$vcal = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
END:VEVENT
END:VCALENDAR
ICS;
$vcal = VObject\Reader::read($vcal);
$this->assertFalse($validator->validate($vcal, ['name' => 'VFOO']));
}
/**
* @param string $icalObject
* @param array $filters
* @param int $outcome
* @dataProvider provider
*/
function testValid($icalObject, $filters, $outcome) {
$validator = new CalendarQueryValidator();
// Wrapping filter in a VCALENDAR component filter, as this is always
// there anyway.
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [$filters],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$vObject = VObject\Reader::read($icalObject);
switch ($outcome) {
case 0 :
$this->assertFalse($validator->validate($vObject, $filters));
break;
case 1 :
$this->assertTrue($validator->validate($vObject, $filters));
break;
case -1 :
try {
$validator->validate($vObject, $filters);
$this->fail('This test was supposed to fail');
} catch (\Exception $e) {
// We need to test something to be valid for phpunit strict
// mode.
$this->assertTrue(true);
} catch (\Throwable $e) {
// PHP7
$this->assertTrue(true);
}
break;
}
}
function provider() {
$blob1 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
SUMMARY:hi
END:VEVENT
END:VCALENDAR
yow;
$blob2 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
SUMMARY:hi
BEGIN:VALARM
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob3 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
SUMMARY:hi
DTSTART;VALUE=DATE:20110704
END:VEVENT
END:VCALENDAR
yow;
$blob4 = <<<yow
BEGIN:VCARD
VERSION:3.0
FN:Evert
END:VCARD
yow;
$blob5 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DTEND:20110102T120000Z
END:VEVENT
END:VCALENDAR
yow;
$blob6 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DURATION:PT5H
END:VEVENT
END:VCALENDAR
yow;
$blob7 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;VALUE=DATE:20110101
END:VEVENT
END:VCALENDAR
yow;
$blob8 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
END:VEVENT
END:VCALENDAR
yow;
$blob9 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
DTSTART:20110101T120000Z
DURATION:PT1H
END:VTODO
END:VCALENDAR
yow;
$blob10 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
DTSTART:20110101T120000Z
DUE:20110101T130000Z
END:VTODO
END:VCALENDAR
yow;
$blob11 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
DTSTART:20110101T120000Z
END:VTODO
END:VCALENDAR
yow;
$blob12 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
DUE:20110101T130000Z
END:VTODO
END:VCALENDAR
yow;
$blob13 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
COMPLETED:20110101T130000Z
CREATED:20110101T110000Z
END:VTODO
END:VCALENDAR
yow;
$blob14 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
COMPLETED:20110101T130000Z
END:VTODO
END:VCALENDAR
yow;
$blob15 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
CREATED:20110101T110000Z
END:VTODO
END:VCALENDAR
yow;
$blob16 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
END:VTODO
END:VCALENDAR
yow;
$blob17 = <<<yow
BEGIN:VCALENDAR
BEGIN:VJOURNAL
END:VJOURNAL
END:VCALENDAR
yow;
$blob18 = <<<yow
BEGIN:VCALENDAR
BEGIN:VJOURNAL
DTSTART:20110101T120000Z
END:VJOURNAL
END:VCALENDAR
yow;
$blob19 = <<<yow
BEGIN:VCALENDAR
BEGIN:VJOURNAL
DTSTART;VALUE=DATE:20110101
END:VJOURNAL
END:VCALENDAR
yow;
$blob20 = <<<yow
BEGIN:VCALENDAR
BEGIN:VFREEBUSY
END:VFREEBUSY
END:VCALENDAR
yow;
$blob21 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
BEGIN:VALARM
TRIGGER:-PT1H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob22 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
BEGIN:VALARM
TRIGGER;VALUE=DURATION:-PT1H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob23 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
BEGIN:VALARM
TRIGGER;VALUE=DURATION;RELATED=END:-PT1H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob24 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DTEND:20110101T130000Z
BEGIN:VALARM
TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob25 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DURATION:PT1H
BEGIN:VALARM
TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob26 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DURATION:PT1H
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20110101T110000Z
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob27 = <<<yow
BEGIN:VCALENDAR
BEGIN:VTODO
DTSTART:20110101T120000Z
DUE:20110101T130000Z
BEGIN:VALARM
TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
END:VALARM
END:VTODO
END:VCALENDAR
yow;
$blob28 = <<<yow
BEGIN:VCALENDAR
BEGIN:VJOURNAL
DTSTART:20110101T120000Z
BEGIN:VALARM
TRIGGER;VALUE=DURATION;RELATED=END:-PT2H
END:VALARM
END:VJOURNAL
END:VCALENDAR
yow;
$blob29 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DURATION:PT1H
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20110101T090000Z
REPEAT:2
DURATION:PT1H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob30 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T120000Z
DURATION:PT1H
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20110101T090000Z
DURATION:PT1H
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$blob31 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART:20080101T120000Z
DURATION:PT1H
RRULE:FREQ=YEARLY
END:VEVENT
END:VCALENDAR
yow;
$blob32 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART:20080102T120000Z
DURATION:PT1H
RRULE:FREQ=YEARLY
END:VEVENT
END:VCALENDAR
yow;
$blob33 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART;VALUE=DATE:20120628
RRULE:FREQ=DAILY
END:VEVENT
END:VCALENDAR
yow;
$blob34 = <<<yow
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foobar
DTSTART;VALUE=DATE:20120628
RRULE:FREQ=DAILY
BEGIN:VALARM
TRIGGER:P52W
END:VALARM
END:VEVENT
END:VCALENDAR
yow;
$filter1 = [
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$filter2 = $filter1;
$filter2['name'] = 'VTODO';
$filter3 = $filter1;
$filter3['is-not-defined'] = true;
$filter4 = $filter1;
$filter4['name'] = 'VTODO';
$filter4['is-not-defined'] = true;
$filter5 = $filter1;
$filter5['comp-filters'] = [
[
'name' => 'VALARM',
'is-not-defined' => false,
'comp-filters' => [],
'prop-filters' => [],
'time-range' => null,
],
];
$filter6 = $filter1;
$filter6['prop-filters'] = [
[
'name' => 'SUMMARY',
'is-not-defined' => false,
'param-filters' => [],
'time-range' => null,
'text-match' => null,
],
];
$filter7 = $filter6;
$filter7['prop-filters'][0]['name'] = 'DESCRIPTION';
$filter8 = $filter6;
$filter8['prop-filters'][0]['is-not-defined'] = true;
$filter9 = $filter7;
$filter9['prop-filters'][0]['is-not-defined'] = true;
$filter10 = $filter5;
$filter10['prop-filters'] = $filter6['prop-filters'];
// Param filters
$filter11 = $filter1;
$filter11['prop-filters'] = [
[
'name' => 'DTSTART',
'is-not-defined' => false,
'param-filters' => [
[
'name' => 'VALUE',
'is-not-defined' => false,
'text-match' => null,
],
],
'time-range' => null,
'text-match' => null,
],
];
$filter12 = $filter11;
$filter12['prop-filters'][0]['param-filters'][0]['name'] = 'TZID';
$filter13 = $filter11;
$filter13['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
$filter14 = $filter12;
$filter14['prop-filters'][0]['param-filters'][0]['is-not-defined'] = true;
// Param text filter
$filter15 = $filter11;
$filter15['prop-filters'][0]['param-filters'][0]['text-match'] = [
'collation' => 'i;ascii-casemap',
'value' => 'dAtE',
'negate-condition' => false,
];
$filter16 = $filter15;
$filter16['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
$filter17 = $filter15;
$filter17['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
$filter18 = $filter15;
$filter18['prop-filters'][0]['param-filters'][0]['text-match']['negate-condition'] = true;
$filter18['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
// prop + text
$filter19 = $filter5;
$filter19['comp-filters'][0]['prop-filters'] = [
[
'name' => 'action',
'is-not-defined' => false,
'time-range' => null,
'param-filters' => [],
'text-match' => [
'collation' => 'i;ascii-casemap',
'value' => 'display',
'negate-condition' => false,
],
],
];
// Time range
$filter20 = [
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
],
];
// Time range, no end date
$filter21 = $filter20;
$filter21['time-range']['end'] = null;
// Time range, no start date
$filter22 = $filter20;
$filter22['time-range']['start'] = null;
// Time range, other dates
$filter23 = $filter20;
$filter23['time-range'] = [
'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
];
// Time range
$filter24 = [
'name' => 'VTODO',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
],
];
// Time range, other dates (1 month in the future)
$filter25 = $filter24;
$filter25['time-range'] = [
'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
];
$filter26 = $filter24;
$filter26['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
];
// Time range for VJOURNAL
$filter27 = [
'name' => 'VJOURNAL',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
],
];
$filter28 = $filter27;
$filter28['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
];
// Time range for VFREEBUSY
$filter29 = [
'name' => 'VFREEBUSY',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
],
];
// Time range filter on property
$filter30 = [
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [
[
'name' => 'DTSTART',
'is-not-defined' => false,
'param-filters' => [],
'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
],
'text-match' => null,
],
],
'is-not-defined' => false,
'time-range' => null,
];
// Time range for alarm
$filter31 = [
'name' => 'VEVENT',
'prop-filters' => [],
'comp-filters' => [
[
'name' => 'VALARM',
'is-not-defined' => false,
'comp-filters' => [],
'prop-filters' => [],
'time-range' => [
'start' => new \DateTime('2011-01-01 10:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')),
],
'text-match' => null,
],
],
'is-not-defined' => false,
'time-range' => null,
];
$filter32 = $filter31;
$filter32['comp-filters'][0]['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
];
$filter33 = $filter31;
$filter33['name'] = 'VTODO';
$filter34 = $filter32;
$filter34['name'] = 'VTODO';
$filter35 = $filter31;
$filter35['name'] = 'VJOURNAL';
$filter36 = $filter32;
$filter36['name'] = 'VJOURNAL';
// Time range filter on non-datetime property
$filter37 = [
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [
[
'name' => 'SUMMARY',
'is-not-defined' => false,
'param-filters' => [],
'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
],
'text-match' => null,
],
],
'is-not-defined' => false,
'time-range' => null,
];
$filter38 = [
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2012-07-01 00:00:00', new \DateTimeZone('UTC')),
'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')),
]
];
$filter39 = [
'name' => 'VEVENT',
'comp-filters' => [
[
'name' => 'VALARM',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2012-09-01 00:00:00', new \DateTimeZone('UTC')),
'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')),
]
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
return [
// Component check
[$blob1, $filter1, 1],
[$blob1, $filter2, 0],
[$blob1, $filter3, 0],
[$blob1, $filter4, 1],
// Subcomponent check (4)
[$blob1, $filter5, 0],
[$blob2, $filter5, 1],
// Property checki (6)
[$blob1, $filter6, 1],
[$blob1, $filter7, 0],
[$blob1, $filter8, 0],
[$blob1, $filter9, 1],
// Subcomponent + property (10)
[$blob2, $filter10, 1],
// Param filter (11)
[$blob3, $filter11, 1],
[$blob3, $filter12, 0],
[$blob3, $filter13, 0],
[$blob3, $filter14, 1],
// Param + text (15)
[$blob3, $filter15, 1],
[$blob3, $filter16, 0],
[$blob3, $filter17, 0],
[$blob3, $filter18, 1],
// Prop + text (19)
[$blob2, $filter19, 1],
// Incorrect object (vcard) (20)
[$blob4, $filter1, -1],
// Time-range for event (21)
[$blob5, $filter20, 1],
[$blob6, $filter20, 1],
[$blob7, $filter20, 1],
[$blob8, $filter20, 1],
[$blob5, $filter21, 1],
[$blob5, $filter22, 1],
[$blob5, $filter23, 0],
[$blob6, $filter23, 0],
[$blob7, $filter23, 0],
[$blob8, $filter23, 0],
// Time-range for todo (31)
[$blob9, $filter24, 1],
[$blob9, $filter25, 0],
[$blob9, $filter26, 1],
[$blob10, $filter24, 1],
[$blob10, $filter25, 0],
[$blob10, $filter26, 1],
[$blob11, $filter24, 0],
[$blob11, $filter25, 0],
[$blob11, $filter26, 1],
[$blob12, $filter24, 1],
[$blob12, $filter25, 0],
[$blob12, $filter26, 0],
[$blob13, $filter24, 1],
[$blob13, $filter25, 0],
[$blob13, $filter26, 1],
[$blob14, $filter24, 1],
[$blob14, $filter25, 0],
[$blob14, $filter26, 0],
[$blob15, $filter24, 1],
[$blob15, $filter25, 1],
[$blob15, $filter26, 1],
[$blob16, $filter24, 1],
[$blob16, $filter25, 1],
[$blob16, $filter26, 1],
// Time-range for journals (55)
[$blob17, $filter27, 0],
[$blob17, $filter28, 0],
[$blob18, $filter27, 0],
[$blob18, $filter28, 1],
[$blob19, $filter27, 1],
[$blob19, $filter28, 1],
// Time-range for free-busy (61)
[$blob20, $filter29, -1],
// Time-range on property (62)
[$blob5, $filter30, 1],
[$blob3, $filter37, -1],
[$blob3, $filter30, 0],
// Time-range on alarm in vevent (65)
[$blob21, $filter31, 1],
[$blob21, $filter32, 0],
[$blob22, $filter31, 1],
[$blob22, $filter32, 0],
[$blob23, $filter31, 1],
[$blob23, $filter32, 0],
[$blob24, $filter31, 1],
[$blob24, $filter32, 0],
[$blob25, $filter31, 1],
[$blob25, $filter32, 0],
[$blob26, $filter31, 1],
[$blob26, $filter32, 0],
// Time-range on alarm for vtodo (77)
[$blob27, $filter33, 1],
[$blob27, $filter34, 0],
// Time-range on alarm for vjournal (79)
[$blob28, $filter35, -1],
[$blob28, $filter36, -1],
// Time-range on alarm with duration (81)
[$blob29, $filter31, 1],
[$blob29, $filter32, 0],
[$blob30, $filter31, 0],
[$blob30, $filter32, 0],
// Time-range with RRULE (85)
[$blob31, $filter20, 1],
[$blob32, $filter20, 0],
// Bug reported on mailing list, related to all-day events (87)
//array($blob33, $filter38, 1),
// Event in timerange, but filtered alarm is in the far future (88).
[$blob34, $filter39, 0],
];
}
}

View File

@ -1,256 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV\PropPatch;
require_once 'Sabre/CalDAV/TestUtil.php';
class CalendarTest extends \PHPUnit_Framework_TestCase {
/**
* @var Sabre\CalDAV\Backend\PDO
*/
protected $backend;
protected $principalBackend;
/**
* @var Sabre\CalDAV\Calendar
*/
protected $calendar;
/**
* @var array
*/
protected $calendars;
function setup() {
$this->backend = TestUtil::getBackend();
$this->calendars = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(2, count($this->calendars));
$this->calendar = new Calendar($this->backend, $this->calendars[0]);
}
function teardown() {
unset($this->backend);
}
function testSimple() {
$this->assertEquals($this->calendars[0]['uri'], $this->calendar->getName());
}
/**
* @depends testSimple
*/
function testUpdateProperties() {
$propPatch = new PropPatch([
'{DAV:}displayname' => 'NewName',
]);
$result = $this->calendar->propPatch($propPatch);
$result = $propPatch->commit();
$this->assertEquals(true, $result);
$calendars2 = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals('NewName', $calendars2[0]['{DAV:}displayname']);
}
/**
* @depends testSimple
*/
function testGetProperties() {
$question = [
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set',
];
$result = $this->calendar->getProperties($question);
foreach ($question as $q) $this->assertArrayHasKey($q, $result);
$this->assertEquals(['VEVENT', 'VTODO'], $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue());
}
/**
* @expectedException Sabre\DAV\Exception\NotFound
* @depends testSimple
*/
function testGetChildNotFound() {
$this->calendar->getChild('randomname');
}
/**
* @depends testSimple
*/
function testGetChildren() {
$children = $this->calendar->getChildren();
$this->assertEquals(1, count($children));
$this->assertTrue($children[0] instanceof CalendarObject);
}
/**
* @depends testGetChildren
*/
function testChildExists() {
$this->assertFalse($this->calendar->childExists('foo'));
$children = $this->calendar->getChildren();
$this->assertTrue($this->calendar->childExists($children[0]->getName()));
}
/**
* @expectedException Sabre\DAV\Exception\MethodNotAllowed
*/
function testCreateDirectory() {
$this->calendar->createDirectory('hello');
}
/**
* @expectedException Sabre\DAV\Exception\MethodNotAllowed
*/
function testSetName() {
$this->calendar->setName('hello');
}
function testGetLastModified() {
$this->assertNull($this->calendar->getLastModified());
}
function testCreateFile() {
$file = fopen('php://memory', 'r+');
fwrite($file, TestUtil::getTestCalendarData());
rewind($file);
$this->calendar->createFile('hello', $file);
$file = $this->calendar->getChild('hello');
$this->assertTrue($file instanceof CalendarObject);
}
function testCreateFileNoSupportedComponents() {
$file = fopen('php://memory', 'r+');
fwrite($file, TestUtil::getTestCalendarData());
rewind($file);
$calendar = new Calendar($this->backend, $this->calendars[1]);
$calendar->createFile('hello', $file);
$file = $calendar->getChild('hello');
$this->assertTrue($file instanceof CalendarObject);
}
function testDelete() {
$this->calendar->delete();
$calendars = $this->backend->getCalendarsForUser('principals/user1');
$this->assertEquals(1, count($calendars));
}
function testGetOwner() {
$this->assertEquals('principals/user1', $this->calendar->getOwner());
}
function testGetGroup() {
$this->assertNull($this->calendar->getGroup());
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
];
$this->assertEquals($expected, $this->calendar->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$this->calendar->setACL([]);
}
function testGetSyncToken() {
$this->assertNull($this->calendar->getSyncToken());
}
function testGetSyncTokenNoSyncSupport() {
$calendar = new Calendar(new Backend\Mock([], []), []);
$this->assertNull($calendar->getSyncToken());
}
function testGetChanges() {
$this->assertNull($this->calendar->getChanges(1, 1));
}
}

View File

@ -1,113 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class ExpandEventsDTSTARTandDTENDTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTEND;TZID=Europe/Berlin:20120207T191500
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
SUMMARY:RecurringEvents 3 times
DTSTART;TZID=Europe/Berlin:20120207T181500
END:VEVENT
BEGIN:VEVENT
CREATED:20120207T111900Z
UID:foobar
DTEND;TZID=Europe/Berlin:20120208T191500
SUMMARY:RecurringEvents 3 times OVERWRITTEN
DTSTART;TZID=Europe/Berlin:20120208T181500
RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
END:VEVENT
END:VCALENDAR
',
],
],
];
function testExpand() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120205T230000Z" end="20120212T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
try {
$vObject = VObject\Reader::read($body);
} catch (VObject\ParseException $e) {
$this->fail('Could not parse object. Error:' . $e->getMessage() . ' full object: ' . $response->getBodyAsString());
}
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART has to be one of three valid values
$this->assertContains($child->getValue(), ['20120207T171500Z', '20120208T171500Z', '20120209T171500Z'], 'DTSTART is not a valid value: ' . $child->getValue());
} elseif ($child->name == 'DTEND') {
// DTEND has to be one of three valid values
$this->assertContains($child->getValue(), ['20120207T181500Z', '20120208T181500Z', '20120209T181500Z'], 'DTEND is not a valid value: ' . $child->getValue());
}
}
}
}
}

View File

@ -1,102 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class ExpandEventsDTSTARTandDTENDbyDayTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTEND;TZID=Europe/Berlin:20120207T191500
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
SUMMARY:RecurringEvents on tuesday and thursday
DTSTART;TZID=Europe/Berlin:20120207T181500
END:VEVENT
END:VCALENDAR
',
],
],
];
function testExpandRecurringByDayEvent() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120210T230000Z" end="20120217T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120210T230000Z" end="20120217T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
$this->assertEquals(2, count($vObject->VEVENT));
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART has to be one of two valid values
$this->assertContains($child->getValue(), ['20120214T171500Z', '20120216T171500Z'], 'DTSTART is not a valid value: ' . $child->getValue());
} elseif ($child->name == 'DTEND') {
// DTEND has to be one of two valid values
$this->assertContains($child->getValue(), ['20120214T181500Z', '20120216T181500Z'], 'DTEND is not a valid value: ' . $child->getValue());
}
}
}
}
}

View File

@ -1,103 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittests is created to find out why certain events show up twice.
*
* Hopefully, by the time I'm done with this, I've both found the problem, and
* fixed it :)
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class ExpandEventsDoubleEventsTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTEND;TZID=Europe/Berlin:20120207T191500
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=3
SUMMARY:RecurringEvents 3 times
DTSTART;TZID=Europe/Berlin:20120207T181500
END:VEVENT
BEGIN:VEVENT
CREATED:20120207T111900Z
UID:foobar
DTEND;TZID=Europe/Berlin:20120208T191500
SUMMARY:RecurringEvents 3 times OVERWRITTEN
DTSTART;TZID=Europe/Berlin:20120208T181500
RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
END:VEVENT
END:VCALENDAR
',
],
],
];
function testExpand() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120205T230000Z" end="20120212T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120205T230000Z" end="20120212T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
// We only expect 3 events
$this->assertEquals(3, count($vObject->VEVENT), 'We got 6 events instead of 3. Output: ' . $body);
// TZID should be gone
$this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID']));
}
}

View File

@ -1,207 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittest is created to check if expand() works correctly with
* floating times (using calendar-timezone information).
*/
class ExpandEventsFloatingTimeTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupCalDAVICSExport = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
'{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
DTSTART:19810329T020000
TZNAME:GMT+2
TZOFFSETTO:+0200
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
DTSTART:19961027T030000
TZNAME:GMT+1
TZOFFSETTO:+0100
END:STANDARD
END:VTIMEZONE
END:VCALENDAR',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20140701T143658Z
UID:dba46fe8-1631-4d98-a575-97963c364dfe
DTEND:20141108T073000
TRANSP:OPAQUE
SUMMARY:Floating Time event, starting 05:30am Europe/Berlin
DTSTART:20141108T053000
DTSTAMP:20140701T143706Z
SEQUENCE:1
END:VEVENT
END:VCALENDAR
',
],
],
];
function testExpandCalendarQuery() {
$request = new HTTP\Request('REPORT', '/calendars/user1/calendar1', [
'Depth' => 1,
'Content-Type' => 'application/xml',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20141107T230000Z" end="20141108T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20141107T230000Z" end="20141108T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART should be the UTC equivalent of given floating time
$this->assertEquals('20141108T043000Z', $child->getValue());
} elseif ($child->name == 'DTEND') {
// DTEND should be the UTC equivalent of given floating time
$this->assertEquals('20141108T063000Z', $child->getValue());
}
}
}
}
function testExpandMultiGet() {
$request = new HTTP\Request('REPORT', '/calendars/user1/calendar1', [
'Depth' => 1,
'Content-Type' => 'application/xml',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-multiget xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20141107T230000Z" end="20141108T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<D:href>/calendars/user1/calendar1/event.ics</D:href>
</C:calendar-multiget>');
$response = $this->request($request);
$this->assertEquals(207, $response->getStatus());
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART should be the UTC equivalent of given floating time
$this->assertEquals($child->getValue(), '20141108T043000Z');
} elseif ($child->name == 'DTEND') {
// DTEND should be the UTC equivalent of given floating time
$this->assertEquals($child->getValue(), '20141108T063000Z');
}
}
}
}
function testExpandExport() {
$request = new HTTP\Request('GET', '/calendars/user1/calendar1?export&start=1&end=2000000000&expand=1', [
'Depth' => 1,
'Content-Type' => 'application/xml',
]);
$response = $this->request($request);
$this->assertEquals(200, $response->getStatus());
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART should be the UTC equivalent of given floating time
$this->assertEquals('20141108T043000Z', $child->getValue());
} elseif ($child->name == 'DTEND') {
// DTEND should be the UTC equivalent of given floating time
$this->assertEquals('20141108T063000Z', $child->getValue());
}
}
}
}
}

View File

@ -1,174 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV;
use Sabre\HTTP;
require_once 'Sabre/CalDAV/Backend/Mock.php';
require_once 'Sabre/HTTP/ResponseMock.php';
class FreeBusyReportTest extends \PHPUnit_Framework_TestCase {
/**
* @var Plugin
*/
protected $plugin;
/**
* @var DAV\Server
*/
protected $server;
function setUp() {
$obj1 = <<<ics
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20111005T120000Z
DURATION:PT1H
END:VEVENT
END:VCALENDAR
ics;
$obj2 = fopen('php://memory', 'r+');
fwrite($obj2, <<<ics
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20121005T120000Z
DURATION:PT1H
END:VEVENT
END:VCALENDAR
ics
);
rewind($obj2);
$obj3 = <<<ics
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20111006T120000
DURATION:PT1H
END:VEVENT
END:VCALENDAR
ics;
$calendarData = [
1 => [
'obj1' => [
'calendarid' => 1,
'uri' => 'event1.ics',
'calendardata' => $obj1,
],
'obj2' => [
'calendarid' => 1,
'uri' => 'event2.ics',
'calendardata' => $obj2
],
'obj3' => [
'calendarid' => 1,
'uri' => 'event3.ics',
'calendardata' => $obj3
]
],
];
$caldavBackend = new Backend\Mock([], $calendarData);
$calendar = new Calendar($caldavBackend, [
'id' => 1,
'uri' => 'calendar',
'principaluri' => 'principals/user1',
'{' . Plugin::NS_CALDAV . '}calendar-timezone' => "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nEND:VTIMEZONE\r\nEND:VCALENDAR",
]);
$this->server = new DAV\Server([$calendar]);
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_URI' => '/calendar',
]);
$this->server->httpRequest = $request;
$this->server->httpResponse = new HTTP\ResponseMock();
$this->plugin = new Plugin();
$this->server->addPlugin($this->plugin);
}
function testFreeBusyReport() {
$reportXML = <<<XML
<?xml version="1.0"?>
<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
<c:time-range start="20111001T000000Z" end="20111101T000000Z" />
</c:free-busy-query>
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
$this->plugin->report($rootElem, $report, null);
$this->assertEquals(200, $this->server->httpResponse->status);
$this->assertEquals('text/calendar', $this->server->httpResponse->getHeader('Content-Type'));
$this->assertTrue(strpos($this->server->httpResponse->body, 'BEGIN:VFREEBUSY') !== false);
$this->assertTrue(strpos($this->server->httpResponse->body, '20111005T120000Z/20111005T130000Z') !== false);
$this->assertTrue(strpos($this->server->httpResponse->body, '20111006T100000Z/20111006T110000Z') !== false);
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
function testFreeBusyReportNoTimeRange() {
$reportXML = <<<XML
<?xml version="1.0"?>
<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
</c:free-busy-query>
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
}
/**
* @expectedException Sabre\DAV\Exception\NotImplemented
*/
function testFreeBusyReportWrongNode() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_URI' => '/',
]);
$this->server->httpRequest = $request;
$reportXML = <<<XML
<?xml version="1.0"?>
<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
<c:time-range start="20111001T000000Z" end="20111101T000000Z" />
</c:free-busy-query>
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
$this->plugin->report($rootElem, $report, null);
}
/**
* @expectedException Sabre\DAV\Exception
*/
function testFreeBusyReportNoACLPlugin() {
$this->server = new DAV\Server();
$this->plugin = new Plugin();
$this->server->addPlugin($this->plugin);
$reportXML = <<<XML
<?xml version="1.0"?>
<c:free-busy-query xmlns:c="urn:ietf:params:xml:ns:caldav">
<c:time-range start="20111001T000000Z" end="20111101T000000Z" />
</c:free-busy-query>
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
$this->plugin->report($rootElem, $report, null);
}
}

View File

@ -1,82 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
/**
* This unittest is created to check if queries for time-range include the start timestamp or not
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class GetEventsByTimerangeTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
CREATED:20120313T142342Z
UID:171EBEFC-C951-499D-B234-7BA7D677B45D
DTEND;TZID=Europe/Berlin:20120227T010000
TRANSP:OPAQUE
SUMMARY:Monday 0h
DTSTART;TZID=Europe/Berlin:20120227T000000
DTSTAMP:20120313T142416Z
SEQUENCE:4
END:VEVENT
END:VCALENDAR
',
],
],
];
function testQueryTimerange() {
$request = new HTTP\Request(
'REPORT',
'/calendars/user1/calendar1',
[
'Content-Type' => 'application/xml',
'Depth' => '1',
]
);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120226T220000Z" end="20120228T225959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120226T220000Z" end="20120228T225959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
$this->assertTrue(strpos($response->body, 'BEGIN:VCALENDAR') !== false);
}
}

View File

@ -1,386 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAVACL;
use Sabre\HTTP;
use Sabre\VObject;
class ICSExportPluginTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $icsExportPlugin;
function setUp() {
parent::setUp();
$this->icsExportPlugin = new ICSExportPlugin();
$this->server->addPlugin(
$this->icsExportPlugin
);
$id = $this->caldavBackend->createCalendar(
'principals/admin',
'UUID-123467',
[
'{DAV:}displayname' => 'Hello!',
'{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
]
);
$this->caldavBackend->createCalendarObject(
$id,
'event-1',
<<<ICS
BEGIN:VCALENDAR
BEGIN:VTIMEZONE
TZID:Europe/Amsterdam
END:VTIMEZONE
BEGIN:VEVENT
UID:event-1
DTSTART;TZID=Europe/Amsterdam:20151020T000000
END:VEVENT
END:VCALENDAR
ICS
);
$this->caldavBackend->createCalendarObject(
$id,
'todo-1',
<<<ICS
BEGIN:VCALENDAR
BEGIN:VTODO
UID:todo-1
END:VTODO
END:VCALENDAR
ICS
);
}
function testInit() {
$this->assertEquals(
$this->icsExportPlugin,
$this->server->getPlugin('ics-export')
);
$this->assertEquals($this->icsExportPlugin, $this->server->getPlugin('ics-export'));
$this->assertEquals('ics-export', $this->icsExportPlugin->getPluginInfo()['name']);
}
function testBeforeMethod() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export'
);
$response = $this->request($request);
$this->assertEquals(200, $response->getStatus());
$this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
$obj = VObject\Reader::read($response->body);
$this->assertEquals(8, count($obj->children()));
$this->assertEquals(1, count($obj->VERSION));
$this->assertEquals(1, count($obj->CALSCALE));
$this->assertEquals(1, count($obj->PRODID));
$this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
$this->assertEquals(1, count($obj->VTIMEZONE));
$this->assertEquals(1, count($obj->VEVENT));
$this->assertEquals("Hello!", $obj->{"X-WR-CALNAME"});
$this->assertEquals("#AA0000FF", $obj->{"X-APPLE-CALENDAR-COLOR"});
}
function testBeforeMethodNoVersion() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export'
);
DAV\Server::$exposeVersion = false;
$response = $this->request($request);
DAV\Server::$exposeVersion = true;
$this->assertEquals(200, $response->getStatus());
$this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
$obj = VObject\Reader::read($response->body);
$this->assertEquals(8, count($obj->children()));
$this->assertEquals(1, count($obj->VERSION));
$this->assertEquals(1, count($obj->CALSCALE));
$this->assertEquals(1, count($obj->PRODID));
$this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
$this->assertEquals(1, count($obj->VTIMEZONE));
$this->assertEquals(1, count($obj->VEVENT));
}
function testBeforeMethodNoExport() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467'
);
$response = new HTTP\Response();
$this->assertNull($this->icsExportPlugin->httpGet($request, $response));
}
function testACLIntegrationBlocked() {
$aclPlugin = new DAVACL\Plugin();
$aclPlugin->allowUnauthenticatedAccess = false;
$this->server->addPlugin(
$aclPlugin
);
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export'
);
$this->request($request, 403);
}
function testACLIntegrationNotBlocked() {
$aclPlugin = new DAVACL\Plugin();
$aclPlugin->allowUnauthenticatedAccess = false;
$this->server->addPlugin(
$aclPlugin
);
$this->server->addPlugin(
new Plugin()
);
$this->autoLogin('admin');
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export'
);
$response = $this->request($request, 200);
$this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
$obj = VObject\Reader::read($response->body);
$this->assertEquals(8, count($obj->children()));
$this->assertEquals(1, count($obj->VERSION));
$this->assertEquals(1, count($obj->CALSCALE));
$this->assertEquals(1, count($obj->PRODID));
$this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
$this->assertEquals(1, count($obj->VTIMEZONE));
$this->assertEquals(1, count($obj->VEVENT));
}
function testBadStartParam() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&start=foo'
);
$this->request($request, 400);
}
function testBadEndParam() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&end=foo'
);
$this->request($request, 400);
}
function testFilterStartEnd() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&start=1&end=2'
);
$response = $this->request($request, 200);
$obj = VObject\Reader::read($response->getBody());
$this->assertEquals(0, count($obj->VTIMEZONE));
$this->assertEquals(0, count($obj->VEVENT));
}
function testExpandNoStart() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&expand=1&end=2'
);
$this->request($request, 400);
}
function testExpand() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&start=1&end=2000000000&expand=1'
);
$response = $this->request($request, 200);
$obj = VObject\Reader::read($response->getBody());
$this->assertEquals(0, count($obj->VTIMEZONE));
$this->assertEquals(1, count($obj->VEVENT));
}
function testJCal() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export',
['Accept' => 'application/calendar+json']
);
$response = $this->request($request, 200);
$this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
}
function testJCalInUrl() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&accept=jcal'
);
$response = $this->request($request, 200);
$this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
}
function testNegotiateDefault() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export',
['Accept' => 'text/plain']
);
$response = $this->request($request, 200);
$this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
}
function testFilterComponentVEVENT() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&componentType=VEVENT'
);
$response = $this->request($request, 200);
$obj = VObject\Reader::read($response->body);
$this->assertEquals(1, count($obj->VTIMEZONE));
$this->assertEquals(1, count($obj->VEVENT));
$this->assertEquals(0, count($obj->VTODO));
}
function testFilterComponentVTODO() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&componentType=VTODO'
);
$response = $this->request($request, 200);
$obj = VObject\Reader::read($response->body);
$this->assertEquals(0, count($obj->VTIMEZONE));
$this->assertEquals(0, count($obj->VEVENT));
$this->assertEquals(1, count($obj->VTODO));
}
function testFilterComponentBadComponent() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export&componentType=VVOODOO'
);
$response = $this->request($request, 400);
}
function testContentDisposition() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export'
);
$response = $this->request($request, 200);
$this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
$this->assertEquals(
'attachment; filename="UUID-123467-' . date('Y-m-d') . '.ics"',
$response->getHeader('Content-Disposition')
);
}
function testContentDispositionJson() {
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-123467?export',
['Accept' => 'application/calendar+json']
);
$response = $this->request($request, 200);
$this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
$this->assertEquals(
'attachment; filename="UUID-123467-' . date('Y-m-d') . '.json"',
$response->getHeader('Content-Disposition')
);
}
function testContentDispositionBadChars() {
$this->caldavBackend->createCalendar(
'principals/admin',
'UUID-b_ad"(ch)ars',
[
'{DAV:}displayname' => 'Test bad characters',
'{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
]
);
$request = new HTTP\Request(
'GET',
'/calendars/admin/UUID-b_ad"(ch)ars?export',
['Accept' => 'application/calendar+json']
);
$response = $this->request($request, 200);
$this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
$this->assertEquals(
'attachment; filename="UUID-b_adchars-' . date('Y-m-d') . '.json"',
$response->getHeader('Content-Disposition')
);
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\VObject;
class Issue166Test extends \PHPUnit_Framework_TestCase {
function testFlaw() {
$input = <<<HI
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Asia/Pyongyang
X-LIC-LOCATION:Asia/Pyongyang
BEGIN:STANDARD
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
TZNAME:KST
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20111118T010857Z
LAST-MODIFIED:20111118T010937Z
DTSTAMP:20111118T010937Z
UID:a03245b3-9947-9a48-a088-863c74e0fdd8
SUMMARY:New Event
RRULE:FREQ=YEARLY
DTSTART;TZID=Asia/Pyongyang:19960102T111500
DTEND;TZID=Asia/Pyongyang:19960102T121500
END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2011-12-01'),
'end' => new \DateTime('2012-02-01'),
],
],
],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => null,
];
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input, $filters));
}
}

View File

@ -1,135 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\VObject;
class Issue172Test extends \PHPUnit_Framework_TestCase {
// DateTimeZone() native name: America/Los_Angeles (GMT-8 in January)
function testBuiltInTimezoneName() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20120118T204500
DTEND;TZID=America/Los_Angeles:20120118T214500
END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
'end' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
],
],
],
'prop-filters' => [],
];
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input, $filters));
}
// Pacific Standard Time, translates to America/Los_Angeles (GMT-8 in January)
function testOutlookTimezoneName() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Pacific Standard Time
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Pacific Standard Time:20120113T100000
DTEND;TZID=Pacific Standard Time:20120113T110000
END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
],
],
],
'prop-filters' => [],
];
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input, $filters));
}
// X-LIC-LOCATION, translates to America/Los_Angeles (GMT-8 in January)
function testLibICalLocationName() {
$input = <<<HI
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
TZID:My own timezone name
X-LIC-LOCATION:America/Los_Angeles
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=My own timezone name:20120113T100000
DTEND;TZID=My own timezone name:20120113T110000
END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
$filters = [
'name' => 'VCALENDAR',
'comp-filters' => [
[
'name' => 'VEVENT',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false,
'time-range' => [
'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
],
],
],
'prop-filters' => [],
];
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input, $filters));
}
}

View File

@ -1,137 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittest is created to find out why an overwritten DAILY event has wrong DTSTART, DTEND, SUMMARY and RECURRENCEID
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class Issue203Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:20120330T155305CEST-6585fBUVgV
DTSTAMP:20120330T135305Z
DTSTART;TZID=Europe/Berlin:20120326T155200
DTEND;TZID=Europe/Berlin:20120326T165200
RRULE:FREQ=DAILY;COUNT=2;INTERVAL=1
SUMMARY:original summary
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
UID:20120330T155305CEST-6585fBUVgV
DTSTAMP:20120330T135352Z
DESCRIPTION:
DTSTART;TZID=Europe/Berlin:20120328T155200
DTEND;TZID=Europe/Berlin:20120328T165200
RECURRENCE-ID;TZID=Europe/Berlin:20120327T155200
SEQUENCE:1
SUMMARY:overwritten summary
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
',
],
],
];
function testIssue203() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120325T220000Z" end="20120401T215959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
$this->assertEquals(2, count($vObject->VEVENT));
$expectedEvents = [
[
'DTSTART' => '20120326T135200Z',
'DTEND' => '20120326T145200Z',
'SUMMARY' => 'original summary',
],
[
'DTSTART' => '20120328T135200Z',
'DTEND' => '20120328T145200Z',
'SUMMARY' => 'overwritten summary',
'RECURRENCE-ID' => '20120327T135200Z',
]
];
// try to match agains $expectedEvents array
foreach ($expectedEvents as $expectedEvent) {
$matching = false;
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children() as $child) {
/** @var $child Sabre\VObject\Property */
if (isset($expectedEvent[$child->name])) {
if ($expectedEvent[$child->name] != $child->getValue()) {
continue 2;
}
}
}
$matching = true;
break;
}
$this->assertTrue($matching, 'Did not find the following event in the response: ' . var_export($expectedEvent, true));
}
}
}

View File

@ -1,98 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
use Sabre\VObject;
/**
* This unittest is created to check if a VALARM TRIGGER of PT0S is supported
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class Issue205Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:20120330T155305CEST-6585fBUVgV
DTSTAMP:20120330T135305Z
DTSTART;TZID=Europe/Berlin:20120326T155200
DTEND;TZID=Europe/Berlin:20120326T165200
SUMMARY:original summary
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:AUDIO
ATTACH;VALUE=URI:Basso
TRIGGER:PT0S
END:VALARM
END:VEVENT
END:VCALENDAR
',
],
],
];
function testIssue205() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120325T220000Z" end="20120401T215959Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:comp-filter name="VALARM">
<C:time-range start="20120325T220000Z" end="20120401T215959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
$this->assertFalse(strpos($response->body, '<s:exception>Exception</s:exception>'), 'Exception occurred: ' . $response->body);
$this->assertFalse(strpos($response->body, 'Unknown or bad format'), 'DateTime unknown format Exception: ' . $response->body);
// Everts super awesome xml parser.
$body = substr(
$response->body,
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
$body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
$this->assertEquals(1, count($vObject->VEVENT));
}
}

View File

@ -1,89 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
/**
* This unittest is created to check for an endless loop in Sabre\CalDAV\CalendarQueryValidator
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class Issue211Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:20120418T172519CEST-3510gh1hVw
DTSTAMP:20120418T152519Z
DTSTART;VALUE=DATE:20120330
DTEND;VALUE=DATE:20120531
EXDATE;TZID=Europe/Berlin:20120330T000000
RRULE:FREQ=YEARLY;INTERVAL=1
SEQUENCE:1
SUMMARY:Birthday
TRANSP:TRANSPARENT
BEGIN:VALARM
ACTION:EMAIL
ATTENDEE:MAILTO:xxx@domain.de
DESCRIPTION:Dies ist eine Kalender Erinnerung
SUMMARY:Kalender Alarm Erinnerung
TRIGGER;VALUE=DATE-TIME:20120329T060000Z
END:VALARM
END:VEVENT
END:VCALENDAR
',
],
],
];
function testIssue211() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data/>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:comp-filter name="VALARM">
<C:time-range start="20120426T220000Z" end="20120427T215959Z"/>
</C:comp-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// if this assert is reached, the endless loop is gone
// There should be no matching events
$this->assertFalse(strpos('BEGIN:VEVENT', $response->body));
}
}

View File

@ -1,99 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
/**
* This unittest is created to check for an endless loop in CalendarQueryValidator
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class Issue220Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20120601T180000
SUMMARY:Brot backen
RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO
TRANSP:OPAQUE
DURATION:PT20M
LAST-MODIFIED:20120601T064634Z
CREATED:20120601T064634Z
DTSTAMP:20120601T064634Z
UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
BEGIN:VALARM
TRIGGER;VALUE=DURATION:-PT5M
ACTION:DISPLAY
DESCRIPTION:Default Event Notification
X-WR-ALARMUID:cd952c1b-b3d6-41fb-b0a6-ec3a1a5bdd58
END:VALARM
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20120606T180000
SUMMARY:Brot backen
TRANSP:OPAQUE
STATUS:CANCELLED
DTEND;TZID=Europe/Berlin:20120606T182000
LAST-MODIFIED:20120605T094310Z
SEQUENCE:1
RECURRENCE-ID:20120606T160000Z
UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
END:VEVENT
END:VCALENDAR
',
],
],
];
function testIssue220() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data/>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:comp-filter name="VALARM">
<C:time-range start="20120607T161646Z" end="20120612T161646Z"/>
</C:comp-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
$this->assertFalse(strpos($response->body, '<s:exception>PHPUnit_Framework_Error_Warning</s:exception>'), 'Error Warning occurred: ' . $response->body);
$this->assertFalse(strpos($response->body, 'Invalid argument supplied for foreach()'), 'Invalid argument supplied for foreach(): ' . $response->body);
$this->assertEquals(207, $response->status);
}
}

View File

@ -1,79 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP;
/**
* This unittest is created to check if the time-range filter is working correctly with all-day-events
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class Issue228Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
]
];
protected $caldavCalendarObjects = [
1 => [
'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:20120730T113415CEST-6804EGphkd@xxxxxx.de
DTSTAMP:20120730T093415Z
DTSTART;VALUE=DATE:20120729
DTEND;VALUE=DATE:20120730
SUMMARY:sunday event
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
',
],
],
];
function testIssue228() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
'REQUEST_URI' => '/calendars/user1/calendar1',
'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<C:calendar-data>
<C:expand start="20120730T095609Z"
end="20120813T095609Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120730T095609Z" end="20120813T095609Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// We must check if absolutely nothing was returned from this query.
$this->assertFalse(strpos($response->body, 'BEGIN:VCALENDAR'));
}
}

View File

@ -1,262 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\HTTP\Request;
use Sabre\VObject;
class JCalTransformTest extends \Sabre\DAVServerTest {
use VObject\PHPUnitAssertions;
protected $setupCalDAV = true;
protected $caldavCalendars = [
[
'id' => 1,
'principaluri' => 'principals/user1',
'uri' => 'foo',
]
];
protected $caldavCalendarObjects = [
1 => [
'bar.ics' => [
'uri' => 'bar.ics',
'calendarid' => 1,
'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'lastmodified' => null
]
],
];
function testGet() {
$headers = [
'Accept' => 'application/calendar+json',
];
$request = new Request('GET', '/calendars/user1/foo/bar.ics', $headers);
$response = $this->request($request);
$body = $response->getBodyAsString();
$this->assertEquals(200, $response->getStatus(), "Incorrect status code: " . $body);
$response = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->fail('Json decoding error: ' . json_last_error_msg());
}
$this->assertEquals(
[
'vcalendar',
[],
[
[
'vevent',
[],
[],
],
],
],
$response
);
}
function testMultiGet() {
$xml = <<<XML
<?xml version="1.0"?>
<c:calendar-multiget xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
<d:prop>
<c:calendar-data content-type="application/calendar+json" />
</d:prop>
<d:href>/calendars/user1/foo/bar.ics</d:href>
</c:calendar-multiget>
XML;
$headers = [];
$request = new Request('REPORT', '/calendars/user1/foo', $headers, $xml);
$response = $this->request($request);
$this->assertEquals(207, $response->getStatus(), 'Full rsponse: ' . $response->getBodyAsString());
$multiStatus = $this->server->xml->parse(
$response->getBodyAsString()
);
$responses = $multiStatus->getResponses();
$this->assertEquals(1, count($responses));
$response = $responses[0]->getResponseProperties()[200]["{urn:ietf:params:xml:ns:caldav}calendar-data"];
$jresponse = json_decode($response, true);
if (json_last_error()) {
$this->fail('Json decoding error: ' . json_last_error_msg() . '. Full response: ' . $response);
}
$this->assertEquals(
[
'vcalendar',
[],
[
[
'vevent',
[],
[],
],
],
],
$jresponse
);
}
function testCalendarQueryDepth1() {
$xml = <<<XML
<?xml version="1.0"?>
<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
<d:prop>
<c:calendar-data content-type="application/calendar+json" />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR" />
</c:filter>
</c:calendar-query>
XML;
$headers = [
'Depth' => '1',
];
$request = new Request('REPORT', '/calendars/user1/foo', $headers, $xml);
$response = $this->request($request);
$this->assertEquals(207, $response->getStatus(), "Invalid response code. Full body: " . $response->getBodyAsString());
$multiStatus = $this->server->xml->parse(
$response->getBodyAsString()
);
$responses = $multiStatus->getResponses();
$this->assertEquals(1, count($responses));
$response = $responses[0]->getResponseProperties()[200]["{urn:ietf:params:xml:ns:caldav}calendar-data"];
$response = json_decode($response, true);
if (json_last_error()) {
$this->fail('Json decoding error: ' . json_last_error_msg());
}
$this->assertEquals(
[
'vcalendar',
[],
[
[
'vevent',
[],
[],
],
],
],
$response
);
}
function testCalendarQueryDepth0() {
$xml = <<<XML
<?xml version="1.0"?>
<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:d="DAV:">
<d:prop>
<c:calendar-data content-type="application/calendar+json" />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR" />
</c:filter>
</c:calendar-query>
XML;
$headers = [
'Depth' => '0',
];
$request = new Request('REPORT', '/calendars/user1/foo/bar.ics', $headers, $xml);
$response = $this->request($request);
$this->assertEquals(207, $response->getStatus(), "Invalid response code. Full body: " . $response->getBodyAsString());
$multiStatus = $this->server->xml->parse(
$response->getBodyAsString()
);
$responses = $multiStatus->getResponses();
$this->assertEquals(1, count($responses));
$response = $responses[0]->getResponseProperties()[200]["{urn:ietf:params:xml:ns:caldav}calendar-data"];
$response = json_decode($response, true);
if (json_last_error()) {
$this->fail('Json decoding error: ' . json_last_error_msg());
}
$this->assertEquals(
[
'vcalendar',
[],
[
[
'vevent',
[],
[],
],
],
],
$response
);
}
function testValidateICalendar() {
$input = [
'vcalendar',
[],
[
[
'vevent',
[
['uid', (object)[], 'text', 'foo'],
['dtstart', (object)[], 'date', '2016-04-06'],
],
[],
],
],
];
$input = json_encode($input);
$this->caldavPlugin->beforeWriteContent(
'calendars/user1/foo/bar.ics',
$this->server->tree->getNodeForPath('calendars/user1/foo/bar.ics'),
$input,
$modified
);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART;VALUE=DATE:20160406
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$input
);
}
}

View File

@ -1,85 +0,0 @@
<?php
namespace Sabre\CalDAV\Notifications;
use Sabre\CalDAV;
class CollectionTest extends \PHPUnit_Framework_TestCase {
protected $caldavBackend;
protected $principalUri;
protected $notification;
function getInstance() {
$this->principalUri = 'principals/user1';
$this->notification = new CalDAV\Xml\Notification\SystemStatus(1, '"1"');
$this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [
'principals/user1' => [
$this->notification
]
]);
return new Collection($this->caldavBackend, $this->principalUri);
}
function testGetChildren() {
$col = $this->getInstance();
$this->assertEquals('notifications', $col->getName());
$this->assertEquals([
new Node($this->caldavBackend, $this->principalUri, $this->notification)
], $col->getChildren());
}
function testGetOwner() {
$col = $this->getInstance();
$this->assertEquals('principals/user1', $col->getOwner());
}
function testGetGroup() {
$col = $this->getInstance();
$this->assertNull($col->getGroup());
}
function testGetACL() {
$col = $this->getInstance();
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => '{DAV:}owner',
'protected' => true,
],
];
$this->assertEquals($expected, $col->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$col = $this->getInstance();
$col->setACL([]);
}
function testGetSupportedPrivilegeSet() {
$col = $this->getInstance();
$this->assertNull($col->getSupportedPrivilegeSet());
}
}

View File

@ -1,96 +0,0 @@
<?php
namespace Sabre\CalDAV\Notifications;
use Sabre\CalDAV;
class NodeTest extends \PHPUnit_Framework_TestCase {
protected $systemStatus;
protected $caldavBackend;
function getInstance() {
$principalUri = 'principals/user1';
$this->systemStatus = new CalDAV\Xml\Notification\SystemStatus(1, '"1"');
$this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [
'principals/user1' => [
$this->systemStatus
]
]);
$node = new Node($this->caldavBackend, 'principals/user1', $this->systemStatus);
return $node;
}
function testGetId() {
$node = $this->getInstance();
$this->assertEquals($this->systemStatus->getId() . '.xml', $node->getName());
}
function testGetEtag() {
$node = $this->getInstance();
$this->assertEquals('"1"', $node->getETag());
}
function testGetNotificationType() {
$node = $this->getInstance();
$this->assertEquals($this->systemStatus, $node->getNotificationType());
}
function testDelete() {
$node = $this->getInstance();
$node->delete();
$this->assertEquals([], $this->caldavBackend->getNotificationsForPrincipal('principals/user1'));
}
function testGetGroup() {
$node = $this->getInstance();
$this->assertNull($node->getGroup());
}
function testGetACL() {
$node = $this->getInstance();
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => '{DAV:}owner',
'protected' => true,
],
];
$this->assertEquals($expected, $node->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$node = $this->getInstance();
$node->setACL([]);
}
function testGetSupportedPrivilegeSet() {
$node = $this->getInstance();
$this->assertNull($node->getSupportedPrivilegeSet());
}
}

View File

@ -1,168 +0,0 @@
<?php
namespace Sabre\CalDAV\Notifications;
use Sabre\CalDAV;
use Sabre\CalDAV\Xml\Notification\SystemStatus;
use Sabre\DAV;
use Sabre\DAVACL;
use Sabre\HTTP;
use Sabre\HTTP\Request;
class PluginTest extends \PHPUnit_Framework_TestCase {
/**
* @var Sabre\DAV\Server
*/
protected $server;
/**
* @var Sabre\CalDAV\Plugin
*/
protected $plugin;
protected $response;
/**
* @var Sabre\CalDAV\Backend\PDO
*/
protected $caldavBackend;
function setup() {
$this->caldavBackend = new CalDAV\Backend\MockSharing();
$principalBackend = new DAVACL\PrincipalBackend\Mock();
$calendars = new CalDAV\CalendarRoot($principalBackend, $this->caldavBackend);
$principals = new CalDAV\Principal\Collection($principalBackend);
$root = new DAV\SimpleCollection('root');
$root->addChild($calendars);
$root->addChild($principals);
$this->server = new DAV\Server($root);
$this->server->sapi = new HTTP\SapiMock();
$this->server->debugExceptions = true;
$this->server->setBaseUri('/');
$this->plugin = new Plugin();
$this->server->addPlugin($this->plugin);
// Adding ACL plugin
$aclPlugin = new DAVACL\Plugin();
$aclPlugin->allowUnauthenticatedAccess = false;
$this->server->addPlugin($aclPlugin);
// CalDAV is also required.
$this->server->addPlugin(new CalDAV\Plugin());
// Adding Auth plugin, and ensuring that we are logged in.
$authBackend = new DAV\Auth\Backend\Mock();
$authPlugin = new DAV\Auth\Plugin($authBackend);
$this->server->addPlugin($authPlugin);
// This forces a login
$authPlugin->beforeMethod(new HTTP\Request(), new HTTP\Response());
$this->response = new HTTP\ResponseMock();
$this->server->httpResponse = $this->response;
}
function testSimple() {
$this->assertEquals([], $this->plugin->getFeatures());
$this->assertEquals('notifications', $this->plugin->getPluginName());
$this->assertEquals(
'notifications',
$this->plugin->getPluginInfo()['name']
);
}
function testPrincipalProperties() {
$httpRequest = new Request('GET', '/', ['Host' => 'sabredav.org']);
$this->server->httpRequest = $httpRequest;
$props = $this->server->getPropertiesForPath('principals/admin', [
'{' . Plugin::NS_CALENDARSERVER . '}notification-URL',
]);
$this->assertArrayHasKey(0, $props);
$this->assertArrayHasKey(200, $props[0]);
$this->assertArrayHasKey('{' . Plugin::NS_CALENDARSERVER . '}notification-URL', $props[0][200]);
$prop = $props[0][200]['{' . Plugin::NS_CALENDARSERVER . '}notification-URL'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals('calendars/admin/notifications/', $prop->getHref());
}
function testNotificationProperties() {
$notification = new Node(
$this->caldavBackend,
'principals/user1',
new SystemStatus('foo', '"1"')
);
$propFind = new DAV\PropFind('calendars/user1/notifications', [
'{' . Plugin::NS_CALENDARSERVER . '}notificationtype',
]);
$this->plugin->propFind($propFind, $notification);
$this->assertEquals(
$notification->getNotificationType(),
$propFind->get('{' . Plugin::NS_CALENDARSERVER . '}notificationtype')
);
}
function testNotificationGet() {
$notification = new Node(
$this->caldavBackend,
'principals/user1',
new SystemStatus('foo', '"1"')
);
$server = new DAV\Server([$notification]);
$caldav = new Plugin();
$server->httpRequest = new Request('GET', '/foo.xml');
$httpResponse = new HTTP\ResponseMock();
$server->httpResponse = $httpResponse;
$server->addPlugin($caldav);
$caldav->httpGet($server->httpRequest, $server->httpResponse);
$this->assertEquals(200, $httpResponse->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
'ETag' => ['"1"'],
], $httpResponse->getHeaders());
$expected =
'<?xml version="1.0" encoding="UTF-8"?>
<cs:notification xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:cs="http://calendarserver.org/ns/">
<cs:systemstatus type="high"/>
</cs:notification>
';
$this->assertXmlStringEqualsXmlString($expected, $httpResponse->getBodyAsString());
}
function testGETPassthrough() {
$server = new DAV\Server();
$caldav = new Plugin();
$httpResponse = new HTTP\ResponseMock();
$server->httpResponse = $httpResponse;
$server->addPlugin($caldav);
$this->assertNull($caldav->httpGet(new HTTP\Request('GET', '/foozz'), $server->httpResponse));
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace Sabre\CalDAV\Principal;
use Sabre\DAVACL;
class CollectionTest extends \PHPUnit_Framework_TestCase {
function testGetChildForPrincipal() {
$back = new DAVACL\PrincipalBackend\Mock();
$col = new Collection($back);
$r = $col->getChildForPrincipal([
'uri' => 'principals/admin',
]);
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\User', $r);
}
}

View File

@ -1,102 +0,0 @@
<?php
namespace Sabre\CalDAV\Principal;
use Sabre\DAVACL;
class ProxyReadTest extends \PHPUnit_Framework_TestCase {
protected $backend;
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
$principal = new ProxyRead($backend, [
'uri' => 'principal/user',
]);
$this->backend = $backend;
return $principal;
}
function testGetName() {
$i = $this->getInstance();
$this->assertEquals('calendar-proxy-read', $i->getName());
}
function testGetDisplayName() {
$i = $this->getInstance();
$this->assertEquals('calendar-proxy-read', $i->getDisplayName());
}
function testGetLastModified() {
$i = $this->getInstance();
$this->assertNull($i->getLastModified());
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
function testDelete() {
$i = $this->getInstance();
$i->delete();
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
function testSetName() {
$i = $this->getInstance();
$i->setName('foo');
}
function testGetAlternateUriSet() {
$i = $this->getInstance();
$this->assertEquals([], $i->getAlternateUriSet());
}
function testGetPrincipalUri() {
$i = $this->getInstance();
$this->assertEquals('principal/user/calendar-proxy-read', $i->getPrincipalUrl());
}
function testGetGroupMemberSet() {
$i = $this->getInstance();
$this->assertEquals([], $i->getGroupMemberSet());
}
function testGetGroupMembership() {
$i = $this->getInstance();
$this->assertEquals([], $i->getGroupMembership());
}
function testSetGroupMemberSet() {
$i = $this->getInstance();
$i->setGroupMemberSet(['principals/foo']);
$expected = [
$i->getPrincipalUrl() => ['principals/foo']
];
$this->assertEquals($expected, $this->backend->groupMembers);
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace Sabre\CalDAV\Principal;
use Sabre\DAVACL;
class ProxyWriteTest extends ProxyReadTest {
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
$principal = new ProxyWrite($backend, [
'uri' => 'principal/user',
]);
$this->backend = $backend;
return $principal;
}
function testGetName() {
$i = $this->getInstance();
$this->assertEquals('calendar-proxy-write', $i->getName());
}
function testGetDisplayName() {
$i = $this->getInstance();
$this->assertEquals('calendar-proxy-write', $i->getDisplayName());
}
function testGetPrincipalUri() {
$i = $this->getInstance();
$this->assertEquals('principal/user/calendar-proxy-write', $i->getPrincipalUrl());
}
}

View File

@ -1,127 +0,0 @@
<?php
namespace Sabre\CalDAV\Principal;
use Sabre\DAVACL;
class UserTest extends \PHPUnit_Framework_TestCase {
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
$backend->addPrincipal([
'uri' => 'principals/user/calendar-proxy-read',
]);
$backend->addPrincipal([
'uri' => 'principals/user/calendar-proxy-write',
]);
$backend->addPrincipal([
'uri' => 'principals/user/random',
]);
return new User($backend, [
'uri' => 'principals/user',
]);
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
function testCreateFile() {
$u = $this->getInstance();
$u->createFile('test');
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
function testCreateDirectory() {
$u = $this->getInstance();
$u->createDirectory('test');
}
function testGetChildProxyRead() {
$u = $this->getInstance();
$child = $u->getChild('calendar-proxy-read');
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $child);
}
function testGetChildProxyWrite() {
$u = $this->getInstance();
$child = $u->getChild('calendar-proxy-write');
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $child);
}
/**
* @expectedException Sabre\DAV\Exception\NotFound
*/
function testGetChildNotFound() {
$u = $this->getInstance();
$child = $u->getChild('foo');
}
/**
* @expectedException Sabre\DAV\Exception\NotFound
*/
function testGetChildNotFound2() {
$u = $this->getInstance();
$child = $u->getChild('random');
}
function testGetChildren() {
$u = $this->getInstance();
$children = $u->getChildren();
$this->assertEquals(2, count($children));
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyRead', $children[0]);
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\ProxyWrite', $children[1]);
}
function testChildExist() {
$u = $this->getInstance();
$this->assertTrue($u->childExists('calendar-proxy-read'));
$this->assertTrue($u->childExists('calendar-proxy-write'));
$this->assertFalse($u->childExists('foo'));
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => '{DAV:}owner',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user/calendar-proxy-write',
'protected' => true,
],
];
$u = $this->getInstance();
$this->assertEquals($expected, $u->getACL());
}
}

View File

@ -1,92 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\HTTP\Request;
use Sabre\VObject;
class DeliverNewEventTest extends \Sabre\DAVServerTest {
public $setupCalDAV = true;
public $setupCalDAVScheduling = true;
public $setupACL = true;
public $autoLogin = 'user1';
function setUp() {
parent::setUp();
$this->caldavBackend->createCalendar(
'principals/user1',
'default',
[
]
);
$this->caldavBackend->createCalendar(
'principals/user2',
'default',
[
]
);
}
function testDelivery() {
$request = new Request('PUT', '/calendars/user1/default/foo.ics');
$request->setBody(<<<ICS
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//Mac OS X 10.9.1//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20140109T204404Z
UID:AADC6438-18CF-4B52-8DD2-EF9AD75ADE83
DTEND;TZID=America/Toronto:20140107T110000
TRANSP:OPAQUE
ATTENDEE;CN="Administrator";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:user1.sabredav@sabredav.org
ATTENDEE;CN="Roxy Kesh";CUTYPE=INDIVIDUAL;EMAIL="user2.sabredav@sabrdav.org";
PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:user2.sabredav@sabredav.org
SUMMARY:Just testing!
DTSTART;TZID=America/Toronto:20140107T100000
DTSTAMP:20140109T204422Z
ORGANIZER;CN="Administrator":mailto:user1.sabredav@sabredav.org
SEQUENCE:4
END:VEVENT
END:VCALENDAR
ICS
);
$messages = [];
$this->server->on('schedule', function($message) use (&$messages) {
$messages[] = $message;
});
$response = $this->request($request);
$this->assertEquals(201, $response->getStatus(), 'Incorrect status code received. Response body:' . $response->getBodyAsString());
$result = $this->request(new Request('GET', '/calendars/user1/default/foo.ics'))->getBody();
$resultVObj = VObject\Reader::read($result);
$this->assertEquals(
'1.2',
$resultVObj->VEVENT->ATTENDEE[1]['SCHEDULE-STATUS']->getValue()
);
$this->assertEquals(1, count($messages));
$message = $messages[0];
$this->assertInstanceOf('\Sabre\VObject\ITip\Message', $message);
$this->assertEquals('mailto:user2.sabredav@sabredav.org', $message->recipient);
$this->assertEquals('Roxy Kesh', $message->recipientName);
$this->assertEquals('mailto:user1.sabredav@sabredav.org', $message->sender);
$this->assertEquals('Administrator', $message->senderName);
$this->assertEquals('REQUEST', $message->method);
$this->assertEquals('REQUEST', $message->message->METHOD->getValue());
}
}

View File

@ -1,611 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\CalDAV;
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
use Sabre\DAV;
use Sabre\DAVACL;
use Sabre\HTTP;
class FreeBusyRequestTest extends \PHPUnit_Framework_TestCase {
protected $plugin;
protected $server;
protected $aclPlugin;
protected $request;
protected $authPlugin;
protected $caldavBackend;
function setUp() {
$caldavNS = '{' . CalDAV\Plugin::NS_CALDAV . '}';
$calendars = [
[
'principaluri' => 'principals/user2',
'id' => 1,
'uri' => 'calendar1',
$caldavNS . 'calendar-timezone' => "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nEND:VTIMEZONE\r\nEND:VCALENDAR",
],
[
'principaluri' => 'principals/user2',
'id' => 2,
'uri' => 'calendar2',
$caldavNS . 'schedule-calendar-transp' => new ScheduleCalendarTransp(ScheduleCalendarTransp::TRANSPARENT),
],
];
$calendarobjects = [
1 => ['1.ics' => [
'uri' => '1.ics',
'calendardata' => 'BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T130000
DURATION:PT1H
END:VEVENT
END:VCALENDAR',
'calendarid' => 1,
]],
2 => ['2.ics' => [
'uri' => '2.ics',
'calendardata' => 'BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20110101T080000
DURATION:PT1H
END:VEVENT
END:VCALENDAR',
'calendarid' => 2,
]]
];
$principalBackend = new DAVACL\PrincipalBackend\Mock();
$this->caldavBackend = new CalDAV\Backend\MockScheduling($calendars, $calendarobjects);
$tree = [
new DAVACL\PrincipalCollection($principalBackend),
new CalDAV\CalendarRoot($principalBackend, $this->caldavBackend),
];
$this->request = HTTP\Sapi::createFromServerArray([
'CONTENT_TYPE' => 'text/calendar',
]);
$this->response = new HTTP\ResponseMock();
$this->server = new DAV\Server($tree);
$this->server->httpRequest = $this->request;
$this->server->httpResponse = $this->response;
$this->aclPlugin = new DAVACL\Plugin();
$this->aclPlugin->allowUnauthenticatedAccess = false;
$this->server->addPlugin($this->aclPlugin);
$authBackend = new DAV\Auth\Backend\Mock();
$authBackend->setPrincipal('principals/user1');
$this->authPlugin = new DAV\Auth\Plugin($authBackend);
// Forcing authentication to work.
$this->authPlugin->beforeMethod($this->request, $this->response);
$this->server->addPlugin($this->authPlugin);
// CalDAV plugin
$this->plugin = new CalDAV\Plugin();
$this->server->addPlugin($this->plugin);
// Scheduling plugin
$this->plugin = new Plugin();
$this->server->addPlugin($this->plugin);
}
function testWrongContentType() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/plain']
);
$this->assertNull(
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse)
);
}
function testNotFound() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/blabla',
['Content-Type' => 'text/calendar']
);
$this->assertNull(
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse)
);
}
function testNotOutbox() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/inbox',
['Content-Type' => 'text/calendar']
);
$this->assertNull(
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse)
);
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
function testNoItipMethod() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
BEGIN:VFREEBUSY
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse);
}
/**
* @expectedException \Sabre\DAV\Exception\NotImplemented
*/
function testNoVFreeBusy() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VEVENT
END:VEVENT
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse);
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
function testIncorrectOrganizer() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:john@wayne.org
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse);
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
function testNoAttendees() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse);
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
function testNoDTStart() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->plugin->httpPost($this->server->httpRequest, $this->server->httpResponse);
}
function testSucceed() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
ATTENDEE:mailto:user3.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
// Lazily making the current principal an admin.
$this->aclPlugin->adminPrincipals[] = 'principals/user1';
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<d:href>mailto:user3.sabredav@sabredav.org</d:href>',
'<cal:request-status>2.0;Success</cal:request-status>',
'<cal:request-status>3.7;Could not find principal</cal:request-status>',
'FREEBUSY:20110101T120000Z/20110101T130000Z',
];
foreach ($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string) !== false,
'The response body did not contain: ' . $string . 'Full response: ' . $this->response->body
);
}
$this->assertTrue(
strpos($this->response->body, 'FREEBUSY;FBTYPE=BUSY:20110101T080000Z/20110101T090000Z') == false,
'The response body did contain free busy info from a transparent calendar.'
);
}
/**
* Testing if the freebusy request still works, even if there are no
* calendars in the target users' account.
*/
function testSucceedNoCalendars() {
// Deleting calendars
$this->caldavBackend->deleteCalendar(1);
$this->caldavBackend->deleteCalendar(2);
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
// Lazily making the current principal an admin.
$this->aclPlugin->adminPrincipals[] = 'principals/user1';
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<cal:request-status>2.0;Success</cal:request-status>',
];
foreach ($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string) !== false,
'The response body did not contain: ' . $string . 'Full response: ' . $this->response->body
);
}
}
function testNoCalendarHomeFound() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
// Lazily making the current principal an admin.
$this->aclPlugin->adminPrincipals[] = 'principals/user1';
// Removing the calendar home
$this->server->on('propFind', function(DAV\PropFind $propFind) {
$propFind->set('{' . Plugin::NS_CALDAV . '}calendar-home-set', null, 403);
});
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<cal:request-status>3.7;No calendar-home-set property found</cal:request-status>',
];
foreach ($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string) !== false,
'The response body did not contain: ' . $string . 'Full response: ' . $this->response->body
);
}
}
function testNoInboxFound() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
// Lazily making the current principal an admin.
$this->aclPlugin->adminPrincipals[] = 'principals/user1';
// Removing the inbox
$this->server->on('propFind', function(DAV\PropFind $propFind) {
$propFind->set('{' . Plugin::NS_CALDAV . '}schedule-inbox-URL', null, 403);
});
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<cal:request-status>3.7;No schedule-inbox-URL property found</cal:request-status>',
];
foreach ($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string) !== false,
'The response body did not contain: ' . $string . 'Full response: ' . $this->response->body
);
}
}
function testSucceedUseVAVAILABILITY() {
$this->server->httpRequest = new HTTP\Request(
'POST',
'/calendars/user1/outbox',
['Content-Type' => 'text/calendar']
);
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
// Lazily making the current principal an admin.
$this->aclPlugin->adminPrincipals[] = 'principals/user1';
// Adding VAVAILABILITY manually
$this->server->on('propFind', function(DAV\PropFind $propFind) {
$propFind->handle('{' . Plugin::NS_CALDAV . '}calendar-availability', function() {
$avail = <<<ICS
BEGIN:VCALENDAR
BEGIN:VAVAILABILITY
DTSTART:20110101T000000Z
DTEND:20110102T000000Z
BEGIN:AVAILABLE
DTSTART:20110101T090000Z
DTEND:20110101T170000Z
END:AVAILABLE
END:VAVAILABILITY
END:VCALENDAR
ICS;
return $avail;
});
});
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => ['application/xml'],
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<cal:request-status>2.0;Success</cal:request-status>',
'FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20110101T080000Z/20110101T090000Z',
'FREEBUSY:20110101T120000Z/20110101T130000Z',
'FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:20110101T170000Z/20110101T180000Z',
];
foreach ($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string) !== false,
'The response body did not contain: ' . $string . 'Full response: ' . $this->response->body
);
}
}
/*
function testNoPrivilege() {
$this->markTestIncomplete('Currently there\'s no "no privilege" situation');
$this->server->httpRequest = HTTP\Sapi::createFromServerArray(array(
'CONTENT_TYPE' => 'text/calendar',
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
));
$body = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
DTSTART:20110101T080000Z
DTEND:20110101T180000Z
END:VFREEBUSY
END:VCALENDAR
ICS;
$this->server->httpRequest->setBody($body);
$this->assertFalse(
$this->plugin->httpPost($this->server->httpRequest, $this->response)
);
$this->assertEquals(200, $this->response->status);
$this->assertEquals([
'Content-Type' => 'application/xml',
], $this->response->getHeaders());
$strings = [
'<d:href>mailto:user2.sabredav@sabredav.org</d:href>',
'<cal:request-status>3.7;No calendar-home-set property found</cal:request-status>',
];
foreach($strings as $string) {
$this->assertTrue(
strpos($this->response->body, $string)!==false,
'The response body did not contain: ' . $string .'Full response: ' . $this->response->body
);
}
}*/
}

View File

@ -1,50 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule\IMip;
/**
* iMIP handler.
*
* This class is responsible for sending out iMIP messages. iMIP is the
* email-based transport for iTIP. iTIP deals with scheduling operations for
* iCalendar objects.
*
* If you want to customize the email that gets sent out, you can do so by
* extending this class and overriding the sendMessage method.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class MockPlugin extends \Sabre\CalDAV\Schedule\IMipPlugin {
protected $emails = [];
/**
* This function is responsible for sending the actual email.
*
* @param string $to Recipient email address
* @param string $subject Subject of the email
* @param string $body iCalendar body
* @param array $headers List of headers
* @return void
*/
protected function mail($to, $subject, $body, array $headers) {
$this->emails[] = [
'to' => $to,
'subject' => $subject,
'body' => $body,
'headers' => $headers,
];
}
function getSentEmails() {
return $this->emails;
}
}

View File

@ -1,221 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\DAV\Server;
use Sabre\VObject\ITip\Message;
use Sabre\VObject\Reader;
class IMipPluginTest extends \PHPUnit_Framework_TestCase {
function testGetPluginInfo() {
$plugin = new IMipPlugin('system@example.com');
$this->assertEquals(
'imip',
$plugin->getPluginInfo()['name']
);
}
function testDeliverReply() {
$message = new Message();
$message->sender = 'mailto:sender@example.org';
$message->senderName = 'Sender';
$message->recipient = 'mailto:recipient@example.org';
$message->recipientName = 'Recipient';
$message->method = 'REPLY';
$ics = <<<ICS
BEGIN:VCALENDAR\r
METHOD:REPLY\r
BEGIN:VEVENT\r
SUMMARY:Birthday party\r
END:VEVENT\r
END:VCALENDAR\r
ICS;
$message->message = Reader::read($ics);
$result = $this->schedule($message);
$expected = [
[
'to' => 'Recipient <recipient@example.org>',
'subject' => 'Re: Birthday party',
'body' => $ics,
'headers' => [
'Reply-To: Sender <sender@example.org>',
'From: system@example.org',
'Content-Type: text/calendar; charset=UTF-8; method=REPLY',
'X-Sabre-Version: ' . \Sabre\DAV\Version::VERSION,
],
]
];
$this->assertEquals($expected, $result);
}
function testDeliverReplyNoMailto() {
$message = new Message();
$message->sender = 'mailto:sender@example.org';
$message->senderName = 'Sender';
$message->recipient = 'http://example.org/recipient';
$message->recipientName = 'Recipient';
$message->method = 'REPLY';
$ics = <<<ICS
BEGIN:VCALENDAR\r
METHOD:REPLY\r
BEGIN:VEVENT\r
SUMMARY:Birthday party\r
END:VEVENT\r
END:VCALENDAR\r
ICS;
$message->message = Reader::read($ics);
$result = $this->schedule($message);
$expected = [];
$this->assertEquals($expected, $result);
}
function testDeliverRequest() {
$message = new Message();
$message->sender = 'mailto:sender@example.org';
$message->senderName = 'Sender';
$message->recipient = 'mailto:recipient@example.org';
$message->recipientName = 'Recipient';
$message->method = 'REQUEST';
$ics = <<<ICS
BEGIN:VCALENDAR\r
METHOD:REQUEST\r
BEGIN:VEVENT\r
SUMMARY:Birthday party\r
END:VEVENT\r
END:VCALENDAR\r
ICS;
$message->message = Reader::read($ics);
$result = $this->schedule($message);
$expected = [
[
'to' => 'Recipient <recipient@example.org>',
'subject' => 'Birthday party',
'body' => $ics,
'headers' => [
'Reply-To: Sender <sender@example.org>',
'From: system@example.org',
'Content-Type: text/calendar; charset=UTF-8; method=REQUEST',
'X-Sabre-Version: ' . \Sabre\DAV\Version::VERSION,
],
]
];
$this->assertEquals($expected, $result);
}
function testDeliverCancel() {
$message = new Message();
$message->sender = 'mailto:sender@example.org';
$message->senderName = 'Sender';
$message->recipient = 'mailto:recipient@example.org';
$message->recipientName = 'Recipient';
$message->method = 'CANCEL';
$ics = <<<ICS
BEGIN:VCALENDAR\r
METHOD:CANCEL\r
BEGIN:VEVENT\r
SUMMARY:Birthday party\r
END:VEVENT\r
END:VCALENDAR\r
ICS;
$message->message = Reader::read($ics);
$result = $this->schedule($message);
$expected = [
[
'to' => 'Recipient <recipient@example.org>',
'subject' => 'Cancelled: Birthday party',
'body' => $ics,
'headers' => [
'Reply-To: Sender <sender@example.org>',
'From: system@example.org',
'Content-Type: text/calendar; charset=UTF-8; method=CANCEL',
'X-Sabre-Version: ' . \Sabre\DAV\Version::VERSION,
],
]
];
$this->assertEquals($expected, $result);
$this->assertEquals('1.1', substr($message->scheduleStatus, 0, 3));
}
function schedule(Message $message) {
$plugin = new IMip\MockPlugin('system@example.org');
$server = new Server();
$server->addPlugin($plugin);
$server->emit('schedule', [$message]);
return $plugin->getSentEmails();
}
function testDeliverInsignificantRequest() {
$message = new Message();
$message->sender = 'mailto:sender@example.org';
$message->senderName = 'Sender';
$message->recipient = 'mailto:recipient@example.org';
$message->recipientName = 'Recipient';
$message->method = 'REQUEST';
$message->significantChange = false;
$ics = <<<ICS
BEGIN:VCALENDAR\r
METHOD:REQUEST\r
BEGIN:VEVENT\r
SUMMARY:Birthday party\r
END:VEVENT\r
END:VCALENDAR\r
ICS;
$message->message = Reader::read($ics);
$result = $this->schedule($message);
$expected = [];
$this->assertEquals($expected, $result);
$this->assertEquals('1.0', $message->getScheduleStatus()[0]);
}
}

View File

@ -1,136 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\CalDAV;
use Sabre\DAV;
class InboxTest extends \PHPUnit_Framework_TestCase {
function testSetup() {
$inbox = new Inbox(
new CalDAV\Backend\MockScheduling(),
'principals/user1'
);
$this->assertEquals('inbox', $inbox->getName());
$this->assertEquals([], $inbox->getChildren());
$this->assertEquals('principals/user1', $inbox->getOwner());
$this->assertEquals(null, $inbox->getGroup());
$this->assertEquals([
[
'privilege' => '{DAV:}read',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}unbind',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}unbind',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{urn:ietf:params:xml:ns:caldav}schedule-deliver',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
], $inbox->getACL());
$ok = false;
}
/**
* @depends testSetup
*/
function testGetChildren() {
$backend = new CalDAV\Backend\MockScheduling();
$inbox = new Inbox(
$backend,
'principals/user1'
);
$this->assertEquals(
0,
count($inbox->getChildren())
);
$backend->createSchedulingObject('principals/user1', 'schedule1.ics', "BEGIN:VCALENDAR\r\nEND:VCALENDAR");
$this->assertEquals(
1,
count($inbox->getChildren())
);
$this->assertInstanceOf('Sabre\CalDAV\Schedule\SchedulingObject', $inbox->getChildren()[0]);
$this->assertEquals(
'schedule1.ics',
$inbox->getChildren()[0]->getName()
);
}
/**
* @depends testGetChildren
*/
function testCreateFile() {
$backend = new CalDAV\Backend\MockScheduling();
$inbox = new Inbox(
$backend,
'principals/user1'
);
$this->assertEquals(
0,
count($inbox->getChildren())
);
$inbox->createFile('schedule1.ics', "BEGIN:VCALENDAR\r\nEND:VCALENDAR");
$this->assertEquals(
1,
count($inbox->getChildren())
);
$this->assertInstanceOf('Sabre\CalDAV\Schedule\SchedulingObject', $inbox->getChildren()[0]);
$this->assertEquals(
'schedule1.ics',
$inbox->getChildren()[0]->getName()
);
}
/**
* @depends testSetup
*/
function testCalendarQuery() {
$backend = new CalDAV\Backend\MockScheduling();
$inbox = new Inbox(
$backend,
'principals/user1'
);
$this->assertEquals(
0,
count($inbox->getChildren())
);
$backend->createSchedulingObject('principals/user1', 'schedule1.ics', "BEGIN:VCALENDAR\r\nEND:VCALENDAR");
$this->assertEquals(
['schedule1.ics'],
$inbox->calendarQuery([
'name' => 'VCALENDAR',
'comp-filters' => [],
'prop-filters' => [],
'is-not-defined' => false
])
);
}
}

View File

@ -1,134 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\HTTP;
class OutboxPostTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupACL = true;
protected $autoLogin = 'user1';
protected $setupCalDAVScheduling = true;
function testPostPassThruNotFound() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/notfound',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$this->assertHTTPStatus(501, $req);
}
function testPostPassThruNotTextCalendar() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
]);
$this->assertHTTPStatus(501, $req);
}
function testPostPassThruNoOutBox() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$this->assertHTTPStatus(501, $req);
}
function testInvalidIcalBody() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$req->setBody('foo');
$this->assertHTTPStatus(400, $req);
}
function testNoVEVENT() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$body = [
'BEGIN:VCALENDAR',
'BEGIN:VTIMEZONE',
'END:VTIMEZONE',
'END:VCALENDAR',
];
$req->setBody(implode("\r\n", $body));
$this->assertHTTPStatus(400, $req);
}
function testNoMETHOD() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$body = [
'BEGIN:VCALENDAR',
'BEGIN:VEVENT',
'END:VEVENT',
'END:VCALENDAR',
];
$req->setBody(implode("\r\n", $body));
$this->assertHTTPStatus(400, $req);
}
function testUnsupportedMethod() {
$req = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/outbox',
'HTTP_ORIGINATOR' => 'mailto:user1.sabredav@sabredav.org',
'HTTP_RECIPIENT' => 'mailto:user2@example.org',
'HTTP_CONTENT_TYPE' => 'text/calendar',
]);
$body = [
'BEGIN:VCALENDAR',
'METHOD:PUBLISH',
'BEGIN:VEVENT',
'END:VEVENT',
'END:VCALENDAR',
];
$req->setBody(implode("\r\n", $body));
$this->assertHTTPStatus(501, $req);
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\CalDAV;
use Sabre\DAV;
class OutboxTest extends \PHPUnit_Framework_TestCase {
function testSetup() {
$outbox = new Outbox('principals/user1');
$this->assertEquals('outbox', $outbox->getName());
$this->assertEquals([], $outbox->getChildren());
$this->assertEquals('principals/user1', $outbox->getOwner());
$this->assertEquals(null, $outbox->getGroup());
$this->assertEquals([
[
'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
],
[
'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
], $outbox->getACL());
}
}

View File

@ -1,39 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
class PluginBasicTest extends \Sabre\DAVServerTest {
public $setupCalDAV = true;
public $setupCalDAVScheduling = true;
function testSimple() {
$plugin = new Plugin();
$this->assertEquals(
'caldav-schedule',
$plugin->getPluginInfo()['name']
);
}
function testOptions() {
$plugin = new Plugin();
$expected = [
'calendar-auto-schedule',
'calendar-availability',
];
$this->assertEquals($expected, $plugin->getFeatures());
}
function testGetHTTPMethods() {
$this->assertEquals([], $this->caldavSchedulePlugin->getHTTPMethods('notfound'));
$this->assertEquals([], $this->caldavSchedulePlugin->getHTTPMethods('calendars/user1'));
$this->assertEquals(['POST'], $this->caldavSchedulePlugin->getHTTPMethods('calendars/user1/outbox'));
}
}

View File

@ -1,146 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\DAV;
class PluginPropertiesTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupCalDAVScheduling = true;
protected $setupPropertyStorage = true;
function setUp() {
parent::setUp();
$this->caldavBackend->createCalendar(
'principals/user1',
'default',
[
]
);
$this->principalBackend->addPrincipal([
'uri' => 'principals/user1/calendar-proxy-read'
]);
}
function testPrincipalProperties() {
$props = $this->server->getPropertiesForPath('/principals/user1', [
'{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL',
'{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',
'{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',
'{urn:ietf:params:xml:ns:caldav}calendar-user-type',
'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL',
]);
$this->assertArrayHasKey(0, $props);
$this->assertArrayHasKey(200, $props[0]);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals('calendars/user1/outbox/', $prop->getHref());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals('calendars/user1/inbox/', $prop->getHref());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-address-set', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-address-set'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals(['mailto:user1.sabredav@sabredav.org', '/principals/user1/'], $prop->getHrefs());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-type', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-type'];
$this->assertEquals('INDIVIDUAL', $prop);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL'];
$this->assertEquals('calendars/user1/default/', $prop->getHref());
}
function testPrincipalPropertiesBadPrincipal() {
$props = $this->server->getPropertiesForPath('principals/user1/calendar-proxy-read', [
'{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL',
'{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',
'{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',
'{urn:ietf:params:xml:ns:caldav}calendar-user-type',
'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL',
]);
$this->assertArrayHasKey(0, $props);
$this->assertArrayHasKey(200, $props[0]);
$this->assertArrayHasKey(404, $props[0]);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL', $props[0][404]);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL', $props[0][404]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-address-set'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals(['/principals/user1/calendar-proxy-read/'], $prop->getHrefs());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-type', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-type'];
$this->assertEquals('INDIVIDUAL', $prop);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL', $props[0][404]);
}
function testNoDefaultCalendar() {
foreach ($this->caldavBackend->getCalendarsForUser('principals/user1') as $calendar) {
$this->caldavBackend->deleteCalendar($calendar['id']);
}
$props = $this->server->getPropertiesForPath('/principals/user1', [
'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL',
]);
$this->assertArrayHasKey(0, $props);
$this->assertArrayHasKey(404, $props[0]);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL', $props[0][404]);
}
/**
* There are two properties for availability. The server should
* automatically map the old property to the standard property.
*/
function testAvailabilityMapping() {
$path = 'calendars/user1/inbox';
$oldProp = '{http://calendarserver.org/ns/}calendar-availability';
$newProp = '{urn:ietf:params:xml:ns:caldav}calendar-availability';
$value1 = 'first value';
$value2 = 'second value';
// Storing with the old name
$this->server->updateProperties($path, [
$oldProp => $value1
]);
// Retrieving with the new name
$this->assertEquals(
[$newProp => $value1],
$this->server->getProperties($path, [$newProp])
);
// Storing with the new name
$this->server->updateProperties($path, [
$newProp => $value2
]);
// Retrieving with the old name
$this->assertEquals(
[$oldProp => $value2],
$this->server->getProperties($path, [$oldProp])
);
}
}

View File

@ -1,71 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\DAV;
class PluginPropertiesWithSharedCalendarTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupCalDAVScheduling = true;
protected $setupCalDAVSharing = true;
function setUp() {
parent::setUp();
$this->caldavBackend->createCalendar(
'principals/user1',
'shared',
[
'share-access' => DAV\Sharing\Plugin::ACCESS_READWRITE
]
);
$this->caldavBackend->createCalendar(
'principals/user1',
'default',
[
]
);
}
function testPrincipalProperties() {
$props = $this->server->getPropertiesForPath('/principals/user1', [
'{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL',
'{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL',
'{urn:ietf:params:xml:ns:caldav}calendar-user-address-set',
'{urn:ietf:params:xml:ns:caldav}calendar-user-type',
'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL',
]);
$this->assertArrayHasKey(0, $props);
$this->assertArrayHasKey(200, $props[0]);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-outbox-URL'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals('calendars/user1/outbox/', $prop->getHref());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-inbox-URL'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals('calendars/user1/inbox/', $prop->getHref());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-address-set', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-address-set'];
$this->assertTrue($prop instanceof DAV\Xml\Property\Href);
$this->assertEquals(['mailto:user1.sabredav@sabredav.org', '/principals/user1/'], $prop->getHrefs());
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}calendar-user-type', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}calendar-user-type'];
$this->assertEquals('INDIVIDUAL', $prop);
$this->assertArrayHasKey('{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL', $props[0][200]);
$prop = $props[0][200]['{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL'];
$this->assertEquals('calendars/user1/default/', $prop->getHref());
}
}

View File

@ -1,666 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\HTTP\Request;
use Sabre\VObject;
class ScheduleDeliverTest extends \Sabre\DAVServerTest {
use VObject\PHPUnitAssertions;
public $setupCalDAV = true;
public $setupCalDAVScheduling = true;
public $setupACL = true;
public $autoLogin = 'user1';
public $caldavCalendars = [
[
'principaluri' => 'principals/user1',
'uri' => 'cal',
],
[
'principaluri' => 'principals/user2',
'uri' => 'cal',
],
];
function setUp() {
$this->calendarObjectUri = '/calendars/user1/cal/object.ics';
parent::setUp();
}
function testNewInvite() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver(null, $newObject);
$this->assertItemsInInbox('user2', 1);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=1.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testNewOnWrongCollection() {
$newObject = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->calendarObjectUri = '/calendars/user1/object.ics';
$this->deliver(null, $newObject);
$this->assertItemsInInbox('user2', 0);
}
function testNewInviteSchedulingDisabled() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver(null, $newObject, true);
$this->assertItemsInInbox('user2', 0);
}
function testUpdatedInvite() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$oldObject = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 1);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=1.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testUpdatedInviteSchedulingDisabled() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver($oldObject, $newObject, true);
$this->assertItemsInInbox('user2', 0);
}
function testUpdatedInviteWrongPath() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->calendarObjectUri = '/calendars/user1/inbox/foo.ics';
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 0);
}
function testDeletedInvite() {
$newObject = null;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 1);
}
function testDeletedInviteSchedulingDisabled() {
$newObject = null;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver($oldObject, $newObject, true);
$this->assertItemsInInbox('user2', 0);
}
/**
* A MOVE request will trigger an unbind on a scheduling resource.
*
* However, we must not treat it as a cancellation, it just got moved to a
* different calendar.
*/
function testUnbindIgnoredOnMove() {
$newObject = null;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->server->httpRequest->setMethod('MOVE');
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 0);
}
function testDeletedInviteWrongUrl() {
$newObject = null;
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->calendarObjectUri = '/calendars/user1/inbox/foo.ics';
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 0);
}
function testReply() {
$oldObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user2.sabredav@sabredav.org
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2.sabredav@sabredav.org
ATTENDEE:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user3.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user2.sabredav@sabredav.org
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2.sabredav@sabredav.org
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user3.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->putPath('calendars/user2/cal/foo.ics', $oldObject);
$this->deliver($oldObject, $newObject);
$this->assertItemsInInbox('user2', 1);
$this->assertItemsInInbox('user1', 0);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER;SCHEDULE-STATUS=1.2:mailto:user2.sabredav@sabredav.org
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user2.sabredav@sabredav.org
ATTENDEE;PARTSTAT=ACCEPTED:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user3.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteUnknownUser() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user3.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=3.7:mailto:user3.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteNoInboxUrl() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->server->on('propFind', function($propFind) {
$propFind->set('{' . Plugin::NS_CALDAV . '}schedule-inbox-URL', null, 403);
});
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=5.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteNoCalendarHomeSet() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->server->on('propFind', function($propFind) {
$propFind->set('{' . Plugin::NS_CALDAV . '}calendar-home-set', null, 403);
});
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=5.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteNoDefaultCalendar() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->server->on('propFind', function($propFind) {
$propFind->set('{' . Plugin::NS_CALDAV . '}schedule-default-calendar-URL', null, 403);
});
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=5.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteNoScheduler() {
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->server->removeAllListeners('schedule');
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=5.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
function testInviteNoACLPlugin() {
$this->setupACL = false;
parent::setUp();
$newObject = <<<ICS
BEGIN:VCALENDAR
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE:mailto:user2.sabredav@sabredav.org
END:VEVENT
END:VCALENDAR
ICS;
$this->deliver(null, $newObject);
$expected = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:foo
DTSTART:20140811T230000Z
ORGANIZER:mailto:user1.sabredav@sabredav.org
ATTENDEE;SCHEDULE-STATUS=5.2:mailto:user2.sabredav@sabredav.org
DTSTAMP:**ANY**
END:VEVENT
END:VCALENDAR
ICS;
$this->assertVObjectEqualsVObject(
$expected,
$newObject
);
}
protected $calendarObjectUri;
function deliver($oldObject, &$newObject, $disableScheduling = false) {
$this->server->httpRequest->setUrl($this->calendarObjectUri);
if ($disableScheduling) {
$this->server->httpRequest->setHeader('Schedule-Reply', 'F');
}
if ($oldObject && $newObject) {
// update
$this->putPath($this->calendarObjectUri, $oldObject);
$stream = fopen('php://memory', 'r+');
fwrite($stream, $newObject);
rewind($stream);
$modified = false;
$this->server->emit('beforeWriteContent', [
$this->calendarObjectUri,
$this->server->tree->getNodeForPath($this->calendarObjectUri),
&$stream,
&$modified
]);
if ($modified) {
$newObject = $stream;
}
} elseif ($oldObject && !$newObject) {
// delete
$this->putPath($this->calendarObjectUri, $oldObject);
$this->caldavSchedulePlugin->beforeUnbind(
$this->calendarObjectUri
);
} else {
// create
$stream = fopen('php://memory', 'r+');
fwrite($stream, $newObject);
rewind($stream);
$modified = false;
$this->server->emit('beforeCreateFile', [
$this->calendarObjectUri,
&$stream,
$this->server->tree->getNodeForPath(dirname($this->calendarObjectUri)),
&$modified
]);
if ($modified) {
$newObject = $stream;
}
}
}
/**
* Creates or updates a node at the specified path.
*
* This circumvents sabredav's internal server apis, so all events and
* access control is skipped.
*
* @param string $path
* @param string $data
* @return void
*/
function putPath($path, $data) {
list($parent, $base) = \Sabre\HTTP\UrlUtil::splitPath($path);
$parentNode = $this->server->tree->getNodeForPath($parent);
/*
if ($parentNode->childExists($base)) {
$childNode = $parentNode->getChild($base);
$childNode->put($data);
} else {*/
$parentNode->createFile($base, $data);
//}
}
function assertItemsInInbox($user, $count) {
$inboxNode = $this->server->tree->getNodeForPath('calendars/' . $user . '/inbox');
$this->assertEquals($count, count($inboxNode->getChildren()));
}
}

View File

@ -1,378 +0,0 @@
<?php
namespace Sabre\CalDAV\Schedule;
use Sabre\CalDAV\Backend;
class SchedulingObjectTest extends \PHPUnit_Framework_TestCase {
/**
* @var Sabre\CalDAV\Backend_PDO
*/
protected $backend;
/**
* @var Sabre\CalDAV\Calendar
*/
protected $calendar;
protected $principalBackend;
protected $data;
protected $data2;
function setup() {
if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$this->backend = new Backend\MockScheduling();
$this->data = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VEVENT
SEQUENCE:1
END:VEVENT
END:VCALENDAR
ICS;
$this->data = <<<ICS
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VEVENT
SEQUENCE:2
END:VEVENT
END:VCALENDAR
ICS;
$this->inbox = new Inbox($this->backend, 'principals/user1');
$this->inbox->createFile('item1.ics', $this->data);
}
function teardown() {
unset($this->inbox);
unset($this->backend);
}
function testSetup() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$this->assertInternalType('string', $children[0]->getName());
$this->assertInternalType('string', $children[0]->get());
$this->assertInternalType('string', $children[0]->getETag());
$this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType());
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg1() {
$obj = new SchedulingObject(
new Backend\MockScheduling([], []),
[],
[]
);
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg2() {
$obj = new SchedulingObject(
new Backend\MockScheduling([], []),
[],
['calendarid' => '1']
);
}
/**
* @depends testSetup
* @expectedException \Sabre\DAV\Exception\MethodNotAllowed
*/
function testPut() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$children[0]->put('');
}
/**
* @depends testSetup
*/
function testDelete() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$obj->delete();
$children2 = $this->inbox->getChildren();
$this->assertEquals(count($children) - 1, count($children2));
}
/**
* @depends testSetup
*/
function testGetLastModified() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$lastMod = $obj->getLastModified();
$this->assertTrue(is_int($lastMod) || ctype_digit($lastMod) || is_null($lastMod));
}
/**
* @depends testSetup
*/
function testGetSize() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$size = $obj->getSize();
$this->assertInternalType('int', $size);
}
function testGetOwner() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$this->assertEquals('principals/user1', $obj->getOwner());
}
function testGetGroup() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$this->assertNull($obj->getGroup());
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => '{DAV:}owner',
'protected' => true,
],
[
'privilege' => '{DAV:}all',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
];
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$this->assertEquals($expected, $obj->getACL());
}
function testDefaultACL() {
$backend = new Backend\MockScheduling([], []);
$calendarObject = new SchedulingObject($backend, ['calendarid' => 1, 'uri' => 'foo', 'principaluri' => 'principals/user1']);
$expected = [
[
'privilege' => '{DAV:}all',
'principal' => '{DAV:}owner',
'protected' => true,
],
[
'privilege' => '{DAV:}all',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
],
];
$this->assertEquals($expected, $calendarObject->getACL());
}
/**
* @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$obj->setACL([]);
}
function testGet() {
$children = $this->inbox->getChildren();
$this->assertTrue($children[0] instanceof SchedulingObject);
$obj = $children[0];
$this->assertEquals($this->data, $obj->get());
}
function testGetRefetch() {
$backend = new Backend\MockScheduling();
$backend->createSchedulingObject('principals/user1', 'foo', 'foo');
$obj = new SchedulingObject($backend, [
'calendarid' => 1,
'uri' => 'foo',
'principaluri' => 'principals/user1',
]);
$this->assertEquals('foo', $obj->get());
}
function testGetEtag1() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'etag' => 'bar',
'calendarid' => 1
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals('bar', $obj->getETag());
}
function testGetEtag2() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
}
function testGetSupportedPrivilegesSet() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertNull($obj->getSupportedPrivilegeSet());
}
function testGetSize1() {
$objectInfo = [
'calendardata' => 'foo',
'uri' => 'foo',
'calendarid' => 1
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals(3, $obj->getSize());
}
function testGetSize2() {
$objectInfo = [
'uri' => 'foo',
'calendarid' => 1,
'size' => 4,
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals(4, $obj->getSize());
}
function testGetContentType() {
$objectInfo = [
'uri' => 'foo',
'calendarid' => 1,
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals('text/calendar; charset=utf-8', $obj->getContentType());
}
function testGetContentType2() {
$objectInfo = [
'uri' => 'foo',
'calendarid' => 1,
'component' => 'VEVENT',
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals('text/calendar; charset=utf-8; component=VEVENT', $obj->getContentType());
}
function testGetACL2() {
$objectInfo = [
'uri' => 'foo',
'calendarid' => 1,
'acl' => [],
];
$backend = new Backend\MockScheduling([], []);
$obj = new SchedulingObject($backend, $objectInfo);
$this->assertEquals([], $obj->getACL());
}
}

View File

@ -1,176 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV\Sharing;
use Sabre\DAV\Xml\Element\Sharee;
class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
protected $backend;
function getInstance(array $props = null) {
if (is_null($props)) {
$props = [
'id' => 1,
'{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
'{http://sabredav.org/ns}owner-principal' => 'principals/owner',
'{http://sabredav.org/ns}read-only' => false,
'share-access' => Sharing\Plugin::ACCESS_READWRITE,
'principaluri' => 'principals/sharee',
];
}
$this->backend = new Backend\MockSharing(
[$props],
[],
[]
);
$sharee = new Sharee();
$sharee->href = 'mailto:removeme@example.org';
$sharee->properties['{DAV:}displayname'] = 'To be removed';
$sharee->access = Sharing\Plugin::ACCESS_READ;
$this->backend->updateInvites(1, [$sharee]);
return new SharedCalendar($this->backend, $props);
}
function testGetInvites() {
$sharee = new Sharee();
$sharee->href = 'mailto:removeme@example.org';
$sharee->properties['{DAV:}displayname'] = 'To be removed';
$sharee->access = Sharing\Plugin::ACCESS_READ;
$sharee->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE;
$this->assertEquals(
[$sharee],
$this->getInstance()->getInvites()
);
}
function testGetOwner() {
$this->assertEquals('principals/sharee', $this->getInstance()->getOwner());
}
function testGetACL() {
$expected = [
[
'privilege' => '{DAV:}write',
'principal' => 'principals/sharee',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => 'principals/sharee',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee/calendar-proxy-read',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
];
$this->assertEquals($expected, $this->getInstance()->getACL());
}
function testGetChildACL() {
$expected = [
[
'privilege' => '{DAV:}write',
'principal' => 'principals/sharee',
'protected' => true,
],
[
'privilege' => '{DAV:}write',
'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
],
[
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee/calendar-proxy-read',
'protected' => true,
],
];
$this->assertEquals($expected, $this->getInstance()->getChildACL());
}
function testUpdateInvites() {
$instance = $this->getInstance();
$newSharees = [
new Sharee(),
new Sharee()
];
$newSharees[0]->href = 'mailto:test@example.org';
$newSharees[0]->properties['{DAV:}displayname'] = 'Foo Bar';
$newSharees[0]->comment = 'Booh';
$newSharees[0]->access = Sharing\Plugin::ACCESS_READWRITE;
$newSharees[1]->href = 'mailto:removeme@example.org';
$newSharees[1]->access = Sharing\Plugin::ACCESS_NOACCESS;
$instance->updateInvites($newSharees);
$expected = [
clone $newSharees[0]
];
$expected[0]->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE;
$this->assertEquals($expected, $instance->getInvites());
}
function testPublish() {
$instance = $this->getInstance();
$this->assertNull($instance->setPublishStatus(true));
$this->assertNull($instance->setPublishStatus(false));
}
}

View File

@ -1,396 +0,0 @@
<?php
namespace Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\Xml\Element\Sharee;
use Sabre\HTTP;
class SharingPluginTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupCalDAVSharing = true;
protected $setupACL = true;
protected $autoLogin = 'user1';
function setUp() {
$this->caldavCalendars = [
[
'principaluri' => 'principals/user1',
'id' => 1,
'uri' => 'cal1',
],
[
'principaluri' => 'principals/user1',
'id' => 2,
'uri' => 'cal2',
'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
],
[
'principaluri' => 'principals/user1',
'id' => 3,
'uri' => 'cal3',
],
];
parent::setUp();
// Making the logged in user an admin, for full access:
$this->aclPlugin->adminPrincipals[] = 'principals/user2';
}
function testSimple() {
$this->assertInstanceOf('Sabre\\CalDAV\\SharingPlugin', $this->server->getPlugin('caldav-sharing'));
$this->assertEquals(
'caldav-sharing',
$this->caldavSharingPlugin->getPluginInfo()['name']
);
}
/**
* @expectedException \LogicException
*/
function testSetupWithoutCoreSharingPlugin() {
$server = new DAV\Server();
$server->addPlugin(
new SharingPlugin()
);
}
function testGetFeatures() {
$this->assertEquals(['calendarserver-sharing'], $this->caldavSharingPlugin->getFeatures());
}
function testBeforeGetShareableCalendar() {
// Forcing the server to authenticate:
$this->authPlugin->beforeMethod(new HTTP\Request(), new HTTP\Response());
$props = $this->server->getProperties('calendars/user1/cal1', [
'{' . Plugin::NS_CALENDARSERVER . '}invite',
'{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
]);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes', $props['{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes']);
}
function testBeforeGetSharedCalendar() {
$props = $this->server->getProperties('calendars/user1/cal2', [
'{' . Plugin::NS_CALENDARSERVER . '}shared-url',
'{' . Plugin::NS_CALENDARSERVER . '}invite',
]);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
//$this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']);
}
function testUpdateResourceType() {
$this->caldavBackend->updateInvites(1,
[
new Sharee([
'href' => 'mailto:joe@example.org',
])
]
);
$result = $this->server->updateProperties('calendars/user1/cal1', [
'{DAV:}resourcetype' => new DAV\Xml\Property\ResourceType(['{DAV:}collection'])
]);
$this->assertEquals([
'{DAV:}resourcetype' => 200
], $result);
$this->assertEquals(0, count($this->caldavBackend->getInvites(1)));
}
function testUpdatePropertiesPassThru() {
$result = $this->server->updateProperties('calendars/user1/cal3', [
'{DAV:}foo' => 'bar',
]);
$this->assertEquals([
'{DAV:}foo' => 200,
], $result);
}
function testUnknownMethodNoPOST() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PATCH',
'REQUEST_URI' => '/',
]);
$response = $this->request($request);
$this->assertEquals(501, $response->status, $response->body);
}
function testUnknownMethodNoXML() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/',
'CONTENT_TYPE' => 'text/plain',
]);
$response = $this->request($request);
$this->assertEquals(501, $response->status, $response->body);
}
function testUnknownMethodNoNode() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/foo',
'CONTENT_TYPE' => 'text/xml',
]);
$response = $this->request($request);
$this->assertEquals(501, $response->status, $response->body);
}
function testShareRequest() {
$request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']);
$xml = <<<RRR
<?xml version="1.0"?>
<cs:share xmlns:cs="http://calendarserver.org/ns/" xmlns:d="DAV:">
<cs:set>
<d:href>mailto:joe@example.org</d:href>
<cs:common-name>Joe Shmoe</cs:common-name>
<cs:read-write />
</cs:set>
<cs:remove>
<d:href>mailto:nancy@example.org</d:href>
</cs:remove>
</cs:share>
RRR;
$request->setBody($xml);
$response = $this->request($request, 200);
$this->assertEquals(
[
new Sharee([
'href' => 'mailto:joe@example.org',
'properties' => [
'{DAV:}displayname' => 'Joe Shmoe',
],
'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE,
'comment' => '',
]),
],
$this->caldavBackend->getInvites(1)
);
// Wiping out tree cache
$this->server->tree->markDirty('');
// Verifying that the calendar is now marked shared.
$props = $this->server->getProperties('calendars/user1/cal1', ['{DAV:}resourcetype']);
$this->assertTrue(
$props['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared-owner')
);
}
function testShareRequestNoShareableCalendar() {
$request = new HTTP\Request(
'POST',
'/calendars/user1/cal2',
['Content-Type' => 'text/xml']
);
$xml = '<?xml version="1.0"?>
<cs:share xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
<cs:set>
<d:href>mailto:joe@example.org</d:href>
<cs:common-name>Joe Shmoe</cs:common-name>
<cs:read-write />
</cs:set>
<cs:remove>
<d:href>mailto:nancy@example.org</d:href>
</cs:remove>
</cs:share>
';
$request->setBody($xml);
$response = $this->request($request, 403);
}
function testInviteReply() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1',
'CONTENT_TYPE' => 'text/xml',
]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
<cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
<cs:invite-accepted />
</cs:invite-reply>
';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(200, $response->status, $response->body);
}
function testInviteBadXML() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1',
'CONTENT_TYPE' => 'text/xml',
]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
</cs:invite-reply>
';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(400, $response->status, $response->body);
}
function testInviteWrongUrl() {
$request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/cal1',
'CONTENT_TYPE' => 'text/xml',
]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
<cs:hosturl><d:href>/principals/owner</d:href></cs:hosturl>
</cs:invite-reply>
';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(501, $response->status, $response->body);
// If the plugin did not handle this request, it must ensure that the
// body is still accessible by other plugins.
$this->assertEquals($xml, $request->getBody(true));
}
function testPublish() {
$request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']);
$xml = '<?xml version="1.0"?>
<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(202, $response->status, $response->body);
}
function testUnpublish() {
$request = new HTTP\Request(
'POST',
'/calendars/user1/cal1',
['Content-Type' => 'text/xml']
);
$xml = '<?xml version="1.0"?>
<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(200, $response->status, $response->body);
}
function testPublishWrongUrl() {
$request = new HTTP\Request(
'POST',
'/calendars/user1',
['Content-Type' => 'text/xml']
);
$xml = '<?xml version="1.0"?>
<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
$this->request($request, 501);
}
function testUnpublishWrongUrl() {
$request = new HTTP\Request(
'POST',
'/calendars/user1',
['Content-Type' => 'text/xml']
);
$xml = '<?xml version="1.0"?>
<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
$this->request($request, 501);
}
function testUnknownXmlDoc() {
$request = new HTTP\Request(
'POST',
'/calendars/user1/cal2',
['Content-Type' => 'text/xml']
);
$xml = '<?xml version="1.0"?>
<cs:foo-bar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />';
$request->setBody($xml);
$response = $this->request($request);
$this->assertEquals(501, $response->status, $response->body);
}
}

View File

@ -1,123 +0,0 @@
<?php
namespace Sabre\CalDAV\Subscriptions;
use Sabre\CalDAV;
use Sabre\HTTP\Request;
class CreateSubscriptionTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
protected $setupCalDAVSubscriptions = true;
/**
* OS X 10.7 - 10.9.1
*/
function testMKCOL() {
$body = <<<XML
<A:mkcol xmlns:A="DAV:">
<A:set>
<A:prop>
<B:subscribed-strip-attachments xmlns:B="http://calendarserver.org/ns/" />
<B:subscribed-strip-todos xmlns:B="http://calendarserver.org/ns/" />
<A:resourcetype>
<A:collection />
<B:subscribed xmlns:B="http://calendarserver.org/ns/" />
</A:resourcetype>
<E:calendar-color xmlns:E="http://apple.com/ns/ical/">#1C4587FF</E:calendar-color>
<A:displayname>Jewish holidays</A:displayname>
<C:calendar-description xmlns:C="urn:ietf:params:xml:ns:caldav">Foo</C:calendar-description>
<E:calendar-order xmlns:E="http://apple.com/ns/ical/">19</E:calendar-order>
<B:source xmlns:B="http://calendarserver.org/ns/">
<A:href>webcal://www.example.org/</A:href>
</B:source>
<E:refreshrate xmlns:E="http://apple.com/ns/ical/">P1W</E:refreshrate>
<B:subscribed-strip-alarms xmlns:B="http://calendarserver.org/ns/" />
</A:prop>
</A:set>
</A:mkcol>
XML;
$headers = [
'Content-Type' => 'application/xml',
];
$request = new Request('MKCOL', '/calendars/user1/subscription1', $headers, $body);
$response = $this->request($request);
$this->assertEquals(201, $response->getStatus());
$subscriptions = $this->caldavBackend->getSubscriptionsForUser('principals/user1');
$this->assertSubscription($subscriptions[0]);
}
/**
* OS X 10.9.2 and up
*/
function testMKCALENDAR() {
$body = <<<XML
<B:mkcalendar xmlns:B="urn:ietf:params:xml:ns:caldav">
<A:set xmlns:A="DAV:">
<A:prop>
<B:supported-calendar-component-set>
<B:comp name="VEVENT" />
</B:supported-calendar-component-set>
<C:subscribed-strip-alarms xmlns:C="http://calendarserver.org/ns/" />
<C:subscribed-strip-attachments xmlns:C="http://calendarserver.org/ns/" />
<A:resourcetype>
<A:collection />
<C:subscribed xmlns:C="http://calendarserver.org/ns/" />
</A:resourcetype>
<D:refreshrate xmlns:D="http://apple.com/ns/ical/">P1W</D:refreshrate>
<C:source xmlns:C="http://calendarserver.org/ns/">
<A:href>webcal://www.example.org/</A:href>
</C:source>
<D:calendar-color xmlns:D="http://apple.com/ns/ical/">#1C4587FF</D:calendar-color>
<D:calendar-order xmlns:D="http://apple.com/ns/ical/">19</D:calendar-order>
<B:calendar-description>Foo</B:calendar-description>
<C:subscribed-strip-todos xmlns:C="http://calendarserver.org/ns/" />
<A:displayname>Jewish holidays</A:displayname>
</A:prop>
</A:set>
</B:mkcalendar>
XML;
$headers = [
'Content-Type' => 'application/xml',
];
$request = new Request('MKCALENDAR', '/calendars/user1/subscription1', $headers, $body);
$response = $this->request($request);
$this->assertEquals(201, $response->getStatus());
$subscriptions = $this->caldavBackend->getSubscriptionsForUser('principals/user1');
$this->assertSubscription($subscriptions[0]);
// Also seeing if it works when calling this as a PROPFIND.
$this->assertEquals([
'{http://calendarserver.org/ns/}subscribed-strip-alarms' => '',
],
$this->server->getProperties('calendars/user1/subscription1', ['{http://calendarserver.org/ns/}subscribed-strip-alarms'])
);
}
function assertSubscription($subscription) {
$this->assertEquals('', $subscription['{http://calendarserver.org/ns/}subscribed-strip-attachments']);
$this->assertEquals('', $subscription['{http://calendarserver.org/ns/}subscribed-strip-todos']);
$this->assertEquals('#1C4587FF', $subscription['{http://apple.com/ns/ical/}calendar-color']);
$this->assertEquals('Jewish holidays', $subscription['{DAV:}displayname']);
$this->assertEquals('Foo', $subscription['{urn:ietf:params:xml:ns:caldav}calendar-description']);
$this->assertEquals('19', $subscription['{http://apple.com/ns/ical/}calendar-order']);
$this->assertEquals('webcal://www.example.org/', $subscription['{http://calendarserver.org/ns/}source']->getHref());
$this->assertEquals('P1W', $subscription['{http://apple.com/ns/ical/}refreshrate']);
$this->assertEquals('subscription1', $subscription['uri']);
$this->assertEquals('principals/user1', $subscription['principaluri']);
$this->assertEquals('webcal://www.example.org/', $subscription['source']);
$this->assertEquals(['principals/user1', 1], $subscription['id']);
}
}

View File

@ -1,50 +0,0 @@
<?php
namespace Sabre\CalDAV\Subscriptions;
use Sabre\DAV\PropFind;
class PluginTest extends \PHPUnit_Framework_TestCase {
function testInit() {
$server = new \Sabre\DAV\Server();
$plugin = new Plugin();
$server->addPlugin($plugin);
$this->assertEquals(
'{http://calendarserver.org/ns/}subscribed',
$server->resourceTypeMapping['Sabre\\CalDAV\\Subscriptions\\ISubscription']
);
$this->assertEquals(
'Sabre\\DAV\\Xml\\Property\\Href',
$server->xml->elementMap['{http://calendarserver.org/ns/}source']
);
$this->assertEquals(
['calendarserver-subscribed'],
$plugin->getFeatures()
);
$this->assertEquals(
'subscriptions',
$plugin->getPluginInfo()['name']
);
}
function testPropFind() {
$propName = '{http://calendarserver.org/ns/}subscribed-strip-alarms';
$propFind = new PropFind('foo', [$propName]);
$propFind->set($propName, null, 200);
$plugin = new Plugin();
$plugin->propFind($propFind, new \Sabre\DAV\SimpleCollection('hi'));
$this->assertFalse(is_null($propFind->get($propName)));
}
}

Some files were not shown because too many files have changed in this diff Show More