Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions src/models/calendarTrashBin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { DavCollection } from './davCollection.js'
import * as NS from '../utility/namespaceUtility.js'
import { VObject } from './vobject.js'
import { DeletedCalendarObject } from './deletedCalendarObject.js'
import * as XMLUtility from '../utility/xmlUtility.js'

export class CalendarTrashBin extends DavCollection {
Expand All @@ -20,7 +20,7 @@ export class CalendarTrashBin extends DavCollection {
constructor(...args) {
super(...args)

super._registerObjectFactory('text/calendar', VObject)
super._registerObjectFactory('text/calendar', DeletedCalendarObject)

super._exposeProperty('retentionDuration', NS.NEXTCLOUD, 'trash-bin-retention-duration')
}
Expand All @@ -31,12 +31,8 @@ export class CalendarTrashBin extends DavCollection {
)
skeleton.children.push({
name: [NS.DAV, 'prop'],
children: VObject.getPropFindList()
.map((p) => ({ name: p }))
.concat([
{ name: [NS.NEXTCLOUD, 'calendar-uri'] },
{ name: [NS.NEXTCLOUD, 'deleted-at'] },
]),
children: DeletedCalendarObject.getPropFindList()
.map((p) => ({ name: p })),
})
skeleton.children.push({
name: [NS.IETF_CALDAV, 'filter'],
Expand Down
60 changes: 60 additions & 0 deletions src/models/deletedCalendarObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* CDAV Library
*
* This library is part of the Nextcloud project
*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { VObject } from './vobject.js'
import * as NS from '../utility/namespaceUtility.js'

/**
* This class represents a deleted calendar object from a calendar trash bin.
*
* @augments VObject
*/
export class DeletedCalendarObject extends VObject {

/**
* @inheritDoc
*/
constructor(...args) {
super(...args)

super._exposeProperty('calendarUri', NS.NEXTCLOUD, 'calendar-uri')
super._exposeProperty('sourceCalendarUri', NS.NEXTCLOUD, 'source-calendar-uri')
super._exposeProperty('calendarOwnerPrincipalUri', NS.NEXTCLOUD, 'calendar-owner-principal-uri')
super._exposeProperty('deletedAt', NS.NEXTCLOUD, 'deleted-at')
}

get calendarUri() {
return this._props[`{${NS.NEXTCLOUD}}calendar-uri`]
}

get sourceCalendarUri() {
return this._props[`{${NS.NEXTCLOUD}}source-calendar-uri`]
}

get calendarOwnerPrincipalUri() {
return this._props[`{${NS.NEXTCLOUD}}calendar-owner-principal-uri`]
}

get deletedAt() {
return this._props[`{${NS.NEXTCLOUD}}deleted-at`]
}

/**
* @inheritDoc
*/
static getPropFindList() {
return super.getPropFindList().concat([
[NS.NEXTCLOUD, 'calendar-uri'],
[NS.NEXTCLOUD, 'source-calendar-uri'],
[NS.NEXTCLOUD, 'calendar-owner-principal-uri'],
[NS.NEXTCLOUD, 'deleted-at'],
])
}

}
2 changes: 2 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ export default class Parser {
this.registerParser('{http://nextcloud.com/ns}owner-displayname', Parser.text)
this.registerParser('{http://nextcloud.com/ns}deleted-at', Parser.iso8601DateTime)
this.registerParser('{http://nextcloud.com/ns}calendar-uri', Parser.text)
this.registerParser('{http://nextcloud.com/ns}source-calendar-uri', Parser.text)
this.registerParser('{http://nextcloud.com/ns}calendar-owner-principal-uri', Parser.text)
this.registerParser('{http://nextcloud.com/ns}has-photo', Parser.bool)
this.registerParser('{http://nextcloud.com/ns}favorite', Parser.bool)
this.registerParser('{http://nextcloud.com/ns}trash-bin-retention-duration', Parser.decInt)
Expand Down
57 changes: 57 additions & 0 deletions test/unit/models/deletedCalendarObjectTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* CDAV Library
*
* This library is part of the Nextcloud project
*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { describe, expect, it } from 'vitest'

import { DeletedCalendarObject } from '../../../src/models/deletedCalendarObject.js'
import { VObject } from '../../../src/models/vobject.js'
import RequestMock from '../../mocks/request.mock.js'
import { DavCollection as DavCollectionMock } from '../../mocks/davCollection.mock.js'

describe('DeletedCalendarObject model', () => {

it('should inherit from VObject', () => {
const parent = new DavCollectionMock()
const request = new RequestMock()
const url = '/trash-bin/objects/deleted.ics'
const props = {
'{DAV:}getetag': '"etag"',
'{DAV:}getcontenttype': 'text/calendar',
'{DAV:}resourcetype': [],
'{urn:ietf:params:xml:ns:caldav}calendar-data': 'BEGIN:VCALENDAR\nEND:VCALENDAR',
}

const object = new DeletedCalendarObject(parent, request, url, props)
expect(object).toEqual(expect.any(VObject))
})

it('should expose deleted calendar object properties', () => {
const parent = new DavCollectionMock()
const request = new RequestMock()
const url = '/trash-bin/objects/deleted.ics'
const props = {
'{DAV:}getetag': '"etag"',
'{DAV:}getcontenttype': 'text/calendar',
'{DAV:}resourcetype': [],
'{urn:ietf:params:xml:ns:caldav}calendar-data': 'BEGIN:VCALENDAR\nEND:VCALENDAR',
'{http://nextcloud.com/ns}calendar-uri': 'calendar-1',
'{http://nextcloud.com/ns}source-calendar-uri': 'source',
'{http://nextcloud.com/ns}calendar-owner-principal-uri': 'principals/users/user',
'{http://nextcloud.com/ns}deleted-at': new Date('2026-05-20T10:11:12Z'),
}

const object = new DeletedCalendarObject(parent, request, url, props)

expect(object.calendarUri).toEqual('calendar-1')
expect(object.sourceCalendarUri).toEqual('source')
expect(object.calendarOwnerPrincipalUri).toEqual('principals/users/user')
expect(object.deletedAt).toEqual(new Date('2026-05-20T10:11:12Z'))
})

})
Loading