Skip to content

Commit

Permalink
fix(calendar): filter by matching property values
Browse files Browse the repository at this point in the history
Added test for calendar-query DAV request
  • Loading branch information
cgx committed May 24, 2022
1 parent dec49c2 commit 5452cd7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 13 deletions.
10 changes: 6 additions & 4 deletions SoObjects/Appointments/SOGoAppointmentFolder.m
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ - (NSArray *) bareFetchFields: (NSArray *) fields

if ([title length])
[baseWhere
addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'",
addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '*%@*'",
[title asSafeSQLLikeString]]];

if (component)
Expand Down Expand Up @@ -1576,14 +1576,14 @@ - (NSArray *) fetchFields: (NSArray *) _fields
{
if ([filters isEqualToString:@"title_Category_Location"] || [filters isEqualToString:@"entireContent"])
{
[baseWhere addObject: [NSString stringWithFormat: @"(c_title isCaseInsensitiveLike: '%%%@%%' OR c_category isCaseInsensitiveLike: '%%%@%%' OR c_location isCaseInsensitiveLike: '%%%@%%')",
[baseWhere addObject: [NSString stringWithFormat: @"(c_title isCaseInsensitiveLike: '*%@*' OR c_category isCaseInsensitiveLike: '*%@*' OR c_location isCaseInsensitiveLike: '*%@*')",
[title asSafeSQLLikeString],
[title asSafeSQLLikeString],
[title asSafeSQLLikeString]]];
}
}
else
[baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '%%%@%%'",
[baseWhere addObject: [NSString stringWithFormat: @"c_title isCaseInsensitiveLike: '*%@*'",
[title asSafeSQLLikeString]]];
}

Expand Down Expand Up @@ -1954,7 +1954,7 @@ - (NSString *) _additionalFilterKey: (NSString *) key
filterString = [NSString stringWithFormat: @"(%@ = '')", key];
else
filterString
= [NSString stringWithFormat: @"(%@ like '%%%@%%')", key, value];
= [NSString stringWithFormat: @"(%@ like '*%@*')", key, value];
}
else
filterString = [NSString stringWithFormat: @"(%@ != '')", key];
Expand Down Expand Up @@ -2169,6 +2169,8 @@ - (NSDictionary *) davSQLFieldsTable
return davSQLFieldsTable;
}

// CALDAV:calendar-query REPORT
// https://datatracker.ietf.org/doc/html/rfc4791#section-7.8
- (id) davCalendarQuery: (id) queryContext
{
WOResponse *r;
Expand Down
8 changes: 4 additions & 4 deletions SoObjects/Appointments/SOGoAppointmentObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -1731,10 +1731,10 @@ - (NSException *) changeParticipationStatus: (NSString *) _status
ex = [self exceptionWithHTTPStatus: 404 // Not Found
reason: @"user does not participate in this calendar event"];
}
else
ex = [self exceptionWithHTTPStatus: 500 // Server Error
reason: @"unable to parse event record"];
else
ex = [self exceptionWithHTTPStatus: 500 // Server Error
reason: @"unable to parse event record"];

return ex;
}

Expand Down
14 changes: 14 additions & 0 deletions Tests/lib/WebDAV.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
propfind,

calendarMultiGet,
calendarQuery,
createCalendarObject,
makeCalendar,

Expand Down Expand Up @@ -408,6 +409,19 @@ class WebDAV {
})
}

calendarQuery(resource, filters) {
return calendarQuery({
url: this.serverUrl + resource,
headers: this.headers,
depth: '1',
props: [
{ name: 'getetag', namespace: DAVNamespace.DAV },
{ name: 'calendar-data', namespace: DAVNamespace.CALDAV },
],
filters,
})
}

calendarMultiGet(resource, filename) {
return calendarMultiGet({
url: this.serverUrl + resource,
Expand Down
61 changes: 61 additions & 0 deletions Tests/spec/CalDAVPropertiesSpec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import config from '../lib/config'
import WebDAV from '../lib/WebDAV'
import TestUtility from '../lib/utilities'

describe('read and set calendar properties', function() {
const webdav = new WebDAV(config.username, config.password)
const utility = new TestUtility(webdav)
const resource = `/SOGo/dav/${config.username}/Calendar/test-dav-properties/`

beforeEach(async function() {
Expand Down Expand Up @@ -56,6 +58,65 @@ describe('read and set calendar properties', function() {
expect(results[0].status)
.withContext(`Setting transparency to ${newValueNode} is successful`)
.toBe(207)
})

it("calendar-query", async function() {
const filename = `new.ics`
const event = `BEGIN:VCALENDAR
PRODID:-//Inverse//Event Generator//EN
VERSION:2.0
BEGIN:VEVENT
SEQUENCE:0
TRANSP:OPAQUE
UID:1234567890
SUMMARY:Visit to the museum of fine arts
DTSTART:20090805T100000Z
DTEND:20090805T140000Z
CLASS:PUBLIC
DESCRIPTION:description
LOCATION:location
DTSTAMP:20090805T100000Z
END:VEVENT
END:VCALENDAR`

let response = await webdav.createCalendarObject(resource, filename, event)
expect(response.status).toBe(201)

response = await webdav.calendarQuery(
resource,
[
{
type: 'comp-filter',
attributes: { name: 'VCALENDAR' },
children: [
{
type: 'comp-filter',
attributes: { name: 'VEVENT' },
children: [
{
type: 'prop-filter',
attributes: { name: 'TITLE' },
children: [
{
type: 'text-match',
value: 'museum'
}
]
}
]
}
]
}
]
)
expect(response.length)
.withContext(`Number of results from calendar-query`)
.toBe(1)
expect(response[0].status)
.withContext(`HTTP status code of calendar-query`)
.toEqual(207)
expect(utility.componentsAreEqual(response[0].props.calendarData, event))
.withContext(`Returned vCalendar matches ${filename}`)
.toBe(true)
})
})
14 changes: 9 additions & 5 deletions Tests/spec/DAVCalendarAppleiCalSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ describe('Apple iCal', function() {
.toContain(`/SOGo/dav/${config.username}/`)
}

beforeEach(async function() {
await _setMemberSet(config.username, [], 'read')
await _setMemberSet(config.username, [], 'write')
await _setMemberSet(config.subscriber_username, [], 'read')
await _setMemberSet(config.subscriber_username, [], 'write')
await _setMemberSet(config.superuser, [], 'read')
await _setMemberSet(config.superuser, [], 'write')
})

// iCalTest

it(`principal-collection-set: 'DAV' header must be returned with iCal 4`, async function() {
Expand Down Expand Up @@ -127,11 +136,6 @@ describe('Apple iCal', function() {
it(`calendar-proxy as used from iCal`, async function() {
let membership, perm, users, proxyFor

await _setMemberSet(config.username, [], 'read')
await _setMemberSet(config.username, [], 'write')
await _setMemberSet(config.subscriber_username, [], 'read')
await _setMemberSet(config.subscriber_username, [], 'write')

membership = await _getMembership(config.username)
expect(membership.length)
.toBe(0)
Expand Down

0 comments on commit 5452cd7

Please sign in to comment.