Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit a2e8972a authored by Georg Ehrke's avatar Georg Ehrke Committed by GitHub
Browse files

Merge pull request #667 from nextcloud/bugfix/589/catch_duplicate_uid_erros

add special treatment for duplicate errors when importing calendars
parents dd3095c8 b4a1460a
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -55,9 +55,21 @@ app.controller('ImportController', ['$scope', '$filter', 'CalendarService', 'VEv
							fileWrapper.errors++;
						}
					}).catch(function(reason) {
						if (reason.status === 400) {
							const xml = reason.xhr.responseXML;
							const error = xml.children[0];

							if (error) {
								const message = error.children[1].textContent;
								if (message === 'Calendar object with uid already exists in this calendar collection.') {
									fileWrapper.duplicates++;
								}
							}
						}

						fileWrapper.state = ImportFileWrapper.stateImporting;
						fileWrapper.progress++;
						fileWrapper.errors++;
						fileWrapper.progress++;
					});
				});
			};
+22 −12
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 * @author Raghu Nayyar
 * @author Georg Ehrke
 * @copyright 2016 Raghu Nayyar <hey@raghunayyar.com>
 * @copyright 2016 Georg Ehrke <oc.list@georgehrke.com>
 * @copyright 2017 Georg Ehrke <oc.list@georgehrke.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -28,18 +28,28 @@ app.filter('importErrorFilter', function () {
			return '';
		}

		//TODO - use n instead of t to use proper plurals in all translations
		switch(file.errors) {
			case 0:
				return t('calendar', 'Successfully imported');

			case 1:
				return t('calendar', 'Partially imported, 1 failure');
		const all = file.progressToReach;
		const errors = (file.errors - file.duplicates);
		const duplicates = file.duplicates;
		const imported = (all - file.errors);

			default:
				return t('calendar', 'Partially imported, {n} failures', {
					n: file.errors
				});
		//TODO - use n instead of t to use proper plurals in all translations
		if (file.errors === 0) {
			return t('calendar', 'Successfully imported {imported} objects', {imported});
		} else if(file.errors === 1) {
			if (file.duplicates === 1) {
				return t('calendar', 'Imported {imported} out of {all}, skipped one duplicate', {all, imported});
			} else {
				return t('calendar', 'Imported {imported} out of {all}, one failure', {all, imported});
			}
		} else {
			if (file.duplicates === 0) {
				return t('calendar', 'Imported {imported} out of {all}, {errors} failures', {all, errors, imported});
			} else if (file.duplicates === file.errors) {
				return t('calendar', 'Imported {imported} out of {all}, skipped {duplicates} duplicates', {all, duplicates, imported});
			} else {
				return t('calendar', 'Imported {imported} out of {all}, {errors} failures, skipped {duplicates} duplicates', {all, duplicates, errors, imported});
			}
		}
	};
});
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ app.factory('ImportFileWrapper', function(Hook, ICalSplitterUtility) {
			progressToReach: -1
		};
		const iface = {
			duplicates: 0,
			_isAImportFileWrapperObject: true
		};

+5 −5
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve

		return DavClient.request('REPORT', url, headers, xml).then(function (response) {
			if (!DavClient.wasRequestSuccessful(response.status)) {
				return Promise.reject(response.status);
				return Promise.reject(response);
			}

			const vevents = [];
@@ -140,7 +140,7 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve

		return DavClient.request('GET', url, headers, '').then(function (response) {
			if (!DavClient.wasRequestSuccessful(response.status)) {
				return Promise.reject(response.status);
				return Promise.reject(response);
			}

			const calendarData = response.body;
@@ -172,7 +172,7 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve

		return DavClient.request('PUT', url, headers, data).then(function (response) {
			if (!DavClient.wasRequestSuccessful(response.status)) {
				return Promise.reject(response.status);
				return Promise.reject(response);
			}

			if (returnEvent) {
@@ -199,7 +199,7 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve

		return DavClient.request('PUT', url, headers, payload).then(function (response) {
			if (!DavClient.wasRequestSuccessful(response.status)) {
				return Promise.reject(response.status);
				return Promise.reject(response);
			}

			// update etag of existing event
@@ -225,7 +225,7 @@ app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEve
			if (DavClient.wasRequestSuccessful(response.status)) {
				return true;
			} else {
				return Promise.reject(response.status);
				return Promise.reject(response);
			}
		});
	};
+21 −8
Original line number Diff line number Diff line
@@ -19,20 +19,33 @@ describe('The importErrorFilter filter', function () {
	});

	it('should be able to handle zero errors', function() {
		expect(filter({errors: 0})).toEqual('Successfully imported');
		expect(t).toHaveBeenCalledWith('calendar', 'Successfully imported');
		expect(filter({progressToReach: 20, errors: 0, duplicates: 0})).toEqual('Successfully imported {imported} objects');
		expect(t).toHaveBeenCalledWith('calendar', 'Successfully imported {imported} objects', {imported: 20});
	});

	it('should be able to display one duplicate', function() {
		expect(filter({progressToReach: 20, errors: 1, duplicates: 1})).toEqual('Imported {imported} out of {all}, skipped one duplicate');
		expect(t).toHaveBeenCalledWith('calendar', 'Imported {imported} out of {all}, skipped one duplicate', {all: 20, imported: 19});
	});

	it('should be able to handle one error', function() {
		expect(filter({errors: 1})).toEqual('Partially imported, 1 failure');
		expect(t).toHaveBeenCalledWith('calendar', 'Partially imported, 1 failure');
		expect(filter({progressToReach: 20, errors: 1, duplicates: 0})).toEqual('Imported {imported} out of {all}, one failure');
		expect(t).toHaveBeenCalledWith('calendar', 'Imported {imported} out of {all}, one failure', {all: 20, imported: 19});
	});

	it('should be able to handle two or more duplicates', function() {
		expect(filter({progressToReach: 20, errors: 2, duplicates: 2})).toEqual('Imported {imported} out of {all}, skipped {duplicates} duplicates');
		expect(t).toHaveBeenCalledWith('calendar', 'Imported {imported} out of {all}, skipped {duplicates} duplicates', {all: 20, imported: 18, duplicates: 2});
	});

	it('should be able to handle two or more errors', function() {
		expect(filter({errors: 2})).toEqual('Partially imported, {n} failures');
		expect(t).toHaveBeenCalledWith('calendar', 'Partially imported, {n} failures', {n:2});
		expect(filter({progressToReach: 20, errors: 2, duplicates: 0})).toEqual('Imported {imported} out of {all}, {errors} failures');
		expect(t).toHaveBeenCalledWith('calendar', 'Imported {imported} out of {all}, {errors} failures', {all: 20, imported: 18, errors: 2});
	});

	it('shoud be able to handle mixed errors and duplicates', function() {
		expect(filter({progressToReach: 20, errors: 5, duplicates: 3})).toEqual('Imported {imported} out of {all}, {errors} failures, skipped {duplicates} duplicates');
		expect(t).toHaveBeenCalledWith('calendar', 'Imported {imported} out of {all}, {errors} failures, skipped {duplicates} duplicates', {all: 20, imported: 15, errors: 2, duplicates: 3});

		expect(filter({errors: 42})).toEqual('Partially imported, {n} failures');
		expect(t).toHaveBeenCalledWith('calendar', 'Partially imported, {n} failures', {n:42});
	});
});
Loading