diff --git a/controller/viewcontroller.php b/controller/viewcontroller.php index dd50db6447..b7261b9715 100644 --- a/controller/viewcontroller.php +++ b/controller/viewcontroller.php @@ -23,6 +23,7 @@ */ namespace OCA\Calendar\Controller; +use OC\AppFramework\Http\Request; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\TemplateResponse; @@ -111,6 +112,7 @@ public function index() { } $webCalWorkaround = $runningOnNextcloud10OrLater ? 'no' : 'yes'; + $isIE = $this->request->isUserAgent([Request::USER_AGENT_IE]); return new TemplateResponse('calendar', 'main', [ 'appVersion' => $appVersion, @@ -123,6 +125,7 @@ public function index() { 'defaultColor' => $defaultColor, 'webCalWorkaround' => $webCalWorkaround, 'isPublic' => false, + 'isIE' => $isIE, 'needsAutosize' => $needsAutosize, ]); } @@ -148,6 +151,7 @@ public function publicIndex() { } $appVersion = $this->config->getAppValue($this->appName, 'installed_version'); + $isIE = $this->request->isUserAgent([Request::USER_AGENT_IE]); $response = new TemplateResponse('calendar', 'main', [ 'appVersion' => $appVersion, @@ -157,6 +161,7 @@ public function publicIndex() { 'weekNumbers' => 'no', 'supportsClass' => $supportsClass, 'firstRun' => 'no', + 'isIE' => $isIE, 'webCalWorkaround' => 'no', 'isPublic' => true, 'shareURL' => $this->request->getServerProtocol() . '://' . $this->request->getServerHost() . $this->request->getRequestUri(), diff --git a/js/app/service/calendarService.js b/js/app/service/calendarService.js index 58297e1126..ab0dd8dbce 100644 --- a/js/app/service/calendarService.js +++ b/js/app/service/calendarService.js @@ -64,10 +64,10 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca ]; const UPDATABLE_PROPERTIES_MAP = { - color: 'a:calendar-color', - displayname: 'd:displayname', - enabled: 'o:calendar-enabled', - order: 'a:calendar-order' + color: [DavClient.NS_APPLE, 'a:calendar-color'], + displayname: [DavClient.NS_DAV, 'd:displayname'], + enabled: [DavClient.NS_OWNCLOUD, 'o:calendar-enabled'], + order: [DavClient.NS_APPLE, 'a:calendar-order'] }; const SHARE_USER = constants.SHARE_TYPE_USER; @@ -287,35 +287,37 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca */ this.create = function(name, color, components=['vevent', 'vtodo']) { return context.bootPromise.then(function() { - const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton('d:mkcol', 'd:set', 'd:prop'); + const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton( + [DavClient.NS_DAV, 'd:mkcol'], [DavClient.NS_DAV, 'd:set'], + [DavClient.NS_DAV, 'd:prop']); dPropChildren.push({ - name: 'd:resourcetype', + name: [DavClient.NS_DAV, 'd:resourcetype'], children: [{ - name: 'd:collection' + name: [DavClient.NS_DAV, 'd:collection'] }, { - name: 'c:calendar' + name: [DavClient.NS_IETF, 'c:calendar'] }] }); dPropChildren.push({ - name: 'd:displayname', + name: [DavClient.NS_DAV, 'd:displayname'], value: name }); dPropChildren.push({ - name: 'a:calendar-color', + name: [DavClient.NS_APPLE, 'a:calendar-color'], value: color }); dPropChildren.push({ - name: 'o:calendar-enabled', + name: [DavClient.NS_OWNCLOUD, 'o:calendar-enabled'], value: '1' }); dPropChildren.push({ - name: 'c:supported-calendar-component-set', + name: [DavClient.NS_IETF, 'c:supported-calendar-component-set'], children: components.map(function(component) { return { - name: 'c:comp', - attributes: { - name: component.toUpperCase() - } + name: [DavClient.NS_IETF, 'c:comp'], + attributes: [ + ['name', component.toUpperCase()] + ] }; }) }); @@ -357,31 +359,33 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca */ this.createWebCal = function(name, color, source) { return context.bootPromise.then(function() { - const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton('d:mkcol', 'd:set', 'd:prop'); + const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton( + [DavClient.NS_DAV, 'd:mkcol'], [DavClient.NS_DAV, 'd:set'], + [DavClient.NS_DAV, 'd:prop']); dPropChildren.push({ - name: 'd:resourcetype', + name: [DavClient.NS_DAV, 'd:resourcetype'], children: [{ - name: 'd:collection' + name: [DavClient.NS_DAV, 'd:collection'] }, { - name: 'cs:subscribed' + name: [DavClient.NS_CALENDARSERVER, 'cs:subscribed'] }] }); dPropChildren.push({ - name: 'd:displayname', + name: [DavClient.NS_DAV, 'd:displayname'], value: name }); dPropChildren.push({ - name: 'a:calendar-color', + name: [DavClient.NS_APPLE, 'a:calendar-color'], value: color }); dPropChildren.push({ - name: 'o:calendar-enabled', + name: [DavClient.NS_OWNCLOUD, 'o:calendar-enabled'], value: '1' }); dPropChildren.push({ - name: 'cs:source', + name: [DavClient.NS_CALENDARSERVER, 'cs:source'], children: [{ - name: 'd:href', + name: [DavClient.NS_DAV, 'd:href'], value: source }] }); @@ -439,7 +443,9 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca return Promise.resolve(calendar); } - const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton('d:propertyupdate', 'd:set', 'd:prop'); + const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton( + [DavClient.NS_DAV, 'd:propertyupdate'], [DavClient.NS_DAV, 'd:set'], + [DavClient.NS_DAV, 'd:prop']); updatedProperties.forEach(function(name) { if (UPDATABLE_PROPERTIES.indexOf(name) === -1) { return; @@ -452,9 +458,9 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca if (name === 'storedUrl') { dPropChildren.push({ - name: 'cs:source', + name: [DavClient.NS_CALENDARSERVER, 'cs:source'], children: [{ - name: 'd:href', + name: [DavClient.NS_DAV, 'd:href'], value: value }] }); @@ -517,15 +523,16 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca * @returns {Promise} */ privateAPI.share = function(calendar, shareType, shareWith, writable, existingShare) { - const [skeleton, oSetChildren] = XMLUtility.getRootSkeleton('o:share', 'o:set'); + const [skeleton, oSetChildren] = XMLUtility.getRootSkeleton( + [DavClient.NS_OWNCLOUD, 'o:share'], [DavClient.NS_OWNCLOUD, 'o:set']); const hrefValue = context.getShareValue(shareType, shareWith); oSetChildren.push({ - name: 'd:href', + name: [DavClient.NS_DAV, 'd:href'], value: hrefValue }); oSetChildren.push({ - name: 'o:summary', + name: [DavClient.NS_OWNCLOUD, 'o:summary'], value: t('calendar', '{calendar} shared by {owner}', { calendar: calendar.displayname, owner: calendar.owner @@ -533,7 +540,7 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca }); if (writable) { oSetChildren.push({ - name: 'o:read-write' + name: [DavClient.NS_OWNCLOUD, 'o:read-write'] }); } @@ -579,11 +586,12 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca * @returns {Promise} */ privateAPI.unshare = function(calendar, shareType, shareWith) { - const [skeleton, oRemoveChildren] = XMLUtility.getRootSkeleton('o:share', 'o:remove'); + const [skeleton, oRemoveChildren] = XMLUtility.getRootSkeleton( + [DavClient.NS_OWNCLOUD, 'o:share'], [DavClient.NS_OWNCLOUD, 'o:remove']); const hrefValue = context.getShareValue(shareType, shareWith); oRemoveChildren.push({ - name: 'd:href', + name: [DavClient.NS_DAV, 'd:href'], value: hrefValue }); @@ -620,7 +628,8 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca * @returns {Promise} */ privateAPI.publish = function(calendar) { - const [skeleton] = XMLUtility.getRootSkeleton('cs:publish-calendar'); + const [skeleton] = XMLUtility.getRootSkeleton( + [DavClient.NS_CALENDARSERVER, 'cs:publish-calendar']); const method = 'POST'; const url = calendar.url; @@ -647,7 +656,8 @@ app.service('CalendarService', function(DavClient, StringUtility, XMLUtility, Ca * @returns {Promise} */ privateAPI.unpublish = function(calendar) { - const [skeleton] = XMLUtility.getRootSkeleton('cs:unpublish-calendar'); + const [skeleton] = XMLUtility.getRootSkeleton( + [DavClient.NS_CALENDARSERVER, 'cs:unpublish-calendar']); const method = 'POST'; const url = calendar.url; diff --git a/js/app/service/veventService.js b/js/app/service/veventService.js index 660cd781a2..8d9b581d0a 100644 --- a/js/app/service/veventService.js +++ b/js/app/service/veventService.js @@ -57,33 +57,33 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve * @returns {Promise} */ this.getAll = function (calendar, start, end) { - const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton('c:calendar-query'); + const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton([DavClient.NS_IETF, 'c:calendar-query']); dPropChildren.push({ - name: 'd:prop', + name: [DavClient.NS_DAV, 'd:prop'], children: [{ - name: 'd:getetag' + name: [DavClient.NS_DAV, 'd:getetag'] }, { - name: 'c:calendar-data' + name: [DavClient.NS_IETF, 'c:calendar-data'] }] }); dPropChildren.push({ - name: 'c:filter', + name: [DavClient.NS_IETF, 'c:filter'], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VCALENDAR' - }, + name: [DavClient.NS_IETF, 'c:comp-filter'], + attributes: [ + ['name', 'VCALENDAR'] + ], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VEVENT' - }, + name: [DavClient.NS_IETF, 'c:comp-filter'], + attributes: [ + ['name', 'VEVENT'] + ], children: [{ - name: 'c:time-range', - attributes: { - start: context.getTimeRangeString(start), - end: context.getTimeRangeString(end) - } + name: [DavClient.NS_IETF, 'c:time-range'], + attributes: [ + ['start', context.getTimeRangeString(start)], + ['end', context.getTimeRangeString(end)] + ] }] }] }] diff --git a/js/app/utility/xmlUtility.js b/js/app/utility/xmlUtility.js index 96824281f3..16c1f1b502 100644 --- a/js/app/utility/xmlUtility.js +++ b/js/app/utility/xmlUtility.js @@ -24,13 +24,16 @@ app.service('XMLUtility', function() { const context = {}; context.XMLify = function(xmlDoc, parent, json) { - const element = xmlDoc.createElement(json.name); + const element = xmlDoc.createElementNS(json.name[0], json.name[1]); - for (let key in json.attributes) { - if (json.attributes.hasOwnProperty(key)) { - element.setAttribute(key, json.attributes[key]); + json.attributes = json.attributes || []; + json.attributes.forEach((a) => { + if (a.length === 2) { + element.setAttribute(a[0], a[1]); + } else { + element.setAttributeNS(a[0], a[1], a[2]); } - } + }); if (json.value) { element.textContent = json.value; @@ -54,14 +57,6 @@ app.service('XMLUtility', function() { const skeleton = { name: arguments[0], - attributes: { - 'xmlns:c': 'urn:ietf:params:xml:ns:caldav', - 'xmlns:d': 'DAV:', - 'xmlns:a': 'http://apple.com/ns/ical/', - 'xmlns:o': 'http://owncloud.org/ns', - 'xmlns:n': 'http://nextcloud.com/ns', - 'xmlns:cs': 'http://calendarserver.org/ns/' - }, children: [] }; @@ -89,6 +84,6 @@ app.service('XMLUtility', function() { const root = document.implementation.createDocument('', '', null); context.XMLify(root, root, json); - return serializer.serializeToString(root.firstChild); + return serializer.serializeToString(root); }; }); diff --git a/js/gulpfile.js b/js/gulpfile.js index 212a982b06..2af94831db 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -37,6 +37,8 @@ const cssBuildTarget = 'app.css'; const cssBuildTargetMin = 'app.min.css'; const vendorTarget = 'vendor.js'; const vendorTargetMin = 'vendor.min.js'; +const vendorIETarget = 'vendor.ie.js'; +const vendorIETargetMin = 'vendor.ie.min.js'; const vendorCssTarget = 'vendor.css'; const vendorCssTargetMin = 'vendor.min.css'; const karmaConfig = __dirname + '/../tests/js/config/karma.js'; @@ -123,6 +125,10 @@ gulp.task('buildVendor', () => { .pipe(concat(vendorCssTarget)) .pipe(gulp.dest(cssDestinationFolder)); + gulp.src(['node_modules/babel-polyfill/dist/polyfill.js'].concat(vendorSources)) + .pipe(concat(vendorIETarget)) + .pipe(gulp.dest(destinationFolder)); + return gulp.src(vendorSources) .pipe(concat(vendorTarget)) .pipe(gulp.dest(destinationFolder)); @@ -139,6 +145,14 @@ gulp.task('minifyVendor', () => { .pipe(sourcemaps.write('./', {includeContent: false})) .pipe(gulp.dest(cssDestinationFolder)); + gulp.src([destinationFolder + vendorIETarget]) + .pipe(concat(vendorIETargetMin)) + .pipe(sourcemaps.init({identityMap: true, largeFile: true})) + .pipe(strip()) + .pipe(uglify()) + .pipe(sourcemaps.write('./', {includeContent: false})) + .pipe(gulp.dest(destinationFolder)); + return gulp.src([destinationFolder + vendorTarget]) .pipe(concat(vendorTargetMin)) .pipe(sourcemaps.init({identityMap: true, largeFile: true})) diff --git a/js/package.json b/js/package.json index 68728cc2c1..25352caa74 100644 --- a/js/package.json +++ b/js/package.json @@ -16,6 +16,7 @@ "url": "https://github.com/nextcloud/calendar/issues" }, "devDependencies": { + "babel-polyfill": "^6.22.0", "babel-preset-es2015": "^6.14.0", "bower": "^1.7.9", "coveralls": "^2.11.12", diff --git a/js/yarn.lock b/js/yarn.lock index 78a9993a1e..2c1099e9bd 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -509,6 +509,14 @@ babel-plugin-transform-strict-mode@^6.18.0: babel-runtime "^6.0.0" babel-types "^6.18.0" +babel-polyfill@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.22.0.tgz#1ac99ebdcc6ba4db1e2618c387b2084a82154a3b" + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-preset-es2015@^6.14.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.18.0.tgz#b8c70df84ec948c43dcf2bf770e988eb7da88312" @@ -557,6 +565,13 @@ babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtim core-js "^2.4.0" regenerator-runtime "^0.10.0" +babel-runtime@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-template@^6.8.0: version "6.16.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.16.0.tgz#e149dd1a9f03a35f817ddbc4d0481988e7ebc8ca" diff --git a/templates/editor.sidebar.php b/templates/editor.sidebar.php index 73eb7be838..b8cc5de53d 100644 --- a/templates/editor.sidebar.php +++ b/templates/editor.sidebar.php @@ -55,6 +55,8 @@ class="checkbox" +
+
diff --git a/templates/main.php b/templates/main.php index 06031682c6..b5de4f2231 100644 --- a/templates/main.php +++ b/templates/main.php @@ -39,15 +39,19 @@ style('calendar', $style); } -$scripts = [ - 'public/vendor.min', - 'public/app.min', -]; - +$scripts = []; +if ($_['isIE']) { + $scripts[] = 'public/vendor.ie.min'; +} else { + $scripts[] = 'public/vendor.min'; +} if ($_['needsAutosize']) { $scripts[] = 'vendor/autosize/dist/autosize'; } +$scripts[] = 'public/app.min'; + + foreach ($scripts as $script) { script('calendar', $script); } diff --git a/tests/js/unit/services/calendarServiceSpec.js b/tests/js/unit/services/calendarServiceSpec.js index 7d32f3b1bc..72b2170c2b 100644 --- a/tests/js/unit/services/calendarServiceSpec.js +++ b/tests/js/unit/services/calendarServiceSpec.js @@ -1084,38 +1084,38 @@ END:VCALENDAR $rootScope.$apply(); expect(dPropChildren).toEqual([{ - name: 'd:resourcetype', + name: ['DAV:', 'd:resourcetype'], children: [{ - name: 'd:collection' + name: ['DAV:', 'd:collection'] }, { - name: 'c:calendar' + name: ['urn:ietf:params:xml:ns:caldav', 'c:calendar'] }] },{ - name: 'd:displayname', + name: ['DAV:', 'd:displayname'], value: 'name-foobar-1337' },{ - name: 'a:calendar-color', + name: ['http://apple.com/ns/ical/', 'a:calendar-color'], value: '#eeeeee' },{ - name: 'o:calendar-enabled', + name: ['http://owncloud.org/ns', 'o:calendar-enabled'], value: '1' },{ - name: 'c:supported-calendar-component-set', + name: ['urn:ietf:params:xml:ns:caldav', 'c:supported-calendar-component-set'], children: [{ - name: 'c:comp', - attributes: { - name: 'VEVENT' - } + name: ['urn:ietf:params:xml:ns:caldav', 'c:comp'], + attributes: [ + ['name', 'VEVENT'] + ] }, { - name: 'c:comp', - attributes: { - name: 'VJOURNAL' - } + name: ['urn:ietf:params:xml:ns:caldav', 'c:comp'], + attributes: [ + ['name', 'VJOURNAL'] + ] }, { - name: 'c:comp', - attributes: { - name: 'VTODO' - } + name: ['urn:ietf:params:xml:ns:caldav', 'c:comp'], + attributes: [ + ['name', 'VTODO'] + ] }] } ]); @@ -1170,7 +1170,7 @@ END:VCALENDAR expect(called).toEqual(true); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('d:mkcol', 'd:set', 'd:prop'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['DAV:', 'd:mkcol'], ['DAV:', 'd:set'], ['DAV:', 'd:prop']); }); it('should create a webcal subscription', function() { @@ -1252,7 +1252,7 @@ END:VCALENDAR expect(called).toEqual(true); expect(result).toEqual(true); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('cs:publish-calendar'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['http://calendarserver.org/ns/', 'cs:publish-calendar']); }); it('should publish a calendar - unsuccessful', function() { @@ -1286,7 +1286,7 @@ END:VCALENDAR expect(called).toEqual(true); expect(result).toEqual(false); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('cs:publish-calendar'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['http://calendarserver.org/ns/', 'cs:publish-calendar']); }); it('should unpublish a calendar', function() { @@ -1320,7 +1320,7 @@ END:VCALENDAR expect(called).toEqual(true); expect(result).toEqual(true); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('cs:unpublish-calendar'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['http://calendarserver.org/ns/', 'cs:unpublish-calendar']); }); it('should unpublish a calendar - unsuccessful', function() { @@ -1354,7 +1354,7 @@ END:VCALENDAR expect(called).toEqual(true); expect(result).toEqual(false); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('cs:unpublish-calendar'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['http://calendarserver.org/ns/', 'cs:unpublish-calendar']); }); }); diff --git a/tests/js/unit/services/veventServiceSpec.js b/tests/js/unit/services/veventServiceSpec.js index f7f5f932b7..8c80c7d028 100644 --- a/tests/js/unit/services/veventServiceSpec.js +++ b/tests/js/unit/services/veventServiceSpec.js @@ -62,32 +62,32 @@ describe('VEventService', function () { const getAllRequest = VEventService.getAll(calendar, start, end); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('c:calendar-query'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['*NSIETF*', 'c:calendar-query']); expect(dPropChildren).toEqual([{ - name: 'd:prop', + name: ['*NSDAV*', 'd:prop'], children: [{ - name: 'd:getetag' + name: ['*NSDAV*', 'd:getetag'] }, { - name: 'c:calendar-data' + name: ['*NSIETF*', 'c:calendar-data'] }] }, { - name: 'c:filter', + name: ['*NSIETF*', 'c:filter'], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VCALENDAR' - }, + name: ['*NSIETF*', 'c:comp-filter'], + attributes: [ + ['name', 'VCALENDAR'] + ], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VEVENT' - }, + name: ['*NSIETF*', 'c:comp-filter'], + attributes: [ + ['name', 'VEVENT'] + ], children: [{ - name: 'c:time-range', - attributes: { - start: '20160828T070000Z', - end: '20161002T065959Z' - } + name: ['*NSIETF*', 'c:time-range'], + attributes: [ + ['start', '20160828T070000Z'], + ['end', '20161002T065959Z'] + ] }] }] }] @@ -160,32 +160,32 @@ describe('VEventService', function () { const getAllRequest = VEventService.getAll(calendar, start, end); - expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith('c:calendar-query'); + expect(XMLUtility.getRootSkeleton).toHaveBeenCalledWith(['*NSIETF*', 'c:calendar-query']); expect(dPropChildren).toEqual([{ - name: 'd:prop', + name: ['*NSDAV*', 'd:prop'], children: [{ - name: 'd:getetag' + name: ['*NSDAV*', 'd:getetag'] }, { - name: 'c:calendar-data' + name: ['*NSIETF*', 'c:calendar-data'] }] }, { - name: 'c:filter', + name: ['*NSIETF*', 'c:filter'], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VCALENDAR' - }, + name: ['*NSIETF*', 'c:comp-filter'], + attributes: [ + ['name', 'VCALENDAR'] + ], children: [{ - name: 'c:comp-filter', - attributes: { - name: 'VEVENT' - }, + name: ['*NSIETF*', 'c:comp-filter'], + attributes: [ + ['name', 'VEVENT'] + ], children: [{ - name: 'c:time-range', - attributes: { - start: '20160828T070000Z', - end: '20161002T065959Z' - } + name: ['*NSIETF*', 'c:time-range'], + attributes: [ + ['start', '20160828T070000Z'], + ['end', '20161002T065959Z'] + ] }] }] }] diff --git a/tests/js/unit/utility/xmlUtilitySpec.js b/tests/js/unit/utility/xmlUtilitySpec.js index b590f5da3b..81af3756dc 100644 --- a/tests/js/unit/utility/xmlUtilitySpec.js +++ b/tests/js/unit/utility/xmlUtilitySpec.js @@ -22,124 +22,118 @@ describe('XMLUtility', function () { it('should return correct xml for one element', function() { expect(XMLUtility.serialize({ - name: 'element' - })).toEqual(''); + name: ['NS123', 'n1:element'] + })).toEqual(''); }); it('should return correct xml for one element with attributes', function() { expect(XMLUtility.serialize({ - name: 'element', - attributes: { - abc: '123', - def: '456' - } - })).toEqual(''); + name: ['NS123', 'n1:element'], + attributes: [ + ['abc', '123'], + ['def', '456'] + ] + })).toEqual(''); }); it('should return correct xml for one element with attributes and value', function() { expect(XMLUtility.serialize({ - name: 'element', - attributes: { - abc: '123', - def: '456' - }, + name: ['NS123', 'n1:element'], + attributes: [ + ['abc', '123'], + ['def', '456'] + ], value: 'test value' - })).toEqual('test value'); + })).toEqual('test value'); }); it('should prefer value over children', function() { expect(XMLUtility.serialize({ - name: 'element', - attributes: { - abc: '123', - def: '456' - }, + name: ['NS123', 'n1:element'], + attributes: [ + ['abc', '123'], + ['def', '456'] + ], value: 'test value', children: [{ name: 'element2' }] - })).toEqual('test value'); + })).toEqual('test value'); }); it('should return correct xml for one child', function() { expect(XMLUtility.serialize({ - name: 'element', - attributes: { - abc: '123', - def: '456' - }, + name: ['NS123', 'n1:element'], + attributes: [ + ['abc', '123'], + ['def', '456'] + ], children: [{ - name: 'element2' + name: ['NS456', 'n2:element2'] }] - })).toEqual(''); + })).toEqual(''); }); it('should return correct xml for multiple children', function() { expect(XMLUtility.serialize({ - name: 'element', - attributes: { - abc: '123', - def: '456' - }, + name: ['NS123', 'ns1:element'], + attributes: [ + ['abc', '123'], + ['def', '456'] + ], children: [{ - name: 'element2' + name: ['NS456', 'ns2:element'] }, { - name: 'element3' + name: ['NS123', 'ns1:element2'] }] - })).toEqual(''); + })).toEqual(''); }); it('should return correct xml for deeply nested objects', function() { expect(XMLUtility.serialize({ - name: 'd:mkcol', - attributes: { - 'xmlns:c': 'urn:ietf:params:xml:ns:caldav', - 'xmlns:d': 'DAV:', - 'xmlns:a': 'http://apple.com/ns/ical/', - 'xmlns:o': 'http://owncloud.org/ns' - }, + name: ['NSDAV', 'd:mkcol'], children: [{ - name: 'd:set', + name: ['NSDAV', 'd:set'], children: [{ - name: 'd:prop', + name: ['NSDAV', 'd:prop'], children: [{ - name: 'd:resourcetype', + name: ['NSDAV', 'd:resourcetype'], children: [{ - name: 'd:collection', + name: ['NSDAV', 'd:collection'], children: [{ - name: 'c:calendar' + name: ['NSCAL', 'c:calendar'] }] }, { - name: 'd:displayname', + name: ['NSDAV', 'd:displayname'], value: 'test_displayname' }, { - name: 'o:calendar-enabled', + name: ['NSOC', 'o:calendar-enabled'], value: 1 }, { - name: 'a:calendar-order', + name: ['NSAAPL', 'a:calendar-order'], value: 42 }, { - name: 'a:calendar-color', + name: ['NSAAPL', 'a:calendar-color'], value: '#00FF00' }, { - name: 'c:supported-calendar-component-set', + name: ['NSCAL', 'c:supported-calendar-component-set'], children: [{ - name: 'c:comp', - attributes: { - name: 'VEVENT' - } + name: ['NSCAL', 'c:comp'], + attributes: [ + ['name', 'VEVENT'] + ] },{ - name: 'c:comp', - attributes: { - name: 'VTODO' - } + name: ['NSCAL', 'c:comp'], + attributes: [ + ['name', 'VTODO'] + ] }] }] }] }] }] - })).toEqual('test_displayname142#00FF00'); + })).toEqual('test_displayname142#00FF00'); }); it('should return an empty object when getRootSkeleton is called with no parameters', function() { @@ -148,63 +142,41 @@ describe('XMLUtility', function () { it('should return the root sceleton correctly for one element', function() { const expected = { - name: 'd:mkcol', - attributes: { - 'xmlns:c': 'urn:ietf:params:xml:ns:caldav', - 'xmlns:d': 'DAV:', - 'xmlns:a': 'http://apple.com/ns/ical/', - 'xmlns:o': 'http://owncloud.org/ns', - 'xmlns:n': 'http://nextcloud.com/ns', - 'xmlns:cs': 'http://calendarserver.org/ns/' - }, + name: ['NSDAV', 'd:mkcol'], children: [] }; - const result = XMLUtility.getRootSkeleton('d:mkcol'); + const result = XMLUtility.getRootSkeleton(['NSDAV', 'd:mkcol']); expect(result).toEqual([expected, expected.children]); expect(result[0].children === result[1]).toBe(true); }); it('should return the root sceleton correctly for two elements', function() { const expected = { - name: 'd:mkcol', - attributes: { - 'xmlns:c': 'urn:ietf:params:xml:ns:caldav', - 'xmlns:d': 'DAV:', - 'xmlns:a': 'http://apple.com/ns/ical/', - 'xmlns:o': 'http://owncloud.org/ns', - 'xmlns:n': 'http://nextcloud.com/ns', - 'xmlns:cs': 'http://calendarserver.org/ns/' - }, + name: ['NSDAV', 'd:mkcol'], children: [{ - name: 'd:set', + name: ['NSDAV', 'd:set'], children: [] }] }; - const result = XMLUtility.getRootSkeleton('d:mkcol', 'd:set'); + const result = XMLUtility.getRootSkeleton(['NSDAV', 'd:mkcol'], + ['NSDAV', 'd:set']); expect(result).toEqual([expected, expected.children[0].children]); expect(result[0].children[0].children === result[1]).toBe(true); }); it('should return the root sceleton correctly for three elements', function() { const expected = { - name: 'd:mkcol', - attributes: { - 'xmlns:c': 'urn:ietf:params:xml:ns:caldav', - 'xmlns:d': 'DAV:', - 'xmlns:a': 'http://apple.com/ns/ical/', - 'xmlns:o': 'http://owncloud.org/ns', - 'xmlns:n': 'http://nextcloud.com/ns', - 'xmlns:cs': 'http://calendarserver.org/ns/' - }, + name: ['NSDAV', 'd:mkcol'], children: [{ - name: 'd:set', + name: ['NSDAV', 'd:set'], children: [{ - name: 'd:prop', + name: ['NSDAV', 'd:prop'], children: [] }] }] }; - const result = XMLUtility.getRootSkeleton('d:mkcol', 'd:set', 'd:prop'); + const result = XMLUtility.getRootSkeleton(['NSDAV', 'd:mkcol'], + ['NSDAV', 'd:set'], ['NSDAV', 'd:prop']); expect(result).toEqual([expected, expected.children[0].children[0].children]); expect(result[0].children[0].children[0].children === result[1]).toBe(true); }); diff --git a/tests/php/controller/viewcontrollerTest.php b/tests/php/controller/viewcontrollerTest.php index 89edf5c275..464e9dc440 100755 --- a/tests/php/controller/viewcontrollerTest.php +++ b/tests/php/controller/viewcontrollerTest.php @@ -60,7 +60,7 @@ public function setUp() { /** * @dataProvider indexDataProvider */ - public function testIndex($isAssetPipelineEnabled, $showAssetPipelineError, $serverVersion, $expectsSupportsClass, $expectsWebcalWorkaround, $needsAutosize) { + public function testIndex($isAssetPipelineEnabled, $showAssetPipelineError, $serverVersion, $expectsSupportsClass, $expectsWebcalWorkaround, $needsAutosize, $isIE) { $this->config->expects($this->at(0)) ->method('getSystemValue') ->with('version') @@ -71,6 +71,13 @@ public function testIndex($isAssetPipelineEnabled, $showAssetPipelineError, $ser ->with('asset-pipeline.enabled', false) ->will($this->returnValue($isAssetPipelineEnabled)); + if (!$showAssetPipelineError) { + $this->request->expects($this->once()) + ->method('isUserAgent') + ->with(['/(MSIE)|(Trident)/']) + ->will($this->returnValue($isIE)); + } + if ($showAssetPipelineError) { $actual = $this->controller->index(); @@ -135,6 +142,7 @@ public function testIndex($isAssetPipelineEnabled, $showAssetPipelineError, $ser 'webCalWorkaround' => $expectsWebcalWorkaround, 'isPublic' => false, 'needsAutosize' => $needsAutosize, + 'isIE' => $isIE, ], $actual->getParams()); $this->assertEquals('main', $actual->getTemplateName()); } @@ -143,11 +151,12 @@ public function testIndex($isAssetPipelineEnabled, $showAssetPipelineError, $ser public function indexDataProvider() { return [ - [true, true, '9.0.5.2', false, 'yes', true], - [true, false, '9.1.0.0', true, 'no', true], - [false, false, '9.0.5.2', false, 'yes', true], - [false, false, '9.1.0.0', true, 'no', true], - [false, false, '11.0.1', true, 'no', false], + [true, true, '9.0.5.2', false, 'yes', true, false], + [true, false, '9.1.0.0', true, 'no', true, false], + [false, false, '9.0.5.2', false, 'yes', true, false], + [false, false, '9.1.0.0', true, 'no', true, false], + [false, false, '11.0.1', true, 'no', false, false], + [false, false, '11.0.1', true, 'no', false, true], ]; } @@ -162,6 +171,11 @@ public function testIndexNoMonthFallback() { ->with('asset-pipeline.enabled', false) ->will($this->returnValue(false)); + $this->request->expects($this->once()) + ->method('isUserAgent') + ->with(['/(MSIE)|(Trident)/']) + ->will($this->returnValue(false)); + $this->userSession->expects($this->once()) ->method('getUser') ->will($this->returnValue($this->dummyUser)); @@ -219,6 +233,7 @@ public function testIndexNoMonthFallback() { 'webCalWorkaround' => 'no', 'isPublic' => false, 'needsAutosize' => true, + 'isIE' => false, ], $actual->getParams()); $this->assertEquals('main', $actual->getTemplateName()); } @@ -237,6 +252,11 @@ public function testIndexFirstRunDetection($initialView, $expectedFirstRun, $exp ->with('asset-pipeline.enabled', false) ->will($this->returnValue(false)); + $this->request->expects($this->once()) + ->method('isUserAgent') + ->with(['/(MSIE)|(Trident)/']) + ->will($this->returnValue(false)); + $this->userSession->expects($this->once()) ->method('getUser') ->will($this->returnValue($this->dummyUser)); @@ -300,6 +320,7 @@ public function testIndexFirstRunDetection($initialView, $expectedFirstRun, $exp 'webCalWorkaround' => 'no', 'isPublic' => false, 'needsAutosize' => true, + 'isIE' => false, ], $actual->getParams()); $this->assertEquals('main', $actual->getTemplateName()); } @@ -314,7 +335,7 @@ public function indexFirstRunDetectionProvider() { /** * @dataProvider indexPublicDataProvider */ - public function testPublicIndex($isAssetPipelineEnabled, $showAssetPipelineError, $serverVersion, $expectsSupportsClass, $needsAutosize) { + public function testPublicIndex($isAssetPipelineEnabled, $showAssetPipelineError, $serverVersion, $expectsSupportsClass, $needsAutosize, $isIE) { $this->config->expects($this->at(0)) ->method('getSystemValue') ->with('version') @@ -325,6 +346,13 @@ public function testPublicIndex($isAssetPipelineEnabled, $showAssetPipelineError ->with('asset-pipeline.enabled', false) ->will($this->returnValue($isAssetPipelineEnabled)); + if (!$showAssetPipelineError) { + $this->request->expects($this->once()) + ->method('isUserAgent') + ->with(['/(MSIE)|(Trident)/']) + ->will($this->returnValue($isIE)); + } + if ($showAssetPipelineError) { $actual = $this->controller->index(); @@ -353,6 +381,7 @@ public function testPublicIndex($isAssetPipelineEnabled, $showAssetPipelineError 'firstRun' => 'no', 'webCalWorkaround' => 'no', 'needsAutosize' => $needsAutosize, + 'isIE' => $isIE, ], $actual->getParams()); $this->assertEquals('main', $actual->getTemplateName()); } @@ -361,11 +390,12 @@ public function testPublicIndex($isAssetPipelineEnabled, $showAssetPipelineError public function indexPublicDataProvider() { return [ - [true, true, '9.0.5.2', false, true], - [true, false, '9.1.0.0', true, true], - [false, false, '9.0.5.2', false, true], - [false, false, '9.1.0.0', true, true], - [false, false, '11.0.0', true, false], + [true, true, '9.0.5.2', false, true, false], + [true, false, '9.1.0.0', true, true, false], + [false, false, '9.0.5.2', false, true, false], + [false, false, '9.1.0.0', true, true, false], + [false, false, '11.0.0', true, false, false], + [false, false, '11.0.0', true, false, true], ]; } }