diff options
Diffstat (limited to 'apps')
553 files changed, 5155 insertions, 5190 deletions
diff --git a/apps/dashboard/l10n/ar.js b/apps/dashboard/l10n/ar.js index cbc7e805515..abe91d4bf28 100644 --- a/apps/dashboard/l10n/ar.js +++ b/apps/dashboard/l10n/ar.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "أهلا، {name} ", "Happy birthday 🥳🤩🎂🎉" : "عيد ميلاد سعيد 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "عيد ميلاد سعيد, يا {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} أيقونة\"", "Customize" : "تعديل", "Edit widgets" : "تعديل أدوات الصفحة الرئيسية", "Get more widgets from the App Store" : "يمكنك الحصول على المزيد من الأدوات من متجر التطبيقات", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "للحفاظ على خصوصيتك، يتم استدعاء بيانات حالة الطقس عبر خادم NextCloud الخاص بك نيابه عنك، وبالتالي فإن خدمة حالة الطقس لا تشارك معلوماتك الشخصية.", "Weather data from Met.no" : "بيانات الطقس من Met.no", "geocoding with Nominatim" : "الترميز الجغرافي مع Nominatim", - "elevation data from OpenTopoData" : "بيانات التقييم من OpenTopoData" + "elevation data from OpenTopoData" : "بيانات التقييم من OpenTopoData", + "\"{title} icon\"" : "\"{title} أيقونة\"" }, "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); diff --git a/apps/dashboard/l10n/ar.json b/apps/dashboard/l10n/ar.json index 15ec6f00dcb..caad4cc7e32 100644 --- a/apps/dashboard/l10n/ar.json +++ b/apps/dashboard/l10n/ar.json @@ -14,7 +14,6 @@ "Hello, {name}" : "أهلا، {name} ", "Happy birthday 🥳🤩🎂🎉" : "عيد ميلاد سعيد 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "عيد ميلاد سعيد, يا {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} أيقونة\"", "Customize" : "تعديل", "Edit widgets" : "تعديل أدوات الصفحة الرئيسية", "Get more widgets from the App Store" : "يمكنك الحصول على المزيد من الأدوات من متجر التطبيقات", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "للحفاظ على خصوصيتك، يتم استدعاء بيانات حالة الطقس عبر خادم NextCloud الخاص بك نيابه عنك، وبالتالي فإن خدمة حالة الطقس لا تشارك معلوماتك الشخصية.", "Weather data from Met.no" : "بيانات الطقس من Met.no", "geocoding with Nominatim" : "الترميز الجغرافي مع Nominatim", - "elevation data from OpenTopoData" : "بيانات التقييم من OpenTopoData" + "elevation data from OpenTopoData" : "بيانات التقييم من OpenTopoData", + "\"{title} icon\"" : "\"{title} أيقونة\"" },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ast.js b/apps/dashboard/l10n/ast.js index 068a13291f2..2817983e456 100644 --- a/apps/dashboard/l10n/ast.js +++ b/apps/dashboard/l10n/ast.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "Bones nueches, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "«Iconu de: {title}»", "Customize" : "Personalizar", "Edit widgets" : "Editar los widgets", "Get more widgets from the App Store" : "Consigui más widgets de l'App Store", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Pa la to privacidá, los datos del clima solicítense dende esta instancia de Nextcloud y, polo tanto, el serviciu del clima no recibe nenguna información personal.", "Weather data from Met.no" : "datos del clima de Met.no", "geocoding with Nominatim" : "xeocodificación con Nominatim", - "elevation data from OpenTopoData" : "datos d'elevaciones d'OpenTopoData" + "elevation data from OpenTopoData" : "datos d'elevaciones d'OpenTopoData", + "\"{title} icon\"" : "«Iconu de: {title}»" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/ast.json b/apps/dashboard/l10n/ast.json index 6adf8dae335..1f194cf8b54 100644 --- a/apps/dashboard/l10n/ast.json +++ b/apps/dashboard/l10n/ast.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "Bones nueches, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "«Iconu de: {title}»", "Customize" : "Personalizar", "Edit widgets" : "Editar los widgets", "Get more widgets from the App Store" : "Consigui más widgets de l'App Store", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Pa la to privacidá, los datos del clima solicítense dende esta instancia de Nextcloud y, polo tanto, el serviciu del clima no recibe nenguna información personal.", "Weather data from Met.no" : "datos del clima de Met.no", "geocoding with Nominatim" : "xeocodificación con Nominatim", - "elevation data from OpenTopoData" : "datos d'elevaciones d'OpenTopoData" + "elevation data from OpenTopoData" : "datos d'elevaciones d'OpenTopoData", + "\"{title} icon\"" : "«Iconu de: {title}»" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/bg.js b/apps/dashboard/l10n/bg.js index a3d874b9dde..aa438921262 100644 --- a/apps/dashboard/l10n/bg.js +++ b/apps/dashboard/l10n/bg.js @@ -13,7 +13,6 @@ OC.L10N.register( "Good evening, {name}" : "Добър вечер, {name}", "Hello" : "Здравейте", "Hello, {name}" : "Здравейте, {name}", - "\"{title} icon\"" : "„икона {title}“", "Customize" : "Персонизиране", "Edit widgets" : "Редактиране на изпълнимите модули", "Get more widgets from the App Store" : "Вземете повече приспособления от App Store", @@ -21,6 +20,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "За вашата поверителност данните за времето се изискват от Nextcloud сървъра ви от ваше име, така че метеорологичната служба не получава лична информация.", "Weather data from Met.no" : "Данни за времето от Met.no", "geocoding with Nominatim" : "геокодиране с Nominatim", - "elevation data from OpenTopoData" : " кота данни от OpenTopoData" + "elevation data from OpenTopoData" : " кота данни от OpenTopoData", + "\"{title} icon\"" : "„икона {title}“" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/bg.json b/apps/dashboard/l10n/bg.json index 6efd79f09be..4917c61e5f2 100644 --- a/apps/dashboard/l10n/bg.json +++ b/apps/dashboard/l10n/bg.json @@ -11,7 +11,6 @@ "Good evening, {name}" : "Добър вечер, {name}", "Hello" : "Здравейте", "Hello, {name}" : "Здравейте, {name}", - "\"{title} icon\"" : "„икона {title}“", "Customize" : "Персонизиране", "Edit widgets" : "Редактиране на изпълнимите модули", "Get more widgets from the App Store" : "Вземете повече приспособления от App Store", @@ -19,6 +18,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "За вашата поверителност данните за времето се изискват от Nextcloud сървъра ви от ваше име, така че метеорологичната служба не получава лична информация.", "Weather data from Met.no" : "Данни за времето от Met.no", "geocoding with Nominatim" : "геокодиране с Nominatim", - "elevation data from OpenTopoData" : " кота данни от OpenTopoData" + "elevation data from OpenTopoData" : " кота данни от OpenTopoData", + "\"{title} icon\"" : "„икона {title}“" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ca.js b/apps/dashboard/l10n/ca.js index 9866240236a..333cdbac223 100644 --- a/apps/dashboard/l10n/ca.js +++ b/apps/dashboard/l10n/ca.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Per molts anys 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Per molts anys, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"icona de {title}\"", "Customize" : "Personalitza", "Edit widgets" : "Edita els ginys", "Get more widgets from the App Store" : "Obtén més ginys a la botiga d'aplicacions", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Per a la vostra privadesa, les dades meteorològiques les sol·licita el servidor del Nextcloud en nom vostre perquè el servei meteorològic no rebi cap informació personal.", "Weather data from Met.no" : "Dades meteorològiques de Met.no", "geocoding with Nominatim" : "codis geogràfics amb Nominatim", - "elevation data from OpenTopoData" : "dades d'altitud d'OpenTopoData" + "elevation data from OpenTopoData" : "dades d'altitud d'OpenTopoData", + "\"{title} icon\"" : "\"icona de {title}\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/ca.json b/apps/dashboard/l10n/ca.json index 6a568cb896b..0c54b9c57ad 100644 --- a/apps/dashboard/l10n/ca.json +++ b/apps/dashboard/l10n/ca.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Per molts anys 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Per molts anys, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"icona de {title}\"", "Customize" : "Personalitza", "Edit widgets" : "Edita els ginys", "Get more widgets from the App Store" : "Obtén més ginys a la botiga d'aplicacions", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Per a la vostra privadesa, les dades meteorològiques les sol·licita el servidor del Nextcloud en nom vostre perquè el servei meteorològic no rebi cap informació personal.", "Weather data from Met.no" : "Dades meteorològiques de Met.no", "geocoding with Nominatim" : "codis geogràfics amb Nominatim", - "elevation data from OpenTopoData" : "dades d'altitud d'OpenTopoData" + "elevation data from OpenTopoData" : "dades d'altitud d'OpenTopoData", + "\"{title} icon\"" : "\"icona de {title}\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/cs.js b/apps/dashboard/l10n/cs.js index 9210dc79f46..6c390e5a041 100644 --- a/apps/dashboard/l10n/cs.js +++ b/apps/dashboard/l10n/cs.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Dobrý den, {name}", "Happy birthday 🥳🤩🎂🎉" : "Všechno nejlepší k narozeninám 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Všechno nejlepší k narozeninám, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„ikona {title}“", "Customize" : "Přizpůsobit si", "Edit widgets" : "Upravit ovládací prvky", "Get more widgets from the App Store" : "Získat další ovládací prvky z katalogu aplikací", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Vaše soukromí je chráněno tím, že komunikaci se službou předpovědi počasí zprostředkovává vámi využívaný Nextcloud server. Díky tomu služba, která tyto údaje poskytuje, neobdrží z vašeho počítače žádné osobní údaje.", "Weather data from Met.no" : "Údaje o počasí z Met.no", "geocoding with Nominatim" : "z popisu polohy na souřadnice převáděno službou Nominatim", - "elevation data from OpenTopoData" : "data o nadmořských výškách z OpenTopoData" + "elevation data from OpenTopoData" : "data o nadmořských výškách z OpenTopoData", + "\"{title} icon\"" : "„ikona {title}“" }, "nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"); diff --git a/apps/dashboard/l10n/cs.json b/apps/dashboard/l10n/cs.json index c64b3280635..6252d433e6f 100644 --- a/apps/dashboard/l10n/cs.json +++ b/apps/dashboard/l10n/cs.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Dobrý den, {name}", "Happy birthday 🥳🤩🎂🎉" : "Všechno nejlepší k narozeninám 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Všechno nejlepší k narozeninám, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„ikona {title}“", "Customize" : "Přizpůsobit si", "Edit widgets" : "Upravit ovládací prvky", "Get more widgets from the App Store" : "Získat další ovládací prvky z katalogu aplikací", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Vaše soukromí je chráněno tím, že komunikaci se službou předpovědi počasí zprostředkovává vámi využívaný Nextcloud server. Díky tomu služba, která tyto údaje poskytuje, neobdrží z vašeho počítače žádné osobní údaje.", "Weather data from Met.no" : "Údaje o počasí z Met.no", "geocoding with Nominatim" : "z popisu polohy na souřadnice převáděno službou Nominatim", - "elevation data from OpenTopoData" : "data o nadmořských výškách z OpenTopoData" + "elevation data from OpenTopoData" : "data o nadmořských výškách z OpenTopoData", + "\"{title} icon\"" : "„ikona {title}“" },"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/da.js b/apps/dashboard/l10n/da.js index 6dbf3240587..c118af726c4 100644 --- a/apps/dashboard/l10n/da.js +++ b/apps/dashboard/l10n/da.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hej {name}", "Happy birthday 🥳🤩🎂🎉" : "Tillykke med fødselsdagen 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Tillykke med fødselsdagen, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikon\"", "Customize" : "Brugerdefiner", "Edit widgets" : "Rediger widgets", "Get more widgets from the App Store" : "Få flere widgets fra App Store", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Af hensyn til dit privatliv, er det din Nextcloud-server der henter vejr-data og udbyderen modtager således ingen oplysninger om dig.", "Weather data from Met.no" : "Vejr-data leveres af Met.no", "geocoding with Nominatim" : "Geocoding med Nominatim", - "elevation data from OpenTopoData" : "Højde-data fra OpenTopoData" + "elevation data from OpenTopoData" : "Højde-data fra OpenTopoData", + "\"{title} icon\"" : "\"{title} ikon\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/da.json b/apps/dashboard/l10n/da.json index 8b184ce6989..71fcc7bc9c9 100644 --- a/apps/dashboard/l10n/da.json +++ b/apps/dashboard/l10n/da.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hej {name}", "Happy birthday 🥳🤩🎂🎉" : "Tillykke med fødselsdagen 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Tillykke med fødselsdagen, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikon\"", "Customize" : "Brugerdefiner", "Edit widgets" : "Rediger widgets", "Get more widgets from the App Store" : "Få flere widgets fra App Store", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Af hensyn til dit privatliv, er det din Nextcloud-server der henter vejr-data og udbyderen modtager således ingen oplysninger om dig.", "Weather data from Met.no" : "Vejr-data leveres af Met.no", "geocoding with Nominatim" : "Geocoding med Nominatim", - "elevation data from OpenTopoData" : "Højde-data fra OpenTopoData" + "elevation data from OpenTopoData" : "Højde-data fra OpenTopoData", + "\"{title} icon\"" : "\"{title} ikon\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/de.js b/apps/dashboard/l10n/de.js index 9fc197d7167..2885e6a657a 100644 --- a/apps/dashboard/l10n/de.js +++ b/apps/dashboard/l10n/de.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hallo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-Symbol\"", "Customize" : "Anpassen", "Edit widgets" : "Widgets bearbeiten", "Get more widgets from the App Store" : "Hole dir weitere Widgets aus dem App-Store", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zu deinem Datenschutz werden die Wetterdaten von deinem Nextcloud-Server für dich angefordert, so dass der Wetterdienst keine persönlichen Informationen erhält.", "Weather data from Met.no" : "Wetterdaten von Met.no", "geocoding with Nominatim" : "Geokodierung mit Nominatim", - "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData" + "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData", + "\"{title} icon\"" : "\"{title}-Symbol\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/de.json b/apps/dashboard/l10n/de.json index 230f4a87ece..d3ff6b42dda 100644 --- a/apps/dashboard/l10n/de.json +++ b/apps/dashboard/l10n/de.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hallo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-Symbol\"", "Customize" : "Anpassen", "Edit widgets" : "Widgets bearbeiten", "Get more widgets from the App Store" : "Hole dir weitere Widgets aus dem App-Store", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zu deinem Datenschutz werden die Wetterdaten von deinem Nextcloud-Server für dich angefordert, so dass der Wetterdienst keine persönlichen Informationen erhält.", "Weather data from Met.no" : "Wetterdaten von Met.no", "geocoding with Nominatim" : "Geokodierung mit Nominatim", - "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData" + "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData", + "\"{title} icon\"" : "\"{title}-Symbol\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/de_DE.js b/apps/dashboard/l10n/de_DE.js index f1b2916cd67..3d18e6f7837 100644 --- a/apps/dashboard/l10n/de_DE.js +++ b/apps/dashboard/l10n/de_DE.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hallo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-Symbol\"", "Customize" : "Anpassen", "Edit widgets" : "Widgets bearbeiten", "Get more widgets from the App Store" : "Holen Sie sich weitere Widgets aus dem App-Store", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zu Ihrem Datenschutz werden die Wetterdaten von Ihrem Nextcloud-Server für Sie angefordert, so dass der Wetterdienst keine persönlichen Informationen erhält.", "Weather data from Met.no" : "Wetterdaten von Met.no", "geocoding with Nominatim" : "Geokodierung mit Nominatim", - "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData" + "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData", + "\"{title} icon\"" : "\"{title}-Symbol\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/de_DE.json b/apps/dashboard/l10n/de_DE.json index ba2ab517a4a..edfbc1c1273 100644 --- a/apps/dashboard/l10n/de_DE.json +++ b/apps/dashboard/l10n/de_DE.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hallo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Alles Gute zum Geburtstag, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-Symbol\"", "Customize" : "Anpassen", "Edit widgets" : "Widgets bearbeiten", "Get more widgets from the App Store" : "Holen Sie sich weitere Widgets aus dem App-Store", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zu Ihrem Datenschutz werden die Wetterdaten von Ihrem Nextcloud-Server für Sie angefordert, so dass der Wetterdienst keine persönlichen Informationen erhält.", "Weather data from Met.no" : "Wetterdaten von Met.no", "geocoding with Nominatim" : "Geokodierung mit Nominatim", - "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData" + "elevation data from OpenTopoData" : "Höhendaten von OpenTopoData", + "\"{title} icon\"" : "\"{title}-Symbol\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/en_GB.js b/apps/dashboard/l10n/en_GB.js index f4050daff2a..9c160f2b279 100644 --- a/apps/dashboard/l10n/en_GB.js +++ b/apps/dashboard/l10n/en_GB.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hello, {name}", "Happy birthday 🥳🤩🎂🎉" : "Happy birthday 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Happy birthday, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} icon\"", "Customize" : "Customise", "Edit widgets" : "Edit widgets", "Get more widgets from the App Store" : "Get more widgets from the App Store", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information.", "Weather data from Met.no" : "Weather data from Met.no", "geocoding with Nominatim" : "geocoding with Nominatim", - "elevation data from OpenTopoData" : "elevation data from OpenTopoData" + "elevation data from OpenTopoData" : "elevation data from OpenTopoData", + "\"{title} icon\"" : "\"{title} icon\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/en_GB.json b/apps/dashboard/l10n/en_GB.json index c0d7640f04b..5ca0a16478b 100644 --- a/apps/dashboard/l10n/en_GB.json +++ b/apps/dashboard/l10n/en_GB.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hello, {name}", "Happy birthday 🥳🤩🎂🎉" : "Happy birthday 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Happy birthday, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} icon\"", "Customize" : "Customise", "Edit widgets" : "Edit widgets", "Get more widgets from the App Store" : "Get more widgets from the App Store", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information.", "Weather data from Met.no" : "Weather data from Met.no", "geocoding with Nominatim" : "geocoding with Nominatim", - "elevation data from OpenTopoData" : "elevation data from OpenTopoData" + "elevation data from OpenTopoData" : "elevation data from OpenTopoData", + "\"{title} icon\"" : "\"{title} icon\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/es.js b/apps/dashboard/l10n/es.js index 3c27523d67b..850943a86de 100644 --- a/apps/dashboard/l10n/es.js +++ b/apps/dashboard/l10n/es.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz cumpleaños 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz cumpleaños, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"icono {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"icono {title}\"" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/es.json b/apps/dashboard/l10n/es.json index 5099c13e47a..44bda12c440 100644 --- a/apps/dashboard/l10n/es.json +++ b/apps/dashboard/l10n/es.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz cumpleaños 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz cumpleaños, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"icono {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"icono {title}\"" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/es_EC.js b/apps/dashboard/l10n/es_EC.js index 2bad48d3946..215599661a9 100644 --- a/apps/dashboard/l10n/es_EC.js +++ b/apps/dashboard/l10n/es_EC.js @@ -13,7 +13,6 @@ OC.L10N.register( "Good evening, {name}" : "Buenas noches, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "\"icono {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -21,6 +20,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"icono {title}\"" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/es_EC.json b/apps/dashboard/l10n/es_EC.json index aa891ede5fb..1a5496448e0 100644 --- a/apps/dashboard/l10n/es_EC.json +++ b/apps/dashboard/l10n/es_EC.json @@ -11,7 +11,6 @@ "Good evening, {name}" : "Buenas noches, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "\"icono {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -19,6 +18,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"icono {title}\"" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/es_MX.js b/apps/dashboard/l10n/es_MX.js index 34da665b988..641db816eaa 100644 --- a/apps/dashboard/l10n/es_MX.js +++ b/apps/dashboard/l10n/es_MX.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "Buenas tardes, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "\"ícono de {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"ícono de {title}\"" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/es_MX.json b/apps/dashboard/l10n/es_MX.json index bbe9417cd30..6f86e0dad2c 100644 --- a/apps/dashboard/l10n/es_MX.json +++ b/apps/dashboard/l10n/es_MX.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "Buenas tardes, {name}", "Hello" : "Hola", "Hello, {name}" : "Hola, {name}", - "\"{title} icon\"" : "\"ícono de {title}\"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Conseguir más widgets desde la tienda de Apps", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Por privacidad, los datos meteorológicos son solicitados por tu servidor Nextcloud en tu nombre de tal forma que el servicio no recibe información personal.", "Weather data from Met.no" : "Datos meteorológicos de Met.no", "geocoding with Nominatim" : "geocoding con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "\"ícono de {title}\"" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/et_EE.js b/apps/dashboard/l10n/et_EE.js index 8c313ee08e8..1b5d84af336 100644 --- a/apps/dashboard/l10n/et_EE.js +++ b/apps/dashboard/l10n/et_EE.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Tere, {name}", "Happy birthday 🥳🤩🎂🎉" : "Palju õnne sünnipäevaks 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Palju õnne, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} ikoon“", "Customize" : "Kohanda", "Edit widgets" : "Muuda vidinaid", "Get more widgets from the App Store" : "Hangi rohkem vidinaid Rakenduste Poest", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Sinu privaatsuse huvides küsib su nimel ilmaandmeid Nextcloudi server, nii et ilmateenistus ei saa isiklikku teavet.", "Weather data from Met.no" : "Ilmaandmed Met.no-st", "geocoding with Nominatim" : "geoprogrammeerimine Nominatimiga", - "elevation data from OpenTopoData" : "kõrgusandmed OpenTopoDatast" + "elevation data from OpenTopoData" : "kõrgusandmed OpenTopoDatast", + "\"{title} icon\"" : "„{title} ikoon“" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/et_EE.json b/apps/dashboard/l10n/et_EE.json index 39b5fa632f1..39bd54a58fa 100644 --- a/apps/dashboard/l10n/et_EE.json +++ b/apps/dashboard/l10n/et_EE.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Tere, {name}", "Happy birthday 🥳🤩🎂🎉" : "Palju õnne sünnipäevaks 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Palju õnne, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} ikoon“", "Customize" : "Kohanda", "Edit widgets" : "Muuda vidinaid", "Get more widgets from the App Store" : "Hangi rohkem vidinaid Rakenduste Poest", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Sinu privaatsuse huvides küsib su nimel ilmaandmeid Nextcloudi server, nii et ilmateenistus ei saa isiklikku teavet.", "Weather data from Met.no" : "Ilmaandmed Met.no-st", "geocoding with Nominatim" : "geoprogrammeerimine Nominatimiga", - "elevation data from OpenTopoData" : "kõrgusandmed OpenTopoDatast" + "elevation data from OpenTopoData" : "kõrgusandmed OpenTopoDatast", + "\"{title} icon\"" : "„{title} ikoon“" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/eu.js b/apps/dashboard/l10n/eu.js index eccb212ea76..7a911ec279f 100644 --- a/apps/dashboard/l10n/eu.js +++ b/apps/dashboard/l10n/eu.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Kaixo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Zorionak 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Zorionak, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikonoa\"", "Customize" : "Pertsonalizatu", "Edit widgets" : "Editatu trepetak", "Get more widgets from the App Store" : "Lortu trepeta (widget) gehiago Aplikazioen Dendatik", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zure pribatutasunaren mesedetan, eguraldiaren datuak Nextcloud zerbitzariak eskatzen ditu zure izenean, eguraldi zerbitzuak informazio pertsonalik ez jasotzeko.", "Weather data from Met.no" : "Met.no-ko eguraldiaren datuak", "geocoding with Nominatim" : "geokodetzea Nominatim-ekin", - "elevation data from OpenTopoData" : "altitude datuak OpenTopoData-tik" + "elevation data from OpenTopoData" : "altitude datuak OpenTopoData-tik", + "\"{title} icon\"" : "\"{title} ikonoa\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/eu.json b/apps/dashboard/l10n/eu.json index 7d07259c94b..9d3c3d08214 100644 --- a/apps/dashboard/l10n/eu.json +++ b/apps/dashboard/l10n/eu.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Kaixo, {name}", "Happy birthday 🥳🤩🎂🎉" : "Zorionak 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Zorionak, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikonoa\"", "Customize" : "Pertsonalizatu", "Edit widgets" : "Editatu trepetak", "Get more widgets from the App Store" : "Lortu trepeta (widget) gehiago Aplikazioen Dendatik", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Zure pribatutasunaren mesedetan, eguraldiaren datuak Nextcloud zerbitzariak eskatzen ditu zure izenean, eguraldi zerbitzuak informazio pertsonalik ez jasotzeko.", "Weather data from Met.no" : "Met.no-ko eguraldiaren datuak", "geocoding with Nominatim" : "geokodetzea Nominatim-ekin", - "elevation data from OpenTopoData" : "altitude datuak OpenTopoData-tik" + "elevation data from OpenTopoData" : "altitude datuak OpenTopoData-tik", + "\"{title} icon\"" : "\"{title} ikonoa\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/fa.js b/apps/dashboard/l10n/fa.js index 18f97b30576..e184f76c85c 100644 --- a/apps/dashboard/l10n/fa.js +++ b/apps/dashboard/l10n/fa.js @@ -14,13 +14,16 @@ OC.L10N.register( "Good evening, {name}" : " عصر بهخیر {name}", "Hello" : "درود", "Hello, {name}" : "درود {name}", - "\"{title} icon\"" : "«نقشک {title}»", + "Happy birthday 🥳🤩🎂🎉" : "تولدت مبارک 🥳🤩🎂🎉", + "Happy birthday, {name} 🥳🤩🎂🎉" : "تولدت مبارک، {name} 🥳🤩🎂🎉", "Customize" : "سفارشیسازی", "Edit widgets" : "ویرایش ابزارکها", - "Get more widgets from the App Store" : "گرفتن ابزارکهای بیشتر از فروشکاه کاره", + "Get more widgets from the App Store" : "گرفتن ابزارکهای بیشتر از فروشگاه کاره", "Weather service" : "خدمت هواشناسی", "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "برای محرمانگیتان، دادههای آب و هوا از طرف کارساز نکستکلودتان درخواست میشود تا خدمت آب و هوا هیچ اطّلاعات شخصیای دریافت نکند.", "Weather data from Met.no" : "اطلاعات هواشناسی از Met.no", - "elevation data from OpenTopoData" : "دادههای ارتفاع از OpenTopoData" + "geocoding with Nominatim" : "کدگذاری جغرافیایی با Nominatim", + "elevation data from OpenTopoData" : "دادههای ارتفاع از OpenTopoData", + "\"{title} icon\"" : "«نقشک {title}»" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/dashboard/l10n/fa.json b/apps/dashboard/l10n/fa.json index 512ebbe0a1d..6120f6657c4 100644 --- a/apps/dashboard/l10n/fa.json +++ b/apps/dashboard/l10n/fa.json @@ -12,13 +12,16 @@ "Good evening, {name}" : " عصر بهخیر {name}", "Hello" : "درود", "Hello, {name}" : "درود {name}", - "\"{title} icon\"" : "«نقشک {title}»", + "Happy birthday 🥳🤩🎂🎉" : "تولدت مبارک 🥳🤩🎂🎉", + "Happy birthday, {name} 🥳🤩🎂🎉" : "تولدت مبارک، {name} 🥳🤩🎂🎉", "Customize" : "سفارشیسازی", "Edit widgets" : "ویرایش ابزارکها", - "Get more widgets from the App Store" : "گرفتن ابزارکهای بیشتر از فروشکاه کاره", + "Get more widgets from the App Store" : "گرفتن ابزارکهای بیشتر از فروشگاه کاره", "Weather service" : "خدمت هواشناسی", "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "برای محرمانگیتان، دادههای آب و هوا از طرف کارساز نکستکلودتان درخواست میشود تا خدمت آب و هوا هیچ اطّلاعات شخصیای دریافت نکند.", "Weather data from Met.no" : "اطلاعات هواشناسی از Met.no", - "elevation data from OpenTopoData" : "دادههای ارتفاع از OpenTopoData" + "geocoding with Nominatim" : "کدگذاری جغرافیایی با Nominatim", + "elevation data from OpenTopoData" : "دادههای ارتفاع از OpenTopoData", + "\"{title} icon\"" : "«نقشک {title}»" },"pluralForm" :"nplurals=2; plural=(n > 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/fr.js b/apps/dashboard/l10n/fr.js index 7f3470a59f0..3a1afaf8326 100644 --- a/apps/dashboard/l10n/fr.js +++ b/apps/dashboard/l10n/fr.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Bonjour {name}", "Happy birthday 🥳🤩🎂🎉" : "Joyeux anniversaire ! 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Joyeux anniversaire, {name}! 🥳🤩🎂🎉", - "\"{title} icon\"" : "« Icône {title} »", "Customize" : "Personnaliser", "Edit widgets" : "Modifier les widgets", "Get more widgets from the App Store" : "Obtenez plus de widgets depuis le magasin d’applications", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Afin de protéger votre vie privée, les données météorologiques sont demandées par votre serveur Nextcloud à votre place afin que le service météo ne reçoive aucune information personnelle.", "Weather data from Met.no" : "Données météo fournies par Met.no", "geocoding with Nominatim" : "Géocodage avec Nominatim", - "elevation data from OpenTopoData" : "Données d’altitude provenant d’OpenTopoData" + "elevation data from OpenTopoData" : "Données d’altitude provenant d’OpenTopoData", + "\"{title} icon\"" : "« Icône {title} »" }, "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/fr.json b/apps/dashboard/l10n/fr.json index 9f4fd034b6e..8ca7aff83f4 100644 --- a/apps/dashboard/l10n/fr.json +++ b/apps/dashboard/l10n/fr.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Bonjour {name}", "Happy birthday 🥳🤩🎂🎉" : "Joyeux anniversaire ! 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Joyeux anniversaire, {name}! 🥳🤩🎂🎉", - "\"{title} icon\"" : "« Icône {title} »", "Customize" : "Personnaliser", "Edit widgets" : "Modifier les widgets", "Get more widgets from the App Store" : "Obtenez plus de widgets depuis le magasin d’applications", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Afin de protéger votre vie privée, les données météorologiques sont demandées par votre serveur Nextcloud à votre place afin que le service météo ne reçoive aucune information personnelle.", "Weather data from Met.no" : "Données météo fournies par Met.no", "geocoding with Nominatim" : "Géocodage avec Nominatim", - "elevation data from OpenTopoData" : "Données d’altitude provenant d’OpenTopoData" + "elevation data from OpenTopoData" : "Données d’altitude provenant d’OpenTopoData", + "\"{title} icon\"" : "« Icône {title} »" },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ga.js b/apps/dashboard/l10n/ga.js index 2ad756df2c0..9fbee59ddd1 100644 --- a/apps/dashboard/l10n/ga.js +++ b/apps/dashboard/l10n/ga.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Dia dhuit, {name}", "Happy birthday 🥳🤩🎂🎉" : "Lá breithe shona duit 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Lá breithe shona duit, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} deilbhín\"", "Customize" : "Saincheap", "Edit widgets" : "Cuir giuirléidí in eagar", "Get more widgets from the App Store" : "Faigh tuilleadh giuirléidí ón Siopa Aip", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ar mhaithe le do phríobháideachas, iarrann do fhreastalaí Nextcloud na sonraí aimsire ar do shon agus mar sin ní fhaigheann an tseirbhís aimsire aon fhaisnéis phearsanta.", "Weather data from Met.no" : "Sonraí aimsire ó Met.no", "geocoding with Nominatim" : "geochódú le Nominatim", - "elevation data from OpenTopoData" : "sonraí ardaithe ó OpenTopoData" + "elevation data from OpenTopoData" : "sonraí ardaithe ó OpenTopoData", + "\"{title} icon\"" : "\"{title} deilbhín\"" }, "nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"); diff --git a/apps/dashboard/l10n/ga.json b/apps/dashboard/l10n/ga.json index afc8137bab7..69e239a1d01 100644 --- a/apps/dashboard/l10n/ga.json +++ b/apps/dashboard/l10n/ga.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Dia dhuit, {name}", "Happy birthday 🥳🤩🎂🎉" : "Lá breithe shona duit 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Lá breithe shona duit, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} deilbhín\"", "Customize" : "Saincheap", "Edit widgets" : "Cuir giuirléidí in eagar", "Get more widgets from the App Store" : "Faigh tuilleadh giuirléidí ón Siopa Aip", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ar mhaithe le do phríobháideachas, iarrann do fhreastalaí Nextcloud na sonraí aimsire ar do shon agus mar sin ní fhaigheann an tseirbhís aimsire aon fhaisnéis phearsanta.", "Weather data from Met.no" : "Sonraí aimsire ó Met.no", "geocoding with Nominatim" : "geochódú le Nominatim", - "elevation data from OpenTopoData" : "sonraí ardaithe ó OpenTopoData" + "elevation data from OpenTopoData" : "sonraí ardaithe ó OpenTopoData", + "\"{title} icon\"" : "\"{title} deilbhín\"" },"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/gl.js b/apps/dashboard/l10n/gl.js index 2f81e867b15..c332320e538 100644 --- a/apps/dashboard/l10n/gl.js +++ b/apps/dashboard/l10n/gl.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Ola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz aniversario 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz aniversario, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "«icona {title}»", "Customize" : "Personalizar", "Edit widgets" : "Editar trebellos", "Get more widgets from the App Store" : "Obter máis trebellos na tenda de aplicacións", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Para a súa privacidade, o servidor de Nextcloud solicita os datos meteorolóxicos no seu nome para que o servizo meteorolóxico non reciba información persoal.", "Weather data from Met.no" : "Datos meteorolóxicos de Met.no", "geocoding with Nominatim" : "xeocodificación con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "«icona {title}»" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/gl.json b/apps/dashboard/l10n/gl.json index 9793d2e25a1..9a3d57da111 100644 --- a/apps/dashboard/l10n/gl.json +++ b/apps/dashboard/l10n/gl.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Ola, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz aniversario 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz aniversario, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "«icona {title}»", "Customize" : "Personalizar", "Edit widgets" : "Editar trebellos", "Get more widgets from the App Store" : "Obter máis trebellos na tenda de aplicacións", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Para a súa privacidade, o servidor de Nextcloud solicita os datos meteorolóxicos no seu nome para que o servizo meteorolóxico non reciba información persoal.", "Weather data from Met.no" : "Datos meteorolóxicos de Met.no", "geocoding with Nominatim" : "xeocodificación con Nominatim", - "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData" + "elevation data from OpenTopoData" : "datos de elevación de OpenTopoData", + "\"{title} icon\"" : "«icona {title}»" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/hu.js b/apps/dashboard/l10n/hu.js index 615abab2904..b4564e6a2ce 100644 --- a/apps/dashboard/l10n/hu.js +++ b/apps/dashboard/l10n/hu.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Üdv {name}!", "Happy birthday 🥳🤩🎂🎉" : "Boldog születésnapot 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Boldog születésnapot, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} ikon”", "Customize" : "Testreszabás", "Edit widgets" : "Modulok szerkesztése", "Get more widgets from the App Store" : "További modulok letöltése az alkalmazástárból.", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Az adatvédelem érdekében az információt a Nextcloud kiszolgáló kéri le az Ön nevében, így az Ön személyes adatai nem kerülnek az időjárási adatok szolgáltatójához.", "Weather data from Met.no" : "Időjárási adatok a Met.no-tól", "geocoding with Nominatim" : "geokódolás a Nominatimmal", - "elevation data from OpenTopoData" : "magassági adatok az OpenTopoDatától" + "elevation data from OpenTopoData" : "magassági adatok az OpenTopoDatától", + "\"{title} icon\"" : "„{title} ikon”" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/hu.json b/apps/dashboard/l10n/hu.json index 29eb14f730d..36b2b3de0de 100644 --- a/apps/dashboard/l10n/hu.json +++ b/apps/dashboard/l10n/hu.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Üdv {name}!", "Happy birthday 🥳🤩🎂🎉" : "Boldog születésnapot 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Boldog születésnapot, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} ikon”", "Customize" : "Testreszabás", "Edit widgets" : "Modulok szerkesztése", "Get more widgets from the App Store" : "További modulok letöltése az alkalmazástárból.", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Az adatvédelem érdekében az információt a Nextcloud kiszolgáló kéri le az Ön nevében, így az Ön személyes adatai nem kerülnek az időjárási adatok szolgáltatójához.", "Weather data from Met.no" : "Időjárási adatok a Met.no-tól", "geocoding with Nominatim" : "geokódolás a Nominatimmal", - "elevation data from OpenTopoData" : "magassági adatok az OpenTopoDatától" + "elevation data from OpenTopoData" : "magassági adatok az OpenTopoDatától", + "\"{title} icon\"" : "„{title} ikon”" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/is.js b/apps/dashboard/l10n/is.js index 2d9e5e89ca5..16e91b972a2 100644 --- a/apps/dashboard/l10n/is.js +++ b/apps/dashboard/l10n/is.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Halló, {name}", "Happy birthday 🥳🤩🎂🎉" : "Til hamingju með afmælið 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Til hamingju með afmælið {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} táknmynd\"", "Customize" : "Sérsníða", "Edit widgets" : "Breyta viðmótshlutum", "Get more widgets from the App Store" : "Náðu í fleiri viðmótshluta í forritasafninu", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Til að vernda friðhelgi þína, eru veðurgögn sótt af Nextcloud-þjóninum fyrir þína hönd, þannig að veðurþjónustan fær engin persónuleg gögn.", "Weather data from Met.no" : "Veðurgögn frá Met.no", "geocoding with Nominatim" : "staðsetningarkóðun með Nominatim", - "elevation data from OpenTopoData" : "hæðargögn frá OpenTopoData" + "elevation data from OpenTopoData" : "hæðargögn frá OpenTopoData", + "\"{title} icon\"" : "\"{title} táknmynd\"" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/dashboard/l10n/is.json b/apps/dashboard/l10n/is.json index c943afc1f47..1e5c30add7d 100644 --- a/apps/dashboard/l10n/is.json +++ b/apps/dashboard/l10n/is.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Halló, {name}", "Happy birthday 🥳🤩🎂🎉" : "Til hamingju með afmælið 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Til hamingju með afmælið {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} táknmynd\"", "Customize" : "Sérsníða", "Edit widgets" : "Breyta viðmótshlutum", "Get more widgets from the App Store" : "Náðu í fleiri viðmótshluta í forritasafninu", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Til að vernda friðhelgi þína, eru veðurgögn sótt af Nextcloud-þjóninum fyrir þína hönd, þannig að veðurþjónustan fær engin persónuleg gögn.", "Weather data from Met.no" : "Veðurgögn frá Met.no", "geocoding with Nominatim" : "staðsetningarkóðun með Nominatim", - "elevation data from OpenTopoData" : "hæðargögn frá OpenTopoData" + "elevation data from OpenTopoData" : "hæðargögn frá OpenTopoData", + "\"{title} icon\"" : "\"{title} táknmynd\"" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/it.js b/apps/dashboard/l10n/it.js index f8fc5449f76..c77e8a25ec5 100644 --- a/apps/dashboard/l10n/it.js +++ b/apps/dashboard/l10n/it.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Ciao {name}", "Happy birthday 🥳🤩🎂🎉" : "Buon compleanno 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Buon compleanno, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"Icona {title}\"", "Customize" : "Personalizza", "Edit widgets" : "Modifica widget", "Get more widgets from the App Store" : "Ottieni altri widget dal negozio delle applicazioni", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Per la tua riservatezza, i dati meteorologici sono richiesti dal tuo server Nextcloud per tuo conto, per cui il servizio meteo non riceve informazioni personali.", "Weather data from Met.no" : "Dati meteo da Met.no", "geocoding with Nominatim" : "geocodifica conh Nominatim", - "elevation data from OpenTopoData" : "dati di elevazione da OpenTopoData" + "elevation data from OpenTopoData" : "dati di elevazione da OpenTopoData", + "\"{title} icon\"" : "\"Icona {title}\"" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/it.json b/apps/dashboard/l10n/it.json index 13fb2b32604..ff05385033a 100644 --- a/apps/dashboard/l10n/it.json +++ b/apps/dashboard/l10n/it.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Ciao {name}", "Happy birthday 🥳🤩🎂🎉" : "Buon compleanno 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Buon compleanno, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"Icona {title}\"", "Customize" : "Personalizza", "Edit widgets" : "Modifica widget", "Get more widgets from the App Store" : "Ottieni altri widget dal negozio delle applicazioni", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Per la tua riservatezza, i dati meteorologici sono richiesti dal tuo server Nextcloud per tuo conto, per cui il servizio meteo non riceve informazioni personali.", "Weather data from Met.no" : "Dati meteo da Met.no", "geocoding with Nominatim" : "geocodifica conh Nominatim", - "elevation data from OpenTopoData" : "dati di elevazione da OpenTopoData" + "elevation data from OpenTopoData" : "dati di elevazione da OpenTopoData", + "\"{title} icon\"" : "\"Icona {title}\"" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ja.js b/apps/dashboard/l10n/ja.js index 97410539843..2ed45a7ac08 100644 --- a/apps/dashboard/l10n/ja.js +++ b/apps/dashboard/l10n/ja.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "こんにちは、{name} さん", "Happy birthday 🥳🤩🎂🎉" : "お誕生日おめでとう 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "お誕生日おめでとう、{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} アイコン\"", "Customize" : "カスタマイズ", "Edit widgets" : "ウィジェットを編集", "Get more widgets from the App Store" : "アプリストアから他のガジェットを入手", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "あなたのプライバシーを保護するため、あなたに変わって Nextcloud サーバーが気象データをウェザーサービスに要求します。そのため、ウェザーサービスはあなたの個人情報を受け取ることはありません。", "Weather data from Met.no" : "気象データ提供元は Met.no", "geocoding with Nominatim" : "Nominatim でジオコーディング", - "elevation data from OpenTopoData" : "標高データ提供元は OpenTopoData です" + "elevation data from OpenTopoData" : "標高データ提供元は OpenTopoData です", + "\"{title} icon\"" : "\"{title} アイコン\"" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/ja.json b/apps/dashboard/l10n/ja.json index ff121e729e4..eb5f9a75715 100644 --- a/apps/dashboard/l10n/ja.json +++ b/apps/dashboard/l10n/ja.json @@ -14,7 +14,6 @@ "Hello, {name}" : "こんにちは、{name} さん", "Happy birthday 🥳🤩🎂🎉" : "お誕生日おめでとう 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "お誕生日おめでとう、{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} アイコン\"", "Customize" : "カスタマイズ", "Edit widgets" : "ウィジェットを編集", "Get more widgets from the App Store" : "アプリストアから他のガジェットを入手", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "あなたのプライバシーを保護するため、あなたに変わって Nextcloud サーバーが気象データをウェザーサービスに要求します。そのため、ウェザーサービスはあなたの個人情報を受け取ることはありません。", "Weather data from Met.no" : "気象データ提供元は Met.no", "geocoding with Nominatim" : "Nominatim でジオコーディング", - "elevation data from OpenTopoData" : "標高データ提供元は OpenTopoData です" + "elevation data from OpenTopoData" : "標高データ提供元は OpenTopoData です", + "\"{title} icon\"" : "\"{title} アイコン\"" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/lt_LT.js b/apps/dashboard/l10n/lt_LT.js index 40181a59310..04c14b11924 100644 --- a/apps/dashboard/l10n/lt_LT.js +++ b/apps/dashboard/l10n/lt_LT.js @@ -15,7 +15,6 @@ OC.L10N.register( "Hello, {name}" : "Sveiki, {name},", "Happy birthday 🥳🤩🎂🎉" : "Su gimtadieniu 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Su gimtadieniu, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} piktograma“", "Customize" : "Tinkinti", "Edit widgets" : "Taisyti valdiklius", "Get more widgets from the App Store" : "Parsisiųsti įskiepių iš App Store", @@ -23,6 +22,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Dėl jūsų privatumo, orų duomenys yra jūsų vardu užklausiami jūsų Nextcloud serverio, todėl orų tarnyba negauna jokios asmeninės informacijos.", "Weather data from Met.no" : "Orų duomenys iš Met.no", "geocoding with Nominatim" : "geografinis kodavimas naudojant Nominatim", - "elevation data from OpenTopoData" : "aukščio duomenys iš OpenTopoData" + "elevation data from OpenTopoData" : "aukščio duomenys iš OpenTopoData", + "\"{title} icon\"" : "„{title} piktograma“" }, "nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"); diff --git a/apps/dashboard/l10n/lt_LT.json b/apps/dashboard/l10n/lt_LT.json index c2df9016135..d3711e0f743 100644 --- a/apps/dashboard/l10n/lt_LT.json +++ b/apps/dashboard/l10n/lt_LT.json @@ -13,7 +13,6 @@ "Hello, {name}" : "Sveiki, {name},", "Happy birthday 🥳🤩🎂🎉" : "Su gimtadieniu 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Su gimtadieniu, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} piktograma“", "Customize" : "Tinkinti", "Edit widgets" : "Taisyti valdiklius", "Get more widgets from the App Store" : "Parsisiųsti įskiepių iš App Store", @@ -21,6 +20,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Dėl jūsų privatumo, orų duomenys yra jūsų vardu užklausiami jūsų Nextcloud serverio, todėl orų tarnyba negauna jokios asmeninės informacijos.", "Weather data from Met.no" : "Orų duomenys iš Met.no", "geocoding with Nominatim" : "geografinis kodavimas naudojant Nominatim", - "elevation data from OpenTopoData" : "aukščio duomenys iš OpenTopoData" + "elevation data from OpenTopoData" : "aukščio duomenys iš OpenTopoData", + "\"{title} icon\"" : "„{title} piktograma“" },"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/mk.js b/apps/dashboard/l10n/mk.js index 650179098bd..5c985bcdcc8 100644 --- a/apps/dashboard/l10n/mk.js +++ b/apps/dashboard/l10n/mk.js @@ -13,7 +13,6 @@ OC.L10N.register( "Good evening, {name}" : "Добровечер, {name}", "Hello" : "Здраво", "Hello, {name}" : "Здраво, {name}", - "\"{title} icon\"" : "\"{title} икона\"", "Customize" : "Прилагоди", "Edit widgets" : "Уреди графички контроли", "Get more widgets from the App Store" : "Преземи повеќе графички контроли од продавницата со апликации", @@ -21,6 +20,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "За ваша приватност, податоците за времето ги бара вашиот сервер во ваше име, така што метеоролошката служба не добива лични информации.", "Weather data from Met.no" : "Податоци за временето од Met.no", "geocoding with Nominatim" : "Геокодирање со Nominatim", - "elevation data from OpenTopoData" : "Податоци за височина од OpenTopoData" + "elevation data from OpenTopoData" : "Податоци за височина од OpenTopoData", + "\"{title} icon\"" : "\"{title} икона\"" }, "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); diff --git a/apps/dashboard/l10n/mk.json b/apps/dashboard/l10n/mk.json index 163c188073e..f225e912978 100644 --- a/apps/dashboard/l10n/mk.json +++ b/apps/dashboard/l10n/mk.json @@ -11,7 +11,6 @@ "Good evening, {name}" : "Добровечер, {name}", "Hello" : "Здраво", "Hello, {name}" : "Здраво, {name}", - "\"{title} icon\"" : "\"{title} икона\"", "Customize" : "Прилагоди", "Edit widgets" : "Уреди графички контроли", "Get more widgets from the App Store" : "Преземи повеќе графички контроли од продавницата со апликации", @@ -19,6 +18,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "За ваша приватност, податоците за времето ги бара вашиот сервер во ваше име, така што метеоролошката служба не добива лични информации.", "Weather data from Met.no" : "Податоци за временето од Met.no", "geocoding with Nominatim" : "Геокодирање со Nominatim", - "elevation data from OpenTopoData" : "Податоци за височина од OpenTopoData" + "elevation data from OpenTopoData" : "Податоци за височина од OpenTopoData", + "\"{title} icon\"" : "\"{title} икона\"" },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/nb.js b/apps/dashboard/l10n/nb.js index 5bc7a9ba998..7091be8f0ee 100644 --- a/apps/dashboard/l10n/nb.js +++ b/apps/dashboard/l10n/nb.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "God kveld, {name}", "Hello" : "Hallo", "Hello, {name}" : "Hallo, {name}", - "\"{title} icon\"" : "\"{title} ikon\"", "Customize" : "Tilpass", "Edit widgets" : "Rediger widgets", "Get more widgets from the App Store" : "Få flere widgets fra app-butikken", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Av hensyn til personvernet ditt blir værdataene bedt om av Nextcloud-serveren din på dine vegne, slik at værtjenesten ikke mottar personlig informasjon.", "Weather data from Met.no" : "Værmelding fra Met.no", "geocoding with Nominatim" : "geokoding med Nominatim", - "elevation data from OpenTopoData" : "høydedata fra OpenTopoData" + "elevation data from OpenTopoData" : "høydedata fra OpenTopoData", + "\"{title} icon\"" : "\"{title} ikon\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/nb.json b/apps/dashboard/l10n/nb.json index fccc6d0686a..95f68c74a9c 100644 --- a/apps/dashboard/l10n/nb.json +++ b/apps/dashboard/l10n/nb.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "God kveld, {name}", "Hello" : "Hallo", "Hello, {name}" : "Hallo, {name}", - "\"{title} icon\"" : "\"{title} ikon\"", "Customize" : "Tilpass", "Edit widgets" : "Rediger widgets", "Get more widgets from the App Store" : "Få flere widgets fra app-butikken", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Av hensyn til personvernet ditt blir værdataene bedt om av Nextcloud-serveren din på dine vegne, slik at værtjenesten ikke mottar personlig informasjon.", "Weather data from Met.no" : "Værmelding fra Met.no", "geocoding with Nominatim" : "geokoding med Nominatim", - "elevation data from OpenTopoData" : "høydedata fra OpenTopoData" + "elevation data from OpenTopoData" : "høydedata fra OpenTopoData", + "\"{title} icon\"" : "\"{title} ikon\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/pl.js b/apps/dashboard/l10n/pl.js index 34c60ac18ba..8c0dd99508f 100644 --- a/apps/dashboard/l10n/pl.js +++ b/apps/dashboard/l10n/pl.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Witaj {name}", "Happy birthday 🥳🤩🎂🎉" : "Najlepsze życzenia urodzinowe 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Najlepsze życzenia urodzinowe, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"ikona {title}\"", "Customize" : "Dostosuj", "Edit widgets" : "Edytuj widżety", "Get more widgets from the App Store" : "Pobierz więcej widżetów z Nextcloud App Store", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ze względu na Twoją prywatność dane pogodowe są pobierane przez serwer Nextcloud w Twoim imieniu. Usługa pogodowa nie otrzymuje żadnych danych osobowych.", "Weather data from Met.no" : "Dane pogodowe z Met.no", "geocoding with Nominatim" : "geokodowanie z Nominatim", - "elevation data from OpenTopoData" : "dane wysokościowe z OpenTopoData" + "elevation data from OpenTopoData" : "dane wysokościowe z OpenTopoData", + "\"{title} icon\"" : "\"ikona {title}\"" }, "nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"); diff --git a/apps/dashboard/l10n/pl.json b/apps/dashboard/l10n/pl.json index 3e80ee3ca3d..cdd254abf25 100644 --- a/apps/dashboard/l10n/pl.json +++ b/apps/dashboard/l10n/pl.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Witaj {name}", "Happy birthday 🥳🤩🎂🎉" : "Najlepsze życzenia urodzinowe 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Najlepsze życzenia urodzinowe, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"ikona {title}\"", "Customize" : "Dostosuj", "Edit widgets" : "Edytuj widżety", "Get more widgets from the App Store" : "Pobierz więcej widżetów z Nextcloud App Store", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ze względu na Twoją prywatność dane pogodowe są pobierane przez serwer Nextcloud w Twoim imieniu. Usługa pogodowa nie otrzymuje żadnych danych osobowych.", "Weather data from Met.no" : "Dane pogodowe z Met.no", "geocoding with Nominatim" : "geokodowanie z Nominatim", - "elevation data from OpenTopoData" : "dane wysokościowe z OpenTopoData" + "elevation data from OpenTopoData" : "dane wysokościowe z OpenTopoData", + "\"{title} icon\"" : "\"ikona {title}\"" },"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/pt_BR.js b/apps/dashboard/l10n/pt_BR.js index 0843b517b11..dbfe53359f7 100644 --- a/apps/dashboard/l10n/pt_BR.js +++ b/apps/dashboard/l10n/pt_BR.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Olá, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz Aniversário 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz Aniversário, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"ícone de {title} \"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Obtenha mais widgets na Loja de Aplicativos", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Para sua privacidade, as informações de Tempo são solicitadas pelo servidor Nextcloud de forma que o serviço de Tempo não receba suas informações pessoais.", "Weather data from Met.no" : "Dados de Tempo do Met.no", "geocoding with Nominatim" : "geocodificado com Nominatim", - "elevation data from OpenTopoData" : "dados topográficos de OpenTopoData" + "elevation data from OpenTopoData" : "dados topográficos de OpenTopoData", + "\"{title} icon\"" : "\"ícone de {title} \"" }, "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dashboard/l10n/pt_BR.json b/apps/dashboard/l10n/pt_BR.json index 4750d3b61a5..a9715dc07f2 100644 --- a/apps/dashboard/l10n/pt_BR.json +++ b/apps/dashboard/l10n/pt_BR.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Olá, {name}", "Happy birthday 🥳🤩🎂🎉" : "Feliz Aniversário 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Feliz Aniversário, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"ícone de {title} \"", "Customize" : "Personalizar", "Edit widgets" : "Editar widgets", "Get more widgets from the App Store" : "Obtenha mais widgets na Loja de Aplicativos", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Para sua privacidade, as informações de Tempo são solicitadas pelo servidor Nextcloud de forma que o serviço de Tempo não receba suas informações pessoais.", "Weather data from Met.no" : "Dados de Tempo do Met.no", "geocoding with Nominatim" : "geocodificado com Nominatim", - "elevation data from OpenTopoData" : "dados topográficos de OpenTopoData" + "elevation data from OpenTopoData" : "dados topográficos de OpenTopoData", + "\"{title} icon\"" : "\"ícone de {title} \"" },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ru.js b/apps/dashboard/l10n/ru.js index 16c595ac1cf..724f9c70712 100644 --- a/apps/dashboard/l10n/ru.js +++ b/apps/dashboard/l10n/ru.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "Добрый вечер, {name}", "Hello" : "Здравствуйте", "Hello, {name}" : "Здравствуйте, {name}!", - "\"{title} icon\"" : "\"{title} иконка\"", "Customize" : "Настроить", "Edit widgets" : "Редактировать виджеты", "Get more widgets from the App Store" : "Загрузить виджеты из магазина приложений", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "В целях вашей конфиденциальности данные о погоде запрашиваются вашим сервером Nextcloud от вашего имени, поэтому служба погоды не получает никакой личной информации.", "Weather data from Met.no" : "Погода от Met.no", "geocoding with Nominatim" : "геокодирование с Nominatim", - "elevation data from OpenTopoData" : "данные о высоте из OpenTopoData" + "elevation data from OpenTopoData" : "данные о высоте из OpenTopoData", + "\"{title} icon\"" : "\"{title} иконка\"" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/apps/dashboard/l10n/ru.json b/apps/dashboard/l10n/ru.json index 14dac286388..f2949da650b 100644 --- a/apps/dashboard/l10n/ru.json +++ b/apps/dashboard/l10n/ru.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "Добрый вечер, {name}", "Hello" : "Здравствуйте", "Hello, {name}" : "Здравствуйте, {name}!", - "\"{title} icon\"" : "\"{title} иконка\"", "Customize" : "Настроить", "Edit widgets" : "Редактировать виджеты", "Get more widgets from the App Store" : "Загрузить виджеты из магазина приложений", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "В целях вашей конфиденциальности данные о погоде запрашиваются вашим сервером Nextcloud от вашего имени, поэтому служба погоды не получает никакой личной информации.", "Weather data from Met.no" : "Погода от Met.no", "geocoding with Nominatim" : "геокодирование с Nominatim", - "elevation data from OpenTopoData" : "данные о высоте из OpenTopoData" + "elevation data from OpenTopoData" : "данные о высоте из OpenTopoData", + "\"{title} icon\"" : "\"{title} иконка\"" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/sk.js b/apps/dashboard/l10n/sk.js index 5a37ecbc0a5..d254adbb5b5 100644 --- a/apps/dashboard/l10n/sk.js +++ b/apps/dashboard/l10n/sk.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Ahoj, {name}", "Happy birthday 🥳🤩🎂🎉" : "Všetko najlepšie k narodeninám 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Všetko najlepšie k narodeninám, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikona\"", "Customize" : "Prispôsobiť", "Edit widgets" : "Upraviť miniaplikácie", "Get more widgets from the App Store" : "Získať viac miniaplikácií v Obchode s aplikáciami", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "V záujme vášho súkromia údaje o počasí vyžaduje váš server Nextcloud vo vašom mene, aby meteorologická služba nedostávala žiadne osobné informácie.", "Weather data from Met.no" : "Dáta počasia z Met.no", "geocoding with Nominatim" : "geokódovanie pomocou Nominatim", - "elevation data from OpenTopoData" : "dáta o nadmorskej výške z OpenTopoData" + "elevation data from OpenTopoData" : "dáta o nadmorskej výške z OpenTopoData", + "\"{title} icon\"" : "\"{title} ikona\"" }, "nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"); diff --git a/apps/dashboard/l10n/sk.json b/apps/dashboard/l10n/sk.json index 615529d33e4..0193916f3e3 100644 --- a/apps/dashboard/l10n/sk.json +++ b/apps/dashboard/l10n/sk.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Ahoj, {name}", "Happy birthday 🥳🤩🎂🎉" : "Všetko najlepšie k narodeninám 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Všetko najlepšie k narodeninám, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} ikona\"", "Customize" : "Prispôsobiť", "Edit widgets" : "Upraviť miniaplikácie", "Get more widgets from the App Store" : "Získať viac miniaplikácií v Obchode s aplikáciami", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "V záujme vášho súkromia údaje o počasí vyžaduje váš server Nextcloud vo vašom mene, aby meteorologická služba nedostávala žiadne osobné informácie.", "Weather data from Met.no" : "Dáta počasia z Met.no", "geocoding with Nominatim" : "geokódovanie pomocou Nominatim", - "elevation data from OpenTopoData" : "dáta o nadmorskej výške z OpenTopoData" + "elevation data from OpenTopoData" : "dáta o nadmorskej výške z OpenTopoData", + "\"{title} icon\"" : "\"{title} ikona\"" },"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/sl.js b/apps/dashboard/l10n/sl.js index e198ee9d615..9422670f2ed 100644 --- a/apps/dashboard/l10n/sl.js +++ b/apps/dashboard/l10n/sl.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "Dober večer, {name}", "Hello" : "Pozdravljeni", "Hello, {name}" : "Pozdravljeni, {name}", - "\"{title} icon\"" : "»Ikona {title}«", "Customize" : "Prilagodi", "Edit widgets" : "Izbor gradnikov", "Get more widgets from the App Store" : "Pridobi več gradnikov s spletišča App Store", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Za večjo zasebnost so podatki vremena pridobljeni prek strežnika Nextcloud, zato tretje osebe ne pridobijo nobenega vašega osebnega podatka.", "Weather data from Met.no" : "Podatke vremena omogoča Met.no", "geocoding with Nominatim" : "geokodiranje Nominatim", - "elevation data from OpenTopoData" : "podatke nadmorske višine OpenTopoData" + "elevation data from OpenTopoData" : "podatke nadmorske višine OpenTopoData", + "\"{title} icon\"" : "»Ikona {title}«" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/dashboard/l10n/sl.json b/apps/dashboard/l10n/sl.json index bb34855f945..7d3de876695 100644 --- a/apps/dashboard/l10n/sl.json +++ b/apps/dashboard/l10n/sl.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "Dober večer, {name}", "Hello" : "Pozdravljeni", "Hello, {name}" : "Pozdravljeni, {name}", - "\"{title} icon\"" : "»Ikona {title}«", "Customize" : "Prilagodi", "Edit widgets" : "Izbor gradnikov", "Get more widgets from the App Store" : "Pridobi več gradnikov s spletišča App Store", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Za večjo zasebnost so podatki vremena pridobljeni prek strežnika Nextcloud, zato tretje osebe ne pridobijo nobenega vašega osebnega podatka.", "Weather data from Met.no" : "Podatke vremena omogoča Met.no", "geocoding with Nominatim" : "geokodiranje Nominatim", - "elevation data from OpenTopoData" : "podatke nadmorske višine OpenTopoData" + "elevation data from OpenTopoData" : "podatke nadmorske višine OpenTopoData", + "\"{title} icon\"" : "»Ikona {title}«" },"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/sr.js b/apps/dashboard/l10n/sr.js index 00ebbddca65..7ba1ba4ed65 100644 --- a/apps/dashboard/l10n/sr.js +++ b/apps/dashboard/l10n/sr.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Здраво, {name}", "Happy birthday 🥳🤩🎂🎉" : "Срећан рођендан 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Срећан рођендан {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} икона”", "Customize" : "Прилагођавање", "Edit widgets" : "Уређивање виџета", "Get more widgets from the App Store" : "Преузмите још виџета из Продавнице апликација", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ради чувања ваше приватности, временске податке са метеоролошког сервиса у ваше име захтева Nextcloud сервер, тако да се метеоролошком сервису не шаљу лични подаци.", "Weather data from Met.no" : "Метеоролошки подаци са Met.no", "geocoding with Nominatim" : "геокодирање са Nominatim", - "elevation data from OpenTopoData" : "висински подаци са OpenTopoData" + "elevation data from OpenTopoData" : "висински подаци са OpenTopoData", + "\"{title} icon\"" : "„{title} икона”" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/dashboard/l10n/sr.json b/apps/dashboard/l10n/sr.json index c8d6cf78e3b..d835955518a 100644 --- a/apps/dashboard/l10n/sr.json +++ b/apps/dashboard/l10n/sr.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Здраво, {name}", "Happy birthday 🥳🤩🎂🎉" : "Срећан рођендан 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Срећан рођендан {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "„{title} икона”", "Customize" : "Прилагођавање", "Edit widgets" : "Уређивање виџета", "Get more widgets from the App Store" : "Преузмите још виџета из Продавнице апликација", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Ради чувања ваше приватности, временске податке са метеоролошког сервиса у ваше име захтева Nextcloud сервер, тако да се метеоролошком сервису не шаљу лични подаци.", "Weather data from Met.no" : "Метеоролошки подаци са Met.no", "geocoding with Nominatim" : "геокодирање са Nominatim", - "elevation data from OpenTopoData" : "висински подаци са OpenTopoData" + "elevation data from OpenTopoData" : "висински подаци са OpenTopoData", + "\"{title} icon\"" : "„{title} икона”" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/sv.js b/apps/dashboard/l10n/sv.js index 5760124eb6e..ed82166c66d 100644 --- a/apps/dashboard/l10n/sv.js +++ b/apps/dashboard/l10n/sv.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Hej, {name}", "Happy birthday 🥳🤩🎂🎉" : "Grattis på födelsedagen 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Grattis på födelsedagen, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-ikon\"", "Customize" : "Anpassa", "Edit widgets" : "Ändra widgetar", "Get more widgets from the App Store" : "Hämta fler widgetar från Appstore", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "För din integritet skull hämtas väderdata av din Nextcloud-server på dina vägnar så att vädertjänsten inte får någon personlig information.", "Weather data from Met.no" : "Väderdata från Met.no", "geocoding with Nominatim" : "geokodning med Nominatim", - "elevation data from OpenTopoData" : "höjddata från OpenTopoData" + "elevation data from OpenTopoData" : "höjddata från OpenTopoData", + "\"{title} icon\"" : "\"{title}-ikon\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/sv.json b/apps/dashboard/l10n/sv.json index 942930ce188..0b06dcbcccc 100644 --- a/apps/dashboard/l10n/sv.json +++ b/apps/dashboard/l10n/sv.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Hej, {name}", "Happy birthday 🥳🤩🎂🎉" : "Grattis på födelsedagen 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Grattis på födelsedagen, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title}-ikon\"", "Customize" : "Anpassa", "Edit widgets" : "Ändra widgetar", "Get more widgets from the App Store" : "Hämta fler widgetar från Appstore", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "För din integritet skull hämtas väderdata av din Nextcloud-server på dina vägnar så att vädertjänsten inte får någon personlig information.", "Weather data from Met.no" : "Väderdata från Met.no", "geocoding with Nominatim" : "geokodning med Nominatim", - "elevation data from OpenTopoData" : "höjddata från OpenTopoData" + "elevation data from OpenTopoData" : "höjddata från OpenTopoData", + "\"{title} icon\"" : "\"{title}-ikon\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/tr.js b/apps/dashboard/l10n/tr.js index d20d2426fdd..1cd70679514 100644 --- a/apps/dashboard/l10n/tr.js +++ b/apps/dashboard/l10n/tr.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Merhaba {name}", "Happy birthday 🥳🤩🎂🎉" : "Mutlu yıllar 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Mutlu yıllar, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} simgesi\"", "Customize" : "Özelleştir", "Edit widgets" : "Pano bileşenlerini düzenle", "Get more widgets from the App Store" : "Uygulama mağazasından başka pano bileşenleri alın", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Kişisel gizliliğinizi korumak için Nextcloud sunucunuz hava durumu verilerini sizin adınıza ister. Böylece hava durumu hizmetine hiçbir kişisel bilgi aktarılmaz.", "Weather data from Met.no" : "Hava durumu verileri Met.no tarafından sağlanıyor", "geocoding with Nominatim" : "Nominatim ile coğrafi kodlama", - "elevation data from OpenTopoData" : "yükseklik verileri OpenTopoData tarafından sağlanıyor" + "elevation data from OpenTopoData" : "yükseklik verileri OpenTopoData tarafından sağlanıyor", + "\"{title} icon\"" : "\"{title} simgesi\"" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/dashboard/l10n/tr.json b/apps/dashboard/l10n/tr.json index 7bb9204043a..4f8759f5261 100644 --- a/apps/dashboard/l10n/tr.json +++ b/apps/dashboard/l10n/tr.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Merhaba {name}", "Happy birthday 🥳🤩🎂🎉" : "Mutlu yıllar 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Mutlu yıllar, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} simgesi\"", "Customize" : "Özelleştir", "Edit widgets" : "Pano bileşenlerini düzenle", "Get more widgets from the App Store" : "Uygulama mağazasından başka pano bileşenleri alın", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Kişisel gizliliğinizi korumak için Nextcloud sunucunuz hava durumu verilerini sizin adınıza ister. Böylece hava durumu hizmetine hiçbir kişisel bilgi aktarılmaz.", "Weather data from Met.no" : "Hava durumu verileri Met.no tarafından sağlanıyor", "geocoding with Nominatim" : "Nominatim ile coğrafi kodlama", - "elevation data from OpenTopoData" : "yükseklik verileri OpenTopoData tarafından sağlanıyor" + "elevation data from OpenTopoData" : "yükseklik verileri OpenTopoData tarafından sağlanıyor", + "\"{title} icon\"" : "\"{title} simgesi\"" },"pluralForm" :"nplurals=2; plural=(n > 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/ug.js b/apps/dashboard/l10n/ug.js index d3ff800a05d..75ca90442a9 100644 --- a/apps/dashboard/l10n/ug.js +++ b/apps/dashboard/l10n/ug.js @@ -14,7 +14,6 @@ OC.L10N.register( "Good evening, {name}" : "خەيرلىك كەچ ، {name}", "Hello" : "ياخشىمۇسىز", "Hello, {name}" : "ياخشىمۇسىز ، {name}", - "\"{title} icon\"" : "\"{title} سىنبەلگىسى\"", "Customize" : "Customize", "Edit widgets" : "كىچىك قوراللارنى تەھرىرلەش", "Get more widgets from the App Store" : "ئەپ دۇكىنىدىن تېخىمۇ كۆپ كىچىك قوراللارغا ئېرىشىڭ", @@ -22,6 +21,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "شەخسىي مەخپىيەتلىكىڭىز ئۈچۈن ھاۋارايى سانلىق مەلۇماتلىرىڭىزنى Nextcloud مۇلازىمېتىرىڭىز تەلەپ قىلىدۇ ، شۇڭا ھاۋارايى مۇلازىمىتى ھېچقانداق شەخسىي ئۇچۇرغا ئېرىشەلمەيدۇ.", "Weather data from Met.no" : "Met.no دىن كەلگەن ھاۋارايى سانلىق مەلۇماتلىرى", "geocoding with Nominatim" : "Nominatim بىلەن جۇغراپىيىلىك كودلاش", - "elevation data from OpenTopoData" : "OpenTopoData دىن ئېگىزلىك سانلىق مەلۇماتلىرى" + "elevation data from OpenTopoData" : "OpenTopoData دىن ئېگىزلىك سانلىق مەلۇماتلىرى", + "\"{title} icon\"" : "\"{title} سىنبەلگىسى\"" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dashboard/l10n/ug.json b/apps/dashboard/l10n/ug.json index e962429e80f..cecbee79dbc 100644 --- a/apps/dashboard/l10n/ug.json +++ b/apps/dashboard/l10n/ug.json @@ -12,7 +12,6 @@ "Good evening, {name}" : "خەيرلىك كەچ ، {name}", "Hello" : "ياخشىمۇسىز", "Hello, {name}" : "ياخشىمۇسىز ، {name}", - "\"{title} icon\"" : "\"{title} سىنبەلگىسى\"", "Customize" : "Customize", "Edit widgets" : "كىچىك قوراللارنى تەھرىرلەش", "Get more widgets from the App Store" : "ئەپ دۇكىنىدىن تېخىمۇ كۆپ كىچىك قوراللارغا ئېرىشىڭ", @@ -20,6 +19,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "شەخسىي مەخپىيەتلىكىڭىز ئۈچۈن ھاۋارايى سانلىق مەلۇماتلىرىڭىزنى Nextcloud مۇلازىمېتىرىڭىز تەلەپ قىلىدۇ ، شۇڭا ھاۋارايى مۇلازىمىتى ھېچقانداق شەخسىي ئۇچۇرغا ئېرىشەلمەيدۇ.", "Weather data from Met.no" : "Met.no دىن كەلگەن ھاۋارايى سانلىق مەلۇماتلىرى", "geocoding with Nominatim" : "Nominatim بىلەن جۇغراپىيىلىك كودلاش", - "elevation data from OpenTopoData" : "OpenTopoData دىن ئېگىزلىك سانلىق مەلۇماتلىرى" + "elevation data from OpenTopoData" : "OpenTopoData دىن ئېگىزلىك سانلىق مەلۇماتلىرى", + "\"{title} icon\"" : "\"{title} سىنبەلگىسى\"" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/uk.js b/apps/dashboard/l10n/uk.js index 9c7131b52e7..7cccfefbc78 100644 --- a/apps/dashboard/l10n/uk.js +++ b/apps/dashboard/l10n/uk.js @@ -15,7 +15,6 @@ OC.L10N.register( "Hello, {name}" : "Привіт, {name}", "Happy birthday 🥳🤩🎂🎉" : "З Днем народження 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "З Днем народження, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} \"іконка\"", "Customize" : "Редагувати", "Edit widgets" : "Редагувати віджети", "Get more widgets from the App Store" : "Більше віджетів у каталозі застосунків", @@ -23,6 +22,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Для забезпечення вашої конфіденційності дані про погоду запитуються вашим сервером Nextcloud від вашого імені, тому служба погоди не отримує особисту інформацію.", "Weather data from Met.no" : "Дані про погоду з Met.no", "geocoding with Nominatim" : "геокодування за допомогою Nominatim", - "elevation data from OpenTopoData" : "дані про висоту з OpenTopoData" + "elevation data from OpenTopoData" : "дані про висоту з OpenTopoData", + "\"{title} icon\"" : "\"{title} \"іконка\"" }, "nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"); diff --git a/apps/dashboard/l10n/uk.json b/apps/dashboard/l10n/uk.json index 231c1aa9cbc..09438fdc22c 100644 --- a/apps/dashboard/l10n/uk.json +++ b/apps/dashboard/l10n/uk.json @@ -13,7 +13,6 @@ "Hello, {name}" : "Привіт, {name}", "Happy birthday 🥳🤩🎂🎉" : "З Днем народження 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "З Днем народження, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} \"іконка\"", "Customize" : "Редагувати", "Edit widgets" : "Редагувати віджети", "Get more widgets from the App Store" : "Більше віджетів у каталозі застосунків", @@ -21,6 +20,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Для забезпечення вашої конфіденційності дані про погоду запитуються вашим сервером Nextcloud від вашого імені, тому служба погоди не отримує особисту інформацію.", "Weather data from Met.no" : "Дані про погоду з Met.no", "geocoding with Nominatim" : "геокодування за допомогою Nominatim", - "elevation data from OpenTopoData" : "дані про висоту з OpenTopoData" + "elevation data from OpenTopoData" : "дані про висоту з OpenTopoData", + "\"{title} icon\"" : "\"{title} \"іконка\"" },"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/uz.js b/apps/dashboard/l10n/uz.js index e85d5ea9296..2140c308e7d 100644 --- a/apps/dashboard/l10n/uz.js +++ b/apps/dashboard/l10n/uz.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "Assalomu aleykum, {name}", "Happy birthday 🥳🤩🎂🎉" : "Tug'ilgan kun muborak bo'lsin 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Tug'ilgan kun muborak bo'lsin, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} belgisi\"", "Customize" : "Moslashtirish", "Edit widgets" : "Vidjetlarni tahrirlash", "Get more widgets from the App Store" : "App Store'dan ko'proq vidjetlarni oling", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Maxfiyligingiz uchun ob-havo maʼlumotlari sizning nomingizdan Nextcloud serveringiz tomonidan soʻraladi, shuning uchun ob-havo xizmati shaxsiy maʼlumotlarni olmaydi.", "Weather data from Met.no" : "Met.no dan ob-havo ma'lumotlari", "geocoding with Nominatim" : "Nominatim bilan geokodlash", - "elevation data from OpenTopoData" : "OpenTopoData dan balandlik ma'lumotlari" + "elevation data from OpenTopoData" : "OpenTopoData dan balandlik ma'lumotlari", + "\"{title} icon\"" : "\"{title} belgisi\"" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/uz.json b/apps/dashboard/l10n/uz.json index 22ce852402a..912c35d409f 100644 --- a/apps/dashboard/l10n/uz.json +++ b/apps/dashboard/l10n/uz.json @@ -14,7 +14,6 @@ "Hello, {name}" : "Assalomu aleykum, {name}", "Happy birthday 🥳🤩🎂🎉" : "Tug'ilgan kun muborak bo'lsin 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "Tug'ilgan kun muborak bo'lsin, {name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} belgisi\"", "Customize" : "Moslashtirish", "Edit widgets" : "Vidjetlarni tahrirlash", "Get more widgets from the App Store" : "App Store'dan ko'proq vidjetlarni oling", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Maxfiyligingiz uchun ob-havo maʼlumotlari sizning nomingizdan Nextcloud serveringiz tomonidan soʻraladi, shuning uchun ob-havo xizmati shaxsiy maʼlumotlarni olmaydi.", "Weather data from Met.no" : "Met.no dan ob-havo ma'lumotlari", "geocoding with Nominatim" : "Nominatim bilan geokodlash", - "elevation data from OpenTopoData" : "OpenTopoData dan balandlik ma'lumotlari" + "elevation data from OpenTopoData" : "OpenTopoData dan balandlik ma'lumotlari", + "\"{title} icon\"" : "\"{title} belgisi\"" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/vi.js b/apps/dashboard/l10n/vi.js index 6be5e56c41a..05d2d143c9c 100644 --- a/apps/dashboard/l10n/vi.js +++ b/apps/dashboard/l10n/vi.js @@ -13,7 +13,6 @@ OC.L10N.register( "Good evening, {name}" : "Chào buổi tối, {name}", "Hello" : "Xin chào", "Hello, {name}" : "Xin chào, {name}", - "\"{title} icon\"" : "\"{title} icon\"", "Customize" : "Tuỳ chỉnh", "Edit widgets" : "Chỉnh sửa widget", "Get more widgets from the App Store" : "Tải thêm widget từ App Store", @@ -21,6 +20,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Vì quyền riêng tư của bạn, dữ liệu thời tiết được yêu cầu bởi máy chủ Nextcloud thay mặt bạn để dịch vụ thời tiết không nhận được thông tin cá nhân.", "Weather data from Met.no" : "Dữ liệu thời tiết từ Met.no", "geocoding with Nominatim" : "mã hóa địa lý với Nominatim", - "elevation data from OpenTopoData" : "dữ liệu độ cao từ OpenTopoData" + "elevation data from OpenTopoData" : "dữ liệu độ cao từ OpenTopoData", + "\"{title} icon\"" : "\"{title} icon\"" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/vi.json b/apps/dashboard/l10n/vi.json index bd2743a9b1d..d3da5f426e8 100644 --- a/apps/dashboard/l10n/vi.json +++ b/apps/dashboard/l10n/vi.json @@ -11,7 +11,6 @@ "Good evening, {name}" : "Chào buổi tối, {name}", "Hello" : "Xin chào", "Hello, {name}" : "Xin chào, {name}", - "\"{title} icon\"" : "\"{title} icon\"", "Customize" : "Tuỳ chỉnh", "Edit widgets" : "Chỉnh sửa widget", "Get more widgets from the App Store" : "Tải thêm widget từ App Store", @@ -19,6 +18,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "Vì quyền riêng tư của bạn, dữ liệu thời tiết được yêu cầu bởi máy chủ Nextcloud thay mặt bạn để dịch vụ thời tiết không nhận được thông tin cá nhân.", "Weather data from Met.no" : "Dữ liệu thời tiết từ Met.no", "geocoding with Nominatim" : "mã hóa địa lý với Nominatim", - "elevation data from OpenTopoData" : "dữ liệu độ cao từ OpenTopoData" + "elevation data from OpenTopoData" : "dữ liệu độ cao từ OpenTopoData", + "\"{title} icon\"" : "\"{title} icon\"" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/zh_CN.js b/apps/dashboard/l10n/zh_CN.js index 18a0d42f636..dcaad44161e 100644 --- a/apps/dashboard/l10n/zh_CN.js +++ b/apps/dashboard/l10n/zh_CN.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "你好, {name}", "Happy birthday 🥳🤩🎂🎉" : "生日快乐 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快乐,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "{title} 图标", "Customize" : "自定义", "Edit widgets" : "编辑小部件", "Get more widgets from the App Store" : "从应用商店获取更多小部件", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "为了您的隐私,天气数据由您的 Nextcloud 服务器为您获取,这样天气服务就无法获得您的个人信息。", "Weather data from Met.no" : "天气数据来自 Met.no", "geocoding with Nominatim" : "使用 Nominatim 地理编码", - "elevation data from OpenTopoData" : "海拔数据来自 OpenTopoData" + "elevation data from OpenTopoData" : "海拔数据来自 OpenTopoData", + "\"{title} icon\"" : "{title} 图标" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/zh_CN.json b/apps/dashboard/l10n/zh_CN.json index 32ae48e0a52..4569ab5ec98 100644 --- a/apps/dashboard/l10n/zh_CN.json +++ b/apps/dashboard/l10n/zh_CN.json @@ -14,7 +14,6 @@ "Hello, {name}" : "你好, {name}", "Happy birthday 🥳🤩🎂🎉" : "生日快乐 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快乐,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "{title} 图标", "Customize" : "自定义", "Edit widgets" : "编辑小部件", "Get more widgets from the App Store" : "从应用商店获取更多小部件", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "为了您的隐私,天气数据由您的 Nextcloud 服务器为您获取,这样天气服务就无法获得您的个人信息。", "Weather data from Met.no" : "天气数据来自 Met.no", "geocoding with Nominatim" : "使用 Nominatim 地理编码", - "elevation data from OpenTopoData" : "海拔数据来自 OpenTopoData" + "elevation data from OpenTopoData" : "海拔数据来自 OpenTopoData", + "\"{title} icon\"" : "{title} 图标" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/zh_HK.js b/apps/dashboard/l10n/zh_HK.js index 15905b4633d..557ec2bedc0 100644 --- a/apps/dashboard/l10n/zh_HK.js +++ b/apps/dashboard/l10n/zh_HK.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "哈囉,{name}", "Happy birthday 🥳🤩🎂🎉" : "生日快樂 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快樂,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} 圖示\"", "Customize" : "自訂", "Edit widgets" : "編輯小工具", "Get more widgets from the App Store" : "從 App Store 取得更多小工具", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "為了保護您的隱私,Nextcloud 會代您請求氣象資料,因此天氣服務不會收到您的個人資訊。", "Weather data from Met.no" : "氣象資訊來自 Met.no", "geocoding with Nominatim" : "使用 Nominatim 來進行地理編碼", - "elevation data from OpenTopoData" : "來自 OpenTopoData 的海拔資料" + "elevation data from OpenTopoData" : "來自 OpenTopoData 的海拔資料", + "\"{title} icon\"" : "\"{title} 圖示\"" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/zh_HK.json b/apps/dashboard/l10n/zh_HK.json index 46333510a82..a7cede02590 100644 --- a/apps/dashboard/l10n/zh_HK.json +++ b/apps/dashboard/l10n/zh_HK.json @@ -14,7 +14,6 @@ "Hello, {name}" : "哈囉,{name}", "Happy birthday 🥳🤩🎂🎉" : "生日快樂 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快樂,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "\"{title} 圖示\"", "Customize" : "自訂", "Edit widgets" : "編輯小工具", "Get more widgets from the App Store" : "從 App Store 取得更多小工具", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "為了保護您的隱私,Nextcloud 會代您請求氣象資料,因此天氣服務不會收到您的個人資訊。", "Weather data from Met.no" : "氣象資訊來自 Met.no", "geocoding with Nominatim" : "使用 Nominatim 來進行地理編碼", - "elevation data from OpenTopoData" : "來自 OpenTopoData 的海拔資料" + "elevation data from OpenTopoData" : "來自 OpenTopoData 的海拔資料", + "\"{title} icon\"" : "\"{title} 圖示\"" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/l10n/zh_TW.js b/apps/dashboard/l10n/zh_TW.js index 472c1ecb5bd..10aa30c9fe7 100644 --- a/apps/dashboard/l10n/zh_TW.js +++ b/apps/dashboard/l10n/zh_TW.js @@ -16,7 +16,6 @@ OC.L10N.register( "Hello, {name}" : "嗨,{name}", "Happy birthday 🥳🤩🎂🎉" : "生日快樂 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快樂,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "「{title} 圖示」", "Customize" : "自訂", "Edit widgets" : "編輯小工具", "Get more widgets from the App Store" : "從應用程式商店取得更多小工具", @@ -24,6 +23,7 @@ OC.L10N.register( "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "為了保護您的隱私,Nextcloud 伺服器會代您請求氣象資料,因此天氣服務不會收到您的個人資訊。", "Weather data from Met.no" : "氣象資訊來自 Met.no", "geocoding with Nominatim" : "地理編碼使用 Nominatim", - "elevation data from OpenTopoData" : "海拔資料來自 OpenTopoData" + "elevation data from OpenTopoData" : "海拔資料來自 OpenTopoData", + "\"{title} icon\"" : "「{title} 圖示」" }, "nplurals=1; plural=0;"); diff --git a/apps/dashboard/l10n/zh_TW.json b/apps/dashboard/l10n/zh_TW.json index 142e61dac51..3b8a8776418 100644 --- a/apps/dashboard/l10n/zh_TW.json +++ b/apps/dashboard/l10n/zh_TW.json @@ -14,7 +14,6 @@ "Hello, {name}" : "嗨,{name}", "Happy birthday 🥳🤩🎂🎉" : "生日快樂 🥳🤩🎂🎉", "Happy birthday, {name} 🥳🤩🎂🎉" : "生日快樂,{name} 🥳🤩🎂🎉", - "\"{title} icon\"" : "「{title} 圖示」", "Customize" : "自訂", "Edit widgets" : "編輯小工具", "Get more widgets from the App Store" : "從應用程式商店取得更多小工具", @@ -22,6 +21,7 @@ "For your privacy, the weather data is requested by your Nextcloud server on your behalf so the weather service receives no personal information." : "為了保護您的隱私,Nextcloud 伺服器會代您請求氣象資料,因此天氣服務不會收到您的個人資訊。", "Weather data from Met.no" : "氣象資訊來自 Met.no", "geocoding with Nominatim" : "地理編碼使用 Nominatim", - "elevation data from OpenTopoData" : "海拔資料來自 OpenTopoData" + "elevation data from OpenTopoData" : "海拔資料來自 OpenTopoData", + "\"{title} icon\"" : "「{title} 圖示」" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dashboard/src/DashboardApp.vue b/apps/dashboard/src/DashboardApp.vue index 42879a5fc0f..afc874be2c9 100644 --- a/apps/dashboard/src/DashboardApp.vue +++ b/apps/dashboard/src/DashboardApp.vue @@ -24,20 +24,10 @@ class="panel"> <div class="panel--header"> <h2> - <img v-if="apiWidgets[panels[panelId].id].icon_url" - :alt="apiWidgets[panels[panelId].id].title + ' icon'" - :src="apiWidgets[panels[panelId].id].icon_url" - aria-hidden="true"> - <span v-else - :aria-labelledby="`panel-${panels[panelId].id}--header--icon--description`" - aria-hidden="true" - :class="apiWidgets[panels[panelId].id].icon_class" - role="img" /> + <img v-if="apiWidgets[panels[panelId].id].icon_url" :src="apiWidgets[panels[panelId].id].icon_url" alt=""> + <span v-else :class="apiWidgets[panels[panelId].id].icon_class" aria-hidden="true" /> {{ apiWidgets[panels[panelId].id].title }} </h2> - <span :id="`panel-${panels[panelId].id}--header--icon--description`" class="hidden-visually"> - {{ t('dashboard', '"{title} icon"', { title: apiWidgets[panels[panelId].id].title }) }} - </span> </div> <div class="panel--content"> <ApiDashboardWidget :widget="apiWidgets[panels[panelId].id]" @@ -48,13 +38,9 @@ <div v-else :key="panels[panelId].id" class="panel"> <div class="panel--header"> <h2> - <span :aria-labelledby="`panel-${panels[panelId].id}--header--icon--description`" - aria-hidden="true" - :class="panels[panelId].iconClass" - role="img" /> + <span :class="panels[panelId].iconClass" aria-hidden="true" /> {{ panels[panelId].title }} </h2> - <span :id="`panel-${panels[panelId].id}--header--icon--description`" class="hidden-visually"> {{ t('dashboard', '"{title} icon"', { title: panels[panelId].title }) }} </span> </div> <div class="panel--content" :class="{ loading: !panels[panelId].mounted }"> <div :ref="panels[panelId].id" :data-id="panels[panelId].id" /> @@ -102,10 +88,7 @@ :checked="isActive(panel)" @input="updateCheckbox(panel, $event.target.checked)"> <label :for="'panel-checkbox-' + panel.id" :class="{ draggable: isActive(panel) }"> - <img v-if="panel.iconUrl" - :alt="panel.title + ' icon'" - :src="panel.iconUrl" - aria-hidden="true"> + <img v-if="panel.iconUrl" alt="" :src="panel.iconUrl"> <span v-else :class="panel.iconClass" aria-hidden="true" /> {{ panel.title }} </label> diff --git a/apps/dav/l10n/de.js b/apps/dav/l10n/de.js index 964bf10370d..788e1bf2f75 100644 --- a/apps/dav/l10n/de.js +++ b/apps/dav/l10n/de.js @@ -161,7 +161,7 @@ OC.L10N.register( "When:" : "Wann:", "Location:" : "Ort:", "Link:" : "Link:", - "Occurring:" : "Vorkommend:", + "Occurring:" : "Findet statt:", "Accept" : "Akzeptieren", "Decline" : "Ablehnen", "More options …" : "Weitere Optionen …", diff --git a/apps/dav/l10n/de.json b/apps/dav/l10n/de.json index fa62791d7e8..32a5497bb4e 100644 --- a/apps/dav/l10n/de.json +++ b/apps/dav/l10n/de.json @@ -159,7 +159,7 @@ "When:" : "Wann:", "Location:" : "Ort:", "Link:" : "Link:", - "Occurring:" : "Vorkommend:", + "Occurring:" : "Findet statt:", "Accept" : "Akzeptieren", "Decline" : "Ablehnen", "More options …" : "Weitere Optionen …", diff --git a/apps/dav/l10n/de_DE.js b/apps/dav/l10n/de_DE.js index 0b1e2863f54..ce9c993e027 100644 --- a/apps/dav/l10n/de_DE.js +++ b/apps/dav/l10n/de_DE.js @@ -161,7 +161,7 @@ OC.L10N.register( "When:" : "Wann:", "Location:" : "Ort:", "Link:" : "Link:", - "Occurring:" : "Vorkommend:", + "Occurring:" : "Findet statt:", "Accept" : "Akzeptieren", "Decline" : "Ablehnen", "More options …" : "Weitere Optionen …", diff --git a/apps/dav/l10n/de_DE.json b/apps/dav/l10n/de_DE.json index 319c04131da..0e903fe8c06 100644 --- a/apps/dav/l10n/de_DE.json +++ b/apps/dav/l10n/de_DE.json @@ -159,7 +159,7 @@ "When:" : "Wann:", "Location:" : "Ort:", "Link:" : "Link:", - "Occurring:" : "Vorkommend:", + "Occurring:" : "Findet statt:", "Accept" : "Akzeptieren", "Decline" : "Ablehnen", "More options …" : "Weitere Optionen …", diff --git a/apps/dav/l10n/fa.js b/apps/dav/l10n/fa.js index dd654921916..692e4fff45e 100644 --- a/apps/dav/l10n/fa.js +++ b/apps/dav/l10n/fa.js @@ -4,96 +4,170 @@ OC.L10N.register( "Calendar" : "تقویم", "Tasks" : "وظایف", "Personal" : "شخصی", - "{actor} created calendar {calendar}" : "{actor} created calendar {calendar}", - "You created calendar {calendar}" : "تقویم ساخته شد", - "{actor} deleted calendar {calendar}" : "{actor} deleted calendar {calendar}", - "You deleted calendar {calendar}" : "You deleted calendar {calendar}", - "{actor} updated calendar {calendar}" : "{actor} updated calendar {calendar}", - "You updated calendar {calendar}" : "You updated calendar {calendar}", - "{actor} restored calendar {calendar}" : "{actor} restored calendar {calendar}", - "You restored calendar {calendar}" : "You restored calendar {calendar}", - "You shared calendar {calendar} as public link" : "You shared calendar {calendar} as public link", - "You removed public link for calendar {calendar}" : "You removed public link for calendar {calendar}", - "{actor} shared calendar {calendar} with you" : "{actor} shared calendar {calendar} with you", - "You shared calendar {calendar} with {user}" : "You shared calendar {calendar} with {user}", - "{actor} shared calendar {calendar} with {user}" : "{actor} shared calendar {calendar} with {user}", - "{actor} unshared calendar {calendar} from you" : "{actor} unshared calendar {calendar} from you", - "You unshared calendar {calendar} from {user}" : "You unshared calendar {calendar} from {user}", - "{actor} unshared calendar {calendar} from {user}" : "{actor} unshared calendar {calendar} from {user}", - "{actor} unshared calendar {calendar} from themselves" : "{actor} unshared calendar {calendar} from themselves", - "You shared calendar {calendar} with group {group}" : "You shared calendar {calendar} with group {group}", - "{actor} shared calendar {calendar} with group {group}" : "{actor} shared calendar {calendar} with group {group}", - "You unshared calendar {calendar} from group {group}" : "You unshared calendar {calendar} from group {group}", - "{actor} unshared calendar {calendar} from group {group}" : "{actor} unshared calendar {calendar} from group {group}", + "{actor} created calendar {calendar}" : "{actor} تقویم {calendar} را ایجاد کرد", + "You created calendar {calendar}" : "شما تقویم {calendar} را ایجاد کردید", + "{actor} deleted calendar {calendar}" : "{actor} تقویم {calendar} را حذف کرد", + "You deleted calendar {calendar}" : "شما تقویم {calendar} را حذف کردید", + "{actor} updated calendar {calendar}" : "{actor} تقویم {calendar} را بهروزرسانی کرد", + "You updated calendar {calendar}" : "شما تقویم {calendar} را بهروزرسانی کردید", + "{actor} restored calendar {calendar}" : "{actor} تقویم {calendar} را بازیابی کرد", + "You restored calendar {calendar}" : "شما تقویم {calendar} را بازیابی کردید", + "You shared calendar {calendar} as public link" : "شما تقویم {calendar} را بهعنوان پیوند عمومی به اشتراک گذاشتید", + "You removed public link for calendar {calendar}" : "شما پیوند عمومی تقویم {calendar} را حذف کردید", + "{actor} shared calendar {calendar} with you" : "{actor} تقویم {calendar} را با شما به اشتراک گذاشت", + "You shared calendar {calendar} with {user}" : "شما تقویم {calendar} را با {user} به اشتراک گذاشتید", + "{actor} shared calendar {calendar} with {user}" : "{actor} تقویم {calendar} را با {user} به اشتراک گذاشت", + "{actor} unshared calendar {calendar} from you" : "{actor} اشتراکگذاری تقویم {calendar} را از شما لغو کرد", + "You unshared calendar {calendar} from {user}" : "شما اشتراکگذاری تقویم {calendar} را از {user} لغو کردید", + "{actor} unshared calendar {calendar} from {user}" : "{actor} اشتراکگذاری تقویم {calendar} را از {user} لغو کرد", + "{actor} unshared calendar {calendar} from themselves" : "{actor} اشتراکگذاری تقویم {calendar} را از خود لغو کرد", + "You shared calendar {calendar} with group {group}" : "شما تقویم {calendar} را با گروه {group} به اشتراک گذاشتید", + "{actor} shared calendar {calendar} with group {group}" : "{actor} تقویم {calendar} را با گروه {group} به اشتراک گذاشت", + "You unshared calendar {calendar} from group {group}" : "شما اشتراکگذاری تقویم {calendar} را از گروه {group} لغو کردید", + "{actor} unshared calendar {calendar} from group {group}" : "{actor} اشتراکگذاری تقویم {calendar} را از گروه {group} لغو کرد", "Untitled event" : "رویداد بدون عنوان", - "{actor} created event {event} in calendar {calendar}" : "{actor} created event {event} in calendar {calendar}", - "You created event {event} in calendar {calendar}" : "You created event {event} in calendar {calendar}", - "{actor} deleted event {event} from calendar {calendar}" : "{actor} deleted event {event} from calendar {calendar}", - "You deleted event {event} from calendar {calendar}" : "You deleted event {event} from calendar {calendar}", - "{actor} updated event {event} in calendar {calendar}" : "{actor} updated event {event} in calendar {calendar}", - "You updated event {event} in calendar {calendar}" : "You updated event {event} in calendar {calendar}", - "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}", - "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}", - "{actor} restored event {event} of calendar {calendar}" : "{actor} restored event {event} of calendar {calendar}", - "You restored event {event} of calendar {calendar}" : "You restored event {event} of calendar {calendar}", + "{actor} created event {event} in calendar {calendar}" : "{actor} رویداد {event} را در تقویم {calendar} ایجاد کرد", + "You created event {event} in calendar {calendar}" : "شما رویداد {event} را در تقویم {calendar} ایجاد کردید", + "{actor} deleted event {event} from calendar {calendar}" : "{actor} رویداد {event} را از تقویم {calendar} حذف کرد", + "You deleted event {event} from calendar {calendar}" : "شما رویداد {event} را از تقویم {calendar} حذف کردید", + "{actor} updated event {event} in calendar {calendar}" : "{actor} رویداد {event} را در تقویم {calendar} بهروزرسانی کرد", + "You updated event {event} in calendar {calendar}" : "شما رویداد {event} را در تقویم {calendar} بهروزرسانی کردید", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} رویداد {event} را از تقویم {sourceCalendar} به تقویم {targetCalendar} منتقل کرد", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "شما رویداد {event} را از تقویم {sourceCalendar} به تقویم {targetCalendar} منتقل کردید", + "{actor} restored event {event} of calendar {calendar}" : "{actor} رویداد {event} را از تقویم {calendar} بازیابی کرد", + "You restored event {event} of calendar {calendar}" : "شما رویداد {event} را از تقویم {calendar} بازیابی کردید", "Busy" : "مشغول", - "{actor} created to-do {todo} in list {calendar}" : "{actor} created to-do {todo} in list {calendar}", - "You created to-do {todo} in list {calendar}" : "You created to-do {todo} in list {calendar}", - "{actor} deleted to-do {todo} from list {calendar}" : "{actor} deleted to-do {todo} from list {calendar}", - "You deleted to-do {todo} from list {calendar}" : "You deleted to-do {todo} from list {calendar}", - "{actor} updated to-do {todo} in list {calendar}" : "{actor} updated to-do {todo} in list {calendar}", - "You updated to-do {todo} in list {calendar}" : "You updated to-do {todo} in list {calendar}", - "{actor} solved to-do {todo} in list {calendar}" : "{actor} solved to-do {todo} in list {calendar}", - "You solved to-do {todo} in list {calendar}" : "You solved to-do {todo} in list {calendar}", - "{actor} reopened to-do {todo} in list {calendar}" : "{actor} reopened to-do {todo} in list {calendar}", - "You reopened to-do {todo} in list {calendar}" : "You reopened to-do {todo} in list {calendar}", - "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}", - "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}", - "Calendar, contacts and tasks" : "Calendar, contacts and tasks", - "A <strong>calendar</strong> was modified" : "یک تقویم تغییر کرد", - "A calendar <strong>event</strong> was modified" : "یک رویداد ثبت شده در تقویم تغییر کرد", - "A calendar <strong>to-do</strong> was modified" : "یک کار ثبت شده در تقویم تغییر کرد", - "Contact birthdays" : "Contact birthdays", - "Death of %s" : "Death of %s", + "{actor} created to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} ایجاد کرد", + "You created to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} ایجاد کردید", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} کار {todo} را از لیست {calendar} حذف کرد", + "You deleted to-do {todo} from list {calendar}" : "شما کار {todo} را از لیست {calendar} حذف کردید", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} بهروزرسانی کرد", + "You updated to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} بهروزرسانی کردید", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} حل کرد", + "You solved to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} حل کردید", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} بازگشایی کرد", + "You reopened to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} بازگشایی کردید", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} کار {todo} را از لیست {sourceCalendar} به لیست {targetCalendar} منتقل کرد", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "شما کار {todo} را از لیست {sourceCalendar} به لیست {targetCalendar} منتقل کردید", + "Calendar, contacts and tasks" : "تقویم، مخاطبین و وظایف", + "A <strong>calendar</strong> was modified" : "یک <strong>تقویم</strong> تغییر کرد", + "A calendar <strong>event</strong> was modified" : "یک <strong>رویداد</strong> تقویم تغییر کرد", + "A calendar <strong>to-do</strong> was modified" : "یک <strong>کار</strong> تقویم تغییر کرد", + "Contact birthdays" : "تولد مخاطبین", + "Death of %s" : "فوت %s", "Untitled calendar" : "تقویم بدون عنوان", - "Calendar:" : "Calendar:", + "Calendar:" : "تقویم:", "Date:" : "تاریخ:", "Where:" : "مکان:", "Description:" : "توضیحات:", - "_%n year_::_%n years_" : ["%n year","%n years"], - "_%n month_::_%n months_" : ["%n month","%n months"], - "_%n day_::_%n days_" : ["%n day","%n days"], - "_%n hour_::_%n hours_" : ["%n hour","%n hours"], - "_%n minute_::_%n minutes_" : ["%n minute","%n minutes"], - "%s (in %s)" : "%s (in %s)", - "%s (%s ago)" : "%s (%s ago)", - "Calendar: %s" : "Calendar: %s", - "Date: %s" : "Date: %s", - "Description: %s" : "Description: %s", - "Where: %s" : "Where: %s", + "_%n year_::_%n years_" : ["%n سال","%n سال"], + "_%n month_::_%n months_" : ["%n ماه","%n ماه"], + "_%n day_::_%n days_" : ["%n روز","%n روز"], + "_%n hour_::_%n hours_" : ["%n ساعت","%n ساعت"], + "_%n minute_::_%n minutes_" : ["%n دقیقه","%n دقیقه"], + "%s (in %s)" : "%s (در %s)", + "%s (%s ago)" : "%s (%s پیش)", + "Calendar: %s" : "تقویم: %s", + "Date: %s" : "تاریخ: %s", + "Description: %s" : "توضیحات: %s", + "Where: %s" : "مکان: %s", "%1$s via %2$s" : "%1$s از طریق %2$s", - "Cancelled: %1$s" : "Cancelled: %1$s", - "\"%1$s\" has been canceled" : "\"%1$s\" has been canceled", - "Re: %1$s" : "Re: %1$s", - "%1$s has accepted your invitation" : "%1$s has accepted your invitation", - "%1$s has tentatively accepted your invitation" : "%1$s has tentatively accepted your invitation", - "%1$s has declined your invitation" : "%1$s has declined your invitation", - "%1$s has responded to your invitation" : "%1$s has responded to your invitation", - "Invitation updated: %1$s" : "Invitation updated: %1$s", - "%1$s updated the event \"%2$s\"" : "%1$s updated the event \"%2$s\"", - "Invitation: %1$s" : "Invitation: %1$s", - "%1$s would like to invite you to \"%2$s\"" : "%1$s would like to invite you to \"%2$s\"", - "Organizer:" : "Organizer:", - "Attendees:" : "Attendees:", + "In the past on %1$s for the entire day" : "در گذشته در %1$s برای کل روز", + "_In a minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["در یک دقیقه در %1$s برای کل روز","در %n دقیقه در %1$s برای کل روز"], + "_In a hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["در یک ساعت در %1$s برای کل روز","در %n ساعت در %1$s برای کل روز"], + "_In a day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["در یک روز در %1$s برای کل روز","در %n روز در %1$s برای کل روز"], + "_In a week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["در یک هفته در %1$s برای کل روز","در %n هفته در %1$s برای کل روز"], + "_In a month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["در یک ماه در %1$s برای کل روز","در %n ماه در %1$s برای کل روز"], + "_In a year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["در یک سال در %1$s برای کل روز","در %n سال در %1$s برای کل روز"], + "In the past on %1$s between %2$s - %3$s" : "در گذشته در %1$s بین %2$s - %3$s", + "_In a minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["در یک دقیقه در %1$s بین %2$s - %3$s","در %n دقیقه در %1$s بین %2$s - %3$s"], + "_In a hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["در یک ساعت در %1$s بین %2$s - %3$s","در %n ساعت در %1$s بین %2$s - %3$s"], + "_In a day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["در یک روز در %1$s بین %2$s - %3$s","در %n روز در %1$s بین %2$s - %3$s"], + "_In a week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["در یک هفته در %1$s بین %2$s - %3$s","در %n هفته در %1$s بین %2$s - %3$s"], + "_In a month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["در یک ماه در %1$s بین %2$s - %3$s","در %n ماه در %1$s بین %2$s - %3$s"], + "_In a year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["در یک سال در %1$s بین %2$s - %3$s","در %n سال در %1$s بین %2$s - %3$s"], + "Could not generate when statement" : "امکان ایجاد عبارت زمان وجود ندارد", + "Every Day for the entire day" : "هر روز برای کل روز", + "Every Day for the entire day until %1$s" : "هر روز برای کل روز تا %1$s", + "Every Day between %1$s - %2$s" : "هر روز بین %1$s - %2$s", + "Every Day between %1$s - %2$s until %3$s" : "هر روز بین %1$s - %2$s تا %3$s", + "Every %1$d Days for the entire day" : "هر %1$d روز برای کل روز", + "Every %1$d Days for the entire day until %2$s" : "هر %1$d روز برای کل روز تا %2$s", + "Every %1$d Days between %2$s - %3$s" : "هر %1$d روز بین %2$s - %3$s", + "Every %1$d Days between %2$s - %3$s until %4$s" : "هر %1$d روز بین %2$s - %3$s تا %4$s", + "Could not generate event recurrence statement" : "امکان ایجاد عبارت تکرار رویداد وجود ندارد", + "Every Week on %1$s for the entire day" : "هر هفته در %1$s برای کل روز", + "Every Week on %1$s for the entire day until %2$s" : "هر هفته در %1$s برای کل روز تا %2$s", + "Every Week on %1$s between %2$s - %3$s" : "هر هفته در %1$s بین %2$s - %3$s", + "Every Week on %1$s between %2$s - %3$s until %4$s" : "هر هفته در %1$s بین %2$s - %3$s تا %4$s", + "Every %1$d Weeks on %2$s for the entire day" : "هر %1$d هفته در %2$s برای کل روز", + "Every %1$d Weeks on %2$s for the entire day until %3$s" : "هر %1$d هفته در %2$s برای کل روز تا %3$s", + "Every %1$d Weeks on %2$s between %3$s - %4$s" : "هر %1$d هفته در %2$s بین %3$s - %4$s", + "Every %1$d Weeks on %2$s between %3$s - %4$s until %5$s" : "هر %1$d هفته در %2$s بین %3$s - %4$s تا %5$s", + "Every Month on the %1$s for the entire day" : "هر ماه در %1$s برای کل روز", + "Every Month on the %1$s for the entire day until %2$s" : "هر ماه در %1$s برای کل روز تا %2$s", + "Every Month on the %1$s between %2$s - %3$s" : "هر ماه در %1$s بین %2$s - %3$s", + "Every Month on the %1$s between %2$s - %3$s until %4$s" : "هر ماه در %1$s بین %2$s - %3$s تا %4$s", + "Every %1$d Months on the %2$s for the entire day" : "هر %1$d ماه در %2$s برای کل روز", + "Every %1$d Months on the %2$s for the entire day until %3$s" : "هر %1$d ماه در %2$s برای کل روز تا %3$s", + "Every %1$d Months on the %2$s between %3$s - %4$s" : "هر %1$d ماه در %2$s بین %3$s - %4$s", + "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "هر %1$d ماه در %2$s بین %3$s - %4$s تا %5$s", + "Every Year in %1$s on the %2$s for the entire day" : "هر سال در %1$s در %2$s برای کل روز", + "Every Year in %1$s on the %2$s for the entire day until %3$s" : "هر سال در %1$s در %2$s برای کل روز تا %3$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s" : "هر سال در %1$s در %2$s بین %3$s - %4$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "هر سال در %1$s در %2$s بین %3$s - %4$s تا %5$s", + "Every %1$d Years in %2$s on the %3$s for the entire day" : "هر %1$d سال در %2$s در %3$s برای کل روز", + "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "هر %1$d سال در %2$s در %3$s برای کل روز تا %4$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "هر %1$d سال در %2$s در %3$s بین %4$s - %5$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "هر %1$d سال در %2$s در %3$s بین %4$s - %5$s تا %6$s", + "On specific dates for the entire day until %1$s" : "در تاریخهای مشخص برای کل روز تا %1$s", + "On specific dates between %1$s - %2$s until %3$s" : "در تاریخهای مشخص بین %1$s - %2$s تا %3$s", + "In the past on %1$s" : "در گذشته در %1$s", + "_In a minute on %1$s_::_In %n minutes on %1$s_" : ["در یک دقیقه در %1$s","در %n دقیقه در %1$s"], + "_In a hour on %1$s_::_In %n hours on %1$s_" : ["در یک ساعت در %1$s","در %n ساعت در %1$s"], + "_In a day on %1$s_::_In %n days on %1$s_" : ["در یک روز در %1$s","در %n روز در %1$s"], + "_In a week on %1$s_::_In %n weeks on %1$s_" : ["در یک هفته در %1$s","در %n هفته در %1$s"], + "_In a month on %1$s_::_In %n months on %1$s_" : ["در یک ماه در %1$s","در %n ماه در %1$s"], + "_In a year on %1$s_::_In %n years on %1$s_" : ["در یک سال در %1$s","در %n سال در %1$s"], + "In the past on %1$s then on %2$s" : "در گذشته در %1$s سپس در %2$s", + "_In a minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["در یک دقیقه در %1$s سپس در %2$s","در %n دقیقه در %1$s سپس در %2$s"], + "_In a hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["در یک ساعت در %1$s سپس در %2$s","در %n ساعت در %1$s سپس در %2$s"], + "_In a day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["در یک روز در %1$s سپس در %2$s","در %n روز در %1$s سپس در %2$s"], + "_In a week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["در یک هفته در %1$s سپس در %2$s","در %n هفته در %1$s سپس در %2$s"], + "_In a month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["در یک ماه در %1$s سپس در %2$s","در %n ماه در %1$s سپس در %2$s"], + "_In a year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["در یک سال در %1$s سپس در %2$s","در %n سال در %1$s سپس در %2$s"], + "In the past on %1$s then on %2$s and %3$s" : "در گذشته در %1$s سپس در %2$s و %3$s", + "_In a minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["در یک دقیقه در %1$s سپس در %2$s و %3$s","در %n دقیقه در %1$s سپس در %2$s و %3$s"], + "_In a hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["در یک ساعت در %1$s سپس در %2$s و %3$s","در %n ساعت در %1$s سپس در %2$s و %3$s"], + "_In a day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["در یک روز در %1$s سپس در %2$s و %3$s","در %n روز در %1$s سپس در %2$s و %3$s"], + "_In a week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["در یک هفته در %1$s سپس در %2$s و %3$s","در %n هفته در %1$s سپس در %2$s و %3$s"], + "_In a month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["در یک ماه در %1$s سپس در %2$s و %3$s","در %n ماه در %1$s سپس در %2$s و %3$s"], + "_In a year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["در یک سال در %1$s سپس در %2$s و %3$s","در %n سال در %1$s سپس در %2$s و %3$s"], + "Could not generate next recurrence statement" : "امکان ایجاد عبارت تکرار بعدی وجود ندارد", + "Cancelled: %1$s" : "لغو شد: %1$s", + "\"%1$s\" has been canceled" : "\"%1$s\" لغو شده است", + "Re: %1$s" : "پاسخ: %1$s", + "%1$s has accepted your invitation" : "%1$s دعوت شما را پذیرفته است", + "%1$s has tentatively accepted your invitation" : "%1$s دعوت شما را بهطور آزمایشی پذیرفته است", + "%1$s has declined your invitation" : "%1$s دعوت شما را رد کرده است", + "%1$s has responded to your invitation" : "%1$s به دعوت شما پاسخ داده است", + "Invitation updated: %1$s" : "دعوت بهروزرسانی شد: %1$s", + "%1$s updated the event \"%2$s\"" : "%1$s رویداد \"%2$s\" را بهروزرسانی کرد", + "Invitation: %1$s" : "دعوت: %1$s", + "%1$s would like to invite you to \"%2$s\"" : "%1$s مایل است شما را به \"%2$s\" دعوت کند", + "Organizer:" : "برگزارکننده:", + "Attendees:" : "شرکتکنندگان:", "Title:" : "عنوان:", + "When:" : "چه زمانی:", "Location:" : "مکان:", - "Link:" : "Link:", - "Accept" : "قبول", - "Decline" : "کاهش می یابد", - "More options …" : "More options …", - "More options at %s" : "More options at %s", + "Link:" : "پیوند:", + "Occurring:" : "در حال وقوع:", + "Accept" : "پذیرفتن", + "Decline" : "رد کردن", + "More options …" : "گزینههای بیشتر…", + "More options at %s" : "گزینههای بیشتر در %s", "Monday" : "دوشنبه", - "Tuesday" : "سه شنبه", + "Tuesday" : "سهشنبه", "Wednesday" : "چهارشنبه", "Thursday" : "پنجشنبه", "Friday" : "جمعه", @@ -105,101 +179,150 @@ OC.L10N.register( "April" : "آوریل", "May" : "مه", "June" : "ژوئن", - "July" : "جولای", + "July" : "ژوئیه", "August" : "اوت", "September" : "سپتامبر", "October" : "اکتبر", "November" : "نوامبر", "December" : "دسامبر", - "First" : "First", - "Last" : "Last", + "First" : "اول", + "Second" : "دوم", + "Third" : "سوم", + "Fourth" : "چهارم", + "Fifth" : "پنجم", + "Last" : "آخر", + "Second Last" : "دومی از آخر", + "Third Last" : "سومی از آخر", + "Fourth Last" : "چهارمی از آخر", + "Fifth Last" : "پنجمی از آخر", "Contacts" : "مخاطبین", - "{actor} created address book {addressbook}" : "{actor} created address book {addressbook}", - "You created address book {addressbook}" : "دفترچه آدرس ساخته شد", - "{actor} deleted address book {addressbook}" : "{actor} deleted address book {addressbook}", - "You deleted address book {addressbook}" : "You deleted address book {addressbook}", - "{actor} updated address book {addressbook}" : "{actor} updated address book {addressbook}", - "You updated address book {addressbook}" : "You updated address book {addressbook}", - "{actor} shared address book {addressbook} with you" : "{actor} shared address book {addressbook} with you", - "You shared address book {addressbook} with {user}" : "You shared address book {addressbook} with {user}", - "{actor} shared address book {addressbook} with {user}" : "{actor} shared address book {addressbook} with {user}", - "{actor} unshared address book {addressbook} from you" : "{actor} unshared address book {addressbook} from you", - "You unshared address book {addressbook} from {user}" : "You unshared address book {addressbook} from {user}", - "{actor} unshared address book {addressbook} from {user}" : "{actor} unshared address book {addressbook} from {user}", - "{actor} unshared address book {addressbook} from themselves" : "{actor} unshared address book {addressbook} from themselves", - "You shared address book {addressbook} with group {group}" : "You shared address book {addressbook} with group {group}", - "{actor} shared address book {addressbook} with group {group}" : "{actor} shared address book {addressbook} with group {group}", - "You unshared address book {addressbook} from group {group}" : "You unshared address book {addressbook} from group {group}", - "{actor} unshared address book {addressbook} from group {group}" : "{actor} unshared address book {addressbook} from group {group}", - "{actor} created contact {card} in address book {addressbook}" : "{actor} created contact {card} in address book {addressbook}", - "You created contact {card} in address book {addressbook}" : "You created contact {card} in address book {addressbook}", - "{actor} deleted contact {card} from address book {addressbook}" : "{actor} deleted contact {card} from address book {addressbook}", - "You deleted contact {card} from address book {addressbook}" : "You deleted contact {card} from address book {addressbook}", - "{actor} updated contact {card} in address book {addressbook}" : "{actor} updated contact {card} in address book {addressbook}", - "You updated contact {card} in address book {addressbook}" : "You updated contact {card} in address book {addressbook}", - "A <strong>contact</strong> or <strong>address book</strong> was modified" : "یک مخاطب یا دفترچه آدرس تغییر کرد", + "{actor} created address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را ایجاد کرد", + "You created address book {addressbook}" : "شما دفترچه آدرس {addressbook} را ایجاد کردید", + "{actor} deleted address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را حذف کرد", + "You deleted address book {addressbook}" : "شما دفترچه آدرس {addressbook} را حذف کردید", + "{actor} updated address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را بهروزرسانی کرد", + "You updated address book {addressbook}" : "شما دفترچه آدرس {addressbook} را بهروزرسانی کردید", + "{actor} shared address book {addressbook} with you" : "{actor} دفترچه آدرس {addressbook} را با شما به اشتراک گذاشت", + "You shared address book {addressbook} with {user}" : "شما دفترچه آدرس {addressbook} را با {user} به اشتراک گذاشتید", + "{actor} shared address book {addressbook} with {user}" : "{actor} دفترچه آدرس {addressbook} را با {user} به اشتراک گذاشت", + "{actor} unshared address book {addressbook} from you" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از شما لغو کرد", + "You unshared address book {addressbook} from {user}" : "شما اشتراکگذاری دفترچه آدرس {addressbook} را از {user} لغو کردید", + "{actor} unshared address book {addressbook} from {user}" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از {user} لغو کرد", + "{actor} unshared address book {addressbook} from themselves" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از خود لغو کرد", + "You shared address book {addressbook} with group {group}" : "شما دفترچه آدرس {addressbook} را با گروه {group} به اشتراک گذاشتید", + "{actor} shared address book {addressbook} with group {group}" : "{actor} دفترچه آدرس {addressbook} را با گروه {group} به اشتراک گذاشت", + "You unshared address book {addressbook} from group {group}" : "شما اشتراکگذاری دفترچه آدرس {addressbook} را از گروه {group} لغو کردید", + "{actor} unshared address book {addressbook} from group {group}" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از گروه {group} لغو کرد", + "{actor} created contact {card} in address book {addressbook}" : "{actor} مخاطب {card} را در دفترچه آدرس {addressbook} ایجاد کرد", + "You created contact {card} in address book {addressbook}" : "شما مخاطب {card} را در دفترچه آدرس {addressbook} ایجاد کردید", + "{actor} deleted contact {card} from address book {addressbook}" : "{actor} مخاطب {card} را از دفترچه آدرس {addressbook} حذف کرد", + "You deleted contact {card} from address book {addressbook}" : "شما مخاطب {card} را از دفترچه آدرس {addressbook} حذف کردید", + "{actor} updated contact {card} in address book {addressbook}" : "{actor} مخاطب {card} را در دفترچه آدرس {addressbook} بهروزرسانی کرد", + "You updated contact {card} in address book {addressbook}" : "شما مخاطب {card} را در دفترچه آدرس {addressbook} بهروزرسانی کردید", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "یک <strong>مخاطب</strong> یا <strong>دفترچه آدرس</strong> تغییر کرد", "Accounts" : "حسابها", - "File is not updatable: %1$s" : "File is not updatable: %1$s", - "Could not write to final file, canceled by hook" : "Could not write to final file, canceled by hook", - "Could not write file contents" : "Could not write file contents", - "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], - "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)", - "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side.", - "Could not rename part file to final file, canceled by hook" : "Could not rename part file to final file, canceled by hook", - "Could not rename part file to final file" : "Could not rename part file to final file", - "Failed to check file size: %1$s" : "Failed to check file size: %1$s", - "Encryption not ready: %1$s" : "Encryption not ready: %1$s", - "Failed to open file: %1$s" : "Failed to open file: %1$s", - "Failed to unlink: %1$s" : "Failed to unlink: %1$s", - "Failed to write file contents: %1$s" : "Failed to write file contents: %1$s", - "File not found: %1$s" : "File not found: %1$s", - "System is in maintenance mode." : "System is in maintenance mode.", - "Upgrade needed" : "Upgrade needed", - "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS.", - "Configures a CalDAV account" : "Configures a CalDAV account", - "Configures a CardDAV account" : "Configures a CardDAV account", - "Events" : "Events", + "System address book which holds all accounts" : "دفترچه آدرس سیستمی که شامل تمام حسابها است", + "File is not updatable: %1$s" : "فایل قابل بهروزرسانی نیست: %1$s", + "Failed to get storage for file" : "دریافت فضای ذخیرهسازی برای فایل با شکست مواجه شد", + "Could not write to final file, canceled by hook" : "نوشتن در فایل نهایی امکانپذیر نبود، توسط هوک لغو شد", + "Could not write file contents" : "امکان نوشتن محتویات فایل وجود ندارد", + "_%n byte_::_%n bytes_" : ["%n بایت","%n بایت"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "خطا هنگام کپی فایل به مکان مقصد (کپی شده: %1$s، حجم فایل مورد انتظار: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "حجم فایل مورد انتظار %1$s بود اما %2$s خوانده (از کلاینت Nextcloud) و نوشته (در فضای ذخیرهسازی Nextcloud) شد. این میتواند ناشی از مشکل شبکه در سمت ارسال یا مشکل نوشتن در فضای ذخیرهسازی در سمت سرور باشد.", + "Could not rename part file to final file, canceled by hook" : "امکان تغییر نام فایل جزئی به فایل نهایی وجود نداشت، توسط هوک لغو شد", + "Could not rename part file to final file" : "امکان تغییر نام فایل جزئی به فایل نهایی وجود ندارد", + "Failed to check file size: %1$s" : "بررسی حجم فایل با شکست مواجه شد: %1$s", + "Could not open file: %1$s, file does seem to exist" : "امکان باز کردن فایل وجود ندارد: %1$s، به نظر میرسد فایل وجود دارد", + "Could not open file: %1$s, file doesn't seem to exist" : "امکان باز کردن فایل وجود ندارد: %1$s، به نظر میرسد فایل وجود ندارد", + "Encryption not ready: %1$s" : "رمزگذاری آماده نیست: %1$s", + "Failed to open file: %1$s" : "باز کردن فایل با شکست مواجه شد: %1$s", + "Failed to unlink: %1$s" : "حذف پیوند با شکست مواجه شد: %1$s", + "Failed to write file contents: %1$s" : "نوشتن محتویات فایل با شکست مواجه شد: %1$s", + "File not found: %1$s" : "فایل یافت نشد: %1$s", + "Invalid target path" : "مسیر مقصد نامعتبر است", + "System is in maintenance mode." : "سیستم در حالت نگهداری است.", + "Upgrade needed" : "نیاز به ارتقا", + "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "برای استفاده از CalDAV و CardDAV با iOS/macOS، %s شما باید برای استفاده از HTTPS پیکربندی شود.", + "Configures a CalDAV account" : "یک حساب CalDAV را پیکربندی میکند", + "Configures a CardDAV account" : "یک حساب CardDAV را پیکربندی میکند", + "Events" : "رویدادها", "Untitled task" : "کار بدون عنوان", - "Completed on %s" : "Completed on %s", - "Due on %s by %s" : "Due on %s by %s", - "Due on %s" : "Due on %s", - "WebDAV endpoint" : "WebDAV endpoint", - "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken.", - "Migrated calendar (%1$s)" : "Migrated calendar (%1$s)", - "Calendars including events, details and attendees" : "Calendars including events, details and attendees", - "Contacts and groups" : "Contacts and groups", - "WebDAV" : "WebDAV", - "First day" : "First day", + "Completed on %s" : "تکمیل شده در %s", + "Due on %s by %s" : "موعد در %s توسط %s", + "Due on %s" : "موعد در %s", + "System Address Book" : "دفترچه آدرس سیستم", + "The system address book contains contact information for all users in your instance." : "دفترچه آدرس سیستم شامل اطلاعات تماس برای همه کاربران در نمونه شما است.", + "Enable System Address Book" : "فعال کردن دفترچه آدرس سیستم", + "DAV system address book" : "دفترچه آدرس سیستم DAV", + "No outstanding DAV system address book sync." : "هیچ همگامسازی دفترچه آدرس سیستم DAV در انتظار نیست.", + "The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "همگامسازی دفترچه آدرس سیستم DAV هنوز اجرا نشده است زیرا نمونه شما بیش از ۱۰۰۰ کاربر دارد یا خطایی رخ داده است. لطفاً آن را بهصورت دستی با فراخوانی \"occ dav:sync-system-addressbook\" اجرا کنید.", + "WebDAV endpoint" : "نقطه پایانی WebDAV", + "Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "امکان بررسی اینکه سرور وب شما به درستی برای همگامسازی فایل از طریق WebDAV تنظیم شده است، وجود ندارد. لطفاً به صورت دستی بررسی کنید.", + "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "سرور وب شما هنوز به درستی برای همگامسازی فایل تنظیم نشده است، زیرا به نظر میرسد رابط WebDAV خراب است.", + "Your web server is properly set up to allow file synchronization over WebDAV." : "سرور وب شما به درستی برای همگامسازی فایل از طریق WebDAV تنظیم شده است.", + "Migrated calendar (%1$s)" : "تقویم منتقل شده (%1$s)", + "Calendars including events, details and attendees" : "تقویمها شامل رویدادها، جزئیات و شرکتکنندگان", + "Contacts and groups" : "مخاطبین و گروهها", + "WebDAV" : "وبدَو", + "Absence saved" : "غیبت ذخیره شد", + "Failed to save your absence settings" : "ذخیره تنظیمات غیبت شما با شکست مواجه شد", + "Absence cleared" : "غیبت پاک شد", + "Failed to clear your absence settings" : "پاک کردن تنظیمات غیبت شما با شکست مواجه شد", + "First day" : "روز اول", + "Last day (inclusive)" : "روز آخر (شامل)", + "Out of office replacement (optional)" : "جایگزین خارج از دفتر (اختیاری)", + "Name of the replacement" : "نام جایگزین", + "No results." : "نتیجهای یافت نشد.", + "Start typing." : "شروع به تایپ کنید.", + "Short absence status" : "وضعیت کوتاه غیبت", + "Long absence Message" : "پیام طولانی غیبت", "Save" : "ذخیره", - "Failed to load availability" : "Failed to load availability", - "Saved availability" : "Saved availability", - "Failed to save availability" : "Failed to save availability", + "Disable absence" : "غیرفعال کردن غیبت", + "Failed to load availability" : "بارگذاری در دسترس بودن با شکست مواجه شد", + "Saved availability" : "در دسترس بودن ذخیره شد", + "Failed to save availability" : "ذخیره در دسترس بودن با شکست مواجه شد", "Time zone:" : "منطقه زمانی:", - "to" : "به", - "Delete slot" : "Delete slot", + "to" : "تا", + "Delete slot" : "حذف بازه زمانی", "No working hours set" : "ساعات کاری تعیین نشده است", - "Add slot" : "Add slot", - "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "وضعیت کاربر بصورت خودکار به \"مزاحم نشوید\" تغییر داده شود تا همه ی اعلان ها خاموش شوند", - "Availability" : "موجود بودن", - "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}.", - "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Please make sure to properly set up {emailopen}the email server{linkclose}.", - "Calendar server" : "Calendar server", - "Send invitations to attendees" : "Send invitations to attendees", - "Automatically generate a birthday calendar" : "Automatically generate a birthday calendar", - "Birthday calendars will be generated by a background job." : "Birthday calendars will be generated by a background job.", - "Hence they will not be available immediately after enabling but will show up after some time." : "Hence they will not be available immediately after enabling but will show up after some time.", - "Send notifications for events" : "Send notifications for events", - "Notifications are sent via background jobs, so these must occur often enough." : "Notifications are sent via background jobs, so these must occur often enough.", - "Send reminder notifications to calendar sharees as well" : "Send reminder notifications to calendar sharees as well", - "Reminders are always sent to organizers and attendees." : "Reminders are always sent to organizers and attendees.", - "Enable notifications for events via push" : "Enable notifications for events via push", - "Cancel" : "ردکردن", + "Add slot" : "افزودن بازه زمانی", + "Weekdays" : "روزهای هفته", + "Pick a start time for {dayName}" : "زمان شروع برای {dayName} را انتخاب کنید", + "Pick a end time for {dayName}" : "زمان پایان برای {dayName} را انتخاب کنید", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "وضعیت کاربر بصورت خودکار به \"مزاحم نشوید\" تغییر داده شود تا همه ی اعلان ها خاموش شوند.", + "Availability" : "در دسترس بودن", + "If you configure your working hours, other people will see when you are out of office when they book a meeting." : "اگر ساعات کاری خود را پیکربندی کنید، دیگران هنگام رزرو جلسه متوجه خواهند شد که شما در دفتر نیستید.", + "Absence" : "غیبت", + "Configure your next absence period." : "دوره غیبت بعدی خود را پیکربندی کنید.", + "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "همچنین {calendarappstoreopen}برنامه تقویم{linkclose} را نصب کنید، یا {calendardocopen}دسکتاپ و موبایل خود را برای همگامسازی متصل کنید ↗{linkclose}.", + "Please make sure to properly set up {emailopen}the email server{linkclose}." : "لطفاً مطمئن شوید که {emailopen}سرور ایمیل{linkclose} را به درستی تنظیم کردهاید.", + "Calendar server" : "سرور تقویم", + "Send invitations to attendees" : "ارسال دعوتنامهها به شرکتکنندگان", + "Automatically generate a birthday calendar" : "بهطور خودکار یک تقویم تولد ایجاد کنید", + "Birthday calendars will be generated by a background job." : "تقویمهای تولد توسط یک کار پسزمینه ایجاد خواهند شد.", + "Hence they will not be available immediately after enabling but will show up after some time." : "بنابراین بلافاصله پس از فعالسازی در دسترس نخواهند بود، اما پس از مدتی نمایان میشوند.", + "Send notifications for events" : "ارسال اعلانها برای رویدادها", + "Notifications are sent via background jobs, so these must occur often enough." : "اعلانها از طریق کارهای پسزمینه ارسال میشوند، بنابراین این کارها باید به اندازه کافی مکرر انجام شوند.", + "Send reminder notifications to calendar sharees as well" : "ارسال اعلانهای یادآوری به اشتراکگذاران تقویم نیز", + "Reminders are always sent to organizers and attendees." : "یادآوریها همیشه برای برگزارکنندگان و شرکتکنندگان ارسال میشوند.", + "Enable notifications for events via push" : "فعال کردن اعلانها برای رویدادها از طریق پوش", + "Cancel" : "لغو", "Import" : "وارد کردن", - "Error while saving settings" : "Error while saving settings", - "There was an error updating your attendance status." : "There was an error updating your attendance status.", - "Please contact the organizer directly." : "Please contact the organizer directly.", - "Are you accepting the invitation?" : "Are you accepting the invitation?", + "Error while saving settings" : "خطا هنگام ذخیره تنظیمات", + "Contact reset successfully" : "مخاطب با موفقیت بازنشانی شد", + "Error while resetting contact" : "خطا هنگام بازنشانی مخاطب", + "Contact imported successfully" : "مخاطب با موفقیت وارد شد", + "Error while importing contact" : "خطا هنگام وارد کردن مخاطب", + "Example Content" : "محتوای نمونه", + "Set example content to be created on new user first login." : "محتوای نمونه را برای ایجاد در اولین ورود کاربر جدید تنظیم کنید.", + "Import contact" : "وارد کردن مخاطب", + "Reset to default contact" : "بازنشانی به مخاطب پیشفرض", + "Import contacts" : "وارد کردن مخاطبین", + "Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?" : "وارد کردن یک فایل .vcf جدید، مخاطب پیشفرض موجود را حذف کرده و آن را با مخاطب جدید جایگزین میکند. آیا میخواهید ادامه دهید؟", + "There was an error updating your attendance status." : "خطایی در بهروزرسانی وضعیت حضور شما رخ داد.", + "Please contact the organizer directly." : "لطفاً مستقیماً با برگزارکننده تماس بگیرید.", + "Are you accepting the invitation?" : "آیا دعوت را میپذیرید؟", "Tentative" : "آزمایشی", - "Your attendance was updated successfully." : "Your attendance was updated successfully." + "Your attendance was updated successfully." : "وضعیت حضور شما با موفقیت بهروزرسانی شد." }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/dav/l10n/fa.json b/apps/dav/l10n/fa.json index 0248714b572..adb640cb47e 100644 --- a/apps/dav/l10n/fa.json +++ b/apps/dav/l10n/fa.json @@ -2,96 +2,170 @@ "Calendar" : "تقویم", "Tasks" : "وظایف", "Personal" : "شخصی", - "{actor} created calendar {calendar}" : "{actor} created calendar {calendar}", - "You created calendar {calendar}" : "تقویم ساخته شد", - "{actor} deleted calendar {calendar}" : "{actor} deleted calendar {calendar}", - "You deleted calendar {calendar}" : "You deleted calendar {calendar}", - "{actor} updated calendar {calendar}" : "{actor} updated calendar {calendar}", - "You updated calendar {calendar}" : "You updated calendar {calendar}", - "{actor} restored calendar {calendar}" : "{actor} restored calendar {calendar}", - "You restored calendar {calendar}" : "You restored calendar {calendar}", - "You shared calendar {calendar} as public link" : "You shared calendar {calendar} as public link", - "You removed public link for calendar {calendar}" : "You removed public link for calendar {calendar}", - "{actor} shared calendar {calendar} with you" : "{actor} shared calendar {calendar} with you", - "You shared calendar {calendar} with {user}" : "You shared calendar {calendar} with {user}", - "{actor} shared calendar {calendar} with {user}" : "{actor} shared calendar {calendar} with {user}", - "{actor} unshared calendar {calendar} from you" : "{actor} unshared calendar {calendar} from you", - "You unshared calendar {calendar} from {user}" : "You unshared calendar {calendar} from {user}", - "{actor} unshared calendar {calendar} from {user}" : "{actor} unshared calendar {calendar} from {user}", - "{actor} unshared calendar {calendar} from themselves" : "{actor} unshared calendar {calendar} from themselves", - "You shared calendar {calendar} with group {group}" : "You shared calendar {calendar} with group {group}", - "{actor} shared calendar {calendar} with group {group}" : "{actor} shared calendar {calendar} with group {group}", - "You unshared calendar {calendar} from group {group}" : "You unshared calendar {calendar} from group {group}", - "{actor} unshared calendar {calendar} from group {group}" : "{actor} unshared calendar {calendar} from group {group}", + "{actor} created calendar {calendar}" : "{actor} تقویم {calendar} را ایجاد کرد", + "You created calendar {calendar}" : "شما تقویم {calendar} را ایجاد کردید", + "{actor} deleted calendar {calendar}" : "{actor} تقویم {calendar} را حذف کرد", + "You deleted calendar {calendar}" : "شما تقویم {calendar} را حذف کردید", + "{actor} updated calendar {calendar}" : "{actor} تقویم {calendar} را بهروزرسانی کرد", + "You updated calendar {calendar}" : "شما تقویم {calendar} را بهروزرسانی کردید", + "{actor} restored calendar {calendar}" : "{actor} تقویم {calendar} را بازیابی کرد", + "You restored calendar {calendar}" : "شما تقویم {calendar} را بازیابی کردید", + "You shared calendar {calendar} as public link" : "شما تقویم {calendar} را بهعنوان پیوند عمومی به اشتراک گذاشتید", + "You removed public link for calendar {calendar}" : "شما پیوند عمومی تقویم {calendar} را حذف کردید", + "{actor} shared calendar {calendar} with you" : "{actor} تقویم {calendar} را با شما به اشتراک گذاشت", + "You shared calendar {calendar} with {user}" : "شما تقویم {calendar} را با {user} به اشتراک گذاشتید", + "{actor} shared calendar {calendar} with {user}" : "{actor} تقویم {calendar} را با {user} به اشتراک گذاشت", + "{actor} unshared calendar {calendar} from you" : "{actor} اشتراکگذاری تقویم {calendar} را از شما لغو کرد", + "You unshared calendar {calendar} from {user}" : "شما اشتراکگذاری تقویم {calendar} را از {user} لغو کردید", + "{actor} unshared calendar {calendar} from {user}" : "{actor} اشتراکگذاری تقویم {calendar} را از {user} لغو کرد", + "{actor} unshared calendar {calendar} from themselves" : "{actor} اشتراکگذاری تقویم {calendar} را از خود لغو کرد", + "You shared calendar {calendar} with group {group}" : "شما تقویم {calendar} را با گروه {group} به اشتراک گذاشتید", + "{actor} shared calendar {calendar} with group {group}" : "{actor} تقویم {calendar} را با گروه {group} به اشتراک گذاشت", + "You unshared calendar {calendar} from group {group}" : "شما اشتراکگذاری تقویم {calendar} را از گروه {group} لغو کردید", + "{actor} unshared calendar {calendar} from group {group}" : "{actor} اشتراکگذاری تقویم {calendar} را از گروه {group} لغو کرد", "Untitled event" : "رویداد بدون عنوان", - "{actor} created event {event} in calendar {calendar}" : "{actor} created event {event} in calendar {calendar}", - "You created event {event} in calendar {calendar}" : "You created event {event} in calendar {calendar}", - "{actor} deleted event {event} from calendar {calendar}" : "{actor} deleted event {event} from calendar {calendar}", - "You deleted event {event} from calendar {calendar}" : "You deleted event {event} from calendar {calendar}", - "{actor} updated event {event} in calendar {calendar}" : "{actor} updated event {event} in calendar {calendar}", - "You updated event {event} in calendar {calendar}" : "You updated event {event} in calendar {calendar}", - "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}", - "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}", - "{actor} restored event {event} of calendar {calendar}" : "{actor} restored event {event} of calendar {calendar}", - "You restored event {event} of calendar {calendar}" : "You restored event {event} of calendar {calendar}", + "{actor} created event {event} in calendar {calendar}" : "{actor} رویداد {event} را در تقویم {calendar} ایجاد کرد", + "You created event {event} in calendar {calendar}" : "شما رویداد {event} را در تقویم {calendar} ایجاد کردید", + "{actor} deleted event {event} from calendar {calendar}" : "{actor} رویداد {event} را از تقویم {calendar} حذف کرد", + "You deleted event {event} from calendar {calendar}" : "شما رویداد {event} را از تقویم {calendar} حذف کردید", + "{actor} updated event {event} in calendar {calendar}" : "{actor} رویداد {event} را در تقویم {calendar} بهروزرسانی کرد", + "You updated event {event} in calendar {calendar}" : "شما رویداد {event} را در تقویم {calendar} بهروزرسانی کردید", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} رویداد {event} را از تقویم {sourceCalendar} به تقویم {targetCalendar} منتقل کرد", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "شما رویداد {event} را از تقویم {sourceCalendar} به تقویم {targetCalendar} منتقل کردید", + "{actor} restored event {event} of calendar {calendar}" : "{actor} رویداد {event} را از تقویم {calendar} بازیابی کرد", + "You restored event {event} of calendar {calendar}" : "شما رویداد {event} را از تقویم {calendar} بازیابی کردید", "Busy" : "مشغول", - "{actor} created to-do {todo} in list {calendar}" : "{actor} created to-do {todo} in list {calendar}", - "You created to-do {todo} in list {calendar}" : "You created to-do {todo} in list {calendar}", - "{actor} deleted to-do {todo} from list {calendar}" : "{actor} deleted to-do {todo} from list {calendar}", - "You deleted to-do {todo} from list {calendar}" : "You deleted to-do {todo} from list {calendar}", - "{actor} updated to-do {todo} in list {calendar}" : "{actor} updated to-do {todo} in list {calendar}", - "You updated to-do {todo} in list {calendar}" : "You updated to-do {todo} in list {calendar}", - "{actor} solved to-do {todo} in list {calendar}" : "{actor} solved to-do {todo} in list {calendar}", - "You solved to-do {todo} in list {calendar}" : "You solved to-do {todo} in list {calendar}", - "{actor} reopened to-do {todo} in list {calendar}" : "{actor} reopened to-do {todo} in list {calendar}", - "You reopened to-do {todo} in list {calendar}" : "You reopened to-do {todo} in list {calendar}", - "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}", - "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}", - "Calendar, contacts and tasks" : "Calendar, contacts and tasks", - "A <strong>calendar</strong> was modified" : "یک تقویم تغییر کرد", - "A calendar <strong>event</strong> was modified" : "یک رویداد ثبت شده در تقویم تغییر کرد", - "A calendar <strong>to-do</strong> was modified" : "یک کار ثبت شده در تقویم تغییر کرد", - "Contact birthdays" : "Contact birthdays", - "Death of %s" : "Death of %s", + "{actor} created to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} ایجاد کرد", + "You created to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} ایجاد کردید", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} کار {todo} را از لیست {calendar} حذف کرد", + "You deleted to-do {todo} from list {calendar}" : "شما کار {todo} را از لیست {calendar} حذف کردید", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} بهروزرسانی کرد", + "You updated to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} بهروزرسانی کردید", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} حل کرد", + "You solved to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} حل کردید", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} کار {todo} را در لیست {calendar} بازگشایی کرد", + "You reopened to-do {todo} in list {calendar}" : "شما کار {todo} را در لیست {calendar} بازگشایی کردید", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} کار {todo} را از لیست {sourceCalendar} به لیست {targetCalendar} منتقل کرد", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "شما کار {todo} را از لیست {sourceCalendar} به لیست {targetCalendar} منتقل کردید", + "Calendar, contacts and tasks" : "تقویم، مخاطبین و وظایف", + "A <strong>calendar</strong> was modified" : "یک <strong>تقویم</strong> تغییر کرد", + "A calendar <strong>event</strong> was modified" : "یک <strong>رویداد</strong> تقویم تغییر کرد", + "A calendar <strong>to-do</strong> was modified" : "یک <strong>کار</strong> تقویم تغییر کرد", + "Contact birthdays" : "تولد مخاطبین", + "Death of %s" : "فوت %s", "Untitled calendar" : "تقویم بدون عنوان", - "Calendar:" : "Calendar:", + "Calendar:" : "تقویم:", "Date:" : "تاریخ:", "Where:" : "مکان:", "Description:" : "توضیحات:", - "_%n year_::_%n years_" : ["%n year","%n years"], - "_%n month_::_%n months_" : ["%n month","%n months"], - "_%n day_::_%n days_" : ["%n day","%n days"], - "_%n hour_::_%n hours_" : ["%n hour","%n hours"], - "_%n minute_::_%n minutes_" : ["%n minute","%n minutes"], - "%s (in %s)" : "%s (in %s)", - "%s (%s ago)" : "%s (%s ago)", - "Calendar: %s" : "Calendar: %s", - "Date: %s" : "Date: %s", - "Description: %s" : "Description: %s", - "Where: %s" : "Where: %s", + "_%n year_::_%n years_" : ["%n سال","%n سال"], + "_%n month_::_%n months_" : ["%n ماه","%n ماه"], + "_%n day_::_%n days_" : ["%n روز","%n روز"], + "_%n hour_::_%n hours_" : ["%n ساعت","%n ساعت"], + "_%n minute_::_%n minutes_" : ["%n دقیقه","%n دقیقه"], + "%s (in %s)" : "%s (در %s)", + "%s (%s ago)" : "%s (%s پیش)", + "Calendar: %s" : "تقویم: %s", + "Date: %s" : "تاریخ: %s", + "Description: %s" : "توضیحات: %s", + "Where: %s" : "مکان: %s", "%1$s via %2$s" : "%1$s از طریق %2$s", - "Cancelled: %1$s" : "Cancelled: %1$s", - "\"%1$s\" has been canceled" : "\"%1$s\" has been canceled", - "Re: %1$s" : "Re: %1$s", - "%1$s has accepted your invitation" : "%1$s has accepted your invitation", - "%1$s has tentatively accepted your invitation" : "%1$s has tentatively accepted your invitation", - "%1$s has declined your invitation" : "%1$s has declined your invitation", - "%1$s has responded to your invitation" : "%1$s has responded to your invitation", - "Invitation updated: %1$s" : "Invitation updated: %1$s", - "%1$s updated the event \"%2$s\"" : "%1$s updated the event \"%2$s\"", - "Invitation: %1$s" : "Invitation: %1$s", - "%1$s would like to invite you to \"%2$s\"" : "%1$s would like to invite you to \"%2$s\"", - "Organizer:" : "Organizer:", - "Attendees:" : "Attendees:", + "In the past on %1$s for the entire day" : "در گذشته در %1$s برای کل روز", + "_In a minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["در یک دقیقه در %1$s برای کل روز","در %n دقیقه در %1$s برای کل روز"], + "_In a hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["در یک ساعت در %1$s برای کل روز","در %n ساعت در %1$s برای کل روز"], + "_In a day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["در یک روز در %1$s برای کل روز","در %n روز در %1$s برای کل روز"], + "_In a week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["در یک هفته در %1$s برای کل روز","در %n هفته در %1$s برای کل روز"], + "_In a month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["در یک ماه در %1$s برای کل روز","در %n ماه در %1$s برای کل روز"], + "_In a year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["در یک سال در %1$s برای کل روز","در %n سال در %1$s برای کل روز"], + "In the past on %1$s between %2$s - %3$s" : "در گذشته در %1$s بین %2$s - %3$s", + "_In a minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["در یک دقیقه در %1$s بین %2$s - %3$s","در %n دقیقه در %1$s بین %2$s - %3$s"], + "_In a hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["در یک ساعت در %1$s بین %2$s - %3$s","در %n ساعت در %1$s بین %2$s - %3$s"], + "_In a day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["در یک روز در %1$s بین %2$s - %3$s","در %n روز در %1$s بین %2$s - %3$s"], + "_In a week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["در یک هفته در %1$s بین %2$s - %3$s","در %n هفته در %1$s بین %2$s - %3$s"], + "_In a month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["در یک ماه در %1$s بین %2$s - %3$s","در %n ماه در %1$s بین %2$s - %3$s"], + "_In a year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["در یک سال در %1$s بین %2$s - %3$s","در %n سال در %1$s بین %2$s - %3$s"], + "Could not generate when statement" : "امکان ایجاد عبارت زمان وجود ندارد", + "Every Day for the entire day" : "هر روز برای کل روز", + "Every Day for the entire day until %1$s" : "هر روز برای کل روز تا %1$s", + "Every Day between %1$s - %2$s" : "هر روز بین %1$s - %2$s", + "Every Day between %1$s - %2$s until %3$s" : "هر روز بین %1$s - %2$s تا %3$s", + "Every %1$d Days for the entire day" : "هر %1$d روز برای کل روز", + "Every %1$d Days for the entire day until %2$s" : "هر %1$d روز برای کل روز تا %2$s", + "Every %1$d Days between %2$s - %3$s" : "هر %1$d روز بین %2$s - %3$s", + "Every %1$d Days between %2$s - %3$s until %4$s" : "هر %1$d روز بین %2$s - %3$s تا %4$s", + "Could not generate event recurrence statement" : "امکان ایجاد عبارت تکرار رویداد وجود ندارد", + "Every Week on %1$s for the entire day" : "هر هفته در %1$s برای کل روز", + "Every Week on %1$s for the entire day until %2$s" : "هر هفته در %1$s برای کل روز تا %2$s", + "Every Week on %1$s between %2$s - %3$s" : "هر هفته در %1$s بین %2$s - %3$s", + "Every Week on %1$s between %2$s - %3$s until %4$s" : "هر هفته در %1$s بین %2$s - %3$s تا %4$s", + "Every %1$d Weeks on %2$s for the entire day" : "هر %1$d هفته در %2$s برای کل روز", + "Every %1$d Weeks on %2$s for the entire day until %3$s" : "هر %1$d هفته در %2$s برای کل روز تا %3$s", + "Every %1$d Weeks on %2$s between %3$s - %4$s" : "هر %1$d هفته در %2$s بین %3$s - %4$s", + "Every %1$d Weeks on %2$s between %3$s - %4$s until %5$s" : "هر %1$d هفته در %2$s بین %3$s - %4$s تا %5$s", + "Every Month on the %1$s for the entire day" : "هر ماه در %1$s برای کل روز", + "Every Month on the %1$s for the entire day until %2$s" : "هر ماه در %1$s برای کل روز تا %2$s", + "Every Month on the %1$s between %2$s - %3$s" : "هر ماه در %1$s بین %2$s - %3$s", + "Every Month on the %1$s between %2$s - %3$s until %4$s" : "هر ماه در %1$s بین %2$s - %3$s تا %4$s", + "Every %1$d Months on the %2$s for the entire day" : "هر %1$d ماه در %2$s برای کل روز", + "Every %1$d Months on the %2$s for the entire day until %3$s" : "هر %1$d ماه در %2$s برای کل روز تا %3$s", + "Every %1$d Months on the %2$s between %3$s - %4$s" : "هر %1$d ماه در %2$s بین %3$s - %4$s", + "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "هر %1$d ماه در %2$s بین %3$s - %4$s تا %5$s", + "Every Year in %1$s on the %2$s for the entire day" : "هر سال در %1$s در %2$s برای کل روز", + "Every Year in %1$s on the %2$s for the entire day until %3$s" : "هر سال در %1$s در %2$s برای کل روز تا %3$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s" : "هر سال در %1$s در %2$s بین %3$s - %4$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "هر سال در %1$s در %2$s بین %3$s - %4$s تا %5$s", + "Every %1$d Years in %2$s on the %3$s for the entire day" : "هر %1$d سال در %2$s در %3$s برای کل روز", + "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "هر %1$d سال در %2$s در %3$s برای کل روز تا %4$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "هر %1$d سال در %2$s در %3$s بین %4$s - %5$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "هر %1$d سال در %2$s در %3$s بین %4$s - %5$s تا %6$s", + "On specific dates for the entire day until %1$s" : "در تاریخهای مشخص برای کل روز تا %1$s", + "On specific dates between %1$s - %2$s until %3$s" : "در تاریخهای مشخص بین %1$s - %2$s تا %3$s", + "In the past on %1$s" : "در گذشته در %1$s", + "_In a minute on %1$s_::_In %n minutes on %1$s_" : ["در یک دقیقه در %1$s","در %n دقیقه در %1$s"], + "_In a hour on %1$s_::_In %n hours on %1$s_" : ["در یک ساعت در %1$s","در %n ساعت در %1$s"], + "_In a day on %1$s_::_In %n days on %1$s_" : ["در یک روز در %1$s","در %n روز در %1$s"], + "_In a week on %1$s_::_In %n weeks on %1$s_" : ["در یک هفته در %1$s","در %n هفته در %1$s"], + "_In a month on %1$s_::_In %n months on %1$s_" : ["در یک ماه در %1$s","در %n ماه در %1$s"], + "_In a year on %1$s_::_In %n years on %1$s_" : ["در یک سال در %1$s","در %n سال در %1$s"], + "In the past on %1$s then on %2$s" : "در گذشته در %1$s سپس در %2$s", + "_In a minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["در یک دقیقه در %1$s سپس در %2$s","در %n دقیقه در %1$s سپس در %2$s"], + "_In a hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["در یک ساعت در %1$s سپس در %2$s","در %n ساعت در %1$s سپس در %2$s"], + "_In a day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["در یک روز در %1$s سپس در %2$s","در %n روز در %1$s سپس در %2$s"], + "_In a week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["در یک هفته در %1$s سپس در %2$s","در %n هفته در %1$s سپس در %2$s"], + "_In a month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["در یک ماه در %1$s سپس در %2$s","در %n ماه در %1$s سپس در %2$s"], + "_In a year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["در یک سال در %1$s سپس در %2$s","در %n سال در %1$s سپس در %2$s"], + "In the past on %1$s then on %2$s and %3$s" : "در گذشته در %1$s سپس در %2$s و %3$s", + "_In a minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["در یک دقیقه در %1$s سپس در %2$s و %3$s","در %n دقیقه در %1$s سپس در %2$s و %3$s"], + "_In a hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["در یک ساعت در %1$s سپس در %2$s و %3$s","در %n ساعت در %1$s سپس در %2$s و %3$s"], + "_In a day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["در یک روز در %1$s سپس در %2$s و %3$s","در %n روز در %1$s سپس در %2$s و %3$s"], + "_In a week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["در یک هفته در %1$s سپس در %2$s و %3$s","در %n هفته در %1$s سپس در %2$s و %3$s"], + "_In a month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["در یک ماه در %1$s سپس در %2$s و %3$s","در %n ماه در %1$s سپس در %2$s و %3$s"], + "_In a year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["در یک سال در %1$s سپس در %2$s و %3$s","در %n سال در %1$s سپس در %2$s و %3$s"], + "Could not generate next recurrence statement" : "امکان ایجاد عبارت تکرار بعدی وجود ندارد", + "Cancelled: %1$s" : "لغو شد: %1$s", + "\"%1$s\" has been canceled" : "\"%1$s\" لغو شده است", + "Re: %1$s" : "پاسخ: %1$s", + "%1$s has accepted your invitation" : "%1$s دعوت شما را پذیرفته است", + "%1$s has tentatively accepted your invitation" : "%1$s دعوت شما را بهطور آزمایشی پذیرفته است", + "%1$s has declined your invitation" : "%1$s دعوت شما را رد کرده است", + "%1$s has responded to your invitation" : "%1$s به دعوت شما پاسخ داده است", + "Invitation updated: %1$s" : "دعوت بهروزرسانی شد: %1$s", + "%1$s updated the event \"%2$s\"" : "%1$s رویداد \"%2$s\" را بهروزرسانی کرد", + "Invitation: %1$s" : "دعوت: %1$s", + "%1$s would like to invite you to \"%2$s\"" : "%1$s مایل است شما را به \"%2$s\" دعوت کند", + "Organizer:" : "برگزارکننده:", + "Attendees:" : "شرکتکنندگان:", "Title:" : "عنوان:", + "When:" : "چه زمانی:", "Location:" : "مکان:", - "Link:" : "Link:", - "Accept" : "قبول", - "Decline" : "کاهش می یابد", - "More options …" : "More options …", - "More options at %s" : "More options at %s", + "Link:" : "پیوند:", + "Occurring:" : "در حال وقوع:", + "Accept" : "پذیرفتن", + "Decline" : "رد کردن", + "More options …" : "گزینههای بیشتر…", + "More options at %s" : "گزینههای بیشتر در %s", "Monday" : "دوشنبه", - "Tuesday" : "سه شنبه", + "Tuesday" : "سهشنبه", "Wednesday" : "چهارشنبه", "Thursday" : "پنجشنبه", "Friday" : "جمعه", @@ -103,101 +177,150 @@ "April" : "آوریل", "May" : "مه", "June" : "ژوئن", - "July" : "جولای", + "July" : "ژوئیه", "August" : "اوت", "September" : "سپتامبر", "October" : "اکتبر", "November" : "نوامبر", "December" : "دسامبر", - "First" : "First", - "Last" : "Last", + "First" : "اول", + "Second" : "دوم", + "Third" : "سوم", + "Fourth" : "چهارم", + "Fifth" : "پنجم", + "Last" : "آخر", + "Second Last" : "دومی از آخر", + "Third Last" : "سومی از آخر", + "Fourth Last" : "چهارمی از آخر", + "Fifth Last" : "پنجمی از آخر", "Contacts" : "مخاطبین", - "{actor} created address book {addressbook}" : "{actor} created address book {addressbook}", - "You created address book {addressbook}" : "دفترچه آدرس ساخته شد", - "{actor} deleted address book {addressbook}" : "{actor} deleted address book {addressbook}", - "You deleted address book {addressbook}" : "You deleted address book {addressbook}", - "{actor} updated address book {addressbook}" : "{actor} updated address book {addressbook}", - "You updated address book {addressbook}" : "You updated address book {addressbook}", - "{actor} shared address book {addressbook} with you" : "{actor} shared address book {addressbook} with you", - "You shared address book {addressbook} with {user}" : "You shared address book {addressbook} with {user}", - "{actor} shared address book {addressbook} with {user}" : "{actor} shared address book {addressbook} with {user}", - "{actor} unshared address book {addressbook} from you" : "{actor} unshared address book {addressbook} from you", - "You unshared address book {addressbook} from {user}" : "You unshared address book {addressbook} from {user}", - "{actor} unshared address book {addressbook} from {user}" : "{actor} unshared address book {addressbook} from {user}", - "{actor} unshared address book {addressbook} from themselves" : "{actor} unshared address book {addressbook} from themselves", - "You shared address book {addressbook} with group {group}" : "You shared address book {addressbook} with group {group}", - "{actor} shared address book {addressbook} with group {group}" : "{actor} shared address book {addressbook} with group {group}", - "You unshared address book {addressbook} from group {group}" : "You unshared address book {addressbook} from group {group}", - "{actor} unshared address book {addressbook} from group {group}" : "{actor} unshared address book {addressbook} from group {group}", - "{actor} created contact {card} in address book {addressbook}" : "{actor} created contact {card} in address book {addressbook}", - "You created contact {card} in address book {addressbook}" : "You created contact {card} in address book {addressbook}", - "{actor} deleted contact {card} from address book {addressbook}" : "{actor} deleted contact {card} from address book {addressbook}", - "You deleted contact {card} from address book {addressbook}" : "You deleted contact {card} from address book {addressbook}", - "{actor} updated contact {card} in address book {addressbook}" : "{actor} updated contact {card} in address book {addressbook}", - "You updated contact {card} in address book {addressbook}" : "You updated contact {card} in address book {addressbook}", - "A <strong>contact</strong> or <strong>address book</strong> was modified" : "یک مخاطب یا دفترچه آدرس تغییر کرد", + "{actor} created address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را ایجاد کرد", + "You created address book {addressbook}" : "شما دفترچه آدرس {addressbook} را ایجاد کردید", + "{actor} deleted address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را حذف کرد", + "You deleted address book {addressbook}" : "شما دفترچه آدرس {addressbook} را حذف کردید", + "{actor} updated address book {addressbook}" : "{actor} دفترچه آدرس {addressbook} را بهروزرسانی کرد", + "You updated address book {addressbook}" : "شما دفترچه آدرس {addressbook} را بهروزرسانی کردید", + "{actor} shared address book {addressbook} with you" : "{actor} دفترچه آدرس {addressbook} را با شما به اشتراک گذاشت", + "You shared address book {addressbook} with {user}" : "شما دفترچه آدرس {addressbook} را با {user} به اشتراک گذاشتید", + "{actor} shared address book {addressbook} with {user}" : "{actor} دفترچه آدرس {addressbook} را با {user} به اشتراک گذاشت", + "{actor} unshared address book {addressbook} from you" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از شما لغو کرد", + "You unshared address book {addressbook} from {user}" : "شما اشتراکگذاری دفترچه آدرس {addressbook} را از {user} لغو کردید", + "{actor} unshared address book {addressbook} from {user}" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از {user} لغو کرد", + "{actor} unshared address book {addressbook} from themselves" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از خود لغو کرد", + "You shared address book {addressbook} with group {group}" : "شما دفترچه آدرس {addressbook} را با گروه {group} به اشتراک گذاشتید", + "{actor} shared address book {addressbook} with group {group}" : "{actor} دفترچه آدرس {addressbook} را با گروه {group} به اشتراک گذاشت", + "You unshared address book {addressbook} from group {group}" : "شما اشتراکگذاری دفترچه آدرس {addressbook} را از گروه {group} لغو کردید", + "{actor} unshared address book {addressbook} from group {group}" : "{actor} اشتراکگذاری دفترچه آدرس {addressbook} را از گروه {group} لغو کرد", + "{actor} created contact {card} in address book {addressbook}" : "{actor} مخاطب {card} را در دفترچه آدرس {addressbook} ایجاد کرد", + "You created contact {card} in address book {addressbook}" : "شما مخاطب {card} را در دفترچه آدرس {addressbook} ایجاد کردید", + "{actor} deleted contact {card} from address book {addressbook}" : "{actor} مخاطب {card} را از دفترچه آدرس {addressbook} حذف کرد", + "You deleted contact {card} from address book {addressbook}" : "شما مخاطب {card} را از دفترچه آدرس {addressbook} حذف کردید", + "{actor} updated contact {card} in address book {addressbook}" : "{actor} مخاطب {card} را در دفترچه آدرس {addressbook} بهروزرسانی کرد", + "You updated contact {card} in address book {addressbook}" : "شما مخاطب {card} را در دفترچه آدرس {addressbook} بهروزرسانی کردید", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "یک <strong>مخاطب</strong> یا <strong>دفترچه آدرس</strong> تغییر کرد", "Accounts" : "حسابها", - "File is not updatable: %1$s" : "File is not updatable: %1$s", - "Could not write to final file, canceled by hook" : "Could not write to final file, canceled by hook", - "Could not write file contents" : "Could not write file contents", - "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], - "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)", - "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side.", - "Could not rename part file to final file, canceled by hook" : "Could not rename part file to final file, canceled by hook", - "Could not rename part file to final file" : "Could not rename part file to final file", - "Failed to check file size: %1$s" : "Failed to check file size: %1$s", - "Encryption not ready: %1$s" : "Encryption not ready: %1$s", - "Failed to open file: %1$s" : "Failed to open file: %1$s", - "Failed to unlink: %1$s" : "Failed to unlink: %1$s", - "Failed to write file contents: %1$s" : "Failed to write file contents: %1$s", - "File not found: %1$s" : "File not found: %1$s", - "System is in maintenance mode." : "System is in maintenance mode.", - "Upgrade needed" : "Upgrade needed", - "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS.", - "Configures a CalDAV account" : "Configures a CalDAV account", - "Configures a CardDAV account" : "Configures a CardDAV account", - "Events" : "Events", + "System address book which holds all accounts" : "دفترچه آدرس سیستمی که شامل تمام حسابها است", + "File is not updatable: %1$s" : "فایل قابل بهروزرسانی نیست: %1$s", + "Failed to get storage for file" : "دریافت فضای ذخیرهسازی برای فایل با شکست مواجه شد", + "Could not write to final file, canceled by hook" : "نوشتن در فایل نهایی امکانپذیر نبود، توسط هوک لغو شد", + "Could not write file contents" : "امکان نوشتن محتویات فایل وجود ندارد", + "_%n byte_::_%n bytes_" : ["%n بایت","%n بایت"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "خطا هنگام کپی فایل به مکان مقصد (کپی شده: %1$s، حجم فایل مورد انتظار: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "حجم فایل مورد انتظار %1$s بود اما %2$s خوانده (از کلاینت Nextcloud) و نوشته (در فضای ذخیرهسازی Nextcloud) شد. این میتواند ناشی از مشکل شبکه در سمت ارسال یا مشکل نوشتن در فضای ذخیرهسازی در سمت سرور باشد.", + "Could not rename part file to final file, canceled by hook" : "امکان تغییر نام فایل جزئی به فایل نهایی وجود نداشت، توسط هوک لغو شد", + "Could not rename part file to final file" : "امکان تغییر نام فایل جزئی به فایل نهایی وجود ندارد", + "Failed to check file size: %1$s" : "بررسی حجم فایل با شکست مواجه شد: %1$s", + "Could not open file: %1$s, file does seem to exist" : "امکان باز کردن فایل وجود ندارد: %1$s، به نظر میرسد فایل وجود دارد", + "Could not open file: %1$s, file doesn't seem to exist" : "امکان باز کردن فایل وجود ندارد: %1$s، به نظر میرسد فایل وجود ندارد", + "Encryption not ready: %1$s" : "رمزگذاری آماده نیست: %1$s", + "Failed to open file: %1$s" : "باز کردن فایل با شکست مواجه شد: %1$s", + "Failed to unlink: %1$s" : "حذف پیوند با شکست مواجه شد: %1$s", + "Failed to write file contents: %1$s" : "نوشتن محتویات فایل با شکست مواجه شد: %1$s", + "File not found: %1$s" : "فایل یافت نشد: %1$s", + "Invalid target path" : "مسیر مقصد نامعتبر است", + "System is in maintenance mode." : "سیستم در حالت نگهداری است.", + "Upgrade needed" : "نیاز به ارتقا", + "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "برای استفاده از CalDAV و CardDAV با iOS/macOS، %s شما باید برای استفاده از HTTPS پیکربندی شود.", + "Configures a CalDAV account" : "یک حساب CalDAV را پیکربندی میکند", + "Configures a CardDAV account" : "یک حساب CardDAV را پیکربندی میکند", + "Events" : "رویدادها", "Untitled task" : "کار بدون عنوان", - "Completed on %s" : "Completed on %s", - "Due on %s by %s" : "Due on %s by %s", - "Due on %s" : "Due on %s", - "WebDAV endpoint" : "WebDAV endpoint", - "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken.", - "Migrated calendar (%1$s)" : "Migrated calendar (%1$s)", - "Calendars including events, details and attendees" : "Calendars including events, details and attendees", - "Contacts and groups" : "Contacts and groups", - "WebDAV" : "WebDAV", - "First day" : "First day", + "Completed on %s" : "تکمیل شده در %s", + "Due on %s by %s" : "موعد در %s توسط %s", + "Due on %s" : "موعد در %s", + "System Address Book" : "دفترچه آدرس سیستم", + "The system address book contains contact information for all users in your instance." : "دفترچه آدرس سیستم شامل اطلاعات تماس برای همه کاربران در نمونه شما است.", + "Enable System Address Book" : "فعال کردن دفترچه آدرس سیستم", + "DAV system address book" : "دفترچه آدرس سیستم DAV", + "No outstanding DAV system address book sync." : "هیچ همگامسازی دفترچه آدرس سیستم DAV در انتظار نیست.", + "The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "همگامسازی دفترچه آدرس سیستم DAV هنوز اجرا نشده است زیرا نمونه شما بیش از ۱۰۰۰ کاربر دارد یا خطایی رخ داده است. لطفاً آن را بهصورت دستی با فراخوانی \"occ dav:sync-system-addressbook\" اجرا کنید.", + "WebDAV endpoint" : "نقطه پایانی WebDAV", + "Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "امکان بررسی اینکه سرور وب شما به درستی برای همگامسازی فایل از طریق WebDAV تنظیم شده است، وجود ندارد. لطفاً به صورت دستی بررسی کنید.", + "Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "سرور وب شما هنوز به درستی برای همگامسازی فایل تنظیم نشده است، زیرا به نظر میرسد رابط WebDAV خراب است.", + "Your web server is properly set up to allow file synchronization over WebDAV." : "سرور وب شما به درستی برای همگامسازی فایل از طریق WebDAV تنظیم شده است.", + "Migrated calendar (%1$s)" : "تقویم منتقل شده (%1$s)", + "Calendars including events, details and attendees" : "تقویمها شامل رویدادها، جزئیات و شرکتکنندگان", + "Contacts and groups" : "مخاطبین و گروهها", + "WebDAV" : "وبدَو", + "Absence saved" : "غیبت ذخیره شد", + "Failed to save your absence settings" : "ذخیره تنظیمات غیبت شما با شکست مواجه شد", + "Absence cleared" : "غیبت پاک شد", + "Failed to clear your absence settings" : "پاک کردن تنظیمات غیبت شما با شکست مواجه شد", + "First day" : "روز اول", + "Last day (inclusive)" : "روز آخر (شامل)", + "Out of office replacement (optional)" : "جایگزین خارج از دفتر (اختیاری)", + "Name of the replacement" : "نام جایگزین", + "No results." : "نتیجهای یافت نشد.", + "Start typing." : "شروع به تایپ کنید.", + "Short absence status" : "وضعیت کوتاه غیبت", + "Long absence Message" : "پیام طولانی غیبت", "Save" : "ذخیره", - "Failed to load availability" : "Failed to load availability", - "Saved availability" : "Saved availability", - "Failed to save availability" : "Failed to save availability", + "Disable absence" : "غیرفعال کردن غیبت", + "Failed to load availability" : "بارگذاری در دسترس بودن با شکست مواجه شد", + "Saved availability" : "در دسترس بودن ذخیره شد", + "Failed to save availability" : "ذخیره در دسترس بودن با شکست مواجه شد", "Time zone:" : "منطقه زمانی:", - "to" : "به", - "Delete slot" : "Delete slot", + "to" : "تا", + "Delete slot" : "حذف بازه زمانی", "No working hours set" : "ساعات کاری تعیین نشده است", - "Add slot" : "Add slot", - "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "وضعیت کاربر بصورت خودکار به \"مزاحم نشوید\" تغییر داده شود تا همه ی اعلان ها خاموش شوند", - "Availability" : "موجود بودن", - "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}.", - "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Please make sure to properly set up {emailopen}the email server{linkclose}.", - "Calendar server" : "Calendar server", - "Send invitations to attendees" : "Send invitations to attendees", - "Automatically generate a birthday calendar" : "Automatically generate a birthday calendar", - "Birthday calendars will be generated by a background job." : "Birthday calendars will be generated by a background job.", - "Hence they will not be available immediately after enabling but will show up after some time." : "Hence they will not be available immediately after enabling but will show up after some time.", - "Send notifications for events" : "Send notifications for events", - "Notifications are sent via background jobs, so these must occur often enough." : "Notifications are sent via background jobs, so these must occur often enough.", - "Send reminder notifications to calendar sharees as well" : "Send reminder notifications to calendar sharees as well", - "Reminders are always sent to organizers and attendees." : "Reminders are always sent to organizers and attendees.", - "Enable notifications for events via push" : "Enable notifications for events via push", - "Cancel" : "ردکردن", + "Add slot" : "افزودن بازه زمانی", + "Weekdays" : "روزهای هفته", + "Pick a start time for {dayName}" : "زمان شروع برای {dayName} را انتخاب کنید", + "Pick a end time for {dayName}" : "زمان پایان برای {dayName} را انتخاب کنید", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "وضعیت کاربر بصورت خودکار به \"مزاحم نشوید\" تغییر داده شود تا همه ی اعلان ها خاموش شوند.", + "Availability" : "در دسترس بودن", + "If you configure your working hours, other people will see when you are out of office when they book a meeting." : "اگر ساعات کاری خود را پیکربندی کنید، دیگران هنگام رزرو جلسه متوجه خواهند شد که شما در دفتر نیستید.", + "Absence" : "غیبت", + "Configure your next absence period." : "دوره غیبت بعدی خود را پیکربندی کنید.", + "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "همچنین {calendarappstoreopen}برنامه تقویم{linkclose} را نصب کنید، یا {calendardocopen}دسکتاپ و موبایل خود را برای همگامسازی متصل کنید ↗{linkclose}.", + "Please make sure to properly set up {emailopen}the email server{linkclose}." : "لطفاً مطمئن شوید که {emailopen}سرور ایمیل{linkclose} را به درستی تنظیم کردهاید.", + "Calendar server" : "سرور تقویم", + "Send invitations to attendees" : "ارسال دعوتنامهها به شرکتکنندگان", + "Automatically generate a birthday calendar" : "بهطور خودکار یک تقویم تولد ایجاد کنید", + "Birthday calendars will be generated by a background job." : "تقویمهای تولد توسط یک کار پسزمینه ایجاد خواهند شد.", + "Hence they will not be available immediately after enabling but will show up after some time." : "بنابراین بلافاصله پس از فعالسازی در دسترس نخواهند بود، اما پس از مدتی نمایان میشوند.", + "Send notifications for events" : "ارسال اعلانها برای رویدادها", + "Notifications are sent via background jobs, so these must occur often enough." : "اعلانها از طریق کارهای پسزمینه ارسال میشوند، بنابراین این کارها باید به اندازه کافی مکرر انجام شوند.", + "Send reminder notifications to calendar sharees as well" : "ارسال اعلانهای یادآوری به اشتراکگذاران تقویم نیز", + "Reminders are always sent to organizers and attendees." : "یادآوریها همیشه برای برگزارکنندگان و شرکتکنندگان ارسال میشوند.", + "Enable notifications for events via push" : "فعال کردن اعلانها برای رویدادها از طریق پوش", + "Cancel" : "لغو", "Import" : "وارد کردن", - "Error while saving settings" : "Error while saving settings", - "There was an error updating your attendance status." : "There was an error updating your attendance status.", - "Please contact the organizer directly." : "Please contact the organizer directly.", - "Are you accepting the invitation?" : "Are you accepting the invitation?", + "Error while saving settings" : "خطا هنگام ذخیره تنظیمات", + "Contact reset successfully" : "مخاطب با موفقیت بازنشانی شد", + "Error while resetting contact" : "خطا هنگام بازنشانی مخاطب", + "Contact imported successfully" : "مخاطب با موفقیت وارد شد", + "Error while importing contact" : "خطا هنگام وارد کردن مخاطب", + "Example Content" : "محتوای نمونه", + "Set example content to be created on new user first login." : "محتوای نمونه را برای ایجاد در اولین ورود کاربر جدید تنظیم کنید.", + "Import contact" : "وارد کردن مخاطب", + "Reset to default contact" : "بازنشانی به مخاطب پیشفرض", + "Import contacts" : "وارد کردن مخاطبین", + "Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?" : "وارد کردن یک فایل .vcf جدید، مخاطب پیشفرض موجود را حذف کرده و آن را با مخاطب جدید جایگزین میکند. آیا میخواهید ادامه دهید؟", + "There was an error updating your attendance status." : "خطایی در بهروزرسانی وضعیت حضور شما رخ داد.", + "Please contact the organizer directly." : "لطفاً مستقیماً با برگزارکننده تماس بگیرید.", + "Are you accepting the invitation?" : "آیا دعوت را میپذیرید؟", "Tentative" : "آزمایشی", - "Your attendance was updated successfully." : "Your attendance was updated successfully." + "Your attendance was updated successfully." : "وضعیت حضور شما با موفقیت بهروزرسانی شد." },"pluralForm" :"nplurals=2; plural=(n > 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/pt_BR.js b/apps/dav/l10n/pt_BR.js index c578d4f4c9d..7d9cc7d4524 100644 --- a/apps/dav/l10n/pt_BR.js +++ b/apps/dav/l10n/pt_BR.js @@ -104,22 +104,22 @@ OC.L10N.register( "Every %1$d Weeks on %2$s for the entire day until %3$s" : "A Cada %1$d Semanas, %2$s para o dia inteiro até %3$s", "Every %1$d Weeks on %2$s between %3$s - %4$s" : "A Cada %1$d Semanas, %2$s entre %3$s - %4$s", "Every %1$d Weeks on %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Semanas, %2$s entre %3$s - %4$s até %5$s", - "Every Month on the %1$s for the entire day" : "Todo Mês no dia %1$s para o dia inteiro", - "Every Month on the %1$s for the entire day until %2$s" : "Todo Mês no dia %1$s para o dia inteiro até %2$s", - "Every Month on the %1$s between %2$s - %3$s" : "Todo Mês no dia %1$s entre %2$s - %3$s", - "Every Month on the %1$s between %2$s - %3$s until %4$s" : "Todo Mês no dia %1$s entre %2$s - %3$s até %4$s", - "Every %1$d Months on the %2$s for the entire day" : "A Cada %1$d Meses no dia %2$s para o dia inteiro", - "Every %1$d Months on the %2$s for the entire day until %3$s" : "A Cada %1$d Meses no dia %2$s para o dia inteiro até %3$s", - "Every %1$d Months on the %2$s between %3$s - %4$s" : "A Cada %1$d Meses no dia %2$s entre %3$s - %4$s", - "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Meses no dia %2$s entre %3$s - %4$s até %5$s", - "Every Year in %1$s on the %2$s for the entire day" : "Todo Ano em %1$s no dia %2$s para o dia inteiro", - "Every Year in %1$s on the %2$s for the entire day until %3$s" : "Todo Ano em %1$s no dia %2$s para o dia inteiro até %3$s", - "Every Year in %1$s on the %2$s between %3$s - %4$s" : "Todo Ano em %1$s no dia %2$s entre %3$s - %4$s", - "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "Todo Ano em %1$s no dia %2$s entre %3$s - %4$s até %5$s", - "Every %1$d Years in %2$s on the %3$s for the entire day" : "A Cada %1$d Anos em %2$s no dia %3$s para o dia inteiro", - "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "A Cada %1$d Anos em %2$s no dia %3$s para o dia inteiro até %4$s", - "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "A Cada %1$d Anos em %2$s no dia %3$s entre %4$s - %5$s ", - "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "A Cada %1$d Anos em %2$s no dia %3$s entre %4$s - %5$s até %6$s", + "Every Month on the %1$s for the entire day" : "Todo Mês, dia: %1$s, para o dia inteiro", + "Every Month on the %1$s for the entire day until %2$s" : "Todo Mês, dia: %1$s, para o dia inteiro até %2$s", + "Every Month on the %1$s between %2$s - %3$s" : "Todo Mês, dia: %1$s, entre %2$s - %3$s", + "Every Month on the %1$s between %2$s - %3$s until %4$s" : "Todo Mês, dia: %1$s, entre %2$s - %3$s até %4$s", + "Every %1$d Months on the %2$s for the entire day" : "A Cada %1$d Meses, dia: %2$s, para o dia inteiro", + "Every %1$d Months on the %2$s for the entire day until %3$s" : "A Cada %1$d Meses, dia: %2$s, para o dia inteiro até %3$s", + "Every %1$d Months on the %2$s between %3$s - %4$s" : "A Cada %1$d Meses, dia: %2$s, entre %3$s - %4$s", + "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Meses, dia: %2$s, entre %3$s - %4$s até %5$s", + "Every Year in %1$s on the %2$s for the entire day" : "Todo Ano em %1$s, dia: %2$s, para o dia inteiro", + "Every Year in %1$s on the %2$s for the entire day until %3$s" : "Todo Ano em %1$s, dia: %2$s, para o dia inteiro até %3$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s" : "Todo Ano em %1$s, dia: %2$s, entre %3$s - %4$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "Todo Ano em %1$s, dia: %2$s, entre %3$s - %4$s até %5$s", + "Every %1$d Years in %2$s on the %3$s for the entire day" : "A Cada %1$d Anos em %2$s, dia: %3$s, para o dia inteiro", + "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, para o dia inteiro até %4$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, entre %4$s - %5$s ", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, entre %4$s - %5$s até %6$s", "On specific dates for the entire day until %1$s" : "Em datas específicas para o dia inteiro até %1$s", "On specific dates between %1$s - %2$s until %3$s" : "Em datas específicas entre %1$s - %2$s até %3$s", "In the past on %1$s" : "No passado em %1$s", @@ -185,16 +185,16 @@ OC.L10N.register( "October" : "Outubro", "November" : "Novembro", "December" : "Dezembro", - "First" : "Primeiro/a", - "Second" : "Segundo/a", - "Third" : "Terço/a", - "Fourth" : "Quarto/a", - "Fifth" : "Quinto/a", + "First" : "1.º/ª", + "Second" : "2.º/ª", + "Third" : "3.º/ª", + "Fourth" : "4.º/ª", + "Fifth" : "5.º/ª", "Last" : "Último/a", "Second Last" : "Penúltimo/a", - "Third Last" : "Terceiro/a Último/a", - "Fourth Last" : "Quarto/a Último/a", - "Fifth Last" : "Quinto/a Último/a", + "Third Last" : "3.º/ª Último/a", + "Fourth Last" : "4.º/ª Último/a", + "Fifth Last" : "5.º/ª Último/a", "Contacts" : "Contatos", "{actor} created address book {addressbook}" : "{actor} criou o catálogo de endereços {addressbook}", "You created address book {addressbook}" : "Você criou o catálogo de endereços {addressbook}", diff --git a/apps/dav/l10n/pt_BR.json b/apps/dav/l10n/pt_BR.json index d2f229a8046..c57088cb0ed 100644 --- a/apps/dav/l10n/pt_BR.json +++ b/apps/dav/l10n/pt_BR.json @@ -102,22 +102,22 @@ "Every %1$d Weeks on %2$s for the entire day until %3$s" : "A Cada %1$d Semanas, %2$s para o dia inteiro até %3$s", "Every %1$d Weeks on %2$s between %3$s - %4$s" : "A Cada %1$d Semanas, %2$s entre %3$s - %4$s", "Every %1$d Weeks on %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Semanas, %2$s entre %3$s - %4$s até %5$s", - "Every Month on the %1$s for the entire day" : "Todo Mês no dia %1$s para o dia inteiro", - "Every Month on the %1$s for the entire day until %2$s" : "Todo Mês no dia %1$s para o dia inteiro até %2$s", - "Every Month on the %1$s between %2$s - %3$s" : "Todo Mês no dia %1$s entre %2$s - %3$s", - "Every Month on the %1$s between %2$s - %3$s until %4$s" : "Todo Mês no dia %1$s entre %2$s - %3$s até %4$s", - "Every %1$d Months on the %2$s for the entire day" : "A Cada %1$d Meses no dia %2$s para o dia inteiro", - "Every %1$d Months on the %2$s for the entire day until %3$s" : "A Cada %1$d Meses no dia %2$s para o dia inteiro até %3$s", - "Every %1$d Months on the %2$s between %3$s - %4$s" : "A Cada %1$d Meses no dia %2$s entre %3$s - %4$s", - "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Meses no dia %2$s entre %3$s - %4$s até %5$s", - "Every Year in %1$s on the %2$s for the entire day" : "Todo Ano em %1$s no dia %2$s para o dia inteiro", - "Every Year in %1$s on the %2$s for the entire day until %3$s" : "Todo Ano em %1$s no dia %2$s para o dia inteiro até %3$s", - "Every Year in %1$s on the %2$s between %3$s - %4$s" : "Todo Ano em %1$s no dia %2$s entre %3$s - %4$s", - "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "Todo Ano em %1$s no dia %2$s entre %3$s - %4$s até %5$s", - "Every %1$d Years in %2$s on the %3$s for the entire day" : "A Cada %1$d Anos em %2$s no dia %3$s para o dia inteiro", - "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "A Cada %1$d Anos em %2$s no dia %3$s para o dia inteiro até %4$s", - "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "A Cada %1$d Anos em %2$s no dia %3$s entre %4$s - %5$s ", - "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "A Cada %1$d Anos em %2$s no dia %3$s entre %4$s - %5$s até %6$s", + "Every Month on the %1$s for the entire day" : "Todo Mês, dia: %1$s, para o dia inteiro", + "Every Month on the %1$s for the entire day until %2$s" : "Todo Mês, dia: %1$s, para o dia inteiro até %2$s", + "Every Month on the %1$s between %2$s - %3$s" : "Todo Mês, dia: %1$s, entre %2$s - %3$s", + "Every Month on the %1$s between %2$s - %3$s until %4$s" : "Todo Mês, dia: %1$s, entre %2$s - %3$s até %4$s", + "Every %1$d Months on the %2$s for the entire day" : "A Cada %1$d Meses, dia: %2$s, para o dia inteiro", + "Every %1$d Months on the %2$s for the entire day until %3$s" : "A Cada %1$d Meses, dia: %2$s, para o dia inteiro até %3$s", + "Every %1$d Months on the %2$s between %3$s - %4$s" : "A Cada %1$d Meses, dia: %2$s, entre %3$s - %4$s", + "Every %1$d Months on the %2$s between %3$s - %4$s until %5$s" : "A Cada %1$d Meses, dia: %2$s, entre %3$s - %4$s até %5$s", + "Every Year in %1$s on the %2$s for the entire day" : "Todo Ano em %1$s, dia: %2$s, para o dia inteiro", + "Every Year in %1$s on the %2$s for the entire day until %3$s" : "Todo Ano em %1$s, dia: %2$s, para o dia inteiro até %3$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s" : "Todo Ano em %1$s, dia: %2$s, entre %3$s - %4$s", + "Every Year in %1$s on the %2$s between %3$s - %4$s until %5$s" : "Todo Ano em %1$s, dia: %2$s, entre %3$s - %4$s até %5$s", + "Every %1$d Years in %2$s on the %3$s for the entire day" : "A Cada %1$d Anos em %2$s, dia: %3$s, para o dia inteiro", + "Every %1$d Years in %2$s on the %3$s for the entire day until %4$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, para o dia inteiro até %4$s", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, entre %4$s - %5$s ", + "Every %1$d Years in %2$s on the %3$s between %4$s - %5$s until %6$s" : "A Cada %1$d Anos em %2$s, dia: %3$s, entre %4$s - %5$s até %6$s", "On specific dates for the entire day until %1$s" : "Em datas específicas para o dia inteiro até %1$s", "On specific dates between %1$s - %2$s until %3$s" : "Em datas específicas entre %1$s - %2$s até %3$s", "In the past on %1$s" : "No passado em %1$s", @@ -183,16 +183,16 @@ "October" : "Outubro", "November" : "Novembro", "December" : "Dezembro", - "First" : "Primeiro/a", - "Second" : "Segundo/a", - "Third" : "Terço/a", - "Fourth" : "Quarto/a", - "Fifth" : "Quinto/a", + "First" : "1.º/ª", + "Second" : "2.º/ª", + "Third" : "3.º/ª", + "Fourth" : "4.º/ª", + "Fifth" : "5.º/ª", "Last" : "Último/a", "Second Last" : "Penúltimo/a", - "Third Last" : "Terceiro/a Último/a", - "Fourth Last" : "Quarto/a Último/a", - "Fifth Last" : "Quinto/a Último/a", + "Third Last" : "3.º/ª Último/a", + "Fourth Last" : "4.º/ª Último/a", + "Fifth Last" : "5.º/ª Último/a", "Contacts" : "Contatos", "{actor} created address book {addressbook}" : "{actor} criou o catálogo de endereços {addressbook}", "You created address book {addressbook}" : "Você criou o catálogo de endereços {addressbook}", diff --git a/apps/dav/lib/BulkUpload/MultipartRequestParser.php b/apps/dav/lib/BulkUpload/MultipartRequestParser.php index 96a90f82cde..f23aca580cc 100644 --- a/apps/dav/lib/BulkUpload/MultipartRequestParser.php +++ b/apps/dav/lib/BulkUpload/MultipartRequestParser.php @@ -57,7 +57,13 @@ class MultipartRequestParser { */ private function parseBoundaryFromHeaders(string $contentType): string { try { + if (!str_contains($contentType, ';')) { + throw new \InvalidArgumentException('No semicolon in header'); + } [$mimeType, $boundary] = explode(';', $contentType); + if (!str_contains($boundary, '=')) { + throw new \InvalidArgumentException('No equal in boundary header'); + } [$boundaryKey, $boundaryValue] = explode('=', $boundary); } catch (\Exception $e) { throw new BadRequest('Error while parsing boundary in Content-Type header.', Http::STATUS_BAD_REQUEST, $e); diff --git a/apps/dav/lib/CalDAV/CachedSubscriptionImpl.php b/apps/dav/lib/CalDAV/CachedSubscriptionImpl.php index 74efebb6e2a..cc1bab6d4fc 100644 --- a/apps/dav/lib/CalDAV/CachedSubscriptionImpl.php +++ b/apps/dav/lib/CalDAV/CachedSubscriptionImpl.php @@ -55,16 +55,6 @@ class CachedSubscriptionImpl implements ICalendar, ICalendarIsEnabled, ICalendar return $this->calendarInfo['{http://apple.com/ns/ical/}calendar-color']; } - /** - * @param string $pattern which should match within the $searchProperties - * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - optional parameters: - * ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]] - * @param int|null $limit - limit number of search results - * @param int|null $offset - offset for paging of search results - * @return array an array of events/journals/todos which are arrays of key-value-pairs - * @since 13.0.0 - */ public function search(string $pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null): array { return $this->backend->search($this->calendarInfo, $pattern, $searchProperties, $options, $limit, $offset); } diff --git a/apps/dav/lib/CalDAV/CalendarImpl.php b/apps/dav/lib/CalDAV/CalendarImpl.php index d36f46df901..b79bf7ea2d0 100644 --- a/apps/dav/lib/CalDAV/CalendarImpl.php +++ b/apps/dav/lib/CalDAV/CalendarImpl.php @@ -93,16 +93,6 @@ class CalendarImpl implements ICreateFromString, IHandleImipMessage, ICalendarIs return $vtimezone; } - /** - * @param string $pattern which should match within the $searchProperties - * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - optional parameters: - * ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]] - * @param int|null $limit - limit number of search results - * @param int|null $offset - offset for paging of search results - * @return array an array of events/journals/todos which are arrays of key-value-pairs - * @since 13.0.0 - */ public function search(string $pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null): array { return $this->backend->search($this->calendarInfo, $pattern, $searchProperties, $options, $limit, $offset); diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index 98e0f2e9e4b..218d38e1c4b 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -216,7 +216,9 @@ class File extends Node implements IFile { try { /** @var IWriteStreamStorage $partStorage */ $count = $partStorage->writeStream($internalPartPath, $wrappedData); - } catch (GenericFileException) { + } catch (GenericFileException $e) { + $logger = Server::get(LoggerInterface::class); + $logger->error('Error while writing stream to storage: ' . $e->getMessage(), ['exception' => $e, 'app' => 'webdav']); $result = $isEOF; if (is_resource($wrappedData)) { $result = feof($wrappedData); diff --git a/apps/dav/tests/unit/Avatars/AvatarHomeTest.php b/apps/dav/tests/unit/Avatars/AvatarHomeTest.php index c0c19192ba9..aaa930b6c19 100644 --- a/apps/dav/tests/unit/Avatars/AvatarHomeTest.php +++ b/apps/dav/tests/unit/Avatars/AvatarHomeTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2017 ownCloud GmbH * SPDX-License-Identifier: AGPL-3.0-only */ -namespace OCA\DAV\Tests\Unit\Avatars; +namespace OCA\DAV\Tests\unit\Avatars; use OCA\DAV\Avatars\AvatarHome; use OCA\DAV\Avatars\AvatarNode; diff --git a/apps/dav/tests/unit/Avatars/AvatarNodeTest.php b/apps/dav/tests/unit/Avatars/AvatarNodeTest.php index 01634e77ed6..0ca147a1f3b 100644 --- a/apps/dav/tests/unit/Avatars/AvatarNodeTest.php +++ b/apps/dav/tests/unit/Avatars/AvatarNodeTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2017 ownCloud GmbH * SPDX-License-Identifier: AGPL-3.0-only */ -namespace OCA\DAV\Tests\Unit\Avatars; +namespace OCA\DAV\Tests\unit\Avatars; use OCA\DAV\Avatars\AvatarNode; use OCP\IAvatar; diff --git a/apps/dav/tests/unit/CapabilitiesTest.php b/apps/dav/tests/unit/CapabilitiesTest.php index 21d00ef183f..ad70d576d48 100644 --- a/apps/dav/tests/unit/CapabilitiesTest.php +++ b/apps/dav/tests/unit/CapabilitiesTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/apps/dav/tests/unit/Command/DeleteCalendarTest.php b/apps/dav/tests/unit/Command/DeleteCalendarTest.php index 5cdb86d123d..2bd269de6dc 100644 --- a/apps/dav/tests/unit/Command/DeleteCalendarTest.php +++ b/apps/dav/tests/unit/Command/DeleteCalendarTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; diff --git a/apps/dav/tests/unit/Command/ListAddressbooksTest.php b/apps/dav/tests/unit/Command/ListAddressbooksTest.php index ab4ce49b840..624b0050bc5 100644 --- a/apps/dav/tests/unit/Command/ListAddressbooksTest.php +++ b/apps/dav/tests/unit/Command/ListAddressbooksTest.php @@ -5,7 +5,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Command\ListAddressbooks; diff --git a/apps/dav/tests/unit/Command/ListCalendarSharesTest.php b/apps/dav/tests/unit/Command/ListCalendarSharesTest.php index 3b3f3a1519e..e5d4251cbf9 100644 --- a/apps/dav/tests/unit/Command/ListCalendarSharesTest.php +++ b/apps/dav/tests/unit/Command/ListCalendarSharesTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Command\ListCalendarShares; diff --git a/apps/dav/tests/unit/Command/ListCalendarsTest.php b/apps/dav/tests/unit/Command/ListCalendarsTest.php index 961d2ce0850..247487433eb 100644 --- a/apps/dav/tests/unit/Command/ListCalendarsTest.php +++ b/apps/dav/tests/unit/Command/ListCalendarsTest.php @@ -5,7 +5,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; diff --git a/apps/dav/tests/unit/Command/MoveCalendarTest.php b/apps/dav/tests/unit/Command/MoveCalendarTest.php index 0c38541c185..c481f5cf15b 100644 --- a/apps/dav/tests/unit/Command/MoveCalendarTest.php +++ b/apps/dav/tests/unit/Command/MoveCalendarTest.php @@ -5,7 +5,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Command; +namespace OCA\DAV\Tests\unit\Command; use InvalidArgumentException; use OCA\DAV\CalDAV\CalDavBackend; diff --git a/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php b/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php index b7860a12452..ec56aa64eb2 100644 --- a/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php +++ b/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2018 ownCloud GmbH * SPDX-License-Identifier: AGPL-3.0-only */ -namespace OCA\DAV\Tests\Unit\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\Command\RemoveInvalidShares; use OCA\DAV\Connector\Sabre\Principal; diff --git a/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php b/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php index 2bb68374162..8b8c775c8ec 100644 --- a/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php +++ b/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -14,6 +15,7 @@ use OCP\Security\Bruteforce\IThrottler; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; /** * Class LegacyPublicAuthTest @@ -23,36 +25,20 @@ use OCP\Share\IShare; * @package OCA\DAV\Tests\unit\Connector */ class LegacyPublicAuthTest extends \Test\TestCase { - - /** @var ISession|\PHPUnit\Framework\MockObject\MockObject */ - private $session; - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - /** @var LegacyPublicAuth */ - private $auth; - /** @var IThrottler|\PHPUnit\Framework\MockObject\MockObject */ - private $throttler; - - /** @var string */ - private $oldUser; + private ISession&MockObject $session; + private IRequest&MockObject $request; + private IManager&MockObject $shareManager; + private IThrottler&MockObject $throttler; + private LegacyPublicAuth $auth; + private string|false $oldUser; protected function setUp(): void { parent::setUp(); - $this->session = $this->getMockBuilder(ISession::class) - ->disableOriginalConstructor() - ->getMock(); - $this->request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor() - ->getMock(); - $this->shareManager = $this->getMockBuilder(IManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->throttler = $this->getMockBuilder(IThrottler::class) - ->disableOriginalConstructor() - ->getMock(); + $this->session = $this->createMock(ISession::class); + $this->request = $this->createMock(IRequest::class); + $this->shareManager = $this->createMock(IManager::class); + $this->throttler = $this->createMock(IThrottler::class); $this->auth = new LegacyPublicAuth( $this->request, @@ -70,7 +56,9 @@ class LegacyPublicAuthTest extends \Test\TestCase { // Set old user \OC_User::setUserId($this->oldUser); - \OC_Util::setupFS($this->oldUser); + if ($this->oldUser !== false) { + \OC_Util::setupFS($this->oldUser); + } parent::tearDown(); } @@ -86,9 +74,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testShareNoPassword(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn(null); $this->shareManager->expects($this->once()) @@ -101,9 +87,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testSharePasswordFancyShareType(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(42); @@ -118,9 +102,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { public function testSharePasswordRemote(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_REMOTE); @@ -134,9 +116,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testSharePasswordLinkValidPassword(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); @@ -156,9 +136,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testSharePasswordMailValidPassword(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL); @@ -178,9 +156,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testInvalidSharePasswordLinkValidSession(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); $share->method('getId')->willReturn('42'); @@ -204,9 +180,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { } public function testSharePasswordLinkInvalidSession(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); $share->method('getId')->willReturn('42'); @@ -231,9 +205,7 @@ class LegacyPublicAuthTest extends \Test\TestCase { public function testSharePasswordMailInvalidSession(): void { - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL); $share->method('getId')->willReturn('42'); diff --git a/apps/dav/tests/unit/Connector/Sabre/AuthTest.php b/apps/dav/tests/unit/Connector/Sabre/AuthTest.php index c6d247b3951..501ef3ef1d1 100644 --- a/apps/dav/tests/unit/Connector/Sabre/AuthTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/AuthTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -29,33 +30,20 @@ use Test\TestCase; * @group DB */ class AuthTest extends TestCase { - /** @var ISession&MockObject */ - private $session; - /** @var Auth */ - private $auth; - /** @var Session&MockObject */ - private $userSession; - /** @var IRequest&MockObject */ - private $request; - /** @var Manager&MockObject */ - private $twoFactorManager; - /** @var IThrottler&MockObject */ - private $throttler; + private ISession&MockObject $session; + private Session&MockObject $userSession; + private IRequest&MockObject $request; + private Manager&MockObject $twoFactorManager; + private IThrottler&MockObject $throttler; + private Auth $auth; protected function setUp(): void { parent::setUp(); - $this->session = $this->getMockBuilder(ISession::class) - ->disableOriginalConstructor()->getMock(); - $this->userSession = $this->getMockBuilder(Session::class) - ->disableOriginalConstructor()->getMock(); - $this->request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor()->getMock(); - $this->twoFactorManager = $this->getMockBuilder(Manager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->throttler = $this->getMockBuilder(IThrottler::class) - ->disableOriginalConstructor() - ->getMock(); + $this->session = $this->createMock(ISession::class); + $this->userSession = $this->createMock(Session::class); + $this->request = $this->createMock(IRequest::class); + $this->twoFactorManager = $this->createMock(Manager::class); + $this->throttler = $this->createMock(IThrottler::class); $this->auth = new Auth( $this->session, $this->userSession, @@ -72,7 +60,7 @@ class AuthTest extends TestCase { ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn(null); - $this->assertFalse($this->invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); + $this->assertFalse(self::invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); } public function testIsDavAuthenticatedWithWrongDavSession(): void { @@ -82,7 +70,7 @@ class AuthTest extends TestCase { ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn('AnotherUser'); - $this->assertFalse($this->invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); + $this->assertFalse(self::invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); } public function testIsDavAuthenticatedWithCorrectDavSession(): void { @@ -92,13 +80,11 @@ class AuthTest extends TestCase { ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn('MyTestUser'); - $this->assertTrue($this->invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); + $this->assertTrue(self::invokePrivate($this->auth, 'isDavAuthenticated', ['MyTestUser'])); } public function testValidateUserPassOfAlreadyDAVAuthenticatedUser(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->exactly(1)) ->method('getUID') ->willReturn('MyTestUser'); @@ -119,13 +105,11 @@ class AuthTest extends TestCase { ->expects($this->once()) ->method('close'); - $this->assertTrue($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); + $this->assertTrue(self::invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); } public function testValidateUserPassOfInvalidDAVAuthenticatedUser(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('MyTestUser'); @@ -146,13 +130,11 @@ class AuthTest extends TestCase { ->expects($this->once()) ->method('close'); - $this->assertFalse($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); + $this->assertFalse(self::invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); } public function testValidateUserPassOfInvalidDAVAuthenticatedUserWithValidPassword(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->exactly(2)) ->method('getUID') ->willReturn('MyTestUser'); @@ -182,7 +164,7 @@ class AuthTest extends TestCase { ->expects($this->once()) ->method('close'); - $this->assertTrue($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); + $this->assertTrue(self::invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); } public function testValidateUserPassWithInvalidPassword(): void { @@ -199,7 +181,7 @@ class AuthTest extends TestCase { ->expects($this->once()) ->method('close'); - $this->assertFalse($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); + $this->assertFalse(self::invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword'])); } @@ -219,16 +201,12 @@ class AuthTest extends TestCase { ->expects($this->once()) ->method('close'); - $this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword']); + self::invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword']); } public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGet(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -242,9 +220,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn(null); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('MyWrongDavUser'); @@ -266,12 +242,8 @@ class AuthTest extends TestCase { } public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenAndCorrectlyDavAuthenticated(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -289,9 +261,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn('LoggedInUser'); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('LoggedInUser'); @@ -311,12 +281,8 @@ class AuthTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class); $this->expectExceptionMessage('2FA challenge not passed.'); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -334,9 +300,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn('LoggedInUser'); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('LoggedInUser'); @@ -360,12 +324,8 @@ class AuthTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class); $this->expectExceptionMessage('CSRF check not passed.'); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -383,9 +343,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn('AnotherUser'); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('LoggedInUser'); @@ -401,12 +359,8 @@ class AuthTest extends TestCase { } public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGetAndDesktopClient(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -424,9 +378,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn(null); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('MyWrongDavUser'); @@ -443,12 +395,8 @@ class AuthTest extends TestCase { } public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -458,9 +406,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn(null); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('MyWrongDavUser'); @@ -478,12 +424,8 @@ class AuthTest extends TestCase { } public function testAuthenticateAlreadyLoggedInWithCsrfTokenForGet(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -493,9 +435,7 @@ class AuthTest extends TestCase { ->method('get') ->with('AUTHENTICATED_TO_DAV_BACKEND') ->willReturn(null); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('MyWrongDavUser'); @@ -513,15 +453,9 @@ class AuthTest extends TestCase { } public function testAuthenticateNoBasicAuthenticateHeadersProvided(): void { - $server = $this->getMockBuilder(Server::class) - ->disableOriginalConstructor() - ->getMock(); - $server->httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $server->httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); + $server->httpRequest = $this->createMock(RequestInterface::class); + $server->httpResponse = $this->createMock(ResponseInterface::class); $response = $this->auth->check($server->httpRequest, $server->httpResponse); $this->assertEquals([false, 'No \'Authorization: Basic\' header found. Either the client didn\'t send one, or the server is misconfigured'], $response); } @@ -532,13 +466,9 @@ class AuthTest extends TestCase { $this->expectExceptionMessage('Cannot authenticate over ajax calls'); /** @var \Sabre\HTTP\RequestInterface&MockObject $httpRequest */ - $httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $httpRequest = $this->createMock(RequestInterface::class); /** @var \Sabre\HTTP\ResponseInterface&MockObject $httpResponse */ - $httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $httpResponse = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->any()) ->method('isLoggedIn') @@ -562,13 +492,9 @@ class AuthTest extends TestCase { ->willReturn(false); /** @var \Sabre\HTTP\RequestInterface&MockObject $httpRequest */ - $httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $httpRequest = $this->createMock(RequestInterface::class); /** @var \Sabre\HTTP\ResponseInterface&MockObject $httpResponse */ - $httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $httpResponse = $this->createMock(ResponseInterface::class); $httpRequest ->expects($this->any()) ->method('getHeader') @@ -577,9 +503,7 @@ class AuthTest extends TestCase { ['Authorization', 'basic dXNlcm5hbWU6cGFzc3dvcmQ='], ]); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('MyDavUser'); @@ -602,17 +526,10 @@ class AuthTest extends TestCase { public function testAuthenticateNoBasicAuthenticateHeadersProvidedWithAjaxButUserIsStillLoggedIn(): void { /** @var \Sabre\HTTP\RequestInterface $httpRequest */ - $httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $httpRequest = $this->createMock(RequestInterface::class); /** @var \Sabre\HTTP\ResponseInterface $httpResponse */ - $httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); - /** @var IUser */ - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $httpResponse = $this->createMock(ResponseInterface::class); + $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('MyTestUser'); $this->userSession ->expects($this->any()) @@ -643,29 +560,21 @@ class AuthTest extends TestCase { } public function testAuthenticateValidCredentials(): void { - $server = $this->getMockBuilder(Server::class) - ->disableOriginalConstructor() - ->getMock(); - $server->httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); + $server->httpRequest = $this->createMock(RequestInterface::class); $server->httpRequest ->expects($this->once()) ->method('getHeader') ->with('Authorization') ->willReturn('basic dXNlcm5hbWU6cGFzc3dvcmQ='); - $server->httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $server->httpResponse = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->once()) ->method('logClientIn') ->with('username', 'password') ->willReturn(true); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->exactly(2)) ->method('getUID') ->willReturn('MyTestUser'); @@ -678,12 +587,8 @@ class AuthTest extends TestCase { } public function testAuthenticateInvalidCredentials(): void { - $server = $this->getMockBuilder(Server::class) - ->disableOriginalConstructor() - ->getMock(); - $server->httpRequest = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); + $server->httpRequest = $this->createMock(RequestInterface::class); $server->httpRequest ->expects($this->exactly(2)) ->method('getHeader') @@ -691,9 +596,7 @@ class AuthTest extends TestCase { ['Authorization', 'basic dXNlcm5hbWU6cGFzc3dvcmQ='], ['X-Requested-With', null], ]); - $server->httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $server->httpResponse = $this->createMock(ResponseInterface::class); $this->userSession ->expects($this->once()) ->method('logClientIn') diff --git a/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php b/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php index 99c2a461557..1e6267d4cbb 100644 --- a/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/BearerAuthTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -21,14 +23,10 @@ use Test\TestCase; * @group DB */ class BearerAuthTest extends TestCase { - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - /** @var ISession|\PHPUnit\Framework\MockObject\MockObject */ - private $session; - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var BearerAuth */ - private $bearerAuth; + private IUserSession&MockObject $userSession; + private ISession&MockObject $session; + private IRequest&MockObject $request; + private BearerAuth $bearerAuth; private IConfig&MockObject $config; @@ -74,9 +72,9 @@ class BearerAuthTest extends TestCase { } public function testChallenge(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|RequestInterface $request */ + /** @var RequestInterface&MockObject $request */ $request = $this->createMock(RequestInterface::class); - /** @var \PHPUnit\Framework\MockObject\MockObject|ResponseInterface $response */ + /** @var ResponseInterface&MockObject $response */ $response = $this->createMock(ResponseInterface::class); $result = $this->bearerAuth->challenge($request, $response); $this->assertEmpty($result); diff --git a/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php index 072dd1a3b58..27ddd3f4a1f 100644 --- a/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/BlockLegacyClientPluginTest.php @@ -83,7 +83,7 @@ class BlockLegacyClientPluginTest extends TestCase { } /** @var RequestInterface|MockObject $request */ - $request = $this->createMock('\Sabre\HTTP\RequestInterface'); + $request = $this->createMock(RequestInterface::class); $request ->expects($this->once()) ->method('getHeader') diff --git a/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php index 1cda0e4dbdb..6606dcd5717 100644 --- a/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/CommentsPropertiesPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,62 +9,45 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre; use OCA\DAV\Connector\Sabre\CommentPropertiesPlugin as CommentPropertiesPluginImplementation; +use OCA\DAV\Connector\Sabre\Directory; use OCA\DAV\Connector\Sabre\File; use OCP\Comments\ICommentsManager; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\PropFind; +use Sabre\DAV\Server; class CommentsPropertiesPluginTest extends \Test\TestCase { - - /** @var CommentPropertiesPluginImplementation */ - protected $plugin; - protected $commentsManager; - protected $userSession; - protected $server; + protected CommentPropertiesPluginImplementation $plugin; + protected ICommentsManager&MockObject $commentsManager; + protected IUserSession&MockObject $userSession; + protected Server&MockObject $server; protected function setUp(): void { parent::setUp(); - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->server = $this->getMockBuilder('\Sabre\DAV\Server') - ->disableOriginalConstructor() - ->getMock(); + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->server = $this->createMock(Server::class); $this->plugin = new CommentPropertiesPluginImplementation($this->commentsManager, $this->userSession); $this->plugin->initialize($this->server); } - public function nodeProvider() { - $mocks = []; - foreach (['\OCA\DAV\Connector\Sabre\File', '\OCA\DAV\Connector\Sabre\Directory', '\Sabre\DAV\INode'] as $class) { - $mocks[] = $this->getMockBuilder($class) - ->disableOriginalConstructor() - ->getMock(); - } - + public static function nodeProvider(): array { return [ - [$mocks[0], true], - [$mocks[1], true], - [$mocks[2], false] + [File::class, true], + [Directory::class, true], + [\Sabre\DAV\INode::class, false] ]; } /** * @dataProvider nodeProvider - * @param $node - * @param $expectedSuccessful */ - public function testHandleGetProperties($node, $expectedSuccessful): void { - $propFind = $this->getMockBuilder(PropFind::class) - ->disableOriginalConstructor() - ->getMock(); + public function testHandleGetProperties(string $class, bool $expectedSuccessful): void { + $propFind = $this->createMock(PropFind::class); if ($expectedSuccessful) { $propFind->expects($this->exactly(3)) @@ -73,10 +57,11 @@ class CommentsPropertiesPluginTest extends \Test\TestCase { ->method('handle'); } + $node = $this->createMock($class); $this->plugin->handleGetProperties($propFind, $node); } - public function baseUriProvider() { + public static function baseUriProvider(): array { return [ ['owncloud/remote.php/webdav/', '4567', 'owncloud/remote.php/dav/comments/files/4567'], ['owncloud/remote.php/files/', '4567', 'owncloud/remote.php/dav/comments/files/4567'], @@ -86,14 +71,9 @@ class CommentsPropertiesPluginTest extends \Test\TestCase { /** * @dataProvider baseUriProvider - * @param $baseUri - * @param $fid - * @param $expectedHref */ - public function testGetCommentsLink($baseUri, $fid, $expectedHref): void { - $node = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + public function testGetCommentsLink(string $baseUri, string $fid, ?string $expectedHref): void { + $node = $this->createMock(File::class); $node->expects($this->any()) ->method('getId') ->willReturn($fid); @@ -106,29 +86,25 @@ class CommentsPropertiesPluginTest extends \Test\TestCase { $this->assertSame($expectedHref, $href); } - public function userProvider() { + public static function userProvider(): array { return [ - [ - $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock() - ], + [IUser::class], [null] ]; } /** * @dataProvider userProvider - * @param $user */ - public function testGetUnreadCount($user): void { - $node = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + public function testGetUnreadCount(?string $user): void { + $node = $this->createMock(File::class); $node->expects($this->any()) ->method('getId') ->willReturn('4567'); + if ($user !== null) { + $user = $this->createMock($user); + } $this->userSession->expects($this->once()) ->method('getUser') ->willReturn($user); diff --git a/apps/dav/tests/unit/Connector/Sabre/CopyEtagHeaderPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/CopyEtagHeaderPluginTest.php index bc19e071ee7..7067cf335ed 100644 --- a/apps/dav/tests/unit/Connector/Sabre/CopyEtagHeaderPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/CopyEtagHeaderPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -15,12 +16,8 @@ use Sabre\DAV\Tree; use Test\TestCase; class CopyEtagHeaderPluginTest extends TestCase { - - /** @var CopyEtagHeaderPlugin */ - private $plugin; - - /** @var Server */ - private $server; + private CopyEtagHeaderPlugin $plugin; + private Server $server; protected function setUp(): void { parent::setUp(); @@ -62,15 +59,11 @@ class CopyEtagHeaderPluginTest extends TestCase { } public function testAfterMove(): void { - $node = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(File::class); $node->expects($this->once()) ->method('getETag') ->willReturn('123456'); - $tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); + $tree = $this->createMock(Tree::class); $tree->expects($this->once()) ->method('getNodeForPath') ->with('test.txt') diff --git a/apps/dav/tests/unit/Connector/Sabre/CustomPropertiesBackendTest.php b/apps/dav/tests/unit/Connector/Sabre/CustomPropertiesBackendTest.php index eb3f291e9c0..381206e336e 100644 --- a/apps/dav/tests/unit/Connector/Sabre/CustomPropertiesBackendTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/CustomPropertiesBackendTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -25,42 +26,21 @@ use Sabre\DAV\Tree; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class CustomPropertiesBackendTest extends \Test\TestCase { - - /** - * @var \Sabre\DAV\Server - */ - private $server; - - /** - * @var \Sabre\DAV\Tree - */ - private $tree; - - /** - * @var CustomPropertiesBackend - */ - private $plugin; - - /** - * @var IUser - */ - private $user; - - /** @property MockObject|DefaultCalendarValidator */ - private $defaultCalendarValidator; + private \Sabre\DAV\Server $server; + private \Sabre\DAV\Tree&MockObject $tree; + private IUser&MockObject $user; + private DefaultCalendarValidator&MockObject $defaultCalendarValidator; + private CustomPropertiesBackend $plugin; protected function setUp(): void { parent::setUp(); + $this->server = new \Sabre\DAV\Server(); - $this->tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tree = $this->createMock(Tree::class); - $userId = $this->getUniqueID('testcustompropertiesuser'); + $userId = self::getUniqueID('testcustompropertiesuser'); - $this->user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $this->user = $this->createMock(IUser::class); $this->user->expects($this->any()) ->method('getUID') ->willReturn($userId); @@ -88,12 +68,12 @@ class CustomPropertiesBackendTest extends \Test\TestCase { ] ); $deleteStatement->closeCursor(); + + parent::tearDown(); } - private function createTestNode($class) { - $node = $this->getMockBuilder($class) - ->disableOriginalConstructor() - ->getMock(); + private function createTestNode(string $class) { + $node = $this->createMock($class); $node->expects($this->any()) ->method('getId') ->willReturn(123); diff --git a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php index 7fefe3e06da..85890c0f987 100644 --- a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php @@ -1,11 +1,12 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ -namespace OCA\DAV\Tests\Unit\Connector\Sabre; +namespace OCA\DAV\Tests\unit\Connector\Sabre; use OC\Files\FileInfo; use OC\Files\Filesystem; @@ -21,6 +22,7 @@ use OCP\Files\ForbiddenException; use OCP\Files\InvalidPathException; use OCP\Files\Mount\IMountPoint; use OCP\Files\StorageNotAvailableException; +use PHPUnit\Framework\MockObject\MockObject; use Test\Traits\UserTrait; class TestViewDirectory extends View { @@ -43,7 +45,7 @@ class TestViewDirectory extends View { return $this->deletables[$path]; } - public function rename($path1, $path2, array $options = []) { + public function rename($source, $target, array $options = []) { return $this->canRename; } @@ -59,16 +61,14 @@ class TestViewDirectory extends View { class DirectoryTest extends \Test\TestCase { use UserTrait; - /** @var View|\PHPUnit\Framework\MockObject\MockObject */ - private $view; - /** @var FileInfo|\PHPUnit\Framework\MockObject\MockObject */ - private $info; + private View&MockObject $view; + private FileInfo&MockObject $info; protected function setUp(): void { parent::setUp(); - $this->view = $this->createMock('OC\Files\View'); - $this->info = $this->createMock('OC\Files\FileInfo'); + $this->view = $this->createMock(View::class); + $this->info = $this->createMock(FileInfo::class); $this->info->method('isReadable') ->willReturn(true); $this->info->method('getType') @@ -81,7 +81,7 @@ class DirectoryTest extends \Test\TestCase { ->willReturn(Constants::PERMISSION_READ); } - private function getDir($path = '/') { + private function getDir(string $path = '/'): Directory { $this->view->expects($this->once()) ->method('getRelativePath') ->willReturn($path); @@ -174,12 +174,8 @@ class DirectoryTest extends \Test\TestCase { } public function testGetChildren(): void { - $info1 = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); - $info2 = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); + $info1 = $this->createMock(FileInfo::class); + $info2 = $this->createMock(FileInfo::class); $info1->method('getName') ->willReturn('first'); $info1->method('getPath') @@ -214,7 +210,7 @@ class DirectoryTest extends \Test\TestCase { $dir = new Directory($this->view, $this->info); $nodes = $dir->getChildren(); - $this->assertEquals(2, count($nodes)); + $this->assertCount(2, $nodes); // calling a second time just returns the cached values, // does not call getDirectoryContents again @@ -273,12 +269,10 @@ class DirectoryTest extends \Test\TestCase { } public function testGetQuotaInfoUnlimited(): void { - self::createUser('user', 'password'); + $this->createUser('user', 'password'); self::loginAsUser('user'); $mountPoint = $this->createMock(IMountPoint::class); - $storage = $this->getMockBuilder(Quota::class) - ->disableOriginalConstructor() - ->getMock(); + $storage = $this->createMock(Quota::class); $mountPoint->method('getStorage') ->willReturn($storage); @@ -329,12 +323,10 @@ class DirectoryTest extends \Test\TestCase { } public function testGetQuotaInfoSpecific(): void { - self::createUser('user', 'password'); + $this->createUser('user', 'password'); self::loginAsUser('user'); $mountPoint = $this->createMock(IMountPoint::class); - $storage = $this->getMockBuilder(Quota::class) - ->disableOriginalConstructor() - ->getMock(); + $storage = $this->createMock(Quota::class); $mountPoint->method('getStorage') ->willReturn($storage); @@ -384,7 +376,7 @@ class DirectoryTest extends \Test\TestCase { /** * @dataProvider moveFailedProvider */ - public function testMoveFailed($source, $destination, $updatables, $deletables): void { + public function testMoveFailed(string $source, string $destination, array $updatables, array $deletables): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); $this->moveTest($source, $destination, $updatables, $deletables); @@ -393,7 +385,7 @@ class DirectoryTest extends \Test\TestCase { /** * @dataProvider moveSuccessProvider */ - public function testMoveSuccess($source, $destination, $updatables, $deletables): void { + public function testMoveSuccess(string $source, string $destination, array $updatables, array $deletables): void { $this->moveTest($source, $destination, $updatables, $deletables); $this->addToAssertionCount(1); } @@ -401,19 +393,19 @@ class DirectoryTest extends \Test\TestCase { /** * @dataProvider moveFailedInvalidCharsProvider */ - public function testMoveFailedInvalidChars($source, $destination, $updatables, $deletables): void { + public function testMoveFailedInvalidChars(string $source, string $destination, array $updatables, array $deletables): void { $this->expectException(InvalidPath::class); $this->moveTest($source, $destination, $updatables, $deletables); } - public function moveFailedInvalidCharsProvider() { + public static function moveFailedInvalidCharsProvider(): array { return [ ['a/valid', "a/i\nvalid", ['a' => true, 'a/valid' => true, 'a/c*' => false], []], ]; } - public function moveFailedProvider() { + public static function moveFailedProvider(): array { return [ ['a/b', 'a/c', ['a' => false, 'a/b' => false, 'a/c' => false], []], ['a/b', 'b/b', ['a' => false, 'a/b' => false, 'b' => false, 'b/b' => false], []], @@ -424,7 +416,7 @@ class DirectoryTest extends \Test\TestCase { ]; } - public function moveSuccessProvider() { + public static function moveSuccessProvider(): array { return [ ['a/b', 'b/b', ['a' => true, 'a/b' => true, 'b' => true, 'b/b' => false], ['a/b' => true]], // older files with special chars can still be renamed to valid names @@ -432,12 +424,7 @@ class DirectoryTest extends \Test\TestCase { ]; } - /** - * @param $source - * @param $destination - * @param $updatables - */ - private function moveTest($source, $destination, $updatables, $deletables): void { + private function moveTest(string $source, string $destination, array $updatables, array $deletables): void { $view = new TestViewDirectory($updatables, $deletables); $sourceInfo = new FileInfo($source, null, null, [ @@ -449,7 +436,7 @@ class DirectoryTest extends \Test\TestCase { $sourceNode = new Directory($view, $sourceInfo); $targetNode = $this->getMockBuilder(Directory::class) - ->setMethods(['childExists']) + ->onlyMethods(['childExists']) ->setConstructorArgs([$view, $targetInfo]) ->getMock(); $targetNode->expects($this->any())->method('childExists') diff --git a/apps/dav/tests/unit/Connector/Sabre/DummyGetResponsePluginTest.php b/apps/dav/tests/unit/Connector/Sabre/DummyGetResponsePluginTest.php index 03c31dc47f8..2d688d64600 100644 --- a/apps/dav/tests/unit/Connector/Sabre/DummyGetResponsePluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/DummyGetResponsePluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -19,8 +20,7 @@ use Test\TestCase; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class DummyGetResponsePluginTest extends TestCase { - /** @var DummyGetResponsePlugin */ - private $dummyGetResponsePlugin; + private DummyGetResponsePlugin $dummyGetResponsePlugin; protected function setUp(): void { parent::setUp(); @@ -29,10 +29,7 @@ class DummyGetResponsePluginTest extends TestCase { } public function testInitialize(): void { - /** @var Server $server */ - $server = $this->getMockBuilder(Server::class) - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); $server ->expects($this->once()) ->method('on') @@ -44,13 +41,9 @@ class DummyGetResponsePluginTest extends TestCase { public function testHttpGet(): void { /** @var \Sabre\HTTP\RequestInterface $request */ - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); /** @var \Sabre\HTTP\ResponseInterface $response */ - $response = $server = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $response = $this->createMock(ResponseInterface::class); $response ->expects($this->once()) ->method('setBody'); diff --git a/apps/dav/tests/unit/Connector/Sabre/Exception/ForbiddenTest.php b/apps/dav/tests/unit/Connector/Sabre/Exception/ForbiddenTest.php index c7fb6066ed4..2f9e0ae9196 100644 --- a/apps/dav/tests/unit/Connector/Sabre/Exception/ForbiddenTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/Exception/ForbiddenTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,6 +9,7 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre\Exception; use OCA\DAV\Connector\Sabre\Exception\Forbidden; +use Sabre\DAV\Server; class ForbiddenTest extends \Test\TestCase { public function testSerialization(): void { @@ -32,9 +34,7 @@ class ForbiddenTest extends \Test\TestCase { EOD; $ex = new Forbidden($message, $retry); - $server = $this->getMockBuilder('Sabre\DAV\Server') - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); $ex->serialize($server, $error); // assert diff --git a/apps/dav/tests/unit/Connector/Sabre/Exception/InvalidPathTest.php b/apps/dav/tests/unit/Connector/Sabre/Exception/InvalidPathTest.php index 98921d735fa..6f62bef86a3 100644 --- a/apps/dav/tests/unit/Connector/Sabre/Exception/InvalidPathTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/Exception/InvalidPathTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,6 +9,7 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre\Exception; use OCA\DAV\Connector\Sabre\Exception\InvalidPath; +use Sabre\DAV\Server; class InvalidPathTest extends \Test\TestCase { public function testSerialization(): void { @@ -32,9 +34,7 @@ class InvalidPathTest extends \Test\TestCase { EOD; $ex = new InvalidPath($message, $retry); - $server = $this->getMockBuilder('Sabre\DAV\Server') - ->disableOriginalConstructor() - ->getMock(); + $server = $this->createMock(Server::class); $ex->serialize($server, $error); // assert diff --git a/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php index 1d50fb2fb9a..a330a885b1f 100644 --- a/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -11,21 +12,16 @@ use OC\SystemConfig; use OCA\DAV\Connector\Sabre\Exception\InvalidPath; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Exception\ServerMaintenanceMode; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\Server; use Test\TestCase; class ExceptionLoggerPluginTest extends TestCase { - - /** @var Server */ - private $server; - - /** @var ExceptionLoggerPlugin */ - private $plugin; - - /** @var LoggerInterface | \PHPUnit\Framework\MockObject\MockObject */ - private $logger; + private Server $server; + private ExceptionLoggerPlugin $plugin; + private LoggerInterface&MockObject $logger; private function init(): void { $config = $this->createMock(SystemConfig::class); @@ -59,7 +55,7 @@ class ExceptionLoggerPluginTest extends TestCase { $this->plugin->logException($e); } - public function providesExceptions() { + public static function providesExceptions(): array { return [ ['debug', new NotFound()], ['debug', new ServerMaintenanceMode('System is in maintenance mode.')], diff --git a/apps/dav/tests/unit/Connector/Sabre/FakeLockerPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FakeLockerPluginTest.php index 18165b79cb2..ef744d13e6a 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FakeLockerPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FakeLockerPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -22,8 +23,7 @@ use Test\TestCase; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class FakeLockerPluginTest extends TestCase { - /** @var FakeLockerPlugin */ - private $fakeLockerPlugin; + private FakeLockerPlugin $fakeLockerPlugin; protected function setUp(): void { parent::setUp(); @@ -32,18 +32,19 @@ class FakeLockerPluginTest extends TestCase { public function testInitialize(): void { /** @var Server $server */ - $server = $this->getMockBuilder(Server::class) - ->disableOriginalConstructor() - ->getMock(); - $server - ->expects($this->exactly(4)) + $server = $this->createMock(Server::class); + $calls = [ + ['method:LOCK', [$this->fakeLockerPlugin, 'fakeLockProvider'], 1], + ['method:UNLOCK', [$this->fakeLockerPlugin, 'fakeUnlockProvider'], 1], + ['propFind', [$this->fakeLockerPlugin, 'propFind'], 100], + ['validateTokens', [$this->fakeLockerPlugin, 'validateTokens'], 100], + ]; + $server->expects($this->exactly(count($calls))) ->method('on') - ->withConsecutive( - ['method:LOCK', [$this->fakeLockerPlugin, 'fakeLockProvider'], 1], - ['method:UNLOCK', [$this->fakeLockerPlugin, 'fakeUnlockProvider'], 1], - ['propFind', [$this->fakeLockerPlugin, 'propFind']], - ['validateTokens', [$this->fakeLockerPlugin, 'validateTokens']], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $this->fakeLockerPlugin->initialize($server); } @@ -64,24 +65,24 @@ class FakeLockerPluginTest extends TestCase { } public function testPropFind(): void { - $propFind = $this->getMockBuilder(PropFind::class) - ->disableOriginalConstructor() - ->getMock(); - $node = $this->getMockBuilder(INode::class) - ->disableOriginalConstructor() - ->getMock(); + $propFind = $this->createMock(PropFind::class); + $node = $this->createMock(INode::class); - $propFind->expects($this->exactly(2)) + $calls = [ + '{DAV:}supportedlock', + '{DAV:}lockdiscovery', + ]; + $propFind->expects($this->exactly(count($calls))) ->method('handle') - ->withConsecutive( - ['{DAV:}supportedlock'], - ['{DAV:}lockdiscovery'], - ); + ->willReturnCallback(function ($propertyName) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, $propertyName); + }); $this->fakeLockerPlugin->propFind($propFind, $node); } - public function tokenDataProvider() { + public static function tokenDataProvider(): array { return [ [ [ @@ -120,21 +121,15 @@ class FakeLockerPluginTest extends TestCase { /** * @dataProvider tokenDataProvider - * @param array $input - * @param array $expected */ public function testValidateTokens(array $input, array $expected): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); $this->fakeLockerPlugin->validateTokens($request, $input); $this->assertSame($expected, $input); } public function testFakeLockProvider(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); $response = new Response(); $server = $this->getMockBuilder(Server::class) ->getMock(); @@ -152,12 +147,8 @@ class FakeLockerPluginTest extends TestCase { } public function testFakeUnlockProvider(): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $response->expects($this->once()) ->method('setStatus') diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php index ef02f145375..4a7ddad7115 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -53,16 +54,9 @@ class FileTest extends TestCase { use MountProviderTrait; use UserTrait; - /** - * @var string - */ - private $user; - - /** @var IConfig|MockObject */ - protected $config; - - /** @var IRequestId|MockObject */ - protected $requestId; + private string $user; + protected IConfig&MockObject $config; + protected IRequestId&MockObject $requestId; protected function setUp(): void { parent::setUp(); @@ -72,7 +66,7 @@ class FileTest extends TestCase { $this->user = 'test_user'; $this->createUser($this->user, 'pass'); - $this->loginAsUser($this->user); + self::loginAsUser($this->user); $this->config = $this->createMock(IConfig::class); $this->requestId = $this->createMock(IRequestId::class); @@ -86,9 +80,7 @@ class FileTest extends TestCase { } private function getMockStorage(): MockObject&IStorage { - $storage = $this->getMockBuilder(IStorage::class) - ->disableOriginalConstructor() - ->getMock(); + $storage = $this->createMock(IStorage::class); $storage->method('getId') ->willReturn('home::someuser'); return $storage; @@ -102,7 +94,7 @@ class FileTest extends TestCase { } - public function fopenFailuresProvider() { + public static function fopenFailuresProvider(): array { return [ [ // return false @@ -161,14 +153,14 @@ class FileTest extends TestCase { /** * @dataProvider fopenFailuresProvider */ - public function testSimplePutFails($thrownException, $expectedException, $checkPreviousClass = true): void { + public function testSimplePutFails(?\Throwable $thrownException, string $expectedException, bool $checkPreviousClass = true): void { // setup $storage = $this->getMockBuilder(Local::class) ->onlyMethods(['writeStream']) ->setConstructorArgs([['datadir' => Server::get(ITempManager::class)->getTemporaryFolder()]]) ->getMock(); Filesystem::mount($storage, [], $this->user . '/'); - /** @var View | MockObject $view */ + /** @var View&MockObject $view */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['getRelativePath', 'resolvePath']) ->getMock(); @@ -221,12 +213,12 @@ class FileTest extends TestCase { * Simulate putting a file to the given path. * * @param string $path path to put the file into - * @param string $viewRoot root to use for the view + * @param ?string $viewRoot root to use for the view * @param null|Request $request the HTTP request * * @return null|string of the PUT operation which is usually the etag */ - private function doPut($path, $viewRoot = null, ?Request $request = null) { + private function doPut(string $path, ?string $viewRoot = null, ?Request $request = null) { $view = Filesystem::getView(); if (!is_null($viewRoot)) { $view = new View($viewRoot); @@ -245,7 +237,7 @@ class FileTest extends TestCase { null ); - /** @var File|MockObject $file */ + /** @var File&MockObject $file */ $file = $this->getMockBuilder(File::class) ->setConstructorArgs([$view, $info, null, $request]) ->onlyMethods(['header']) @@ -269,55 +261,55 @@ class FileTest extends TestCase { $this->assertNotEmpty($this->doPut('/foo.txt')); } - public function legalMtimeProvider() { + public static function legalMtimeProvider(): array { return [ 'string' => [ - 'HTTP_X_OC_MTIME' => 'string', - 'expected result' => null + 'requestMtime' => 'string', + 'resultMtime' => null ], 'castable string (int)' => [ - 'HTTP_X_OC_MTIME' => '987654321', - 'expected result' => 987654321 + 'requestMtime' => '987654321', + 'resultMtime' => 987654321 ], 'castable string (float)' => [ - 'HTTP_X_OC_MTIME' => '123456789.56', - 'expected result' => 123456789 + 'requestMtime' => '123456789.56', + 'resultMtime' => 123456789 ], 'float' => [ - 'HTTP_X_OC_MTIME' => 123456789.56, - 'expected result' => 123456789 + 'requestMtime' => 123456789.56, + 'resultMtime' => 123456789 ], 'zero' => [ - 'HTTP_X_OC_MTIME' => 0, - 'expected result' => null + 'requestMtime' => 0, + 'resultMtime' => null ], 'zero string' => [ - 'HTTP_X_OC_MTIME' => '0', - 'expected result' => null + 'requestMtime' => '0', + 'resultMtime' => null ], 'negative zero string' => [ - 'HTTP_X_OC_MTIME' => '-0', - 'expected result' => null + 'requestMtime' => '-0', + 'resultMtime' => null ], 'string starting with number following by char' => [ - 'HTTP_X_OC_MTIME' => '2345asdf', - 'expected result' => null + 'requestMtime' => '2345asdf', + 'resultMtime' => null ], 'string castable hex int' => [ - 'HTTP_X_OC_MTIME' => '0x45adf', - 'expected result' => null + 'requestMtime' => '0x45adf', + 'resultMtime' => null ], 'string that looks like invalid hex int' => [ - 'HTTP_X_OC_MTIME' => '0x123g', - 'expected result' => null + 'requestMtime' => '0x123g', + 'resultMtime' => null ], 'negative int' => [ - 'HTTP_X_OC_MTIME' => -34, - 'expected result' => null + 'requestMtime' => -34, + 'resultMtime' => null ], 'negative float' => [ - 'HTTP_X_OC_MTIME' => -34.43, - 'expected result' => null + 'requestMtime' => -34.43, + 'resultMtime' => null ], ]; } @@ -326,7 +318,7 @@ class FileTest extends TestCase { * Test putting a file with string Mtime * @dataProvider legalMtimeProvider */ - public function testPutSingleFileLegalMtime($requestMtime, $resultMtime): void { + public function testPutSingleFileLegalMtime(mixed $requestMtime, ?int $resultMtime): void { $request = new Request([ 'server' => [ 'HTTP_X_OC_MTIME' => (string)$requestMtime, @@ -482,7 +474,7 @@ class FileTest extends TestCase { */ public function testSimplePutFailsSizeCheck(): void { // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['rename', 'getRelativePath', 'filesize']) ->getMock(); @@ -569,7 +561,7 @@ class FileTest extends TestCase { */ public function testSimplePutInvalidChars(): void { // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['getRelativePath']) ->getMock(); @@ -609,7 +601,7 @@ class FileTest extends TestCase { $this->expectException(InvalidPath::class); // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['getRelativePath']) ->getMock(); @@ -630,7 +622,7 @@ class FileTest extends TestCase { public function testUploadAbort(): void { // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['rename', 'getRelativePath', 'filesize']) ->getMock(); @@ -680,7 +672,7 @@ class FileTest extends TestCase { public function testDeleteWhenAllowed(): void { // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->getMock(); @@ -704,7 +696,7 @@ class FileTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->getMock(); @@ -724,7 +716,7 @@ class FileTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->getMock(); @@ -749,7 +741,7 @@ class FileTest extends TestCase { $this->expectException(Forbidden::class); // setup - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->getMock(); @@ -923,7 +915,7 @@ class FileTest extends TestCase { public function testGetFopenFails(): void { $this->expectException(\Sabre\DAV\Exception\ServiceUnavailable::class); - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['fopen']) ->getMock(); @@ -945,7 +937,7 @@ class FileTest extends TestCase { public function testGetFopenThrows(): void { $this->expectException(Forbidden::class); - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['fopen']) ->getMock(); @@ -967,7 +959,7 @@ class FileTest extends TestCase { public function testGetThrowsIfNoPermission(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - /** @var View|MockObject */ + /** @var View&MockObject */ $view = $this->getMockBuilder(View::class) ->onlyMethods(['fopen']) ->getMock(); diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php index 1352229b1f5..d8b32067dda 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -73,23 +74,15 @@ class FilesPluginTest extends TestCase { $this->accountManager, ); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $response = $this->createMock(ResponseInterface::class); $this->server->httpResponse = $response; $this->server->xml = new Service(); $this->plugin->initialize($this->server); } - /** - * @param string $class - * @return \PHPUnit\Framework\MockObject\MockObject - */ - private function createTestNode($class, $path = '/dummypath') { - $node = $this->getMockBuilder($class) - ->disableOriginalConstructor() - ->getMock(); + private function createTestNode(string $class, string $path = '/dummypath'): MockObject { + $node = $this->createMock($class); $node->expects($this->any()) ->method('getId') @@ -129,8 +122,8 @@ class FilesPluginTest extends TestCase { } public function testGetPropertiesForFile(): void { - /** @var File|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); + /** @var File&MockObject $node */ + $node = $this->createTestNode(File::class); $propFind = new PropFind( '/dummyPath', @@ -149,8 +142,7 @@ class FilesPluginTest extends TestCase { 0 ); - $user = $this->getMockBuilder(User::class) - ->disableOriginalConstructor()->getMock(); + $user = $this->createMock(User::class); $user ->expects($this->once()) ->method('getUID') @@ -160,8 +152,7 @@ class FilesPluginTest extends TestCase { ->method('getDisplayName') ->willReturn('M. Foo'); - $owner = $this->getMockBuilder(Account::class) - ->disableOriginalConstructor()->getMock(); + $owner = $this->createMock(Account::class); $this->accountManager->expects($this->once()) ->method('getAccount') ->with($user) @@ -174,8 +165,7 @@ class FilesPluginTest extends TestCase { ->method('getOwner') ->willReturn($user); - $displayNameProp = $this->getMockBuilder(AccountProperty::class) - ->disableOriginalConstructor()->getMock(); + $displayNameProp = $this->createMock(AccountProperty::class); $owner ->expects($this->once()) ->method('getProperty') @@ -205,9 +195,7 @@ class FilesPluginTest extends TestCase { } public function testGetDisplayNamePropertyWhenNotPublished(): void { - /** @var File|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - + $node = $this->createTestNode(File::class); $propFind = new PropFind( '/dummyPath', [ @@ -220,15 +208,12 @@ class FilesPluginTest extends TestCase { ->method('getUser') ->willReturn(null); - $user = $this->getMockBuilder(User::class) - ->disableOriginalConstructor()->getMock(); + $user = $this->createMock(User::class); - $user - ->expects($this->never()) + $user->expects($this->never()) ->method('getDisplayName'); - $owner = $this->getMockBuilder(Account::class) - ->disableOriginalConstructor()->getMock(); + $owner = $this->createMock(Account::class); $this->accountManager->expects($this->once()) ->method('getAccount') ->with($user) @@ -238,8 +223,7 @@ class FilesPluginTest extends TestCase { ->method('getOwner') ->willReturn($user); - $displayNameProp = $this->getMockBuilder(AccountProperty::class) - ->disableOriginalConstructor()->getMock(); + $displayNameProp = $this->createMock(AccountProperty::class); $owner ->expects($this->once()) ->method('getProperty') @@ -257,10 +241,9 @@ class FilesPluginTest extends TestCase { $this->assertEquals(null, $propFind->get(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME)); } - + public function testGetDisplayNamePropertyWhenNotPublishedButLoggedIn(): void { - /** @var File|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); + $node = $this->createTestNode(File::class); $propFind = new PropFind( '/dummyPath', @@ -270,15 +253,13 @@ class FilesPluginTest extends TestCase { 0 ); - $user = $this->getMockBuilder(User::class) - ->disableOriginalConstructor()->getMock(); + $user = $this->createMock(User::class); $node->expects($this->once()) ->method('getOwner') ->willReturn($user); - $loggedInUser = $this->getMockBuilder(User::class) - ->disableOriginalConstructor()->getMock(); + $loggedInUser = $this->createMock(User::class); $this->userSession->expects($this->once()) ->method('getUser') ->willReturn($loggedInUser); @@ -300,8 +281,8 @@ class FilesPluginTest extends TestCase { } public function testGetPropertiesStorageNotAvailable(): void { - /** @var File|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); + /** @var File&MockObject $node */ + $node = $this->createTestNode(File::class); $propFind = new PropFind( '/dummyPath', @@ -325,9 +306,7 @@ class FilesPluginTest extends TestCase { public function testGetPublicPermissions(): void { /** @var IRequest&MockObject */ - $request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(IRequest::class); $this->plugin = new FilesPlugin( $this->tree, $this->config, @@ -348,8 +327,8 @@ class FilesPluginTest extends TestCase { 0 ); - /** @var File|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); + /** @var File&MockObject $node */ + $node = $this->createTestNode(File::class); $node->expects($this->any()) ->method('getDavPermissions') ->willReturn('DWCKMSR'); @@ -363,8 +342,8 @@ class FilesPluginTest extends TestCase { } public function testGetPropertiesForDirectory(): void { - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory'); + /** @var Directory&MockObject $node */ + $node = $this->createTestNode(Directory::class); $propFind = new PropFind( '/dummyPath', @@ -398,10 +377,8 @@ class FilesPluginTest extends TestCase { } public function testGetPropertiesForRootDirectory(): void { - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + /** @var Directory&MockObject $node */ + $node = $this->createMock(Directory::class); $node->expects($this->any())->method('getPath')->willReturn('/'); $fileInfo = $this->createMock(FileInfo::class); @@ -433,10 +410,8 @@ class FilesPluginTest extends TestCase { // No read permissions can be caused by files access control. // But we still want to load the directory list, so this is okay for us. // $this->expectException(\Sabre\DAV\Exception\NotFound::class); - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + /** @var Directory&MockObject $node */ + $node = $this->createMock(Directory::class); $node->expects($this->any())->method('getPath')->willReturn('/'); $fileInfo = $this->createMock(FileInfo::class); @@ -465,7 +440,7 @@ class FilesPluginTest extends TestCase { } public function testUpdateProps(): void { - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); + $node = $this->createTestNode(File::class); $testDate = 'Fri, 13 Feb 2015 00:01:02 GMT'; $testCreationDate = '2007-08-31T16:47+00:00'; @@ -549,16 +524,12 @@ class FilesPluginTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); $this->expectExceptionMessage('FolderA/test.txt cannot be deleted'); - $fileInfoFolderATestTXT = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); + $fileInfoFolderATestTXT = $this->createMock(FileInfo::class); $fileInfoFolderATestTXT->expects($this->once()) ->method('isDeletable') ->willReturn(false); - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->atLeastOnce()) ->method('getFileInfo') ->willReturn($fileInfoFolderATestTXT); @@ -571,16 +542,12 @@ class FilesPluginTest extends TestCase { } public function testMoveSrcDeletable(): void { - $fileInfoFolderATestTXT = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); + $fileInfoFolderATestTXT = $this->createMock(FileInfo::class); $fileInfoFolderATestTXT->expects($this->once()) ->method('isDeletable') ->willReturn(true); - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->atLeastOnce()) ->method('getFileInfo') ->willReturn($fileInfoFolderATestTXT); @@ -596,9 +563,7 @@ class FilesPluginTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\NotFound::class); $this->expectExceptionMessage('FolderA/test.txt does not exist'); - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->atLeastOnce()) ->method('getFileInfo') ->willReturn(null); @@ -674,7 +639,7 @@ class FilesPluginTest extends TestCase { $this->plugin->checkCopy('FolderA/test.txt', 'invalid\\path.txt'); } - public function downloadHeadersProvider() { + public static function downloadHeadersProvider(): array { return [ [ false, @@ -690,22 +655,16 @@ class FilesPluginTest extends TestCase { /** * @dataProvider downloadHeadersProvider */ - public function testDownloadHeaders($isClumsyAgent, $contentDispositionHeader): void { - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + public function testDownloadHeaders(bool $isClumsyAgent, string $contentDispositionHeader): void { + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request ->expects($this->once()) ->method('getPath') ->willReturn('test/somefile.xml'); - $node = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(File::class); $node ->expects($this->once()) ->method('getName') @@ -722,20 +681,24 @@ class FilesPluginTest extends TestCase { ->method('isUserAgent') ->willReturn($isClumsyAgent); + $calls = [ + ['Content-Disposition', $contentDispositionHeader], + ['X-Accel-Buffering', 'no'], + ]; $response - ->expects($this->exactly(2)) + ->expects($this->exactly(count($calls))) ->method('addHeader') - ->withConsecutive( - ['Content-Disposition', $contentDispositionHeader], - ['X-Accel-Buffering', 'no'] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected, func_get_args()); + }); $this->plugin->httpGet($request, $response); } public function testHasPreview(): void { - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject $node */ - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory'); + /** @var Directory&MockObject $node */ + $node = $this->createTestNode(Directory::class); $propFind = new PropFind( '/dummyPath', diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php index 6a9372ca3fd..e6cfb1f67b2 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -31,6 +32,7 @@ use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\INode; +use Sabre\DAV\Server; use Sabre\DAV\Tree; use Sabre\HTTP\ResponseInterface; @@ -52,15 +54,11 @@ class FilesReportPluginTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $this->tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); - $this->view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tree = $this->createMock(Tree::class); + $this->view = $this->createMock(View::class); - $this->server = $this->getMockBuilder('\Sabre\DAV\Server') + $this->server = $this->getMockBuilder(Server::class) ->setConstructorArgs([$this->tree]) ->onlyMethods(['getRequestUri', 'getBaseUri']) ->getMock(); @@ -69,22 +67,10 @@ class FilesReportPluginTest extends \Test\TestCase { ->method('getBaseUri') ->willReturn('http://example.com/owncloud/remote.php/dav'); - $this->groupManager = $this->getMockBuilder(IGroupManager::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->userFolder = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->previewManager = $this->getMockBuilder(IPreview::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->appManager = $this->getMockBuilder(IAppManager::class) - ->disableOriginalConstructor() - ->getMock(); - + $this->groupManager = $this->createMock(IGroupManager::class); + $this->userFolder = $this->createMock(Folder::class); + $this->previewManager = $this->createMock(IPreview::class); + $this->appManager = $this->createMock(IAppManager::class); $this->tagManager = $this->createMock(ISystemTagManager::class); $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); $this->userSession = $this->createMock(IUserSession::class); @@ -95,9 +81,7 @@ class FilesReportPluginTest extends \Test\TestCase { ->with('files') ->willReturn($this->privateTags); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('testuser'); @@ -124,11 +108,7 @@ class FilesReportPluginTest extends \Test\TestCase { $this->tree->expects($this->any()) ->method('getNodeForPath') ->with('/' . $path) - ->willReturn( - $this->getMockBuilder(INode::class) - ->disableOriginalConstructor() - ->getMock() - ); + ->willReturn($this->createMock(INode::class)); $this->server->expects($this->any()) ->method('getRequestUri') @@ -182,16 +162,12 @@ class FilesReportPluginTest extends \Test\TestCase { ->method('isAdmin') ->willReturn(true); - $reportTargetNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $reportTargetNode = $this->createMock(Directory::class); $reportTargetNode->expects($this->any()) ->method('getPath') ->willReturn(''); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $response = $this->createMock(ResponseInterface::class); $response->expects($this->once()) ->method('setHeader') @@ -240,14 +216,10 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive( - ['OneTwoThree'], - ['FourFiveSix'], - ) - ->willReturnOnConsecutiveCalls( - [$filesNode1], - [$filesNode2], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1]], + ['FourFiveSix', 'testuser', 0, 0, [$filesNode2]], + ]); $this->server->expects($this->any()) ->method('getRequestUri') @@ -259,74 +231,56 @@ class FilesReportPluginTest extends \Test\TestCase { } public function testFindNodesByFileIdsRoot(): void { - $filesNode1 = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); + $filesNode1 = $this->createMock(Folder::class); $filesNode1->expects($this->once()) ->method('getName') ->willReturn('first node'); - $filesNode2 = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + $filesNode2 = $this->createMock(File::class); $filesNode2->expects($this->once()) ->method('getName') ->willReturn('second node'); - $reportTargetNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $reportTargetNode = $this->createMock(Directory::class); $reportTargetNode->expects($this->any()) ->method('getPath') ->willReturn('/'); $this->userFolder->expects($this->exactly(2)) ->method('getFirstNodeById') - ->withConsecutive( - ['111'], - ['222'], - ) - ->willReturnOnConsecutiveCalls( - $filesNode1, - $filesNode2, - ); + ->willReturnMap([ + [111, $filesNode1], + [222, $filesNode2], + ]); /** @var Directory&MockObject $reportTargetNode */ $result = $this->plugin->findNodesByFileIds($reportTargetNode, ['111', '222']); $this->assertCount(2, $result); - $this->assertInstanceOf('\OCA\DAV\Connector\Sabre\Directory', $result[0]); + $this->assertInstanceOf(Directory::class, $result[0]); $this->assertEquals('first node', $result[0]->getName()); - $this->assertInstanceOf('\OCA\DAV\Connector\Sabre\File', $result[1]); + $this->assertInstanceOf(\OCA\DAV\Connector\Sabre\File::class, $result[1]); $this->assertEquals('second node', $result[1]->getName()); } public function testFindNodesByFileIdsSubDir(): void { - $filesNode1 = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); + $filesNode1 = $this->createMock(Folder::class); $filesNode1->expects($this->once()) ->method('getName') ->willReturn('first node'); - $filesNode2 = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + $filesNode2 = $this->createMock(File::class); $filesNode2->expects($this->once()) ->method('getName') ->willReturn('second node'); - $reportTargetNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $reportTargetNode = $this->createMock(Directory::class); $reportTargetNode->expects($this->any()) ->method('getPath') ->willReturn('/sub1/sub2'); - $subNode = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); + $subNode = $this->createMock(Folder::class); $this->userFolder->expects($this->once()) ->method('get') @@ -335,22 +289,18 @@ class FilesReportPluginTest extends \Test\TestCase { $subNode->expects($this->exactly(2)) ->method('getFirstNodeById') - ->withConsecutive( - ['111'], - ['222'], - ) - ->willReturnOnConsecutiveCalls( - $filesNode1, - $filesNode2, - ); + ->willReturnMap([ + [111, $filesNode1], + [222, $filesNode2], + ]); /** @var Directory&MockObject $reportTargetNode */ $result = $this->plugin->findNodesByFileIds($reportTargetNode, ['111', '222']); $this->assertCount(2, $result); - $this->assertInstanceOf('\OCA\DAV\Connector\Sabre\Directory', $result[0]); + $this->assertInstanceOf(Directory::class, $result[0]); $this->assertEquals('first node', $result[0]->getName()); - $this->assertInstanceOf('\OCA\DAV\Connector\Sabre\File', $result[1]); + $this->assertInstanceOf(\OCA\DAV\Connector\Sabre\File::class, $result[1]); $this->assertEquals('second node', $result[1]->getName()); } @@ -360,12 +310,8 @@ class FilesReportPluginTest extends \Test\TestCase { $fileInfo = $this->createMock(FileInfo::class); $fileInfo->method('isReadable')->willReturn(true); - $node1 = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); - $node2 = $this->getMockBuilder(\OCA\DAV\Connector\Sabre\File::class) - ->disableOriginalConstructor() - ->getMock(); + $node1 = $this->createMock(Directory::class); + $node2 = $this->createMock(\OCA\DAV\Connector\Sabre\File::class); $node1->expects($this->once()) ->method('getInternalFileId') @@ -385,10 +331,7 @@ class FilesReportPluginTest extends \Test\TestCase { ->willReturn('/sub/node2'); $node2->method('getFileInfo')->willReturn($fileInfo); - $config = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor() - ->getMock(); - + $config = $this->createMock(IConfig::class); $validator = $this->createMock(IFilenameValidator::class); $accountManager = $this->createMock(IAccountManager::class); @@ -461,7 +404,7 @@ class FilesReportPluginTest extends \Test\TestCase { ->with('OneTwoThree') ->willReturn([$filesNode1, $filesNode2]); - $this->assertEquals([$filesNode1, $filesNode2], $this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, 0, 0])); + $this->assertEquals([$filesNode1, $filesNode2], self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, 0, 0])); } public function testProcessFilterRulesAndCondition(): void { @@ -513,21 +456,17 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive( - ['OneTwoThree'], - ['FourFiveSix'], - ) - ->willReturnOnConsecutiveCalls( - [$filesNode1, $filesNode2], - [$filesNode2, $filesNode3], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1, $filesNode2]], + ['FourFiveSix', 'testuser', 0, 0, [$filesNode2, $filesNode3]], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->assertEquals([$filesNode2], array_values($this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); + $this->assertEquals([$filesNode2], array_values(self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); } public function testProcessFilterRulesAndConditionWithOneEmptyResult(): void { @@ -572,21 +511,17 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive( - ['OneTwoThree'], - ['FourFiveSix'], - ) - ->willReturnOnConsecutiveCalls( - [$filesNode1, $filesNode2], - [], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1, $filesNode2]], + ['FourFiveSix', 'testuser', 0, 0, []], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->assertEquals([], $this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null])); + $this->assertEquals([], self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null])); } public function testProcessFilterRulesAndConditionWithFirstEmptyResult(): void { @@ -631,18 +566,16 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->once()) ->method('searchBySystemTag') - ->with('OneTwoThree') - ->willReturnOnConsecutiveCalls( - [], - [$filesNode1, $filesNode2], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, []], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->assertEquals([], $this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null])); + $this->assertEquals([], self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null])); } public function testProcessFilterRulesAndConditionWithEmptyMidResult(): void { @@ -689,7 +622,7 @@ class FilesReportPluginTest extends \Test\TestCase { $tag789 = $this->createMock(ISystemTag::class); $tag789->expects($this->any()) ->method('getName') - ->willReturn('SevenEightNein'); + ->willReturn('SevenEightNine'); $tag789->expects($this->any()) ->method('isUserVisible') ->willReturn(true); @@ -701,12 +634,10 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive(['OneTwoThree'], ['FourFiveSix'], ['SevenEightNein']) - ->willReturnOnConsecutiveCalls( - [$filesNode1, $filesNode2], - [$filesNode3], - [$filesNode1, $filesNode2], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1, $filesNode2]], + ['FourFiveSix', 'testuser', 0, 0, [$filesNode3]], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], @@ -714,7 +645,7 @@ class FilesReportPluginTest extends \Test\TestCase { ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '789'], ]; - $this->assertEquals([], array_values($this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); + $this->assertEquals([], array_values(self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); } public function testProcessFilterRulesInvisibleTagAsAdmin(): void { @@ -766,18 +697,17 @@ class FilesReportPluginTest extends \Test\TestCase { $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive(['OneTwoThree'], ['FourFiveSix']) - ->willReturnOnConsecutiveCalls( - [$filesNode1, $filesNode2], - [$filesNode2, $filesNode3], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1, $filesNode2]], + ['FourFiveSix', 'testuser', 0, 0, [$filesNode2, $filesNode3]], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->assertEquals([$filesNode2], array_values($this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); + $this->assertEquals([$filesNode2], array_values(self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); } @@ -816,7 +746,7 @@ class FilesReportPluginTest extends \Test\TestCase { ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]); + self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]); } public function testProcessFilterRulesVisibleTagAsUser(): void { @@ -881,18 +811,17 @@ class FilesReportPluginTest extends \Test\TestCase { // main assertion: only user visible tags are being passed through. $this->userFolder->expects($this->exactly(2)) ->method('searchBySystemTag') - ->withConsecutive(['OneTwoThree'], ['FourFiveSix']) - ->willReturnOnConsecutiveCalls( - [$filesNode1, $filesNode2], - [$filesNode2, $filesNode3], - ); + ->willReturnMap([ + ['OneTwoThree', 'testuser', 0, 0, [$filesNode1, $filesNode2]], + ['FourFiveSix', 'testuser', 0, 0, [$filesNode2, $filesNode3]], + ]); $rules = [ ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '123'], ['name' => '{http://owncloud.org/ns}systemtag', 'value' => '456'], ]; - $this->assertEquals([$filesNode2], array_values($this->invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); + $this->assertEquals([$filesNode2], array_values(self::invokePrivate($this->plugin, 'processFilterRulesForFileNodes', [$rules, null, null]))); } public function testProcessFavoriteFilter(): void { @@ -904,10 +833,10 @@ class FilesReportPluginTest extends \Test\TestCase { ->method('getFavorites') ->willReturn(['456', '789']); - $this->assertEquals(['456', '789'], array_values($this->invokePrivate($this->plugin, 'processFilterRulesForFileIDs', [$rules]))); + $this->assertEquals(['456', '789'], array_values(self::invokePrivate($this->plugin, 'processFilterRulesForFileIDs', [$rules]))); } - public function filesBaseUriProvider() { + public static function filesBaseUriProvider(): array { return [ ['', '', ''], ['files/username', '', '/files/username'], @@ -920,7 +849,7 @@ class FilesReportPluginTest extends \Test\TestCase { /** * @dataProvider filesBaseUriProvider */ - public function testFilesBaseUri($uri, $reportPath, $expectedUri): void { - $this->assertEquals($expectedUri, $this->invokePrivate($this->plugin, 'getFilesBaseUri', [$uri, $reportPath])); + public function testFilesBaseUri(string $uri, string $reportPath, string $expectedUri): void { + $this->assertEquals($expectedUri, self::invokePrivate($this->plugin, 'getFilesBaseUri', [$uri, $reportPath])); } } diff --git a/apps/dav/tests/unit/Connector/Sabre/MaintenancePluginTest.php b/apps/dav/tests/unit/Connector/Sabre/MaintenancePluginTest.php index 9ecc49222e9..bc1d50ac41f 100644 --- a/apps/dav/tests/unit/Connector/Sabre/MaintenancePluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/MaintenancePluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,6 +11,7 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre; use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCP\IConfig; use OCP\IL10N; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; /** @@ -18,18 +20,15 @@ use Test\TestCase; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class MaintenancePluginTest extends TestCase { - /** @var IConfig */ - private $config; - /** @var \PHPUnit\Framework\MockObject\Builder\InvocationMocker|\PHPUnit_Framework_MockObject_Builder_InvocationMocker|IL10N */ - private $l10n; - /** @var MaintenancePlugin */ - private $maintenancePlugin; + private IConfig&MockObject $config; + private IL10N&MockObject $l10n; + private MaintenancePlugin $maintenancePlugin; protected function setUp(): void { parent::setUp(); - $this->config = $this->getMockBuilder(IConfig::class)->getMock(); - $this->l10n = $this->getMockBuilder(IL10N::class)->getMock(); + $this->config = $this->createMock(IConfig::class); + $this->l10n = $this->createMock(IL10N::class); $this->maintenancePlugin = new MaintenancePlugin($this->config, $this->l10n); } diff --git a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php index 04cd60fbdaa..3dea5cf281b 100644 --- a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -32,7 +33,7 @@ use PHPUnit\Framework\MockObject\MockObject; * @package OCA\DAV\Tests\unit\Connector\Sabre */ class NodeTest extends \Test\TestCase { - public function davPermissionsProvider() { + public static function davPermissionsProvider(): array { return [ [Constants::PERMISSION_ALL, 'file', false, Constants::PERMISSION_ALL, false, 'test', 'RGDNVW'], [Constants::PERMISSION_ALL, 'dir', false, Constants::PERMISSION_ALL, false, 'test', 'RGDNVCK'], @@ -53,7 +54,7 @@ class NodeTest extends \Test\TestCase { /** * @dataProvider davPermissionsProvider */ - public function testDavPermissions($permissions, $type, $shared, $shareRootPermissions, $mounted, $internalPath, $expected): void { + public function testDavPermissions(int $permissions, string $type, bool $shared, int $shareRootPermissions, bool $mounted, string $internalPath, string $expected): void { $info = $this->getMockBuilder(FileInfo::class) ->disableOriginalConstructor() ->onlyMethods(['getPermissions', 'isShared', 'isMounted', 'getType', 'getInternalPath', 'getStorage', 'getMountPoint']) @@ -94,15 +95,13 @@ class NodeTest extends \Test\TestCase { } $info->method('getStorage') ->willReturn($storage); - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->createMock(View::class); $node = new File($view, $info); $this->assertEquals($expected, $node->getDavPermissions()); } - public function sharePermissionsProvider() { + public static function sharePermissionsProvider(): array { return [ [\OCP\Files\FileInfo::TYPE_FILE, null, 1, 1], [\OCP\Files\FileInfo::TYPE_FILE, null, 3, 3], @@ -145,18 +144,14 @@ class NodeTest extends \Test\TestCase { /** * @dataProvider sharePermissionsProvider */ - public function testSharePermissions($type, $user, $permissions, $expected): void { - $storage = $this->getMockBuilder(IStorage::class) - ->disableOriginalConstructor() - ->getMock(); + public function testSharePermissions(string $type, ?string $user, int $permissions, int $expected): void { + $storage = $this->createMock(IStorage::class); $storage->method('getPermissions')->willReturn($permissions); - $mountpoint = $this->getMockBuilder(IMountPoint::class) - ->disableOriginalConstructor() - ->getMock(); + $mountpoint = $this->createMock(IMountPoint::class); $mountpoint->method('getMountPoint')->willReturn('myPath'); - $shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); - $share = $this->getMockBuilder(IShare::class)->disableOriginalConstructor()->getMock(); + $shareManager = $this->createMock(IManager::class); + $share = $this->createMock(IShare::class); if ($user === null) { $shareManager->expects($this->never())->method('getShareByToken'); @@ -169,7 +164,7 @@ class NodeTest extends \Test\TestCase { $info = $this->getMockBuilder(FileInfo::class) ->disableOriginalConstructor() - ->setMethods(['getStorage', 'getType', 'getMountPoint', 'getPermissions']) + ->onlyMethods(['getStorage', 'getType', 'getMountPoint', 'getPermissions']) ->getMock(); $info->method('getStorage')->willReturn($storage); @@ -177,9 +172,7 @@ class NodeTest extends \Test\TestCase { $info->method('getMountPoint')->willReturn($mountpoint); $info->method('getPermissions')->willReturn($permissions); - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->createMock(View::class); $node = new File($view, $info); $this->invokePrivate($node, 'shareManager', [$shareManager]); @@ -189,11 +182,11 @@ class NodeTest extends \Test\TestCase { public function testShareAttributes(): void { $storage = $this->getMockBuilder(SharedStorage::class) ->disableOriginalConstructor() - ->setMethods(['getShare']) + ->onlyMethods(['getShare']) ->getMock(); - $shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); - $share = $this->getMockBuilder(IShare::class)->disableOriginalConstructor()->getMock(); + $shareManager = $this->createMock(IManager::class); + $share = $this->createMock(IShare::class); $storage->expects($this->once()) ->method('getShare') @@ -214,9 +207,7 @@ class NodeTest extends \Test\TestCase { $info->method('getType')->willReturn(FileInfo::TYPE_FOLDER); /** @var View&MockObject $view */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->createMock(View::class); $node = new File($view, $info); $this->invokePrivate($node, 'shareManager', [$shareManager]); @@ -224,11 +215,8 @@ class NodeTest extends \Test\TestCase { } public function testShareAttributesNonShare(): void { - $storage = $this->getMockBuilder(IStorage::class) - ->disableOriginalConstructor() - ->getMock(); - - $shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); + $storage = $this->createMock(IStorage::class); + $shareManager = $this->createMock(IManager::class); /** @var Folder&MockObject */ $info = $this->getMockBuilder(Folder::class) @@ -240,16 +228,14 @@ class NodeTest extends \Test\TestCase { $info->method('getType')->willReturn(FileInfo::TYPE_FOLDER); /** @var View&MockObject */ - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->createMock(View::class); $node = new File($view, $info); $this->invokePrivate($node, 'shareManager', [$shareManager]); $this->assertEquals([], $node->getShareAttributes()); } - public function sanitizeMtimeProvider() { + public static function sanitizeMtimeProvider(): array { return [ [123456789, 123456789], ['987654321', 987654321], @@ -259,7 +245,7 @@ class NodeTest extends \Test\TestCase { /** * @dataProvider sanitizeMtimeProvider */ - public function testSanitizeMtime($mtime, $expected): void { + public function testSanitizeMtime(string|int $mtime, int $expected): void { $view = $this->getMockBuilder(View::class) ->disableOriginalConstructor() ->getMock(); @@ -272,7 +258,7 @@ class NodeTest extends \Test\TestCase { $this->assertEquals($expected, $result); } - public function invalidSanitizeMtimeProvider() { + public static function invalidSanitizeMtimeProvider(): array { return [ [-1337], [0], ['abcdef'], ['-1337'], ['0'], [12321], [24 * 60 * 60 - 1], ]; @@ -281,17 +267,13 @@ class NodeTest extends \Test\TestCase { /** * @dataProvider invalidSanitizeMtimeProvider */ - public function testInvalidSanitizeMtime($mtime): void { + public function testInvalidSanitizeMtime(int|string $mtime): void { $this->expectException(\InvalidArgumentException::class); - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); - $info = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); + $view = $this->createMock(View::class); + $info = $this->createMock(FileInfo::class); $node = new File($view, $info); - $result = $this->invokePrivate($node, 'sanitizeMtime', [$mtime]); + self::invokePrivate($node, 'sanitizeMtime', [$mtime]); } } diff --git a/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php b/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php index 393f3c72c20..4a5937e365b 100644 --- a/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/ObjectTreeTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -27,7 +28,7 @@ use OCP\Files\Mount\IMountManager; * @package OCA\DAV\Tests\Unit\Connector\Sabre */ class ObjectTreeTest extends \Test\TestCase { - public function copyDataProvider() { + public static function copyDataProvider(): array { return [ // copy into same dir ['a', 'b', ''], @@ -41,7 +42,7 @@ class ObjectTreeTest extends \Test\TestCase { /** * @dataProvider copyDataProvider */ - public function testCopy($sourcePath, $targetPath, $targetParent): void { + public function testCopy(string $sourcePath, string $targetPath, string $targetParent): void { $view = $this->createMock(View::class); $view->expects($this->once()) ->method('verifyPath') @@ -67,7 +68,7 @@ class ObjectTreeTest extends \Test\TestCase { $rootDir = new Directory($view, $info); $objectTree = $this->getMockBuilder(ObjectTree::class) - ->setMethods(['nodeExists', 'getNodeForPath']) + ->onlyMethods(['nodeExists', 'getNodeForPath']) ->setConstructorArgs([$rootDir, $view]) ->getMock(); @@ -110,7 +111,7 @@ class ObjectTreeTest extends \Test\TestCase { $rootDir = new Directory($view, $info); $objectTree = $this->getMockBuilder(ObjectTree::class) - ->setMethods(['nodeExists', 'getNodeForPath']) + ->onlyMethods(['nodeExists', 'getNodeForPath']) ->setConstructorArgs([$rootDir, $view]) ->getMock(); @@ -127,23 +128,15 @@ class ObjectTreeTest extends \Test\TestCase { * @dataProvider nodeForPathProvider */ public function testGetNodeForPath( - $inputFileName, - $fileInfoQueryPath, - $outputFileName, - $type, + string $inputFileName, + string $fileInfoQueryPath, + string $outputFileName, + string $type, ): void { - $rootNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); - $mountManager = $this->getMockBuilder(Manager::class) - ->disableOriginalConstructor() - ->getMock(); - $view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); - $fileInfo = $this->getMockBuilder(FileInfo::class) - ->disableOriginalConstructor() - ->getMock(); + $rootNode = $this->createMock(Directory::class); + $mountManager = $this->createMock(Manager::class); + $view = $this->createMock(View::class); + $fileInfo = $this->createMock(FileInfo::class); $fileInfo->method('getType') ->willReturn($type); $fileInfo->method('getName') @@ -164,13 +157,13 @@ class ObjectTreeTest extends \Test\TestCase { $this->assertEquals($outputFileName, $node->getName()); if ($type === 'file') { - $this->assertTrue($node instanceof File); + $this->assertInstanceOf(File::class, $node); } else { - $this->assertTrue($node instanceof Directory); + $this->assertInstanceOf(Directory::class, $node); } } - public function nodeForPathProvider() { + public static function nodeForPathProvider(): array { return [ // regular file [ @@ -213,7 +206,7 @@ class ObjectTreeTest extends \Test\TestCase { $storage = new Temporary([]); $view = $this->getMockBuilder(View::class) - ->setMethods(['resolvePath']) + ->onlyMethods(['resolvePath']) ->getMock(); $view->expects($this->once()) ->method('resolvePath') @@ -221,9 +214,7 @@ class ObjectTreeTest extends \Test\TestCase { return [$storage, ltrim($path, '/')]; }); - $rootNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $rootNode = $this->createMock(Directory::class); $mountManager = $this->createMock(IMountManager::class); $tree = new ObjectTree(); @@ -239,7 +230,7 @@ class ObjectTreeTest extends \Test\TestCase { $storage = new Temporary([]); $view = $this->getMockBuilder(View::class) - ->setMethods(['resolvePath']) + ->onlyMethods(['resolvePath']) ->getMock(); $view->expects($this->any()) ->method('resolvePath') @@ -247,9 +238,7 @@ class ObjectTreeTest extends \Test\TestCase { return [$storage, ltrim($path, '/')]; }); - $rootNode = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $rootNode = $this->createMock(Directory::class); $mountManager = $this->createMock(IMountManager::class); $tree = new ObjectTree(); diff --git a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php index 30e2c995d18..087bbd66107 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -30,38 +32,21 @@ use Sabre\DAV\PropPatch; use Test\TestCase; class PrincipalTest extends TestCase { - /** @var IUserManager | MockObject */ - private $userManager; - - /** @var Principal */ - private $connector; - - /** @var IGroupManager | MockObject */ - private $groupManager; - - /** @var IAccountManager|MockObject */ - private $accountManager; - - /** @var IManager | MockObject */ - private $shareManager; - - /** @var IUserSession | MockObject */ - private $userSession; - - /** @var IAppManager | MockObject */ - private $appManager; - - /** @var ProxyMapper | MockObject */ - private $proxyMapper; - - /** @var KnownUserService|MockObject */ - private $knownUserService; - /** @var IConfig | MockObject */ - private $config; - /** @var IFactory|MockObject */ - private $languageFactory; + private IUserManager&MockObject $userManager; + private IGroupManager&MockObject $groupManager; + private IAccountManager&MockObject $accountManager; + private IManager&MockObject $shareManager; + private IUserSession&MockObject $userSession; + private IAppManager&MockObject $appManager; + private ProxyMapper&MockObject $proxyMapper; + private KnownUserService&MockObject $knownUserService; + private IConfig&MockObject $config; + private IFactory&MockObject $languageFactory; + private Principal $connector; protected function setUp(): void { + parent::setUp(); + $this->userManager = $this->createMock(IUserManager::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->accountManager = $this->createMock(IAccountManager::class); @@ -85,7 +70,6 @@ class PrincipalTest extends TestCase { $this->config, $this->languageFactory ); - parent::setUp(); } public function testGetPrincipalsByPrefixWithoutPrefix(): void { @@ -125,13 +109,14 @@ class PrincipalTest extends TestCase { $this->languageFactory ->expects($this->exactly(2)) ->method('getUserLanguage') - ->withConsecutive([$fooUser], [$barUser]) - ->willReturnOnConsecutiveCalls('de', 'en'); + ->willReturnMap([ + [$fooUser, 'de'], + [$barUser, 'en'], + ]); $fooAccountPropertyCollection = $this->createMock(IAccountPropertyCollection::class); $fooAccountPropertyCollection->expects($this->once()) ->method('getProperties') - ->with() ->willReturn([]); $fooAccount = $this->createMock(IAccount::class); $fooAccount->expects($this->once()) @@ -142,18 +127,15 @@ class PrincipalTest extends TestCase { $emailPropertyOne = $this->createMock(IAccountProperty::class); $emailPropertyOne->expects($this->once()) ->method('getValue') - ->with() ->willReturn('alias@nextcloud.com'); $emailPropertyTwo = $this->createMock(IAccountProperty::class); $emailPropertyTwo->expects($this->once()) ->method('getValue') - ->with() ->willReturn('alias2@nextcloud.com'); $barAccountPropertyCollection = $this->createMock(IAccountPropertyCollection::class); $barAccountPropertyCollection->expects($this->once()) ->method('getProperties') - ->with() ->willReturn([$emailPropertyOne, $emailPropertyTwo]); $barAccount = $this->createMock(IAccount::class); $barAccount->expects($this->once()) @@ -164,8 +146,10 @@ class PrincipalTest extends TestCase { $this->accountManager ->expects($this->exactly(2)) ->method('getAccount') - ->withConsecutive([$fooUser], [$barUser]) - ->willReturnOnConsecutiveCalls($fooAccount, $barAccount); + ->willReturnMap([ + [$fooUser, $fooAccount], + [$barUser, $barAccount], + ]); $expectedResponse = [ 0 => [ @@ -482,7 +466,7 @@ class PrincipalTest extends TestCase { /** * @dataProvider searchPrincipalsDataProvider */ - public function testSearchPrincipals($sharingEnabled, $groupsOnly, $test, $result): void { + public function testSearchPrincipals(bool $sharingEnabled, bool $groupsOnly, string $test, array $result): void { $this->shareManager->expects($this->once()) ->method('shareAPIEnabled') ->willReturn($sharingEnabled); @@ -556,7 +540,7 @@ class PrincipalTest extends TestCase { '{DAV:}displayname' => 'User 12'], $test)); } - public function searchPrincipalsDataProvider(): array { + public static function searchPrincipalsDataProvider(): array { return [ [true, false, 'allof', ['principals/users/user3']], [true, false, 'anyof', ['principals/users/user2', 'principals/users/user3', 'principals/users/user4']], @@ -845,7 +829,7 @@ class PrincipalTest extends TestCase { /** * @dataProvider findByUriWithGroupRestrictionDataProvider */ - public function testFindByUriWithGroupRestriction($uri, $email, $expects): void { + public function testFindByUriWithGroupRestriction(string $uri, string $email, ?string $expects): void { $this->shareManager->expects($this->once()) ->method('shareApiEnabled') ->willReturn(true); @@ -872,31 +856,23 @@ class PrincipalTest extends TestCase { if ($email === 'user2@foo.bar') { $this->groupManager->expects($this->exactly(2)) ->method('getUserGroupIds') - ->withConsecutive( - [$user], - [$user2], - ) - ->willReturnOnConsecutiveCalls( - ['group1', 'group2'], - ['group1', 'group3'], - ); + ->willReturnMap([ + [$user, ['group1', 'group2']], + [$user2, ['group1', 'group3']], + ]); } else { $this->groupManager->expects($this->exactly(2)) ->method('getUserGroupIds') - ->withConsecutive( - [$user], - [$user3], - ) - ->willReturnOnConsecutiveCalls( - ['group1', 'group2'], - ['group3', 'group3'], - ); + ->willReturnMap([ + [$user, ['group1', 'group2']], + [$user3, ['group3', 'group3']], + ]); } $this->assertEquals($expects, $this->connector->findByUri($uri, 'principals/users')); } - public function findByUriWithGroupRestrictionDataProvider(): array { + public static function findByUriWithGroupRestrictionDataProvider(): array { return [ ['mailto:user2@foo.bar', 'user2@foo.bar', 'principals/users/user2'], ['mailto:user3@foo.bar', 'user3@foo.bar', null], @@ -906,7 +882,7 @@ class PrincipalTest extends TestCase { /** * @dataProvider findByUriWithoutGroupRestrictionDataProvider */ - public function testFindByUriWithoutGroupRestriction($uri, $email, $expects): void { + public function testFindByUriWithoutGroupRestriction(string $uri, string $email, string $expects): void { $this->shareManager->expects($this->once()) ->method('shareApiEnabled') ->willReturn(true); @@ -928,7 +904,7 @@ class PrincipalTest extends TestCase { $this->assertEquals($expects, $this->connector->findByUri($uri, 'principals/users')); } - public function findByUriWithoutGroupRestrictionDataProvider(): array { + public static function findByUriWithoutGroupRestrictionDataProvider(): array { return [ ['mailto:user2@foo.bar', 'user2@foo.bar', 'principals/users/user2'], ['mailto:user3@foo.bar', 'user3@foo.bar', 'principals/users/user3'], diff --git a/apps/dav/tests/unit/Connector/Sabre/PropfindCompressionPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/PropfindCompressionPluginTest.php index 42414ad6efb..e6f696ed160 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PropfindCompressionPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PropfindCompressionPluginTest.php @@ -14,8 +14,7 @@ use Sabre\HTTP\Response; use Test\TestCase; class PropfindCompressionPluginTest extends TestCase { - /** @var PropfindCompressionPlugin */ - private $plugin; + private PropfindCompressionPlugin $plugin; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php b/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php index 67e7f6af675..2340890ae5a 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -30,12 +31,12 @@ class PublicAuthTest extends \Test\TestCase { private ISession&MockObject $session; private IRequest&MockObject $request; private IManager&MockObject $shareManager; - private PublicAuth $auth; private IThrottler&MockObject $throttler; private LoggerInterface&MockObject $logger; private IURLGenerator&MockObject $urlGenerator; + private PublicAuth $auth; - private string $oldUser; + private bool|string $oldUser; protected function setUp(): void { parent::setUp(); @@ -65,7 +66,9 @@ class PublicAuthTest extends \Test\TestCase { // Set old user \OC_User::setUserId($this->oldUser); - \OC_Util::setupFS($this->oldUser); + if ($this->oldUser !== false) { + \OC_Util::setupFS($this->oldUser); + } parent::tearDown(); } @@ -74,7 +77,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $result = $this->invokePrivate($this->auth, 'getToken'); + $result = self::invokePrivate($this->auth, 'getToken'); $this->assertSame('GX9HSGQrGE', $result); } @@ -84,16 +87,14 @@ class PublicAuthTest extends \Test\TestCase { ->willReturn('/dav/files'); $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $this->invokePrivate($this->auth, 'getToken'); + self::invokePrivate($this->auth, 'getToken'); } public function testCheckTokenValidShare(): void { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn(null); $this->shareManager->expects($this->once()) @@ -101,7 +102,7 @@ class PublicAuthTest extends \Test\TestCase { ->with('GX9HSGQrGE') ->willReturn($share); - $result = $this->invokePrivate($this->auth, 'checkToken'); + $result = self::invokePrivate($this->auth, 'checkToken'); $this->assertSame([true, 'principals/GX9HSGQrGE'], $result); } @@ -116,16 +117,14 @@ class PublicAuthTest extends \Test\TestCase { ->will($this->throwException(new ShareNotFound())); $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $this->invokePrivate($this->auth, 'checkToken'); + self::invokePrivate($this->auth, 'checkToken'); } public function testCheckTokenAlreadyAuthenticated(): void { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getShareType')->willReturn(42); $this->shareManager->expects($this->once()) @@ -136,7 +135,7 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); $this->session->method('get')->with('public_link_authenticated')->willReturn('42'); - $result = $this->invokePrivate($this->auth, 'checkToken'); + $result = self::invokePrivate($this->auth, 'checkToken'); $this->assertSame([true, 'principals/GX9HSGQrGE'], $result); } @@ -144,9 +143,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(42); @@ -158,16 +155,14 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('exists')->with('public_link_authenticated')->willReturn(false); $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class); - $this->invokePrivate($this->auth, 'checkToken'); + self::invokePrivate($this->auth, 'checkToken'); } public function testCheckTokenPasswordAuthenticatedWrongShare(): void { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(42); @@ -180,7 +175,7 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('get')->with('public_link_authenticated')->willReturn('43'); $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class); - $this->invokePrivate($this->auth, 'checkToken'); + self::invokePrivate($this->auth, 'checkToken'); } public function testNoShare(): void { @@ -192,7 +187,7 @@ class PublicAuthTest extends \Test\TestCase { ->with('GX9HSGQrGE') ->willThrowException(new ShareNotFound()); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertFalse($result); } @@ -201,9 +196,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn(null); $this->shareManager->expects($this->once()) @@ -211,7 +204,7 @@ class PublicAuthTest extends \Test\TestCase { ->with('GX9HSGQrGE') ->willReturn($share); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertTrue($result); } @@ -220,9 +213,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(42); @@ -231,7 +222,7 @@ class PublicAuthTest extends \Test\TestCase { ->with('GX9HSGQrGE') ->willReturn($share); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertFalse($result); } @@ -241,9 +232,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_REMOTE); @@ -252,7 +241,7 @@ class PublicAuthTest extends \Test\TestCase { ->with('GX9HSGQrGE') ->willReturn($share); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertTrue($result); } @@ -261,9 +250,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); @@ -278,7 +265,7 @@ class PublicAuthTest extends \Test\TestCase { $this->equalTo('password') )->willReturn(true); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertTrue($result); } @@ -287,9 +274,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL); @@ -304,7 +289,7 @@ class PublicAuthTest extends \Test\TestCase { $this->equalTo('password') )->willReturn(true); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertTrue($result); } @@ -313,9 +298,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); $share->method('getId')->willReturn('42'); @@ -335,7 +318,7 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); $this->session->method('get')->with('public_link_authenticated')->willReturn('42'); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertTrue($result); } @@ -344,9 +327,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_LINK); $share->method('getId')->willReturn('42'); @@ -366,7 +347,7 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); $this->session->method('get')->with('public_link_authenticated')->willReturn('43'); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertFalse($result); } @@ -376,9 +357,7 @@ class PublicAuthTest extends \Test\TestCase { $this->request->method('getPathInfo') ->willReturn('/dav/files/GX9HSGQrGE'); - $share = $this->getMockBuilder(IShare::class) - ->disableOriginalConstructor() - ->getMock(); + $share = $this->createMock(IShare::class); $share->method('getPassword')->willReturn('password'); $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL); $share->method('getId')->willReturn('42'); @@ -398,7 +377,7 @@ class PublicAuthTest extends \Test\TestCase { $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); $this->session->method('get')->with('public_link_authenticated')->willReturn('43'); - $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); + $result = self::invokePrivate($this->auth, 'validateUserPass', ['username', 'password']); $this->assertFalse($result); } diff --git a/apps/dav/tests/unit/Connector/Sabre/QuotaPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/QuotaPluginTest.php index c370e0fb0f7..a78a1a223c5 100644 --- a/apps/dav/tests/unit/Connector/Sabre/QuotaPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/QuotaPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2013-2016 ownCloud, Inc. @@ -13,29 +14,23 @@ use OCP\Files\FileInfo; use Test\TestCase; class QuotaPluginTest extends TestCase { - /** @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject */ - private $server; + private \Sabre\DAV\Server $server; - /** @var QuotaPlugin|\PHPUnit\Framework\MockObject\MockObject */ - private $plugin; + private QuotaPlugin $plugin; - private function init($quota, $checkedPath = ''): void { - $view = $this->buildFileViewMock($quota, $checkedPath); + private function init(int $quota, string $checkedPath = ''): void { + $view = $this->buildFileViewMock((string)$quota, $checkedPath); $this->server = new \Sabre\DAV\Server(); - $this->plugin = $this->getMockBuilder(QuotaPlugin::class) - ->setConstructorArgs([$view]) - ->setMethods(['getFileChunking']) - ->getMock(); + $this->plugin = new QuotaPlugin($view); $this->plugin->initialize($this->server); } /** * @dataProvider lengthProvider */ - public function testLength($expected, $headers): void { + public function testLength(?int $expected, array $headers): void { $this->init(0); - $this->plugin->expects($this->never()) - ->method('getFileChunking'); + $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers); $length = $this->plugin->getLength(); $this->assertEquals($expected, $length); @@ -44,10 +39,8 @@ class QuotaPluginTest extends TestCase { /** * @dataProvider quotaOkayProvider */ - public function testCheckQuota($quota, $headers): void { + public function testCheckQuota(int $quota, array $headers): void { $this->init($quota); - $this->plugin->expects($this->never()) - ->method('getFileChunking'); $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers); $result = $this->plugin->checkQuota(''); @@ -57,12 +50,10 @@ class QuotaPluginTest extends TestCase { /** * @dataProvider quotaExceededProvider */ - public function testCheckExceededQuota($quota, $headers): void { + public function testCheckExceededQuota(int $quota, array $headers): void { $this->expectException(\Sabre\DAV\Exception\InsufficientStorage::class); $this->init($quota); - $this->plugin->expects($this->never()) - ->method('getFileChunking'); $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers); $this->plugin->checkQuota(''); @@ -71,17 +62,15 @@ class QuotaPluginTest extends TestCase { /** * @dataProvider quotaOkayProvider */ - public function testCheckQuotaOnPath($quota, $headers): void { + public function testCheckQuotaOnPath(int $quota, array $headers): void { $this->init($quota, 'sub/test.txt'); - $this->plugin->expects($this->never()) - ->method('getFileChunking'); $this->server->httpRequest = new \Sabre\HTTP\Request('POST', 'dummy.file', $headers); $result = $this->plugin->checkQuota('/sub/test.txt'); $this->assertTrue($result); } - public function quotaOkayProvider() { + public static function quotaOkayProvider(): array { return [ [1024, []], [1024, ['X-EXPECTED-ENTITY-LENGTH' => '1024']], @@ -100,7 +89,7 @@ class QuotaPluginTest extends TestCase { ]; } - public function quotaExceededProvider() { + public static function quotaExceededProvider(): array { return [ [1023, ['X-EXPECTED-ENTITY-LENGTH' => '1024']], [511, ['CONTENT-LENGTH' => '512']], @@ -108,7 +97,7 @@ class QuotaPluginTest extends TestCase { ]; } - public function lengthProvider() { + public static function lengthProvider(): array { return [ [null, []], [1024, ['X-EXPECTED-ENTITY-LENGTH' => '1024']], @@ -124,7 +113,7 @@ class QuotaPluginTest extends TestCase { ]; } - public function quotaChunkedOkProvider() { + public static function quotaChunkedOkProvider(): array { return [ [1024, 0, ['X-EXPECTED-ENTITY-LENGTH' => '1024']], [1024, 0, ['CONTENT-LENGTH' => '512']], @@ -143,7 +132,7 @@ class QuotaPluginTest extends TestCase { ]; } - public function quotaChunkedFailProvider() { + public static function quotaChunkedFailProvider(): array { return [ [400, 0, ['X-EXPECTED-ENTITY-LENGTH' => '1024']], [400, 0, ['CONTENT-LENGTH' => '512']], @@ -155,15 +144,15 @@ class QuotaPluginTest extends TestCase { ]; } - private function buildFileViewMock($quota, $checkedPath) { - // mock filesysten + private function buildFileViewMock(string $quota, string $checkedPath): View { + // mock filesystem $view = $this->getMockBuilder(View::class) - ->setMethods(['free_space']) + ->onlyMethods(['free_space']) ->disableOriginalConstructor() ->getMock(); $view->expects($this->any()) ->method('free_space') - ->with($this->identicalTo($checkedPath)) + ->with($checkedPath) ->willReturn($quota); return $view; diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/Auth.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/Auth.php index 836766b366d..b01807d5bbb 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/Auth.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/Auth.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/DeleteTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/DeleteTest.php index e7f20fbadfa..c5c7e99c7e5 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/DeleteTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/DeleteTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,7 +19,7 @@ use OCP\AppFramework\Http; */ class DeleteTest extends RequestTestCase { public function testBasicUpload(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'asd'); @@ -29,7 +30,7 @@ class DeleteTest extends RequestTestCase { $mount->getStorage()->unlink($mount->getInternalPath($internalPath)); // cache entry still exists - $this->assertInstanceOf('\OCP\Files\FileInfo', $view->getFileInfo('foo.txt')); + $this->assertInstanceOf(\OCP\Files\FileInfo::class, $view->getFileInfo('foo.txt')); $response = $this->request($view, $user, 'pass', 'DELETE', '/foo.txt'); diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/DownloadTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/DownloadTest.php index bec4cd9967b..34171963ef0 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/DownloadTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/DownloadTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -19,7 +20,7 @@ use OCP\Lock\ILockingProvider; */ class DownloadTest extends RequestTestCase { public function testDownload(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'bar'); @@ -30,7 +31,7 @@ class DownloadTest extends RequestTestCase { } public function testDownloadWriteLocked(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'bar'); @@ -42,7 +43,7 @@ class DownloadTest extends RequestTestCase { } public function testDownloadReadLocked(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'bar'); diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionMasterKeyUploadTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionMasterKeyUploadTest.php index 92d89d7753a..615490ddc92 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionMasterKeyUploadTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionMasterKeyUploadTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -23,7 +24,7 @@ use Test\Traits\EncryptionTrait; class EncryptionMasterKeyUploadTest extends UploadTest { use EncryptionTrait; - protected function setupUser($name, $password) { + protected function setupUser($name, $password): View { $this->createUser($name, $password); $tmpFolder = Server::get(ITempManager::class)->getTemporaryFolder(); $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionUploadTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionUploadTest.php index 935ef6d9464..efa7bb54cf8 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionUploadTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/EncryptionUploadTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -23,7 +24,7 @@ use Test\Traits\EncryptionTrait; class EncryptionUploadTest extends UploadTest { use EncryptionTrait; - protected function setupUser($name, $password) { + protected function setupUser($name, $password): View { $this->createUser($name, $password); $tmpFolder = Server::get(ITempManager::class)->getTemporaryFolder(); $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/ExceptionPlugin.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/ExceptionPlugin.php index b1e68f9597b..0c53e4b1009 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/ExceptionPlugin.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/ExceptionPlugin.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/PartFileInRootUploadTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/PartFileInRootUploadTest.php index 5f3dc6f4e32..e6fa489fb24 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/PartFileInRootUploadTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/PartFileInRootUploadTest.php @@ -21,9 +21,7 @@ use OCP\Server; class PartFileInRootUploadTest extends UploadTest { protected function setUp(): void { $config = Server::get(IConfig::class); - $mockConfig = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor() - ->getMock(); + $mockConfig = $this->createMock(IConfig::class); $mockConfig->expects($this->any()) ->method('getSystemValue') ->willReturnCallback(function ($key, $default) use ($config) { diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php index d02f1d76cac..404dc7fa5d7 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/RequestTestCase.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -20,6 +21,7 @@ use OCP\IRequestId; use OCP\ITagManager; use OCP\ITempManager; use OCP\IUserSession; +use OCP\L10N\IFactory; use Psr\Log\LoggerInterface; use Sabre\HTTP\Request; use Test\TestCase; @@ -29,11 +31,7 @@ use Test\Traits\UserTrait; abstract class RequestTestCase extends TestCase { use UserTrait; use MountProviderTrait; - - /** - * @var ServerFactory - */ - protected $serverFactory; + protected ServerFactory $serverFactory; protected function getStream($string) { $stream = fopen('php://temp', 'r+'); @@ -52,20 +50,18 @@ abstract class RequestTestCase extends TestCase { \OCP\Server::get(IUserSession::class), \OCP\Server::get(IMountManager::class), \OCP\Server::get(ITagManager::class), - $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor() - ->getMock(), + $this->createMock(IRequest::class), \OCP\Server::get(IPreview::class), \OCP\Server::get(IEventDispatcher::class), - \OC::$server->getL10N('dav') + \OCP\Server::get(IFactory::class)->get('dav'), ); } - protected function setupUser($name, $password) { + protected function setupUser($name, $password): View { $this->createUser($name, $password); $tmpFolder = \OCP\Server::get(ITempManager::class)->getTemporaryFolder(); $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]); - $this->loginAsUser($name); + self::loginAsUser($name); return new View('/' . $name . '/files'); } diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/Sapi.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/Sapi.php index f12c93468ff..08d774e56b8 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/Sapi.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/Sapi.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/dav/tests/unit/Connector/Sabre/RequestTest/UploadTest.php b/apps/dav/tests/unit/Connector/Sabre/RequestTest/UploadTest.php index 60decd4c846..5c6d0f03334 100644 --- a/apps/dav/tests/unit/Connector/Sabre/RequestTest/UploadTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/RequestTest/UploadTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -19,7 +20,7 @@ use OCP\Lock\ILockingProvider; */ class UploadTest extends RequestTestCase { public function testBasicUpload(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $this->assertFalse($view->file_exists('foo.txt')); @@ -35,7 +36,7 @@ class UploadTest extends RequestTestCase { } public function testUploadOverWrite(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'foobar'); @@ -51,7 +52,7 @@ class UploadTest extends RequestTestCase { } public function testUploadOverWriteReadLocked(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $view->file_put_contents('foo.txt', 'bar'); @@ -63,7 +64,7 @@ class UploadTest extends RequestTestCase { } public function testUploadOverWriteWriteLocked(): void { - $user = $this->getUniqueID(); + $user = self::getUniqueID(); $view = $this->setupUser($user, 'pass'); $this->loginAsUser($user); diff --git a/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php index 97d3ba79046..00ac5b5543f 100644 --- a/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/SharesPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -17,35 +18,17 @@ use OCP\IUser; use OCP\IUserSession; use OCP\Share\IManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Tree; class SharesPluginTest extends \Test\TestCase { public const SHARETYPES_PROPERTYNAME = SharesPlugin::SHARETYPES_PROPERTYNAME; - /** - * @var \Sabre\DAV\Server - */ - private $server; - - /** - * @var \Sabre\DAV\Tree - */ - private $tree; - - /** - * @var \OCP\Share\IManager - */ - private $shareManager; - - /** - * @var Folder - */ - private $userFolder; - - /** - * @var SharesPlugin - */ - private $plugin; + private \Sabre\DAV\Server $server; + private \Sabre\DAV\Tree&MockObject $tree; + private \OCP\Share\IManager&MockObject $shareManager; + private Folder&MockObject $userFolder; + private SharesPlugin $plugin; protected function setUp(): void { parent::setUp(); @@ -74,10 +57,8 @@ class SharesPluginTest extends \Test\TestCase { /** * @dataProvider sharesGetPropertiesDataProvider */ - public function testGetProperties($shareTypes): void { - $sabreNode = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + public function testGetProperties(array $shareTypes): void { + $sabreNode = $this->createMock(Node::class); $sabreNode->expects($this->any()) ->method('getId') ->willReturn(123); @@ -86,9 +67,7 @@ class SharesPluginTest extends \Test\TestCase { ->willReturn('/subdir'); // node API nodes - $node = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Folder::class); $sabreNode->method('getNode') ->willReturn($node); @@ -143,7 +122,7 @@ class SharesPluginTest extends \Test\TestCase { /** * @dataProvider sharesGetPropertiesDataProvider */ - public function testPreloadThenGetProperties($shareTypes): void { + public function testPreloadThenGetProperties(array $shareTypes): void { $sabreNode1 = $this->createMock(File::class); $sabreNode1->method('getId') ->willReturn(111); @@ -182,7 +161,7 @@ class SharesPluginTest extends \Test\TestCase { ->willReturn($node2); $dummyShares = array_map(function ($type) { - $share = $this->getMockBuilder(IShare::class)->getMock(); + $share = $this->createMock(IShare::class); $share->expects($this->any()) ->method('getShareType') ->willReturn($type); @@ -268,7 +247,7 @@ class SharesPluginTest extends \Test\TestCase { $this->assertEquals($shareTypes, $result[200][self::SHARETYPES_PROPERTYNAME]->getShareTypes()); } - public function sharesGetPropertiesDataProvider() { + public static function sharesGetPropertiesDataProvider(): array { return [ [[]], [[IShare::TYPE_USER]], @@ -287,9 +266,7 @@ class SharesPluginTest extends \Test\TestCase { } public function testGetPropertiesSkipChunks(): void { - $sabreNode = $this->getMockBuilder(UploadFile::class) - ->disableOriginalConstructor() - ->getMock(); + $sabreNode = $this->createMock(UploadFile::class); $propFind = new \Sabre\DAV\PropFind( '/dummyPath', diff --git a/apps/dav/tests/unit/Connector/Sabre/TagsPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/TagsPluginTest.php index 43c08a1a61c..bef508e08ca 100644 --- a/apps/dav/tests/unit/Connector/Sabre/TagsPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/TagsPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2014-2016 ownCloud, Inc. @@ -18,6 +19,7 @@ use OCP\ITagManager; use OCP\ITags; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Tree; class TagsPluginTest extends \Test\TestCase { @@ -25,61 +27,24 @@ class TagsPluginTest extends \Test\TestCase { public const FAVORITE_PROPERTYNAME = TagsPlugin::FAVORITE_PROPERTYNAME; public const TAG_FAVORITE = TagsPlugin::TAG_FAVORITE; - /** - * @var \Sabre\DAV\Server - */ - private $server; - - /** - * @var Tree - */ - private $tree; - - /** - * @var ITagManager - */ - private $tagManager; - - /** - * @var ITags - */ - private $tagger; - - /** - * @var IEventDispatcher - */ - private $eventDispatcher; - - /** - * @var IUserSession - */ - private $userSession; - - /** - * @var TagsPlugin - */ - private $plugin; + private \Sabre\DAV\Server $server; + private Tree&MockObject $tree; + private ITagManager&MockObject $tagManager; + private ITags&MockObject $tagger; + private IEventDispatcher&MockObject $eventDispatcher; + private IUserSession&MockObject $userSession; + private TagsPlugin $plugin; protected function setUp(): void { parent::setUp(); + $this->server = new \Sabre\DAV\Server(); - $this->tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tagger = $this->getMockBuilder(ITags::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tagManager = $this->getMockBuilder(ITagManager::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->eventDispatcher = $this->getMockBuilder(IEventDispatcher::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tree = $this->createMock(Tree::class); + $this->tagger = $this->createMock(ITags::class); + $this->tagManager = $this->createMock(ITagManager::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $user = $this->createMock(IUser::class); - /** - * @var IUserSession - */ + $this->userSession = $this->createMock(IUserSession::class); $this->userSession->expects($this->any()) ->method('getUser') @@ -96,10 +61,8 @@ class TagsPluginTest extends \Test\TestCase { /** * @dataProvider tagsGetPropertiesDataProvider */ - public function testGetProperties($tags, $requestedProperties, $expectedProperties): void { - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + public function testGetProperties(array $tags, array $requestedProperties, array $expectedProperties): void { + $node = $this->createMock(Node::class); $node->expects($this->any()) ->method('getId') ->willReturn(123); @@ -135,16 +98,12 @@ class TagsPluginTest extends \Test\TestCase { /** * @dataProvider tagsGetPropertiesDataProvider */ - public function testPreloadThenGetProperties($tags, $requestedProperties, $expectedProperties): void { - $node1 = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + public function testPreloadThenGetProperties(array $tags, array $requestedProperties, array $expectedProperties): void { + $node1 = $this->createMock(File::class); $node1->expects($this->any()) ->method('getId') ->willReturn(111); - $node2 = $this->getMockBuilder(File::class) - ->disableOriginalConstructor() - ->getMock(); + $node2 = $this->createMock(File::class); $node2->expects($this->any()) ->method('getId') ->willReturn(222); @@ -157,9 +116,7 @@ class TagsPluginTest extends \Test\TestCase { $expectedCallCount = 1; } - $node = $this->getMockBuilder(Directory::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Directory::class); $node->expects($this->any()) ->method('getId') ->willReturn(123); @@ -214,7 +171,7 @@ class TagsPluginTest extends \Test\TestCase { $this->assertEquals($expectedProperties, $result); } - public function tagsGetPropertiesDataProvider() { + public static function tagsGetPropertiesDataProvider(): array { return [ // request both, receive both [ @@ -270,9 +227,7 @@ class TagsPluginTest extends \Test\TestCase { } public function testGetPropertiesSkipChunks(): void { - $sabreNode = $this->getMockBuilder(UploadFile::class) - ->disableOriginalConstructor() - ->getMock(); + $sabreNode = $this->createMock(UploadFile::class); $propFind = new \Sabre\DAV\PropFind( '/dummyPath', @@ -292,9 +247,7 @@ class TagsPluginTest extends \Test\TestCase { public function testUpdateTags(): void { // this test will replace the existing tags "tagremove" with "tag1" and "tag2" // and keep "tagkeep" - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->any()) ->method('getId') ->willReturn(123); @@ -310,12 +263,16 @@ class TagsPluginTest extends \Test\TestCase { ->willReturn([123 => ['tagkeep', 'tagremove', self::TAG_FAVORITE]]); // then tag as tag1 and tag2 - $this->tagger->expects($this->exactly(2)) + $calls = [ + [123, 'tag1'], + [123, 'tag2'], + ]; + $this->tagger->expects($this->exactly(count($calls))) ->method('tagAs') - ->withConsecutive( - [123, 'tag1'], - [123, 'tag2'], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); // it will untag tag3 $this->tagger->expects($this->once()) @@ -339,13 +296,11 @@ class TagsPluginTest extends \Test\TestCase { $result = $propPatch->getResult(); $this->assertEquals(200, $result[self::TAGS_PROPERTYNAME]); - $this->assertFalse(isset($result[self::FAVORITE_PROPERTYNAME])); + $this->assertArrayNotHasKey(self::FAVORITE_PROPERTYNAME, $result); } public function testUpdateTagsFromScratch(): void { - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->any()) ->method('getId') ->willReturn(123); @@ -361,12 +316,16 @@ class TagsPluginTest extends \Test\TestCase { ->willReturn([]); // then tag as tag1 and tag2 - $this->tagger->expects($this->exactly(2)) + $calls = [ + [123, 'tag1'], + [123, 'tag2'], + ]; + $this->tagger->expects($this->exactly(count($calls))) ->method('tagAs') - ->withConsecutive( - [123, 'tag1'], - [123, 'tag2'], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); // properties to set $propPatch = new \Sabre\DAV\PropPatch([ @@ -385,15 +344,13 @@ class TagsPluginTest extends \Test\TestCase { $result = $propPatch->getResult(); $this->assertEquals(200, $result[self::TAGS_PROPERTYNAME]); - $this->assertFalse(false, isset($result[self::FAVORITE_PROPERTYNAME])); + $this->assertArrayNotHasKey(self::FAVORITE_PROPERTYNAME, $result); } public function testUpdateFav(): void { // this test will replace the existing tags "tagremove" with "tag1" and "tag2" // and keep "tagkeep" - $node = $this->getMockBuilder(Node::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->any()) ->method('getId') ->willReturn(123); @@ -424,8 +381,8 @@ class TagsPluginTest extends \Test\TestCase { $this->assertEmpty($propPatch->getRemainingMutations()); $result = $propPatch->getResult(); - $this->assertFalse(false, isset($result[self::TAGS_PROPERTYNAME])); - $this->assertEquals(200, isset($result[self::FAVORITE_PROPERTYNAME])); + $this->assertArrayNotHasKey(self::TAGS_PROPERTYNAME, $result); + $this->assertEquals(200, $result[self::FAVORITE_PROPERTYNAME]); // unfavorite now // set favorite tag @@ -449,7 +406,7 @@ class TagsPluginTest extends \Test\TestCase { $this->assertEmpty($propPatch->getRemainingMutations()); $result = $propPatch->getResult(); - $this->assertFalse(false, isset($result[self::TAGS_PROPERTYNAME])); - $this->assertEquals(200, isset($result[self::FAVORITE_PROPERTYNAME])); + $this->assertArrayNotHasKey(self::TAGS_PROPERTYNAME, $result); + $this->assertEquals(200, $result[self::FAVORITE_PROPERTYNAME]); } } diff --git a/apps/dav/tests/unit/Controller/BirthdayCalendarControllerTest.php b/apps/dav/tests/unit/Controller/BirthdayCalendarControllerTest.php index c7c2bf0e431..9aa0ef3a2a7 100644 --- a/apps/dav/tests/unit/Controller/BirthdayCalendarControllerTest.php +++ b/apps/dav/tests/unit/Controller/BirthdayCalendarControllerTest.php @@ -1,43 +1,33 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Controller; +namespace OCA\DAV\Tests\unit\DAV\Controller; use OCA\DAV\BackgroundJob\GenerateBirthdayCalendarBackgroundJob; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Controller\BirthdayCalendarController; +use OCP\AppFramework\Http\JSONResponse; use OCP\BackgroundJob\IJobList; use OCP\IConfig; use OCP\IDBConnection; use OCP\IRequest; use OCP\IUser; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class BirthdayCalendarControllerTest extends TestCase { - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - private $db; - - /** @var IJobList|\PHPUnit\Framework\MockObject\MockObject */ - private $jobList; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - - /** @var CalDavBackend|\PHPUnit\Framework\MockObject\MockObject */ - private $caldav; - - /** @var BirthdayCalendarController|\PHPUnit\Framework\MockObject\MockObject */ - private $controller; + private IConfig&MockObject $config; + private IRequest&MockObject $request; + private IDBConnection&MockObject $db; + private IJobList&MockObject $jobList; + private IUserManager&MockObject $userManager; + private CalDavBackend&MockObject $caldav; + private BirthdayCalendarController $controller; protected function setUp(): void { parent::setUp(); @@ -74,16 +64,20 @@ class BirthdayCalendarControllerTest extends TestCase { $closure($user3); }); + $calls = [ + [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid1']], + [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid2']], + [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid3']], + ]; $this->jobList->expects($this->exactly(3)) ->method('add') - ->withConsecutive( - [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid1']], - [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid2']], - [GenerateBirthdayCalendarBackgroundJob::class, ['userId' => 'uid3']], - ); + ->willReturnCallback(function () use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $response = $this->controller->enable(); - $this->assertInstanceOf('OCP\AppFramework\Http\JSONResponse', $response); + $this->assertInstanceOf(JSONResponse::class, $response); } public function testDisable(): void { @@ -97,6 +91,6 @@ class BirthdayCalendarControllerTest extends TestCase { ->method('deleteAllBirthdayCalendars'); $response = $this->controller->disable(); - $this->assertInstanceOf('OCP\AppFramework\Http\JSONResponse', $response); + $this->assertInstanceOf(JSONResponse::class, $response); } } diff --git a/apps/dav/tests/unit/Controller/DirectControllerTest.php b/apps/dav/tests/unit/Controller/DirectControllerTest.php index faaf67d266b..837adde1da7 100644 --- a/apps/dav/tests/unit/Controller/DirectControllerTest.php +++ b/apps/dav/tests/unit/Controller/DirectControllerTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Controller; +namespace OCA\DAV\Tests\unit\DAV\Controller; use OCA\DAV\Controller\DirectController; use OCA\DAV\Db\Direct; @@ -20,29 +20,18 @@ use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\IRequest; -use OCP\IUrlGenerator; +use OCP\IURLGenerator; use OCP\Security\ISecureRandom; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class DirectControllerTest extends TestCase { - - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var DirectMapper|\PHPUnit\Framework\MockObject\MockObject */ - private $directMapper; - - /** @var ISecureRandom|\PHPUnit\Framework\MockObject\MockObject */ - private $random; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var IUrlGenerator|\PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ - private $eventDispatcher; + private IRootFolder&MockObject $rootFolder; + private DirectMapper&MockObject $directMapper; + private ISecureRandom&MockObject $random; + private ITimeFactory&MockObject $timeFactory; + private IURLGenerator&MockObject $urlGenerator; + private IEventDispatcher&MockObject $eventDispatcher; private DirectController $controller; @@ -53,7 +42,7 @@ class DirectControllerTest extends TestCase { $this->directMapper = $this->createMock(DirectMapper::class); $this->random = $this->createMock(ISecureRandom::class); $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->urlGenerator = $this->createMock(IUrlGenerator::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->controller = new DirectController( diff --git a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php index 640c66b75e5..895a84b8404 100644 --- a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php +++ b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Controller; +namespace OCA\DAV\Tests\unit\DAV\Controller; use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer; use OCA\DAV\Controller\InvitationResponseController; @@ -18,24 +18,16 @@ use OCP\DB\QueryBuilder\IExpressionBuilder; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\ITip\Message; use Test\TestCase; class InvitationResponseControllerTest extends TestCase { - /** @var InvitationResponseController */ - private $controller; - - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - private $dbConnection; - - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var InvitationResponseServer|\PHPUnit\Framework\MockObject\MockObject */ - private $responseServer; + private IDBConnection&MockObject $dbConnection; + private IRequest&MockObject $request; + private ITimeFactory&MockObject $timeFactory; + private InvitationResponseServer&MockObject $responseServer; + private InvitationResponseController $controller; protected function setUp(): void { parent::setUp(); @@ -43,9 +35,7 @@ class InvitationResponseControllerTest extends TestCase { $this->dbConnection = $this->createMock(IDBConnection::class); $this->request = $this->createMock(IRequest::class); $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->responseServer = $this->getMockBuilder(InvitationResponseServer::class) - ->disableOriginalConstructor() - ->getMock(); + $this->responseServer = $this->createMock(InvitationResponseServer::class); $this->controller = new InvitationResponseController( 'appName', @@ -56,7 +46,7 @@ class InvitationResponseControllerTest extends TestCase { ); } - public function attendeeProvider(): array { + public static function attendeeProvider(): array { return [ 'local attendee' => [false], 'external attendee' => [true] @@ -424,7 +414,7 @@ EOF; $this->assertTrue($called); } - private function buildQueryExpects($token, $return, $time): void { + private function buildQueryExpects(string $token, ?array $return, int $time): void { $queryBuilder = $this->createMock(IQueryBuilder::class); $stmt = $this->createMock(IResult::class); $expr = $this->createMock(IExpressionBuilder::class); diff --git a/apps/dav/tests/unit/Controller/UpcomingEventsControllerTest.php b/apps/dav/tests/unit/Controller/UpcomingEventsControllerTest.php index bab0ef77bd0..527943e5221 100644 --- a/apps/dav/tests/unit/Controller/UpcomingEventsControllerTest.php +++ b/apps/dav/tests/unit/Controller/UpcomingEventsControllerTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Service; +namespace OCA\DAV\Tests\unit\DAV\Service; use OCA\DAV\CalDAV\UpcomingEvent; use OCA\DAV\CalDAV\UpcomingEventsService; @@ -17,9 +17,8 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class UpcomingEventsControllerTest extends TestCase { - - private IRequest|MockObject $request; - private UpcomingEventsService|MockObject $service; + private IRequest&MockObject $request; + private UpcomingEventsService&MockObject $service; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/DAV/AnonymousOptionsTest.php b/apps/dav/tests/unit/DAV/AnonymousOptionsTest.php index ea5450391e8..c99ebf327c8 100644 --- a/apps/dav/tests/unit/DAV/AnonymousOptionsTest.php +++ b/apps/dav/tests/unit/DAV/AnonymousOptionsTest.php @@ -1,9 +1,11 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\tests\unit\DAV; +namespace OCA\DAV\Tests\unit\DAV; use OCA\DAV\Connector\Sabre\AnonymousOptionsPlugin; use Sabre\DAV\Auth\Backend\BasicCallBack; @@ -14,7 +16,7 @@ use Sabre\HTTP\Sapi; use Test\TestCase; class AnonymousOptionsTest extends TestCase { - private function sendRequest($method, $path, $userAgent = '') { + private function sendRequest(string $method, string $path, string $userAgent = '') { $server = new Server(); $server->addPlugin(new AnonymousOptionsPlugin()); $server->addPlugin(new Plugin(new BasicCallBack(function () { diff --git a/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php b/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php index 088330cecff..23ee2b66f77 100644 --- a/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php +++ b/apps/dav/tests/unit/DAV/BrowserErrorPagePluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,6 +9,7 @@ namespace OCA\DAV\Tests\unit\DAV; use OCA\DAV\Files\BrowserErrorPagePlugin; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\NotFound; use Sabre\HTTP\Response; @@ -15,18 +17,16 @@ class BrowserErrorPagePluginTest extends \Test\TestCase { /** * @dataProvider providesExceptions - * @param $expectedCode - * @param $exception */ - public function test($expectedCode, $exception): void { - /** @var BrowserErrorPagePlugin | \PHPUnit\Framework\MockObject\MockObject $plugin */ - $plugin = $this->getMockBuilder(BrowserErrorPagePlugin::class)->setMethods(['sendResponse', 'generateBody'])->getMock(); + public function test(int $expectedCode, \Throwable $exception): void { + /** @var BrowserErrorPagePlugin&MockObject $plugin */ + $plugin = $this->getMockBuilder(BrowserErrorPagePlugin::class)->onlyMethods(['sendResponse', 'generateBody'])->getMock(); $plugin->expects($this->once())->method('generateBody')->willReturn(':boom:'); $plugin->expects($this->once())->method('sendResponse'); - /** @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject $server */ - $server = $this->getMockBuilder('Sabre\DAV\Server')->disableOriginalConstructor()->getMock(); + /** @var \Sabre\DAV\Server&MockObject $server */ + $server = $this->createMock('Sabre\DAV\Server'); $server->expects($this->once())->method('on'); - $httpResponse = $this->getMockBuilder(Response::class)->disableOriginalConstructor()->getMock(); + $httpResponse = $this->createMock(Response::class); $httpResponse->expects($this->once())->method('addHeaders'); $httpResponse->expects($this->once())->method('setStatus')->with($expectedCode); $httpResponse->expects($this->once())->method('setBody')->with(':boom:'); @@ -35,7 +35,7 @@ class BrowserErrorPagePluginTest extends \Test\TestCase { $plugin->logException($exception); } - public function providesExceptions() { + public static function providesExceptions(): array { return [ [ 404, new NotFound()], [ 500, new \RuntimeException()], diff --git a/apps/dav/tests/unit/DAV/CustomPropertiesBackendTest.php b/apps/dav/tests/unit/DAV/CustomPropertiesBackendTest.php index 5590e8c1ff0..7c77b3fcb28 100644 --- a/apps/dav/tests/unit/DAV/CustomPropertiesBackendTest.php +++ b/apps/dav/tests/unit/DAV/CustomPropertiesBackendTest.php @@ -1,10 +1,11 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\DAV; +namespace OCA\DAV\Tests\unit\DAV; use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\DefaultCalendarValidator; @@ -12,6 +13,7 @@ use OCA\DAV\DAV\CustomPropertiesBackend; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\IUser; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\PropFind; use Sabre\DAV\PropPatch; @@ -28,23 +30,12 @@ use Test\TestCase; class CustomPropertiesBackendTest extends TestCase { private const BASE_URI = '/remote.php/dav/'; - /** @var Server | \PHPUnit\Framework\MockObject\MockObject */ - private $server; - - /** @var Tree | \PHPUnit\Framework\MockObject\MockObject */ - private $tree; - - /** @var IDBConnection */ - private $dbConnection; - - /** @var IUser | \PHPUnit\Framework\MockObject\MockObject */ - private $user; - - /** @var CustomPropertiesBackend | \PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @property DefaultCalendarValidator | \PHPUnit\Framework\MockObject\MockObject */ - private $defaultCalendarValidator; + private Server&MockObject $server; + private Tree&MockObject $tree; + private IDBConnection $dbConnection; + private IUser&MockObject $user; + private DefaultCalendarValidator&MockObject $defaultCalendarValidator; + private CustomPropertiesBackend $backend; protected function setUp(): void { parent::setUp(); @@ -85,13 +76,13 @@ class CustomPropertiesBackendTest extends TestCase { } } - protected function insertProps(string $user, string $path, array $props) { + protected function insertProps(string $user, string $path, array $props): void { foreach ($props as $name => $value) { $this->insertProp($user, $path, $name, $value); } } - protected function insertProp(string $user, string $path, string $name, mixed $value) { + protected function insertProp(string $user, string $path, string $name, mixed $value): void { $type = CustomPropertiesBackend::PROPERTY_TYPE_STRING; if ($value instanceof Href) { $value = $value->getHref(); @@ -110,7 +101,7 @@ class CustomPropertiesBackendTest extends TestCase { $query->execute(); } - protected function getProps(string $user, string $path) { + protected function getProps(string $user, string $path): array { $query = $this->dbConnection->getQueryBuilder(); $query->select('propertyname', 'propertyvalue', 'valuetype') ->from('properties') @@ -245,7 +236,7 @@ class CustomPropertiesBackendTest extends TestCase { $this->assertEquals($props, $setProps); } - public function propFindPrincipalScheduleDefaultCalendarProviderUrlProvider(): array { + public static function propFindPrincipalScheduleDefaultCalendarProviderUrlProvider(): array { // [ user, nodes, existingProps, requestedProps, returnedProps ] return [ [ // Exists @@ -373,7 +364,7 @@ class CustomPropertiesBackendTest extends TestCase { $this->assertEquals($result, $storedProps); } - public function propPatchProvider() { + public static function propPatchProvider(): array { $longPath = str_repeat('long_path', 100); return [ ['foo_bar_path_1337', [], ['{DAV:}displayname' => 'anything'], ['{DAV:}displayname' => 'anything']], @@ -436,7 +427,7 @@ class CustomPropertiesBackendTest extends TestCase { $this->assertEquals([], $this->getProps('dummy_user_42', $path)); } - public function deleteProvider() { + public static function deleteProvider(): array { return [ ['foo_bar_path_1337'], [str_repeat('long_path', 100)] @@ -453,7 +444,7 @@ class CustomPropertiesBackendTest extends TestCase { $this->assertEquals(['foo' => 'bar'], $this->getProps('dummy_user_42', $target)); } - public function moveProvider() { + public static function moveProvider(): array { return [ ['foo_bar_path_1337', 'foo_bar_path_7333'], [str_repeat('long_path1', 100), str_repeat('long_path2', 100)] @@ -475,5 +466,4 @@ class CustomPropertiesBackendTest extends TestCase { $this->assertInstanceOf(\Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp::class, $decodeValue); $this->assertEquals('opaque', $decodeValue->getValue()); } - } diff --git a/apps/dav/tests/unit/DAV/GroupPrincipalTest.php b/apps/dav/tests/unit/DAV/GroupPrincipalTest.php index bfc4c5b2493..2ede450c36b 100644 --- a/apps/dav/tests/unit/DAV/GroupPrincipalTest.php +++ b/apps/dav/tests/unit/DAV/GroupPrincipalTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,20 +20,11 @@ use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\PropPatch; class GroupPrincipalTest extends \Test\TestCase { - /** @var IConfig|MockObject */ - private $config; - - /** @var IGroupManager | MockObject */ - private $groupManager; - - /** @var IUserSession | MockObject */ - private $userSession; - - /** @var IManager | MockObject */ - private $shareManager; - - /** @var GroupPrincipalBackend */ - private $connector; + private IConfig&MockObject $config; + private IGroupManager&MockObject $groupManager; + private IUserSession&MockObject $userSession; + private IManager&MockObject $shareManager; + private GroupPrincipalBackend $connector; protected function setUp(): void { $this->groupManager = $this->createMock(IGroupManager::class); @@ -201,11 +194,6 @@ class GroupPrincipalTest extends \Test\TestCase { /** * @dataProvider searchPrincipalsDataProvider - * @param bool $sharingEnabled - * @param bool $groupSharingEnabled - * @param bool $groupsOnly - * @param string $test - * @param array $result */ public function testSearchPrincipals(bool $sharingEnabled, bool $groupSharingEnabled, bool $groupsOnly, string $test, array $result): void { $this->shareManager->expects($this->once()) @@ -264,7 +252,7 @@ class GroupPrincipalTest extends \Test\TestCase { ['{DAV:}displayname' => 'Foo'], $test)); } - public function searchPrincipalsDataProvider() { + public static function searchPrincipalsDataProvider(): array { return [ [true, true, false, 'allof', ['principals/groups/group1', 'principals/groups/group2', 'principals/groups/group3', 'principals/groups/group4', 'principals/groups/group5']], [true, true, false, 'anyof', ['principals/groups/group1', 'principals/groups/group2', 'principals/groups/group3', 'principals/groups/group4', 'principals/groups/group5']], @@ -279,11 +267,6 @@ class GroupPrincipalTest extends \Test\TestCase { /** * @dataProvider findByUriDataProvider - * @param bool $sharingEnabled - * @param bool $groupSharingEnabled - * @param bool $groupsOnly - * @param string $findUri - * @param string|null $result */ public function testFindByUri(bool $sharingEnabled, bool $groupSharingEnabled, bool $groupsOnly, string $findUri, ?string $result): void { $this->shareManager->expects($this->once()) @@ -320,7 +303,7 @@ class GroupPrincipalTest extends \Test\TestCase { $this->assertEquals($result, $this->connector->findByUri($findUri, 'principals/groups')); } - public function findByUriDataProvider() { + public static function findByUriDataProvider(): array { return [ [false, false, false, 'principal:principals/groups/group1', null], [false, false, false, 'principal:principals/groups/group3', null], @@ -337,10 +320,7 @@ class GroupPrincipalTest extends \Test\TestCase { ]; } - /** - * @return Group|MockObject - */ - private function mockGroup($gid) { + private function mockGroup(string $gid): Group&MockObject { $fooGroup = $this->createMock(Group::class); $fooGroup ->expects($this->exactly(1)) diff --git a/apps/dav/tests/unit/DAV/Listener/UserEventsListenerTest.php b/apps/dav/tests/unit/DAV/Listener/UserEventsListenerTest.php index a0876d8e483..420f0a0d937 100644 --- a/apps/dav/tests/unit/DAV/Listener/UserEventsListenerTest.php +++ b/apps/dav/tests/unit/DAV/Listener/UserEventsListenerTest.php @@ -51,9 +51,7 @@ class UserEventsListenerTest extends TestCase { } public function test(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->once())->method('getUID')->willReturn('newUser'); $this->defaults->expects($this->once())->method('getColorPrimary')->willReturn('#745bca'); @@ -76,9 +74,7 @@ class UserEventsListenerTest extends TestCase { } public function testWithExisting(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->once())->method('getUID')->willReturn('newUser'); $this->calDavBackend->expects($this->once())->method('getCalendarsForUserCount')->willReturn(1); @@ -91,9 +87,7 @@ class UserEventsListenerTest extends TestCase { } public function testWithBirthdayCalendar(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->once())->method('getUID')->willReturn('newUser'); $this->defaults->expects($this->once())->method('getColorPrimary')->willReturn('#745bca'); @@ -116,9 +110,7 @@ class UserEventsListenerTest extends TestCase { } public function testDeleteCalendar(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->once())->method('getUID')->willReturn('newUser'); $this->syncService->expects($this->once()) diff --git a/apps/dav/tests/unit/DAV/Sharing/BackendTest.php b/apps/dav/tests/unit/DAV/Sharing/BackendTest.php index dd2681d149f..556a623a73f 100644 --- a/apps/dav/tests/unit/DAV/Sharing/BackendTest.php +++ b/apps/dav/tests/unit/DAV/Sharing/BackendTest.php @@ -24,14 +24,14 @@ use Test\TestCase; class BackendTest extends TestCase { - private IDBConnection|MockObject $db; - private IUserManager|MockObject $userManager; - private IGroupManager|MockObject $groupManager; - private MockObject|Principal $principalBackend; - private MockObject|ICache $shareCache; - private LoggerInterface|MockObject $logger; - private MockObject|ICacheFactory $cacheFactory; - private Service|MockObject $calendarService; + private IDBConnection&MockObject $db; + private IUserManager&MockObject $userManager; + private IGroupManager&MockObject $groupManager; + private Principal&MockObject $principalBackend; + private ICache&MockObject $shareCache; + private LoggerInterface&MockObject $logger; + private ICacheFactory&MockObject $cacheFactory; + private Service&MockObject $calendarService; private CalendarSharingBackend $backend; protected function setUp(): void { diff --git a/apps/dav/tests/unit/DAV/Sharing/PluginTest.php b/apps/dav/tests/unit/DAV/Sharing/PluginTest.php index 9c6950f19e8..7a88f7cc5dd 100644 --- a/apps/dav/tests/unit/DAV/Sharing/PluginTest.php +++ b/apps/dav/tests/unit/DAV/Sharing/PluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -12,6 +13,7 @@ use OCA\DAV\DAV\Sharing\IShareable; use OCA\DAV\DAV\Sharing\Plugin; use OCP\IConfig; use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Server; use Sabre\DAV\SimpleCollection; use Sabre\HTTP\Request; @@ -19,32 +21,24 @@ use Sabre\HTTP\Response; use Test\TestCase; class PluginTest extends TestCase { - - /** @var Plugin */ - private $plugin; - /** @var Server */ - private $server; - /** @var IShareable | \PHPUnit\Framework\MockObject\MockObject */ - private $book; + private Plugin $plugin; + private Server $server; + private IShareable&MockObject $book; protected function setUp(): void { parent::setUp(); - /** @var Auth | \PHPUnit\Framework\MockObject\MockObject $authBackend */ - $authBackend = $this->getMockBuilder(Auth::class)->disableOriginalConstructor()->getMock(); + $authBackend = $this->createMock(Auth::class); $authBackend->method('isDavAuthenticated')->willReturn(true); - /** @var IRequest $request */ - $request = $this->getMockBuilder(IRequest::class)->disableOriginalConstructor()->getMock(); + $request = $this->createMock(IRequest::class); $config = $this->createMock(IConfig::class); $this->plugin = new Plugin($authBackend, $request, $config); $root = new SimpleCollection('root'); $this->server = new \Sabre\DAV\Server($root); /** @var SimpleCollection $node */ - $this->book = $this->getMockBuilder(IShareable::class)-> - disableOriginalConstructor()-> - getMock(); + $this->book = $this->createMock(IShareable::class); $this->book->method('getName')->willReturn('addressbook1.vcf'); $root->addChild($this->book); $this->plugin->initialize($this->server); diff --git a/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php b/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php index 32916804080..127de1ede0a 100644 --- a/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php +++ b/apps/dav/tests/unit/DAV/SystemPrincipalBackendTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,22 +9,21 @@ namespace OCA\DAV\Tests\unit\DAV; use OCA\DAV\DAV\SystemPrincipalBackend; +use Sabre\DAV\Exception; use Test\TestCase; class SystemPrincipalBackendTest extends TestCase { /** * @dataProvider providesPrefix - * @param $expected - * @param $prefix */ - public function testGetPrincipalsByPrefix($expected, $prefix): void { + public function testGetPrincipalsByPrefix(array $expected, string $prefix): void { $backend = new SystemPrincipalBackend(); $result = $backend->getPrincipalsByPrefix($prefix); $this->assertEquals($expected, $result); } - public function providesPrefix() { + public static function providesPrefix(): array { return [ [[], ''], [[[ @@ -40,16 +40,14 @@ class SystemPrincipalBackendTest extends TestCase { /** * @dataProvider providesPath - * @param $expected - * @param $path */ - public function testGetPrincipalByPath($expected, $path): void { + public function testGetPrincipalByPath(?array $expected, string $path): void { $backend = new SystemPrincipalBackend(); $result = $backend->getPrincipalByPath($path); $this->assertEquals($expected, $result); } - public function providesPath() { + public static function providesPath(): array { return [ [null, ''], [null, 'principals'], @@ -63,28 +61,22 @@ class SystemPrincipalBackendTest extends TestCase { /** * @dataProvider providesPrincipalForGetGroupMemberSet - * - * @param string $principal - * @throws \Sabre\DAV\Exception */ - public function testGetGroupMemberSetExceptional($principal): void { - $this->expectException(\Sabre\DAV\Exception::class); + public function testGetGroupMemberSetExceptional(?string $principal): void { + $this->expectException(Exception::class); $this->expectExceptionMessage('Principal not found'); $backend = new SystemPrincipalBackend(); $backend->getGroupMemberSet($principal); } - public function providesPrincipalForGetGroupMemberSet() { + public static function providesPrincipalForGetGroupMemberSet(): array { return [ [null], ['principals/system'], ]; } - /** - * @throws \Sabre\DAV\Exception - */ public function testGetGroupMemberSet(): void { $backend = new SystemPrincipalBackend(); $result = $backend->getGroupMemberSet('principals/system/system'); @@ -93,27 +85,21 @@ class SystemPrincipalBackendTest extends TestCase { /** * @dataProvider providesPrincipalForGetGroupMembership - * - * @param string $principal - * @throws \Sabre\DAV\Exception */ - public function testGetGroupMembershipExceptional($principal): void { - $this->expectException(\Sabre\DAV\Exception::class); + public function testGetGroupMembershipExceptional(string $principal): void { + $this->expectException(Exception::class); $this->expectExceptionMessage('Principal not found'); $backend = new SystemPrincipalBackend(); $backend->getGroupMembership($principal); } - public function providesPrincipalForGetGroupMembership() { + public static function providesPrincipalForGetGroupMembership(): array { return [ ['principals/system/a'], ]; } - /** - * @throws \Sabre\DAV\Exception - */ public function testGetGroupMembership(): void { $backend = new SystemPrincipalBackend(); $result = $backend->getGroupMembership('principals/system/system'); diff --git a/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php index 7a4828dd2de..9227d34b30f 100644 --- a/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php +++ b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2019 ownCloud GmbH @@ -20,30 +21,29 @@ use OCP\Files\Storage\IStorage; use OCP\IUser; use OCP\Share\IAttributes; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Server; use Sabre\DAV\Tree; use Sabre\HTTP\RequestInterface; use Test\TestCase; class ViewOnlyPluginTest extends TestCase { - + private Tree&MockObject $tree; + private RequestInterface&MockObject $request; + private Folder&MockObject $userFolder; private ViewOnlyPlugin $plugin; - /** @var Tree | \PHPUnit\Framework\MockObject\MockObject */ - private $tree; - /** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var Folder | \PHPUnit\Framework\MockObject\MockObject */ - private $userFolder; public function setUp(): void { + parent::setUp(); + $this->userFolder = $this->createMock(Folder::class); - $this->plugin = new ViewOnlyPlugin( - $this->userFolder, - ); $this->request = $this->createMock(RequestInterface::class); $this->tree = $this->createMock(Tree::class); - $server = $this->createMock(Server::class); + + $this->plugin = new ViewOnlyPlugin( + $this->userFolder, + ); $server->tree = $this->tree; $this->plugin->initialize($server); @@ -71,7 +71,7 @@ class ViewOnlyPluginTest extends TestCase { $this->assertTrue($this->plugin->checkViewOnly($this->request)); } - public function providesDataForCanGet(): array { + public static function providesDataForCanGet(): array { return [ // has attribute permissions-download enabled - can get file [false, true, true], diff --git a/apps/dav/tests/unit/Direct/DirectFileTest.php b/apps/dav/tests/unit/Direct/DirectFileTest.php index 07d19807ef0..f6f0f49fa8c 100644 --- a/apps/dav/tests/unit/Direct/DirectFileTest.php +++ b/apps/dav/tests/unit/Direct/DirectFileTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Direct; +namespace OCA\DAV\Tests\unit\Direct; use OCA\DAV\Db\Direct; use OCA\DAV\Direct\DirectFile; @@ -14,28 +14,17 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\Forbidden; use Test\TestCase; class DirectFileTest extends TestCase { - - /** @var Direct */ - private $direct; - - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var Folder|\PHPUnit\Framework\MockObject\MockObject */ - private $userFolder; - - /** @var File|\PHPUnit\Framework\MockObject\MockObject */ - private $file; - - /** @var DirectFile */ - private $directFile; - - /** @var IEventDispatcher */ - private $eventDispatcher; + private Direct $direct; + private IRootFolder&MockObject $rootFolder; + private Folder&MockObject $userFolder; + private File&MockObject $file; + private IEventDispatcher&MockObject $eventDispatcher; + private DirectFile $directFile; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Direct/DirectHomeTest.php b/apps/dav/tests/unit/Direct/DirectHomeTest.php index 06fb48a64d8..94c82c2b7c5 100644 --- a/apps/dav/tests/unit/Direct/DirectHomeTest.php +++ b/apps/dav/tests/unit/Direct/DirectHomeTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Direct; +namespace OCA\DAV\Tests\unit\Direct; use OCA\DAV\Db\Direct; use OCA\DAV\Db\DirectMapper; @@ -18,33 +18,20 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\IRequest; use OCP\Security\Bruteforce\IThrottler; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\MethodNotAllowed; use Sabre\DAV\Exception\NotFound; use Test\TestCase; class DirectHomeTest extends TestCase { - - /** @var DirectMapper|\PHPUnit\Framework\MockObject\MockObject */ - private $directMapper; - - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var IThrottler|\PHPUnit\Framework\MockObject\MockObject */ - private $throttler; - - /** @var IRequest */ - private $request; - - /** @var DirectHome */ - private $directHome; - - /** @var IEventDispatcher */ - private $eventDispatcher; + private DirectMapper&MockObject $directMapper; + private IRootFolder&MockObject $rootFolder; + private ITimeFactory&MockObject $timeFactory; + private IThrottler&MockObject $throttler; + private IRequest&MockObject $request; + private IEventDispatcher&MockObject $eventDispatcher; + private DirectHome $directHome; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Files/FileSearchBackendTest.php b/apps/dav/tests/unit/Files/FileSearchBackendTest.php index aaa3d8c147e..ce56dde5fbd 100644 --- a/apps/dav/tests/unit/Files/FileSearchBackendTest.php +++ b/apps/dav/tests/unit/Files/FileSearchBackendTest.php @@ -1,10 +1,12 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Files; +namespace OCA\DAV\Tests\unit\Files; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; @@ -23,42 +25,26 @@ use OCP\Files\Search\ISearchQuery; use OCP\FilesMetadata\IFilesMetadataManager; use OCP\IUser; use OCP\Share\IManager; +use PHPUnit\Framework\MockObject\MockObject; use SearchDAV\Backend\SearchPropertyDefinition; use SearchDAV\Query\Limit; +use SearchDAV\Query\Literal; use SearchDAV\Query\Operator; use SearchDAV\Query\Query; +use SearchDAV\Query\Scope; use Test\TestCase; class FileSearchBackendTest extends TestCase { - /** @var ObjectTree|\PHPUnit\Framework\MockObject\MockObject */ - private $tree; - - /** @var IUser */ - private $user; - - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - - /** @var View|\PHPUnit\Framework\MockObject\MockObject */ - private $view; - - /** @var Folder|\PHPUnit\Framework\MockObject\MockObject */ - private $searchFolder; - - /** @var FileSearchBackend */ - private $search; - - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject */ - private $davFolder; + private ObjectTree&MockObject $tree; + private IUser&MockObject $user; + private IRootFolder&MockObject $rootFolder; + private IManager&MockObject $shareManager; + private View&MockObject $view; + private Folder&MockObject $searchFolder; + private Directory&MockObject $davFolder; + private FileSearchBackend $search; protected function setUp(): void { - if (PHP_VERSION_ID >= 80400) { - $this->markTestSkipped('SearchDAV is not yet PHP 8.4 compatible'); - } - parent::setUp(); $this->user = $this->createMock(IUser::class); @@ -66,11 +52,13 @@ class FileSearchBackendTest extends TestCase { ->method('getUID') ->willReturn('test'); - $this->tree = $this->getMockBuilder(ObjectTree::class) - ->disableOriginalConstructor() - ->getMock(); - + $this->tree = $this->createMock(ObjectTree::class); $this->view = $this->createMock(View::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->shareManager = $this->createMock(IManager::class); + $this->searchFolder = $this->createMock(Folder::class); + $fileInfo = $this->createMock(FileInfo::class); + $this->davFolder = $this->createMock(Directory::class); $this->view->expects($this->any()) ->method('getRoot') @@ -80,16 +68,6 @@ class FileSearchBackendTest extends TestCase { ->method('getRelativePath') ->willReturnArgument(0); - $this->rootFolder = $this->createMock(IRootFolder::class); - - $this->shareManager = $this->createMock(IManager::class); - - $this->searchFolder = $this->createMock(Folder::class); - - $fileInfo = $this->createMock(FileInfo::class); - - $this->davFolder = $this->createMock(Directory::class); - $this->davFolder->expects($this->any()) ->method('getFileInfo') ->willReturn($fileInfo); @@ -263,8 +241,8 @@ class FileSearchBackendTest extends TestCase { $this->search->search($query); } - private function getBasicQuery($type, $property, $value = null) { - $scope = new \SearchDAV\Query\Scope('/', 'infinite'); + private function getBasicQuery(string $type, string $property, int|string|null $value = null) { + $scope = new Scope('/', 'infinite'); $scope->path = '/'; $from = [$scope]; $orderBy = []; @@ -272,12 +250,12 @@ class FileSearchBackendTest extends TestCase { if (is_null($value)) { $where = new Operator( $type, - [new \SearchDAV\Query\Literal($property)] + [new Literal($property)] ); } else { $where = new Operator( $type, - [new SearchPropertyDefinition($property, true, true, true), new \SearchDAV\Query\Literal($value)] + [new SearchPropertyDefinition($property, true, true, true), new Literal($value)] ); } $limit = new Limit(); @@ -350,11 +328,11 @@ class FileSearchBackendTest extends TestCase { [ new Operator( Operator::OPERATION_EQUAL, - [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new \SearchDAV\Query\Literal('image/png')] + [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new Literal('image/png')] ), new Operator( Operator::OPERATION_EQUAL, - [new SearchPropertyDefinition(FilesPlugin::OWNER_ID_PROPERTYNAME, true, true, true), new \SearchDAV\Query\Literal($this->user->getUID())] + [new SearchPropertyDefinition(FilesPlugin::OWNER_ID_PROPERTYNAME, true, true, true), new Literal($this->user->getUID())] ), ] ); @@ -383,7 +361,7 @@ class FileSearchBackendTest extends TestCase { $innerOperator = new Operator( Operator::OPERATION_EQUAL, - [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new \SearchDAV\Query\Literal('image/png')] + [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new Literal('image/png')] ); // 5 child operators $level1Operator = new Operator( diff --git a/apps/dav/tests/unit/Files/MultipartRequestParserTest.php b/apps/dav/tests/unit/Files/MultipartRequestParserTest.php index 40880bdca9c..dc0e884f07c 100644 --- a/apps/dav/tests/unit/Files/MultipartRequestParserTest.php +++ b/apps/dav/tests/unit/Files/MultipartRequestParserTest.php @@ -1,10 +1,12 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-only */ -namespace OCA\DAV\Tests\unit\DAV; +namespace OCA\DAV\Tests\unit\Files; use OCA\DAV\BulkUpload\MultipartRequestParser; use PHPUnit\Framework\MockObject\MockObject; @@ -17,10 +19,11 @@ class MultipartRequestParserTest extends TestCase { protected LoggerInterface&MockObject $logger; protected function setUp(): void { + parent::setUp(); $this->logger = $this->createMock(LoggerInterface::class); } - private function getValidBodyObject() { + private static function getValidBodyObject(): array { return [ [ 'headers' => [ @@ -99,7 +102,7 @@ class MultipartRequestParserTest extends TestCase { * - valid file path */ public function testValidRequest(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); unset($bodyObject['0']['headers']['X-File-MD5']); $multipartParser = $this->getMultipartParser($bodyObject); @@ -122,7 +125,7 @@ class MultipartRequestParserTest extends TestCase { * - valid file path */ public function testValidRequestWithMd5(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); unset($bodyObject['0']['headers']['OC-Checksum']); $multipartParser = $this->getMultipartParser($bodyObject); @@ -140,7 +143,7 @@ class MultipartRequestParserTest extends TestCase { * Test with invalid hash. */ public function testInvalidHash(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $bodyObject['0']['headers']['OC-Checksum'] = 'md5:f2377b4d911f7ec46325fe603c3af03'; unset($bodyObject['0']['headers']['X-File-MD5']); $multipartParser = $this->getMultipartParser( @@ -155,7 +158,7 @@ class MultipartRequestParserTest extends TestCase { * Test with invalid md5 hash. */ public function testInvalidMd5Hash(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); unset($bodyObject['0']['headers']['OC-Checksum']); $bodyObject['0']['headers']['X-File-MD5'] = 'f2377b4d911f7ec46325fe603c3af03'; $multipartParser = $this->getMultipartParser( @@ -170,7 +173,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a null hash headers. */ public function testNullHash(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); unset($bodyObject['0']['headers']['OC-Checksum']); unset($bodyObject['0']['headers']['X-File-MD5']); $multipartParser = $this->getMultipartParser( @@ -185,7 +188,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a null Content-Length. */ public function testNullContentLength(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); unset($bodyObject['0']['headers']['Content-Length']); $multipartParser = $this->getMultipartParser( $bodyObject @@ -199,7 +202,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a lower Content-Length. */ public function testLowerContentLength(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $bodyObject['0']['headers']['Content-Length'] = 6; $multipartParser = $this->getMultipartParser( $bodyObject @@ -213,7 +216,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a higher Content-Length. */ public function testHigherContentLength(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $bodyObject['0']['headers']['Content-Length'] = 8; $multipartParser = $this->getMultipartParser( $bodyObject @@ -227,7 +230,7 @@ class MultipartRequestParserTest extends TestCase { * Test with wrong boundary in body. */ public function testWrongBoundary(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $multipartParser = $this->getMultipartParser( $bodyObject, ['Content-Type' => 'multipart/related; boundary=boundary_poiuytreza'] @@ -241,7 +244,7 @@ class MultipartRequestParserTest extends TestCase { * Test with no boundary in request headers. */ public function testNoBoundaryInHeader(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $this->expectExceptionMessage('Error while parsing boundary in Content-Type header.'); $this->getMultipartParser( $bodyObject, @@ -253,7 +256,7 @@ class MultipartRequestParserTest extends TestCase { * Test with no boundary in the request's headers. */ public function testNoBoundaryInBody(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $multipartParser = $this->getMultipartParser( $bodyObject, ['Content-Type' => 'multipart/related; boundary=boundary_azertyuiop'], @@ -268,7 +271,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a boundary with quotes in the request's headers. */ public function testBoundaryWithQuotes(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $multipartParser = $this->getMultipartParser( $bodyObject, ['Content-Type' => 'multipart/related; boundary="boundary_azertyuiop"'], @@ -284,7 +287,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a wrong Content-Type in the request's headers. */ public function testWrongContentType(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $this->expectExceptionMessage('Content-Type must be multipart/related'); $this->getMultipartParser( $bodyObject, @@ -296,7 +299,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a wrong key after the content type in the request's headers. */ public function testWrongKeyInContentType(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $this->expectExceptionMessage('Boundary is invalid'); $this->getMultipartParser( $bodyObject, @@ -308,7 +311,7 @@ class MultipartRequestParserTest extends TestCase { * Test with a null Content-Type in the request's headers. */ public function testNullContentType(): void { - $bodyObject = $this->getValidBodyObject(); + $bodyObject = self::getValidBodyObject(); $this->expectExceptionMessage('Content-Type can not be null'); $this->getMultipartParser( $bodyObject, diff --git a/apps/dav/tests/unit/Files/Sharing/FilesDropPluginTest.php b/apps/dav/tests/unit/Files/Sharing/FilesDropPluginTest.php index 16891ced3d0..545bea9a406 100644 --- a/apps/dav/tests/unit/Files/Sharing/FilesDropPluginTest.php +++ b/apps/dav/tests/unit/Files/Sharing/FilesDropPluginTest.php @@ -1,9 +1,11 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Files\Sharing; +namespace OCA\DAV\Tests\unit\Files\Sharing; use OCA\DAV\Files\Sharing\FilesDropPlugin; use OCP\Files\Folder; @@ -205,7 +207,7 @@ class FilesDropPluginTest extends TestCase { $this->request->method('getHeader') ->with('X-NC-Nickname') ->willReturn('nickname'); - + $this->request->method('getPath') ->willReturn('/files/token/folder/subfolder/file.txt'); $this->request->method('getBaseUrl') diff --git a/apps/dav/tests/unit/Listener/ActivityUpdaterListenerTest.php b/apps/dav/tests/unit/Listener/ActivityUpdaterListenerTest.php index 78769c7fb47..7bd7bdc2167 100644 --- a/apps/dav/tests/unit/Listener/ActivityUpdaterListenerTest.php +++ b/apps/dav/tests/unit/Listener/ActivityUpdaterListenerTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Listener; +namespace OCA\DAV\Tests\unit\Listener; use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend; use OCA\DAV\CalDAV\Activity\Provider\Event; @@ -20,10 +20,8 @@ use Test\TestCase; class ActivityUpdaterListenerTest extends TestCase { - /** @var ActivityBackend|MockObject */ - private $activityBackend; - /** @var LoggerInterface|MockObject */ - private $logger; + private ActivityBackend&MockObject $activityBackend; + private LoggerInterface&MockObject $logger; private ActivityUpdaterListener $listener; protected function setUp(): void { @@ -55,7 +53,7 @@ class ActivityUpdaterListenerTest extends TestCase { $this->listener->handle($event); } - public function dataForTestHandleCalendarObjectDeletedEvent(): array { + public static function dataForTestHandleCalendarObjectDeletedEvent(): array { return [ [1, [], [], [], true], [1, [], [], ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], false], @@ -77,7 +75,7 @@ class ActivityUpdaterListenerTest extends TestCase { $this->listener->handle($event); } - public function dataForTestHandleCalendarDeletedEvent(): array { + public static function dataForTestHandleCalendarDeletedEvent(): array { return [ [1, [], [], true], [1, ['{' . SharingPlugin::NS_NEXTCLOUD . '}deleted-at' => 120], [], false], diff --git a/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php b/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php index 96d8514da41..dc3dce8a62f 100644 --- a/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php +++ b/apps/dav/tests/unit/Listener/CalendarContactInteractionListenerTest.php @@ -6,7 +6,7 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Listener; +namespace OCA\DAV\Tests\unit\Listener; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\Events\CalendarShareUpdatedEvent; @@ -23,24 +23,12 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class CalendarContactInteractionListenerTest extends TestCase { - - /** @var IEventDispatcher|MockObject */ - private $eventDispatcher; - - /** @var IUserSession|MockObject */ - private $userSession; - - /** @var Principal|MockObject */ - private $principalConnector; - - /** @var LoggerInterface|MockObject */ - private $logger; - - /** @var IMailer|MockObject */ - private $mailer; - - /** @var CalendarContactInteractionListener */ - private $listener; + private IEventDispatcher&MockObject $eventDispatcher; + private IUserSession&MockObject $userSession; + private Principal&MockObject $principalConnector; + private LoggerInterface&MockObject $logger; + private IMailer&MockObject $mailer; + private CalendarContactInteractionListener $listener; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Listener/OutOfOfficeListenerTest.php b/apps/dav/tests/unit/Listener/OutOfOfficeListenerTest.php index a21d3a5e928..971d113b742 100644 --- a/apps/dav/tests/unit/Listener/OutOfOfficeListenerTest.php +++ b/apps/dav/tests/unit/Listener/OutOfOfficeListenerTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Listener; +namespace OCA\DAV\Tests\unit\Listener; use DateTimeImmutable; use InvalidArgumentException; @@ -27,7 +27,6 @@ use OCP\User\Events\OutOfOfficeChangedEvent; use OCP\User\Events\OutOfOfficeClearedEvent; use OCP\User\Events\OutOfOfficeScheduledEvent; use OCP\User\IOutOfOfficeData; -use OCP\UserStatus\IManager; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\DAV\Exception\NotFound; @@ -42,11 +41,10 @@ use Test\TestCase; */ class OutOfOfficeListenerTest extends TestCase { - private ServerFactory|MockObject $serverFactory; - private IConfig|MockObject $appConfig; - private LoggerInterface|MockObject $loggerInterface; - private MockObject|TimezoneService $timezoneService; - private IManager|MockObject $manager; + private ServerFactory&MockObject $serverFactory; + private IConfig&MockObject $appConfig; + private LoggerInterface&MockObject $loggerInterface; + private TimezoneService&MockObject $timezoneService; private OutOfOfficeListener $listener; protected function setUp(): void { @@ -56,14 +54,12 @@ class OutOfOfficeListenerTest extends TestCase { $this->appConfig = $this->createMock(IConfig::class); $this->timezoneService = $this->createMock(TimezoneService::class); $this->loggerInterface = $this->createMock(LoggerInterface::class); - $this->manager = $this->createMock(IManager::class); $this->listener = new OutOfOfficeListener( $this->serverFactory, $this->appConfig, $this->timezoneService, $this->loggerInterface, - $this->manager ); } @@ -453,8 +449,6 @@ class OutOfOfficeListenerTest extends TestCase { ->method('getPlugin') ->with('caldav') ->willReturn($caldavPlugin); - $this->manager->expects(self::never()) - ->method('revertUserStatus'); $event = new OutOfOfficeClearedEvent($data); $this->listener->handle($event); @@ -483,8 +477,6 @@ class OutOfOfficeListenerTest extends TestCase { ->method('getNodeForPath') ->with('/home/calendar') ->willThrowException(new NotFound('nope')); - $this->manager->expects(self::never()) - ->method('revertUserStatus'); $event = new OutOfOfficeClearedEvent($data); $this->listener->handle($event); @@ -522,8 +514,6 @@ class OutOfOfficeListenerTest extends TestCase { ->method('getChild') ->with('personal-1') ->willThrowException(new NotFound('nope')); - $this->manager->expects(self::never()) - ->method('revertUserStatus'); $event = new OutOfOfficeClearedEvent($data); $this->listener->handle($event); @@ -565,8 +555,6 @@ class OutOfOfficeListenerTest extends TestCase { $calendar->expects(self::once()) ->method('getChild') ->willThrowException(new NotFound()); - $this->manager->expects(self::never()) - ->method('revertUserStatus'); $event = new OutOfOfficeClearedEvent($data); $this->listener->handle($event); diff --git a/apps/dav/tests/unit/Migration/CalDAVRemoveEmptyValueTest.php b/apps/dav/tests/unit/Migration/CalDAVRemoveEmptyValueTest.php index be2c64c47a4..1852d2709c1 100644 --- a/apps/dav/tests/unit/Migration/CalDAVRemoveEmptyValueTest.php +++ b/apps/dav/tests/unit/Migration/CalDAVRemoveEmptyValueTest.php @@ -1,15 +1,18 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Migration; +namespace OCA\DAV\Tests\unit\DAV\Migration; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Migration\CalDAVRemoveEmptyValue; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\VObject\InvalidDataException; use Test\TestCase; @@ -21,18 +24,10 @@ use Test\TestCase; * @group DB */ class CalDAVRemoveEmptyValueTest extends TestCase { - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; - - /** @var CalDavBackend|\PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @var IOutput|\PHPUnit\Framework\MockObject\MockObject */ - private $output; - - /** @var string */ - private $invalid = 'BEGIN:VCALENDAR + private LoggerInterface&MockObject $logger; + private CalDavBackend&MockObject $backend; + private IOutput&MockObject $output; + private string $invalid = 'BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Apple Inc.//Mac OS X 10.11.2//EN CALSCALE:GREGORIAN @@ -52,8 +47,7 @@ CREATED;VALUE=:20151214T091032Z END:VEVENT END:VCALENDAR'; - /** @var string */ - private $valid = 'BEGIN:VCALENDAR + private string $valid = 'BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Apple Inc.//Mac OS X 10.11.2//EN CALSCALE:GREGORIAN @@ -82,14 +76,14 @@ END:VCALENDAR'; } public function testRunAllValid(): void { - /** @var CalDAVRemoveEmptyValue|\PHPUnit\Framework\MockObject\MockObject $step */ + /** @var CalDAVRemoveEmptyValue&MockObject $step */ $step = $this->getMockBuilder(CalDAVRemoveEmptyValue::class) ->setConstructorArgs([ Server::get(IDBConnection::class), $this->backend, $this->logger ]) - ->setMethods(['getInvalidObjects']) + ->onlyMethods(['getInvalidObjects']) ->getMock(); $step->expects($this->once()) @@ -106,14 +100,14 @@ END:VCALENDAR'; } public function testRunInvalid(): void { - /** @var CalDAVRemoveEmptyValue|\PHPUnit\Framework\MockObject\MockObject $step */ + /** @var CalDAVRemoveEmptyValue&MockObject $step */ $step = $this->getMockBuilder(CalDAVRemoveEmptyValue::class) ->setConstructorArgs([ Server::get(IDBConnection::class), $this->backend, $this->logger ]) - ->setMethods(['getInvalidObjects']) + ->onlyMethods(['getInvalidObjects']) ->getMock(); $step->expects($this->once()) @@ -149,14 +143,14 @@ END:VCALENDAR'; } public function testRunValid(): void { - /** @var CalDAVRemoveEmptyValue|\PHPUnit\Framework\MockObject\MockObject $step */ + /** @var CalDAVRemoveEmptyValue&MockObject $step */ $step = $this->getMockBuilder(CalDAVRemoveEmptyValue::class) ->setConstructorArgs([ Server::get(IDBConnection::class), $this->backend, $this->logger ]) - ->setMethods(['getInvalidObjects']) + ->onlyMethods(['getInvalidObjects']) ->getMock(); $step->expects($this->once()) @@ -191,14 +185,14 @@ END:VCALENDAR'; } public function testRunStillInvalid(): void { - /** @var CalDAVRemoveEmptyValue|\PHPUnit\Framework\MockObject\MockObject $step */ + /** @var CalDAVRemoveEmptyValue&MockObject $step */ $step = $this->getMockBuilder(CalDAVRemoveEmptyValue::class) ->setConstructorArgs([ Server::get(IDBConnection::class), $this->backend, $this->logger ]) - ->setMethods(['getInvalidObjects']) + ->onlyMethods(['getInvalidObjects']) ->getMock(); $step->expects($this->once()) diff --git a/apps/dav/tests/unit/Migration/CreateSystemAddressBookStepTest.php b/apps/dav/tests/unit/Migration/CreateSystemAddressBookStepTest.php index bbecd0607b4..667d2e39d3a 100644 --- a/apps/dav/tests/unit/Migration/CreateSystemAddressBookStepTest.php +++ b/apps/dav/tests/unit/Migration/CreateSystemAddressBookStepTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Migration; +namespace OCA\DAV\Tests\unit\Migration; use OCA\DAV\CardDAV\SyncService; use OCA\DAV\Migration\CreateSystemAddressBookStep; @@ -17,7 +17,7 @@ use PHPUnit\Framework\TestCase; class CreateSystemAddressBookStepTest extends TestCase { - private SyncService|MockObject $syncService; + private SyncService&MockObject $syncService; private CreateSystemAddressBookStep $step; protected function setUp(): void { diff --git a/apps/dav/tests/unit/Migration/RefreshWebcalJobRegistrarTest.php b/apps/dav/tests/unit/Migration/RefreshWebcalJobRegistrarTest.php index bf4c60b3cf1..73d9c1efd29 100644 --- a/apps/dav/tests/unit/Migration/RefreshWebcalJobRegistrarTest.php +++ b/apps/dav/tests/unit/Migration/RefreshWebcalJobRegistrarTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,17 +14,13 @@ use OCP\DB\IResult; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\Migration\IOutput; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class RefreshWebcalJobRegistrarTest extends TestCase { - /** @var IDBConnection | \PHPUnit\Framework\MockObject\MockObject */ - private $db; - - /** @var IJobList | \PHPUnit\Framework\MockObject\MockObject */ - private $jobList; - - /** @var RefreshWebcalJobRegistrar */ - private $migration; + private IDBConnection&MockObject $db; + private IJobList&MockObject $jobList; + private RefreshWebcalJobRegistrar $migration; protected function setUp(): void { parent::setUp(); @@ -80,35 +78,37 @@ class RefreshWebcalJobRegistrarTest extends TestCase { $this->jobList->expects($this->exactly(3)) ->method('has') - ->withConsecutive( + ->willReturnMap([ [RefreshWebcalJob::class, [ 'principaluri' => 'foo1', 'uri' => 'bar1', - ]], + ], false], [RefreshWebcalJob::class, [ 'principaluri' => 'foo2', 'uri' => 'bar2', - ]], + ], true ], [RefreshWebcalJob::class, [ 'principaluri' => 'foo3', 'uri' => 'bar3', - ]]) - ->willReturnOnConsecutiveCalls( - false, - true, - false, - ); + ], false], + ]); + + $calls = [ + [RefreshWebcalJob::class, [ + 'principaluri' => 'foo1', + 'uri' => 'bar1', + ]], + [RefreshWebcalJob::class, [ + 'principaluri' => 'foo3', + 'uri' => 'bar3', + ]] + ]; $this->jobList->expects($this->exactly(2)) ->method('add') - ->withConsecutive( - [RefreshWebcalJob::class, [ - 'principaluri' => 'foo1', - 'uri' => 'bar1', - ]], - [RefreshWebcalJob::class, [ - 'principaluri' => 'foo3', - 'uri' => 'bar3', - ]]); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $output->expects($this->once()) ->method('info') diff --git a/apps/dav/tests/unit/Migration/RegenerateBirthdayCalendarsTest.php b/apps/dav/tests/unit/Migration/RegenerateBirthdayCalendarsTest.php index e2ac45526d2..6f681badb8b 100644 --- a/apps/dav/tests/unit/Migration/RegenerateBirthdayCalendarsTest.php +++ b/apps/dav/tests/unit/Migration/RegenerateBirthdayCalendarsTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -10,18 +12,13 @@ use OCA\DAV\Migration\RegenerateBirthdayCalendars; use OCP\BackgroundJob\IJobList; use OCP\IConfig; use OCP\Migration\IOutput; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class RegenerateBirthdayCalendarsTest extends TestCase { - - /** @var IJobList | \PHPUnit\Framework\MockObject\MockObject */ - private $jobList; - - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ - private $config; - - /** @var RegenerateBirthdayCalendars */ - private $migration; + private IJobList&MockObject $jobList; + private IConfig&MockObject $config; + private RegenerateBirthdayCalendars $migration; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php b/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php index a3daf1c918a..0a646e91602 100644 --- a/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php +++ b/apps/dav/tests/unit/Migration/RemoveDeletedUsersCalendarSubscriptionsTest.php @@ -22,23 +22,10 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class RemoveDeletedUsersCalendarSubscriptionsTest extends TestCase { - /** - * @var IDBConnection|MockObject - */ - private $dbConnection; - /** - * @var IUserManager|MockObject - */ - private $userManager; - - /** - * @var IOutput|MockObject - */ - private $output; - /** - * @var RemoveDeletedUsersCalendarSubscriptions - */ - private $migration; + private IDBConnection&MockObject $dbConnection; + private IUserManager&MockObject $userManager; + private IOutput&MockObject $output; + private RemoveDeletedUsersCalendarSubscriptions $migration; protected function setUp(): void { @@ -60,10 +47,6 @@ class RemoveDeletedUsersCalendarSubscriptionsTest extends TestCase { /** * @dataProvider dataTestRun - * @param array $subscriptions - * @param array $userExists - * @param int $deletions - * @throws \Exception */ public function testRun(array $subscriptions, array $userExists, int $deletions): void { $qb = $this->createMock(IQueryBuilder::class); @@ -132,21 +115,28 @@ class RemoveDeletedUsersCalendarSubscriptionsTest extends TestCase { $this->migration->run($this->output); } - public function dataTestRun(): array { + public static function dataTestRun(): array { return [ [[], [], 0], - [[[ - 'id' => 1, - 'principaluri' => 'users/principals/foo1', - ], + [ [ - 'id' => 2, - 'principaluri' => 'users/principals/bar1', + [ + 'id' => 1, + 'principaluri' => 'users/principals/foo1', + ], + [ + 'id' => 2, + 'principaluri' => 'users/principals/bar1', + ], + [ + 'id' => 3, + 'principaluri' => 'users/principals/bar1', + ], + [], ], - [ - 'id' => 3, - 'principaluri' => 'users/principals/bar1', - ]], ['foo1' => true, 'bar1' => false], 2] + ['foo1' => true, 'bar1' => false], + 2 + ], ]; } } diff --git a/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningNodeTest.php b/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningNodeTest.php index 0979aff8a81..53de908ca27 100644 --- a/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningNodeTest.php +++ b/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningNodeTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -7,15 +9,13 @@ namespace OCA\DAV\Tests\unit\Provisioning\Apple; use OCA\DAV\Provisioning\Apple\AppleProvisioningNode; use OCP\AppFramework\Utility\ITimeFactory; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\PropPatch; use Test\TestCase; class AppleProvisioningNodeTest extends TestCase { - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var AppleProvisioningNode */ - private $node; + private ITimeFactory&MockObject $timeFactory; + private AppleProvisioningNode $node; protected function setUp(): void { parent::setUp(); @@ -28,7 +28,6 @@ class AppleProvisioningNodeTest extends TestCase { $this->assertEquals('apple-provisioning.mobileconfig', $this->node->getName()); } - public function testSetName(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); $this->expectExceptionMessage('Renaming apple-provisioning.mobileconfig is forbidden'); diff --git a/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningPluginTest.php b/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningPluginTest.php index dbb399ea7a6..ba44efe7421 100644 --- a/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningPluginTest.php +++ b/apps/dav/tests/unit/Provisioning/Apple/AppleProvisioningPluginTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,40 +14,27 @@ use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; +use Sabre\DAV\Server; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; use Test\TestCase; class AppleProvisioningPluginTest extends TestCase { - /** @var \Sabre\DAV\Server|\PHPUnit\Framework\MockObject\MockObject */ - protected $server; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - protected $userSession; - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - protected $urlGenerator; - - /** @var ThemingDefaults|\PHPUnit\Framework\MockObject\MockObject */ - protected $themingDefaults; - - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - protected $request; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - protected $l10n; - - /** @var \Sabre\HTTP\RequestInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $sabreRequest; - - /** @var \Sabre\HTTP\ResponseInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $sabreResponse; - - /** @var AppleProvisioningPlugin */ - protected $plugin; + protected Server&MockObject $server; + protected IUserSession&MockObject $userSession; + protected IURLGenerator&MockObject $urlGenerator; + protected ThemingDefaults&MockObject $themingDefaults; + protected IRequest&MockObject $request; + protected IL10N&MockObject $l10n; + protected RequestInterface&MockObject $sabreRequest; + protected ResponseInterface&MockObject $sabreResponse; + protected AppleProvisioningPlugin $plugin; protected function setUp(): void { parent::setUp(); - $this->server = $this->createMock(\Sabre\DAV\Server::class); + $this->server = $this->createMock(Server::class); $this->userSession = $this->createMock(IUserSession::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->themingDefaults = $this->createMock(ThemingDefaults::class); @@ -62,12 +51,12 @@ class AppleProvisioningPluginTest extends TestCase { } ); - $this->sabreRequest = $this->createMock(\Sabre\HTTP\RequestInterface::class); - $this->sabreResponse = $this->createMock(\Sabre\HTTP\ResponseInterface::class); + $this->sabreRequest = $this->createMock(RequestInterface::class); + $this->sabreResponse = $this->createMock(ResponseInterface::class); } public function testInitialize(): void { - $server = $this->createMock(\Sabre\DAV\Server::class); + $server = $this->createMock(Server::class); $plugin = new AppleProvisioningPlugin($this->userSession, $this->urlGenerator, $this->themingDefaults, $this->request, $this->l10n, @@ -149,24 +138,25 @@ class AppleProvisioningPluginTest extends TestCase { $this->l10n->expects($this->exactly(2)) ->method('t') - ->withConsecutive( - ['Configures a CalDAV account'], - ['Configures a CardDAV account'], - ) - ->willReturnOnConsecutiveCalls( - 'LocalizedConfiguresCalDAV', - 'LocalizedConfiguresCardDAV', - ); + ->willReturnMap([ + ['Configures a CalDAV account', [], 'LocalizedConfiguresCalDAV'], + ['Configures a CardDAV account', [], 'LocalizedConfiguresCardDAV'], + ]); $this->sabreResponse->expects($this->once()) ->method('setStatus') ->with(200); + + $calls = [ + ['Content-Disposition', 'attachment; filename="userName-apple-provisioning.mobileconfig"'], + ['Content-Type', 'application/xml; charset=utf-8'], + ]; $this->sabreResponse->expects($this->exactly(2)) ->method('setHeader') - ->withConsecutive( - ['Content-Disposition', 'attachment; filename="userName-apple-provisioning.mobileconfig"'], - ['Content-Type', 'application/xml; charset=utf-8'], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $this->sabreResponse->expects($this->once()) ->method('setBody') ->with(<<<EOF diff --git a/apps/dav/tests/unit/Search/ContactsSearchProviderTest.php b/apps/dav/tests/unit/Search/ContactsSearchProviderTest.php index 0a83d238f0f..f0e5a5ea354 100644 --- a/apps/dav/tests/unit/Search/ContactsSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/ContactsSearchProviderTest.php @@ -17,27 +17,18 @@ use OCP\IUser; use OCP\Search\ISearchQuery; use OCP\Search\SearchResult; use OCP\Search\SearchResultEntry; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Reader; use Test\TestCase; class ContactsSearchProviderTest extends TestCase { + private IAppManager&MockObject $appManager; + private IL10N&MockObject $l10n; + private IURLGenerator&MockObject $urlGenerator; + private CardDavBackend&MockObject $backend; + private ContactsSearchProvider $provider; - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ - private $appManager; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10n; - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var CardDavBackend|\PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @var ContactsSearchProvider */ - private $provider; - - private $vcardTest0 = 'BEGIN:VCARD' . PHP_EOL . + private string $vcardTest0 = 'BEGIN:VCARD' . PHP_EOL . 'VERSION:3.0' . PHP_EOL . 'PRODID:-//Sabre//Sabre VObject 4.1.2//EN' . PHP_EOL . 'UID:Test' . PHP_EOL . @@ -46,7 +37,7 @@ class ContactsSearchProviderTest extends TestCase { 'EMAIL:forrestgump@example.com' . PHP_EOL . 'END:VCARD'; - private $vcardTest1 = 'BEGIN:VCARD' . PHP_EOL . + private string $vcardTest1 = 'BEGIN:VCARD' . PHP_EOL . 'VERSION:3.0' . PHP_EOL . 'PRODID:-//Sabre//Sabre VObject 4.1.2//EN' . PHP_EOL . 'PHOTO;ENCODING=b;TYPE=image/jpeg:' . PHP_EOL . @@ -174,7 +165,7 @@ class ContactsSearchProviderTest extends TestCase { $this->urlGenerator, $this->backend, ]) - ->setMethods([ + ->onlyMethods([ 'getDavUrlForContact', 'getDeepLinkToContactsApp', 'generateSubline', @@ -191,11 +182,10 @@ class ContactsSearchProviderTest extends TestCase { ->willReturn('subline'); $provider->expects($this->exactly(2)) ->method('getDeepLinkToContactsApp') - ->withConsecutive( - ['addressbook-uri-99', 'Test'], - ['addressbook-uri-123', 'Test2'] - ) - ->willReturn('deep-link-to-contacts'); + ->willReturnMap([ + ['addressbook-uri-99', 'Test', 'deep-link-to-contacts'], + ['addressbook-uri-123', 'Test2', 'deep-link-to-contacts'], + ]); $actual = $provider->search($user, $query); $data = $actual->jsonSerialize(); diff --git a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php index 0eafe0782e5..7c0b74e8ff3 100644 --- a/apps/dav/tests/unit/Search/EventsSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/EventsSearchProviderTest.php @@ -18,27 +18,19 @@ use OCP\Search\IFilter; use OCP\Search\ISearchQuery; use OCP\Search\SearchResult; use OCP\Search\SearchResultEntry; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Reader; use Test\TestCase; class EventsSearchProviderTest extends TestCase { - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ - private $appManager; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10n; - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var CalDavBackend|\PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @var EventsSearchProvider */ - private $provider; + private IAppManager&MockObject $appManager; + private IL10N&MockObject $l10n; + private IURLGenerator&MockObject $urlGenerator; + private CalDavBackend&MockObject $backend; + private EventsSearchProvider $provider; // NO SUMMARY - private $vEvent0 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent0 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Apple Inc.//Mac OS X 10.11.6//EN' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -54,7 +46,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // TIMED SAME DAY - private $vEvent1 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent1 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Tests//' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -88,7 +80,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // TIMED DIFFERENT DAY - private $vEvent2 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent2 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Tests//' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -122,7 +114,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // ALL-DAY ONE-DAY - private $vEvent3 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent3 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Apple Inc.//Mac OS X 10.11.6//EN' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -138,7 +130,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // ALL-DAY MULTIPLE DAYS - private $vEvent4 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent4 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Apple Inc.//Mac OS X 10.11.6//EN' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -154,7 +146,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // DURATION - private $vEvent5 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent5 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Apple Inc.//Mac OS X 10.11.6//EN' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -170,7 +162,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // NO DTEND - DATE - private $vEvent6 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent6 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Apple Inc.//Mac OS X 10.11.6//EN' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -185,7 +177,7 @@ class EventsSearchProviderTest extends TestCase { 'END:VCALENDAR'; // NO DTEND - DATE-TIME - private $vEvent7 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vEvent7 = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//Tests//' . PHP_EOL . 'CALSCALE:GREGORIAN' . PHP_EOL . @@ -327,19 +319,19 @@ class EventsSearchProviderTest extends TestCase { 'calendarid' => 99, 'calendartype' => CalDavBackend::CALENDAR_TYPE_CALENDAR, 'uri' => 'event0.ics', - 'calendardata' => $this->vEvent0, + 'calendardata' => self::$vEvent0, ], [ 'calendarid' => 123, 'calendartype' => CalDavBackend::CALENDAR_TYPE_CALENDAR, 'uri' => 'event1.ics', - 'calendardata' => $this->vEvent1, + 'calendardata' => self::$vEvent1, ], [ 'calendarid' => 1337, 'calendartype' => CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION, 'uri' => 'event2.ics', - 'calendardata' => $this->vEvent2, + 'calendardata' => self::$vEvent2, ] ]); @@ -350,7 +342,7 @@ class EventsSearchProviderTest extends TestCase { $this->urlGenerator, $this->backend, ]) - ->setMethods([ + ->onlyMethods([ 'getDeepLinkToCalendarApp', 'generateSubline', ]) @@ -361,12 +353,11 @@ class EventsSearchProviderTest extends TestCase { ->willReturn('subline'); $provider->expects($this->exactly(3)) ->method('getDeepLinkToCalendarApp') - ->withConsecutive( - ['principals/users/john.doe', 'calendar-uri-99', 'event0.ics'], - ['principals/users/john.doe', 'calendar-uri-123', 'event1.ics'], - ['principals/users/john.doe', 'subscription-uri-1337', 'event2.ics'] - ) - ->willReturn('deep-link-to-calendar'); + ->willReturnMap([ + ['principals/users/john.doe', 'calendar-uri-99', 'event0.ics', 'deep-link-to-calendar'], + ['principals/users/john.doe', 'calendar-uri-123', 'event1.ics', 'deep-link-to-calendar'], + ['principals/users/john.doe', 'subscription-uri-1337', 'event2.ics', 'deep-link-to-calendar'] + ]); $actual = $provider->search($user, $query); $data = $actual->jsonSerialize(); @@ -428,9 +419,6 @@ class EventsSearchProviderTest extends TestCase { } /** - * @param string $ics - * @param string $expectedSubline - * * @dataProvider generateSublineDataProvider */ public function testGenerateSubline(string $ics, string $expectedSubline): void { @@ -450,15 +438,15 @@ class EventsSearchProviderTest extends TestCase { $this->assertEquals($expectedSubline, $actual); } - public function generateSublineDataProvider(): array { + public static function generateSublineDataProvider(): array { return [ - [$this->vEvent1, '08-16 09:00 - 10:00'], - [$this->vEvent2, '08-16 09:00 - 08-17 10:00'], - [$this->vEvent3, '10-05'], - [$this->vEvent4, '10-05 - 10-07'], - [$this->vEvent5, '10-05 - 10-09'], - [$this->vEvent6, '10-05'], - [$this->vEvent7, '08-16 09:00 - 09:00'], + [self::$vEvent1, '08-16 09:00 - 10:00'], + [self::$vEvent2, '08-16 09:00 - 08-17 10:00'], + [self::$vEvent3, '10-05'], + [self::$vEvent4, '10-05 - 10-07'], + [self::$vEvent5, '10-05 - 10-09'], + [self::$vEvent6, '10-05'], + [self::$vEvent7, '08-16 09:00 - 09:00'], ]; } } diff --git a/apps/dav/tests/unit/Search/TasksSearchProviderTest.php b/apps/dav/tests/unit/Search/TasksSearchProviderTest.php index de4e29058da..bd242080547 100644 --- a/apps/dav/tests/unit/Search/TasksSearchProviderTest.php +++ b/apps/dav/tests/unit/Search/TasksSearchProviderTest.php @@ -17,28 +17,19 @@ use OCP\IUser; use OCP\Search\ISearchQuery; use OCP\Search\SearchResult; use OCP\Search\SearchResultEntry; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Reader; use Test\TestCase; class TasksSearchProviderTest extends TestCase { - - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ - private $appManager; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10n; - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var CalDavBackend|\PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @var TasksSearchProvider */ - private $provider; + private IAppManager&MockObject $appManager; + private IL10N&MockObject $l10n; + private IURLGenerator&MockObject $urlGenerator; + private CalDavBackend&MockObject $backend; + private TasksSearchProvider $provider; // NO DUE NOR COMPLETED NOR SUMMARY - private $vTodo0 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vTodo0 = 'BEGIN:VCALENDAR' . PHP_EOL . 'PRODID:TEST' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'BEGIN:VTODO' . PHP_EOL . @@ -49,7 +40,7 @@ class TasksSearchProviderTest extends TestCase { 'END:VCALENDAR'; // DUE AND COMPLETED - private $vTodo1 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vTodo1 = 'BEGIN:VCALENDAR' . PHP_EOL . 'PRODID:TEST' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'BEGIN:VTODO' . PHP_EOL . @@ -63,7 +54,7 @@ class TasksSearchProviderTest extends TestCase { 'END:VCALENDAR'; // COMPLETED ONLY - private $vTodo2 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vTodo2 = 'BEGIN:VCALENDAR' . PHP_EOL . 'PRODID:TEST' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'BEGIN:VTODO' . PHP_EOL . @@ -76,7 +67,7 @@ class TasksSearchProviderTest extends TestCase { 'END:VCALENDAR'; // DUE DATE - private $vTodo3 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vTodo3 = 'BEGIN:VCALENDAR' . PHP_EOL . 'PRODID:TEST' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'BEGIN:VTODO' . PHP_EOL . @@ -89,7 +80,7 @@ class TasksSearchProviderTest extends TestCase { 'END:VCALENDAR'; // DUE DATETIME - private $vTodo4 = 'BEGIN:VCALENDAR' . PHP_EOL . + private static string $vTodo4 = 'BEGIN:VCALENDAR' . PHP_EOL . 'PRODID:TEST' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'BEGIN:VTODO' . PHP_EOL . @@ -204,19 +195,19 @@ class TasksSearchProviderTest extends TestCase { 'calendarid' => 99, 'calendartype' => CalDavBackend::CALENDAR_TYPE_CALENDAR, 'uri' => 'todo0.ics', - 'calendardata' => $this->vTodo0, + 'calendardata' => self::$vTodo0, ], [ 'calendarid' => 123, 'calendartype' => CalDavBackend::CALENDAR_TYPE_CALENDAR, 'uri' => 'todo1.ics', - 'calendardata' => $this->vTodo1, + 'calendardata' => self::$vTodo1, ], [ 'calendarid' => 1337, 'calendartype' => CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION, 'uri' => 'todo2.ics', - 'calendardata' => $this->vTodo2, + 'calendardata' => self::$vTodo2, ] ]); @@ -227,7 +218,7 @@ class TasksSearchProviderTest extends TestCase { $this->urlGenerator, $this->backend, ]) - ->setMethods([ + ->onlyMethods([ 'getDeepLinkToTasksApp', 'generateSubline', ]) @@ -238,12 +229,11 @@ class TasksSearchProviderTest extends TestCase { ->willReturn('subline'); $provider->expects($this->exactly(3)) ->method('getDeepLinkToTasksApp') - ->withConsecutive( - ['calendar-uri-99', 'todo0.ics'], - ['calendar-uri-123', 'todo1.ics'], - ['subscription-uri-1337', 'todo2.ics'] - ) - ->willReturn('deep-link-to-tasks'); + ->willReturnMap([ + ['calendar-uri-99', 'todo0.ics', 'deep-link-to-tasks'], + ['calendar-uri-123', 'todo1.ics', 'deep-link-to-tasks'], + ['subscription-uri-1337', 'todo2.ics', 'deep-link-to-tasks'] + ]); $actual = $provider->search($user, $query); $data = $actual->jsonSerialize(); @@ -300,9 +290,6 @@ class TasksSearchProviderTest extends TestCase { } /** - * @param string $ics - * @param string $expectedSubline - * * @dataProvider generateSublineDataProvider */ public function testGenerateSubline(string $ics, string $expectedSubline): void { @@ -310,19 +297,19 @@ class TasksSearchProviderTest extends TestCase { $taskComponent = $vCalendar->VTODO; $this->l10n->method('t')->willReturnArgument(0); - $this->l10n->method('l')->willReturnArgument(''); + $this->l10n->method('l')->willReturnArgument(0); $actual = self::invokePrivate($this->provider, 'generateSubline', [$taskComponent]); $this->assertEquals($expectedSubline, $actual); } - public function generateSublineDataProvider(): array { + public static function generateSublineDataProvider(): array { return [ - [$this->vTodo0, ''], - [$this->vTodo1, 'Completed on %s'], - [$this->vTodo2, 'Completed on %s'], - [$this->vTodo3, 'Due on %s'], - [$this->vTodo4, 'Due on %s by %s'], + [self::$vTodo0, ''], + [self::$vTodo1, 'Completed on %s'], + [self::$vTodo2, 'Completed on %s'], + [self::$vTodo3, 'Due on %s'], + [self::$vTodo4, 'Due on %s by %s'], ]; } } diff --git a/apps/dav/tests/unit/ServerTest.php b/apps/dav/tests/unit/ServerTest.php index 16e0a5b80aa..0baef015056 100644 --- a/apps/dav/tests/unit/ServerTest.php +++ b/apps/dav/tests/unit/ServerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -22,7 +23,7 @@ class ServerTest extends \Test\TestCase { /** * @dataProvider providesUris */ - public function test($uri, array $plugins): void { + public function test(string $uri, array $plugins): void { /** @var IRequest | \PHPUnit\Framework\MockObject\MockObject $r */ $r = $this->createMock(IRequest::class); $r->expects($this->any())->method('getRequestUri')->willReturn($uri); @@ -33,7 +34,7 @@ class ServerTest extends \Test\TestCase { $this->assertNotNull($s->server->getPlugin($plugin)); } } - public function providesUris() { + public static function providesUris(): array { return [ 'principals' => ['principals/users/admin', ['caldav', 'oc-resource-sharing', 'carddav']], 'calendars' => ['calendars/admin', ['caldav', 'oc-resource-sharing']], diff --git a/apps/dav/tests/unit/Service/AbsenceServiceTest.php b/apps/dav/tests/unit/Service/AbsenceServiceTest.php index 5cff29a6f61..c16c715d5c2 100644 --- a/apps/dav/tests/unit/Service/AbsenceServiceTest.php +++ b/apps/dav/tests/unit/Service/AbsenceServiceTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\dav\tests\unit\Service; +namespace OCA\DAV\Tests\unit\Service; use DateTimeImmutable; use DateTimeZone; @@ -24,25 +24,16 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IUser; use OCP\User\Events\OutOfOfficeChangedEvent; use OCP\User\Events\OutOfOfficeScheduledEvent; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class AbsenceServiceTest extends TestCase { private AbsenceService $absenceService; - - /** @var MockObject|AbsenceMapper */ - private $absenceMapper; - - /** @var MockObject|IEventDispatcher */ - private $eventDispatcher; - - /** @var MockObject|IJobList */ - private $jobList; - - /** @var MockObject|TimezoneService */ - private $timezoneService; - - /** @var MockObject|ITimeFactory */ - private $timeFactory; + private AbsenceMapper&MockObject $absenceMapper; + private IEventDispatcher&MockObject $eventDispatcher; + private IJobList&MockObject $jobList; + private TimezoneService&MockObject $timezoneService; + private ITimeFactory&MockObject $timeFactory; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Service/DefaultContactServiceTest.php b/apps/dav/tests/unit/Service/DefaultContactServiceTest.php index 68bbc02ed08..3bd8c9cb6f6 100644 --- a/apps/dav/tests/unit/Service/DefaultContactServiceTest.php +++ b/apps/dav/tests/unit/Service/DefaultContactServiceTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\Service; +namespace OCA\DAV\Tests\unit\Service; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Service\DefaultContactService; @@ -24,12 +24,12 @@ use Symfony\Component\Uid\Uuid; use Test\TestCase; class DefaultContactServiceTest extends TestCase { - private DefaultContactService $service; - private MockObject|CardDavBackend $cardDav; - private MockObject|IAppManager $appManager; - private MockObject|IAppDataFactory $appDataFactory; - private MockObject|LoggerInterface $logger; - private MockObject|IAppConfig $config; + protected DefaultContactService $service; + protected CardDavBackend&MockObject $cardDav; + protected IAppManager&MockObject $appManager; + protected IAppDataFactory&MockObject $appDataFactory; + protected LoggerInterface&MockObject $logger; + protected IAppConfig&MockObject $config; protected function setUp(): void { parent::setUp(); @@ -84,7 +84,7 @@ class DefaultContactServiceTest extends TestCase { $folder->method('getFile')->willReturn($file); $appData->method('getFolder')->willReturn($folder); $this->appDataFactory->method('get')->willReturn($appData); - + $capturedCardData = null; $this->cardDav->expects($this->once()) ->method('createCard') @@ -97,9 +97,9 @@ class DefaultContactServiceTest extends TestCase { }), $this->anything() )->willReturn(null); - + $this->service->createDefaultContact(123); - + $vcard = \Sabre\VObject\Reader::read($capturedCardData); $this->assertNotEquals($originalUid, $vcard->UID->getValue()); $this->assertTrue(Uuid::isValid($vcard->UID->getValue())); diff --git a/apps/dav/tests/unit/Service/UpcomingEventsServiceTest.php b/apps/dav/tests/unit/Service/UpcomingEventsServiceTest.php index ecb0268c8c2..fdfe37d8918 100644 --- a/apps/dav/tests/unit/Service/UpcomingEventsServiceTest.php +++ b/apps/dav/tests/unit/Service/UpcomingEventsServiceTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Service; +namespace OCA\DAV\Tests\unit\DAV\Service; use DateTimeImmutable; use OCA\DAV\CalDAV\UpcomingEventsService; @@ -22,11 +22,11 @@ use PHPUnit\Framework\TestCase; class UpcomingEventsServiceTest extends TestCase { - private MockObject|IManager $calendarManager; - private ITimeFactory|MockObject $timeFactory; - private IUserManager|MockObject $userManager; - private IAppManager|MockObject $appManager; - private IURLGenerator|MockObject $urlGenerator; + private IManager&MockObject $calendarManager; + private ITimeFactory&MockObject $timeFactory; + private IUserManager&MockObject $userManager; + private IAppManager&MockObject $appManager; + private IURLGenerator&MockObject $urlGenerator; private UpcomingEventsService $service; protected function setUp(): void { diff --git a/apps/dav/tests/unit/Settings/CalDAVSettingsTest.php b/apps/dav/tests/unit/Settings/CalDAVSettingsTest.php index 9f2d2582884..df7a08d5d08 100644 --- a/apps/dav/tests/unit/Settings/CalDAVSettingsTest.php +++ b/apps/dav/tests/unit/Settings/CalDAVSettingsTest.php @@ -1,9 +1,11 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\DAV\Tests\Unit\DAV\Settings; +namespace OCA\DAV\Tests\unit\DAV\Settings; use OCA\DAV\Settings\CalDAVSettings; use OCP\App\IAppManager; @@ -15,19 +17,10 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class CalDAVSettingsTest extends TestCase { - - /** @var IConfig|MockObject */ - private $config; - - /** @var IInitialState|MockObject */ - private $initialState; - - /** @var IURLGenerator|MockObject */ - private $urlGenerator; - - /** @var IAppManager|MockObject */ - private $appManager; - + private IConfig&MockObject $config; + private IInitialState&MockObject $initialState; + private IURLGenerator&MockObject $urlGenerator; + private IAppManager&MockObject $appManager; private CalDAVSettings $settings; protected function setUp(): void { @@ -42,28 +35,32 @@ class CalDAVSettingsTest extends TestCase { public function testGetForm(): void { $this->config->method('getAppValue') - ->withConsecutive( - ['dav', 'sendInvitations', 'yes'], - ['dav', 'generateBirthdayCalendar', 'yes'], - ['dav', 'sendEventReminders', 'yes'], - ['dav', 'sendEventRemindersToSharedUsers', 'yes'], - ['dav', 'sendEventRemindersPush', 'yes'], - ) - ->will($this->onConsecutiveCalls('yes', 'no', 'yes', 'yes', 'yes')); + ->willReturnMap([ + ['dav', 'sendInvitations', 'yes', 'yes'], + ['dav', 'generateBirthdayCalendar', 'yes', 'no'], + ['dav', 'sendEventReminders', 'yes', 'yes'], + ['dav', 'sendEventRemindersToSharedUsers', 'yes', 'yes'], + ['dav', 'sendEventRemindersPush', 'yes', 'yes'], + ]); $this->urlGenerator ->expects($this->once()) ->method('linkToDocs') ->with('user-sync-calendars') ->willReturn('Some docs URL'); + + $calls = [ + ['userSyncCalendarsDocUrl', 'Some docs URL'], + ['sendInvitations', true], + ['generateBirthdayCalendar', false], + ['sendEventReminders', true], + ['sendEventRemindersToSharedUsers', true], + ['sendEventRemindersPush', true], + ]; $this->initialState->method('provideInitialState') - ->withConsecutive( - ['userSyncCalendarsDocUrl', 'Some docs URL'], - ['sendInvitations', true], - ['generateBirthdayCalendar', false], - ['sendEventReminders', true], - ['sendEventRemindersToSharedUsers', true], - ['sendEventRemindersPush', true], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $result = $this->settings->getForm(); $this->assertInstanceOf(TemplateResponse::class, $result); @@ -88,5 +85,4 @@ class CalDAVSettingsTest extends TestCase { public function testGetPriority(): void { $this->assertEquals(10, $this->settings->getPriority()); } - } diff --git a/apps/dav/tests/unit/SystemTag/SystemTagMappingNodeTest.php b/apps/dav/tests/unit/SystemTag/SystemTagMappingNodeTest.php index ed830685b7a..0096b188291 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagMappingNodeTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagMappingNodeTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -14,30 +15,28 @@ use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; +use PHPUnit\Framework\MockObject\MockObject; class SystemTagMappingNodeTest extends \Test\TestCase { - private ISystemTagManager $tagManager; - private ISystemTagObjectMapper $tagMapper; - private IUser $user; + private ISystemTagManager&MockObject $tagManager; + private ISystemTagObjectMapper&MockObject $tagMapper; + private IUser&MockObject $user; protected function setUp(): void { parent::setUp(); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); - $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); - $this->user = $this->getMockBuilder(IUser::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); + $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); + $this->user = $this->createMock(IUser::class); } public function getMappingNode($tag = null, array $writableNodeIds = []) { if ($tag === null) { - $tag = new SystemTag(1, 'Test', true, true); + $tag = new SystemTag('1', 'Test', true, true); } return new SystemTagMappingNode( $tag, - 123, + '123', 'files', $this->user, $this->tagManager, @@ -47,7 +46,7 @@ class SystemTagMappingNodeTest extends \Test\TestCase { } public function testGetters(): void { - $tag = new SystemTag(1, 'Test', true, false); + $tag = new SystemTag('1', 'Test', true, false); $node = $this->getMappingNode($tag); $this->assertEquals('1', $node->getName()); $this->assertEquals($tag, $node->getSystemTag()); @@ -93,16 +92,16 @@ class SystemTagMappingNodeTest extends \Test\TestCase { $node->delete(); } - public function tagNodeDeleteProviderPermissionException() { + public static function tagNodeDeleteProviderPermissionException(): array { return [ [ // cannot unassign invisible tag - new SystemTag(1, 'Original', false, true), + new SystemTag('1', 'Original', false, true), 'Sabre\DAV\Exception\NotFound', ], [ // cannot unassign non-assignable tag - new SystemTag(1, 'Original', true, false), + new SystemTag('1', 'Original', true, false), 'Sabre\DAV\Exception\Forbidden', ], ]; @@ -141,7 +140,7 @@ class SystemTagMappingNodeTest extends \Test\TestCase { // assuming the tag existed at the time the node was created, // but got deleted concurrently in the database - $tag = new SystemTag(1, 'Test', true, true); + $tag = new SystemTag('1', 'Test', true, true); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($tag) diff --git a/apps/dav/tests/unit/SystemTag/SystemTagNodeTest.php b/apps/dav/tests/unit/SystemTag/SystemTagNodeTest.php index 32ee733dce8..642cc21319b 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagNodeTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagNodeTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -15,39 +16,25 @@ use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagAlreadyExistsException; use OCP\SystemTag\TagNotFoundException; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\Forbidden; class SystemTagNodeTest extends \Test\TestCase { - - /** - * @var ISystemTagManager|\PHPUnit\Framework\MockObject\MockObject - */ - private $tagManager; - - /** - * @var ISystemTagObjectMapper|\PHPUnit\Framework\MockObject\MockObject - */ - private $tagMapper; - - /** - * @var IUser - */ - private $user; + private ISystemTagManager&MockObject $tagManager; + private ISystemTagObjectMapper&MockObject $tagMapper; + private IUser&MockObject $user; protected function setUp(): void { parent::setUp(); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); - $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); - $this->user = $this->getMockBuilder(IUser::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); + $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); + $this->user = $this->createMock(IUser::class); } protected function getTagNode($isAdmin = true, $tag = null) { if ($tag === null) { - $tag = new SystemTag(1, 'Test', true, true); + $tag = new SystemTag('1', 'Test', true, true); } return new SystemTagNode( $tag, @@ -58,14 +45,14 @@ class SystemTagNodeTest extends \Test\TestCase { ); } - public function adminFlagProvider() { + public static function adminFlagProvider(): array { return [[true], [false]]; } /** * @dataProvider adminFlagProvider */ - public function testGetters($isAdmin): void { + public function testGetters(bool $isAdmin): void { $tag = new SystemTag('1', 'Test', true, true); $node = $this->getTagNode($isAdmin, $tag); $this->assertEquals('1', $node->getName()); @@ -79,24 +66,24 @@ class SystemTagNodeTest extends \Test\TestCase { $this->getTagNode()->setName('2'); } - public function tagNodeProvider() { + public static function tagNodeProvider(): array { return [ // admin [ true, - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Renamed', true, true, null] ], [ true, - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Original', false, false, null] ], // non-admin [ // renaming allowed false, - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Rename', true, true, '0082c9'] ], ]; @@ -105,7 +92,7 @@ class SystemTagNodeTest extends \Test\TestCase { /** * @dataProvider tagNodeProvider */ - public function testUpdateTag($isAdmin, ISystemTag $originalTag, $changedArgs): void { + public function testUpdateTag(bool $isAdmin, ISystemTag $originalTag, array $changedArgs): void { $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($originalTag) @@ -121,41 +108,41 @@ class SystemTagNodeTest extends \Test\TestCase { ->update($changedArgs[0], $changedArgs[1], $changedArgs[2], $changedArgs[3]); } - public function tagNodeProviderPermissionException() { + public static function tagNodeProviderPermissionException(): array { return [ [ // changing permissions not allowed - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Original', false, true, ''], 'Sabre\DAV\Exception\Forbidden', ], [ // changing permissions not allowed - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Original', true, false, ''], 'Sabre\DAV\Exception\Forbidden', ], [ // changing permissions not allowed - new SystemTag(1, 'Original', true, true), + new SystemTag('1', 'Original', true, true), ['Original', false, false, ''], 'Sabre\DAV\Exception\Forbidden', ], [ // changing non-assignable not allowed - new SystemTag(1, 'Original', true, false), + new SystemTag('1', 'Original', true, false), ['Rename', true, false, ''], 'Sabre\DAV\Exception\Forbidden', ], [ // changing non-assignable not allowed - new SystemTag(1, 'Original', true, false), + new SystemTag('1', 'Original', true, false), ['Original', true, true, ''], 'Sabre\DAV\Exception\Forbidden', ], [ // invisible tag does not exist - new SystemTag(1, 'Original', false, false), + new SystemTag('1', 'Original', false, false), ['Rename', false, false, ''], 'Sabre\DAV\Exception\NotFound', ], @@ -165,7 +152,7 @@ class SystemTagNodeTest extends \Test\TestCase { /** * @dataProvider tagNodeProviderPermissionException */ - public function testUpdateTagPermissionException(ISystemTag $originalTag, $changedArgs, $expectedException = null): void { + public function testUpdateTagPermissionException(ISystemTag $originalTag, array $changedArgs, string $expectedException): void { $this->tagManager->expects($this->any()) ->method('canUserSeeTag') ->with($originalTag) @@ -193,7 +180,7 @@ class SystemTagNodeTest extends \Test\TestCase { public function testUpdateTagAlreadyExists(): void { $this->expectException(\Sabre\DAV\Exception\Conflict::class); - $tag = new SystemTag(1, 'tag1', true, true); + $tag = new SystemTag('1', 'tag1', true, true); $this->tagManager->expects($this->any()) ->method('canUserSeeTag') ->with($tag) @@ -213,7 +200,7 @@ class SystemTagNodeTest extends \Test\TestCase { public function testUpdateTagNotFound(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $tag = new SystemTag(1, 'tag1', true, true); + $tag = new SystemTag('1', 'tag1', true, true); $this->tagManager->expects($this->any()) ->method('canUserSeeTag') ->with($tag) @@ -232,8 +219,8 @@ class SystemTagNodeTest extends \Test\TestCase { /** * @dataProvider adminFlagProvider */ - public function testDeleteTag($isAdmin): void { - $tag = new SystemTag(1, 'tag1', true, true); + public function testDeleteTag(bool $isAdmin): void { + $tag = new SystemTag('1', 'tag1', true, true); $this->tagManager->expects($isAdmin ? $this->once() : $this->never()) ->method('canUserSeeTag') ->with($tag) @@ -247,16 +234,16 @@ class SystemTagNodeTest extends \Test\TestCase { $this->getTagNode($isAdmin, $tag)->delete(); } - public function tagNodeDeleteProviderPermissionException() { + public static function tagNodeDeleteProviderPermissionException(): array { return [ [ // cannot delete invisible tag - new SystemTag(1, 'Original', false, true), + new SystemTag('1', 'Original', false, true), 'Sabre\DAV\Exception\Forbidden', ], [ // cannot delete non-assignable tag - new SystemTag(1, 'Original', true, false), + new SystemTag('1', 'Original', true, false), 'Sabre\DAV\Exception\Forbidden', ], ]; @@ -265,7 +252,7 @@ class SystemTagNodeTest extends \Test\TestCase { /** * @dataProvider tagNodeDeleteProviderPermissionException */ - public function testDeleteTagPermissionException(ISystemTag $tag, $expectedException): void { + public function testDeleteTagPermissionException(ISystemTag $tag, string $expectedException): void { $this->tagManager->expects($this->any()) ->method('canUserSeeTag') ->with($tag) @@ -281,7 +268,7 @@ class SystemTagNodeTest extends \Test\TestCase { public function testDeleteTagNotFound(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $tag = new SystemTag(1, 'tag1', true, true); + $tag = new SystemTag('1', 'tag1', true, true); $this->tagManager->expects($this->any()) ->method('canUserSeeTag') ->with($tag) diff --git a/apps/dav/tests/unit/SystemTag/SystemTagPluginTest.php b/apps/dav/tests/unit/SystemTag/SystemTagPluginTest.php index ab5253147a7..a9368794cc2 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagPluginTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -20,6 +21,7 @@ use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagAlreadyExistsException; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Tree; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; @@ -32,67 +34,26 @@ class SystemTagPluginTest extends \Test\TestCase { public const CANASSIGN_PROPERTYNAME = SystemTagPlugin::CANASSIGN_PROPERTYNAME; public const GROUPS_PROPERTYNAME = SystemTagPlugin::GROUPS_PROPERTYNAME; - /** - * @var \Sabre\DAV\Server - */ - private $server; - - /** - * @var \Sabre\DAV\Tree - */ - private $tree; - - /** - * @var ISystemTagManager - */ - private $tagManager; - - /** - * @var IGroupManager - */ - private $groupManager; - - /** - * @var IUserSession - */ - private $userSession; - - /** - * @var IRootFolder - */ - private $rootFolder; - - /** - * @var IUser - */ - private $user; - - /** - * @var SystemTagPlugin - */ - private $plugin; - - /** - * @var ISystemTagObjectMapper - */ - private $tagMapper; + private \Sabre\DAV\Server $server; + private \Sabre\DAV\Tree&MockObject $tree; + private ISystemTagManager&MockObject $tagManager; + private IGroupManager&MockObject $groupManager; + private IUserSession&MockObject $userSession; + private IRootFolder&MockObject $rootFolder; + private IUser&MockObject $user; + private ISystemTagObjectMapper&MockObject $tagMapper; + private SystemTagPlugin $plugin; protected function setUp(): void { parent::setUp(); - $this->tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tree = $this->createMock(Tree::class); $this->server = new \Sabre\DAV\Server($this->tree); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); - $this->groupManager = $this->getMockBuilder(IGroupManager::class) - ->getMock(); - $this->user = $this->getMockBuilder(IUser::class) - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->user = $this->createMock(IUser::class); + $this->userSession = $this->createMock(IUserSession::class); $this->userSession ->expects($this->any()) ->method('getUser') @@ -102,10 +63,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->method('isLoggedIn') ->willReturn(true); - $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); - $this->rootFolder = $this->getMockBuilder(IRootFolder::class) - ->getMock(); + $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); + $this->rootFolder = $this->createMock(IRootFolder::class); $this->plugin = new SystemTagPlugin( $this->tagManager, @@ -117,10 +76,10 @@ class SystemTagPluginTest extends \Test\TestCase { $this->plugin->initialize($this->server); } - public function getPropertiesDataProvider() { + public static function getPropertiesDataProvider(): array { return [ [ - new SystemTag(1, 'Test', true, true), + new SystemTag('1', 'Test', true, true), [], [ self::ID_PROPERTYNAME, @@ -138,7 +97,7 @@ class SystemTagPluginTest extends \Test\TestCase { ] ], [ - new SystemTag(1, 'Test', true, false), + new SystemTag('1', 'Test', true, false), [], [ self::ID_PROPERTYNAME, @@ -156,7 +115,7 @@ class SystemTagPluginTest extends \Test\TestCase { ] ], [ - new SystemTag(1, 'Test', true, false), + new SystemTag('1', 'Test', true, false), ['group1', 'group2'], [ self::ID_PROPERTYNAME, @@ -168,7 +127,7 @@ class SystemTagPluginTest extends \Test\TestCase { ] ], [ - new SystemTag(1, 'Test', true, true), + new SystemTag('1', 'Test', true, true), ['group1', 'group2'], [ self::ID_PROPERTYNAME, @@ -186,7 +145,7 @@ class SystemTagPluginTest extends \Test\TestCase { /** * @dataProvider getPropertiesDataProvider */ - public function testGetProperties(ISystemTag $systemTag, $groups, $requestedProperties, $expectedProperties): void { + public function testGetProperties(ISystemTag $systemTag, array $groups, array $requestedProperties, array $expectedProperties): void { $this->user->expects($this->any()) ->method('getUID') ->willReturn('admin'); @@ -237,7 +196,7 @@ class SystemTagPluginTest extends \Test\TestCase { public function testGetPropertiesForbidden(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $requestedProperties = [ self::ID_PROPERTYNAME, self::GROUPS_PROPERTYNAME, @@ -276,7 +235,7 @@ class SystemTagPluginTest extends \Test\TestCase { } public function testUpdatePropertiesAdmin(): void { - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $this->user->expects($this->any()) ->method('getUID') ->willReturn('admin'); @@ -334,7 +293,7 @@ class SystemTagPluginTest extends \Test\TestCase { public function testUpdatePropertiesForbidden(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $this->user->expects($this->any()) ->method('getUID') ->willReturn('admin'); @@ -375,7 +334,7 @@ class SystemTagPluginTest extends \Test\TestCase { $propPatch->commit(); } - public function createTagInsufficientPermissionsProvider() { + public static function createTagInsufficientPermissionsProvider(): array { return [ [true, false, ''], [false, true, ''], @@ -385,7 +344,7 @@ class SystemTagPluginTest extends \Test\TestCase { /** * @dataProvider createTagInsufficientPermissionsProvider */ - public function testCreateNotAssignableTagAsRegularUser($userVisible, $userAssignable, $groups): void { + public function testCreateNotAssignableTagAsRegularUser(bool $userVisible, bool $userAssignable, string $groups): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('Not sufficient permissions'); @@ -408,9 +367,7 @@ class SystemTagPluginTest extends \Test\TestCase { } $requestData = json_encode($requestData); - $node = $this->getMockBuilder(SystemTagsByIdCollection::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(SystemTagsByIdCollection::class); $this->tagManager->expects($this->never()) ->method('createTag'); $this->tagManager->expects($this->never()) @@ -421,12 +378,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('/systemtags') ->willReturn($node); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') @@ -445,7 +398,7 @@ class SystemTagPluginTest extends \Test\TestCase { } public function testCreateTagInByIdCollectionAsRegularUser(): void { - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $requestData = json_encode([ 'name' => 'Test', @@ -453,9 +406,7 @@ class SystemTagPluginTest extends \Test\TestCase { 'userAssignable' => true, ]); - $node = $this->getMockBuilder(SystemTagsByIdCollection::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(SystemTagsByIdCollection::class); $this->tagManager->expects($this->once()) ->method('createTag') ->with('Test', true, true) @@ -466,12 +417,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('/systemtags') ->willReturn($node); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') @@ -497,7 +444,7 @@ class SystemTagPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - public function createTagProvider() { + public static function createTagProvider(): array { return [ [true, false, ''], [false, false, ''], @@ -508,7 +455,7 @@ class SystemTagPluginTest extends \Test\TestCase { /** * @dataProvider createTagProvider */ - public function testCreateTagInByIdCollection($userVisible, $userAssignable, $groups): void { + public function testCreateTagInByIdCollection(bool $userVisible, bool $userAssignable, string $groups): void { $this->user->expects($this->once()) ->method('getUID') ->willReturn('admin'); @@ -518,7 +465,7 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('admin') ->willReturn(true); - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $requestData = [ 'name' => 'Test', @@ -530,9 +477,7 @@ class SystemTagPluginTest extends \Test\TestCase { } $requestData = json_encode($requestData); - $node = $this->getMockBuilder(SystemTagsByIdCollection::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(SystemTagsByIdCollection::class); $this->tagManager->expects($this->once()) ->method('createTag') ->with('Test', $userVisible, $userAssignable) @@ -553,12 +498,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('/systemtags') ->willReturn($node); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') @@ -584,7 +525,7 @@ class SystemTagPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - public function nodeClassProvider() { + public static function nodeClassProvider(): array { return [ ['\OCA\DAV\SystemTag\SystemTagsByIdCollection'], ['\OCA\DAV\SystemTag\SystemTagsObjectMappingCollection'], @@ -601,7 +542,7 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('admin') ->willReturn(true); - $systemTag = new SystemTag(1, 'Test', true, false); + $systemTag = new SystemTag('1', 'Test', true, false); $requestData = json_encode([ 'name' => 'Test', @@ -609,9 +550,7 @@ class SystemTagPluginTest extends \Test\TestCase { 'userAssignable' => false, ]); - $node = $this->getMockBuilder(SystemTagsObjectMappingCollection::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(SystemTagsObjectMappingCollection::class); $this->tagManager->expects($this->once()) ->method('createTag') @@ -627,12 +566,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->method('createFile') ->with(1); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') @@ -662,9 +597,7 @@ class SystemTagPluginTest extends \Test\TestCase { public function testCreateTagToUnknownNode(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $node = $this->getMockBuilder(SystemTagsObjectMappingCollection::class) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock(SystemTagsObjectMappingCollection::class); $this->tree->expects($this->any()) ->method('getNodeForPath') @@ -676,12 +609,8 @@ class SystemTagPluginTest extends \Test\TestCase { $node->expects($this->never()) ->method('createFile'); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') @@ -693,7 +622,7 @@ class SystemTagPluginTest extends \Test\TestCase { /** * @dataProvider nodeClassProvider */ - public function testCreateTagConflict($nodeClass): void { + public function testCreateTagConflict(string $nodeClass): void { $this->expectException(\Sabre\DAV\Exception\Conflict::class); $this->user->expects($this->once()) @@ -711,9 +640,7 @@ class SystemTagPluginTest extends \Test\TestCase { 'userAssignable' => false, ]); - $node = $this->getMockBuilder($nodeClass) - ->disableOriginalConstructor() - ->getMock(); + $node = $this->createMock($nodeClass); $this->tagManager->expects($this->once()) ->method('createTag') ->with('Test', true, false) @@ -724,12 +651,8 @@ class SystemTagPluginTest extends \Test\TestCase { ->with('/systemtags') ->willReturn($node); - $request = $this->getMockBuilder(RequestInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $response = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); $request->expects($this->once()) ->method('getPath') diff --git a/apps/dav/tests/unit/SystemTag/SystemTagsByIdCollectionTest.php b/apps/dav/tests/unit/SystemTag/SystemTagsByIdCollectionTest.php index b26171650a2..a6c97af26b4 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagsByIdCollectionTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagsByIdCollectionTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,50 +19,36 @@ use OCP\SystemTag\TagNotFoundException; use PHPUnit\Framework\MockObject\MockObject; class SystemTagsByIdCollectionTest extends \Test\TestCase { - - /** - * @var ISystemTagManager - */ - private $tagManager; - - /** - * @var IUser - */ - private $user; + private ISystemTagManager&MockObject $tagManager; + private IUser&MockObject $user; protected function setUp(): void { parent::setUp(); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); } - public function getNode($isAdmin = true) { - $this->user = $this->getMockBuilder(IUser::class) - ->getMock(); + public function getNode(bool $isAdmin = true) { + $this->user = $this->createMock(IUser::class); $this->user->expects($this->any()) ->method('getUID') ->willReturn('testuser'); - /** @var IUserSession|MockObject */ - $userSession = $this->getMockBuilder(IUserSession::class) - ->getMock(); + /** @var IUserSession&MockObject */ + $userSession = $this->createMock(IUserSession::class); $userSession->expects($this->any()) ->method('getUser') ->willReturn($this->user); - /** @var IGroupManager|MockObject */ - $groupManager = $this->getMockBuilder(IGroupManager::class) - ->getMock(); + /** @var IGroupManager&MockObject */ + $groupManager = $this->createMock(IGroupManager::class); $groupManager->expects($this->any()) ->method('isAdmin') ->with('testuser') ->willReturn($isAdmin); - /** @var ISystemTagObjectMapper|MockObject */ - $tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); - + /** @var ISystemTagObjectMapper&MockObject */ + $tagMapper = $this->createMock(ISystemTagObjectMapper::class); return new SystemTagsByIdCollection( $this->tagManager, $userSession, @@ -70,18 +57,18 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { ); } - public function adminFlagProvider() { + public static function adminFlagProvider(): array { return [[true], [false]]; } - + public function testForbiddenCreateFile(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); $this->getNode()->createFile('555'); } - + public function testForbiddenCreateDirectory(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); @@ -89,7 +76,7 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { } public function testGetChild(): void { - $tag = new SystemTag(123, 'Test', true, false); + $tag = new SystemTag('123', 'Test', true, false); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($tag) @@ -107,7 +94,7 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { $this->assertEquals($tag, $childNode->getSystemTag()); } - + public function testGetChildInvalidName(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); @@ -119,7 +106,7 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { $this->getNode()->getChild('invalid'); } - + public function testGetChildNotFound(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); @@ -131,11 +118,11 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { $this->getNode()->getChild('444'); } - + public function testGetChildUserNotVisible(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $tag = new SystemTag(123, 'Test', false, false); + $tag = new SystemTag('123', 'Test', false, false); $this->tagManager->expects($this->once()) ->method('getTagsByIds') @@ -146,8 +133,8 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { } public function testGetChildrenAdmin(): void { - $tag1 = new SystemTag(123, 'One', true, false); - $tag2 = new SystemTag(456, 'Two', true, true); + $tag1 = new SystemTag('123', 'One', true, false); + $tag2 = new SystemTag('456', 'Two', true, true); $this->tagManager->expects($this->once()) ->method('getAllTags') @@ -165,8 +152,8 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { } public function testGetChildrenNonAdmin(): void { - $tag1 = new SystemTag(123, 'One', true, false); - $tag2 = new SystemTag(456, 'Two', true, true); + $tag1 = new SystemTag('123', 'One', true, false); + $tag2 = new SystemTag('456', 'Two', true, true); $this->tagManager->expects($this->once()) ->method('getAllTags') @@ -191,7 +178,7 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { $this->assertCount(0, $this->getNode()->getChildren()); } - public function childExistsProvider() { + public static function childExistsProvider(): array { return [ [true, true], [false, false], @@ -201,8 +188,8 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { /** * @dataProvider childExistsProvider */ - public function testChildExists($userVisible, $expectedResult): void { - $tag = new SystemTag(123, 'One', $userVisible, false); + public function testChildExists(bool $userVisible, bool $expectedResult): void { + $tag = new SystemTag('123', 'One', $userVisible, false); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($tag) @@ -225,7 +212,7 @@ class SystemTagsByIdCollectionTest extends \Test\TestCase { $this->assertFalse($this->getNode()->childExists('123')); } - + public function testChildExistsBadRequest(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); diff --git a/apps/dav/tests/unit/SystemTag/SystemTagsObjectMappingCollectionTest.php b/apps/dav/tests/unit/SystemTag/SystemTagsObjectMappingCollectionTest.php index 66052847f16..59cd3955f1f 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagsObjectMappingCollectionTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagsObjectMappingCollectionTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -13,27 +14,24 @@ use OCP\IUser; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\SystemTag\TagNotFoundException; +use PHPUnit\Framework\MockObject\MockObject; class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { - private ISystemTagManager $tagManager; - private ISystemTagObjectMapper $tagMapper; - private IUser $user; + private ISystemTagManager&MockObject $tagManager; + private ISystemTagObjectMapper&MockObject $tagMapper; + private IUser&MockObject $user; protected function setUp(): void { parent::setUp(); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); - $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); - - $this->user = $this->getMockBuilder(IUser::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); + $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); + $this->user = $this->createMock(IUser::class); } - public function getNode(array $writableNodeIds = []) { + public function getNode(array $writableNodeIds = []): SystemTagsObjectMappingCollection { return new SystemTagsObjectMappingCollection( - 111, + '111', 'files', $this->user, $this->tagManager, @@ -86,7 +84,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { $this->getNode()->createFile('555'); } - public function permissionsProvider() { + public static function permissionsProvider(): array { return [ // invisible, tag does not exist for user [false, true, '\Sabre\DAV\Exception\PreconditionFailed'], @@ -98,7 +96,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { /** * @dataProvider permissionsProvider */ - public function testAssignTagNoPermission($userVisible, $userAssignable, $expectedException): void { + public function testAssignTagNoPermission(bool $userVisible, bool $userAssignable, string $expectedException): void { $tag = new SystemTag('1', 'Test', $userVisible, $userAssignable); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') @@ -146,7 +144,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { } public function testGetChild(): void { - $tag = new SystemTag(555, 'TheTag', true, false); + $tag = new SystemTag('555', 'TheTag', true, false); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($tag) @@ -172,7 +170,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { public function testGetChildNonVisible(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); - $tag = new SystemTag(555, 'TheTag', false, false); + $tag = new SystemTag('555', 'TheTag', false, false); $this->tagManager->expects($this->once()) ->method('canUserSeeTag') ->with($tag) @@ -228,9 +226,9 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { } public function testGetChildren(): void { - $tag1 = new SystemTag(555, 'TagOne', true, false); - $tag2 = new SystemTag(556, 'TagTwo', true, true); - $tag3 = new SystemTag(557, 'InvisibleTag', false, true); + $tag1 = new SystemTag('555', 'TagOne', true, false); + $tag2 = new SystemTag('556', 'TagTwo', true, true); + $tag3 = new SystemTag('557', 'InvisibleTag', false, true); $this->tagMapper->expects($this->once()) ->method('getTagIdsForObjects') @@ -265,7 +263,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { } public function testChildExistsWithVisibleTag(): void { - $tag = new SystemTag(555, 'TagOne', true, false); + $tag = new SystemTag('555', 'TagOne', true, false); $this->tagMapper->expects($this->once()) ->method('haveTag') @@ -286,7 +284,7 @@ class SystemTagsObjectMappingCollectionTest extends \Test\TestCase { } public function testChildExistsWithInvisibleTag(): void { - $tag = new SystemTag(555, 'TagOne', false, false); + $tag = new SystemTag('555', 'TagOne', false, false); $this->tagMapper->expects($this->once()) ->method('haveTag') diff --git a/apps/dav/tests/unit/SystemTag/SystemTagsObjectTypeCollectionTest.php b/apps/dav/tests/unit/SystemTag/SystemTagsObjectTypeCollectionTest.php index ba9304d33fc..301eb528436 100644 --- a/apps/dav/tests/unit/SystemTag/SystemTagsObjectTypeCollectionTest.php +++ b/apps/dav/tests/unit/SystemTag/SystemTagsObjectTypeCollectionTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -15,60 +16,39 @@ use OCP\IUser; use OCP\IUserSession; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; +use PHPUnit\Framework\MockObject\MockObject; class SystemTagsObjectTypeCollectionTest extends \Test\TestCase { - - /** - * @var SystemTagsObjectTypeCollection - */ - private $node; - - /** - * @var ISystemTagManager - */ - private $tagManager; - - /** - * @var ISystemTagObjectMapper - */ - private $tagMapper; - - /** - * @var Folder - */ - private $userFolder; + private ISystemTagManager&MockObject $tagManager; + private ISystemTagObjectMapper&MockObject $tagMapper; + private Folder&MockObject $userFolder; + private SystemTagsObjectTypeCollection $node; protected function setUp(): void { parent::setUp(); - $this->tagManager = $this->getMockBuilder(ISystemTagManager::class) - ->getMock(); - $this->tagMapper = $this->getMockBuilder(ISystemTagObjectMapper::class) - ->getMock(); + $this->tagManager = $this->createMock(ISystemTagManager::class); + $this->tagMapper = $this->createMock(ISystemTagObjectMapper::class); - $user = $this->getMockBuilder(IUser::class) - ->getMock(); + $user = $this->createMock(IUser::class); $user->expects($this->any()) ->method('getUID') ->willReturn('testuser'); - $userSession = $this->getMockBuilder(IUserSession::class) - ->getMock(); + $userSession = $this->createMock(IUserSession::class); $userSession->expects($this->any()) ->method('getUser') ->willReturn($user); - $groupManager = $this->getMockBuilder(IGroupManager::class) - ->getMock(); + $groupManager = $this->createMock(IGroupManager::class); $groupManager->expects($this->any()) ->method('isAdmin') ->with('testuser') ->willReturn(true); - $this->userFolder = $this->getMockBuilder(Folder::class) - ->getMock(); + $this->userFolder = $this->createMock(Folder::class); $userFolder = $this->userFolder; $closure = function ($name) use ($userFolder) { - $node = $userFolder->getFirstNodeById(intval($name)); + $node = $userFolder->getFirstNodeById((int)$name); return $node !== null; }; $writeAccessClosure = function ($name) use ($userFolder) { diff --git a/apps/dav/tests/unit/Upload/ChunkingPluginTest.php b/apps/dav/tests/unit/Upload/ChunkingPluginTest.php index 87feebf5d09..00ed7657dd3 100644 --- a/apps/dav/tests/unit/Upload/ChunkingPluginTest.php +++ b/apps/dav/tests/unit/Upload/ChunkingPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2017 ownCloud GmbH @@ -10,40 +11,24 @@ namespace OCA\DAV\Tests\unit\Upload; use OCA\DAV\Connector\Sabre\Directory; use OCA\DAV\Upload\ChunkingPlugin; use OCA\DAV\Upload\FutureFile; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\NotFound; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use Test\TestCase; class ChunkingPluginTest extends TestCase { - /** - * @var \Sabre\DAV\Server | \PHPUnit\Framework\MockObject\MockObject - */ - private $server; - - /** - * @var \Sabre\DAV\Tree | \PHPUnit\Framework\MockObject\MockObject - */ - private $tree; - - /** - * @var ChunkingPlugin - */ - private $plugin; - /** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var ResponseInterface | \PHPUnit\Framework\MockObject\MockObject */ - private $response; + private \Sabre\DAV\Server&MockObject $server; + private \Sabre\DAV\Tree&MockObject $tree; + private ChunkingPlugin $plugin; + private RequestInterface&MockObject $request; + private ResponseInterface&MockObject $response; protected function setUp(): void { parent::setUp(); - $this->server = $this->getMockBuilder('\Sabre\DAV\Server') - ->disableOriginalConstructor() - ->getMock(); - $this->tree = $this->getMockBuilder('\Sabre\DAV\Tree') - ->disableOriginalConstructor() - ->getMock(); + $this->server = $this->createMock('\Sabre\DAV\Server'); + $this->tree = $this->createMock('\Sabre\DAV\Tree'); $this->server->tree = $this->tree; $this->plugin = new ChunkingPlugin(); @@ -78,14 +63,10 @@ class ChunkingPluginTest extends TestCase { $this->tree->expects($this->exactly(2)) ->method('getNodeForPath') - ->withConsecutive( - ['source'], - ['target'], - ) - ->willReturnOnConsecutiveCalls( - $sourceNode, - $targetNode, - ); + ->willReturnMap([ + ['source', $sourceNode], + ['target', $targetNode], + ]); $this->response->expects($this->never()) ->method('setStatus'); @@ -98,16 +79,20 @@ class ChunkingPluginTest extends TestCase { ->method('getSize') ->willReturn(4); + $calls = [ + ['source', $sourceNode], + ['target', new NotFound()], + ]; $this->tree->expects($this->exactly(2)) ->method('getNodeForPath') - ->withConsecutive( - ['source'], - ['target'], - ) - ->willReturnOnConsecutiveCalls( - $sourceNode, - $this->throwException(new NotFound()), - ); + ->willReturnCallback(function (string $path) use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected[0], $path); + if ($expected[1] instanceof \Throwable) { + throw $expected[1]; + } + return $expected[1]; + }); $this->tree->expects($this->any()) ->method('nodeExists') ->with('target') @@ -132,17 +117,21 @@ class ChunkingPluginTest extends TestCase { ->method('getSize') ->willReturn(4); - + $calls = [ + ['source', $sourceNode], + ['target', new NotFound()], + ]; $this->tree->expects($this->exactly(2)) ->method('getNodeForPath') - ->withConsecutive( - ['source'], - ['target'], - ) - ->willReturnOnConsecutiveCalls( - $sourceNode, - $this->throwException(new NotFound()), - ); + ->willReturnCallback(function (string $path) use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected[0], $path); + if ($expected[1] instanceof \Throwable) { + throw $expected[1]; + } + return $expected[1]; + }); + $this->tree->expects($this->any()) ->method('nodeExists') ->with('target') @@ -175,17 +164,21 @@ class ChunkingPluginTest extends TestCase { ->method('getSize') ->willReturn(3); - + $calls = [ + ['source', $sourceNode], + ['target', new NotFound()], + ]; $this->tree->expects($this->exactly(2)) ->method('getNodeForPath') - ->withConsecutive( - ['source'], - ['target'], - ) - ->willReturnOnConsecutiveCalls( - $sourceNode, - $this->throwException(new NotFound()), - ); + ->willReturnCallback(function (string $path) use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected[0], $path); + if ($expected[1] instanceof \Throwable) { + throw $expected[1]; + } + return $expected[1]; + }); + $this->request->expects($this->once()) ->method('getHeader') ->with('OC-Total-Length') diff --git a/apps/dav/tests/unit/Upload/FutureFileTest.php b/apps/dav/tests/unit/Upload/FutureFileTest.php index 750670992eb..1409df937c0 100644 --- a/apps/dav/tests/unit/Upload/FutureFileTest.php +++ b/apps/dav/tests/unit/Upload/FutureFileTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -45,7 +46,7 @@ class FutureFileTest extends \Test\TestCase { public function testDelete(): void { $d = $this->getMockBuilder(Directory::class) ->disableOriginalConstructor() - ->setMethods(['delete']) + ->onlyMethods(['delete']) ->getMock(); $d->expects($this->once()) @@ -55,7 +56,7 @@ class FutureFileTest extends \Test\TestCase { $f->delete(); } - + public function testPut(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); @@ -63,7 +64,7 @@ class FutureFileTest extends \Test\TestCase { $f->put(''); } - + public function testSetName(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); @@ -71,13 +72,10 @@ class FutureFileTest extends \Test\TestCase { $f->setName(''); } - /** - * @return FutureFile - */ - private function mockFutureFile() { + private function mockFutureFile(): FutureFile { $d = $this->getMockBuilder(Directory::class) ->disableOriginalConstructor() - ->setMethods(['getETag', 'getLastModified', 'getChildren']) + ->onlyMethods(['getETag', 'getLastModified', 'getChildren']) ->getMock(); $d->expects($this->any()) diff --git a/apps/encryption/tests/Command/FixEncryptedVersionTest.php b/apps/encryption/tests/Command/FixEncryptedVersionTest.php index 7a69b4bf901..d0af359183b 100644 --- a/apps/encryption/tests/Command/FixEncryptedVersionTest.php +++ b/apps/encryption/tests/Command/FixEncryptedVersionTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2019 ownCloud GmbH @@ -16,6 +18,7 @@ use OCP\IConfig; use OCP\ITempManager; use OCP\IUserManager; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Tester\CommandTester; use Test\TestCase; @@ -34,16 +37,13 @@ class FixEncryptedVersionTest extends TestCase { use EncryptionTrait; use UserTrait; - private $userId; + private string $userId; - /** @var FixEncryptedVersion */ - private $fixEncryptedVersion; + private FixEncryptedVersion $fixEncryptedVersion; - /** @var CommandTester */ - private $commandTester; + private CommandTester $commandTester; - /** @var Util|\PHPUnit\Framework\MockObject\MockObject */ - protected $util; + protected Util&MockObject $util; public function setUp(): void { parent::setUp(); diff --git a/apps/encryption/tests/Command/TestEnableMasterKey.php b/apps/encryption/tests/Command/TestEnableMasterKey.php index c4678b778bc..744bbaed6f8 100644 --- a/apps/encryption/tests/Command/TestEnableMasterKey.php +++ b/apps/encryption/tests/Command/TestEnableMasterKey.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/encryption/tests/Controller/RecoveryControllerTest.php b/apps/encryption/tests/Controller/RecoveryControllerTest.php index 9de583b387c..7eff312d6ce 100644 --- a/apps/encryption/tests/Controller/RecoveryControllerTest.php +++ b/apps/encryption/tests/Controller/RecoveryControllerTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -13,26 +15,23 @@ use OCP\AppFramework\Http; use OCP\IConfig; use OCP\IL10N; use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class RecoveryControllerTest extends TestCase { - /** @var RecoveryController */ - private $controller; - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $requestMock; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $configMock; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10nMock; - /** @var Recovery|\PHPUnit\Framework\MockObject\MockObject */ - private $recoveryMock; - - public function adminRecoveryProvider() { + protected RecoveryController $controller; + + protected IRequest&MockObject $requestMock; + protected IConfig&MockObject $configMock; + protected IL10N&MockObject $l10nMock; + protected Recovery&MockObject $recoveryMock; + + public static function adminRecoveryProvider(): array { return [ ['test', 'test', '1', 'Recovery key successfully enabled', Http::STATUS_OK], ['', 'test', '1', 'Missing recovery key password', Http::STATUS_BAD_REQUEST], ['test', '', '1', 'Please repeat the recovery key password', Http::STATUS_BAD_REQUEST], - ['test', 'soimething that doesn\'t match', '1', 'Repeated recovery key password does not match the provided recovery key password', Http::STATUS_BAD_REQUEST], + ['test', 'something that doesn\'t match', '1', 'Repeated recovery key password does not match the provided recovery key password', Http::STATUS_BAD_REQUEST], ['test', 'test', '0', 'Recovery key successfully disabled', Http::STATUS_OK], ]; } @@ -63,7 +62,7 @@ class RecoveryControllerTest extends TestCase { $this->assertEquals($expectedStatus, $response->getStatus()); } - public function changeRecoveryPasswordProvider() { + public static function changeRecoveryPasswordProvider(): array { return [ ['test', 'test', 'oldtestFail', 'Could not change the password. Maybe the old password was not correct.', Http::STATUS_BAD_REQUEST], ['test', 'test', 'oldtest', 'Password successfully changed.', Http::STATUS_OK], @@ -98,7 +97,7 @@ class RecoveryControllerTest extends TestCase { $this->assertEquals($expectedStatus, $response->getStatus()); } - public function userSetRecoveryProvider() { + public static function userSetRecoveryProvider(): array { return [ ['1', 'Recovery Key enabled', Http::STATUS_OK], ['0', 'Could not enable the recovery key, please try again or contact your administrator', Http::STATUS_BAD_REQUEST] diff --git a/apps/encryption/tests/Controller/SettingsControllerTest.php b/apps/encryption/tests/Controller/SettingsControllerTest.php index b676d57164f..bee20f67cec 100644 --- a/apps/encryption/tests/Controller/SettingsControllerTest.php +++ b/apps/encryption/tests/Controller/SettingsControllerTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -24,37 +26,18 @@ use Test\TestCase; class SettingsControllerTest extends TestCase { - /** @var SettingsController */ - private $controller; - - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $requestMock; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10nMock; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManagerMock; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSessionMock; - - /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject */ - private $keyManagerMock; + protected SettingsController $controller; - /** @var Crypt|\PHPUnit\Framework\MockObject\MockObject */ - private $cryptMock; - - /** @var Session|\PHPUnit\Framework\MockObject\MockObject */ - private $sessionMock; - /** @var MockObject|IUser */ - private $user; - - /** @var ISession|\PHPUnit\Framework\MockObject\MockObject */ - private $ocSessionMock; - - /** @var Util|\PHPUnit\Framework\MockObject\MockObject */ - private $utilMock; + protected IRequest&MockObject $requestMock; + protected IL10N&MockObject $l10nMock; + protected IUserManager&MockObject $userManagerMock; + protected IUserSession&MockObject $userSessionMock; + protected KeyManager&MockObject $keyManagerMock; + protected Crypt&MockObject $cryptMock; + protected Session&MockObject $sessionMock; + protected IUser&MockObject $user; + protected ISession&MockObject $ocSessionMock; + protected Util&MockObject $utilMock; protected function setUp(): void { parent::setUp(); @@ -171,21 +154,17 @@ class SettingsControllerTest extends TestCase { $newPassword = 'new'; $this->ocSessionMock->expects($this->once()) - ->method('get')->with('loginname')->willReturn('testUser'); + ->method('get') + ->with('loginname') + ->willReturn('testUser'); $this->userManagerMock ->expects($this->exactly(2)) ->method('checkPassword') - ->withConsecutive( - ['testUserUid', 'new'], - ['testUser', 'new'], - ) - ->willReturnOnConsecutiveCalls( - false, - true, - ); - - + ->willReturnMap([ + ['testUserUid', 'new', false], + ['testUser', 'new', true], + ]); $this->cryptMock ->expects($this->once()) diff --git a/apps/encryption/tests/Controller/StatusControllerTest.php b/apps/encryption/tests/Controller/StatusControllerTest.php index fbe44f52fb7..616114927e8 100644 --- a/apps/encryption/tests/Controller/StatusControllerTest.php +++ b/apps/encryption/tests/Controller/StatusControllerTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -12,24 +14,17 @@ use OCA\Encryption\Session; use OCP\Encryption\IManager; use OCP\IL10N; use OCP\IRequest; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class StatusControllerTest extends TestCase { - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $requestMock; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10nMock; - - /** @var Session|\PHPUnit\Framework\MockObject\MockObject */ - protected $sessionMock; - - /** @var IManager | \PHPUnit\Framework\MockObject\MockObject */ - protected $encryptionManagerMock; + protected IRequest&MockObject $requestMock; + protected IL10N&MockObject $l10nMock; + protected Session&MockObject $sessionMock; + protected IManager&MockObject $encryptionManagerMock; - /** @var StatusController */ - protected $controller; + protected StatusController $controller; protected function setUp(): void { parent::setUp(); @@ -68,7 +63,7 @@ class StatusControllerTest extends TestCase { $this->assertSame($expectedStatus, $data['status']); } - public function dataTestGetStatus() { + public static function dataTestGetStatus(): array { return [ [Session::INIT_EXECUTED, 'interactionNeeded'], [Session::INIT_SUCCESSFUL, 'success'], diff --git a/apps/encryption/tests/Crypto/CryptTest.php b/apps/encryption/tests/Crypto/CryptTest.php index 74afc6d44a1..345311da4d0 100644 --- a/apps/encryption/tests/Crypto/CryptTest.php +++ b/apps/encryption/tests/Crypto/CryptTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -12,24 +14,17 @@ use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\IConfig; use OCP\IL10N; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; class CryptTest extends TestCase { - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected IConfig&MockObject $config; + protected IL10N&MockObject $l; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l; - - /** @var Crypt */ - private $crypt; + protected Crypt $crypt; protected function setUp(): void { parent::setUp(); @@ -113,10 +108,7 @@ class CryptTest extends TestCase { $this->crypt->generateHeader('unknown'); } - /** - * @return array - */ - public function dataTestGenerateHeader() { + public static function dataTestGenerateHeader(): array { return [ [null, 'HBEGIN:cipher:AES-128-CFB:keyFormat:hash2:encoding:binary:HEND'], ['password', 'HBEGIN:cipher:AES-128-CFB:keyFormat:password:encoding:binary:HEND'], @@ -155,10 +147,8 @@ class CryptTest extends TestCase { /** * data provider for testGetCipher - * - * @return array */ - public function dataProviderGetCipher() { + public static function dataProviderGetCipher(): array { return [ ['AES-128-CFB', 'AES-128-CFB'], ['AES-256-CFB', 'AES-256-CFB'], @@ -201,7 +191,7 @@ class CryptTest extends TestCase { $this->assertSame($expected['signature'], $result['signature']); } - public function dataTestSplitMetaData() { + public static function dataTestSplitMetaData(): array { return [ ['encryptedContent00iv001234567890123456xx', ['encrypted' => 'encryptedContent', 'iv' => '1234567890123456', 'signature' => false]], @@ -222,7 +212,7 @@ class CryptTest extends TestCase { ); } - public function dataTestHasSignature() { + public static function dataTestHasSignature(): array { return [ ['encryptedContent00iv001234567890123456xx', false], ['encryptedContent00iv00123456789012345600sig00e1992521e437f6915f9173b190a512cfc38a00ac24502db44e0ba10c2bb0cc86xxx', true] @@ -239,7 +229,7 @@ class CryptTest extends TestCase { $this->invokePrivate($this->crypt, 'hasSignature', [$data, $cipher]); } - public function dataTestHasSignatureFail() { + public static function dataTestHasSignatureFail(): array { return [ ['AES-256-CTR'], ['aes-256-ctr'], @@ -270,10 +260,8 @@ class CryptTest extends TestCase { /** * data provider for testRemovePadding - * - * @return array */ - public function dataProviderRemovePadding() { + public static function dataProviderRemovePadding(): array { return [ ['dataxx', 'data'], ['data', false] @@ -357,10 +345,7 @@ class CryptTest extends TestCase { $this->invokePrivate($this->crypt, 'getKeySize', ['foo']); } - /** - * @return array - */ - public function dataTestGetKeySize() { + public static function dataTestGetKeySize(): array { return [ ['AES-256-CFB', 32], ['AES-128-CFB', 16], @@ -374,28 +359,25 @@ class CryptTest extends TestCase { */ public function testDecryptPrivateKey($header, $privateKey, $expectedCipher, $isValidKey, $expected): void { $this->config->method('getSystemValueBool') - ->withConsecutive(['encryption.legacy_format_support', false], - ['encryption.use_legacy_base64_encoding', false]) - ->willReturnOnConsecutiveCalls(true, false); + ->willReturnMap([ + ['encryption.legacy_format_support', false, true], + ['encryption.use_legacy_base64_encoding', false, false], + ]); /** @var Crypt|\PHPUnit\Framework\MockObject\MockObject $crypt */ $crypt = $this->getMockBuilder(Crypt::class) - ->setConstructorArgs( - [ - $this->logger, - $this->userSession, - $this->config, - $this->l - ] - ) - ->setMethods( - [ - 'parseHeader', - 'generatePasswordHash', - 'symmetricDecryptFileContent', - 'isValidPrivateKey' - ] - ) + ->setConstructorArgs([ + $this->logger, + $this->userSession, + $this->config, + $this->l + ]) + ->onlyMethods([ + 'parseHeader', + 'generatePasswordHash', + 'symmetricDecryptFileContent', + 'isValidPrivateKey' + ]) ->getMock(); $crypt->expects($this->once())->method('parseHeader')->willReturn($header); @@ -416,10 +398,7 @@ class CryptTest extends TestCase { $this->assertSame($expected, $result); } - /** - * @return array - */ - public function dataTestDecryptPrivateKey() { + public static function dataTestDecryptPrivateKey(): array { return [ [['cipher' => 'AES-128-CFB', 'keyFormat' => 'password'], 'HBEGIN:HENDprivateKey', 'AES-128-CFB', true, 'key'], [['cipher' => 'AES-256-CFB', 'keyFormat' => 'password'], 'HBEGIN:HENDprivateKey', 'AES-256-CFB', true, 'key'], diff --git a/apps/encryption/tests/Crypto/DecryptAllTest.php b/apps/encryption/tests/Crypto/DecryptAllTest.php index 0d8543153ef..83684b8be32 100644 --- a/apps/encryption/tests/Crypto/DecryptAllTest.php +++ b/apps/encryption/tests/Crypto/DecryptAllTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -12,28 +14,19 @@ use OCA\Encryption\Crypto\DecryptAll; use OCA\Encryption\KeyManager; use OCA\Encryption\Session; use OCA\Encryption\Util; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Helper\QuestionHelper; use Test\TestCase; class DecryptAllTest extends TestCase { - /** @var DecryptAll */ - protected $instance; - - /** @var Util | \PHPUnit\Framework\MockObject\MockObject */ - protected $util; - - /** @var KeyManager | \PHPUnit\Framework\MockObject\MockObject */ - protected $keyManager; - - /** @var Crypt | \PHPUnit\Framework\MockObject\MockObject */ - protected $crypt; - - /** @var Session | \PHPUnit\Framework\MockObject\MockObject */ - protected $session; + protected DecryptAll $instance; - /** @var QuestionHelper | \PHPUnit\Framework\MockObject\MockObject */ - protected $questionHelper; + protected Util&MockObject $util; + protected KeyManager&MockObject $keyManager; + protected Crypt&MockObject $crypt; + protected Session&MockObject $session; + protected QuestionHelper&MockObject $questionHelper; protected function setUp(): void { parent::setUp(); @@ -75,6 +68,7 @@ class DecryptAllTest extends TestCase { $password = 'passwd'; $recoveryKey = 'recoveryKey'; $userKey = 'userKey'; + $masterKey = 'userKey'; $unencryptedKey = 'unencryptedKey'; $this->keyManager->expects($this->any())->method('getRecoveryKeyId') @@ -105,7 +99,7 @@ class DecryptAllTest extends TestCase { ); } - public function dataTestGetPrivateKey() { + public static function dataTestGetPrivateKey() { return [ ['user1', 'recoveryKey', 'masterKeyId'], ['recoveryKeyId', 'recoveryKeyId', 'masterKeyId'], diff --git a/apps/encryption/tests/Crypto/EncryptAllTest.php b/apps/encryption/tests/Crypto/EncryptAllTest.php index d702c123b9b..45743ae733b 100644 --- a/apps/encryption/tests/Crypto/EncryptAllTest.php +++ b/apps/encryption/tests/Crypto/EncryptAllTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -20,6 +22,7 @@ use OCP\L10N\IFactory; use OCP\Mail\IMailer; use OCP\Security\ISecureRandom; use OCP\UserInterface; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Helper\QuestionHelper; @@ -29,50 +32,22 @@ use Test\TestCase; class EncryptAllTest extends TestCase { - /** @var \PHPUnit\Framework\MockObject\MockObject|KeyManager */ - protected $keyManager; - - /** @var \PHPUnit\Framework\MockObject\MockObject|Util */ - protected $util; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IUserManager */ - protected $userManager; - - /** @var \PHPUnit\Framework\MockObject\MockObject|Setup */ - protected $setupUser; - - /** @var \PHPUnit\Framework\MockObject\MockObject|View */ - protected $view; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */ - protected $config; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IMailer */ - protected $mailer; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IL10N */ - protected $l; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IFactory */ - protected $l10nFactory; - - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Helper\QuestionHelper */ - protected $questionHelper; - - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */ - protected $inputInterface; - - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */ - protected $outputInterface; - - /** @var \PHPUnit\Framework\MockObject\MockObject|UserInterface */ - protected $userInterface; - - /** @var \PHPUnit\Framework\MockObject\MockObject|ISecureRandom */ - protected $secureRandom; - - /** @var EncryptAll */ - protected $encryptAll; + protected KeyManager&MockObject $keyManager; + protected Util&MockObject $util; + protected IUserManager&MockObject $userManager; + protected Setup&MockObject $setupUser; + protected View&MockObject $view; + protected IConfig&MockObject $config; + protected IMailer&MockObject $mailer; + protected IL10N&MockObject $l; + protected IFactory&MockObject $l10nFactory; + protected \Symfony\Component\Console\Helper\QuestionHelper&MockObject $questionHelper; + protected \Symfony\Component\Console\Input\InputInterface&MockObject $inputInterface; + protected \Symfony\Component\Console\Output\OutputInterface&MockObject $outputInterface; + protected UserInterface&MockObject $userInterface; + protected ISecureRandom&MockObject $secureRandom; + + protected EncryptAll $encryptAll; protected function setUp(): void { parent::setUp(); @@ -153,7 +128,7 @@ class EncryptAllTest extends TestCase { $this->secureRandom ] ) - ->setMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords']) + ->onlyMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords']) ->getMock(); $this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false); @@ -182,7 +157,7 @@ class EncryptAllTest extends TestCase { $this->secureRandom ] ) - ->setMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords']) + ->onlyMethods(['createKeyPairs', 'encryptAllUsersFiles', 'outputPasswords']) ->getMock(); $this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(true); @@ -212,7 +187,7 @@ class EncryptAllTest extends TestCase { $this->secureRandom ] ) - ->setMethods(['setupUserFS', 'generateOneTimePassword']) + ->onlyMethods(['setupUserFS', 'generateOneTimePassword']) ->getMock(); @@ -245,7 +220,7 @@ class EncryptAllTest extends TestCase { } public function testEncryptAllUsersFiles(): void { - /** @var EncryptAll | \PHPUnit\Framework\MockObject\MockObject $encryptAll */ + /** @var EncryptAll&MockObject $encryptAll */ $encryptAll = $this->getMockBuilder(EncryptAll::class) ->setConstructorArgs( [ @@ -262,7 +237,7 @@ class EncryptAllTest extends TestCase { $this->secureRandom ] ) - ->setMethods(['encryptUsersFiles']) + ->onlyMethods(['encryptUsersFiles']) ->getMock(); $this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false); @@ -271,17 +246,22 @@ class EncryptAllTest extends TestCase { $this->invokePrivate($encryptAll, 'output', [$this->outputInterface]); $this->invokePrivate($encryptAll, 'userPasswords', [['user1' => 'pwd1', 'user2' => 'pwd2']]); - $encryptAll->expects($this->exactly(2))->method('encryptUsersFiles') - ->withConsecutive( - ['user1'], - ['user2'], - ); + $encryptAllCalls = []; + $encryptAll->expects($this->exactly(2)) + ->method('encryptUsersFiles') + ->willReturnCallback(function ($uid) use (&$encryptAllCalls) { + $encryptAllCalls[] = $uid; + }); $this->invokePrivate($encryptAll, 'encryptAllUsersFiles'); + self::assertEquals([ + 'user1', + 'user2', + ], $encryptAllCalls); } public function testEncryptUsersFiles(): void { - /** @var EncryptAll | \PHPUnit\Framework\MockObject\MockObject $encryptAll */ + /** @var EncryptAll&MockObject $encryptAll */ $encryptAll = $this->getMockBuilder(EncryptAll::class) ->setConstructorArgs( [ @@ -298,24 +278,31 @@ class EncryptAllTest extends TestCase { $this->secureRandom ] ) - ->setMethods(['encryptFile', 'setupUserFS']) + ->onlyMethods(['encryptFile', 'setupUserFS']) ->getMock(); $this->util->expects($this->any())->method('isMasterKeyEnabled')->willReturn(false); $this->view->expects($this->exactly(2))->method('getDirectoryContent') - ->withConsecutive( - ['/user1/files'], - ['/user1/files/foo'], - )->willReturnOnConsecutiveCalls( + ->willReturnMap([ [ - ['name' => 'foo', 'type' => 'dir'], - ['name' => 'bar', 'type' => 'file'], + '/user1/files', + '', + null, + [ + ['name' => 'foo', 'type' => 'dir'], + ['name' => 'bar', 'type' => 'file'], + ], ], [ - ['name' => 'subfile', 'type' => 'file'] - ] - ); + '/user1/files/foo', + '', + null, + [ + ['name' => 'subfile', 'type' => 'file'] + ], + ], + ]); $this->view->expects($this->any())->method('is_dir') ->willReturnCallback( @@ -327,11 +314,12 @@ class EncryptAllTest extends TestCase { } ); - $encryptAll->expects($this->exactly(2))->method('encryptFile') - ->withConsecutive( - ['/user1/files/bar'], - ['/user1/files/foo/subfile'], - ); + $encryptAllCalls = []; + $encryptAll->expects($this->exactly(2)) + ->method('encryptFile') + ->willReturnCallback(function (string $path) use (&$encryptAllCalls) { + $encryptAllCalls[] = $path; + }); $outputFormatter = $this->createMock(OutputFormatterInterface::class); $outputFormatter->method('isDecorated')->willReturn(false); @@ -341,6 +329,10 @@ class EncryptAllTest extends TestCase { $progressBar = new ProgressBar($this->outputInterface); $this->invokePrivate($encryptAll, 'encryptUsersFiles', ['user1', $progressBar, '']); + self::assertEquals([ + '/user1/files/bar', + '/user1/files/foo/subfile', + ], $encryptAllCalls); } public function testGenerateOneTimePassword(): void { @@ -378,7 +370,7 @@ class EncryptAllTest extends TestCase { ); } - public function dataTestEncryptFile() { + public static function dataTestEncryptFile(): array { return [ [true], [false], diff --git a/apps/encryption/tests/Crypto/EncryptionTest.php b/apps/encryption/tests/Crypto/EncryptionTest.php index 7f3d9d1f348..999c6242f0c 100644 --- a/apps/encryption/tests/Crypto/EncryptionTest.php +++ b/apps/encryption/tests/Crypto/EncryptionTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -26,34 +28,18 @@ use Symfony\Component\Console\Output\OutputInterface; use Test\TestCase; class EncryptionTest extends TestCase { - /** @var Encryption */ - private $instance; - - /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject */ - private $keyManagerMock; - - /** @var EncryptAll|\PHPUnit\Framework\MockObject\MockObject */ - private $encryptAllMock; - - /** @var DecryptAll|\PHPUnit\Framework\MockObject\MockObject */ - private $decryptAllMock; - - /** @var Session|\PHPUnit\Framework\MockObject\MockObject */ - private $sessionMock; - - /** @var Crypt|\PHPUnit\Framework\MockObject\MockObject */ - private $cryptMock; - - /** @var Util|\PHPUnit\Framework\MockObject\MockObject */ - private $utilMock; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $loggerMock; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10nMock; + protected Encryption $instance; - private IStorage&MockObject $storageMock; + protected KeyManager&MockObject $keyManagerMock; + protected EncryptAll&MockObject $encryptAllMock; + protected DecryptAll&MockObject $decryptAllMock; + protected Session&MockObject $sessionMock; + protected Crypt&MockObject $cryptMock; + protected Util&MockObject $utilMock; + protected LoggerInterface&MockObject $loggerMock; + protected IL10N&MockObject $l10nMock; + protected IStorage&MockObject $storageMock; protected function setUp(): void { parent::setUp(); @@ -175,7 +161,7 @@ class EncryptionTest extends TestCase { ); } - public function dataProviderForTestGetPathToRealFile() { + public static function dataProviderForTestGetPathToRealFile(): array { return [ ['/user/files/foo/bar.txt', '/user/files/foo/bar.txt'], ['/user/files/foo.txt', '/user/files/foo.txt'], @@ -228,7 +214,7 @@ class EncryptionTest extends TestCase { } } - public function dataTestBegin() { + public static function dataTestBegin(): array { return [ ['w', ['cipher' => 'myCipher'], 'legacyCipher', 'defaultCipher', 'fileKey', 'defaultCipher'], ['r', ['cipher' => 'myCipher'], 'legacyCipher', 'defaultCipher', 'fileKey', 'myCipher'], @@ -305,7 +291,7 @@ class EncryptionTest extends TestCase { ); } - public function dataTestUpdate() { + public static function dataTestUpdate(): array { return [ ['', false], ['fileKey', true] @@ -387,7 +373,7 @@ class EncryptionTest extends TestCase { ); } - public function dataTestShouldEncrypt() { + public static function dataTestShouldEncrypt(): array { return [ ['/user1/files/foo.txt', true, true, true], ['/user1/files_versions/foo.txt', true, true, true], diff --git a/apps/encryption/tests/KeyManagerTest.php b/apps/encryption/tests/KeyManagerTest.php index 8f5c9a78faf..187c21bc687 100644 --- a/apps/encryption/tests/KeyManagerTest.php +++ b/apps/encryption/tests/KeyManagerTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -28,41 +30,19 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class KeyManagerTest extends TestCase { - /** - * @var KeyManager - */ - private $instance; - /** - * @var string - */ - private $userId; - - /** @var string */ - private $systemKeyId; - - /** @var \OCP\Encryption\Keys\IStorage|\PHPUnit\Framework\MockObject\MockObject */ - private $keyStorageMock; - - /** @var Crypt|\PHPUnit\Framework\MockObject\MockObject */ - private $cryptMock; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userMock; - - /** @var Session|\PHPUnit\Framework\MockObject\MockObject */ - private $sessionMock; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logMock; - - /** @var Util|\PHPUnit\Framework\MockObject\MockObject */ - private $utilMock; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $configMock; + protected KeyManager $instance; - /** @var ILockingProvider|MockObject */ - private $lockingProviderMock; + protected string $userId; + protected string $systemKeyId; + protected IStorage&MockObject $keyStorageMock; + protected Crypt&MockObject $cryptMock; + protected IUserSession&MockObject $userMock; + protected Session&MockObject $sessionMock; + protected LoggerInterface&MockObject $logMock; + protected Util&MockObject $utilMock; + protected IConfig&MockObject $configMock; + protected ILockingProvider&MockObject $lockingProviderMock; protected function setUp(): void { parent::setUp(); @@ -201,7 +181,7 @@ class KeyManagerTest extends TestCase { ); } - public function dataTestUserHasKeys() { + public static function dataTestUserHasKeys(): array { return [ ['key', true], ['', false] @@ -246,7 +226,7 @@ class KeyManagerTest extends TestCase { * @param bool $useMasterKey */ public function testInit($useMasterKey): void { - /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject $instance */ + /** @var KeyManager&MockObject $instance */ $instance = $this->getMockBuilder(KeyManager::class) ->setConstructorArgs( [ @@ -259,17 +239,18 @@ class KeyManagerTest extends TestCase { $this->utilMock, $this->lockingProviderMock ] - )->setMethods(['getMasterKeyId', 'getMasterKeyPassword', 'getSystemPrivateKey', 'getPrivateKey']) + )->onlyMethods(['getMasterKeyId', 'getMasterKeyPassword', 'getSystemPrivateKey', 'getPrivateKey']) ->getMock(); $this->utilMock->expects($this->once())->method('isMasterKeyEnabled') ->willReturn($useMasterKey); - $this->sessionMock->expects($this->exactly(2))->method('setStatus') - ->withConsecutive( - [Session::INIT_EXECUTED], - [Session::INIT_SUCCESSFUL], - ); + $sessionSetStatusCalls = []; + $this->sessionMock->expects($this->exactly(2)) + ->method('setStatus') + ->willReturnCallback(function (string $status) use (&$sessionSetStatusCalls) { + $sessionSetStatusCalls[] = $status; + }); $instance->expects($this->any())->method('getMasterKeyId')->willReturn('masterKeyId'); $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword'); @@ -290,9 +271,13 @@ class KeyManagerTest extends TestCase { ->with('key'); $this->assertTrue($instance->init($this->userId, 'pass')); + self::assertEquals([ + Session::INIT_EXECUTED, + Session::INIT_SUCCESSFUL, + ], $sessionSetStatusCalls); } - public function dataTestInit() { + public static function dataTestInit(): array { return [ [true], [false] @@ -349,7 +334,7 @@ class KeyManagerTest extends TestCase { $this->assertTrue($this->instance->getEncryptedFileKey('/')); } - public function dataTestGetFileKey() { + public static function dataTestGetFileKey(): array { return [ ['user1', false, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'], ['user1', false, 'privateKey', '', 'multiKeyDecryptResult'], @@ -395,14 +380,10 @@ class KeyManagerTest extends TestCase { $this->keyStorageMock->expects($this->exactly(2)) ->method('getFileKey') - ->withConsecutive( - [$path, 'fileKey', 'OC_DEFAULT_MODULE'], - [$path, $expectedUid . '.shareKey', 'OC_DEFAULT_MODULE'], - ) - ->willReturnOnConsecutiveCalls( - $encryptedFileKey, - 'fileKey', - ); + ->willReturnMap([ + [$path, 'fileKey', 'OC_DEFAULT_MODULE', $encryptedFileKey], + [$path, $expectedUid . '.shareKey', 'OC_DEFAULT_MODULE', 'fileKey'], + ]); $this->utilMock->expects($this->any())->method('isMasterKeyEnabled') ->willReturn($isMasterKeyEnabled); @@ -515,7 +496,7 @@ class KeyManagerTest extends TestCase { * * @return array */ - public function dataTestAddSystemKeys() { + public static function dataTestAddSystemKeys(): array { return [ [['public' => true],[], 'user1', ['publicShareKey', 'recoveryKey']], [['public' => false], [], 'user1', ['recoveryKey']], @@ -563,7 +544,7 @@ class KeyManagerTest extends TestCase { * @param $masterKey */ public function testValidateMasterKey($masterKey): void { - /** @var KeyManager|\PHPUnit\Framework\MockObject\MockObject $instance */ + /** @var KeyManager&MockObject $instance */ $instance = $this->getMockBuilder(KeyManager::class) ->setConstructorArgs( [ @@ -576,7 +557,7 @@ class KeyManagerTest extends TestCase { $this->utilMock, $this->lockingProviderMock ] - )->setMethods(['getPublicMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword']) + )->onlyMethods(['getPublicMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword']) ->getMock(); $this->utilMock->expects($this->once())->method('isMasterKeyEnabled') @@ -611,20 +592,19 @@ class KeyManagerTest extends TestCase { } public function testValidateMasterKeyLocked(): void { - /** @var KeyManager|\PHPUnit_Framework_MockObject_MockObject $instance */ + /** @var KeyManager&MockObject $instance */ $instance = $this->getMockBuilder(KeyManager::class) - ->setConstructorArgs( - [ - $this->keyStorageMock, - $this->cryptMock, - $this->configMock, - $this->userMock, - $this->sessionMock, - $this->logMock, - $this->utilMock, - $this->lockingProviderMock - ] - )->setMethods(['getPublicMasterKey', 'getPrivateMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword']) + ->setConstructorArgs([ + $this->keyStorageMock, + $this->cryptMock, + $this->configMock, + $this->userMock, + $this->sessionMock, + $this->logMock, + $this->utilMock, + $this->lockingProviderMock + ]) + ->onlyMethods(['getPublicMasterKey', 'getPrivateMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword']) ->getMock(); $this->utilMock->expects($this->once())->method('isMasterKeyEnabled') @@ -646,7 +626,7 @@ class KeyManagerTest extends TestCase { $instance->validateMasterKey(); } - public function dataTestValidateMasterKey() { + public static function dataTestValidateMasterKey(): array { return [ ['masterKey'], [''] diff --git a/apps/encryption/tests/RecoveryTest.php b/apps/encryption/tests/RecoveryTest.php index 17ad385eca0..0627724a856 100644 --- a/apps/encryption/tests/RecoveryTest.php +++ b/apps/encryption/tests/RecoveryTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/encryption/tests/SessionTest.php b/apps/encryption/tests/SessionTest.php index 3072bc6ef3b..9e38f857e73 100644 --- a/apps/encryption/tests/SessionTest.php +++ b/apps/encryption/tests/SessionTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,17 +12,14 @@ namespace OCA\Encryption\Tests; use OCA\Encryption\Exceptions\PrivateKeyMissingException; use OCA\Encryption\Session; use OCP\ISession; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class SessionTest extends TestCase { private static $tempStorage = []; - /** - * @var Session - */ - private $instance; - /** @var ISession|\PHPUnit\Framework\MockObject\MockObject */ - private $sessionMock; + protected Session $instance; + protected ISession&MockObject $sessionMock; public function testThatGetPrivateKeyThrowsExceptionWhenNotSet(): void { $this->expectException(PrivateKeyMissingException::class); @@ -122,10 +121,11 @@ class SessionTest extends TestCase { * @param bool $expected */ public function testIsReady($status, $expected): void { - /** @var Session | \PHPUnit\Framework\MockObject\MockObject $instance */ + /** @var Session&MockObject $instance */ $instance = $this->getMockBuilder(Session::class) ->setConstructorArgs([$this->sessionMock]) - ->setMethods(['getStatus'])->getMock(); + ->onlyMethods(['getStatus']) + ->getMock(); $instance->expects($this->once())->method('getStatus') ->willReturn($status); @@ -133,7 +133,7 @@ class SessionTest extends TestCase { $this->assertSame($expected, $instance->isReady()); } - public function dataTestIsReady() { + public static function dataTestIsReady(): array { return [ [Session::INIT_SUCCESSFUL, true], [Session::INIT_EXECUTED, false], diff --git a/apps/encryption/tests/Settings/AdminTest.php b/apps/encryption/tests/Settings/AdminTest.php index 4ddaeb1b84d..5ae9e7eb3c6 100644 --- a/apps/encryption/tests/Settings/AdminTest.php +++ b/apps/encryption/tests/Settings/AdminTest.php @@ -1,4 +1,7 @@ <?php + +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,24 +15,20 @@ use OCP\IL10N; use OCP\ISession; use OCP\IUserManager; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; class AdminTest extends TestCase { - /** @var Admin */ - private $admin; - /** @var IL10N */ - private $l; - /** @var LoggerInterface */ - private $logger; - /** @var IUserSession */ - private $userSession; - /** @var IConfig */ - private $config; - /** @var IUserManager */ - private $userManager; - /** @var ISession */ - private $session; + + protected Admin $admin; + + protected IL10N&MockObject $l; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected IConfig&MockObject $config; + protected IUserManager&MockObject $userManager; + protected ISession&MockObject $session; protected function setUp(): void { parent::setUp(); diff --git a/apps/encryption/tests/Users/SetupTest.php b/apps/encryption/tests/Users/SetupTest.php index 7a6beaf3594..b2abfcba1db 100644 --- a/apps/encryption/tests/Users/SetupTest.php +++ b/apps/encryption/tests/Users/SetupTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,21 +12,15 @@ namespace OCA\Encryption\Tests\Users; use OCA\Encryption\Crypto\Crypt; use OCA\Encryption\KeyManager; use OCA\Encryption\Users\Setup; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class SetupTest extends TestCase { - /** - * @var KeyManager|\PHPUnit\Framework\MockObject\MockObject - */ - private $keyManagerMock; - /** - * @var Crypt|\PHPUnit\Framework\MockObject\MockObject - */ - private $cryptMock; - /** - * @var Setup - */ - private $instance; + + protected Setup $instance; + + protected KeyManager&MockObject $keyManagerMock; + protected Crypt&MockObject $cryptMock; protected function setUp(): void { parent::setUp(); @@ -72,7 +68,7 @@ class SetupTest extends TestCase { ); } - public function dataTestSetupUser() { + public static function dataTestSetupUser(): array { return [ [true, true], [false, true] diff --git a/apps/encryption/tests/UtilTest.php b/apps/encryption/tests/UtilTest.php index 711564af5bd..3556b9e34c1 100644 --- a/apps/encryption/tests/UtilTest.php +++ b/apps/encryption/tests/UtilTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -20,22 +22,14 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class UtilTest extends TestCase { - private static $tempStorage = []; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $configMock; - - /** @var View|\PHPUnit\Framework\MockObject\MockObject */ - private $filesMock; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManagerMock; - /** @var IMountPoint|\PHPUnit\Framework\MockObject\MockObject */ - private $mountMock; + protected Util $instance; + protected static $tempStorage = []; - /** @var Util */ - private $instance; + protected IConfig&MockObject $configMock; + protected View&MockObject $filesMock; + protected IUserManager&MockObject $userManagerMock; + protected IMountPoint&MockObject $mountMock; public function testSetRecoveryForUser(): void { $this->instance->setRecoveryForUser('1'); @@ -134,7 +128,7 @@ class UtilTest extends TestCase { ); } - public function dataTestIsMasterKeyEnabled() { + public static function dataTestIsMasterKeyEnabled(): array { return [ ['0', false], ['1', true] @@ -155,7 +149,7 @@ class UtilTest extends TestCase { $this->instance->shouldEncryptHomeStorage()); } - public function dataTestShouldEncryptHomeStorage() { + public static function dataTestShouldEncryptHomeStorage(): array { return [ ['1', true], ['0', false] @@ -173,7 +167,7 @@ class UtilTest extends TestCase { $this->instance->setEncryptHomeStorage($value); } - public function dataTestSetEncryptHomeStorage() { + public static function dataTestSetEncryptHomeStorage(): array { return [ [true, '1'], [false, '0'] diff --git a/apps/federatedfilesharing/tests/AddressHandlerTest.php b/apps/federatedfilesharing/tests/AddressHandlerTest.php index ffb34d965ce..232ac21a869 100644 --- a/apps/federatedfilesharing/tests/AddressHandlerTest.php +++ b/apps/federatedfilesharing/tests/AddressHandlerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -16,31 +17,20 @@ use OCP\ICacheFactory; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; class AddressHandlerTest extends \Test\TestCase { - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $contactsManager; - - /** @var AddressHandler */ - private $addressHandler; - - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var IL10N | \PHPUnit\Framework\MockObject\MockObject */ - private $il10n; - - /** @var CloudIdManager */ - private $cloudIdManager; + protected IManager&MockObject $contactsManager; + private IURLGenerator&MockObject $urlGenerator; + private IL10N&MockObject $il10n; + private CloudIdManager $cloudIdManager; + private AddressHandler $addressHandler; protected function setUp(): void { parent::setUp(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class) - ->getMock(); - $this->il10n = $this->getMockBuilder(IL10N::class) - ->getMock(); - + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->il10n = $this->createMock(IL10N::class); $this->contactsManager = $this->createMock(IManager::class); $this->cloudIdManager = new CloudIdManager( @@ -54,7 +44,7 @@ class AddressHandlerTest extends \Test\TestCase { $this->addressHandler = new AddressHandler($this->urlGenerator, $this->il10n, $this->cloudIdManager); } - public function dataTestSplitUserRemote() { + public static function dataTestSplitUserRemote(): array { $userPrefix = ['user@name', 'username']; $protocols = ['', 'http://', 'https://']; $remotes = [ @@ -92,12 +82,8 @@ class AddressHandlerTest extends \Test\TestCase { /** * @dataProvider dataTestSplitUserRemote - * - * @param string $remote - * @param string $expectedUser - * @param string $expectedUrl */ - public function testSplitUserRemote($remote, $expectedUser, $expectedUrl): void { + public function testSplitUserRemote(string $remote, string $expectedUser, string $expectedUrl): void { $this->contactsManager->expects($this->any()) ->method('search') ->willReturn([]); @@ -107,7 +93,7 @@ class AddressHandlerTest extends \Test\TestCase { $this->assertSame($expectedUrl, $remoteUrl); } - public function dataTestSplitUserRemoteError() { + public static function dataTestSplitUserRemoteError(): array { return [ // Invalid path ['user@'], @@ -127,10 +113,8 @@ class AddressHandlerTest extends \Test\TestCase { /** * @dataProvider dataTestSplitUserRemoteError - * - * @param string $id */ - public function testSplitUserRemoteError($id): void { + public function testSplitUserRemoteError(string $id): void { $this->expectException(HintException::class); $this->addressHandler->splitUserRemote($id); @@ -138,20 +122,14 @@ class AddressHandlerTest extends \Test\TestCase { /** * @dataProvider dataTestCompareAddresses - * - * @param string $user1 - * @param string $server1 - * @param string $user2 - * @param string $server2 - * @param bool $expected */ - public function testCompareAddresses($user1, $server1, $user2, $server2, $expected): void { + public function testCompareAddresses(string $user1, string $server1, string $user2, string $server2, bool $expected): void { $this->assertSame($expected, $this->addressHandler->compareAddresses($user1, $server1, $user2, $server2) ); } - public function dataTestCompareAddresses() { + public static function dataTestCompareAddresses(): array { return [ ['user1', 'http://server1', 'user1', 'http://server1', true], ['user1', 'https://server1', 'user1', 'http://server1', true], @@ -173,35 +151,29 @@ class AddressHandlerTest extends \Test\TestCase { /** * @dataProvider dataTestRemoveProtocolFromUrl - * - * @param string $url - * @param string $expectedResult */ - public function testRemoveProtocolFromUrl($url, $expectedResult): void { + public function testRemoveProtocolFromUrl(string $url, string $expectedResult): void { $result = $this->addressHandler->removeProtocolFromUrl($url); $this->assertSame($expectedResult, $result); } - public function dataTestRemoveProtocolFromUrl() { + public static function dataTestRemoveProtocolFromUrl(): array { return [ - ['http://owncloud.org', 'owncloud.org'], - ['https://owncloud.org', 'owncloud.org'], - ['owncloud.org', 'owncloud.org'], + ['http://example.tld', 'example.tld'], + ['https://example.tld', 'example.tld'], + ['example.tld', 'example.tld'], ]; } /** * @dataProvider dataTestUrlContainProtocol - * - * @param string $url - * @param bool $expectedResult */ - public function testUrlContainProtocol($url, $expectedResult): void { + public function testUrlContainProtocol(string $url, bool $expectedResult): void { $result = $this->addressHandler->urlContainProtocol($url); $this->assertSame($expectedResult, $result); } - public function dataTestUrlContainProtocol() { + public static function dataTestUrlContainProtocol(): array { return [ ['http://nextcloud.com', true], ['https://nextcloud.com', true], diff --git a/apps/federatedfilesharing/tests/Controller/MountPublicLinkControllerTest.php b/apps/federatedfilesharing/tests/Controller/MountPublicLinkControllerTest.php index 8222f25bb49..a6c10148425 100644 --- a/apps/federatedfilesharing/tests/Controller/MountPublicLinkControllerTest.php +++ b/apps/federatedfilesharing/tests/Controller/MountPublicLinkControllerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -31,64 +33,35 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class MountPublicLinkControllerTest extends \Test\TestCase { - /** @var IContactsManager|MockObject */ - protected $contactsManager; - - /** @var MountPublicLinkController */ - private $controller; - - /** @var IRequest|MockObject */ - private $request; - - /** @var FederatedShareProvider|MockObject */ - private $federatedShareProvider; - - /** @var IManager|MockObject */ - private $shareManager; - - /** @var AddressHandler|MockObject */ - private $addressHandler; - - /** @var IRootFolder|MockObject */ - private $rootFolder; - - /** @var IUserManager|MockObject */ - private $userManager; - - /** @var ISession|MockObject */ - private $session; - - /** @var IL10N|MockObject */ - private $l10n; - - /** @var IUserSession|MockObject */ - private $userSession; - - /** @var IClientService|MockObject */ - private $clientService; - - /** @var IShare */ - private $share; - - /** @var ICloudIdManager */ - private $cloudIdManager; + protected IContactsManager&MockObject $contactsManager; + private IRequest&MockObject $request; + private FederatedShareProvider&MockObject $federatedShareProvider; + private IManager&MockObject $shareManager; + private AddressHandler&MockObject $addressHandler; + private IRootFolder&MockObject $rootFolder; + private IUserManager&MockObject $userManager; + private ISession&MockObject $session; + private IL10N&MockObject $l10n; + private IUserSession&MockObject $userSession; + private IClientService&MockObject $clientService; + private IShare $share; + private ICloudIdManager $cloudIdManager; + private MountPublicLinkController $controller; protected function setUp(): void { parent::setUp(); - $this->request = $this->getMockBuilder(IRequest::class)->disableOriginalConstructor()->getMock(); - $this->federatedShareProvider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider') - ->disableOriginalConstructor()->getMock(); - $this->shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); - $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler') - ->disableOriginalConstructor()->getMock(); - $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->disableOriginalConstructor()->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class)->disableOriginalConstructor()->getMock(); + $this->request = $this->createMock(IRequest::class); + $this->federatedShareProvider = $this->createMock(FederatedShareProvider::class); + $this->shareManager = $this->createMock(IManager::class); + $this->addressHandler = $this->createMock(AddressHandler::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->userManager = $this->createMock(IUserManager::class); $this->share = new Share($this->rootFolder, $this->userManager); - $this->session = $this->getMockBuilder(ISession::class)->disableOriginalConstructor()->getMock(); - $this->l10n = $this->getMockBuilder(IL10N::class)->disableOriginalConstructor()->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class)->disableOriginalConstructor()->getMock(); - $this->clientService = $this->getMockBuilder('OCP\Http\Client\IClientService')->disableOriginalConstructor()->getMock(); + $this->session = $this->createMock(ISession::class); + $this->l10n = $this->createMock(IL10N::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->clientService = $this->createMock(IClientService::class); $this->contactsManager = $this->createMock(IContactsManager::class); $this->cloudIdManager = new CloudIdManager( $this->contactsManager, @@ -114,23 +87,16 @@ class MountPublicLinkControllerTest extends \Test\TestCase { /** * @dataProvider dataTestCreateFederatedShare - * - * @param string $shareWith - * @param bool $outgoingSharesAllowed - * @param bool $validShareWith - * @param string $token - * @param bool $validToken - * @param bool $createSuccessful - * @param string $expectedReturnData */ - public function testCreateFederatedShare($shareWith, - $outgoingSharesAllowed, - $validShareWith, - $token, - $validToken, - $createSuccessful, - $expectedReturnData, - $permissions, + public function testCreateFederatedShare( + string $shareWith, + bool $outgoingSharesAllowed, + bool $validShareWith, + string $token, + bool $validToken, + bool $createSuccessful, + string $expectedReturnData, + int $permissions, ): void { $this->federatedShareProvider->expects($this->any()) ->method('isOutgoingServer2serverShareEnabled') @@ -188,7 +154,7 @@ class MountPublicLinkControllerTest extends \Test\TestCase { } } - public function dataTestCreateFederatedShare() { + public static function dataTestCreateFederatedShare(): array { return [ //shareWith, outgoingSharesAllowed, validShareWith, token, validToken, createSuccessful, expectedReturnData ['user@server', true, true, 'token', true, true, 'server', 31], diff --git a/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php b/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php index c4c45c1aca5..81c67a29254 100644 --- a/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php +++ b/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -23,6 +24,7 @@ use OCP\IRequest; use OCP\IUserManager; use OCP\Share; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; /** @@ -32,65 +34,32 @@ use Psr\Log\LoggerInterface; * @group DB */ class RequestHandlerControllerTest extends \Test\TestCase { - private $owner = 'owner'; - private $user1 = 'user1'; - private $user2 = 'user2'; - private $ownerCloudId = 'owner@server0.org'; - private $user1CloudId = 'user1@server1.org'; - private $user2CloudId = 'user2@server2.org'; - - /** @var RequestHandlerController */ - private $requestHandler; - - /** @var FederatedShareProvider|\PHPUnit\Framework\MockObject\MockObject */ - private $federatedShareProvider; - - /** @var Notifications|\PHPUnit\Framework\MockObject\MockObject */ - private $notifications; - - /** @var AddressHandler|\PHPUnit\Framework\MockObject\MockObject */ - private $addressHandler; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - - /** @var IShare|\PHPUnit\Framework\MockObject\MockObject */ - private $share; - - /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudIdManager; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; - - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - private $connection; - - /** @var Share\IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - - /** @var ICloudFederationFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationFactory; - - /** @var ICloudFederationProviderManager|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationProviderManager; - - /** @var ICloudFederationProvider|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationProvider; - - /** @var ICloudFederationShare|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationShare; - - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ - private $eventDispatcher; + private string $owner = 'owner'; + private string $user1 = 'user1'; + private string $user2 = 'user2'; + private string $ownerCloudId = 'owner@server0.org'; + private string $user1CloudId = 'user1@server1.org'; + + private RequestHandlerController $requestHandler; + private FederatedShareProvider&MockObject $federatedShareProvider; + private Notifications&MockObject $notifications; + private AddressHandler&MockObject $addressHandler; + private IUserManager&MockObject $userManager; + private IShare&MockObject $share; + private ICloudIdManager&MockObject $cloudIdManager; + private LoggerInterface&MockObject $logger; + private IRequest&MockObject $request; + private IDBConnection&MockObject $connection; + private Share\IManager&MockObject $shareManager; + private ICloudFederationFactory&MockObject $cloudFederationFactory; + private ICloudFederationProviderManager&MockObject $cloudFederationProviderManager; + private ICloudFederationProvider&MockObject $cloudFederationProvider; + private ICloudFederationShare&MockObject $cloudFederationShare; + private IEventDispatcher&MockObject $eventDispatcher; protected function setUp(): void { - $this->share = $this->getMockBuilder(IShare::class)->getMock(); - $this->federatedShareProvider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider') - ->disableOriginalConstructor()->getMock(); + $this->share = $this->createMock(IShare::class); + $this->federatedShareProvider = $this->createMock(FederatedShareProvider::class); $this->federatedShareProvider->expects($this->any()) ->method('isOutgoingServer2serverShareEnabled')->willReturn(true); $this->federatedShareProvider->expects($this->any()) @@ -98,11 +67,9 @@ class RequestHandlerControllerTest extends \Test\TestCase { $this->federatedShareProvider->expects($this->any())->method('getShareById') ->willReturn($this->share); - $this->notifications = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications') - ->disableOriginalConstructor()->getMock(); - $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler') - ->disableOriginalConstructor()->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock(); + $this->notifications = $this->createMock(Notifications::class); + $this->addressHandler = $this->createMock(AddressHandler::class); + $this->userManager = $this->createMock(IUserManager::class); $this->cloudIdManager = $this->createMock(ICloudIdManager::class); $this->request = $this->createMock(IRequest::class); $this->connection = $this->createMock(IDBConnection::class); @@ -149,7 +116,7 @@ class RequestHandlerControllerTest extends \Test\TestCase { 'file' )->willReturn($this->cloudFederationShare); - /** @var ICloudFederationProvider|\PHPUnit\Framework\MockObject\MockObject $provider */ + /** @var ICloudFederationProvider&MockObject $provider */ $this->cloudFederationProviderManager->expects($this->once()) ->method('getCloudFederationProvider') ->with('file') diff --git a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php index 002a8bac374..fc6dbf7a699 100644 --- a/apps/federatedfilesharing/tests/FederatedShareProviderTest.php +++ b/apps/federatedfilesharing/tests/FederatedShareProviderTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -38,61 +39,39 @@ use Psr\Log\LoggerInterface; * @group DB */ class FederatedShareProviderTest extends \Test\TestCase { - /** @var IDBConnection */ - protected $connection; - /** @var AddressHandler|MockObject */ - protected $addressHandler; - /** @var Notifications|MockObject */ - protected $notifications; - /** @var TokenHandler|MockObject */ - protected $tokenHandler; - /** @var IL10N */ - protected $l; - /** @var LoggerInterface */ - protected $logger; - /** @var IRootFolder|MockObject */ - protected $rootFolder; - /** @var IConfig|MockObject */ - protected $config; - /** @var IUserManager|MockObject */ - protected $userManager; - /** @var \OCP\GlobalScale\IConfig|MockObject */ - protected $gsConfig; - - /** @var IManager */ - protected $shareManager; - /** @var FederatedShareProvider */ - protected $provider; - /** @var IContactsManager|MockObject */ - protected $contactsManager; - - /** @var ICloudIdManager */ - private $cloudIdManager; - - /** @var MockObject|ICloudFederationProviderManager */ - private $cloudFederationProviderManager; + protected IDBConnection $connection; + protected AddressHandler&MockObject $addressHandler; + protected Notifications&MockObject $notifications; + protected TokenHandler&MockObject $tokenHandler; + protected IL10N $l; + protected LoggerInterface $logger; + protected IRootFolder&MockObject $rootFolder; + protected IConfig&MockObject $config; + protected IUserManager&MockObject $userManager; + protected \OCP\GlobalScale\IConfig&MockObject $gsConfig; + protected IManager $shareManager; + protected FederatedShareProvider $provider; + protected IContactsManager&MockObject $contactsManager; + private ICloudIdManager $cloudIdManager; + private ICloudFederationProviderManager&MockObject $cloudFederationProviderManager; protected function setUp(): void { parent::setUp(); $this->connection = Server::get(IDBConnection::class); - $this->notifications = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications') - ->disableOriginalConstructor() - ->getMock(); - $this->tokenHandler = $this->getMockBuilder('OCA\FederatedFileSharing\TokenHandler') - ->disableOriginalConstructor() - ->getMock(); - $this->l = $this->getMockBuilder(IL10N::class)->getMock(); + $this->notifications = $this->createMock(Notifications::class); + $this->tokenHandler = $this->createMock(TokenHandler::class); + $this->l = $this->createMock(IL10N::class); $this->l->method('t') ->willReturnCallback(function ($text, $parameters = []) { return vsprintf($text, $parameters); }); - $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); - $this->config = $this->getMockBuilder(IConfig::class)->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock(); + $this->logger = $this->createMock(LoggerInterface::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->config = $this->createMock(IConfig::class); + $this->userManager = $this->createMock(IUserManager::class); //$this->addressHandler = new AddressHandler(\OC::$server->getURLGenerator(), $this->l); - $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler')->disableOriginalConstructor()->getMock(); + $this->addressHandler = $this->createMock(AddressHandler::class); $this->contactsManager = $this->createMock(IContactsManager::class); $this->cloudIdManager = new CloudIdManager( $this->contactsManager, @@ -122,16 +101,16 @@ class FederatedShareProviderTest extends \Test\TestCase { $this->logger, ); - $this->shareManager = Server::get(\OCP\Share\IManager::class); + $this->shareManager = Server::get(IManager::class); } protected function tearDown(): void { - $this->connection->getQueryBuilder()->delete('share')->execute(); + $this->connection->getQueryBuilder()->delete('share')->executeStatement(); parent::tearDown(); } - public function dataTestCreate() { + public static function dataTestCreate(): array { return [ [null, null], [new \DateTime('2020-03-01T01:02:03'), '2020-03-01 01:02:03'], @@ -141,11 +120,11 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestCreate */ - public function testCreate($expirationDate, $expectedDataDate): void { + public function testCreate(?\DateTime $expirationDate, ?string $expectedDataDate): void { $share = $this->shareManager->newShare(); - /** @var File|MockObject $node */ - $node = $this->getMockBuilder(File::class)->getMock(); + /** @var File&MockObject $node */ + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -190,7 +169,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $stmt = $qb->select('*') ->from('share') ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) - ->execute(); + ->executeQuery(); $data = $stmt->fetch(); $stmt->closeCursor(); @@ -227,7 +206,7 @@ class FederatedShareProviderTest extends \Test\TestCase { public function testCreateCouldNotFindServer(): void { $share = $this->shareManager->newShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -277,7 +256,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $stmt = $qb->select('*') ->from('share') ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) - ->execute(); + ->executeQuery(); $data = $stmt->fetch(); $stmt->closeCursor(); @@ -288,7 +267,7 @@ class FederatedShareProviderTest extends \Test\TestCase { public function testCreateException(): void { $share = $this->shareManager->newShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -338,7 +317,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $stmt = $qb->select('*') ->from('share') ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) - ->execute(); + ->executeQuery(); $data = $stmt->fetch(); $stmt->closeCursor(); @@ -349,7 +328,7 @@ class FederatedShareProviderTest extends \Test\TestCase { public function testCreateShareWithSelf(): void { $share = $this->shareManager->newShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -381,7 +360,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $stmt = $qb->select('*') ->from('share') ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) - ->execute(); + ->executeQuery(); $data = $stmt->fetch(); $stmt->closeCursor(); @@ -392,7 +371,7 @@ class FederatedShareProviderTest extends \Test\TestCase { public function testCreateAlreadyShared(): void { $share = $this->shareManager->newShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -443,8 +422,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestUpdate */ - public function testUpdate($owner, $sharedBy, $expirationDate): void { - $this->provider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider') + public function testUpdate(string $owner, string $sharedBy, ?\DateTime $expirationDate): void { + $this->provider = $this->getMockBuilder(FederatedShareProvider::class) ->setConstructorArgs( [ $this->connection, @@ -460,11 +439,13 @@ class FederatedShareProviderTest extends \Test\TestCase { $this->cloudFederationProviderManager, $this->logger, ] - )->setMethods(['sendPermissionUpdate'])->getMock(); + ) + ->onlyMethods(['sendPermissionUpdate']) + ->getMock(); $share = $this->shareManager->newShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -520,7 +501,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $this->assertEquals($expirationDate, $share->getExpirationDate()); } - public function dataTestUpdate() { + public static function dataTestUpdate(): array { return [ ['sharedBy', 'shareOwner', new \DateTime('2020-03-01T01:02:03')], ['shareOwner', 'shareOwner', null], @@ -528,7 +509,7 @@ class FederatedShareProviderTest extends \Test\TestCase { } public function testGetSharedBy(): void { - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -574,7 +555,7 @@ class FederatedShareProviderTest extends \Test\TestCase { } public function testGetSharedByWithNode(): void { - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -621,7 +602,7 @@ class FederatedShareProviderTest extends \Test\TestCase { } public function testGetSharedByWithReshares(): void { - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -663,7 +644,7 @@ class FederatedShareProviderTest extends \Test\TestCase { } public function testGetSharedByWithLimit(): void { - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->method('getId')->willReturn(42); $node->method('getName')->willReturn('myFile'); @@ -713,7 +694,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $this->assertEquals('user2@server.com', $shares[0]->getSharedWith()); } - public function dataDeleteUser() { + public static function dataDeleteUser(): array { return [ ['a', 'b', 'c', 'a', true], ['a', 'b', 'c', 'b', false], @@ -732,7 +713,7 @@ class FederatedShareProviderTest extends \Test\TestCase { * @param string $deletedUser The user that is deleted * @param bool $rowDeleted Is the row deleted in this setup */ - public function testDeleteUser($owner, $initiator, $recipient, $deletedUser, $rowDeleted): void { + public function testDeleteUser(string $owner, string $initiator, string $recipient, string $deletedUser, bool $rowDeleted): void { $qb = $this->connection->getQueryBuilder(); $qb->insert('share') ->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_REMOTE)) @@ -742,7 +723,7 @@ class FederatedShareProviderTest extends \Test\TestCase { ->setValue('item_type', $qb->createNamedParameter('file')) ->setValue('item_source', $qb->createNamedParameter(42)) ->setValue('file_source', $qb->createNamedParameter(42)) - ->execute(); + ->executeStatement(); $id = $qb->getLastInsertId(); @@ -754,7 +735,7 @@ class FederatedShareProviderTest extends \Test\TestCase { ->where( $qb->expr()->eq('id', $qb->createNamedParameter($id)) ); - $cursor = $qb->execute(); + $cursor = $qb->executeQuery(); $data = $cursor->fetchAll(); $cursor->closeCursor(); @@ -763,11 +744,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestIsOutgoingServer2serverShareEnabled - * - * @param string $isEnabled - * @param bool $expected */ - public function testIsOutgoingServer2serverShareEnabled($internalOnly, $isEnabled, $expected): void { + public function testIsOutgoingServer2serverShareEnabled(bool $internalOnly, string $isEnabled, bool $expected): void { $this->gsConfig->expects($this->once())->method('onlyInternalFederation') ->willReturn($internalOnly); $this->config->expects($this->any())->method('getAppValue') @@ -779,7 +757,7 @@ class FederatedShareProviderTest extends \Test\TestCase { ); } - public function dataTestIsOutgoingServer2serverShareEnabled() { + public static function dataTestIsOutgoingServer2serverShareEnabled(): array { return [ [false, 'yes', true], [false, 'no', false], @@ -790,11 +768,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestIsIncomingServer2serverShareEnabled - * - * @param string $isEnabled - * @param bool $expected */ - public function testIsIncomingServer2serverShareEnabled($onlyInternal, $isEnabled, $expected): void { + public function testIsIncomingServer2serverShareEnabled(bool $onlyInternal, string $isEnabled, bool $expected): void { $this->gsConfig->expects($this->once())->method('onlyInternalFederation') ->willReturn($onlyInternal); $this->config->expects($this->any())->method('getAppValue') @@ -806,7 +781,7 @@ class FederatedShareProviderTest extends \Test\TestCase { ); } - public function dataTestIsIncomingServer2serverShareEnabled() { + public static function dataTestIsIncomingServer2serverShareEnabled(): array { return [ [false, 'yes', true], [false, 'no', false], @@ -817,11 +792,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestIsLookupServerQueriesEnabled - * - * @param string $isEnabled - * @param bool $expected */ - public function testIsLookupServerQueriesEnabled($gsEnabled, $isEnabled, $expected): void { + public function testIsLookupServerQueriesEnabled(bool $gsEnabled, string $isEnabled, bool $expected): void { $this->gsConfig->expects($this->once())->method('isGlobalScaleEnabled') ->willReturn($gsEnabled); $this->config->expects($this->any())->method('getAppValue') @@ -834,7 +806,7 @@ class FederatedShareProviderTest extends \Test\TestCase { } - public function dataTestIsLookupServerQueriesEnabled() { + public static function dataTestIsLookupServerQueriesEnabled(): array { return [ [true, 'yes', true], [true, 'no', true], @@ -848,11 +820,8 @@ class FederatedShareProviderTest extends \Test\TestCase { /** * @dataProvider dataTestIsLookupServerUploadEnabled - * - * @param string $isEnabled - * @param bool $expected */ - public function testIsLookupServerUploadEnabled($gsEnabled, $isEnabled, $expected): void { + public function testIsLookupServerUploadEnabled(bool $gsEnabled, string $isEnabled, bool $expected): void { $this->gsConfig->expects($this->once())->method('isGlobalScaleEnabled') ->willReturn($gsEnabled); $this->config->expects($this->any())->method('getAppValue') @@ -864,7 +833,7 @@ class FederatedShareProviderTest extends \Test\TestCase { ); } - public function dataTestIsLookupServerUploadEnabled() { + public static function dataTestIsLookupServerUploadEnabled(): array { return [ [true, 'yes', false], [true, 'no', false], @@ -880,8 +849,8 @@ class FederatedShareProviderTest extends \Test\TestCase { $userManager = Server::get(IUserManager::class); $rootFolder = Server::get(IRootFolder::class); - $u1 = $userManager->createUser('testFed', md5(time())); - $u2 = $userManager->createUser('testFed2', md5(time())); + $u1 = $userManager->createUser('testFed', md5((string)time())); + $u2 = $userManager->createUser('testFed2', md5((string)time())); $folder1 = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo'); $file1 = $folder1->newFile('bar1'); @@ -934,7 +903,7 @@ class FederatedShareProviderTest extends \Test\TestCase { $userManager = Server::get(IUserManager::class); $rootFolder = Server::get(IRootFolder::class); - $u1 = $userManager->createUser('testFed', md5(time())); + $u1 = $userManager->createUser('testFed', md5((string)time())); $folder1 = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo'); $file1 = $folder1->newFile('bar1'); diff --git a/apps/federatedfilesharing/tests/NotificationsTest.php b/apps/federatedfilesharing/tests/NotificationsTest.php index 7ac4e964362..94d08b5aa5d 100644 --- a/apps/federatedfilesharing/tests/NotificationsTest.php +++ b/apps/federatedfilesharing/tests/NotificationsTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,6 +9,7 @@ namespace OCA\FederatedFileSharing\Tests; use OCA\FederatedFileSharing\AddressHandler; +use OCA\FederatedFileSharing\BackgroundJob\RetryJob; use OCA\FederatedFileSharing\Notifications; use OCP\BackgroundJob\IJobList; use OCP\EventDispatcher\IEventDispatcher; @@ -19,38 +21,22 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class NotificationsTest extends \Test\TestCase { - /** @var AddressHandler|MockObject */ - private $addressHandler; - - /** @var IClientService|MockObject */ - private $httpClientService; - - /** @var IDiscoveryService|MockObject */ - private $discoveryService; - - /** @var IJobList|MockObject */ - private $jobList; - - /** @var ICloudFederationProviderManager|MockObject */ - private $cloudFederationProviderManager; - - /** @var ICloudFederationFactory|MockObject */ - private $cloudFederationFactory; - - /** @var IEventDispatcher|MockObject */ - private $eventDispatcher; - - /** @var LoggerInterface|MockObject */ - private $logger; + private AddressHandler&MockObject $addressHandler; + private IClientService&MockObject $httpClientService; + private IDiscoveryService&MockObject $discoveryService; + private IJobList&MockObject $jobList; + private ICloudFederationProviderManager&MockObject $cloudFederationProviderManager; + private ICloudFederationFactory&MockObject $cloudFederationFactory; + private IEventDispatcher&MockObject $eventDispatcher; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); - $this->jobList = $this->getMockBuilder('OCP\BackgroundJob\IJobList')->getMock(); - $this->discoveryService = $this->getMockBuilder(IDiscoveryService::class)->getMock(); - $this->httpClientService = $this->getMockBuilder('OCP\Http\Client\IClientService')->getMock(); - $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler') - ->disableOriginalConstructor()->getMock(); + $this->jobList = $this->createMock(IJobList::class); + $this->discoveryService = $this->createMock(IDiscoveryService::class); + $this->httpClientService = $this->createMock(IClientService::class); + $this->addressHandler = $this->createMock(AddressHandler::class); $this->logger = $this->createMock(LoggerInterface::class); $this->cloudFederationProviderManager = $this->createMock(ICloudFederationProviderManager::class); $this->cloudFederationFactory = $this->createMock(ICloudFederationFactory::class); @@ -58,14 +44,11 @@ class NotificationsTest extends \Test\TestCase { } /** - * get instance of Notifications class - * - * @param array $mockedMethods methods which should be mocked - * @return Notifications | \PHPUnit\Framework\MockObject\MockObject + * @return Notifications|MockObject */ private function getInstance(array $mockedMethods = []) { if (empty($mockedMethods)) { - $instance = new Notifications( + return new Notifications( $this->addressHandler, $this->httpClientService, $this->discoveryService, @@ -75,34 +58,30 @@ class NotificationsTest extends \Test\TestCase { $this->eventDispatcher, $this->logger, ); - } else { - $instance = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications') - ->setConstructorArgs( - [ - $this->addressHandler, - $this->httpClientService, - $this->discoveryService, - $this->jobList, - $this->cloudFederationProviderManager, - $this->cloudFederationFactory, - $this->eventDispatcher, - $this->logger, - ] - )->setMethods($mockedMethods)->getMock(); } - return $instance; + return $this->getMockBuilder(Notifications::class) + ->setConstructorArgs( + [ + $this->addressHandler, + $this->httpClientService, + $this->discoveryService, + $this->jobList, + $this->cloudFederationProviderManager, + $this->cloudFederationFactory, + $this->eventDispatcher, + $this->logger, + ] + ) + ->onlyMethods($mockedMethods) + ->getMock(); } /** * @dataProvider dataTestSendUpdateToRemote - * - * @param int $try - * @param array $httpRequestResult - * @param bool $expected */ - public function testSendUpdateToRemote($try, $httpRequestResult, $expected): void { + public function testSendUpdateToRemote(int $try, array $httpRequestResult, bool $expected): void { $remote = 'http://remote'; $id = 42; $timestamp = 63576; @@ -120,7 +99,7 @@ class NotificationsTest extends \Test\TestCase { if ($try === 0 && $expected === false) { $this->jobList->expects($this->once())->method('add') ->with( - 'OCA\FederatedFileSharing\BackgroundJob\RetryJob', + RetryJob::class, [ 'remote' => $remote, 'remoteId' => $id, @@ -141,7 +120,7 @@ class NotificationsTest extends \Test\TestCase { } - public function dataTestSendUpdateToRemote() { + public static function dataTestSendUpdateToRemote(): array { return [ // test if background job is added correctly [0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], true], diff --git a/apps/federatedfilesharing/tests/Settings/AdminTest.php b/apps/federatedfilesharing/tests/Settings/AdminTest.php index efbe763c633..1eb75003b4f 100644 --- a/apps/federatedfilesharing/tests/Settings/AdminTest.php +++ b/apps/federatedfilesharing/tests/Settings/AdminTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,17 +14,14 @@ use OCP\AppFramework\Services\IInitialState; use OCP\GlobalScale\IConfig; use OCP\IL10N; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class AdminTest extends TestCase { - /** @var Admin */ - private $admin; - /** @var FederatedShareProvider */ - private $federatedShareProvider; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $gsConfig; - /** @var IInitialState|\PHPUnit\Framework\MockObject\MockObject */ - private $initialState; + private FederatedShareProvider&MockObject $federatedShareProvider; + private IConfig $gsConfig; + private IInitialState&MockObject $initialState; + private Admin $admin; protected function setUp(): void { parent::setUp(); @@ -43,7 +42,7 @@ class AdminTest extends TestCase { ); } - public function sharingStateProvider() { + public static function sharingStateProvider(): array { return [ [ true, @@ -56,9 +55,8 @@ class AdminTest extends TestCase { /** * @dataProvider sharingStateProvider - * @param bool $state */ - public function testGetForm($state): void { + public function testGetForm(bool $state): void { $this->federatedShareProvider ->expects($this->once()) ->method('isOutgoingServer2serverShareEnabled') @@ -98,20 +96,24 @@ class AdminTest extends TestCase { $this->gsConfig->expects($this->once())->method('onlyInternalFederation') ->willReturn($state); + $calls = [ + ['internalOnly', $state], + ['sharingFederatedDocUrl', 'doc-link'], + ['outgoingServer2serverShareEnabled', $state], + ['incomingServer2serverShareEnabled', $state], + ['federatedGroupSharingSupported', $state], + ['outgoingServer2serverGroupShareEnabled', $state], + ['incomingServer2serverGroupShareEnabled', $state], + ['lookupServerEnabled', $state], + ['lookupServerUploadEnabled', $state], + ['federatedTrustedShareAutoAccept', $state], + ]; $this->initialState->expects($this->exactly(10)) ->method('provideInitialState') - ->withConsecutive( - ['internalOnly', $state], - ['sharingFederatedDocUrl', 'doc-link'], - ['outgoingServer2serverShareEnabled', $state], - ['incomingServer2serverShareEnabled', $state], - ['federatedGroupSharingSupported', $state], - ['outgoingServer2serverGroupShareEnabled', $state], - ['incomingServer2serverGroupShareEnabled', $state], - ['lookupServerEnabled', $state], - ['lookupServerUploadEnabled', $state], - ['federatedTrustedShareAutoAccept', $state] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected, func_get_args()); + }); $expected = new TemplateResponse('federatedfilesharing', 'settings-admin', [], ''); $this->assertEquals($expected, $this->admin->getForm()); diff --git a/apps/federatedfilesharing/tests/TestCase.php b/apps/federatedfilesharing/tests/TestCase.php index b9787f2ffab..1536e1b3375 100644 --- a/apps/federatedfilesharing/tests/TestCase.php +++ b/apps/federatedfilesharing/tests/TestCase.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -9,6 +10,7 @@ namespace OCA\FederatedFileSharing\Tests; use OC\Files\Filesystem; use OC\Group\Database; +use OCP\Files\IRootFolder; use OCP\IGroupManager; use OCP\IUserManager; use OCP\IUserSession; @@ -70,12 +72,7 @@ abstract class TestCase extends \Test\TestCase { parent::tearDownAfterClass(); } - /** - * @param string $user - * @param bool $create - * @param bool $password - */ - protected static function loginHelper($user, $create = false, $password = false) { + protected static function loginHelper(string $user, bool $create = false, bool $password = false) { if ($password === false) { $password = $user; } @@ -96,7 +93,7 @@ abstract class TestCase extends \Test\TestCase { Server::get(IUserSession::class)->setUser(null); Filesystem::tearDown(); Server::get(IUserSession::class)->login($user, $password); - \OC::$server->getUserFolder($user); + \OCP\Server::get(IRootFolder::class)->getUserFolder($user); \OC_Util::setupFS($user); } diff --git a/apps/federatedfilesharing/tests/TokenHandlerTest.php b/apps/federatedfilesharing/tests/TokenHandlerTest.php index 9ed20779857..7a210274013 100644 --- a/apps/federatedfilesharing/tests/TokenHandlerTest.php +++ b/apps/federatedfilesharing/tests/TokenHandlerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -9,17 +10,12 @@ namespace OCA\FederatedFileSharing\Tests; use OCA\FederatedFileSharing\TokenHandler; use OCP\Security\ISecureRandom; +use PHPUnit\Framework\MockObject\MockObject; class TokenHandlerTest extends \Test\TestCase { - - /** @var TokenHandler */ - private $tokenHandler; - - /** @var ISecureRandom | \PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; - - /** @var int */ - private $expectedTokenLength = 15; + private TokenHandler $tokenHandler; + private ISecureRandom&MockObject $secureRandom; + private int $expectedTokenLength = 15; protected function setUp(): void { parent::setUp(); diff --git a/apps/federation/tests/BackgroundJob/GetSharedSecretTest.php b/apps/federation/tests/BackgroundJob/GetSharedSecretTest.php index 3da2e2e15e4..7ac68d618a1 100644 --- a/apps/federation/tests/BackgroundJob/GetSharedSecretTest.php +++ b/apps/federation/tests/BackgroundJob/GetSharedSecretTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -77,12 +78,9 @@ class GetSharedSecretTest extends TestCase { /** * @dataProvider dataTestExecute - * - * @param bool $isTrustedServer - * @param bool $retainBackgroundJob */ public function testExecute(bool $isTrustedServer, bool $retainBackgroundJob): void { - /** @var GetSharedSecret |\PHPUnit\Framework\MockObject\MockObject $getSharedSecret */ + /** @var GetSharedSecret&MockObject $getSharedSecret */ $getSharedSecret = $this->getMockBuilder(GetSharedSecret::class) ->setConstructorArgs( [ @@ -95,8 +93,10 @@ class GetSharedSecretTest extends TestCase { $this->timeFactory, $this->config, ] - )->setMethods(['parentStart'])->getMock(); - $this->invokePrivate($getSharedSecret, 'argument', [['url' => 'url', 'token' => 'token']]); + ) + ->onlyMethods(['parentStart']) + ->getMock(); + self::invokePrivate($getSharedSecret, 'argument', [['url' => 'url', 'token' => 'token']]); $this->trustedServers->expects($this->once())->method('isTrustedServer') ->with('url')->willReturn($isTrustedServer); @@ -105,7 +105,7 @@ class GetSharedSecretTest extends TestCase { } else { $getSharedSecret->expects($this->never())->method('parentStart'); } - $this->invokePrivate($getSharedSecret, 'retainJob', [$retainBackgroundJob]); + self::invokePrivate($getSharedSecret, 'retainJob', [$retainBackgroundJob]); $this->jobList->expects($this->once())->method('remove'); $this->timeFactory->method('getTime')->willReturn(42); @@ -128,7 +128,7 @@ class GetSharedSecretTest extends TestCase { $getSharedSecret->start($this->jobList); } - public function dataTestExecute() { + public static function dataTestExecute(): array { return [ [true, true], [true, false], @@ -138,10 +138,8 @@ class GetSharedSecretTest extends TestCase { /** * @dataProvider dataTestRun - * - * @param int $statusCode */ - public function testRun($statusCode): void { + public function testRun(int $statusCode): void { $target = 'targetURL'; $source = 'sourceURL'; $token = 'token'; @@ -181,18 +179,18 @@ class GetSharedSecretTest extends TestCase { $this->trustedServers->expects($this->never())->method('addSharedSecret'); } - $this->invokePrivate($this->getSharedSecret, 'run', [$argument]); + self::invokePrivate($this->getSharedSecret, 'run', [$argument]); if ( $statusCode !== Http::STATUS_OK && $statusCode !== Http::STATUS_FORBIDDEN ) { - $this->assertTrue($this->invokePrivate($this->getSharedSecret, 'retainJob')); + $this->assertTrue(self::invokePrivate($this->getSharedSecret, 'retainJob')); } else { - $this->assertFalse($this->invokePrivate($this->getSharedSecret, 'retainJob')); + $this->assertFalse(self::invokePrivate($this->getSharedSecret, 'retainJob')); } } - public function dataTestRun() { + public static function dataTestRun(): array { return [ [Http::STATUS_OK], [Http::STATUS_FORBIDDEN], @@ -227,7 +225,7 @@ class GetSharedSecretTest extends TestCase { TrustedServers::STATUS_FAILURE ); - $this->invokePrivate($this->getSharedSecret, 'run', [$argument]); + self::invokePrivate($this->getSharedSecret, 'run', [$argument]); } public function testRunConnectionError(): void { @@ -263,8 +261,8 @@ class GetSharedSecretTest extends TestCase { $this->trustedServers->expects($this->never())->method('addSharedSecret'); - $this->invokePrivate($this->getSharedSecret, 'run', [$argument]); + self::invokePrivate($this->getSharedSecret, 'run', [$argument]); - $this->assertTrue($this->invokePrivate($this->getSharedSecret, 'retainJob')); + $this->assertTrue(self::invokePrivate($this->getSharedSecret, 'retainJob')); } } diff --git a/apps/federation/tests/BackgroundJob/RequestSharedSecretTest.php b/apps/federation/tests/BackgroundJob/RequestSharedSecretTest.php index 68f8cc070c8..8bec10c11e1 100644 --- a/apps/federation/tests/BackgroundJob/RequestSharedSecretTest.php +++ b/apps/federation/tests/BackgroundJob/RequestSharedSecretTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -24,50 +25,28 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class RequestSharedSecretTest extends TestCase { - /** @var MockObject|IClientService */ - private $httpClientService; - - /** @var MockObject|IClient */ - private $httpClient; - - /** @var MockObject|IJobList */ - private $jobList; - - /** @var MockObject|IURLGenerator */ - private $urlGenerator; - - /** @var MockObject|TrustedServers */ - private $trustedServers; - - /** @var MockObject|IResponse */ - private $response; - - /** @var MockObject|IDiscoveryService */ - private $discoveryService; - - /** @var MockObject|LoggerInterface */ - private $logger; - - /** @var MockObject|ITimeFactory */ - private $timeFactory; - - /** @var MockObject|IConfig */ - private $config; - - /** @var RequestSharedSecret */ - private $requestSharedSecret; + private IClientService&MockObject $httpClientService; + private IClient&MockObject $httpClient; + private IJobList&MockObject $jobList; + private IURLGenerator&MockObject $urlGenerator; + private TrustedServers&MockObject $trustedServers; + private IResponse&MockObject $response; + private IDiscoveryService&MockObject $discoveryService; + private LoggerInterface&MockObject $logger; + private ITimeFactory&MockObject $timeFactory; + private IConfig&MockObject $config; + private RequestSharedSecret $requestSharedSecret; protected function setUp(): void { parent::setUp(); $this->httpClientService = $this->createMock(IClientService::class); - $this->httpClient = $this->getMockBuilder(IClient::class)->getMock(); - $this->jobList = $this->getMockBuilder(IJobList::class)->getMock(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock(); - $this->trustedServers = $this->getMockBuilder(TrustedServers::class) - ->disableOriginalConstructor()->getMock(); - $this->response = $this->getMockBuilder(IResponse::class)->getMock(); - $this->discoveryService = $this->getMockBuilder(IDiscoveryService::class)->getMock(); + $this->httpClient = $this->createMock(IClient::class); + $this->jobList = $this->createMock(IJobList::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->trustedServers = $this->createMock(TrustedServers::class); + $this->response = $this->createMock(IResponse::class); + $this->discoveryService = $this->createMock(IDiscoveryService::class); $this->logger = $this->createMock(LoggerInterface::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->config = $this->createMock(IConfig::class); @@ -89,13 +68,10 @@ class RequestSharedSecretTest extends TestCase { /** * @dataProvider dataTestStart - * - * @param bool $isTrustedServer - * @param bool $retainBackgroundJob */ - public function testStart($isTrustedServer, $retainBackgroundJob): void { - /** @var RequestSharedSecret |MockObject $requestSharedSecret */ - $requestSharedSecret = $this->getMockBuilder('OCA\Federation\BackgroundJob\RequestSharedSecret') + public function testStart(bool $isTrustedServer, bool $retainBackgroundJob): void { + /** @var RequestSharedSecret&MockObject $requestSharedSecret */ + $requestSharedSecret = $this->getMockBuilder(RequestSharedSecret::class) ->setConstructorArgs( [ $this->httpClientService, @@ -107,8 +83,10 @@ class RequestSharedSecretTest extends TestCase { $this->timeFactory, $this->config, ] - )->setMethods(['parentStart'])->getMock(); - $this->invokePrivate($requestSharedSecret, 'argument', [['url' => 'url', 'token' => 'token']]); + ) + ->onlyMethods(['parentStart']) + ->getMock(); + self::invokePrivate($requestSharedSecret, 'argument', [['url' => 'url', 'token' => 'token']]); $this->trustedServers->expects($this->once())->method('isTrustedServer') ->with('url')->willReturn($isTrustedServer); @@ -117,7 +95,7 @@ class RequestSharedSecretTest extends TestCase { } else { $requestSharedSecret->expects($this->never())->method('parentStart'); } - $this->invokePrivate($requestSharedSecret, 'retainJob', [$retainBackgroundJob]); + self::invokePrivate($requestSharedSecret, 'retainJob', [$retainBackgroundJob]); $this->jobList->expects($this->once())->method('remove'); $this->timeFactory->method('getTime')->willReturn(42); @@ -141,7 +119,7 @@ class RequestSharedSecretTest extends TestCase { $requestSharedSecret->start($this->jobList); } - public function dataTestStart() { + public static function dataTestStart(): array { return [ [true, true], [true, false], @@ -151,8 +129,6 @@ class RequestSharedSecretTest extends TestCase { /** * @dataProvider dataTestRun - * - * @param int $statusCode */ public function testRun(int $statusCode, int $attempt = 0): void { $target = 'targetURL'; @@ -184,18 +160,18 @@ class RequestSharedSecretTest extends TestCase { $this->response->expects($this->once())->method('getStatusCode') ->willReturn($statusCode); - $this->invokePrivate($this->requestSharedSecret, 'run', [$argument]); + self::invokePrivate($this->requestSharedSecret, 'run', [$argument]); if ( $statusCode !== Http::STATUS_OK && ($statusCode !== Http::STATUS_FORBIDDEN || $attempt < 5) ) { - $this->assertTrue($this->invokePrivate($this->requestSharedSecret, 'retainJob')); + $this->assertTrue(self::invokePrivate($this->requestSharedSecret, 'retainJob')); } else { - $this->assertFalse($this->invokePrivate($this->requestSharedSecret, 'retainJob')); + $this->assertFalse(self::invokePrivate($this->requestSharedSecret, 'retainJob')); } } - public function dataTestRun() { + public static function dataTestRun(): array { return [ [Http::STATUS_OK], [Http::STATUS_FORBIDDEN, 5], @@ -231,7 +207,7 @@ class RequestSharedSecretTest extends TestCase { TrustedServers::STATUS_FAILURE ); - $this->invokePrivate($this->requestSharedSecret, 'run', [$argument]); + self::invokePrivate($this->requestSharedSecret, 'run', [$argument]); } public function testRunConnectionError(): void { @@ -267,7 +243,7 @@ class RequestSharedSecretTest extends TestCase { ] )->willThrowException($this->createMock(ConnectException::class)); - $this->invokePrivate($this->requestSharedSecret, 'run', [$argument]); - $this->assertTrue($this->invokePrivate($this->requestSharedSecret, 'retainJob')); + self::invokePrivate($this->requestSharedSecret, 'run', [$argument]); + $this->assertTrue(self::invokePrivate($this->requestSharedSecret, 'retainJob')); } } diff --git a/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php b/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php index 9f2d41a1072..25b0db94e21 100644 --- a/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php +++ b/apps/federation/tests/Controller/OCSAuthAPIControllerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,6 +9,7 @@ namespace OCA\Federation\Tests\Controller; use OC\BackgroundJob\JobList; +use OCA\Federation\BackgroundJob\GetSharedSecret; use OCA\Federation\Controller\OCSAuthAPIController; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; @@ -16,34 +18,19 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\IRequest; use OCP\Security\Bruteforce\IThrottler; use OCP\Security\ISecureRandom; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; class OCSAuthAPIControllerTest extends TestCase { - /** @var \PHPUnit\Framework\MockObject\MockObject|IRequest */ - private $request; - - /** @var \PHPUnit\Framework\MockObject\MockObject|ISecureRandom */ - private $secureRandom; - - /** @var \PHPUnit\Framework\MockObject\MockObject|JobList */ - private $jobList; - - /** @var \PHPUnit\Framework\MockObject\MockObject|TrustedServers */ - private $trustedServers; - - /** @var \PHPUnit\Framework\MockObject\MockObject|DbHandler */ - private $dbHandler; - - /** @var \PHPUnit\Framework\MockObject\MockObject|LoggerInterface */ - private $logger; - - /** @var \PHPUnit\Framework\MockObject\MockObject|ITimeFactory */ - private $timeFactory; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IThrottler */ - private $throttler; - + private IRequest&MockObject $request; + private ISecureRandom&MockObject $secureRandom; + private JobList&MockObject $jobList; + private TrustedServers&MockObject $trustedServers; + private DbHandler&MockObject $dbHandler; + private LoggerInterface&MockObject $logger; + private ITimeFactory&MockObject $timeFactory; + private IThrottler&MockObject $throttler; private OCSAuthAPIController $ocsAuthApi; /** @var int simulated timestamp */ @@ -91,7 +78,7 @@ class OCSAuthAPIControllerTest extends TestCase { if ($ok) { $this->jobList->expects($this->once())->method('add') - ->with('OCA\Federation\BackgroundJob\GetSharedSecret', ['url' => $url, 'token' => $token, 'created' => $this->currentTime]); + ->with(GetSharedSecret::class, ['url' => $url, 'token' => $token, 'created' => $this->currentTime]); } else { $this->jobList->expects($this->never())->method('add'); $this->jobList->expects($this->never())->method('remove'); @@ -111,7 +98,7 @@ class OCSAuthAPIControllerTest extends TestCase { } } - public function dataTestRequestSharedSecret() { + public static function dataTestRequestSharedSecret(): array { return [ ['token2', 'token1', true, true], ['token1', 'token2', false, false], @@ -126,8 +113,8 @@ class OCSAuthAPIControllerTest extends TestCase { $url = 'url'; $token = 'token'; - /** @var OCSAuthAPIController | \PHPUnit\Framework\MockObject\MockObject $ocsAuthApi */ - $ocsAuthApi = $this->getMockBuilder('OCA\Federation\Controller\OCSAuthAPIController') + /** @var OCSAuthAPIController&MockObject $ocsAuthApi */ + $ocsAuthApi = $this->getMockBuilder(OCSAuthAPIController::class) ->setConstructorArgs( [ 'federation', @@ -140,7 +127,9 @@ class OCSAuthAPIControllerTest extends TestCase { $this->timeFactory, $this->throttler ] - )->setMethods(['isValidToken'])->getMock(); + ) + ->onlyMethods(['isValidToken']) + ->getMock(); $this->trustedServers ->expects($this->any()) @@ -171,7 +160,7 @@ class OCSAuthAPIControllerTest extends TestCase { } } - public function dataTestGetSharedSecret() { + public static function dataTestGetSharedSecret(): array { return [ [true, true, true], [false, true, false], diff --git a/apps/federation/tests/Controller/SettingsControllerTest.php b/apps/federation/tests/Controller/SettingsControllerTest.php index c3e83945e9a..d88f397da34 100644 --- a/apps/federation/tests/Controller/SettingsControllerTest.php +++ b/apps/federation/tests/Controller/SettingsControllerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -20,19 +22,18 @@ use Test\TestCase; class SettingsControllerTest extends TestCase { private SettingsController $controller; - private MockObject&IRequest $request; - private MockObject&IL10N $l10n; - private MockObject&TrustedServers $trustedServers; - private MockObject&LoggerInterface $logger; + private IRequest&MockObject $request; + private IL10N&MockObject $l10n; + private TrustedServers&MockObject $trustedServers; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); - $this->request = $this->getMockBuilder(IRequest::class)->getMock(); - $this->l10n = $this->getMockBuilder(IL10N::class)->getMock(); - $this->trustedServers = $this->getMockBuilder(TrustedServers::class) - ->disableOriginalConstructor()->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); + $this->request = $this->createMock(IRequest::class); + $this->l10n = $this->createMock(IL10N::class); + $this->trustedServers = $this->createMock(TrustedServers::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->controller = new SettingsController( 'SettingsControllerTest', @@ -56,7 +57,7 @@ class SettingsControllerTest extends TestCase { ->willReturn(true); $result = $this->controller->addServer('url'); - $this->assertTrue($result instanceof DataResponse); + $this->assertInstanceOf(DataResponse::class, $result); $data = $result->getData(); $this->assertSame(200, $result->getStatus()); @@ -110,7 +111,7 @@ class SettingsControllerTest extends TestCase { ->willReturn(true); $this->assertNull( - $this->invokePrivate($this->controller, 'checkServer', ['url']) + self::invokePrivate($this->controller, 'checkServer', ['url']) ); } @@ -136,14 +137,11 @@ class SettingsControllerTest extends TestCase { } $this->assertTrue( - $this->invokePrivate($this->controller, 'checkServer', ['url']) + self::invokePrivate($this->controller, 'checkServer', ['url']) ); } - /** - * Data to simulate checkServer fails - */ - public function checkServerFails(): array { + public static function checkServerFails(): array { return [ [true, true], [false, false] diff --git a/apps/federation/tests/DAV/FedAuthTest.php b/apps/federation/tests/DAV/FedAuthTest.php index d059fff0481..c49e6f7e86f 100644 --- a/apps/federation/tests/DAV/FedAuthTest.php +++ b/apps/federation/tests/DAV/FedAuthTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -9,27 +10,24 @@ namespace OCA\Federation\Tests\DAV; use OCA\Federation\DAV\FedAuth; use OCA\Federation\DbHandler; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class FedAuthTest extends TestCase { /** * @dataProvider providesUser - * - * @param array $expected - * @param string $user - * @param string $password */ - public function testFedAuth($expected, $user, $password): void { - /** @var DbHandler | \PHPUnit\Framework\MockObject\MockObject $db */ - $db = $this->getMockBuilder('OCA\Federation\DbHandler')->disableOriginalConstructor()->getMock(); + public function testFedAuth(bool $expected, string $user, string $password): void { + /** @var DbHandler&MockObject $db */ + $db = $this->createMock(DbHandler::class); $db->method('auth')->willReturn(true); $auth = new FedAuth($db); - $result = $this->invokePrivate($auth, 'validateUserPass', [$user, $password]); + $result = self::invokePrivate($auth, 'validateUserPass', [$user, $password]); $this->assertEquals($expected, $result); } - public function providesUser() { + public static function providesUser(): array { return [ [true, 'system', '123456'] ]; diff --git a/apps/federation/tests/DbHandlerTest.php b/apps/federation/tests/DbHandlerTest.php index 1db9f7f2315..a9abdbf776c 100644 --- a/apps/federation/tests/DbHandlerTest.php +++ b/apps/federation/tests/DbHandlerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -12,30 +13,23 @@ use OCA\Federation\TrustedServers; use OCP\IDBConnection; use OCP\IL10N; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; /** * @group DB */ class DbHandlerTest extends TestCase { - - /** @var DbHandler */ - private $dbHandler; - - /** @var IL10N | \PHPUnit\Framework\MockObject\MockObject */ - private $il10n; - - /** @var IDBConnection */ - private $connection; - - /** @var string */ - private $dbTable = 'trusted_servers'; + private DbHandler $dbHandler; + private IL10N&MockObject $il10n; + private IDBConnection $connection; + private string $dbTable = 'trusted_servers'; protected function setUp(): void { parent::setUp(); $this->connection = Server::get(IDBConnection::class); - $this->il10n = $this->getMockBuilder(IL10N::class)->getMock(); + $this->il10n = $this->createMock(IL10N::class); $this->dbHandler = new DbHandler( $this->connection, @@ -44,16 +38,17 @@ class DbHandlerTest extends TestCase { $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); $this->assertEmpty($result, 'we need to start with a empty trusted_servers table'); } protected function tearDown(): void { - parent::tearDown(); $query = $this->connection->getQueryBuilder()->delete($this->dbTable); - $query->execute(); + $query->executeStatement() + ; + parent::tearDown(); } /** @@ -63,7 +58,7 @@ class DbHandlerTest extends TestCase { * @param string $expectedUrl the url we expect to be written to the db * @param string $expectedHash the hash value we expect to be written to the db */ - public function testAddServer($url, $expectedUrl, $expectedHash): void { + public function testAddServer(string $url, string $expectedUrl, string $expectedHash): void { $id = $this->dbHandler->addServer($url); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); @@ -71,14 +66,14 @@ class DbHandlerTest extends TestCase { $qResult = $query->execute(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame($expectedUrl, $result[0]['url']); $this->assertSame($id, (int)$result[0]['id']); $this->assertSame($expectedHash, $result[0]['url_hash']); $this->assertSame(TrustedServers::STATUS_PENDING, (int)$result[0]['status']); } - public function dataTestAddServer() { + public static function dataTestAddServer(): array { return [ ['http://owncloud.org', 'http://owncloud.org', sha1('owncloud.org')], ['https://owncloud.org', 'https://owncloud.org', sha1('owncloud.org')], @@ -95,7 +90,7 @@ class DbHandlerTest extends TestCase { $qResult = $query->execute(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(2, count($result)); + $this->assertCount(2, $result); $this->assertSame('server1', $result[0]['url']); $this->assertSame('server2', $result[1]['url']); $this->assertSame($id1, (int)$result[0]['id']); @@ -107,7 +102,7 @@ class DbHandlerTest extends TestCase { $qResult = $query->execute(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame('server1', $result[0]['url']); $this->assertSame($id1, (int)$result[0]['id']); } @@ -135,19 +130,15 @@ class DbHandlerTest extends TestCase { /** * @dataProvider dataTestServerExists - * - * @param string $serverInTable - * @param string $checkForServer - * @param bool $expected */ - public function testServerExists($serverInTable, $checkForServer, $expected): void { + public function testServerExists(string $serverInTable, string $checkForServer, bool $expected): void { $this->dbHandler->addServer($serverInTable); $this->assertSame($expected, $this->dbHandler->serverExists($checkForServer) ); } - public function dataTestServerExists() { + public static function dataTestServerExists(): array { return [ ['server1', 'server1', true], ['server1', 'http://server1', true], @@ -159,18 +150,18 @@ class DbHandlerTest extends TestCase { $this->dbHandler->addServer('server1'); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame(null, $result[0]['token']); $this->dbHandler->addToken('http://server1', 'token'); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame('token', $result[0]['token']); } @@ -189,7 +180,7 @@ class DbHandlerTest extends TestCase { $qResult = $query->execute(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame(null, $result[0]['shared_secret']); $this->dbHandler->addSharedSecret('http://server1', 'secret'); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); @@ -197,7 +188,7 @@ class DbHandlerTest extends TestCase { $qResult = $query->execute(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame('secret', $result[0]['shared_secret']); } @@ -213,18 +204,18 @@ class DbHandlerTest extends TestCase { $this->dbHandler->addServer('server1'); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame(TrustedServers::STATUS_PENDING, (int)$result[0]['status']); $this->dbHandler->setServerStatus('http://server1', TrustedServers::STATUS_OK); $query = $this->connection->getQueryBuilder()->select('*')->from($this->dbTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(1, count($result)); + $this->assertCount(1, $result); $this->assertSame(TrustedServers::STATUS_OK, (int)$result[0]['status']); } @@ -245,17 +236,14 @@ class DbHandlerTest extends TestCase { * hash should always be computed with the normalized URL * * @dataProvider dataTestHash - * - * @param string $url - * @param string $expected */ - public function testHash($url, $expected): void { + public function testHash(string $url, string $expected): void { $this->assertSame($expected, $this->invokePrivate($this->dbHandler, 'hash', [$url]) ); } - public function dataTestHash() { + public static function dataTestHash(): array { return [ ['server1', sha1('server1')], ['http://server1', sha1('server1')], @@ -266,17 +254,14 @@ class DbHandlerTest extends TestCase { /** * @dataProvider dataTestNormalizeUrl - * - * @param string $url - * @param string $expected */ - public function testNormalizeUrl($url, $expected): void { + public function testNormalizeUrl(string $url, string $expected): void { $this->assertSame($expected, $this->invokePrivate($this->dbHandler, 'normalizeUrl', [$url]) ); } - public function dataTestNormalizeUrl() { + public static function dataTestNormalizeUrl(): array { return [ ['owncloud.org', 'owncloud.org'], ['http://owncloud.org', 'owncloud.org'], @@ -289,7 +274,7 @@ class DbHandlerTest extends TestCase { /** * @dataProvider providesAuth */ - public function testAuth($expectedResult, $user, $password): void { + public function testAuth(bool $expectedResult, string $user, string $password): void { if ($expectedResult) { $this->dbHandler->addServer('url1'); $this->dbHandler->addSharedSecret('url1', $password); @@ -298,7 +283,7 @@ class DbHandlerTest extends TestCase { $this->assertEquals($expectedResult, $result); } - public function providesAuth() { + public static function providesAuth(): array { return [ [false, 'foo', ''], [true, 'system', '123456789'], diff --git a/apps/federation/tests/Settings/AdminTest.php b/apps/federation/tests/Settings/AdminTest.php index 3d58fae2d7b..b4c7121c5c9 100644 --- a/apps/federation/tests/Settings/AdminTest.php +++ b/apps/federation/tests/Settings/AdminTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -9,17 +11,16 @@ use OCA\Federation\Settings\Admin; use OCA\Federation\TrustedServers; use OCP\AppFramework\Http\TemplateResponse; use OCP\IL10N; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class AdminTest extends TestCase { - /** @var Admin */ - private $admin; - /** @var TrustedServers */ - private $trustedServers; + private TrustedServers&MockObject $trustedServers; + private Admin $admin; protected function setUp(): void { parent::setUp(); - $this->trustedServers = $this->getMockBuilder('\OCA\Federation\TrustedServers')->disableOriginalConstructor()->getMock(); + $this->trustedServers = $this->createMock(\OCA\Federation\TrustedServers::class); $this->admin = new Admin( $this->trustedServers, $this->createMock(IL10N::class) diff --git a/apps/federation/tests/SyncFederationAddressbooksTest.php b/apps/federation/tests/SyncFederationAddressbooksTest.php index 39274a11ade..aebd4aa2b93 100644 --- a/apps/federation/tests/SyncFederationAddressbooksTest.php +++ b/apps/federation/tests/SyncFederationAddressbooksTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -16,30 +17,21 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class SyncFederationAddressbooksTest extends \Test\TestCase { - - /** @var array */ - private $callBacks = []; - - /** @var MockObject | DiscoveryService */ - private $discoveryService; - - /** @var MockObject|LoggerInterface */ - private $logger; + private array $callBacks = []; + private DiscoveryService&MockObject $discoveryService; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); - $this->discoveryService = $this->getMockBuilder(DiscoveryService::class) - ->disableOriginalConstructor()->getMock(); + $this->discoveryService = $this->createMock(DiscoveryService::class); $this->discoveryService->expects($this->any())->method('discover')->willReturn([]); $this->logger = $this->createMock(LoggerInterface::class); } public function testSync(): void { - /** @var DbHandler | MockObject $dbHandler */ - $dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler') - ->disableOriginalConstructor() - ->getMock(); + /** @var DbHandler&MockObject $dbHandler */ + $dbHandler = $this->createMock(DbHandler::class); $dbHandler->method('getAllServer') ->willReturn([ [ @@ -51,9 +43,7 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { ]); $dbHandler->expects($this->once())->method('setServerStatus')-> with('https://cloud.drop.box', 1, '1'); - $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') - ->disableOriginalConstructor() - ->getMock(); + $syncService = $this->createMock(SyncService::class); $syncService->expects($this->once())->method('syncRemoteAddressBook') ->willReturn('1'); @@ -62,14 +52,12 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { $s->syncThemAll(function ($url, $ex): void { $this->callBacks[] = [$url, $ex]; }); - $this->assertEquals('1', count($this->callBacks)); + $this->assertCount(1, $this->callBacks); } public function testException(): void { - /** @var DbHandler | MockObject $dbHandler */ - $dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')-> - disableOriginalConstructor()-> - getMock(); + /** @var DbHandler&MockObject $dbHandler */ + $dbHandler = $this->createMock(DbHandler::class); $dbHandler->method('getAllServer')-> willReturn([ [ @@ -79,9 +67,7 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { 'sync_token' => '0' ] ]); - $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') - ->disableOriginalConstructor() - ->getMock(); + $syncService = $this->createMock(SyncService::class); $syncService->expects($this->once())->method('syncRemoteAddressBook') ->willThrowException(new \Exception('something did not work out')); @@ -90,14 +76,12 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { $s->syncThemAll(function ($url, $ex): void { $this->callBacks[] = [$url, $ex]; }); - $this->assertEquals(2, count($this->callBacks)); + $this->assertCount(2, $this->callBacks); } public function testSuccessfulSyncWithoutChangesAfterFailure(): void { - /** @var DbHandler | MockObject $dbHandler */ - $dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler') - ->disableOriginalConstructor() - ->getMock(); + /** @var DbHandler&MockObject $dbHandler */ + $dbHandler = $this->createMock(DbHandler::class); $dbHandler->method('getAllServer') ->willReturn([ [ @@ -110,9 +94,7 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { $dbHandler->method('getServerStatus')->willReturn(TrustedServers::STATUS_FAILURE); $dbHandler->expects($this->once())->method('setServerStatus')-> with('https://cloud.drop.box', 1); - $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') - ->disableOriginalConstructor() - ->getMock(); + $syncService = $this->createMock(SyncService::class); $syncService->expects($this->once())->method('syncRemoteAddressBook') ->willReturn('0'); @@ -121,6 +103,6 @@ class SyncFederationAddressbooksTest extends \Test\TestCase { $s->syncThemAll(function ($url, $ex): void { $this->callBacks[] = [$url, $ex]; }); - $this->assertEquals('1', count($this->callBacks)); + $this->assertCount(1, $this->callBacks); } } diff --git a/apps/federation/tests/TrustedServersTest.php b/apps/federation/tests/TrustedServersTest.php index c3f0368858b..4d64df7a5e1 100644 --- a/apps/federation/tests/TrustedServersTest.php +++ b/apps/federation/tests/TrustedServersTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -7,6 +8,7 @@ */ namespace OCA\Federation\Tests; +use OCA\Federation\BackgroundJob\RequestSharedSecret; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; use OCP\AppFramework\Utility\ITimeFactory; @@ -19,57 +21,35 @@ use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; use OCP\IConfig; use OCP\Security\ISecureRandom; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; class TrustedServersTest extends TestCase { - /** @var \PHPUnit\Framework\MockObject\MockObject | TrustedServers */ - private $trustedServers; - - /** @var \PHPUnit\Framework\MockObject\MockObject | DbHandler */ - private $dbHandler; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IClientService */ - private $httpClientService; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IClient */ - private $httpClient; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IResponse */ - private $response; - - /** @var \PHPUnit\Framework\MockObject\MockObject | LoggerInterface */ - private $logger; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IJobList */ - private $jobList; - - /** @var \PHPUnit\Framework\MockObject\MockObject | ISecureRandom */ - private $secureRandom; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IConfig */ - private $config; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IEventDispatcher */ - private $dispatcher; - - /** @var \PHPUnit\Framework\MockObject\MockObject|ITimeFactory */ - private $timeFactory; + private TrustedServers $trustedServers; + private DbHandler&MockObject $dbHandler; + private IClientService&MockObject $httpClientService; + private IClient&MockObject $httpClient; + private IResponse&MockObject $response; + private LoggerInterface&MockObject $logger; + private IJobList&MockObject $jobList; + private ISecureRandom&MockObject $secureRandom; + private IConfig&MockObject $config; + private IEventDispatcher&MockObject $dispatcher; + private ITimeFactory&MockObject $timeFactory; protected function setUp(): void { parent::setUp(); - $this->dbHandler = $this->getMockBuilder(DbHandler::class) - ->disableOriginalConstructor()->getMock(); - $this->dispatcher = $this->getMockBuilder(IEventDispatcher::class) - ->disableOriginalConstructor()->getMock(); - $this->httpClientService = $this->getMockBuilder(IClientService::class)->getMock(); - $this->httpClient = $this->getMockBuilder(IClient::class)->getMock(); - $this->response = $this->getMockBuilder(IResponse::class)->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $this->jobList = $this->getMockBuilder(IJobList::class)->getMock(); - $this->secureRandom = $this->getMockBuilder(ISecureRandom::class)->getMock(); - $this->config = $this->getMockBuilder(IConfig::class)->getMock(); + $this->dbHandler = $this->createMock(DbHandler::class); + $this->dispatcher = $this->createMock(IEventDispatcher::class); + $this->httpClientService = $this->createMock(IClientService::class); + $this->httpClient = $this->createMock(IClient::class); + $this->response = $this->createMock(IResponse::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->jobList = $this->createMock(IJobList::class); + $this->secureRandom = $this->createMock(ISecureRandom::class); + $this->config = $this->createMock(IConfig::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->trustedServers = new TrustedServers( @@ -85,8 +65,8 @@ class TrustedServersTest extends TestCase { } public function testAddServer(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject|TrustedServers $trustedServers */ - $trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers') + /** @var TrustedServers&MockObject $trustedServers */ + $trustedServers = $this->getMockBuilder(TrustedServers::class) ->setConstructorArgs( [ $this->dbHandler, @@ -99,7 +79,7 @@ class TrustedServersTest extends TestCase { $this->timeFactory ] ) - ->setMethods(['normalizeUrl', 'updateProtocol']) + ->onlyMethods(['updateProtocol']) ->getMock(); $trustedServers->expects($this->once())->method('updateProtocol') ->with('url')->willReturn('https://url'); @@ -112,12 +92,12 @@ class TrustedServersTest extends TestCase { ->willReturn('token'); $this->dbHandler->expects($this->once())->method('addToken')->with('https://url', 'token'); $this->jobList->expects($this->once())->method('add') - ->with('OCA\Federation\BackgroundJob\RequestSharedSecret', + ->with(RequestSharedSecret::class, ['url' => 'https://url', 'token' => 'token', 'created' => 1234567]); $this->assertSame( - $trustedServers->addServer('url'), - 1 + 1, + $trustedServers->addServer('url') ); } @@ -196,8 +176,8 @@ class TrustedServersTest extends TestCase { public function testIsNextcloudServer(int $statusCode, bool $isValidNextcloudVersion, bool $expected): void { $server = 'server1'; - /** @var \PHPUnit\Framework\MockObject\MockObject | TrustedServers $trustedServers */ - $trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers') + /** @var TrustedServers&MockObject $trustedServers */ + $trustedServers = $this->getMockBuilder(TrustedServers::class) ->setConstructorArgs( [ $this->dbHandler, @@ -210,7 +190,7 @@ class TrustedServersTest extends TestCase { $this->timeFactory ] ) - ->setMethods(['checkNextcloudVersion']) + ->onlyMethods(['checkNextcloudVersion']) ->getMock(); $this->httpClientService->expects($this->once())->method('newClient') @@ -236,7 +216,7 @@ class TrustedServersTest extends TestCase { ); } - public function dataTestIsNextcloudServer(): array { + public static function dataTestIsNextcloudServer(): array { return [ [200, true, true], [200, false, false], @@ -244,19 +224,17 @@ class TrustedServersTest extends TestCase { ]; } - /** - * @expectedExceptionMessage simulated exception - */ public function testIsNextcloudServerFail(): void { $server = 'server1'; - $this->httpClientService->expects($this->once())->method('newClient') + $this->httpClientService->expects($this->once()) + ->method('newClient') ->willReturn($this->httpClient); - $this->httpClient->expects($this->once())->method('get')->with($server . '/status.php') - ->willReturnCallback(function (): void { - throw new \Exception('simulated exception'); - }); + $this->httpClient->expects($this->once()) + ->method('get') + ->with($server . '/status.php') + ->willThrowException(new \Exception('simulated exception')); $this->assertFalse($this->trustedServers->isNextcloudServer($server)); } @@ -264,11 +242,11 @@ class TrustedServersTest extends TestCase { /** * @dataProvider dataTestCheckNextcloudVersion */ - public function testCheckNextcloudVersion($status): void { - $this->assertTrue($this->invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status])); + public function testCheckNextcloudVersion(string $status): void { + $this->assertTrue(self::invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status])); } - public function dataTestCheckNextcloudVersion(): array { + public static function dataTestCheckNextcloudVersion(): array { return [ ['{"version":"9.0.0"}'], ['{"version":"9.1.0"}'] @@ -282,10 +260,10 @@ class TrustedServersTest extends TestCase { $this->expectException(HintException::class); $this->expectExceptionMessage('Remote server version is too low. 9.0 is required.'); - $this->invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status]); + self::invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status]); } - public function dataTestCheckNextcloudVersionTooLow(): array { + public static function dataTestCheckNextcloudVersionTooLow(): array { return [ ['{"version":"8.2.3"}'], ]; @@ -296,11 +274,11 @@ class TrustedServersTest extends TestCase { */ public function testUpdateProtocol(string $url, string $expected): void { $this->assertSame($expected, - $this->invokePrivate($this->trustedServers, 'updateProtocol', [$url]) + self::invokePrivate($this->trustedServers, 'updateProtocol', [$url]) ); } - public function dataTestUpdateProtocol(): array { + public static function dataTestUpdateProtocol(): array { return [ ['http://owncloud.org', 'http://owncloud.org'], ['https://owncloud.org', 'https://owncloud.org'], diff --git a/apps/files/l10n/ar.js b/apps/files/l10n/ar.js index 4cffecf72eb..2966ea64b30 100644 --- a/apps/files/l10n/ar.js +++ b/apps/files/l10n/ar.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : ".عملية النسخ أو النقل تمّ إلغاؤها", "Open folder {displayName}" : "فتح المجلد {displayName}", "Open in Files" : "فتح في \"الملفات\"", + "Open locally" : "الفتح محلّيّاً", + "Failed to redirect to client" : "فشل في التحويل الى العميل", "Open file locally" : "فتح الملف محلّيّاً", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "يجب أن يفتح الملف الآن على جهازك. إذا لم يحدث ذلك، فيرجى التأكد من تثبيت تطبيق سطح المكتب.", "Retry and close" : "أعِد المحاولة ثم أغلِق", "Open online" : "إفتَح مُتَّصِلاً بالإنترنت", - "Failed to redirect to client" : "فشل في التحويل الى العميل", - "Open locally" : "الفتح محلّيّاً", "Rename" : "إعادة التسمية", "Open details" : "فتح التفاصيل", "View in folder" : "عرض في المجلد", diff --git a/apps/files/l10n/ar.json b/apps/files/l10n/ar.json index 84c956af639..44bf401f1ec 100644 --- a/apps/files/l10n/ar.json +++ b/apps/files/l10n/ar.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : ".عملية النسخ أو النقل تمّ إلغاؤها", "Open folder {displayName}" : "فتح المجلد {displayName}", "Open in Files" : "فتح في \"الملفات\"", + "Open locally" : "الفتح محلّيّاً", + "Failed to redirect to client" : "فشل في التحويل الى العميل", "Open file locally" : "فتح الملف محلّيّاً", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "يجب أن يفتح الملف الآن على جهازك. إذا لم يحدث ذلك، فيرجى التأكد من تثبيت تطبيق سطح المكتب.", "Retry and close" : "أعِد المحاولة ثم أغلِق", "Open online" : "إفتَح مُتَّصِلاً بالإنترنت", - "Failed to redirect to client" : "فشل في التحويل الى العميل", - "Open locally" : "الفتح محلّيّاً", "Rename" : "إعادة التسمية", "Open details" : "فتح التفاصيل", "View in folder" : "عرض في المجلد", diff --git a/apps/files/l10n/ast.js b/apps/files/l10n/ast.js index 036797e4a76..d9bdbf9b621 100644 --- a/apps/files/l10n/ast.js +++ b/apps/files/l10n/ast.js @@ -196,8 +196,8 @@ OC.L10N.register( "Cancelled move or copy operation" : "Anulóse la operación de mover o copiar", "Open folder {displayName}" : "Abrir la carpeta «{displayName}»", "Open in Files" : "Abrir en Ficheros", - "Failed to redirect to client" : "Nun se pue redirixir al veceru", "Open locally" : "Abrir llocalmente", + "Failed to redirect to client" : "Nun se pue redirixir al veceru", "Rename" : "Renomar", "Open details" : "Abrir los detalles", "View in folder" : "Ver na carpeta", diff --git a/apps/files/l10n/ast.json b/apps/files/l10n/ast.json index c44539d7603..3ccfed40a0c 100644 --- a/apps/files/l10n/ast.json +++ b/apps/files/l10n/ast.json @@ -194,8 +194,8 @@ "Cancelled move or copy operation" : "Anulóse la operación de mover o copiar", "Open folder {displayName}" : "Abrir la carpeta «{displayName}»", "Open in Files" : "Abrir en Ficheros", - "Failed to redirect to client" : "Nun se pue redirixir al veceru", "Open locally" : "Abrir llocalmente", + "Failed to redirect to client" : "Nun se pue redirixir al veceru", "Rename" : "Renomar", "Open details" : "Abrir los detalles", "View in folder" : "Ver na carpeta", diff --git a/apps/files/l10n/bg.js b/apps/files/l10n/bg.js index 454ccaf0894..a4e57455bba 100644 --- a/apps/files/l10n/bg.js +++ b/apps/files/l10n/bg.js @@ -144,9 +144,9 @@ OC.L10N.register( "Copy" : "Копирай", "Move" : "Преместване", "Move or copy" : "Премести или копирай", - "Open file locally" : "Локално отваряне на файл", - "Failed to redirect to client" : "Неуспешно пренасочване към клиент", "Open locally" : "Локално отваряне", + "Failed to redirect to client" : "Неуспешно пренасочване към клиент", + "Open file locally" : "Локално отваряне на файл", "Rename" : "Преименувай", "Open details" : "Отваряне на подробности", "View in folder" : "Преглед в папката", diff --git a/apps/files/l10n/bg.json b/apps/files/l10n/bg.json index 8f2d29bdb50..0ab99619fd5 100644 --- a/apps/files/l10n/bg.json +++ b/apps/files/l10n/bg.json @@ -142,9 +142,9 @@ "Copy" : "Копирай", "Move" : "Преместване", "Move or copy" : "Премести или копирай", - "Open file locally" : "Локално отваряне на файл", - "Failed to redirect to client" : "Неуспешно пренасочване към клиент", "Open locally" : "Локално отваряне", + "Failed to redirect to client" : "Неуспешно пренасочване към клиент", + "Open file locally" : "Локално отваряне на файл", "Rename" : "Преименувай", "Open details" : "Отваряне на подробности", "View in folder" : "Преглед в папката", diff --git a/apps/files/l10n/ca.js b/apps/files/l10n/ca.js index 460fc96ee21..0c0eb111936 100644 --- a/apps/files/l10n/ca.js +++ b/apps/files/l10n/ca.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "S'ha cancel·lat l'operació de desplaçament o còpia", "Open folder {displayName}" : "Obre la carpeta {displayName}", "Open in Files" : "Obre a Fitxers", + "Open locally" : "Obre en local", + "Failed to redirect to client" : "No s'ha pogut redirigir al client", "Open file locally" : "Obre el fitxer en local", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Ara s'hauria d'obrir el fitxer al dispositiu. Si no és així, comproveu que teniu instal·lada l'aplicació d'escriptori.", "Retry and close" : "Torna-ho a provar i tanca", "Open online" : "Obre en línia", - "Failed to redirect to client" : "No s'ha pogut redirigir al client", - "Open locally" : "Obre en local", "Rename" : "Canvia el nom", "Open details" : "Obre els detalls", "View in folder" : "Visualitza-ho en la carpeta", diff --git a/apps/files/l10n/ca.json b/apps/files/l10n/ca.json index 7b9690f94b4..a29248f26e9 100644 --- a/apps/files/l10n/ca.json +++ b/apps/files/l10n/ca.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "S'ha cancel·lat l'operació de desplaçament o còpia", "Open folder {displayName}" : "Obre la carpeta {displayName}", "Open in Files" : "Obre a Fitxers", + "Open locally" : "Obre en local", + "Failed to redirect to client" : "No s'ha pogut redirigir al client", "Open file locally" : "Obre el fitxer en local", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Ara s'hauria d'obrir el fitxer al dispositiu. Si no és així, comproveu que teniu instal·lada l'aplicació d'escriptori.", "Retry and close" : "Torna-ho a provar i tanca", "Open online" : "Obre en línia", - "Failed to redirect to client" : "No s'ha pogut redirigir al client", - "Open locally" : "Obre en local", "Rename" : "Canvia el nom", "Open details" : "Obre els detalls", "View in folder" : "Visualitza-ho en la carpeta", diff --git a/apps/files/l10n/cs.js b/apps/files/l10n/cs.js index a229b8a7ddf..c4db8c2ebc9 100644 --- a/apps/files/l10n/cs.js +++ b/apps/files/l10n/cs.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Operace přesunutí či zkopírování zrušena", "Open folder {displayName}" : "Otevřít složku {displayName}", "Open in Files" : "Otevřít v Souborech", + "Open locally" : "Otevřít lokálně", + "Failed to redirect to client" : "Nepodařilo se přesměrovat klienta", "Open file locally" : "Otevřít soubor lokálně", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Soubor by se nyní měl otevřít na vašem zařízení. Pokud ne, zkontrolujte, zda máte nainstalovanou desktopovou aplikaci.", "Retry and close" : "Zkusit znovu a zavřít", "Open online" : "Otevřít online", - "Failed to redirect to client" : "Nepodařilo se přesměrovat klienta", - "Open locally" : "Otevřít lokálně", "Rename" : "Přejmenovat", "Open details" : "Otevřít podrobnosti", "View in folder" : "Zobrazit ve složce", diff --git a/apps/files/l10n/cs.json b/apps/files/l10n/cs.json index f5293dcd9ed..b3ab9d87ded 100644 --- a/apps/files/l10n/cs.json +++ b/apps/files/l10n/cs.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Operace přesunutí či zkopírování zrušena", "Open folder {displayName}" : "Otevřít složku {displayName}", "Open in Files" : "Otevřít v Souborech", + "Open locally" : "Otevřít lokálně", + "Failed to redirect to client" : "Nepodařilo se přesměrovat klienta", "Open file locally" : "Otevřít soubor lokálně", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Soubor by se nyní měl otevřít na vašem zařízení. Pokud ne, zkontrolujte, zda máte nainstalovanou desktopovou aplikaci.", "Retry and close" : "Zkusit znovu a zavřít", "Open online" : "Otevřít online", - "Failed to redirect to client" : "Nepodařilo se přesměrovat klienta", - "Open locally" : "Otevřít lokálně", "Rename" : "Přejmenovat", "Open details" : "Otevřít podrobnosti", "View in folder" : "Zobrazit ve složce", diff --git a/apps/files/l10n/da.js b/apps/files/l10n/da.js index 3d2898dc93e..4c22f5a4cfe 100644 --- a/apps/files/l10n/da.js +++ b/apps/files/l10n/da.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Flytning eller kopiering er annulleret", "Open folder {displayName}" : "Åben mappe {displayName}", "Open in Files" : "Åben i Filer", + "Open locally" : "Åben lokalt", + "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", "Open file locally" : "Åben fil lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen bør nu åbne på dit apparat. Hvis den ikke gør det, så kontroller venligst at desktop app'en er installeret.", "Retry and close" : "Forsøg igen og luk", "Open online" : "Åben online", - "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", - "Open locally" : "Åben lokalt", "Rename" : "Omdøb", "Open details" : "Mere information", "View in folder" : "Vis i mappe", diff --git a/apps/files/l10n/da.json b/apps/files/l10n/da.json index e23ab072eb3..b791f81d82e 100644 --- a/apps/files/l10n/da.json +++ b/apps/files/l10n/da.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "Flytning eller kopiering er annulleret", "Open folder {displayName}" : "Åben mappe {displayName}", "Open in Files" : "Åben i Filer", + "Open locally" : "Åben lokalt", + "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", "Open file locally" : "Åben fil lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen bør nu åbne på dit apparat. Hvis den ikke gør det, så kontroller venligst at desktop app'en er installeret.", "Retry and close" : "Forsøg igen og luk", "Open online" : "Åben online", - "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", - "Open locally" : "Åben lokalt", "Rename" : "Omdøb", "Open details" : "Mere information", "View in folder" : "Vis i mappe", diff --git a/apps/files/l10n/de.js b/apps/files/l10n/de.js index 144e2205a32..b201407f4c7 100644 --- a/apps/files/l10n/de.js +++ b/apps/files/l10n/de.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Verschieben oder Kopieren abgebrochen", "Open folder {displayName}" : "Ordner {displayName} öffnen", "Open in Files" : "In \"Dateien\" öffnen", + "Open locally" : "Lokal öffnen", + "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", "Open file locally" : "Datei lokal öffnen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Die Datei sollte sich jetzt auf deinem Gerät öffnen. Wenn dies nicht der Fall ist, überprüfe, ob du die Desktop-App installiert hast.", "Retry and close" : "Erneut versuchen und schließen", "Open online" : "Online öffnen", - "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", - "Open locally" : "Lokal öffnen", "Rename" : "Umbenennen", "Open details" : "Details öffnen", "View in folder" : "In Ordner anzeigen", diff --git a/apps/files/l10n/de.json b/apps/files/l10n/de.json index 3d32975468a..8b16a6cf288 100644 --- a/apps/files/l10n/de.json +++ b/apps/files/l10n/de.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Verschieben oder Kopieren abgebrochen", "Open folder {displayName}" : "Ordner {displayName} öffnen", "Open in Files" : "In \"Dateien\" öffnen", + "Open locally" : "Lokal öffnen", + "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", "Open file locally" : "Datei lokal öffnen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Die Datei sollte sich jetzt auf deinem Gerät öffnen. Wenn dies nicht der Fall ist, überprüfe, ob du die Desktop-App installiert hast.", "Retry and close" : "Erneut versuchen und schließen", "Open online" : "Online öffnen", - "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", - "Open locally" : "Lokal öffnen", "Rename" : "Umbenennen", "Open details" : "Details öffnen", "View in folder" : "In Ordner anzeigen", diff --git a/apps/files/l10n/de_DE.js b/apps/files/l10n/de_DE.js index 1f571bd6895..4eb6dbf8fdc 100644 --- a/apps/files/l10n/de_DE.js +++ b/apps/files/l10n/de_DE.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Verschieben oder kopieren abgebrochen", "Open folder {displayName}" : "Ordner {displayName} öffnen", "Open in Files" : "In Dateien öffnen", + "Open locally" : "Lokal öffnen", + "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", "Open file locally" : "Datei lokal öffnen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Die Datei sollte sich jetzt auf Ihrem Gerät öffnen. Wenn dies nicht der Fall ist, überprüfen Sie, ob Sie die Desktop-App installiert haben.", "Retry and close" : "Erneut versuchen und schließen", "Open online" : "Online öffnen", - "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", - "Open locally" : "Lokal öffnen", "Rename" : "Umbenennen", "Open details" : "Details öffnen", "View in folder" : "In Ordner anzeigen", diff --git a/apps/files/l10n/de_DE.json b/apps/files/l10n/de_DE.json index 66301fbde19..6303adcd035 100644 --- a/apps/files/l10n/de_DE.json +++ b/apps/files/l10n/de_DE.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Verschieben oder kopieren abgebrochen", "Open folder {displayName}" : "Ordner {displayName} öffnen", "Open in Files" : "In Dateien öffnen", + "Open locally" : "Lokal öffnen", + "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", "Open file locally" : "Datei lokal öffnen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Die Datei sollte sich jetzt auf Ihrem Gerät öffnen. Wenn dies nicht der Fall ist, überprüfen Sie, ob Sie die Desktop-App installiert haben.", "Retry and close" : "Erneut versuchen und schließen", "Open online" : "Online öffnen", - "Failed to redirect to client" : "Umleitung zum Client fehlgeschlagen", - "Open locally" : "Lokal öffnen", "Rename" : "Umbenennen", "Open details" : "Details öffnen", "View in folder" : "In Ordner anzeigen", diff --git a/apps/files/l10n/en_GB.js b/apps/files/l10n/en_GB.js index d539aad061f..c49fcc464f8 100644 --- a/apps/files/l10n/en_GB.js +++ b/apps/files/l10n/en_GB.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "Open folder {displayName}", "Open in Files" : "Open in Files", + "Open locally" : "Open locally", + "Failed to redirect to client" : "Failed to redirect to client", "Open file locally" : "Open file locally", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "The file should now open on your device. If it doesn't, please check that you have the desktop app installed.", "Retry and close" : "Retry and close", "Open online" : "Open online", - "Failed to redirect to client" : "Failed to redirect to client", - "Open locally" : "Open locally", "Rename" : "Rename", "Open details" : "Open details", "View in folder" : "View in folder", diff --git a/apps/files/l10n/en_GB.json b/apps/files/l10n/en_GB.json index 1cda6a41d5f..640b2b24d64 100644 --- a/apps/files/l10n/en_GB.json +++ b/apps/files/l10n/en_GB.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "Open folder {displayName}", "Open in Files" : "Open in Files", + "Open locally" : "Open locally", + "Failed to redirect to client" : "Failed to redirect to client", "Open file locally" : "Open file locally", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "The file should now open on your device. If it doesn't, please check that you have the desktop app installed.", "Retry and close" : "Retry and close", "Open online" : "Open online", - "Failed to redirect to client" : "Failed to redirect to client", - "Open locally" : "Open locally", "Rename" : "Rename", "Open details" : "Open details", "View in folder" : "View in folder", diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js index 811e43178b7..04e9c3a8dc4 100644 --- a/apps/files/l10n/es.js +++ b/apps/files/l10n/es.js @@ -280,12 +280,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Se canceló la operación de mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}", "Open in Files" : "Abrir en Archivos", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Fallo al redirigir al cliente", "Open file locally" : "Abrir archivo localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "El archivo se abrirá ahora en tu dispositivo. Si esto no ocurre, por favor verifica que has instalado la aplicación de escritorio", "Retry and close" : "Reintentar y cerrar", "Open online" : "Abrir en línea", - "Failed to redirect to client" : "Fallo al redirigir al cliente", - "Open locally" : "Abrir localmente", "Rename" : "Renombrar", "Open details" : "Abrir detalles", "View in folder" : "Ver en carpeta", diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json index 5a7e7a29703..a8ee83caba0 100644 --- a/apps/files/l10n/es.json +++ b/apps/files/l10n/es.json @@ -278,12 +278,12 @@ "Cancelled move or copy operation" : "Se canceló la operación de mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}", "Open in Files" : "Abrir en Archivos", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Fallo al redirigir al cliente", "Open file locally" : "Abrir archivo localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "El archivo se abrirá ahora en tu dispositivo. Si esto no ocurre, por favor verifica que has instalado la aplicación de escritorio", "Retry and close" : "Reintentar y cerrar", "Open online" : "Abrir en línea", - "Failed to redirect to client" : "Fallo al redirigir al cliente", - "Open locally" : "Abrir localmente", "Rename" : "Renombrar", "Open details" : "Abrir detalles", "View in folder" : "Ver en carpeta", diff --git a/apps/files/l10n/es_EC.js b/apps/files/l10n/es_EC.js index 7e353f0a6a4..2e937b91fae 100644 --- a/apps/files/l10n/es_EC.js +++ b/apps/files/l10n/es_EC.js @@ -149,9 +149,9 @@ OC.L10N.register( "Move" : "Mover", "Move or copy" : "Mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}.", - "Open file locally" : "Abrir archivo localmente", - "Failed to redirect to client" : "No se pudo redirigir al cliente.", "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "No se pudo redirigir al cliente.", + "Open file locally" : "Abrir archivo localmente", "Rename" : "Renombrar", "Open details" : "Abrir detalles.", "View in folder" : "Ver en la carpeta", diff --git a/apps/files/l10n/es_EC.json b/apps/files/l10n/es_EC.json index 3f7ce16df35..ce46795a8ae 100644 --- a/apps/files/l10n/es_EC.json +++ b/apps/files/l10n/es_EC.json @@ -147,9 +147,9 @@ "Move" : "Mover", "Move or copy" : "Mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}.", - "Open file locally" : "Abrir archivo localmente", - "Failed to redirect to client" : "No se pudo redirigir al cliente.", "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "No se pudo redirigir al cliente.", + "Open file locally" : "Abrir archivo localmente", "Rename" : "Renombrar", "Open details" : "Abrir detalles.", "View in folder" : "Ver en la carpeta", diff --git a/apps/files/l10n/es_MX.js b/apps/files/l10n/es_MX.js index 3fdea38848c..1825c108261 100644 --- a/apps/files/l10n/es_MX.js +++ b/apps/files/l10n/es_MX.js @@ -227,9 +227,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "Se canceló la operación de mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}", "Open in Files" : "Abrir en Archivos", + "Failed to redirect to client" : "Fallo al redirigir al cliente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "El archivo se abrirá ahora en tu dispositivo. Si esto no ocurre, por favor verifica que hayas instalado la aplicación de escritorio.", "Retry and close" : "Reintentar y cerrar", - "Failed to redirect to client" : "Fallo al redirigir al cliente", "Rename" : "Renombrar", "Open details" : "Abrir detalles", "View in folder" : "Ver en la carpeta", diff --git a/apps/files/l10n/es_MX.json b/apps/files/l10n/es_MX.json index 24a26109117..c15bb55f569 100644 --- a/apps/files/l10n/es_MX.json +++ b/apps/files/l10n/es_MX.json @@ -225,9 +225,9 @@ "Cancelled move or copy operation" : "Se canceló la operación de mover o copiar", "Open folder {displayName}" : "Abrir carpeta {displayName}", "Open in Files" : "Abrir en Archivos", + "Failed to redirect to client" : "Fallo al redirigir al cliente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "El archivo se abrirá ahora en tu dispositivo. Si esto no ocurre, por favor verifica que hayas instalado la aplicación de escritorio.", "Retry and close" : "Reintentar y cerrar", - "Failed to redirect to client" : "Fallo al redirigir al cliente", "Rename" : "Renombrar", "Open details" : "Abrir detalles", "View in folder" : "Ver en la carpeta", diff --git a/apps/files/l10n/et_EE.js b/apps/files/l10n/et_EE.js index 4e9582550f7..95ffdc76632 100644 --- a/apps/files/l10n/et_EE.js +++ b/apps/files/l10n/et_EE.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Teisaldamine või kopeerimine on katkestatud", "Open folder {displayName}" : "Ava kaust {displayName}", "Open in Files" : "Ava failirakenduses", + "Open locally" : "Ava kohalikust andmeruumist", + "Failed to redirect to client" : "Kliendi ümbersuunamine ei õnnestunud", "Open file locally" : "Ava fail kohalikus seadmes", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Fail peaks nüüd sinu seadmes või arvutis olema avatud. Kui see nii pole, siis palun kontrolli, et töölauarakendus on paigaldatud.", "Retry and close" : "Proovi uuesti ja sulge", "Open online" : "Ava võrgust", - "Failed to redirect to client" : "Kliendi ümbersuunamine ei õnnestunud", - "Open locally" : "Ava kohalikust andmeruumist", "Rename" : "Muuda nime", "Open details" : "Ava üksikasjad", "View in folder" : "Vaata kaustas", diff --git a/apps/files/l10n/et_EE.json b/apps/files/l10n/et_EE.json index 3409dc8cdfa..80c27615d01 100644 --- a/apps/files/l10n/et_EE.json +++ b/apps/files/l10n/et_EE.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Teisaldamine või kopeerimine on katkestatud", "Open folder {displayName}" : "Ava kaust {displayName}", "Open in Files" : "Ava failirakenduses", + "Open locally" : "Ava kohalikust andmeruumist", + "Failed to redirect to client" : "Kliendi ümbersuunamine ei õnnestunud", "Open file locally" : "Ava fail kohalikus seadmes", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Fail peaks nüüd sinu seadmes või arvutis olema avatud. Kui see nii pole, siis palun kontrolli, et töölauarakendus on paigaldatud.", "Retry and close" : "Proovi uuesti ja sulge", "Open online" : "Ava võrgust", - "Failed to redirect to client" : "Kliendi ümbersuunamine ei õnnestunud", - "Open locally" : "Ava kohalikust andmeruumist", "Rename" : "Muuda nime", "Open details" : "Ava üksikasjad", "View in folder" : "Vaata kaustas", diff --git a/apps/files/l10n/eu.js b/apps/files/l10n/eu.js index c2cfee285f2..5c5863a131d 100644 --- a/apps/files/l10n/eu.js +++ b/apps/files/l10n/eu.js @@ -251,11 +251,11 @@ OC.L10N.register( "Cancelled move or copy operation" : "Mugitze edo kopiatze operazioa utzi da", "Open folder {displayName}" : "Ireki {displayName} karpeta", "Open in Files" : "Ireki Fitxategiak aplikazioan", + "Open locally" : "Ireki lokalean", + "Failed to redirect to client" : "Bezerora birbideratzeak huts egin du", "Open file locally" : "Ireki fitxategia lokalean", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Fitxategia orain zure gailuan ireki beharko litzateke. Hala ez bada, egiaztatu mahaigaineko aplikazioa instalatuta duzula.", "Retry and close" : "Saiatu berriro eta itxi", - "Failed to redirect to client" : "Bezerora birbideratzeak huts egin du", - "Open locally" : "Ireki lokalean", "Rename" : "Berrizendatu", "Open details" : "Ireki xehetasunak", "View in folder" : "Ikusi karpetan", diff --git a/apps/files/l10n/eu.json b/apps/files/l10n/eu.json index 3def8199ade..d285b0d0339 100644 --- a/apps/files/l10n/eu.json +++ b/apps/files/l10n/eu.json @@ -249,11 +249,11 @@ "Cancelled move or copy operation" : "Mugitze edo kopiatze operazioa utzi da", "Open folder {displayName}" : "Ireki {displayName} karpeta", "Open in Files" : "Ireki Fitxategiak aplikazioan", + "Open locally" : "Ireki lokalean", + "Failed to redirect to client" : "Bezerora birbideratzeak huts egin du", "Open file locally" : "Ireki fitxategia lokalean", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Fitxategia orain zure gailuan ireki beharko litzateke. Hala ez bada, egiaztatu mahaigaineko aplikazioa instalatuta duzula.", "Retry and close" : "Saiatu berriro eta itxi", - "Failed to redirect to client" : "Bezerora birbideratzeak huts egin du", - "Open locally" : "Ireki lokalean", "Rename" : "Berrizendatu", "Open details" : "Ireki xehetasunak", "View in folder" : "Ikusi karpetan", diff --git a/apps/files/l10n/fa.js b/apps/files/l10n/fa.js index 6a23baaa9a3..a30878c6cf0 100644 --- a/apps/files/l10n/fa.js +++ b/apps/files/l10n/fa.js @@ -13,6 +13,7 @@ OC.L10N.register( "Restored by {user}" : "بازیابی شده توسط {user}", "Renamed by {user}" : "تغییر نام توسط {user}", "Moved by {user}" : "منتقل شده توسط {user}", + "\"remote account\"" : ""حساب از راه دور"", "You created {file}" : "شما {file} را ایجاد کردید", "You created an encrypted file in {file}" : "شما یک فایل رمزگذاری شده در {file} ایجاد کردید", "{user} created {file}" : "{user} {file} را ایجاد کرد", @@ -42,11 +43,23 @@ OC.L10N.register( "Files" : "پروندهها", "A file or folder has been <strong>changed</strong>" : "یک فایل یا پوشه تغییر کرده است", "A favorite file or folder has been <strong>changed</strong>" : "یک فایل یا پوشه مورد علاقه تغییر کرده است", + "Failed to authorize" : "مجوز صادر نشد", + "Invalid folder path" : "Invalid folder path", + "Folder not found" : "Folder not found", + "The file cannot be found" : "The file cannot be found", + "The destination path does not exist: %1$s" : "The destination path does not exist: %1$s", + "You do not have permission to create a file at the specified location" : "You do not have permission to create a file at the specified location", + "The file could not be converted." : "The file could not be converted.", + "Could not get relative path to converted file" : "Could not get relative path to converted file", + "Favorite files" : "Favorite files", "No favorites" : "هیچ برگزیده", + "More favorites" : "More favorites", "Accept" : "قبول", "Reject" : "رد کردن", "Incoming ownership transfer from {user}" : "انتقال مالکیت ورودی از {user}", "Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "آیا می خواهید {path} را بپذیرید؟\n\nتوجه: فرآیند انتقال پس از پذیرش ممکن است تا 1 ساعت طول بکشد.", + "Ownership transfer denied" : "Ownership transfer denied", + "Your ownership transfer of {path} was denied by {user}." : "Your ownership transfer of {path} was denied by {user}.", "Ownership transfer failed" : "انتقال مالکیت ناموفق بود", "Your ownership transfer of {path} to {user} failed." : "انتقال مالکیت شما از {path} به {user} انجام نشد.", "The ownership transfer of {path} from {user} failed." : "انتقال مالکیت {path} از {user} انجام نشد.", @@ -54,42 +67,77 @@ OC.L10N.register( "Your ownership transfer of {path} to {user} has completed." : "انتقال مالکیت شما از {path} به {user} تکمیل شد.", "The ownership transfer of {path} from {user} has completed." : "انتقال مالکیت {path} از {user} تکمیل شد.", "in %s" : "در %s", + "Transferred from %1$s on %2$s" : "Transferred from %1$s on %2$s", + "Files compatibility" : "Files compatibility", + "Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed." : "Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed.", + "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.", + "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command." : "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command.", + "Enforce Windows compatibility" : "Enforce Windows compatibility", + "This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity." : "This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity.", "File Management" : "مدیریت فایل", "Home" : "خانه", "Target folder does not exist any more" : "پوشه هدف وجود ندارد", "Reload current directory" : "دایرکتوری فعلی را دوباره بارگیری کنید", "Go to the \"{dir}\" directory" : "به دایرکتوری \"{dir}\" بروید", + "Current directory path" : "Current directory path", + "Your have used your space quota and cannot upload files anymore" : "Your have used your space quota and cannot upload files anymore", + "You do not have permission to upload or create files here." : "You do not have permission to upload or create files here.", "Drag and drop files here to upload" : "برای بارگذاری، فایلها را بکشید و اینجا بیاندازید", "Favorite" : "برگزیده", - "Back" : "Back", + "Back" : "بازگشت", + "Toggle selection for file \"{displayName}\"" : "Toggle selection for file \"{displayName}\"", + "Toggle selection for folder \"{displayName}\"" : "Toggle selection for folder \"{displayName}\"", + "File is loading" : "File is loading", + "Folder is loading" : "Folder is loading", "Filename" : "نام پرونده", "Folder name" : "نام پوشه", "This node is unavailable" : "گره شما در دسترس نیست", + "Another entry with the same name already exists." : "Another entry with the same name already exists.", + "Invalid filename." : "Invalid filename.", "Renamed \"{oldName}\" to \"{newName}\"" : "تغییر نام \"{oldName}\" به \"{newName}\"", "Rename file" : "تغییر نام فایل", "Folder" : "پوشه", + "Unknown file type" : "Unknown file type", + "{ext} image" : "{ext} image", + "{ext} video" : "{ext} video", + "{ext} audio" : "{ext} audio", + "{ext} text" : "{ext} text", "Pending" : "در انتظار", + "Unknown date" : "Unknown date", "Clear filter" : "پاک کردن پالایه", "Modified" : "تاریخ", "Type" : "نوع", - "Active filters" : "Active filters", - "Remove filter" : "Remove filter", + "Active filters" : "فیلترهای فعال", + "Remove filter" : "فیلتر را بردارید", "Total rows summary" : "خلاصه کل ردیف ها", + "Toggle selection for all files and folders" : "Toggle selection for all files and folders", "Name" : "نام", + "File type" : "File type", "Size" : "اندازه", + "\"{displayName}\" failed on some elements" : "\"{displayName}\" failed on some elements", "\"{displayName}\" batch action executed successfully" : "عملکرد دستهای \"{displayName}\" با موفقیت اجرا شد", "\"{displayName}\" action failed" : "اقدام \"{displayName}\" ناموفق بود", "Actions" : "فعالیت ها", + "(selected)" : "(selected)", "List of files and folders." : "لیست فایل ها و پوشه ها", + "You have used your space quota and cannot upload files anymore." : "You have used your space quota and cannot upload files anymore.", + "Column headers with buttons are sortable." : "Column headers with buttons are sortable.", "This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "این لیست به دلایل عملکرد به طور کامل ارائه نشده است. در حین حرکت در لیست، فایل ها ارائه می شوند.", "File not found" : "فایل یافت نشد", + "{count} selected" : "{count} selected", "{usedQuotaByte} used" : "{usedQuotaByte} استفاده شده است", "{used} of {quota} used" : "{used} از {quota} استفاده شده", + "{relative}% used" : "{relative}% used", "Could not refresh storage stats" : "نمیتوان آمار ذخیرهسازی را بازخوانی کرد", "Your storage is full, files can not be updated or synced anymore!" : "فضای ذخیره ی شما کاملا پر است، بیش از این فایلها بهنگام یا همگام سازی نمی توانند بشوند!", + "Storage information" : "اطلاعات ذخیرهسازی", + "Storage quota" : "محدودیت ذخیرهسازی", "New folder" : "پوشه جدید", "Create new folder" : "ساختن پوشه جدید", - "Create" : "ساخت", + "This name is already in use." : "This name is already in use.", + "Create" : "ایجاد", + "Fill template fields" : "Fill template fields", + "Submitting fields …" : "Submitting fields …", "Submit" : "ارسال", "Choose a file or folder to transfer" : "فایل یا پوشه ای را برای انتقال انتخاب کنید", "Transfer" : "انتقال", @@ -102,39 +150,84 @@ OC.L10N.register( "Choose file or folder to transfer" : "فایل یا پوشه را برای انتقال انتخاب کنید", "Change" : "تغییر", "New owner" : "مالک جدید", + "Keep {old}" : "Keep {old}", + "Keep without extension" : "Keep without extension", + "Use {new}" : "Use {new}", + "Remove extension" : "Remove extension", + "Change file extension" : "Change file extension", + "Changing the file extension from \"{old}\" to \"{new}\" may render the file unreadable." : "Changing the file extension from \"{old}\" to \"{new}\" may render the file unreadable.", + "Removing the file extension \"{old}\" may render the file unreadable." : "Removing the file extension \"{old}\" may render the file unreadable.", + "Adding the file extension \"{new}\" may render the file unreadable." : "Adding the file extension \"{new}\" may render the file unreadable.", + "Do not show this dialog again." : "Do not show this dialog again.", "Select file or folder to link to" : "فایل یا پوشه را برای پیوند انتخاب کنید", "Choose {file}" : "انتخاب {file}", "Share" : "اشتراکگذاری", "Shared by link" : "اشتراک گذاشته شده از طریق لینک", "Shared" : "به اشتراک گذاشته شده ", - "Switch to list view" : "Switch to list view", + "Switch to list view" : "تغییر به نمای لیست", + "Switch to grid view" : "Switch to grid view", + "The file could not be found" : "The file could not be found", "Upload was cancelled by user" : "آپلود توسط کاربر لغو شد", "Not enough free space" : "فضای کافی در دسترس نیست", "Operation is blocked by access control" : "مدیریت دسترسی، عملیات را متوقف کرد", + "Error during upload: {message}" : "Error during upload: {message}", + "Error during upload, status code {status}" : "Error during upload, status code {status}", + "Unknown error during upload" : "Unknown error during upload", "\"{displayName}\" action executed successfully" : "عملکرد \"{displayName}\" با موفقیت اجرا شد", "Loading current folder" : "در حال بارگیری پوشه فعلی", "Retry" : "تلاش دوباره", "No files in here" : "هیچ فایلی اینجا وجود ندارد", "Upload some content or sync with your devices!" : "محتوایی را آپلود کنید یا با دستگاه خود همگامسازی کنید!", "Go back" : "برگرد", + "Filter file names …" : "Filter file names …", "Views" : "بازدیدها", "Files settings" : "تنظیمات پروندهها", - "Open in files" : "Open in files", + "Your files" : "Your files", + "Open in files" : "باز کردن در فایلها", "File cannot be accessed" : "فایل قابل دسترسی نیست", + "The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "The file could not be found or you do not have permissions to view it. Ask the sender to share it.", "Clipboard is not available" : "کلیپ بورد در دسترس نیست", "WebDAV URL copied to clipboard" : "URL WebDAV در کلیپ بورد کپی شد", "Sort favorites first" : "ابتدا موارد دلخواه را مرتب کنید", + "Sort folders before files" : "Sort folders before files", "Show hidden files" : "نمایش پروندههای مخفی", + "Show file type column" : "Show file type column", "Crop image previews" : "پیش نمایش تصویر برش", + "Enable the grid view" : "Enable the grid view", + "Enable folder tree" : "Enable folder tree", "Additional settings" : "تنظیمات اضافی", "WebDAV" : "WebDAV", + "WebDAV URL" : "WebDAV URL", "Copy to clipboard" : "کپی به کلیپ بورد", "Use this address to access your Files via WebDAV" : "از این آدرس برای دسترسی به فایل های خود از طریق WebDAV استفاده کنید", "If you have enabled 2FA, you must create and use a new app password by clicking here." : "اگر 2FA را فعال کرده اید، باید با کلیک کردن در اینجا یک رمز عبور برنامه جدید ایجاد و استفاده کنید.", + "Warnings" : "Warnings", + "Prevent warning dialogs from open or reenable them." : "Prevent warning dialogs from open or reenable them.", + "Show a warning dialog when changing a file extension." : "Show a warning dialog when changing a file extension.", "Keyboard shortcuts" : "میانبرهای صفحهکلید", + "Speed up your Files experience with these quick shortcuts." : "Speed up your Files experience with these quick shortcuts.", + "Open the actions menu for a file" : "Open the actions menu for a file", + "Rename a file" : "Rename a file", + "Delete a file" : "Delete a file", + "Favorite or remove a file from favorites" : "Favorite or remove a file from favorites", + "Manage tags for a file" : "Manage tags for a file", "Selection" : "انتخاب", + "Select all files" : "Select all files", + "Deselect all files" : "Deselect all files", + "Select or deselect a file" : "Select or deselect a file", + "Select a range of files" : "Select a range of files", "Navigation" : "جهت یابی", + "Navigate to the parent folder" : "Navigate to the parent folder", + "Navigate to the file above" : "Navigate to the file above", + "Navigate to the file below" : "Navigate to the file below", + "Navigate to the file on the left (in grid mode)" : "Navigate to the file on the left (in grid mode)", + "Navigate to the file on the right (in grid mode)" : "Navigate to the file on the right (in grid mode)", "View" : "نمایش", + "Toggle the grid view" : "Toggle the grid view", + "Open the sidebar for a file" : "Open the sidebar for a file", + "Show those shortcuts" : "Show those shortcuts", + "You" : "You", + "Shared multiple times with different people" : "Shared multiple times with different people", "Error while loading the file data" : "خطا هنگام بارگیری داده های فایل", "Owner" : "مالک", "Remove from favorites" : "حذف کردن از برگزیده ها", @@ -145,45 +238,121 @@ OC.L10N.register( "Pick a template for {name}" : "یک الگو برای {name} انتخاب کنید", "Create a new file with the selected template" : "یک فایل جدید با الگوی انتخاب شده ایجاد کنید", "Creating file" : "ایجاد فایل", + "Save as {displayName}" : "Save as {displayName}", + "Save as …" : "Save as …", + "Converting files …" : "Converting files …", + "Failed to convert files: {message}" : "Failed to convert files: {message}", + "All files failed to be converted" : "All files failed to be converted", + "One file could not be converted: {message}" : "One file could not be converted: {message}", + "_One file could not be converted_::_%n files could not be converted_" : ["One file could not be converted","%n files could not be converted"], + "_One file successfully converted_::_%n files successfully converted_" : ["One file successfully converted","%n files successfully converted"], + "Files successfully converted" : "Files successfully converted", + "Failed to convert files" : "Failed to convert files", + "Converting file …" : "Converting file …", + "File successfully converted" : "File successfully converted", + "Failed to convert file: {message}" : "Failed to convert file: {message}", + "Failed to convert file" : "Failed to convert file", + "Deletion cancelled" : "Deletion cancelled", "Leave this share" : "ترک این اشتراک", + "Leave these shares" : "Leave these shares", "Disconnect storage" : "فضای ذخیره را جدا کنید", + "Disconnect storages" : "Disconnect storages", "Delete permanently" : "حذف قطعی", + "Delete and unshare" : "Delete and unshare", "Delete file" : "حذف پرونده", - "Delete files" : "Delete files", + "Delete files" : "حذف فایلها", "Delete folder" : "حذف پوشه", + "Delete folders" : "Delete folders", "Delete" : "حذف", + "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["You are about to permanently delete {count} item","You are about to permanently delete {count} items"], + "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["You are about to delete {count} item","You are about to delete {count} items"], + "Confirm deletion" : "Confirm deletion", "Cancel" : "لغو", + "Moving \"{source}\" to \"{destination}\" …" : "Moving \"{source}\" to \"{destination}\" …", + "Copying \"{source}\" to \"{destination}\" …" : "Copying \"{source}\" to \"{destination}\" …", + "You cannot move a file/folder onto itself or into a subfolder of itself" : "You cannot move a file/folder onto itself or into a subfolder of itself", + "(copy)" : "(copy)", + "(copy %n)" : "(copy %n)", + "Move cancelled" : "Move cancelled", + "A file or folder with that name already exists in this folder" : "A file or folder with that name already exists in this folder", + "The files are locked" : "The files are locked", + "The file does not exist anymore" : "The file does not exist anymore", + "Choose destination" : "Choose destination", "Copy to {target}" : "رونوشت به {target}", "Copy" : "رونوشت", "Move to {target}" : "جابجایی به {target}", "Move" : "انتقال", + "Move or copy operation failed" : "Move or copy operation failed", "Move or copy" : "انتقال یا رونوشت", + "Cancelled move or copy of \"{filename}\"." : "Cancelled move or copy of \"{filename}\".", + "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "باز کردن پوشه {displayName}", "Open in Files" : "در فایل باز کنید", - "Open file locally" : "گشودن محلی پرونده", - "Failed to redirect to client" : "هدایت به مشتری انجام نشد", "Open locally" : "گشودن محلی", + "Failed to redirect to client" : "هدایت به مشتری انجام نشد", + "Open file locally" : "گشودن محلی پرونده", + "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "The file should now open on your device. If it doesn't, please check that you have the desktop app installed.", + "Retry and close" : "Retry and close", + "Open online" : "Open online", "Rename" : "تغییرنام", "Open details" : "باز کردن جزئیات", "View in folder" : "مشاهده در پوشه", "Today" : "امروز", "Last 7 days" : "۷ روز گذشته", "Last 30 days" : "۳۰ روز گذشته", + "This year ({year})" : "This year ({year})", + "Last year ({year})" : "Last year ({year})", "Documents" : "سندها", + "Spreadsheets" : "Spreadsheets", + "Presentations" : "Presentations", + "PDFs" : "PDFs", + "Folders" : "Folders", "Audio" : "صدا", + "Photos and images" : "Photos and images", "Videos" : "فیلم ها ", + "New folder creation cancelled" : "New folder creation cancelled", + "Created new folder \"{name}\"" : "Created new folder \"{name}\"", "Unable to initialize the templates directory" : "راه اندازی دایرکتوری الگوها ممکن نیست", + "Create templates folder" : "Create templates folder", "Templates" : "قالبها", + "New template folder" : "New template folder", + "In folder" : "In folder", + "Search in folder: {folder}" : "Search in folder: {folder}", + "One of the dropped files could not be processed" : "One of the dropped files could not be processed", + "Your browser does not support the Filesystem API. Directories will not be uploaded" : "Your browser does not support the Filesystem API. Directories will not be uploaded", + "No files to upload" : "No files to upload", + "Unable to create the directory {directory}" : "Unable to create the directory {directory}", + "Some files could not be uploaded" : "Some files could not be uploaded", + "Files uploaded successfully" : "Files uploaded successfully", + "No files to process" : "No files to process", + "Some files could not be copied" : "Some files could not be copied", "Some files could not be moved" : "برخی از پروندهها قابل انتقال نیستند", + "Files copied successfully" : "Files copied successfully", + "Files moved successfully" : "Files moved successfully", + "Conflicts resolution skipped" : "Conflicts resolution skipped", + "Upload cancelled" : "Upload cancelled", "This operation is forbidden" : "این عملیات غیرمجاز است", "This directory is unavailable, please check the logs or contact the administrator" : "پوشه در دسترس نیست، لطفا لاگها را بررسی کنید یا به مدیر سیستم اطلاع دهید", "Storage is temporarily not available" : "ذخیره سازی به طور موقت در دسترس نیست", + "Unexpected error: {error}" : "Unexpected error: {error}", "_%n file_::_%n files_" : ["%n فایل","%n فایل"], "_%n folder_::_%n folders_" : ["%n پوشه","%n پوشه"], + "_%n hidden_::_%n hidden_" : ["%n hidden","%n hidden"], + "Filename must not be empty." : "Filename must not be empty.", + "\"{char}\" is not allowed inside a filename." : "\"{char}\" is not allowed inside a filename.", + "\"{segment}\" is a reserved name and not allowed for filenames." : "\"{segment}\" is a reserved name and not allowed for filenames.", + "\"{extension}\" is not an allowed filetype." : "\"{extension}\" is not an allowed filetype.", + "Filenames must not end with \"{extension}\"." : "Filenames must not end with \"{extension}\".", + "List of favorite files and folders." : "List of favorite files and folders.", "No favorites yet" : "هنوز مورد دلخواه وجود ندارد", "Files and folders you mark as favorite will show up here" : "فایلها و پوشههای انتخاب شده به عنوان برگزیده توسط شما، در اینجا نمایش داده میشود", "All files" : "تمامی فایلها", + "List of your files and folders." : "List of your files and folders.", + "All folders" : "All folders", "Personal files" : "فایلهای شخصی", + "List of your files and folders that are not shared." : "List of your files and folders that are not shared.", + "No personal files found" : "No personal files found", + "Files that are not shared will show up here." : "Files that are not shared will show up here.", "Recent" : "اخیر", "List of recently modified files and folders." : "فهرست فایلها و پوشههایی که اخیراً اصلاح شدهاند.", "No recently modified files" : "هیچ فایلی که اخیراً اصلاح شده است", @@ -208,13 +377,13 @@ OC.L10N.register( "An unknown error has occurred" : "خطایی ناشناخته اتفاق افتاده است", "File could not be uploaded" : "پرونده بارگذاری نشد", "Uploading …" : "بارگذاری...", - "{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})", + "{remainingTime} ({currentNumber}/{total})" : "{remainingTime}({currentNumber} /{total} )", "Uploading … ({currentNumber}/{total})" : "در حال بارگذاری ... ({currentNumber}/{total})", "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} از {totalSize} ({bitrate})", "Uploading that item is not supported" : "بارگذاری آن مورد پشتیبانی نمیشود", "Error when assembling chunks, status code {status}" : "خطا هنگام جمع آوری قطعه ها، کد وضعیت {status}", "Choose target folder" : "پوشهٔ هدف را انتخاب کنید", - "Set reminder" : "Set reminder", + "Set reminder" : "تنظیم یادآوری", "Edit locally" : "ویرایش محلی", "Open" : "باز کردن", "Could not load info for file \"{file}\"" : "بارگیری اطلاعات برای پرونده امکان پذیر نیست \"{file}\"", @@ -227,6 +396,9 @@ OC.L10N.register( "Could not move \"{file}\", target exists" : "انتقال\"{file}\" امکان پذیر نیست ، هدف وجود دارد", "Could not move \"{file}\"" : "پروندهٔ \"{file}\" منتقل نمیشود", "copy" : "کپی", + "Could not copy \"{file}\", target exists" : "Could not copy \"{file}\", target exists", + "Could not copy \"{file}\"" : "Could not copy \"{file}\"", + "Copied {origin} inside {destination}" : "Copied {origin} inside {destination}", "Copied {origin} and {nbfiles} other files inside {destination}" : "رونوشت شده از {origin} و {nbfiles} پروندههای دیگر در {destination}", "{newName} already exists" : "{newName} قبلاً موجود است", "Could not rename \"{fileName}\", it does not exist any more" : "نمیتوان نام «{fileName}» را تغییر داد، دیگر وجود ندارد", @@ -261,14 +433,32 @@ OC.L10N.register( "External storage \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "حافظه خارجی \"{mountPoint}\" تقریباً پر است ({usedSpacePercent}%).", "Your storage is almost full ({usedSpacePercent}%)." : "فضای ذخیرهسازی شما تقریباً پر است ({usedSpacePercent}%).", "_matches \"{filter}\"_::_match \"{filter}\"_" : ["مطابقت با \"{filter}\"","مطابقت با \"{filter}\""], + "Direct link was copied (only works for people who have access to this file/folder)" : "Direct link was copied (only works for people who have access to this file/folder)", "Path" : "مسیر", "_%n byte_::_%n bytes_" : ["%n بایت","%n بایت"], + "Favored" : "Favored", + "Favor" : "Favor", + "Copy direct link (only works for people who have access to this file/folder)" : "Copy direct link (only works for people who have access to this file/folder)", "Upload file" : "بارگذاری پرونده", + "Not favored" : "Not favored", "An error occurred while trying to update the tags" : "یک خطا در حین بروزرسانی برچسبها رخ داده است", "Upload (max. %s)" : "آپلود (بیشترین سایز %s)", + "Submitting fields…" : "Submitting fields…", + "Filter filenames…" : "Filter filenames…", + "Edit file locally" : "Edit file locally", + "Edit online" : "Edit online", "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} پوشه","{folderCount} پوشه"], "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} پرونده","{fileCount} پرونده"], + "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 file and {folderCount} folder","1 file and {folderCount} folders"], + "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} file and 1 folder","{fileCount} files and 1 folder"], + "{fileCount} files and {folderCount} folders" : "{fileCount} files and {folderCount} folders", + "Personal Files" : "Personal Files", "Text file" : "فایل متنی", - "New text file.txt" : "پروندهٔ متنی جدید با پسوند txt" + "New text file.txt" : "پروندهٔ متنی جدید با پسوند txt", + "%1$s (renamed)" : "%1$s (renamed)", + "renamed file" : "renamed file", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.", + "{count} files could not be converted" : "{count} files could not be converted", + "{count} files successfully converted" : "{count} files successfully converted" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/files/l10n/fa.json b/apps/files/l10n/fa.json index af4a5027093..98bfc9a30a4 100644 --- a/apps/files/l10n/fa.json +++ b/apps/files/l10n/fa.json @@ -11,6 +11,7 @@ "Restored by {user}" : "بازیابی شده توسط {user}", "Renamed by {user}" : "تغییر نام توسط {user}", "Moved by {user}" : "منتقل شده توسط {user}", + "\"remote account\"" : ""حساب از راه دور"", "You created {file}" : "شما {file} را ایجاد کردید", "You created an encrypted file in {file}" : "شما یک فایل رمزگذاری شده در {file} ایجاد کردید", "{user} created {file}" : "{user} {file} را ایجاد کرد", @@ -40,11 +41,23 @@ "Files" : "پروندهها", "A file or folder has been <strong>changed</strong>" : "یک فایل یا پوشه تغییر کرده است", "A favorite file or folder has been <strong>changed</strong>" : "یک فایل یا پوشه مورد علاقه تغییر کرده است", + "Failed to authorize" : "مجوز صادر نشد", + "Invalid folder path" : "Invalid folder path", + "Folder not found" : "Folder not found", + "The file cannot be found" : "The file cannot be found", + "The destination path does not exist: %1$s" : "The destination path does not exist: %1$s", + "You do not have permission to create a file at the specified location" : "You do not have permission to create a file at the specified location", + "The file could not be converted." : "The file could not be converted.", + "Could not get relative path to converted file" : "Could not get relative path to converted file", + "Favorite files" : "Favorite files", "No favorites" : "هیچ برگزیده", + "More favorites" : "More favorites", "Accept" : "قبول", "Reject" : "رد کردن", "Incoming ownership transfer from {user}" : "انتقال مالکیت ورودی از {user}", "Do you want to accept {path}?\n\nNote: The transfer process after accepting may take up to 1 hour." : "آیا می خواهید {path} را بپذیرید؟\n\nتوجه: فرآیند انتقال پس از پذیرش ممکن است تا 1 ساعت طول بکشد.", + "Ownership transfer denied" : "Ownership transfer denied", + "Your ownership transfer of {path} was denied by {user}." : "Your ownership transfer of {path} was denied by {user}.", "Ownership transfer failed" : "انتقال مالکیت ناموفق بود", "Your ownership transfer of {path} to {user} failed." : "انتقال مالکیت شما از {path} به {user} انجام نشد.", "The ownership transfer of {path} from {user} failed." : "انتقال مالکیت {path} از {user} انجام نشد.", @@ -52,42 +65,77 @@ "Your ownership transfer of {path} to {user} has completed." : "انتقال مالکیت شما از {path} به {user} تکمیل شد.", "The ownership transfer of {path} from {user} has completed." : "انتقال مالکیت {path} از {user} تکمیل شد.", "in %s" : "در %s", + "Transferred from %1$s on %2$s" : "Transferred from %1$s on %2$s", + "Files compatibility" : "Files compatibility", + "Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed." : "Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed.", + "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.", + "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command." : "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command.", + "Enforce Windows compatibility" : "Enforce Windows compatibility", + "This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity." : "This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity.", "File Management" : "مدیریت فایل", "Home" : "خانه", "Target folder does not exist any more" : "پوشه هدف وجود ندارد", "Reload current directory" : "دایرکتوری فعلی را دوباره بارگیری کنید", "Go to the \"{dir}\" directory" : "به دایرکتوری \"{dir}\" بروید", + "Current directory path" : "Current directory path", + "Your have used your space quota and cannot upload files anymore" : "Your have used your space quota and cannot upload files anymore", + "You do not have permission to upload or create files here." : "You do not have permission to upload or create files here.", "Drag and drop files here to upload" : "برای بارگذاری، فایلها را بکشید و اینجا بیاندازید", "Favorite" : "برگزیده", - "Back" : "Back", + "Back" : "بازگشت", + "Toggle selection for file \"{displayName}\"" : "Toggle selection for file \"{displayName}\"", + "Toggle selection for folder \"{displayName}\"" : "Toggle selection for folder \"{displayName}\"", + "File is loading" : "File is loading", + "Folder is loading" : "Folder is loading", "Filename" : "نام پرونده", "Folder name" : "نام پوشه", "This node is unavailable" : "گره شما در دسترس نیست", + "Another entry with the same name already exists." : "Another entry with the same name already exists.", + "Invalid filename." : "Invalid filename.", "Renamed \"{oldName}\" to \"{newName}\"" : "تغییر نام \"{oldName}\" به \"{newName}\"", "Rename file" : "تغییر نام فایل", "Folder" : "پوشه", + "Unknown file type" : "Unknown file type", + "{ext} image" : "{ext} image", + "{ext} video" : "{ext} video", + "{ext} audio" : "{ext} audio", + "{ext} text" : "{ext} text", "Pending" : "در انتظار", + "Unknown date" : "Unknown date", "Clear filter" : "پاک کردن پالایه", "Modified" : "تاریخ", "Type" : "نوع", - "Active filters" : "Active filters", - "Remove filter" : "Remove filter", + "Active filters" : "فیلترهای فعال", + "Remove filter" : "فیلتر را بردارید", "Total rows summary" : "خلاصه کل ردیف ها", + "Toggle selection for all files and folders" : "Toggle selection for all files and folders", "Name" : "نام", + "File type" : "File type", "Size" : "اندازه", + "\"{displayName}\" failed on some elements" : "\"{displayName}\" failed on some elements", "\"{displayName}\" batch action executed successfully" : "عملکرد دستهای \"{displayName}\" با موفقیت اجرا شد", "\"{displayName}\" action failed" : "اقدام \"{displayName}\" ناموفق بود", "Actions" : "فعالیت ها", + "(selected)" : "(selected)", "List of files and folders." : "لیست فایل ها و پوشه ها", + "You have used your space quota and cannot upload files anymore." : "You have used your space quota and cannot upload files anymore.", + "Column headers with buttons are sortable." : "Column headers with buttons are sortable.", "This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "این لیست به دلایل عملکرد به طور کامل ارائه نشده است. در حین حرکت در لیست، فایل ها ارائه می شوند.", "File not found" : "فایل یافت نشد", + "{count} selected" : "{count} selected", "{usedQuotaByte} used" : "{usedQuotaByte} استفاده شده است", "{used} of {quota} used" : "{used} از {quota} استفاده شده", + "{relative}% used" : "{relative}% used", "Could not refresh storage stats" : "نمیتوان آمار ذخیرهسازی را بازخوانی کرد", "Your storage is full, files can not be updated or synced anymore!" : "فضای ذخیره ی شما کاملا پر است، بیش از این فایلها بهنگام یا همگام سازی نمی توانند بشوند!", + "Storage information" : "اطلاعات ذخیرهسازی", + "Storage quota" : "محدودیت ذخیرهسازی", "New folder" : "پوشه جدید", "Create new folder" : "ساختن پوشه جدید", - "Create" : "ساخت", + "This name is already in use." : "This name is already in use.", + "Create" : "ایجاد", + "Fill template fields" : "Fill template fields", + "Submitting fields …" : "Submitting fields …", "Submit" : "ارسال", "Choose a file or folder to transfer" : "فایل یا پوشه ای را برای انتقال انتخاب کنید", "Transfer" : "انتقال", @@ -100,39 +148,84 @@ "Choose file or folder to transfer" : "فایل یا پوشه را برای انتقال انتخاب کنید", "Change" : "تغییر", "New owner" : "مالک جدید", + "Keep {old}" : "Keep {old}", + "Keep without extension" : "Keep without extension", + "Use {new}" : "Use {new}", + "Remove extension" : "Remove extension", + "Change file extension" : "Change file extension", + "Changing the file extension from \"{old}\" to \"{new}\" may render the file unreadable." : "Changing the file extension from \"{old}\" to \"{new}\" may render the file unreadable.", + "Removing the file extension \"{old}\" may render the file unreadable." : "Removing the file extension \"{old}\" may render the file unreadable.", + "Adding the file extension \"{new}\" may render the file unreadable." : "Adding the file extension \"{new}\" may render the file unreadable.", + "Do not show this dialog again." : "Do not show this dialog again.", "Select file or folder to link to" : "فایل یا پوشه را برای پیوند انتخاب کنید", "Choose {file}" : "انتخاب {file}", "Share" : "اشتراکگذاری", "Shared by link" : "اشتراک گذاشته شده از طریق لینک", "Shared" : "به اشتراک گذاشته شده ", - "Switch to list view" : "Switch to list view", + "Switch to list view" : "تغییر به نمای لیست", + "Switch to grid view" : "Switch to grid view", + "The file could not be found" : "The file could not be found", "Upload was cancelled by user" : "آپلود توسط کاربر لغو شد", "Not enough free space" : "فضای کافی در دسترس نیست", "Operation is blocked by access control" : "مدیریت دسترسی، عملیات را متوقف کرد", + "Error during upload: {message}" : "Error during upload: {message}", + "Error during upload, status code {status}" : "Error during upload, status code {status}", + "Unknown error during upload" : "Unknown error during upload", "\"{displayName}\" action executed successfully" : "عملکرد \"{displayName}\" با موفقیت اجرا شد", "Loading current folder" : "در حال بارگیری پوشه فعلی", "Retry" : "تلاش دوباره", "No files in here" : "هیچ فایلی اینجا وجود ندارد", "Upload some content or sync with your devices!" : "محتوایی را آپلود کنید یا با دستگاه خود همگامسازی کنید!", "Go back" : "برگرد", + "Filter file names …" : "Filter file names …", "Views" : "بازدیدها", "Files settings" : "تنظیمات پروندهها", - "Open in files" : "Open in files", + "Your files" : "Your files", + "Open in files" : "باز کردن در فایلها", "File cannot be accessed" : "فایل قابل دسترسی نیست", + "The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "The file could not be found or you do not have permissions to view it. Ask the sender to share it.", "Clipboard is not available" : "کلیپ بورد در دسترس نیست", "WebDAV URL copied to clipboard" : "URL WebDAV در کلیپ بورد کپی شد", "Sort favorites first" : "ابتدا موارد دلخواه را مرتب کنید", + "Sort folders before files" : "Sort folders before files", "Show hidden files" : "نمایش پروندههای مخفی", + "Show file type column" : "Show file type column", "Crop image previews" : "پیش نمایش تصویر برش", + "Enable the grid view" : "Enable the grid view", + "Enable folder tree" : "Enable folder tree", "Additional settings" : "تنظیمات اضافی", "WebDAV" : "WebDAV", + "WebDAV URL" : "WebDAV URL", "Copy to clipboard" : "کپی به کلیپ بورد", "Use this address to access your Files via WebDAV" : "از این آدرس برای دسترسی به فایل های خود از طریق WebDAV استفاده کنید", "If you have enabled 2FA, you must create and use a new app password by clicking here." : "اگر 2FA را فعال کرده اید، باید با کلیک کردن در اینجا یک رمز عبور برنامه جدید ایجاد و استفاده کنید.", + "Warnings" : "Warnings", + "Prevent warning dialogs from open or reenable them." : "Prevent warning dialogs from open or reenable them.", + "Show a warning dialog when changing a file extension." : "Show a warning dialog when changing a file extension.", "Keyboard shortcuts" : "میانبرهای صفحهکلید", + "Speed up your Files experience with these quick shortcuts." : "Speed up your Files experience with these quick shortcuts.", + "Open the actions menu for a file" : "Open the actions menu for a file", + "Rename a file" : "Rename a file", + "Delete a file" : "Delete a file", + "Favorite or remove a file from favorites" : "Favorite or remove a file from favorites", + "Manage tags for a file" : "Manage tags for a file", "Selection" : "انتخاب", + "Select all files" : "Select all files", + "Deselect all files" : "Deselect all files", + "Select or deselect a file" : "Select or deselect a file", + "Select a range of files" : "Select a range of files", "Navigation" : "جهت یابی", + "Navigate to the parent folder" : "Navigate to the parent folder", + "Navigate to the file above" : "Navigate to the file above", + "Navigate to the file below" : "Navigate to the file below", + "Navigate to the file on the left (in grid mode)" : "Navigate to the file on the left (in grid mode)", + "Navigate to the file on the right (in grid mode)" : "Navigate to the file on the right (in grid mode)", "View" : "نمایش", + "Toggle the grid view" : "Toggle the grid view", + "Open the sidebar for a file" : "Open the sidebar for a file", + "Show those shortcuts" : "Show those shortcuts", + "You" : "You", + "Shared multiple times with different people" : "Shared multiple times with different people", "Error while loading the file data" : "خطا هنگام بارگیری داده های فایل", "Owner" : "مالک", "Remove from favorites" : "حذف کردن از برگزیده ها", @@ -143,45 +236,121 @@ "Pick a template for {name}" : "یک الگو برای {name} انتخاب کنید", "Create a new file with the selected template" : "یک فایل جدید با الگوی انتخاب شده ایجاد کنید", "Creating file" : "ایجاد فایل", + "Save as {displayName}" : "Save as {displayName}", + "Save as …" : "Save as …", + "Converting files …" : "Converting files …", + "Failed to convert files: {message}" : "Failed to convert files: {message}", + "All files failed to be converted" : "All files failed to be converted", + "One file could not be converted: {message}" : "One file could not be converted: {message}", + "_One file could not be converted_::_%n files could not be converted_" : ["One file could not be converted","%n files could not be converted"], + "_One file successfully converted_::_%n files successfully converted_" : ["One file successfully converted","%n files successfully converted"], + "Files successfully converted" : "Files successfully converted", + "Failed to convert files" : "Failed to convert files", + "Converting file …" : "Converting file …", + "File successfully converted" : "File successfully converted", + "Failed to convert file: {message}" : "Failed to convert file: {message}", + "Failed to convert file" : "Failed to convert file", + "Deletion cancelled" : "Deletion cancelled", "Leave this share" : "ترک این اشتراک", + "Leave these shares" : "Leave these shares", "Disconnect storage" : "فضای ذخیره را جدا کنید", + "Disconnect storages" : "Disconnect storages", "Delete permanently" : "حذف قطعی", + "Delete and unshare" : "Delete and unshare", "Delete file" : "حذف پرونده", - "Delete files" : "Delete files", + "Delete files" : "حذف فایلها", "Delete folder" : "حذف پوشه", + "Delete folders" : "Delete folders", "Delete" : "حذف", + "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["You are about to permanently delete {count} item","You are about to permanently delete {count} items"], + "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["You are about to delete {count} item","You are about to delete {count} items"], + "Confirm deletion" : "Confirm deletion", "Cancel" : "لغو", + "Moving \"{source}\" to \"{destination}\" …" : "Moving \"{source}\" to \"{destination}\" …", + "Copying \"{source}\" to \"{destination}\" …" : "Copying \"{source}\" to \"{destination}\" …", + "You cannot move a file/folder onto itself or into a subfolder of itself" : "You cannot move a file/folder onto itself or into a subfolder of itself", + "(copy)" : "(copy)", + "(copy %n)" : "(copy %n)", + "Move cancelled" : "Move cancelled", + "A file or folder with that name already exists in this folder" : "A file or folder with that name already exists in this folder", + "The files are locked" : "The files are locked", + "The file does not exist anymore" : "The file does not exist anymore", + "Choose destination" : "Choose destination", "Copy to {target}" : "رونوشت به {target}", "Copy" : "رونوشت", "Move to {target}" : "جابجایی به {target}", "Move" : "انتقال", + "Move or copy operation failed" : "Move or copy operation failed", "Move or copy" : "انتقال یا رونوشت", + "Cancelled move or copy of \"{filename}\"." : "Cancelled move or copy of \"{filename}\".", + "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "باز کردن پوشه {displayName}", "Open in Files" : "در فایل باز کنید", - "Open file locally" : "گشودن محلی پرونده", - "Failed to redirect to client" : "هدایت به مشتری انجام نشد", "Open locally" : "گشودن محلی", + "Failed to redirect to client" : "هدایت به مشتری انجام نشد", + "Open file locally" : "گشودن محلی پرونده", + "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "The file should now open on your device. If it doesn't, please check that you have the desktop app installed.", + "Retry and close" : "Retry and close", + "Open online" : "Open online", "Rename" : "تغییرنام", "Open details" : "باز کردن جزئیات", "View in folder" : "مشاهده در پوشه", "Today" : "امروز", "Last 7 days" : "۷ روز گذشته", "Last 30 days" : "۳۰ روز گذشته", + "This year ({year})" : "This year ({year})", + "Last year ({year})" : "Last year ({year})", "Documents" : "سندها", + "Spreadsheets" : "Spreadsheets", + "Presentations" : "Presentations", + "PDFs" : "PDFs", + "Folders" : "Folders", "Audio" : "صدا", + "Photos and images" : "Photos and images", "Videos" : "فیلم ها ", + "New folder creation cancelled" : "New folder creation cancelled", + "Created new folder \"{name}\"" : "Created new folder \"{name}\"", "Unable to initialize the templates directory" : "راه اندازی دایرکتوری الگوها ممکن نیست", + "Create templates folder" : "Create templates folder", "Templates" : "قالبها", + "New template folder" : "New template folder", + "In folder" : "In folder", + "Search in folder: {folder}" : "Search in folder: {folder}", + "One of the dropped files could not be processed" : "One of the dropped files could not be processed", + "Your browser does not support the Filesystem API. Directories will not be uploaded" : "Your browser does not support the Filesystem API. Directories will not be uploaded", + "No files to upload" : "No files to upload", + "Unable to create the directory {directory}" : "Unable to create the directory {directory}", + "Some files could not be uploaded" : "Some files could not be uploaded", + "Files uploaded successfully" : "Files uploaded successfully", + "No files to process" : "No files to process", + "Some files could not be copied" : "Some files could not be copied", "Some files could not be moved" : "برخی از پروندهها قابل انتقال نیستند", + "Files copied successfully" : "Files copied successfully", + "Files moved successfully" : "Files moved successfully", + "Conflicts resolution skipped" : "Conflicts resolution skipped", + "Upload cancelled" : "Upload cancelled", "This operation is forbidden" : "این عملیات غیرمجاز است", "This directory is unavailable, please check the logs or contact the administrator" : "پوشه در دسترس نیست، لطفا لاگها را بررسی کنید یا به مدیر سیستم اطلاع دهید", "Storage is temporarily not available" : "ذخیره سازی به طور موقت در دسترس نیست", + "Unexpected error: {error}" : "Unexpected error: {error}", "_%n file_::_%n files_" : ["%n فایل","%n فایل"], "_%n folder_::_%n folders_" : ["%n پوشه","%n پوشه"], + "_%n hidden_::_%n hidden_" : ["%n hidden","%n hidden"], + "Filename must not be empty." : "Filename must not be empty.", + "\"{char}\" is not allowed inside a filename." : "\"{char}\" is not allowed inside a filename.", + "\"{segment}\" is a reserved name and not allowed for filenames." : "\"{segment}\" is a reserved name and not allowed for filenames.", + "\"{extension}\" is not an allowed filetype." : "\"{extension}\" is not an allowed filetype.", + "Filenames must not end with \"{extension}\"." : "Filenames must not end with \"{extension}\".", + "List of favorite files and folders." : "List of favorite files and folders.", "No favorites yet" : "هنوز مورد دلخواه وجود ندارد", "Files and folders you mark as favorite will show up here" : "فایلها و پوشههای انتخاب شده به عنوان برگزیده توسط شما، در اینجا نمایش داده میشود", "All files" : "تمامی فایلها", + "List of your files and folders." : "List of your files and folders.", + "All folders" : "All folders", "Personal files" : "فایلهای شخصی", + "List of your files and folders that are not shared." : "List of your files and folders that are not shared.", + "No personal files found" : "No personal files found", + "Files that are not shared will show up here." : "Files that are not shared will show up here.", "Recent" : "اخیر", "List of recently modified files and folders." : "فهرست فایلها و پوشههایی که اخیراً اصلاح شدهاند.", "No recently modified files" : "هیچ فایلی که اخیراً اصلاح شده است", @@ -206,13 +375,13 @@ "An unknown error has occurred" : "خطایی ناشناخته اتفاق افتاده است", "File could not be uploaded" : "پرونده بارگذاری نشد", "Uploading …" : "بارگذاری...", - "{remainingTime} ({currentNumber}/{total})" : "{remainingTime} ({currentNumber}/{total})", + "{remainingTime} ({currentNumber}/{total})" : "{remainingTime}({currentNumber} /{total} )", "Uploading … ({currentNumber}/{total})" : "در حال بارگذاری ... ({currentNumber}/{total})", "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} از {totalSize} ({bitrate})", "Uploading that item is not supported" : "بارگذاری آن مورد پشتیبانی نمیشود", "Error when assembling chunks, status code {status}" : "خطا هنگام جمع آوری قطعه ها، کد وضعیت {status}", "Choose target folder" : "پوشهٔ هدف را انتخاب کنید", - "Set reminder" : "Set reminder", + "Set reminder" : "تنظیم یادآوری", "Edit locally" : "ویرایش محلی", "Open" : "باز کردن", "Could not load info for file \"{file}\"" : "بارگیری اطلاعات برای پرونده امکان پذیر نیست \"{file}\"", @@ -225,6 +394,9 @@ "Could not move \"{file}\", target exists" : "انتقال\"{file}\" امکان پذیر نیست ، هدف وجود دارد", "Could not move \"{file}\"" : "پروندهٔ \"{file}\" منتقل نمیشود", "copy" : "کپی", + "Could not copy \"{file}\", target exists" : "Could not copy \"{file}\", target exists", + "Could not copy \"{file}\"" : "Could not copy \"{file}\"", + "Copied {origin} inside {destination}" : "Copied {origin} inside {destination}", "Copied {origin} and {nbfiles} other files inside {destination}" : "رونوشت شده از {origin} و {nbfiles} پروندههای دیگر در {destination}", "{newName} already exists" : "{newName} قبلاً موجود است", "Could not rename \"{fileName}\", it does not exist any more" : "نمیتوان نام «{fileName}» را تغییر داد، دیگر وجود ندارد", @@ -259,14 +431,32 @@ "External storage \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "حافظه خارجی \"{mountPoint}\" تقریباً پر است ({usedSpacePercent}%).", "Your storage is almost full ({usedSpacePercent}%)." : "فضای ذخیرهسازی شما تقریباً پر است ({usedSpacePercent}%).", "_matches \"{filter}\"_::_match \"{filter}\"_" : ["مطابقت با \"{filter}\"","مطابقت با \"{filter}\""], + "Direct link was copied (only works for people who have access to this file/folder)" : "Direct link was copied (only works for people who have access to this file/folder)", "Path" : "مسیر", "_%n byte_::_%n bytes_" : ["%n بایت","%n بایت"], + "Favored" : "Favored", + "Favor" : "Favor", + "Copy direct link (only works for people who have access to this file/folder)" : "Copy direct link (only works for people who have access to this file/folder)", "Upload file" : "بارگذاری پرونده", + "Not favored" : "Not favored", "An error occurred while trying to update the tags" : "یک خطا در حین بروزرسانی برچسبها رخ داده است", "Upload (max. %s)" : "آپلود (بیشترین سایز %s)", + "Submitting fields…" : "Submitting fields…", + "Filter filenames…" : "Filter filenames…", + "Edit file locally" : "Edit file locally", + "Edit online" : "Edit online", "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} پوشه","{folderCount} پوشه"], "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} پرونده","{fileCount} پرونده"], + "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 file and {folderCount} folder","1 file and {folderCount} folders"], + "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} file and 1 folder","{fileCount} files and 1 folder"], + "{fileCount} files and {folderCount} folders" : "{fileCount} files and {folderCount} folders", + "Personal Files" : "Personal Files", "Text file" : "فایل متنی", - "New text file.txt" : "پروندهٔ متنی جدید با پسوند txt" + "New text file.txt" : "پروندهٔ متنی جدید با پسوند txt", + "%1$s (renamed)" : "%1$s (renamed)", + "renamed file" : "renamed file", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner.", + "{count} files could not be converted" : "{count} files could not be converted", + "{count} files successfully converted" : "{count} files successfully converted" },"pluralForm" :"nplurals=2; plural=(n > 1);" }
\ No newline at end of file diff --git a/apps/files/l10n/fi.js b/apps/files/l10n/fi.js index 4c419f2e482..6e6fd348feb 100644 --- a/apps/files/l10n/fi.js +++ b/apps/files/l10n/fi.js @@ -244,10 +244,10 @@ OC.L10N.register( "Cancelled move or copy operation" : "Siirto- tai kopiointitoiminto peruttu", "Open folder {displayName}" : "Avaa kansio {displayName}", "Open in Files" : "Avaa tiedostosovelluksessa", + "Open locally" : "Avaa paikallisesti", + "Failed to redirect to client" : "Uudelleenohjaus asiakkaaseen epäonnistui", "Open file locally" : "Avaa tiedosto paikallisesti", "Retry and close" : "Yritä uudelleen ja sulje", - "Failed to redirect to client" : "Uudelleenohjaus asiakkaaseen epäonnistui", - "Open locally" : "Avaa paikallisesti", "Rename" : "Nimeä uudelleen", "Open details" : "Avaa yksityiskohdat", "View in folder" : "Näe kansiossa", diff --git a/apps/files/l10n/fi.json b/apps/files/l10n/fi.json index fad7ebafc6e..c40fef57d23 100644 --- a/apps/files/l10n/fi.json +++ b/apps/files/l10n/fi.json @@ -242,10 +242,10 @@ "Cancelled move or copy operation" : "Siirto- tai kopiointitoiminto peruttu", "Open folder {displayName}" : "Avaa kansio {displayName}", "Open in Files" : "Avaa tiedostosovelluksessa", + "Open locally" : "Avaa paikallisesti", + "Failed to redirect to client" : "Uudelleenohjaus asiakkaaseen epäonnistui", "Open file locally" : "Avaa tiedosto paikallisesti", "Retry and close" : "Yritä uudelleen ja sulje", - "Failed to redirect to client" : "Uudelleenohjaus asiakkaaseen epäonnistui", - "Open locally" : "Avaa paikallisesti", "Rename" : "Nimeä uudelleen", "Open details" : "Avaa yksityiskohdat", "View in folder" : "Näe kansiossa", diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js index 8ba8a759b0a..6d7ffb9200a 100644 --- a/apps/files/l10n/fr.js +++ b/apps/files/l10n/fr.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Opération de déplacement ou de copie annulée", "Open folder {displayName}" : "Ouvrir le dossier {displayName}", "Open in Files" : "Ouvrir dans Fichiers", + "Open locally" : "Ouvrir localement", + "Failed to redirect to client" : "Échec de la redirection vers le client", "Open file locally" : "Ouvrir le fichier localement", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Le fichier devrait maintenant s'ouvrir sur votre appareil. Si ce n'est pas le cas, vérifiez que vous avez installé l'application de bureau.", "Retry and close" : "Réessayer et fermer", "Open online" : "Ouvrir en ligne", - "Failed to redirect to client" : "Échec de la redirection vers le client", - "Open locally" : "Ouvrir localement", "Rename" : "Renommer", "Open details" : "Ouvrir les détails", "View in folder" : "Afficher dans le dossier", @@ -457,6 +457,7 @@ OC.L10N.register( "New text file.txt" : "Nouveau fichier texte.txt", "%1$s (renamed)" : "%1$s (renommé)", "renamed file" : "fichier renommé", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Après avoir activé les noms de fichiers compatibles Windows, les fichiers existants ne peuvent plus être modifiés, mais peuvent être renommés avec des noms valides par leur propriétaire.", "{count} files could not be converted" : "{count}fichier n'a pas pu être converti", "{count} files successfully converted" : "{count}fichier converti avec succès" }, diff --git a/apps/files/l10n/fr.json b/apps/files/l10n/fr.json index 03030c23c4c..d7e622dd9c6 100644 --- a/apps/files/l10n/fr.json +++ b/apps/files/l10n/fr.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Opération de déplacement ou de copie annulée", "Open folder {displayName}" : "Ouvrir le dossier {displayName}", "Open in Files" : "Ouvrir dans Fichiers", + "Open locally" : "Ouvrir localement", + "Failed to redirect to client" : "Échec de la redirection vers le client", "Open file locally" : "Ouvrir le fichier localement", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Le fichier devrait maintenant s'ouvrir sur votre appareil. Si ce n'est pas le cas, vérifiez que vous avez installé l'application de bureau.", "Retry and close" : "Réessayer et fermer", "Open online" : "Ouvrir en ligne", - "Failed to redirect to client" : "Échec de la redirection vers le client", - "Open locally" : "Ouvrir localement", "Rename" : "Renommer", "Open details" : "Ouvrir les détails", "View in folder" : "Afficher dans le dossier", @@ -455,6 +455,7 @@ "New text file.txt" : "Nouveau fichier texte.txt", "%1$s (renamed)" : "%1$s (renommé)", "renamed file" : "fichier renommé", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Après avoir activé les noms de fichiers compatibles Windows, les fichiers existants ne peuvent plus être modifiés, mais peuvent être renommés avec des noms valides par leur propriétaire.", "{count} files could not be converted" : "{count}fichier n'a pas pu être converti", "{count} files successfully converted" : "{count}fichier converti avec succès" },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" diff --git a/apps/files/l10n/ga.js b/apps/files/l10n/ga.js index 4ec8d02a2bd..5e71dfac609 100644 --- a/apps/files/l10n/ga.js +++ b/apps/files/l10n/ga.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Oibríocht aistrithe nó cóipeála curtha ar ceal", "Open folder {displayName}" : "Oscail fillteán {displayName}", "Open in Files" : "Oscail i Comhaid", + "Open locally" : "Oscail go háitiúil", + "Failed to redirect to client" : "Theip ar atreorú chuig an gcliant", "Open file locally" : "Oscail comhad go háitiúil", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Ba cheart an comhad a oscailt anois ar do ghléas. Mura ndéanann sé, seiceáil le do thoil go bhfuil an aip deisce suiteáilte agat.", "Retry and close" : "Bain triail eile as agus dún", "Open online" : "Oscail ar líne", - "Failed to redirect to client" : "Theip ar atreorú chuig an gcliant", - "Open locally" : "Oscail go háitiúil", "Rename" : "Athainmnigh", "Open details" : "Sonraí oscailte", "View in folder" : "Amharc san fhillteán", diff --git a/apps/files/l10n/ga.json b/apps/files/l10n/ga.json index c0f40183c41..3d2e164a6f3 100644 --- a/apps/files/l10n/ga.json +++ b/apps/files/l10n/ga.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Oibríocht aistrithe nó cóipeála curtha ar ceal", "Open folder {displayName}" : "Oscail fillteán {displayName}", "Open in Files" : "Oscail i Comhaid", + "Open locally" : "Oscail go háitiúil", + "Failed to redirect to client" : "Theip ar atreorú chuig an gcliant", "Open file locally" : "Oscail comhad go háitiúil", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Ba cheart an comhad a oscailt anois ar do ghléas. Mura ndéanann sé, seiceáil le do thoil go bhfuil an aip deisce suiteáilte agat.", "Retry and close" : "Bain triail eile as agus dún", "Open online" : "Oscail ar líne", - "Failed to redirect to client" : "Theip ar atreorú chuig an gcliant", - "Open locally" : "Oscail go háitiúil", "Rename" : "Athainmnigh", "Open details" : "Sonraí oscailte", "View in folder" : "Amharc san fhillteán", diff --git a/apps/files/l10n/gl.js b/apps/files/l10n/gl.js index c352a853798..4a73f0d8785 100644 --- a/apps/files/l10n/gl.js +++ b/apps/files/l10n/gl.js @@ -277,12 +277,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Foi cancelada a operación de movemento ou copia", "Open folder {displayName}" : "Abrir o cartafol {displayName}", "Open in Files" : "Abrir en Ficheiros", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Produciuse un fallo ao redirixir ao cliente", "Open file locally" : "Abrir o ficheiro localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "O ficheiro debería abrirse agora no seu dispositivo. Se non é así, comprobe se ten instalada a aplicación de escritorio.", "Retry and close" : "Tentar de novo e pechar", "Open online" : "Abrir en liña", - "Failed to redirect to client" : "Produciuse un fallo ao redirixir ao cliente", - "Open locally" : "Abrir localmente", "Rename" : "Cambiar o nome", "Open details" : "Abrir detalles", "View in folder" : "Ver no cartafol", diff --git a/apps/files/l10n/gl.json b/apps/files/l10n/gl.json index 88363ce23bc..7911fe7ed11 100644 --- a/apps/files/l10n/gl.json +++ b/apps/files/l10n/gl.json @@ -275,12 +275,12 @@ "Cancelled move or copy operation" : "Foi cancelada a operación de movemento ou copia", "Open folder {displayName}" : "Abrir o cartafol {displayName}", "Open in Files" : "Abrir en Ficheiros", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Produciuse un fallo ao redirixir ao cliente", "Open file locally" : "Abrir o ficheiro localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "O ficheiro debería abrirse agora no seu dispositivo. Se non é así, comprobe se ten instalada a aplicación de escritorio.", "Retry and close" : "Tentar de novo e pechar", "Open online" : "Abrir en liña", - "Failed to redirect to client" : "Produciuse un fallo ao redirixir ao cliente", - "Open locally" : "Abrir localmente", "Rename" : "Cambiar o nome", "Open details" : "Abrir detalles", "View in folder" : "Ver no cartafol", diff --git a/apps/files/l10n/hu.js b/apps/files/l10n/hu.js index a07747091f7..b9c8dbb0aba 100644 --- a/apps/files/l10n/hu.js +++ b/apps/files/l10n/hu.js @@ -264,11 +264,11 @@ OC.L10N.register( "Cancelled move or copy operation" : "Az áthelyezés vagy másolás művelet megszakítva", "Open folder {displayName}" : "A(z) {displayName} mappa megnyitása", "Open in Files" : "Megnyitás a Fájlokban", + "Open locally" : "Megnyitás helyben", + "Failed to redirect to client" : "Nem sikerült az átirányítás a klienshez", "Open file locally" : "A fájl megnyitása helyben", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "A fájlnak most már meg kellene nyílni az eszközén. Ha mégsem, ellenőrizze, hogy telepítve van-e az asztali alkalmazás.", "Retry and close" : "Újrapróbálás és bezárás", - "Failed to redirect to client" : "Nem sikerült az átirányítás a klienshez", - "Open locally" : "Megnyitás helyben", "Rename" : "Átnevezés", "Open details" : "Részletek megnyitása", "View in folder" : "Megtekintés mappában", diff --git a/apps/files/l10n/hu.json b/apps/files/l10n/hu.json index f396814aa2b..75a19cd5c04 100644 --- a/apps/files/l10n/hu.json +++ b/apps/files/l10n/hu.json @@ -262,11 +262,11 @@ "Cancelled move or copy operation" : "Az áthelyezés vagy másolás művelet megszakítva", "Open folder {displayName}" : "A(z) {displayName} mappa megnyitása", "Open in Files" : "Megnyitás a Fájlokban", + "Open locally" : "Megnyitás helyben", + "Failed to redirect to client" : "Nem sikerült az átirányítás a klienshez", "Open file locally" : "A fájl megnyitása helyben", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "A fájlnak most már meg kellene nyílni az eszközén. Ha mégsem, ellenőrizze, hogy telepítve van-e az asztali alkalmazás.", "Retry and close" : "Újrapróbálás és bezárás", - "Failed to redirect to client" : "Nem sikerült az átirányítás a klienshez", - "Open locally" : "Megnyitás helyben", "Rename" : "Átnevezés", "Open details" : "Részletek megnyitása", "View in folder" : "Megtekintés mappában", diff --git a/apps/files/l10n/is.js b/apps/files/l10n/is.js index 396e17102d2..69a2c015b82 100644 --- a/apps/files/l10n/is.js +++ b/apps/files/l10n/is.js @@ -263,9 +263,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "Hætti við aðgerð við að færa eða afrita", "Open folder {displayName}" : "Opna möppu {displayName}", "Open in Files" : "Opna í skráaforritinu", + "Failed to redirect to client" : "Mistókst að endurbeina til biðlara", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Skráin ætti núna að opnast á tækinu þínu. Ef það gerist ekki, ættirðu að ganga úr skugga um að þú sért með vinnutölvuforritið uppsett.", "Retry and close" : "Prófa aftur og loka", - "Failed to redirect to client" : "Mistókst að endurbeina til biðlara", "Rename" : "Endurnefna", "Open details" : "Opna nánari upplýsingar", "View in folder" : "Skoða í möppu", diff --git a/apps/files/l10n/is.json b/apps/files/l10n/is.json index 4da31a7d937..ebf1c4095bb 100644 --- a/apps/files/l10n/is.json +++ b/apps/files/l10n/is.json @@ -261,9 +261,9 @@ "Cancelled move or copy operation" : "Hætti við aðgerð við að færa eða afrita", "Open folder {displayName}" : "Opna möppu {displayName}", "Open in Files" : "Opna í skráaforritinu", + "Failed to redirect to client" : "Mistókst að endurbeina til biðlara", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Skráin ætti núna að opnast á tækinu þínu. Ef það gerist ekki, ættirðu að ganga úr skugga um að þú sért með vinnutölvuforritið uppsett.", "Retry and close" : "Prófa aftur og loka", - "Failed to redirect to client" : "Mistókst að endurbeina til biðlara", "Rename" : "Endurnefna", "Open details" : "Opna nánari upplýsingar", "View in folder" : "Skoða í möppu", diff --git a/apps/files/l10n/it.js b/apps/files/l10n/it.js index e93f1cbf211..c679e500af3 100644 --- a/apps/files/l10n/it.js +++ b/apps/files/l10n/it.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Operazione di spostamento o copia annullata", "Open folder {displayName}" : "Apri la cartella {displayName}", "Open in Files" : "Apri in File", + "Open locally" : "Aprire localmente", + "Failed to redirect to client" : "Reindirizzamento al client non riuscito", "Open file locally" : "Apri file localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Il file dovrebbe ora aprirsi sul tuo dispositivo. In caso contrario, controlla di aver installato l'app desktop.", "Retry and close" : "Riprova e chiudi", "Open online" : "Apri online", - "Failed to redirect to client" : "Reindirizzamento al client non riuscito", - "Open locally" : "Aprire localmente", "Rename" : "Rinomina", "Open details" : "Apri i dettagli", "View in folder" : "Visualizza nella cartella", diff --git a/apps/files/l10n/it.json b/apps/files/l10n/it.json index 8c5942f6582..22126950860 100644 --- a/apps/files/l10n/it.json +++ b/apps/files/l10n/it.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Operazione di spostamento o copia annullata", "Open folder {displayName}" : "Apri la cartella {displayName}", "Open in Files" : "Apri in File", + "Open locally" : "Aprire localmente", + "Failed to redirect to client" : "Reindirizzamento al client non riuscito", "Open file locally" : "Apri file localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Il file dovrebbe ora aprirsi sul tuo dispositivo. In caso contrario, controlla di aver installato l'app desktop.", "Retry and close" : "Riprova e chiudi", "Open online" : "Apri online", - "Failed to redirect to client" : "Reindirizzamento al client non riuscito", - "Open locally" : "Aprire localmente", "Rename" : "Rinomina", "Open details" : "Apri i dettagli", "View in folder" : "Visualizza nella cartella", diff --git a/apps/files/l10n/ja.js b/apps/files/l10n/ja.js index f7db5f58b5d..54b12237bf2 100644 --- a/apps/files/l10n/ja.js +++ b/apps/files/l10n/ja.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "キャンセルされた移動またはコピー操作", "Open folder {displayName}" : "フォルダ {displayName} を開く", "Open in Files" : "ファイルアプリで開く", + "Open locally" : "ローカルで開く", + "Failed to redirect to client" : "クライアントへリダイレクトできませんでした", "Open file locally" : "ローカルでファイルを開く", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "ファイルがデバイス上で開くはずです。開かない場合は、デスクトップアプリがインストールされているかご確認ください。", "Retry and close" : "再試行して閉じる", "Open online" : "オンラインで開く", - "Failed to redirect to client" : "クライアントへリダイレクトできませんでした", - "Open locally" : "ローカルで開く", "Rename" : "名前の変更", "Open details" : "詳細を開く", "View in folder" : "フォルダー内で表示", @@ -457,6 +457,7 @@ OC.L10N.register( "New text file.txt" : "新規のテキストファイル作成", "%1$s (renamed)" : "%1$s (リネーム済み)", "renamed file" : "リネーム済みファイル", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Windows 互換のファイル名を有効にすると、既存のファイルは変更できなくなりますが、所有者が有効な新しいファイル名に変更できるようになります。", "{count} files could not be converted" : "{count}個のファイルが変換できませんでした", "{count} files successfully converted" : "{count}個のファイルの変換に成功しました" }, diff --git a/apps/files/l10n/ja.json b/apps/files/l10n/ja.json index cda2ae24dd6..5a03f50eb2e 100644 --- a/apps/files/l10n/ja.json +++ b/apps/files/l10n/ja.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "キャンセルされた移動またはコピー操作", "Open folder {displayName}" : "フォルダ {displayName} を開く", "Open in Files" : "ファイルアプリで開く", + "Open locally" : "ローカルで開く", + "Failed to redirect to client" : "クライアントへリダイレクトできませんでした", "Open file locally" : "ローカルでファイルを開く", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "ファイルがデバイス上で開くはずです。開かない場合は、デスクトップアプリがインストールされているかご確認ください。", "Retry and close" : "再試行して閉じる", "Open online" : "オンラインで開く", - "Failed to redirect to client" : "クライアントへリダイレクトできませんでした", - "Open locally" : "ローカルで開く", "Rename" : "名前の変更", "Open details" : "詳細を開く", "View in folder" : "フォルダー内で表示", @@ -455,6 +455,7 @@ "New text file.txt" : "新規のテキストファイル作成", "%1$s (renamed)" : "%1$s (リネーム済み)", "renamed file" : "リネーム済みファイル", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Windows 互換のファイル名を有効にすると、既存のファイルは変更できなくなりますが、所有者が有効な新しいファイル名に変更できるようになります。", "{count} files could not be converted" : "{count}個のファイルが変換できませんでした", "{count} files successfully converted" : "{count}個のファイルの変換に成功しました" },"pluralForm" :"nplurals=1; plural=0;" diff --git a/apps/files/l10n/ka.js b/apps/files/l10n/ka.js index 70aa60fc292..550819832fc 100644 --- a/apps/files/l10n/ka.js +++ b/apps/files/l10n/ka.js @@ -170,9 +170,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "Open folder {displayName}", "Open in Files" : "Open in Files", - "Open file locally" : "Open file locally", - "Failed to redirect to client" : "Failed to redirect to client", "Open locally" : "Open locally", + "Failed to redirect to client" : "Failed to redirect to client", + "Open file locally" : "Open file locally", "Rename" : "Rename", "Open details" : "Open details", "View in folder" : "View in folder", diff --git a/apps/files/l10n/ka.json b/apps/files/l10n/ka.json index afd9e6386d7..b9120314895 100644 --- a/apps/files/l10n/ka.json +++ b/apps/files/l10n/ka.json @@ -168,9 +168,9 @@ "Cancelled move or copy operation" : "Cancelled move or copy operation", "Open folder {displayName}" : "Open folder {displayName}", "Open in Files" : "Open in Files", - "Open file locally" : "Open file locally", - "Failed to redirect to client" : "Failed to redirect to client", "Open locally" : "Open locally", + "Failed to redirect to client" : "Failed to redirect to client", + "Open file locally" : "Open file locally", "Rename" : "Rename", "Open details" : "Open details", "View in folder" : "View in folder", diff --git a/apps/files/l10n/ko.js b/apps/files/l10n/ko.js index a91f928294e..296322c3a90 100644 --- a/apps/files/l10n/ko.js +++ b/apps/files/l10n/ko.js @@ -267,11 +267,11 @@ OC.L10N.register( "Cancelled move or copy operation" : "이동 또는 복사 작업을 취소함", "Open folder {displayName}" : "{displayName} 폴더 열기", "Open in Files" : "파일에서 열기", + "Open locally" : "로컬에서 열기", + "Failed to redirect to client" : "클라이언트로 리디렉션 하는데 실패함", "Open file locally" : "로컬에서 파일 열기", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "이제 이 파일이 당신의 기기에서 열려야 합니다. 그렇지 않다면, 데스크톱 앱이 설치되어 있는지 확인하세요.", "Retry and close" : "재시도 후 닫기", - "Failed to redirect to client" : "클라이언트로 리디렉션 하는데 실패함", - "Open locally" : "로컬에서 열기", "Rename" : "이름 바꾸기", "Open details" : "자세한 정보 열기", "View in folder" : "폴더에서 보기", diff --git a/apps/files/l10n/ko.json b/apps/files/l10n/ko.json index d40c82e850e..94f0888b200 100644 --- a/apps/files/l10n/ko.json +++ b/apps/files/l10n/ko.json @@ -265,11 +265,11 @@ "Cancelled move or copy operation" : "이동 또는 복사 작업을 취소함", "Open folder {displayName}" : "{displayName} 폴더 열기", "Open in Files" : "파일에서 열기", + "Open locally" : "로컬에서 열기", + "Failed to redirect to client" : "클라이언트로 리디렉션 하는데 실패함", "Open file locally" : "로컬에서 파일 열기", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "이제 이 파일이 당신의 기기에서 열려야 합니다. 그렇지 않다면, 데스크톱 앱이 설치되어 있는지 확인하세요.", "Retry and close" : "재시도 후 닫기", - "Failed to redirect to client" : "클라이언트로 리디렉션 하는데 실패함", - "Open locally" : "로컬에서 열기", "Rename" : "이름 바꾸기", "Open details" : "자세한 정보 열기", "View in folder" : "폴더에서 보기", diff --git a/apps/files/l10n/lt_LT.js b/apps/files/l10n/lt_LT.js index 9f5a301df9e..e977378b33b 100644 --- a/apps/files/l10n/lt_LT.js +++ b/apps/files/l10n/lt_LT.js @@ -185,8 +185,8 @@ OC.L10N.register( "Move or copy operation failed" : "Perkėlimo ar kopijavimo operacija patyrė nesėkmę", "Move or copy" : "Perkelti ar kopijuoti", "Open folder {displayName}" : "Atverti aplanką {displayName}", - "Retry and close" : "Bandyti dar kartą ir užverti", "Failed to redirect to client" : "Nepavyko peradresuoti į klientą", + "Retry and close" : "Bandyti dar kartą ir užverti", "Rename" : "Pervadinti", "Open details" : "Atverti išsamesnę informaciją", "View in folder" : "Rodyti aplanke", diff --git a/apps/files/l10n/lt_LT.json b/apps/files/l10n/lt_LT.json index ca5618e0f08..a2495e4f0f5 100644 --- a/apps/files/l10n/lt_LT.json +++ b/apps/files/l10n/lt_LT.json @@ -183,8 +183,8 @@ "Move or copy operation failed" : "Perkėlimo ar kopijavimo operacija patyrė nesėkmę", "Move or copy" : "Perkelti ar kopijuoti", "Open folder {displayName}" : "Atverti aplanką {displayName}", - "Retry and close" : "Bandyti dar kartą ir užverti", "Failed to redirect to client" : "Nepavyko peradresuoti į klientą", + "Retry and close" : "Bandyti dar kartą ir užverti", "Rename" : "Pervadinti", "Open details" : "Atverti išsamesnę informaciją", "View in folder" : "Rodyti aplanke", diff --git a/apps/files/l10n/mk.js b/apps/files/l10n/mk.js index 3f2259cc908..213f0f96325 100644 --- a/apps/files/l10n/mk.js +++ b/apps/files/l10n/mk.js @@ -201,9 +201,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "Откажана операција на копирање или преместување", "Open folder {displayName}" : "Отвори папка {displayName}", "Open in Files" : "Отвори во датотеките", - "Open file locally" : "Отвори ја датотеката локално", - "Failed to redirect to client" : "Неуспешно пренасочување кон клиентот", "Open locally" : "Отвори локално", + "Failed to redirect to client" : "Неуспешно пренасочување кон клиентот", + "Open file locally" : "Отвори ја датотеката локално", "Rename" : "Преименувај", "Open details" : "Отвори детали", "View in folder" : "Погледни во папката", @@ -218,6 +218,7 @@ OC.L10N.register( "Videos" : "Видеа", "Created new folder \"{name}\"" : "Креирана нова папка \"{name}\"", "Unable to initialize the templates directory" : "Не може да се иницијализира папка за шаблони", + "Create templates folder" : "Креирај папка за шаблони", "Templates" : "Шаблони", "One of the dropped files could not be processed" : "Една од испуштените датотеки неможе да се процесоира", "Some files could not be moved" : "Некои датотеки не можат да се преместат", diff --git a/apps/files/l10n/mk.json b/apps/files/l10n/mk.json index f3a3a4f32dc..bfb0df09b99 100644 --- a/apps/files/l10n/mk.json +++ b/apps/files/l10n/mk.json @@ -199,9 +199,9 @@ "Cancelled move or copy operation" : "Откажана операција на копирање или преместување", "Open folder {displayName}" : "Отвори папка {displayName}", "Open in Files" : "Отвори во датотеките", - "Open file locally" : "Отвори ја датотеката локално", - "Failed to redirect to client" : "Неуспешно пренасочување кон клиентот", "Open locally" : "Отвори локално", + "Failed to redirect to client" : "Неуспешно пренасочување кон клиентот", + "Open file locally" : "Отвори ја датотеката локално", "Rename" : "Преименувај", "Open details" : "Отвори детали", "View in folder" : "Погледни во папката", @@ -216,6 +216,7 @@ "Videos" : "Видеа", "Created new folder \"{name}\"" : "Креирана нова папка \"{name}\"", "Unable to initialize the templates directory" : "Не може да се иницијализира папка за шаблони", + "Create templates folder" : "Креирај папка за шаблони", "Templates" : "Шаблони", "One of the dropped files could not be processed" : "Една од испуштените датотеки неможе да се процесоира", "Some files could not be moved" : "Некои датотеки не можат да се преместат", diff --git a/apps/files/l10n/nb.js b/apps/files/l10n/nb.js index e87b6544890..e7972e34eef 100644 --- a/apps/files/l10n/nb.js +++ b/apps/files/l10n/nb.js @@ -248,11 +248,11 @@ OC.L10N.register( "Cancelled move or copy operation" : "Kansellert flytte- eller kopieroperasjon", "Open folder {displayName}" : "Åpne mappe {displayName}", "Open in Files" : "Åpne i Filer", + "Open locally" : "Åpne lokalt", + "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", "Open file locally" : "Åpne fil lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen skal nå åpnes på enheten din. Om ikke, vennligst sjekk at du har skrivebordsprogrammet installert.", "Retry and close" : "Prøv igjen og lukk", - "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", - "Open locally" : "Åpne lokalt", "Rename" : "Gi nytt navn", "Open details" : "Åpne detaljer", "View in folder" : "Vis i mappe", diff --git a/apps/files/l10n/nb.json b/apps/files/l10n/nb.json index 877330c4ebc..3da228e2da7 100644 --- a/apps/files/l10n/nb.json +++ b/apps/files/l10n/nb.json @@ -246,11 +246,11 @@ "Cancelled move or copy operation" : "Kansellert flytte- eller kopieroperasjon", "Open folder {displayName}" : "Åpne mappe {displayName}", "Open in Files" : "Åpne i Filer", + "Open locally" : "Åpne lokalt", + "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", "Open file locally" : "Åpne fil lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen skal nå åpnes på enheten din. Om ikke, vennligst sjekk at du har skrivebordsprogrammet installert.", "Retry and close" : "Prøv igjen og lukk", - "Failed to redirect to client" : "Kunne ikke omdirigere til klienten", - "Open locally" : "Åpne lokalt", "Rename" : "Gi nytt navn", "Open details" : "Åpne detaljer", "View in folder" : "Vis i mappe", diff --git a/apps/files/l10n/nl.js b/apps/files/l10n/nl.js index e0563aaac3c..fcf1ea0ab6e 100644 --- a/apps/files/l10n/nl.js +++ b/apps/files/l10n/nl.js @@ -277,12 +277,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Verplaatsen of kopiëren geannuleerd.", "Open folder {displayName}" : "Open map {displayName}", "Open in Files" : "Open in Bestanden", + "Open locally" : "Lokaal openen", + "Failed to redirect to client" : "Omleiden naar cliënt mislukt", "Open file locally" : "Bestand lokaal openen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Het bestand zou nu moeten openen op je apparaat. Als dat niet het geval is, controleer dan of je de desktop app geïnstalleerd hebt.", "Retry and close" : "Probeer opnieuw en sluiten", "Open online" : "Open online", - "Failed to redirect to client" : "Omleiden naar cliënt mislukt", - "Open locally" : "Lokaal openen", "Rename" : "Naam wijzigen", "Open details" : "Details openen", "View in folder" : "Bekijken in map", diff --git a/apps/files/l10n/nl.json b/apps/files/l10n/nl.json index d7fc7f09003..ae41b7c1376 100644 --- a/apps/files/l10n/nl.json +++ b/apps/files/l10n/nl.json @@ -275,12 +275,12 @@ "Cancelled move or copy operation" : "Verplaatsen of kopiëren geannuleerd.", "Open folder {displayName}" : "Open map {displayName}", "Open in Files" : "Open in Bestanden", + "Open locally" : "Lokaal openen", + "Failed to redirect to client" : "Omleiden naar cliënt mislukt", "Open file locally" : "Bestand lokaal openen", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Het bestand zou nu moeten openen op je apparaat. Als dat niet het geval is, controleer dan of je de desktop app geïnstalleerd hebt.", "Retry and close" : "Probeer opnieuw en sluiten", "Open online" : "Open online", - "Failed to redirect to client" : "Omleiden naar cliënt mislukt", - "Open locally" : "Lokaal openen", "Rename" : "Naam wijzigen", "Open details" : "Details openen", "View in folder" : "Bekijken in map", diff --git a/apps/files/l10n/pl.js b/apps/files/l10n/pl.js index 501c16e77ae..05c5ed0ce51 100644 --- a/apps/files/l10n/pl.js +++ b/apps/files/l10n/pl.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Anulowano operację przenoszenia lub kopiowania", "Open folder {displayName}" : "Otwórz katalog {displayName}", "Open in Files" : "Otwórz w Plikach", + "Open locally" : "Otwórz lokalnie", + "Failed to redirect to client" : "Nie udało się przekierować do klienta", "Open file locally" : "Otwórz plik lokalnie", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Plik powinien teraz otworzyć się na Twoim urządzeniu. Jeśli tak się nie stanie, sprawdź, czy masz zainstalowaną aplikację komputerową.", "Retry and close" : "Spróbuj ponownie i zamknij", "Open online" : "Otwórz online", - "Failed to redirect to client" : "Nie udało się przekierować do klienta", - "Open locally" : "Otwórz lokalnie", "Rename" : "Zmień nazwę", "Open details" : "Otwórz szczegóły", "View in folder" : "Zobacz w katalogu", diff --git a/apps/files/l10n/pl.json b/apps/files/l10n/pl.json index 12338508034..8cd71406922 100644 --- a/apps/files/l10n/pl.json +++ b/apps/files/l10n/pl.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Anulowano operację przenoszenia lub kopiowania", "Open folder {displayName}" : "Otwórz katalog {displayName}", "Open in Files" : "Otwórz w Plikach", + "Open locally" : "Otwórz lokalnie", + "Failed to redirect to client" : "Nie udało się przekierować do klienta", "Open file locally" : "Otwórz plik lokalnie", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Plik powinien teraz otworzyć się na Twoim urządzeniu. Jeśli tak się nie stanie, sprawdź, czy masz zainstalowaną aplikację komputerową.", "Retry and close" : "Spróbuj ponownie i zamknij", "Open online" : "Otwórz online", - "Failed to redirect to client" : "Nie udało się przekierować do klienta", - "Open locally" : "Otwórz lokalnie", "Rename" : "Zmień nazwę", "Open details" : "Otwórz szczegóły", "View in folder" : "Zobacz w katalogu", diff --git a/apps/files/l10n/pt_BR.js b/apps/files/l10n/pt_BR.js index 128b099de9e..1a81b4afd01 100644 --- a/apps/files/l10n/pt_BR.js +++ b/apps/files/l10n/pt_BR.js @@ -244,8 +244,8 @@ OC.L10N.register( "Failed to convert files: {message}" : "Falha ao converter arquivos: {message}", "All files failed to be converted" : "Todos os arquivos falharam na conversão", "One file could not be converted: {message}" : "Um arquivo não pôde ser convertido: {message}", - "_One file could not be converted_::_%n files could not be converted_" : ["Não foi possível converter um arquivo","Não foi possível converter %n arquivos","Não foi possível converter %n arquivos"], - "_One file successfully converted_::_%n files successfully converted_" : ["Um arquivo convertido com sucesso","%n arquivos convertidos com sucesso","%n arquivos convertidos com sucesso"], + "_One file could not be converted_::_%n files could not be converted_" : ["Não foi possível converter um arquivo","Não foi possível converter %n de arquivos","Não foi possível converter %n arquivos"], + "_One file successfully converted_::_%n files successfully converted_" : ["Um arquivo convertido com sucesso","%n de arquivos convertidos com sucesso","%n arquivos convertidos com sucesso"], "Files successfully converted" : "Arquivos convertidos com sucesso", "Failed to convert files" : "Falha ao converter arquivos", "Converting file …" : "Convertendo arquivo …", @@ -264,8 +264,8 @@ OC.L10N.register( "Delete folder" : "Excluir pasta", "Delete folders" : "Excluir pastas", "Delete" : "Excluir", - "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["Você está prestes a excluir permanentemente {count} item","Você está prestes a excluir permanentemente {count} itens","Você está prestes a excluir permanentemente {count} itens"], - "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["Você está prestes a excluir {count} item","Você está prestes a excluir {count} itens","Você está prestes a excluir {count} itens"], + "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["Você está prestes a excluir permanentemente {count} item","Você está prestes a excluir permanentemente {count} de itens","Você está prestes a excluir permanentemente {count} itens"], + "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["Você está prestes a excluir {count} item","Você está prestes a excluir {count} de itens","Você está prestes a excluir {count} itens"], "Confirm deletion" : "Confirmar exclusão", "Cancel" : "Cancelar", "Moving \"{source}\" to \"{destination}\" …" : "Movendo \"{source}\" para \"{destination}\" …", @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Operação de mover ou copiar cancelada", "Open folder {displayName}" : "Abrir a pasta {displayName}", "Open in Files" : "Abrir em Arquivos", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Falha ao redirecionar para o cliente", "Open file locally" : "Abrir o arquivo localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "O arquivo agora deve abrir no seu dispositivo. Caso contrário, verifique se você tem o aplicativo para desktop instalado.", "Retry and close" : "Repetir e fechar", "Open online" : "Abrir on-line", - "Failed to redirect to client" : "Falha ao redirecionar para o cliente", - "Open locally" : "Abrir localmente", "Rename" : "Renomear", "Open details" : "Abrir detalhes", "View in folder" : "Exibir na pasta", @@ -335,9 +335,9 @@ OC.L10N.register( "This directory is unavailable, please check the logs or contact the administrator" : "Este diretório não está disponível, por favor verifique os logs ou contacte o administrador", "Storage is temporarily not available" : "O armazenamento está temporariamente indisponível", "Unexpected error: {error}" : "Erro inesperado: {error}", - "_%n file_::_%n files_" : ["%n arquivo","%n arquivos","%n arquivos"], - "_%n folder_::_%n folders_" : ["%n pasta","%n pastas","%n pastas"], - "_%n hidden_::_%n hidden_" : ["%n oculto","%n ocultos","%n ocultos"], + "_%n file_::_%n files_" : ["%n arquivo","%n de arquivos","%n arquivos"], + "_%n folder_::_%n folders_" : ["%n pasta","%n de pastas","%n pastas"], + "_%n hidden_::_%n hidden_" : ["%n oculto","%n de ocultos","%n ocultos"], "Filename must not be empty." : "O nome do arquivo não pode estar vazio.", "\"{char}\" is not allowed inside a filename." : "\"{char}\" não é permitido dentro de um nome de arquivo.", "\"{segment}\" is a reserved name and not allowed for filenames." : "\"{segment}\" é um nome reservado e não é permitido para nomes de arquivos.", @@ -412,9 +412,9 @@ OC.L10N.register( "No search results in other folders for {tag}{filter}{endtag}" : "Sem resultados de pesquisa em outras pastas para {tag}{filter}{endtag}", "Enter more than two characters to search in other folders" : "Digite mais de dois caracteres para pesquisar em outras pastas", "{dirs} and {files}" : "{dirs} e {files}", - "_including %n hidden_::_including %n hidden_" : ["incluindo %n oculto","incluindo %n ocultos","incluindo %n ocultos"], + "_including %n hidden_::_including %n hidden_" : ["incluindo %n oculto","incluindo %n de ocultos","incluindo %n ocultos"], "You do not have permission to upload or create files here" : "Você não tem permissão para carregar ou criar arquivos aqui", - "_Uploading %n file_::_Uploading %n files_" : ["Enviando %n arquivo","Enviando %n arquivos","Enviando %n arquivos"], + "_Uploading %n file_::_Uploading %n files_" : ["Enviando %n arquivo","Enviando %n de arquivos","Enviando %n arquivos"], "New" : "Novo", "New file/folder menu" : "Menu de novo arquivo/pasta", "Select file range" : "Selecionar o intervalo de arquivos", @@ -432,7 +432,7 @@ OC.L10N.register( "Group folder \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "A pasta de grupo \"{mountPoint}\" está quase cheia ({usedSpacePercent}%).", "External storage \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "O armazenamento externo \"{mountPoint}\" está quase cheio ({usedSpacePercent}%).", "Your storage is almost full ({usedSpacePercent}%)." : "Seu armazenamento está quase cheio ({usedSpacePercent}%).", - "_matches \"{filter}\"_::_match \"{filter}\"_" : ["coincide \"{filter}\"","coincide \"{filter}\"","coincide \"{filter}\""], + "_matches \"{filter}\"_::_match \"{filter}\"_" : ["corresponde a \"{filter}\"","correspondem a \"{filter}\"","correspondem a \"{filter}\""], "Direct link was copied (only works for people who have access to this file/folder)" : "Link direto foi copiado (funciona apenas para pessoas que têm acesso a este arquivo/pasta)", "Path" : "Caminho", "_%n byte_::_%n bytes_" : ["%n byte","%n bytes","%n bytes"], @@ -447,10 +447,10 @@ OC.L10N.register( "Filter filenames…" : "Filtrar nomes de arquivos…", "Edit file locally" : "Editar arquivo localmente", "Edit online" : "Editar on-line", - "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} pasta","{folderCount} pastas","{folderCount} pastas"], - "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} arquivo","{fileCount} arquivos","{fileCount} arquivos"], - "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 arquivo e {folderCount} pasta","1 arquivo e {folderCount} pastas","1 arquivo e {folderCount} pastas"], - "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} arquivo e 1 pasta","{fileCount} arquivos e 1 pasta","{fileCount} arquivos e 1 pasta"], + "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} pasta","{folderCount} de pastas","{folderCount} pastas"], + "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} arquivo","{fileCount} de arquivos","{fileCount} arquivos"], + "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 arquivo e {folderCount} pasta","1 arquivo e {folderCount} de pastas","1 arquivo e {folderCount} pastas"], + "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} arquivo e 1 pasta","{fileCount} de arquivos e 1 pasta","{fileCount} arquivos e 1 pasta"], "{fileCount} files and {folderCount} folders" : "{fileCount} arquivos e {folderCount} pastas", "Personal Files" : "Arquivos pessoais", "Text file" : "Arquivo texto", diff --git a/apps/files/l10n/pt_BR.json b/apps/files/l10n/pt_BR.json index d99df1ee981..1c53429cdeb 100644 --- a/apps/files/l10n/pt_BR.json +++ b/apps/files/l10n/pt_BR.json @@ -242,8 +242,8 @@ "Failed to convert files: {message}" : "Falha ao converter arquivos: {message}", "All files failed to be converted" : "Todos os arquivos falharam na conversão", "One file could not be converted: {message}" : "Um arquivo não pôde ser convertido: {message}", - "_One file could not be converted_::_%n files could not be converted_" : ["Não foi possível converter um arquivo","Não foi possível converter %n arquivos","Não foi possível converter %n arquivos"], - "_One file successfully converted_::_%n files successfully converted_" : ["Um arquivo convertido com sucesso","%n arquivos convertidos com sucesso","%n arquivos convertidos com sucesso"], + "_One file could not be converted_::_%n files could not be converted_" : ["Não foi possível converter um arquivo","Não foi possível converter %n de arquivos","Não foi possível converter %n arquivos"], + "_One file successfully converted_::_%n files successfully converted_" : ["Um arquivo convertido com sucesso","%n de arquivos convertidos com sucesso","%n arquivos convertidos com sucesso"], "Files successfully converted" : "Arquivos convertidos com sucesso", "Failed to convert files" : "Falha ao converter arquivos", "Converting file …" : "Convertendo arquivo …", @@ -262,8 +262,8 @@ "Delete folder" : "Excluir pasta", "Delete folders" : "Excluir pastas", "Delete" : "Excluir", - "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["Você está prestes a excluir permanentemente {count} item","Você está prestes a excluir permanentemente {count} itens","Você está prestes a excluir permanentemente {count} itens"], - "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["Você está prestes a excluir {count} item","Você está prestes a excluir {count} itens","Você está prestes a excluir {count} itens"], + "_You are about to permanently delete {count} item_::_You are about to permanently delete {count} items_" : ["Você está prestes a excluir permanentemente {count} item","Você está prestes a excluir permanentemente {count} de itens","Você está prestes a excluir permanentemente {count} itens"], + "_You are about to delete {count} item_::_You are about to delete {count} items_" : ["Você está prestes a excluir {count} item","Você está prestes a excluir {count} de itens","Você está prestes a excluir {count} itens"], "Confirm deletion" : "Confirmar exclusão", "Cancel" : "Cancelar", "Moving \"{source}\" to \"{destination}\" …" : "Movendo \"{source}\" para \"{destination}\" …", @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Operação de mover ou copiar cancelada", "Open folder {displayName}" : "Abrir a pasta {displayName}", "Open in Files" : "Abrir em Arquivos", + "Open locally" : "Abrir localmente", + "Failed to redirect to client" : "Falha ao redirecionar para o cliente", "Open file locally" : "Abrir o arquivo localmente", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "O arquivo agora deve abrir no seu dispositivo. Caso contrário, verifique se você tem o aplicativo para desktop instalado.", "Retry and close" : "Repetir e fechar", "Open online" : "Abrir on-line", - "Failed to redirect to client" : "Falha ao redirecionar para o cliente", - "Open locally" : "Abrir localmente", "Rename" : "Renomear", "Open details" : "Abrir detalhes", "View in folder" : "Exibir na pasta", @@ -333,9 +333,9 @@ "This directory is unavailable, please check the logs or contact the administrator" : "Este diretório não está disponível, por favor verifique os logs ou contacte o administrador", "Storage is temporarily not available" : "O armazenamento está temporariamente indisponível", "Unexpected error: {error}" : "Erro inesperado: {error}", - "_%n file_::_%n files_" : ["%n arquivo","%n arquivos","%n arquivos"], - "_%n folder_::_%n folders_" : ["%n pasta","%n pastas","%n pastas"], - "_%n hidden_::_%n hidden_" : ["%n oculto","%n ocultos","%n ocultos"], + "_%n file_::_%n files_" : ["%n arquivo","%n de arquivos","%n arquivos"], + "_%n folder_::_%n folders_" : ["%n pasta","%n de pastas","%n pastas"], + "_%n hidden_::_%n hidden_" : ["%n oculto","%n de ocultos","%n ocultos"], "Filename must not be empty." : "O nome do arquivo não pode estar vazio.", "\"{char}\" is not allowed inside a filename." : "\"{char}\" não é permitido dentro de um nome de arquivo.", "\"{segment}\" is a reserved name and not allowed for filenames." : "\"{segment}\" é um nome reservado e não é permitido para nomes de arquivos.", @@ -410,9 +410,9 @@ "No search results in other folders for {tag}{filter}{endtag}" : "Sem resultados de pesquisa em outras pastas para {tag}{filter}{endtag}", "Enter more than two characters to search in other folders" : "Digite mais de dois caracteres para pesquisar em outras pastas", "{dirs} and {files}" : "{dirs} e {files}", - "_including %n hidden_::_including %n hidden_" : ["incluindo %n oculto","incluindo %n ocultos","incluindo %n ocultos"], + "_including %n hidden_::_including %n hidden_" : ["incluindo %n oculto","incluindo %n de ocultos","incluindo %n ocultos"], "You do not have permission to upload or create files here" : "Você não tem permissão para carregar ou criar arquivos aqui", - "_Uploading %n file_::_Uploading %n files_" : ["Enviando %n arquivo","Enviando %n arquivos","Enviando %n arquivos"], + "_Uploading %n file_::_Uploading %n files_" : ["Enviando %n arquivo","Enviando %n de arquivos","Enviando %n arquivos"], "New" : "Novo", "New file/folder menu" : "Menu de novo arquivo/pasta", "Select file range" : "Selecionar o intervalo de arquivos", @@ -430,7 +430,7 @@ "Group folder \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "A pasta de grupo \"{mountPoint}\" está quase cheia ({usedSpacePercent}%).", "External storage \"{mountPoint}\" is almost full ({usedSpacePercent}%)." : "O armazenamento externo \"{mountPoint}\" está quase cheio ({usedSpacePercent}%).", "Your storage is almost full ({usedSpacePercent}%)." : "Seu armazenamento está quase cheio ({usedSpacePercent}%).", - "_matches \"{filter}\"_::_match \"{filter}\"_" : ["coincide \"{filter}\"","coincide \"{filter}\"","coincide \"{filter}\""], + "_matches \"{filter}\"_::_match \"{filter}\"_" : ["corresponde a \"{filter}\"","correspondem a \"{filter}\"","correspondem a \"{filter}\""], "Direct link was copied (only works for people who have access to this file/folder)" : "Link direto foi copiado (funciona apenas para pessoas que têm acesso a este arquivo/pasta)", "Path" : "Caminho", "_%n byte_::_%n bytes_" : ["%n byte","%n bytes","%n bytes"], @@ -445,10 +445,10 @@ "Filter filenames…" : "Filtrar nomes de arquivos…", "Edit file locally" : "Editar arquivo localmente", "Edit online" : "Editar on-line", - "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} pasta","{folderCount} pastas","{folderCount} pastas"], - "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} arquivo","{fileCount} arquivos","{fileCount} arquivos"], - "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 arquivo e {folderCount} pasta","1 arquivo e {folderCount} pastas","1 arquivo e {folderCount} pastas"], - "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} arquivo e 1 pasta","{fileCount} arquivos e 1 pasta","{fileCount} arquivos e 1 pasta"], + "_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} pasta","{folderCount} de pastas","{folderCount} pastas"], + "_{fileCount} file_::_{fileCount} files_" : ["{fileCount} arquivo","{fileCount} de arquivos","{fileCount} arquivos"], + "_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 arquivo e {folderCount} pasta","1 arquivo e {folderCount} de pastas","1 arquivo e {folderCount} pastas"], + "_{fileCount} file and 1 folder_::_{fileCount} files and 1 folder_" : ["{fileCount} arquivo e 1 pasta","{fileCount} de arquivos e 1 pasta","{fileCount} arquivos e 1 pasta"], "{fileCount} files and {folderCount} folders" : "{fileCount} arquivos e {folderCount} pastas", "Personal Files" : "Arquivos pessoais", "Text file" : "Arquivo texto", diff --git a/apps/files/l10n/ru.js b/apps/files/l10n/ru.js index 8aaaccd14ed..18fd0305ef7 100644 --- a/apps/files/l10n/ru.js +++ b/apps/files/l10n/ru.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Копирование или перемещение отменено", "Open folder {displayName}" : "Открыть папку «{displayName}»", "Open in Files" : "Открыть в приложении «Файлы»", + "Open locally" : "Открыть локально", + "Failed to redirect to client" : "Ошибка перенаправления в клиент", "Open file locally" : "Открыть файл локально", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Теперь файл должен открыться на вашем устройстве. Если это не произошло, пожалуйста, убедитесь, что у вас установлено настольное приложение.", "Retry and close" : "Повторить попытку и закрыть", "Open online" : "Открыть онлайн", - "Failed to redirect to client" : "Ошибка перенаправления в клиент", - "Open locally" : "Открыть локально", "Rename" : "Переименовать", "Open details" : "Открыть подробности", "View in folder" : "Посмотреть в каталоге", diff --git a/apps/files/l10n/ru.json b/apps/files/l10n/ru.json index 990e8624982..67706042b9e 100644 --- a/apps/files/l10n/ru.json +++ b/apps/files/l10n/ru.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "Копирование или перемещение отменено", "Open folder {displayName}" : "Открыть папку «{displayName}»", "Open in Files" : "Открыть в приложении «Файлы»", + "Open locally" : "Открыть локально", + "Failed to redirect to client" : "Ошибка перенаправления в клиент", "Open file locally" : "Открыть файл локально", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Теперь файл должен открыться на вашем устройстве. Если это не произошло, пожалуйста, убедитесь, что у вас установлено настольное приложение.", "Retry and close" : "Повторить попытку и закрыть", "Open online" : "Открыть онлайн", - "Failed to redirect to client" : "Ошибка перенаправления в клиент", - "Open locally" : "Открыть локально", "Rename" : "Переименовать", "Open details" : "Открыть подробности", "View in folder" : "Посмотреть в каталоге", diff --git a/apps/files/l10n/sc.js b/apps/files/l10n/sc.js index 4eaf13b42c3..90722be0e4c 100644 --- a/apps/files/l10n/sc.js +++ b/apps/files/l10n/sc.js @@ -160,8 +160,8 @@ OC.L10N.register( "Cancelled move or copy operation" : "Operatzione de tràmuda o còpia annullada", "Open folder {displayName}" : "Aberi sa cartella {displayName}", "Open in Files" : "Aberi in Archìvios", - "Open file locally" : "Aberi s'archìviu in locale", "Open locally" : "Aberi in locale", + "Open file locally" : "Aberi s'archìviu in locale", "Rename" : "Torra a numenare", "Open details" : "Aberi is detàllios", "View in folder" : "Visualiza in sa cartella", diff --git a/apps/files/l10n/sc.json b/apps/files/l10n/sc.json index aabefe1451a..0bdada5e8a7 100644 --- a/apps/files/l10n/sc.json +++ b/apps/files/l10n/sc.json @@ -158,8 +158,8 @@ "Cancelled move or copy operation" : "Operatzione de tràmuda o còpia annullada", "Open folder {displayName}" : "Aberi sa cartella {displayName}", "Open in Files" : "Aberi in Archìvios", - "Open file locally" : "Aberi s'archìviu in locale", "Open locally" : "Aberi in locale", + "Open file locally" : "Aberi s'archìviu in locale", "Rename" : "Torra a numenare", "Open details" : "Aberi is detàllios", "View in folder" : "Visualiza in sa cartella", diff --git a/apps/files/l10n/sk.js b/apps/files/l10n/sk.js index 62343002fb7..d15bd7dd00e 100644 --- a/apps/files/l10n/sk.js +++ b/apps/files/l10n/sk.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Zrušená operácia kopírovania alebo presunu", "Open folder {displayName}" : "Otvoriť priečinok {displayName}", "Open in Files" : "Otvoriť v súboroch", + "Open locally" : "Otvoriť lokálne", + "Failed to redirect to client" : "Nepodarilo sa presmerovať na klienta", "Open file locally" : "Otvoriť súbor lokálne", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Súbor by sa mal teraz otvoriť v zariadení. Ak sa tak nestane, skontrolujte, či máte nainštalovanú aplikáciu pre počítače.", "Retry and close" : "Skúsiť znova a zatvoriť", "Open online" : "Otvoriť online", - "Failed to redirect to client" : "Nepodarilo sa presmerovať na klienta", - "Open locally" : "Otvoriť lokálne", "Rename" : "Premenovať", "Open details" : "Otvoriť detaily", "View in folder" : "Zobraziť v priečinku", diff --git a/apps/files/l10n/sk.json b/apps/files/l10n/sk.json index 30343cf97db..1fe5202ad50 100644 --- a/apps/files/l10n/sk.json +++ b/apps/files/l10n/sk.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "Zrušená operácia kopírovania alebo presunu", "Open folder {displayName}" : "Otvoriť priečinok {displayName}", "Open in Files" : "Otvoriť v súboroch", + "Open locally" : "Otvoriť lokálne", + "Failed to redirect to client" : "Nepodarilo sa presmerovať na klienta", "Open file locally" : "Otvoriť súbor lokálne", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Súbor by sa mal teraz otvoriť v zariadení. Ak sa tak nestane, skontrolujte, či máte nainštalovanú aplikáciu pre počítače.", "Retry and close" : "Skúsiť znova a zatvoriť", "Open online" : "Otvoriť online", - "Failed to redirect to client" : "Nepodarilo sa presmerovať na klienta", - "Open locally" : "Otvoriť lokálne", "Rename" : "Premenovať", "Open details" : "Otvoriť detaily", "View in folder" : "Zobraziť v priečinku", diff --git a/apps/files/l10n/sl.js b/apps/files/l10n/sl.js index e9f36fa49e3..527f11c03d2 100644 --- a/apps/files/l10n/sl.js +++ b/apps/files/l10n/sl.js @@ -281,12 +281,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Opravilo kopiranje in premikanja je preklicano", "Open folder {displayName}" : "Odpri mapo {displayName}", "Open in Files" : "Open in Files", + "Open locally" : "Odpri krajevno", + "Failed to redirect to client" : "Preusmerjanje odjemalca je spodletelo", "Open file locally" : "Odpri datoteko krajevno", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Datoteka bi se sedaj morala odpreti z vaše naprave. Če se to ne zgodi, preverite namestitev namizne aplikacije.", "Retry and close" : "Ponovno poskusi in zapri", "Open online" : "Odpri v brskalniku", - "Failed to redirect to client" : "Preusmerjanje odjemalca je spodletelo", - "Open locally" : "Odpri krajevno", "Rename" : "Preimenuj", "Open details" : "Odpri podrobnosti", "View in folder" : "Pokaži v mapi", diff --git a/apps/files/l10n/sl.json b/apps/files/l10n/sl.json index d7cbd0e10e1..2dece4209a8 100644 --- a/apps/files/l10n/sl.json +++ b/apps/files/l10n/sl.json @@ -279,12 +279,12 @@ "Cancelled move or copy operation" : "Opravilo kopiranje in premikanja je preklicano", "Open folder {displayName}" : "Odpri mapo {displayName}", "Open in Files" : "Open in Files", + "Open locally" : "Odpri krajevno", + "Failed to redirect to client" : "Preusmerjanje odjemalca je spodletelo", "Open file locally" : "Odpri datoteko krajevno", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Datoteka bi se sedaj morala odpreti z vaše naprave. Če se to ne zgodi, preverite namestitev namizne aplikacije.", "Retry and close" : "Ponovno poskusi in zapri", "Open online" : "Odpri v brskalniku", - "Failed to redirect to client" : "Preusmerjanje odjemalca je spodletelo", - "Open locally" : "Odpri krajevno", "Rename" : "Preimenuj", "Open details" : "Odpri podrobnosti", "View in folder" : "Pokaži v mapi", diff --git a/apps/files/l10n/sr.js b/apps/files/l10n/sr.js index 94e709d9248..f4eb40db0f5 100644 --- a/apps/files/l10n/sr.js +++ b/apps/files/l10n/sr.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Операција премештања или копирања је отказана", "Open folder {displayName}" : "Отвори фолдер {displayName}", "Open in Files" : "Отвори у Фајловима", + "Open locally" : "Отвори локално", + "Failed to redirect to client" : "Преусмеравање на клијента није успело", "Open file locally" : "Отвори фајл локално", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Фајл би сада требало да се отвори на вашем уређају. Ако се не отвори, проверите да ли сте инсталирали декстоп апликацију.", "Retry and close" : "Покушај поново и затвори", "Open online" : "Отвори на мрежи", - "Failed to redirect to client" : "Преусмеравање на клијента није успело", - "Open locally" : "Отвори локално", "Rename" : "Преименуј", "Open details" : "Отвори детаље", "View in folder" : "Види у фасцикли", diff --git a/apps/files/l10n/sr.json b/apps/files/l10n/sr.json index 1d19118186c..b5582f24e88 100644 --- a/apps/files/l10n/sr.json +++ b/apps/files/l10n/sr.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Операција премештања или копирања је отказана", "Open folder {displayName}" : "Отвори фолдер {displayName}", "Open in Files" : "Отвори у Фајловима", + "Open locally" : "Отвори локално", + "Failed to redirect to client" : "Преусмеравање на клијента није успело", "Open file locally" : "Отвори фајл локално", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Фајл би сада требало да се отвори на вашем уређају. Ако се не отвори, проверите да ли сте инсталирали декстоп апликацију.", "Retry and close" : "Покушај поново и затвори", "Open online" : "Отвори на мрежи", - "Failed to redirect to client" : "Преусмеравање на клијента није успело", - "Open locally" : "Отвори локално", "Rename" : "Преименуј", "Open details" : "Отвори детаље", "View in folder" : "Види у фасцикли", diff --git a/apps/files/l10n/sv.js b/apps/files/l10n/sv.js index 43acc102eab..58c04d50834 100644 --- a/apps/files/l10n/sv.js +++ b/apps/files/l10n/sv.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Flytta eller kopiera avbröts", "Open folder {displayName}" : "Öppna mappen {displayName}", "Open in Files" : "Öppna i Filer", + "Open locally" : "Öppna lokalt", + "Failed to redirect to client" : "Det gick inte att omdirigera till klienten", "Open file locally" : "Öppna filen lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen bör nu öppnas på din enhet. Om den inte gör det, kontrollera att du har installerat skrivbordsappen.", "Retry and close" : "Försök igen och stäng", "Open online" : "Öppna online", - "Failed to redirect to client" : "Det gick inte att omdirigera till klienten", - "Open locally" : "Öppna lokalt", "Rename" : "Byt namn", "Open details" : "Öppna detaljer", "View in folder" : "Utforska i mapp", diff --git a/apps/files/l10n/sv.json b/apps/files/l10n/sv.json index d2e1bd7f4d4..07063208aa4 100644 --- a/apps/files/l10n/sv.json +++ b/apps/files/l10n/sv.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "Flytta eller kopiera avbröts", "Open folder {displayName}" : "Öppna mappen {displayName}", "Open in Files" : "Öppna i Filer", + "Open locally" : "Öppna lokalt", + "Failed to redirect to client" : "Det gick inte att omdirigera till klienten", "Open file locally" : "Öppna filen lokalt", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Filen bör nu öppnas på din enhet. Om den inte gör det, kontrollera att du har installerat skrivbordsappen.", "Retry and close" : "Försök igen och stäng", "Open online" : "Öppna online", - "Failed to redirect to client" : "Det gick inte att omdirigera till klienten", - "Open locally" : "Öppna lokalt", "Rename" : "Byt namn", "Open details" : "Öppna detaljer", "View in folder" : "Utforska i mapp", diff --git a/apps/files/l10n/tr.js b/apps/files/l10n/tr.js index f15d99f1ed7..7772be56ed8 100644 --- a/apps/files/l10n/tr.js +++ b/apps/files/l10n/tr.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Taşıma ya da kopyalama işlemi iptal edildi", "Open folder {displayName}" : "{displayName} klasörünü aç", "Open in Files" : "Dosyalar uygulamasında aç", + "Open locally" : "Yerel olarak aç", + "Failed to redirect to client" : "İstemciye yönlendirilemedi", "Open file locally" : "Dosyayı yerel olarak aç", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Dosya artık aygıtınızda açılmalıdır. Açılmazsa lütfen masaüstü uygulamasının kurulu olduğundan emin olun.", "Retry and close" : "Yeniden deneyip kapat", "Open online" : "Çevrim içi aç", - "Failed to redirect to client" : "İstemciye yönlendirilemedi", - "Open locally" : "Yerel olarak aç", "Rename" : "Yeniden adlandır", "Open details" : "Ayrıntıları aç", "View in folder" : "Klasörde görüntüle", diff --git a/apps/files/l10n/tr.json b/apps/files/l10n/tr.json index 91591db8821..84185475ce1 100644 --- a/apps/files/l10n/tr.json +++ b/apps/files/l10n/tr.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "Taşıma ya da kopyalama işlemi iptal edildi", "Open folder {displayName}" : "{displayName} klasörünü aç", "Open in Files" : "Dosyalar uygulamasında aç", + "Open locally" : "Yerel olarak aç", + "Failed to redirect to client" : "İstemciye yönlendirilemedi", "Open file locally" : "Dosyayı yerel olarak aç", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Dosya artık aygıtınızda açılmalıdır. Açılmazsa lütfen masaüstü uygulamasının kurulu olduğundan emin olun.", "Retry and close" : "Yeniden deneyip kapat", "Open online" : "Çevrim içi aç", - "Failed to redirect to client" : "İstemciye yönlendirilemedi", - "Open locally" : "Yerel olarak aç", "Rename" : "Yeniden adlandır", "Open details" : "Ayrıntıları aç", "View in folder" : "Klasörde görüntüle", diff --git a/apps/files/l10n/ug.js b/apps/files/l10n/ug.js index 5c828bb4c51..77deefc5a0f 100644 --- a/apps/files/l10n/ug.js +++ b/apps/files/l10n/ug.js @@ -218,9 +218,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "يۆتكەش ياكى كۆچۈرۈش مەشغۇلاتى ئەمەلدىن قالدۇرۇلدى", "Open folder {displayName}" : "ھۆججەت قىسقۇچ {displayName}", "Open in Files" : "ھۆججەتلەرنى ئېچىڭ", - "Open file locally" : "ھۆججەتنى يەرلىكتە ئېچىڭ", - "Failed to redirect to client" : "خېرىدارغا قايتا نىشانلاش مەغلۇپ بولدى", "Open locally" : "يەرلىكتە ئېچىڭ", + "Failed to redirect to client" : "خېرىدارغا قايتا نىشانلاش مەغلۇپ بولدى", + "Open file locally" : "ھۆججەتنى يەرلىكتە ئېچىڭ", "Rename" : "ئات ئۆزگەرت", "Open details" : "تەپسىلاتلارنى ئېچىڭ", "View in folder" : "قىسقۇچتا كۆرۈش", diff --git a/apps/files/l10n/ug.json b/apps/files/l10n/ug.json index bd7dae0388f..e8cf0bf212a 100644 --- a/apps/files/l10n/ug.json +++ b/apps/files/l10n/ug.json @@ -216,9 +216,9 @@ "Cancelled move or copy operation" : "يۆتكەش ياكى كۆچۈرۈش مەشغۇلاتى ئەمەلدىن قالدۇرۇلدى", "Open folder {displayName}" : "ھۆججەت قىسقۇچ {displayName}", "Open in Files" : "ھۆججەتلەرنى ئېچىڭ", - "Open file locally" : "ھۆججەتنى يەرلىكتە ئېچىڭ", - "Failed to redirect to client" : "خېرىدارغا قايتا نىشانلاش مەغلۇپ بولدى", "Open locally" : "يەرلىكتە ئېچىڭ", + "Failed to redirect to client" : "خېرىدارغا قايتا نىشانلاش مەغلۇپ بولدى", + "Open file locally" : "ھۆججەتنى يەرلىكتە ئېچىڭ", "Rename" : "ئات ئۆزگەرت", "Open details" : "تەپسىلاتلارنى ئېچىڭ", "View in folder" : "قىسقۇچتا كۆرۈش", diff --git a/apps/files/l10n/uk.js b/apps/files/l10n/uk.js index e565adfc9de..991e9aef5a1 100644 --- a/apps/files/l10n/uk.js +++ b/apps/files/l10n/uk.js @@ -279,12 +279,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "Переміщення або копіювання скасовано", "Open folder {displayName}" : "Відкрити каталог {displayName}", "Open in Files" : "Відкрити у Файлах", + "Open locally" : "Відкрити локально", + "Failed to redirect to client" : "Не вдалося перенаправити на клієнта", "Open file locally" : "Відкрити файл локально", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Тепер файл можна відкрити на вашому пристрої. Якщо він не відкривається, перевірте, що у вас встановлено настільний клієнт синхронізації.", "Retry and close" : "Спробувати ще раз", "Open online" : "Відкрити віддалено", - "Failed to redirect to client" : "Не вдалося перенаправити на клієнта", - "Open locally" : "Відкрити локально", "Rename" : "Перейменувати", "Open details" : "Показати деталі", "View in folder" : "Переглянути у каталозі", diff --git a/apps/files/l10n/uk.json b/apps/files/l10n/uk.json index e133f666763..d0b104bac89 100644 --- a/apps/files/l10n/uk.json +++ b/apps/files/l10n/uk.json @@ -277,12 +277,12 @@ "Cancelled move or copy operation" : "Переміщення або копіювання скасовано", "Open folder {displayName}" : "Відкрити каталог {displayName}", "Open in Files" : "Відкрити у Файлах", + "Open locally" : "Відкрити локально", + "Failed to redirect to client" : "Не вдалося перенаправити на клієнта", "Open file locally" : "Відкрити файл локально", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Тепер файл можна відкрити на вашому пристрої. Якщо він не відкривається, перевірте, що у вас встановлено настільний клієнт синхронізації.", "Retry and close" : "Спробувати ще раз", "Open online" : "Відкрити віддалено", - "Failed to redirect to client" : "Не вдалося перенаправити на клієнта", - "Open locally" : "Відкрити локально", "Rename" : "Перейменувати", "Open details" : "Показати деталі", "View in folder" : "Переглянути у каталозі", diff --git a/apps/files/l10n/vi.js b/apps/files/l10n/vi.js index 475bafe02f5..a2504192d8d 100644 --- a/apps/files/l10n/vi.js +++ b/apps/files/l10n/vi.js @@ -219,9 +219,9 @@ OC.L10N.register( "Cancelled move or copy operation" : "Đã hủy thao tác di chuyển hoặc sao chép", "Open folder {displayName}" : "Mở thư mục {displayName}", "Open in Files" : "Mở trong Tệp", - "Open file locally" : "Mở tệp cục bộ (local)/ ngoại tuyến", - "Failed to redirect to client" : "Không thể chuyển hướng đến ứng dụng khách", "Open locally" : "Mở cục bộ (local)/ ngoại tuyến", + "Failed to redirect to client" : "Không thể chuyển hướng đến ứng dụng khách", + "Open file locally" : "Mở tệp cục bộ (local)/ ngoại tuyến", "Rename" : "Đổi tên", "Open details" : "Mở chi tiết", "View in folder" : "Xem trong thư mục", diff --git a/apps/files/l10n/vi.json b/apps/files/l10n/vi.json index 0e11bbac94d..9ea384d4147 100644 --- a/apps/files/l10n/vi.json +++ b/apps/files/l10n/vi.json @@ -217,9 +217,9 @@ "Cancelled move or copy operation" : "Đã hủy thao tác di chuyển hoặc sao chép", "Open folder {displayName}" : "Mở thư mục {displayName}", "Open in Files" : "Mở trong Tệp", - "Open file locally" : "Mở tệp cục bộ (local)/ ngoại tuyến", - "Failed to redirect to client" : "Không thể chuyển hướng đến ứng dụng khách", "Open locally" : "Mở cục bộ (local)/ ngoại tuyến", + "Failed to redirect to client" : "Không thể chuyển hướng đến ứng dụng khách", + "Open file locally" : "Mở tệp cục bộ (local)/ ngoại tuyến", "Rename" : "Đổi tên", "Open details" : "Mở chi tiết", "View in folder" : "Xem trong thư mục", diff --git a/apps/files/l10n/zh_CN.js b/apps/files/l10n/zh_CN.js index 69d0b69c945..36816fb1814 100644 --- a/apps/files/l10n/zh_CN.js +++ b/apps/files/l10n/zh_CN.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "已取消移动或复制操作", "Open folder {displayName}" : "打开文件夹{displayName}", "Open in Files" : "在文件中打开", + "Open locally" : "本地打开", + "Failed to redirect to client" : "重定向到客户端失败", "Open file locally" : "在本地打开文件", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "该文件现在应该在你的设备上打开。如果没有,请检查你是否安装了桌面应用程序。", "Retry and close" : "重试并关闭", "Open online" : "在线打开", - "Failed to redirect to client" : "重定向到客户端失败", - "Open locally" : "本地打开", "Rename" : "重命名", "Open details" : "打开详情", "View in folder" : "在文件夹中查看", diff --git a/apps/files/l10n/zh_CN.json b/apps/files/l10n/zh_CN.json index d3fb7b565e8..fbd76bc8be9 100644 --- a/apps/files/l10n/zh_CN.json +++ b/apps/files/l10n/zh_CN.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "已取消移动或复制操作", "Open folder {displayName}" : "打开文件夹{displayName}", "Open in Files" : "在文件中打开", + "Open locally" : "本地打开", + "Failed to redirect to client" : "重定向到客户端失败", "Open file locally" : "在本地打开文件", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "该文件现在应该在你的设备上打开。如果没有,请检查你是否安装了桌面应用程序。", "Retry and close" : "重试并关闭", "Open online" : "在线打开", - "Failed to redirect to client" : "重定向到客户端失败", - "Open locally" : "本地打开", "Rename" : "重命名", "Open details" : "打开详情", "View in folder" : "在文件夹中查看", diff --git a/apps/files/l10n/zh_HK.js b/apps/files/l10n/zh_HK.js index 0eb38d5a429..e4cef2fa393 100644 --- a/apps/files/l10n/zh_HK.js +++ b/apps/files/l10n/zh_HK.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "已取消移動或複製操作", "Open folder {displayName}" : "打開資料夾 {displayName}", "Open in Files" : "在「檔案」應用程式中打開", + "Open locally" : "在近端打開", + "Failed to redirect to client" : "無法重定向到客戶端", "Open file locally" : "在近端打開檔案", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "檔案現在應該在您的裝置上打開。如果沒有,請檢查您是否已安裝桌面應用程式。", "Retry and close" : "重試和關閉", "Open online" : "線上開啟", - "Failed to redirect to client" : "無法重定向到客戶端", - "Open locally" : "在近端打開", "Rename" : "重新命名", "Open details" : "開啟細節", "View in folder" : "在資料夾中檢視", diff --git a/apps/files/l10n/zh_HK.json b/apps/files/l10n/zh_HK.json index 8276f7ec957..f3cb90bc6d3 100644 --- a/apps/files/l10n/zh_HK.json +++ b/apps/files/l10n/zh_HK.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "已取消移動或複製操作", "Open folder {displayName}" : "打開資料夾 {displayName}", "Open in Files" : "在「檔案」應用程式中打開", + "Open locally" : "在近端打開", + "Failed to redirect to client" : "無法重定向到客戶端", "Open file locally" : "在近端打開檔案", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "檔案現在應該在您的裝置上打開。如果沒有,請檢查您是否已安裝桌面應用程式。", "Retry and close" : "重試和關閉", "Open online" : "線上開啟", - "Failed to redirect to client" : "無法重定向到客戶端", - "Open locally" : "在近端打開", "Rename" : "重新命名", "Open details" : "開啟細節", "View in folder" : "在資料夾中檢視", diff --git a/apps/files/l10n/zh_TW.js b/apps/files/l10n/zh_TW.js index f9f0c84aa79..20c0848d1e8 100644 --- a/apps/files/l10n/zh_TW.js +++ b/apps/files/l10n/zh_TW.js @@ -288,12 +288,12 @@ OC.L10N.register( "Cancelled move or copy operation" : "已取消移動或複製操作", "Open folder {displayName}" : "開啟資料夾 {displayName}", "Open in Files" : "以「檔案」開啟", + "Open locally" : "在本機開啟", + "Failed to redirect to client" : "重新導向到客戶端失敗", "Open file locally" : "在本機開啟檔案", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "檔案現在應該可以在您的裝置上開啟。如果打不開,請檢查您是否有安裝桌面應用程式。", "Retry and close" : "重試並關閉", "Open online" : "線上開啟", - "Failed to redirect to client" : "重新導向到客戶端失敗", - "Open locally" : "在本機開啟", "Rename" : "重新命名", "Open details" : "開啟詳細資訊", "View in folder" : "在資料夾中檢視", diff --git a/apps/files/l10n/zh_TW.json b/apps/files/l10n/zh_TW.json index ee9ff0a91c6..1a129a968b9 100644 --- a/apps/files/l10n/zh_TW.json +++ b/apps/files/l10n/zh_TW.json @@ -286,12 +286,12 @@ "Cancelled move or copy operation" : "已取消移動或複製操作", "Open folder {displayName}" : "開啟資料夾 {displayName}", "Open in Files" : "以「檔案」開啟", + "Open locally" : "在本機開啟", + "Failed to redirect to client" : "重新導向到客戶端失敗", "Open file locally" : "在本機開啟檔案", "The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "檔案現在應該可以在您的裝置上開啟。如果打不開,請檢查您是否有安裝桌面應用程式。", "Retry and close" : "重試並關閉", "Open online" : "線上開啟", - "Failed to redirect to client" : "重新導向到客戶端失敗", - "Open locally" : "在本機開啟", "Rename" : "重新命名", "Open details" : "開啟詳細資訊", "View in folder" : "在資料夾中檢視", diff --git a/apps/files/lib/Listener/SyncLivePhotosListener.php b/apps/files/lib/Listener/SyncLivePhotosListener.php index 6334e5d16a6..b6773e8c452 100644 --- a/apps/files/lib/Listener/SyncLivePhotosListener.php +++ b/apps/files/lib/Listener/SyncLivePhotosListener.php @@ -37,6 +37,8 @@ class SyncLivePhotosListener implements IEventListener { private array $pendingRenames = []; /** @var Array<int, bool> */ private array $pendingDeletion = []; + /** @var Array<int> */ + private array $pendingCopies = []; public function __construct( private ?Folder $userFolder, @@ -153,7 +155,6 @@ class SyncLivePhotosListener implements IEventListener { $targetName = $targetFile->getName(); $peerTargetName = substr($targetName, 0, -strlen($sourceExtension)) . $peerFileExtension; - if ($targetParent->nodeExists($peerTargetName)) { // If the copy was a folder copy, then the peer file already exists. $targetPeerFile = $targetParent->get($peerTargetName); @@ -225,6 +226,11 @@ class SyncLivePhotosListener implements IEventListener { $this->handleCopyRecursive($event, $sourceChild, $targetChild); } } elseif ($sourceNode instanceof File && $targetNode instanceof File) { + // in case the copy was initiated from this listener, we stop right now + if (in_array($sourceNode->getId(), $this->pendingCopies)) { + return; + } + $peerFileId = $this->livePhotosService->getLivePhotoPeerId($sourceNode->getId()); if ($peerFileId === null) { return; @@ -234,11 +240,13 @@ class SyncLivePhotosListener implements IEventListener { return; } + $this->pendingCopies[] = $peerFileId; if ($event instanceof BeforeNodeCopiedEvent) { $this->runMoveOrCopyChecks($sourceNode, $targetNode, $peerFile); } elseif ($event instanceof NodeCopiedEvent) { $this->handleCopy($sourceNode, $targetNode, $peerFile); } + $this->pendingCopies = array_diff($this->pendingCopies, [$peerFileId]); } else { throw new Exception('Source and target type are not matching'); } diff --git a/apps/files/src/actions/openLocallyAction.ts b/apps/files/src/actions/openLocallyAction.ts index a80cf0cbeed..986b304210c 100644 --- a/apps/files/src/actions/openLocallyAction.ts +++ b/apps/files/src/actions/openLocallyAction.ts @@ -13,71 +13,6 @@ import LaptopSvg from '@mdi/svg/svg/laptop.svg?raw' import IconWeb from '@mdi/svg/svg/web.svg?raw' import { isPublicShare } from '@nextcloud/sharing/public' -const confirmLocalEditDialog = ( - localEditCallback: (openingLocally: boolean) => void = () => {}, -) => { - let callbackCalled = false - - return (new DialogBuilder()) - .setName(t('files', 'Open file locally')) - .setText(t('files', 'The file should now open on your device. If it doesn\'t, please check that you have the desktop app installed.')) - .setButtons([ - { - label: t('files', 'Retry and close'), - type: 'secondary', - callback: () => { - callbackCalled = true - localEditCallback(true) - }, - }, - { - label: t('files', 'Open online'), - icon: IconWeb, - type: 'primary', - callback: () => { - callbackCalled = true - localEditCallback(false) - }, - }, - ]) - .build() - .show() - .then(() => { - // Ensure the callback is called even if the dialog is dismissed in other ways - if (!callbackCalled) { - localEditCallback(false) - } - }) -} - -const attemptOpenLocalClient = async (path: string) => { - openLocalClient(path) - confirmLocalEditDialog( - (openLocally: boolean) => { - if (!openLocally) { - window.OCA.Viewer.open({ path }) - return - } - openLocalClient(path) - }, - ) -} - -const openLocalClient = async function(path: string) { - const link = generateOcsUrl('apps/files/api/v1') + '/openlocaleditor?format=json' - - try { - const result = await axios.post(link, { path }) - const uid = getCurrentUser()?.uid - let url = `nc://open/${uid}@` + window.location.host + encodePath(path) - url += '?token=' + result.data.ocs.data.token - - window.open(url, '_self') - } catch (error) { - showError(t('files', 'Failed to redirect to client')) - } -} - export const action = new FileAction({ id: 'edit-locally', displayName: () => t('files', 'Open locally'), @@ -99,9 +34,81 @@ export const action = new FileAction({ }, async exec(node: Node) { - attemptOpenLocalClient(node.path) + await attemptOpenLocalClient(node.path) return null }, order: 25, }) + +/** + * Try to open the path in the Nextcloud client. + * + * If this fails a dialog is shown with 3 options: + * 1. Retry: If it fails no further dialog is shown. + * 2. Open online: The viewer is used to open the file. + * 3. Close the dialog and nothing happens (abort). + * + * @param path - The path to open + */ +async function attemptOpenLocalClient(path: string) { + await openLocalClient(path) + const result = await confirmLocalEditDialog() + if (result === 'local') { + await openLocalClient(path) + } else if (result === 'online') { + window.OCA.Viewer.open({ path }) + } +} + +/** + * Try to open a file in the Nextcloud client. + * There is no way to get notified if this action was successfull. + * + * @param path - Path to open + */ +async function openLocalClient(path: string): Promise<void> { + const link = generateOcsUrl('apps/files/api/v1') + '/openlocaleditor?format=json' + + try { + const result = await axios.post(link, { path }) + const uid = getCurrentUser()?.uid + let url = `nc://open/${uid}@` + window.location.host + encodePath(path) + url += '?token=' + result.data.ocs.data.token + + window.open(url, '_self') + } catch (error) { + showError(t('files', 'Failed to redirect to client')) + } +} + +/** + * Open the confirmation dialog. + */ +async function confirmLocalEditDialog(): Promise<'online'|'local'|false> { + let result: 'online'|'local'|false = false + const dialog = (new DialogBuilder()) + .setName(t('files', 'Open file locally')) + .setText(t('files', 'The file should now open on your device. If it doesn\'t, please check that you have the desktop app installed.')) + .setButtons([ + { + label: t('files', 'Retry and close'), + type: 'secondary', + callback: () => { + result = 'local' + }, + }, + { + label: t('files', 'Open online'), + icon: IconWeb, + type: 'primary', + callback: () => { + result = 'online' + }, + }, + ]) + .build() + + await dialog.show() + return result +} diff --git a/apps/files/tests/Activity/Filter/GenericTest.php b/apps/files/tests/Activity/Filter/GenericTest.php index dbb2538ed8a..f37a1cb2c9e 100644 --- a/apps/files/tests/Activity/Filter/GenericTest.php +++ b/apps/files/tests/Activity/Filter/GenericTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -18,7 +20,7 @@ use Test\TestCase; * @group DB */ class GenericTest extends TestCase { - public function dataFilters() { + public static function dataFilters(): array { return [ [Favorites::class], [FileChanges::class], @@ -27,18 +29,16 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testImplementsInterface($filterClass): void { + public function testImplementsInterface(string $filterClass): void { $filter = Server::get($filterClass); $this->assertInstanceOf(IFilter::class, $filter); } /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testGetIdentifier($filterClass): void { + public function testGetIdentifier(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $this->assertIsString($filter->getIdentifier()); @@ -46,9 +46,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testGetName($filterClass): void { + public function testGetName(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $this->assertIsString($filter->getName()); @@ -56,9 +55,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testGetPriority($filterClass): void { + public function testGetPriority(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $priority = $filter->getPriority(); @@ -69,9 +67,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testGetIcon($filterClass): void { + public function testGetIcon(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $this->assertIsString($filter->getIcon()); @@ -80,9 +77,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testFilterTypes($filterClass): void { + public function testFilterTypes(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $this->assertIsArray($filter->filterTypes([])); @@ -90,9 +86,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataFilters - * @param string $filterClass */ - public function testAllowedApps($filterClass): void { + public function testAllowedApps(string $filterClass): void { /** @var IFilter $filter */ $filter = Server::get($filterClass); $this->assertIsArray($filter->allowedApps()); diff --git a/apps/files/tests/Activity/ProviderTest.php b/apps/files/tests/Activity/ProviderTest.php index 7b91e980842..ed52c76ba28 100644 --- a/apps/files/tests/Activity/ProviderTest.php +++ b/apps/files/tests/Activity/ProviderTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -26,23 +28,14 @@ use Test\TestCase; * @package OCA\Files\Tests\Activity */ class ProviderTest extends TestCase { - - /** @var IFactory|MockObject */ - protected $l10nFactory; - /** @var IURLGenerator|MockObject */ - protected $url; - /** @var IManager|MockObject */ - protected $activityManager; - /** @var IUserManager|MockObject */ - protected $userManager; - /** @var IRootFolder|MockObject */ - protected $rootFolder; - /** @var ICloudIdManager|MockObject */ - protected $cloudIdManager; - /** @var IContactsManager|MockObject */ - protected $contactsManager; - /** @var IEventMerger|MockObject */ - protected $eventMerger; + protected IFactory&MockObject $l10nFactory; + protected IURLGenerator&MockObject $url; + protected IManager&MockObject $activityManager; + protected IUserManager&MockObject $userManager; + protected IRootFolder&MockObject $rootFolder; + protected ICloudIdManager&MockObject $cloudIdManager; + protected IContactsManager&MockObject $contactsManager; + protected IEventMerger&MockObject $eventMerger; protected function setUp(): void { parent::setUp(); @@ -74,7 +67,7 @@ class ProviderTest extends TestCase { $this->contactsManager, $this->eventMerger, ]) - ->setMethods($methods) + ->onlyMethods($methods) ->getMock(); } return new Provider( @@ -89,7 +82,7 @@ class ProviderTest extends TestCase { ); } - public function dataGetFile() { + public static function dataGetFile(): array { return [ [[42 => '/FortyTwo.txt'], null, '42', 'FortyTwo.txt', 'FortyTwo.txt'], [['23' => '/Twenty/Three.txt'], null, '23', 'Three.txt', 'Twenty/Three.txt'], @@ -99,13 +92,8 @@ class ProviderTest extends TestCase { /** * @dataProvider dataGetFile - * @param mixed $parameter - * @param mixed $eventId - * @param int $id - * @param string $name - * @param string $path */ - public function testGetFile($parameter, $eventId, $id, $name, $path): void { + public function testGetFile(array|string $parameter, ?int $eventId, string $id, string $name, string $path): void { $provider = $this->getProvider(); if ($eventId !== null) { @@ -139,7 +127,7 @@ class ProviderTest extends TestCase { self::invokePrivate($provider, 'getFile', ['/Foo/Bar.txt', null]); } - public function dataGetUser() { + public static function dataGetUser(): array { return [ ['test', 'Test user', null, ['type' => 'user', 'id' => 'test', 'name' => 'Test user']], ['test@http://localhost', null, ['user' => 'test', 'displayId' => 'test@localhost', 'remote' => 'localhost', 'name' => null], ['type' => 'user', 'id' => 'test', 'name' => 'test@localhost', 'server' => 'localhost']], @@ -150,10 +138,6 @@ class ProviderTest extends TestCase { /** * @dataProvider dataGetUser - * @param string $uid - * @param string|null $userDisplayName - * @param array|null $cloudIdData - * @param array $expected */ public function testGetUser(string $uid, ?string $userDisplayName, ?array $cloudIdData, array $expected): void { $provider = $this->getProvider(); diff --git a/apps/files/tests/Activity/Setting/GenericTest.php b/apps/files/tests/Activity/Setting/GenericTest.php index 1dc551be927..7e549ce9dc0 100644 --- a/apps/files/tests/Activity/Setting/GenericTest.php +++ b/apps/files/tests/Activity/Setting/GenericTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,7 +14,7 @@ use OCP\Server; use Test\TestCase; class GenericTest extends TestCase { - public function dataSettings() { + public static function dataSettings(): array { return [ [FavoriteAction::class], [FileChanged::class], @@ -22,18 +24,16 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testImplementsInterface($settingClass): void { + public function testImplementsInterface(string $settingClass): void { $setting = Server::get($settingClass); $this->assertInstanceOf(ISetting::class, $setting); } /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testGetIdentifier($settingClass): void { + public function testGetIdentifier(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsString($setting->getIdentifier()); @@ -41,9 +41,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testGetName($settingClass): void { + public function testGetName(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsString($setting->getName()); @@ -51,9 +50,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testGetPriority($settingClass): void { + public function testGetPriority(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $priority = $setting->getPriority(); @@ -64,9 +62,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testCanChangeStream($settingClass): void { + public function testCanChangeStream(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsBool($setting->canChangeStream()); @@ -74,9 +71,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testIsDefaultEnabledStream($settingClass): void { + public function testIsDefaultEnabledStream(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsBool($setting->isDefaultEnabledStream()); @@ -84,9 +80,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testCanChangeMail($settingClass): void { + public function testCanChangeMail(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsBool($setting->canChangeMail()); @@ -94,9 +89,8 @@ class GenericTest extends TestCase { /** * @dataProvider dataSettings - * @param string $settingClass */ - public function testIsDefaultEnabledMail($settingClass): void { + public function testIsDefaultEnabledMail(string $settingClass): void { /** @var ISetting $setting */ $setting = Server::get($settingClass); $this->assertIsBool($setting->isDefaultEnabledMail()); diff --git a/apps/files/tests/AdvancedCapabilitiesTest.php b/apps/files/tests/AdvancedCapabilitiesTest.php index af38c51a4a2..8f4a845b708 100644 --- a/apps/files/tests/AdvancedCapabilitiesTest.php +++ b/apps/files/tests/AdvancedCapabilitiesTest.php @@ -18,6 +18,7 @@ class AdvancedCapabilitiesTest extends TestCase { protected AdvancedCapabilities $capabilities; protected function setUp(): void { + parent::setUp(); $this->service = $this->createMock(SettingsService::class); $this->capabilities = new AdvancedCapabilities($this->service); } diff --git a/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php b/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php index e31b1574815..3f811fca407 100644 --- a/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php +++ b/apps/files/tests/BackgroundJob/DeleteOrphanedItemsJobTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -33,16 +34,16 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $this->logger = Server::get(LoggerInterface::class); } - protected function cleanMapping($table) { + protected function cleanMapping(string $table): void { $query = $this->connection->getQueryBuilder(); - $query->delete($table)->execute(); + $query->delete($table)->executeStatement(); } - protected function getMappings($table) { + protected function getMappings(string $table): array { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from($table); - $result = $query->execute(); + $result = $query->executeQuery(); $mapping = $result->fetchAll(); $result->closeCursor(); @@ -61,7 +62,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -71,7 +72,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objectid' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'objecttype' => $query->createNamedParameter('files'), 'systemtagid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -80,13 +81,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objectid' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'objecttype' => $query->createNamedParameter('files'), 'systemtagid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('systemtag_object_mapping'); $this->assertCount(2, $mapping); $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); - $this->invokePrivate($job, 'cleanSystemTags'); + self::invokePrivate($job, 'cleanSystemTags'); $mapping = $this->getMappings('systemtag_object_mapping'); $this->assertCount(1, $mapping); @@ -94,7 +95,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('systemtag_object_mapping'); } @@ -110,7 +111,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -120,7 +121,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objid' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'type' => $query->createNamedParameter('files'), 'categoryid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -129,13 +130,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'objid' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'type' => $query->createNamedParameter('files'), 'categoryid' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('vcategory_to_object'); $this->assertCount(2, $mapping); $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); - $this->invokePrivate($job, 'cleanUserTags'); + self::invokePrivate($job, 'cleanUserTags'); $mapping = $this->getMappings('vcategory_to_object'); $this->assertCount(1, $mapping); @@ -143,7 +144,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('vcategory_to_object'); } @@ -159,7 +160,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -170,7 +171,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_type' => $query->createNamedParameter('files'), 'actor_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), 'actor_type' => $query->createNamedParameter('users'), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -180,13 +181,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_type' => $query->createNamedParameter('files'), 'actor_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), 'actor_type' => $query->createNamedParameter('users'), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('comments'); $this->assertCount(2, $mapping); $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); - $this->invokePrivate($job, 'cleanComments'); + self::invokePrivate($job, 'cleanComments'); $mapping = $this->getMappings('comments'); $this->assertCount(1, $mapping); @@ -194,7 +195,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('comments'); } @@ -210,7 +211,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'storage' => $query->createNamedParameter(1337, IQueryBuilder::PARAM_INT), 'path' => $query->createNamedParameter('apps/files/tests/deleteorphanedtagsjobtest.php'), 'path_hash' => $query->createNamedParameter(md5('apps/files/tests/deleteorphanedtagsjobtest.php')), - ])->execute(); + ])->executeStatement(); $fileId = $query->getLastInsertId(); // Existing file @@ -220,7 +221,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_id' => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), 'object_type' => $query->createNamedParameter('files'), 'user_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); // Non-existing file $query = $this->connection->getQueryBuilder(); @@ -229,13 +230,13 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { 'object_id' => $query->createNamedParameter($fileId + 1, IQueryBuilder::PARAM_INT), 'object_type' => $query->createNamedParameter('files'), 'user_id' => $query->createNamedParameter('Alice', IQueryBuilder::PARAM_INT), - ])->execute(); + ])->executeStatement(); $mapping = $this->getMappings('comments_read_markers'); $this->assertCount(2, $mapping); $job = new DeleteOrphanedItems($this->timeFactory, $this->connection, $this->logger); - $this->invokePrivate($job, 'cleanCommentMarkers'); + self::invokePrivate($job, 'cleanCommentMarkers'); $mapping = $this->getMappings('comments_read_markers'); $this->assertCount(1, $mapping); @@ -243,7 +244,7 @@ class DeleteOrphanedItemsJobTest extends \Test\TestCase { $query = $this->connection->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))) - ->execute(); + ->executeStatement(); $this->cleanMapping('comments_read_markers'); } } diff --git a/apps/files/tests/BackgroundJob/ScanFilesTest.php b/apps/files/tests/BackgroundJob/ScanFilesTest.php index ce602805aa2..00d9ed823f9 100644 --- a/apps/files/tests/BackgroundJob/ScanFilesTest.php +++ b/apps/files/tests/BackgroundJob/ScanFilesTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -32,10 +33,8 @@ class ScanFilesTest extends TestCase { use UserTrait; use MountProviderTrait; - /** @var ScanFiles */ - private $scanFiles; - /** @var IUserMountCache */ - private $mountCache; + private ScanFiles $scanFiles; + private IUserMountCache $mountCache; protected function setUp(): void { parent::setUp(); @@ -46,7 +45,7 @@ class ScanFilesTest extends TestCase { $connection = Server::get(IDBConnection::class); $this->mountCache = Server::get(IUserMountCache::class); - $this->scanFiles = $this->getMockBuilder('\OCA\Files\BackgroundJob\ScanFiles') + $this->scanFiles = $this->getMockBuilder(ScanFiles::class) ->setConstructorArgs([ $config, $dispatcher, @@ -54,12 +53,12 @@ class ScanFilesTest extends TestCase { $connection, $this->createMock(ITimeFactory::class) ]) - ->setMethods(['runScanner']) + ->onlyMethods(['runScanner']) ->getMock(); } - private function runJob() { - $this->invokePrivate($this->scanFiles, 'run', [[]]); + private function runJob(): void { + self::invokePrivate($this->scanFiles, 'run', [[]]); } private function getUser(string $userId): IUser { diff --git a/apps/files/tests/Command/DeleteOrphanedFilesTest.php b/apps/files/tests/Command/DeleteOrphanedFilesTest.php index 389ede2a74d..54b5ac6c12f 100644 --- a/apps/files/tests/Command/DeleteOrphanedFilesTest.php +++ b/apps/files/tests/Command/DeleteOrphanedFilesTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -56,7 +57,7 @@ class DeleteOrphanedFilesTest extends TestCase { parent::tearDown(); } - protected function getFile($fileId) { + protected function getFile(int $fileId): array { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('filecache') @@ -64,7 +65,7 @@ class DeleteOrphanedFilesTest extends TestCase { return $query->executeQuery()->fetchAll(); } - protected function getMounts($storageId) { + protected function getMounts(int $storageId): array { $query = $this->connection->getQueryBuilder(); $query->select('*') ->from('mounts') @@ -76,12 +77,8 @@ class DeleteOrphanedFilesTest extends TestCase { * Test clearing orphaned files */ public function testClearFiles(): void { - $input = $this->getMockBuilder(InputInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $output = $this->getMockBuilder(OutputInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $input = $this->createMock(InputInterface::class); + $output = $this->createMock(OutputInterface::class); $rootFolder = Server::get(IRootFolder::class); @@ -112,14 +109,18 @@ class DeleteOrphanedFilesTest extends TestCase { $this->assertSame(1, $deletedRows, 'Asserts that storage got deleted'); // parent folder, `files`, ´test` and `welcome.txt` => 4 elements + $calls = [ + '3 orphaned file cache entries deleted', + '0 orphaned file cache extended entries deleted', + '1 orphaned mount entries deleted', + ]; $output ->expects($this->exactly(3)) ->method('writeln') - ->withConsecutive( - ['3 orphaned file cache entries deleted'], - ['0 orphaned file cache extended entries deleted'], - ['1 orphaned mount entries deleted'], - ); + ->willReturnCallback(function (string $message) use (&$calls) { + $expected = array_shift($calls); + $this->assertSame($expected, $message); + }); $this->command->execute($input, $output); diff --git a/apps/files/tests/Controller/ApiControllerTest.php b/apps/files/tests/Controller/ApiControllerTest.php index 429d3c06f66..0c9d7a4fa6e 100644 --- a/apps/files/tests/Controller/ApiControllerTest.php +++ b/apps/files/tests/Controller/ApiControllerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -31,6 +32,7 @@ use OCP\IUserSession; use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; @@ -40,41 +42,25 @@ use Test\TestCase; * @package OCA\Files\Controller */ class ApiControllerTest extends TestCase { - /** @var string */ - private $appName = 'files'; - /** @var IUser */ - private $user; - /** @var IRequest */ - private $request; - /** @var TagService */ - private $tagService; - /** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */ - private $preview; - /** @var ApiController */ - private $apiController; - /** @var \OCP\Share\IManager */ - private $shareManager; - /** @var IConfig */ - private $config; - /** @var Folder|\PHPUnit\Framework\MockObject\MockObject */ - private $userFolder; - /** @var UserConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $userConfig; - /** @var ViewConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $viewConfig; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l10n; - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; + private string $appName = 'files'; + private IUser $user; + private IRequest $request; + private TagService $tagService; + private IPreview&MockObject $preview; + private ApiController $apiController; + private IManager $shareManager; + private IConfig $config; + private Folder&MockObject $userFolder; + private UserConfig&MockObject $userConfig; + private ViewConfig&MockObject $viewConfig; + private IL10N&MockObject $l10n; + private IRootFolder&MockObject $rootFolder; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); - $this->request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor() - ->getMock(); + $this->request = $this->createMock(IRequest::class); $this->user = $this->createMock(IUser::class); $this->user->expects($this->any()) ->method('getUID') @@ -83,19 +69,11 @@ class ApiControllerTest extends TestCase { $userSession->expects($this->any()) ->method('getUser') ->willReturn($this->user); - $this->tagService = $this->getMockBuilder(TagService::class) - ->disableOriginalConstructor() - ->getMock(); - $this->shareManager = $this->getMockBuilder(IManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->preview = $this->getMockBuilder(IPreview::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tagService = $this->createMock(TagService::class); + $this->shareManager = $this->createMock(IManager::class); + $this->preview = $this->createMock(IPreview::class); $this->config = $this->createMock(IConfig::class); - $this->userFolder = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); + $this->userFolder = $this->createMock(Folder::class); $this->userConfig = $this->createMock(UserConfig::class); $this->viewConfig = $this->createMock(ViewConfig::class); $this->l10n = $this->createMock(IL10N::class); diff --git a/apps/files/tests/Controller/ConversionApiControllerTest.php b/apps/files/tests/Controller/ConversionApiControllerTest.php index a2f1fccd978..659fbe1a956 100644 --- a/apps/files/tests/Controller/ConversionApiControllerTest.php +++ b/apps/files/tests/Controller/ConversionApiControllerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -60,12 +61,12 @@ class ConversionApiControllerTest extends TestCase { ); } - public function testThrowsNotFoundException() { + public function testThrowsNotFoundException(): void { $this->expectException(OCSNotFoundException::class); $this->conversionApiController->convert(42, 'image/png'); } - public function testThrowsOcsException() { + public function testThrowsOcsException(): void { $this->userFolder->method('getFirstNodeById')->with(42)->willReturn($this->file); $this->fileConversionManager->method('convert')->willThrowException(new \Exception()); @@ -73,7 +74,7 @@ class ConversionApiControllerTest extends TestCase { $this->conversionApiController->convert(42, 'image/png'); } - public function testConvert() { + public function testConvert(): void { $convertedFileAbsolutePath = $this->user . '/files/test.png'; $this->userFolder->method('getFirstNodeById')->with(42)->willReturn($this->file); diff --git a/apps/files/tests/Controller/ViewControllerTest.php b/apps/files/tests/Controller/ViewControllerTest.php index dd76e814054..93ef98bdec7 100644 --- a/apps/files/tests/Controller/ViewControllerTest.php +++ b/apps/files/tests/Controller/ViewControllerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -192,7 +193,7 @@ class ViewControllerTest extends TestCase { $this->assertEquals($expected, $this->viewController->index('MyDir', 'MyView')); } - public function dataTestShortRedirect(): array { + public static function dataTestShortRedirect(): array { // openfile is true by default // opendetails is undefined by default // both will be evaluated as truthy @@ -212,7 +213,7 @@ class ViewControllerTest extends TestCase { /** * @dataProvider dataTestShortRedirect */ - public function testShortRedirect($openfile, $opendetails, $result) { + public function testShortRedirect(?string $openfile, ?string $opendetails, string $result): void { $this->appManager->expects($this->any()) ->method('isEnabledForUser') ->with('files') @@ -239,7 +240,7 @@ class ViewControllerTest extends TestCase { ->with(123456) ->willReturn($node); - $response = $this->viewController->showFile(123456, $opendetails, $openfile); + $response = $this->viewController->showFile('123456', $opendetails, $openfile); $this->assertStringContainsString($result, $response->getHeaders()['Location']); } @@ -248,13 +249,13 @@ class ViewControllerTest extends TestCase { ->method('isEnabledForUser') ->willReturn(true); - $parentNode = $this->getMockBuilder(Folder::class)->getMock(); + $parentNode = $this->createMock(Folder::class); $parentNode->expects($this->once()) ->method('getPath') ->willReturn('testuser1/files_trashbin/files/test.d1462861890/sub'); - $baseFolderFiles = $this->getMockBuilder(Folder::class)->getMock(); - $baseFolderTrash = $this->getMockBuilder(Folder::class)->getMock(); + $baseFolderFiles = $this->createMock(Folder::class); + $baseFolderTrash = $this->createMock(Folder::class); $this->rootFolder->expects($this->any()) ->method('getUserFolder') @@ -270,7 +271,7 @@ class ViewControllerTest extends TestCase { ->with(123) ->willReturn(null); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->expects($this->once()) ->method('getParent') ->willReturn($parentNode); diff --git a/apps/files/tests/HelperTest.php b/apps/files/tests/HelperTest.php index 5900e94215c..cb1fc5ed66d 100644 --- a/apps/files/tests/HelperTest.php +++ b/apps/files/tests/HelperTest.php @@ -1,15 +1,17 @@ <?php -use OC\Files\FileInfo; -use OCA\Files\Helper; - +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ + +use OC\Files\FileInfo; +use OCA\Files\Helper; + class HelperTest extends \Test\TestCase { - private function makeFileInfo($name, $size, $mtime, $isDir = false) { + private static function makeFileInfo($name, $size, $mtime, $isDir = false): FileInfo { return new FileInfo( '/' . $name, null, @@ -28,7 +30,7 @@ class HelperTest extends \Test\TestCase { /** * Returns a file list for testing */ - private function getTestFileList() { + private static function getTestFileList(): array { return [ self::makeFileInfo('a.txt', 4, 2.3 * pow(10, 9)), self::makeFileInfo('q.txt', 5, 150), @@ -39,7 +41,7 @@ class HelperTest extends \Test\TestCase { ]; } - public function sortDataProvider() { + public static function sortDataProvider(): array { return [ [ 'name', diff --git a/apps/files/tests/Service/TagServiceTest.php b/apps/files/tests/Service/TagServiceTest.php index 79dcf110f8a..74e58e674bb 100644 --- a/apps/files/tests/Service/TagServiceTest.php +++ b/apps/files/tests/Service/TagServiceTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,6 +11,7 @@ namespace OCA\Files\Tests\Service; use OCA\Files\Service\TagService; use OCP\Activity\IManager; use OCP\Files\Folder; +use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\ITagManager; use OCP\ITags; @@ -17,6 +19,7 @@ use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; /** * Class TagServiceTest @@ -26,32 +29,12 @@ use OCP\Server; * @package OCA\Files */ class TagServiceTest extends \Test\TestCase { - - /** - * @var string - */ - private $user; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; - - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $activityManager; - - /** - * @var Folder - */ - private $root; - - /** - * @var TagService|\PHPUnit\Framework\MockObject\MockObject - */ - private $tagService; - - /** - * @var ITags - */ - private $tagger; + private string $user; + private IUserSession&MockObject $userSession; + private IManager&MockObject $activityManager; + private Folder $root; + private TagService&MockObject $tagService; + private ITags $tagger; protected function setUp(): void { parent::setUp(); @@ -70,17 +53,13 @@ class TagServiceTest extends \Test\TestCase { ->withAnyParameters() ->willReturn($user); - $this->root = \OC::$server->getUserFolder(); + $this->root = \OCP\Server::get(IRootFolder::class)->getUserFolder($this->user); $this->tagger = Server::get(ITagManager::class)->load('files'); - $this->tagService = $this->getTagService(['addActivity']); + $this->tagService = $this->getTagService(); } - /** - * @param array $methods - * @return TagService|\PHPUnit\Framework\MockObject\MockObject - */ - protected function getTagService(array $methods = []) { + protected function getTagService(array $methods = []): TagService&MockObject { return $this->getMockBuilder(TagService::class) ->setConstructorArgs([ $this->userSession, @@ -88,7 +67,7 @@ class TagServiceTest extends \Test\TestCase { $this->tagger, $this->root, ]) - ->setMethods($methods) + ->onlyMethods($methods) ->getMock(); } @@ -98,6 +77,8 @@ class TagServiceTest extends \Test\TestCase { if ($user !== null) { $user->delete(); } + + parent::tearDown(); } public function testUpdateFileTags(): void { diff --git a/apps/files_external/l10n/et_EE.js b/apps/files_external/l10n/et_EE.js index c43471fe499..9624cfcc025 100644 --- a/apps/files_external/l10n/et_EE.js +++ b/apps/files_external/l10n/et_EE.js @@ -2,13 +2,14 @@ OC.L10N.register( "files_external", { "Grant access" : "Anna ligipääs", - "Error configuring OAuth1" : "OAuth1 seadistamise tõrge", - "Please provide a valid app key and secret." : "Palun sisesta rakenduse ketiva võti ja saladus.", - "Error configuring OAuth2" : "OAuth2 seadistamise tõrge", + "Error configuring OAuth1" : "Viga OAuth1 seadistamisel", + "Please provide a valid app key and secret." : "Palun sisesta rakenduse kehtiv võti ja saladus.", + "Error configuring OAuth2" : "Viga OAuth2 seadistamisel", "Generate keys" : "Loo võtmed", "Error generating key pair" : "Viga võtmepaari loomisel", "You are not logged in" : "Sa pole sisse logitud.", "Permission denied" : "Õigus on keelatud", + "Forbidden to manage local mounts" : "Kohalike haakepunktide haldamine on keelatud", "Storage with ID \"%d\" not found" : "Andmeruumi tunnusega „%d“ ei leidu", "Invalid backend or authentication mechanism class" : "Vigane taustateenus või autentimismeetodi klass", "Invalid mount point" : "Vigane haakepunkt", @@ -19,6 +20,7 @@ OC.L10N.register( "Unsatisfied backend parameters" : "Rahuldamata taustarakenduse parameetrid", "Insufficient data: %s" : "Pole piisavalt andmeid: %s", "%s" : "%s", + "Storage with ID \"%d\" is not editable by non-admins" : "Andmeruumi tunnusega „%d“ on muudetav vaid peakasutajate poolt", "Access key" : "Ligipääsuvõti", "Secret key" : "Salavõti", "Builtin" : "Sisseehitatud", @@ -43,6 +45,7 @@ OC.L10N.register( "Login and password" : "Kasutajanimi ja salasõna", "Log-in credentials, save in session" : "Salvesta sisselogimise kasutajanimi/salasõna sessioonis", "Global credentials, manually entered" : "Käsitsi sisestatud üldine kasutajanimi/salasõna", + "Manually entered, store in database" : "Käsitsi sisestatud ja salvestub andmebaasis", "RSA public key" : "RSA avalik võti", "Public key" : "Avalik võti", "RSA private key" : "RSA privaatvõti", @@ -52,12 +55,13 @@ OC.L10N.register( "Hostname" : "Hostinimi", "Port" : "Port", "Region" : "Piirkond", + "Storage Class" : "Andmeruumi klass (Storage class)", "Enable SSL" : "SSL-i kasutamine", "Enable Path Style" : "Luba otsingtee stiilis", "Legacy (v2) authentication" : "Pärandvormis autentimine (v2)", "SSE-C encryption key" : "SSE-C krüptimisvõti", "WebDAV" : "WebDAV", - "URL" : "URL", + "URL" : "Võrguaadress", "Remote subfolder" : "Mujal olev alamkaust", "Secure https://" : "Turvaline https://", "FTP" : "FTP", @@ -73,6 +77,7 @@ OC.L10N.register( "Share" : "Jaga", "Show hidden files" : "Näita peidetud faile", "Case sensitive file system" : "Tõstutundlik failisüsteem", + "Disabling it will allow to use a case insensitive file system, but comes with a performance penalty" : "Selle valiku keelamisega saad kasutada tõstutundetut failisüsteemi, kuid sellega kaasneb jõudluskadu", "Timeout" : "Aegumine", "SMB/CIFS using OC login" : "SMB / CIFS kasutades OC sisselogimist", "OpenStack Object Storage" : "OpenStack Object Storage", @@ -80,25 +85,37 @@ OC.L10N.register( "Request timeout (seconds)" : "Päringu aegumine (sekundites)", "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "cURL-i tugi on PHP-s on kas paigaldamata või pole kasutusele võetud. „%s“ haakimine pole võimalik. Palun oma peakasutajat, et ta teeks cURL-i toe tagamiseks vajalikud muudatused.", "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "FTP tugi on PHP-s on kas paigaldamata või pole kasutusele võetud. „%s“ haakimine pole võimalik. Palun oma peakasutajat, et ta teeks FTP toe tagamiseks vajalikud muudatused.", + "\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "„%1$s“ pole paigladatud. „%2$s“ haakimine pole võimalik. Palu oma peakasutajal või süsteemihalduril ta paigaldada.", "External storage" : "Väline andmehoidla", "External storage support" : "Väliste andmehoidlate tugi", - "Adds basic external storage support" : "Lisab väliste andmehoidlate toe baasiteratsioonis", + "Adds basic external storage support" : "Lisab väliste andmehoidlate toe põhivariandi", "Confirm" : "Kinnita", "Storage credentials" : "Andmeruumi kasutajanimi/salasõna", "To access the storage, you need to provide the authentication credentials." : "Selle andmeruumi jaoks pead autentimiseks lisama kasutajanime ja salasõna.", "Enter the storage login" : "Sisesta andmeruumi kasutajatunnus", "Enter the storage password" : "Sisesta andmeruumi kasutaja salasõna", + "Unable to update this external storage config. {statusMessage}" : "Selle välise andmeruumi seadistusi pole võimalik uuendada. {statusMessage}", + "New configuration successfully saved" : "Uue seadistuse salvestamine õnnestus", "Enter missing credentials" : "Lisa puuduvad kasutajanimi/salasõna", "Credentials successfully set" : "Kasutajanime/salasõna lisamine õnnestus", "Error while setting credentials: {error}" : "Viga kasutajanime/salasõna lisamisel: {error}", "Checking storage …" : "Kontrollin andmeruumi…", + "There was an error with this external storage." : "Selle välis andmeruumi kontekstis tekkis viga.", + "We were unable to check the external storage {basename}" : "Meil ei õnnestunud kontrollida välist andmeruumi „{basename}“", + "Examine this faulty external storage configuration" : "Kontrolli uuesti selle vigase välise andmeruumi seadistusi", "Open in Files" : "Ava failirakenduses", - "External mount error" : "Välise seostamise tõrge", - "Storage type" : "Andmehoidla tüüp", + "There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Selle välise andmeruumiga tekkis viga. Kas sa tahaksid seadistustest kontrollida haakepunkti konfiguratsiooni?", + "External mount error" : "Viga välise andmeruumi haakimisel", + "List of external storage." : "Väliste andmeruumide loend.", + "There is no external storage configured. You can configure them in your Personal settings." : "Ühtegi välist andmeruumi pole seadistatud. Saad seda teha isiklikest seadistustest.", + "There is no external storage configured and you don't have the permission to configure them." : "Ühtegi välist andmeruumi pole seadistatud ja sul pole õigust seda teha.", + "No external storage" : "Ühtegi välist andmeruumi ei leidu", + "Storage type" : "Andmeruumi tüüp", "Unknown" : "Teadmata", "Scope" : "Skoop", "Personal" : "Isiklik", "System" : "Süsteem", + "Type to select account or group." : "Kasutakonto või grupi leidmiseks kirjuta midagi.", "(Group)" : "(Grupp)", "Compatibility with Mac NFD encoding (slow)" : "Ühilduvus Mac NFD kodeeringuga (aeglane)", "Enable encryption" : "Luba krüptimine", @@ -124,6 +141,8 @@ OC.L10N.register( "Configuration" : "Seadistamine", "Available for" : "Saadaval", "Add storage" : "Lisa andmehoidla", - "Advanced settings" : "Lisavalikud" + "All people" : "Kõik inimesed", + "Advanced settings" : "Lisavalikud", + "Allow people to mount external storage" : "Luba kõigil haakida välist andmeruumi" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_external/l10n/et_EE.json b/apps/files_external/l10n/et_EE.json index 108e1ad18aa..eed33193c14 100644 --- a/apps/files_external/l10n/et_EE.json +++ b/apps/files_external/l10n/et_EE.json @@ -1,12 +1,13 @@ { "translations": { "Grant access" : "Anna ligipääs", - "Error configuring OAuth1" : "OAuth1 seadistamise tõrge", - "Please provide a valid app key and secret." : "Palun sisesta rakenduse ketiva võti ja saladus.", - "Error configuring OAuth2" : "OAuth2 seadistamise tõrge", + "Error configuring OAuth1" : "Viga OAuth1 seadistamisel", + "Please provide a valid app key and secret." : "Palun sisesta rakenduse kehtiv võti ja saladus.", + "Error configuring OAuth2" : "Viga OAuth2 seadistamisel", "Generate keys" : "Loo võtmed", "Error generating key pair" : "Viga võtmepaari loomisel", "You are not logged in" : "Sa pole sisse logitud.", "Permission denied" : "Õigus on keelatud", + "Forbidden to manage local mounts" : "Kohalike haakepunktide haldamine on keelatud", "Storage with ID \"%d\" not found" : "Andmeruumi tunnusega „%d“ ei leidu", "Invalid backend or authentication mechanism class" : "Vigane taustateenus või autentimismeetodi klass", "Invalid mount point" : "Vigane haakepunkt", @@ -17,6 +18,7 @@ "Unsatisfied backend parameters" : "Rahuldamata taustarakenduse parameetrid", "Insufficient data: %s" : "Pole piisavalt andmeid: %s", "%s" : "%s", + "Storage with ID \"%d\" is not editable by non-admins" : "Andmeruumi tunnusega „%d“ on muudetav vaid peakasutajate poolt", "Access key" : "Ligipääsuvõti", "Secret key" : "Salavõti", "Builtin" : "Sisseehitatud", @@ -41,6 +43,7 @@ "Login and password" : "Kasutajanimi ja salasõna", "Log-in credentials, save in session" : "Salvesta sisselogimise kasutajanimi/salasõna sessioonis", "Global credentials, manually entered" : "Käsitsi sisestatud üldine kasutajanimi/salasõna", + "Manually entered, store in database" : "Käsitsi sisestatud ja salvestub andmebaasis", "RSA public key" : "RSA avalik võti", "Public key" : "Avalik võti", "RSA private key" : "RSA privaatvõti", @@ -50,12 +53,13 @@ "Hostname" : "Hostinimi", "Port" : "Port", "Region" : "Piirkond", + "Storage Class" : "Andmeruumi klass (Storage class)", "Enable SSL" : "SSL-i kasutamine", "Enable Path Style" : "Luba otsingtee stiilis", "Legacy (v2) authentication" : "Pärandvormis autentimine (v2)", "SSE-C encryption key" : "SSE-C krüptimisvõti", "WebDAV" : "WebDAV", - "URL" : "URL", + "URL" : "Võrguaadress", "Remote subfolder" : "Mujal olev alamkaust", "Secure https://" : "Turvaline https://", "FTP" : "FTP", @@ -71,6 +75,7 @@ "Share" : "Jaga", "Show hidden files" : "Näita peidetud faile", "Case sensitive file system" : "Tõstutundlik failisüsteem", + "Disabling it will allow to use a case insensitive file system, but comes with a performance penalty" : "Selle valiku keelamisega saad kasutada tõstutundetut failisüsteemi, kuid sellega kaasneb jõudluskadu", "Timeout" : "Aegumine", "SMB/CIFS using OC login" : "SMB / CIFS kasutades OC sisselogimist", "OpenStack Object Storage" : "OpenStack Object Storage", @@ -78,25 +83,37 @@ "Request timeout (seconds)" : "Päringu aegumine (sekundites)", "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "cURL-i tugi on PHP-s on kas paigaldamata või pole kasutusele võetud. „%s“ haakimine pole võimalik. Palun oma peakasutajat, et ta teeks cURL-i toe tagamiseks vajalikud muudatused.", "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "FTP tugi on PHP-s on kas paigaldamata või pole kasutusele võetud. „%s“ haakimine pole võimalik. Palun oma peakasutajat, et ta teeks FTP toe tagamiseks vajalikud muudatused.", + "\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "„%1$s“ pole paigladatud. „%2$s“ haakimine pole võimalik. Palu oma peakasutajal või süsteemihalduril ta paigaldada.", "External storage" : "Väline andmehoidla", "External storage support" : "Väliste andmehoidlate tugi", - "Adds basic external storage support" : "Lisab väliste andmehoidlate toe baasiteratsioonis", + "Adds basic external storage support" : "Lisab väliste andmehoidlate toe põhivariandi", "Confirm" : "Kinnita", "Storage credentials" : "Andmeruumi kasutajanimi/salasõna", "To access the storage, you need to provide the authentication credentials." : "Selle andmeruumi jaoks pead autentimiseks lisama kasutajanime ja salasõna.", "Enter the storage login" : "Sisesta andmeruumi kasutajatunnus", "Enter the storage password" : "Sisesta andmeruumi kasutaja salasõna", + "Unable to update this external storage config. {statusMessage}" : "Selle välise andmeruumi seadistusi pole võimalik uuendada. {statusMessage}", + "New configuration successfully saved" : "Uue seadistuse salvestamine õnnestus", "Enter missing credentials" : "Lisa puuduvad kasutajanimi/salasõna", "Credentials successfully set" : "Kasutajanime/salasõna lisamine õnnestus", "Error while setting credentials: {error}" : "Viga kasutajanime/salasõna lisamisel: {error}", "Checking storage …" : "Kontrollin andmeruumi…", + "There was an error with this external storage." : "Selle välis andmeruumi kontekstis tekkis viga.", + "We were unable to check the external storage {basename}" : "Meil ei õnnestunud kontrollida välist andmeruumi „{basename}“", + "Examine this faulty external storage configuration" : "Kontrolli uuesti selle vigase välise andmeruumi seadistusi", "Open in Files" : "Ava failirakenduses", - "External mount error" : "Välise seostamise tõrge", - "Storage type" : "Andmehoidla tüüp", + "There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Selle välise andmeruumiga tekkis viga. Kas sa tahaksid seadistustest kontrollida haakepunkti konfiguratsiooni?", + "External mount error" : "Viga välise andmeruumi haakimisel", + "List of external storage." : "Väliste andmeruumide loend.", + "There is no external storage configured. You can configure them in your Personal settings." : "Ühtegi välist andmeruumi pole seadistatud. Saad seda teha isiklikest seadistustest.", + "There is no external storage configured and you don't have the permission to configure them." : "Ühtegi välist andmeruumi pole seadistatud ja sul pole õigust seda teha.", + "No external storage" : "Ühtegi välist andmeruumi ei leidu", + "Storage type" : "Andmeruumi tüüp", "Unknown" : "Teadmata", "Scope" : "Skoop", "Personal" : "Isiklik", "System" : "Süsteem", + "Type to select account or group." : "Kasutakonto või grupi leidmiseks kirjuta midagi.", "(Group)" : "(Grupp)", "Compatibility with Mac NFD encoding (slow)" : "Ühilduvus Mac NFD kodeeringuga (aeglane)", "Enable encryption" : "Luba krüptimine", @@ -122,6 +139,8 @@ "Configuration" : "Seadistamine", "Available for" : "Saadaval", "Add storage" : "Lisa andmehoidla", - "Advanced settings" : "Lisavalikud" + "All people" : "Kõik inimesed", + "Advanced settings" : "Lisavalikud", + "Allow people to mount external storage" : "Luba kõigil haakida välist andmeruumi" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_sharing/l10n/cs.js b/apps/files_sharing/l10n/cs.js index ddd9f9e9319..97cb49425d6 100644 --- a/apps/files_sharing/l10n/cs.js +++ b/apps/files_sharing/l10n/cs.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Předání souboru", "Upload files to {foldername}." : "Nahrát soubory do {foldername}", "By uploading files, you agree to the terms of service." : "Nahráním souborů souhlasíte s podmínkami služby.", + "Successfully uploaded files" : "Soubory úspěšně nahrány", "View terms of service" : "Zobrazit smluvní podmínky", "Terms of service" : "Všeobecné podmínky", "Upload files to {folder}" : "Nahrát soubory do {folder}", diff --git a/apps/files_sharing/l10n/cs.json b/apps/files_sharing/l10n/cs.json index b135d8e9e9e..b5f512d20e7 100644 --- a/apps/files_sharing/l10n/cs.json +++ b/apps/files_sharing/l10n/cs.json @@ -255,6 +255,7 @@ "File drop" : "Předání souboru", "Upload files to {foldername}." : "Nahrát soubory do {foldername}", "By uploading files, you agree to the terms of service." : "Nahráním souborů souhlasíte s podmínkami služby.", + "Successfully uploaded files" : "Soubory úspěšně nahrány", "View terms of service" : "Zobrazit smluvní podmínky", "Terms of service" : "Všeobecné podmínky", "Upload files to {folder}" : "Nahrát soubory do {folder}", diff --git a/apps/files_sharing/l10n/de.js b/apps/files_sharing/l10n/de.js index ce2b7c73e3f..b2fb1dc3159 100644 --- a/apps/files_sharing/l10n/de.js +++ b/apps/files_sharing/l10n/de.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Dateiablage", "Upload files to {foldername}." : "Dateien hochladen nach {foldername}.", "By uploading files, you agree to the terms of service." : "Durch das Hochladen von Dateien stimmst du den Nutzungsbedingungen zu.", + "Successfully uploaded files" : "Dateien wurden hochgeladen", "View terms of service" : "Nutzungsbedingungen anzeigen", "Terms of service" : "Nutzungsbedingungen", "Upload files to {folder}" : "Dateien hochladen nach {folder}", diff --git a/apps/files_sharing/l10n/de.json b/apps/files_sharing/l10n/de.json index 0dbe6cc8141..5edc31fe79c 100644 --- a/apps/files_sharing/l10n/de.json +++ b/apps/files_sharing/l10n/de.json @@ -255,6 +255,7 @@ "File drop" : "Dateiablage", "Upload files to {foldername}." : "Dateien hochladen nach {foldername}.", "By uploading files, you agree to the terms of service." : "Durch das Hochladen von Dateien stimmst du den Nutzungsbedingungen zu.", + "Successfully uploaded files" : "Dateien wurden hochgeladen", "View terms of service" : "Nutzungsbedingungen anzeigen", "Terms of service" : "Nutzungsbedingungen", "Upload files to {folder}" : "Dateien hochladen nach {folder}", diff --git a/apps/files_sharing/l10n/de_DE.js b/apps/files_sharing/l10n/de_DE.js index c825e4c948f..69abf34bd75 100644 --- a/apps/files_sharing/l10n/de_DE.js +++ b/apps/files_sharing/l10n/de_DE.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Dateiablage", "Upload files to {foldername}." : "Dateien hochladen nach {foldername}.", "By uploading files, you agree to the terms of service." : "Durch das Hochladen von Dateien stimmen Sie den Nutzungsbedingungen zu.", + "Successfully uploaded files" : "Dateien wurden hochgeladen", "View terms of service" : "Nutzungsbedingungen anzeigen", "Terms of service" : "Nutzungsbedingungen", "Upload files to {folder}" : "Dateien hochladen nach {folder}", diff --git a/apps/files_sharing/l10n/de_DE.json b/apps/files_sharing/l10n/de_DE.json index 19c796cfd66..33b5d08bade 100644 --- a/apps/files_sharing/l10n/de_DE.json +++ b/apps/files_sharing/l10n/de_DE.json @@ -255,6 +255,7 @@ "File drop" : "Dateiablage", "Upload files to {foldername}." : "Dateien hochladen nach {foldername}.", "By uploading files, you agree to the terms of service." : "Durch das Hochladen von Dateien stimmen Sie den Nutzungsbedingungen zu.", + "Successfully uploaded files" : "Dateien wurden hochgeladen", "View terms of service" : "Nutzungsbedingungen anzeigen", "Terms of service" : "Nutzungsbedingungen", "Upload files to {folder}" : "Dateien hochladen nach {folder}", diff --git a/apps/files_sharing/l10n/en_GB.js b/apps/files_sharing/l10n/en_GB.js index dc48e5526ee..bfef88bf61a 100644 --- a/apps/files_sharing/l10n/en_GB.js +++ b/apps/files_sharing/l10n/en_GB.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "File drop", "Upload files to {foldername}." : "Upload files to {foldername}.", "By uploading files, you agree to the terms of service." : "By uploading files, you agree to the terms of service.", + "Successfully uploaded files" : "Successfully uploaded files", "View terms of service" : "View terms of service", "Terms of service" : "Terms of service", "Upload files to {folder}" : "Upload files to {folder}", diff --git a/apps/files_sharing/l10n/en_GB.json b/apps/files_sharing/l10n/en_GB.json index ae93f32a6b2..202aa25d2ad 100644 --- a/apps/files_sharing/l10n/en_GB.json +++ b/apps/files_sharing/l10n/en_GB.json @@ -255,6 +255,7 @@ "File drop" : "File drop", "Upload files to {foldername}." : "Upload files to {foldername}.", "By uploading files, you agree to the terms of service." : "By uploading files, you agree to the terms of service.", + "Successfully uploaded files" : "Successfully uploaded files", "View terms of service" : "View terms of service", "Terms of service" : "Terms of service", "Upload files to {folder}" : "Upload files to {folder}", diff --git a/apps/files_sharing/l10n/et_EE.js b/apps/files_sharing/l10n/et_EE.js index bbf9425b62d..8c090e4c295 100644 --- a/apps/files_sharing/l10n/et_EE.js +++ b/apps/files_sharing/l10n/et_EE.js @@ -356,7 +356,7 @@ OC.L10N.register( "File requests" : "Failipäringud", "List of file requests." : "Failipäringute loend.", "No file requests" : "Failipäringuid ei leidu", - "File requests you have created will show up here" : "Sinu loodud failipäringus saavad olema nähtavad siin.", + "File requests you have created will show up here" : "Sinu loodud failipäringud saavad olema nähtavad siin.", "Deleted shares" : "Kustutatud jagamised", "List of shares you left." : "Jaosmeedia loend, kust sa oled lahkunud.", "No deleted shares" : "Kustutatud jagamisi pole", diff --git a/apps/files_sharing/l10n/et_EE.json b/apps/files_sharing/l10n/et_EE.json index d5a086f454a..e6110e021b6 100644 --- a/apps/files_sharing/l10n/et_EE.json +++ b/apps/files_sharing/l10n/et_EE.json @@ -354,7 +354,7 @@ "File requests" : "Failipäringud", "List of file requests." : "Failipäringute loend.", "No file requests" : "Failipäringuid ei leidu", - "File requests you have created will show up here" : "Sinu loodud failipäringus saavad olema nähtavad siin.", + "File requests you have created will show up here" : "Sinu loodud failipäringud saavad olema nähtavad siin.", "Deleted shares" : "Kustutatud jagamised", "List of shares you left." : "Jaosmeedia loend, kust sa oled lahkunud.", "No deleted shares" : "Kustutatud jagamisi pole", diff --git a/apps/files_sharing/l10n/fa.js b/apps/files_sharing/l10n/fa.js index 21c1715227e..0981c98e95e 100644 --- a/apps/files_sharing/l10n/fa.js +++ b/apps/files_sharing/l10n/fa.js @@ -150,6 +150,7 @@ OC.L10N.register( "Unable to fetch inherited shares" : "واگذاری سهام ارثی امکان پذیر نیست", "Shares" : "اشتراک گذاری ها", "Unable to load the shares list" : "لیست سهام بارگیری نمی شود", + "Expires {relativetime}" : "منقضی در {relativetime}", "this share just expired." : "این اشتراک تازه منقضی شد", "Shared with you by {owner}" : "به اشتراک گذاشته شده با شما توسط {owner}", "Link to a file" : "پیوند به یک پرونده", @@ -158,6 +159,7 @@ OC.L10N.register( "_Reject share_::_Reject shares_" : ["Reject share","Reject shares"], "_Restore share_::_Restore shares_" : ["Restore share","Restore shares"], "Shared" : "به اشتراک گذاشته شده ", + "Shared multiple times with different people" : "Shared multiple times with different people", "Shared with others" : "موارد به اشتراک گذاشته شده با دیگران", "Public file share" : "اشتراک عمومی پرونده", "Publicly shared file." : "پرونده بصورت عمومی به اشتراک گذاشته شده است", diff --git a/apps/files_sharing/l10n/fa.json b/apps/files_sharing/l10n/fa.json index 444d6173913..2e243499611 100644 --- a/apps/files_sharing/l10n/fa.json +++ b/apps/files_sharing/l10n/fa.json @@ -148,6 +148,7 @@ "Unable to fetch inherited shares" : "واگذاری سهام ارثی امکان پذیر نیست", "Shares" : "اشتراک گذاری ها", "Unable to load the shares list" : "لیست سهام بارگیری نمی شود", + "Expires {relativetime}" : "منقضی در {relativetime}", "this share just expired." : "این اشتراک تازه منقضی شد", "Shared with you by {owner}" : "به اشتراک گذاشته شده با شما توسط {owner}", "Link to a file" : "پیوند به یک پرونده", @@ -156,6 +157,7 @@ "_Reject share_::_Reject shares_" : ["Reject share","Reject shares"], "_Restore share_::_Restore shares_" : ["Restore share","Restore shares"], "Shared" : "به اشتراک گذاشته شده ", + "Shared multiple times with different people" : "Shared multiple times with different people", "Shared with others" : "موارد به اشتراک گذاشته شده با دیگران", "Public file share" : "اشتراک عمومی پرونده", "Publicly shared file." : "پرونده بصورت عمومی به اشتراک گذاشته شده است", diff --git a/apps/files_sharing/l10n/fr.js b/apps/files_sharing/l10n/fr.js index 53adc1f132c..f99ebfc1530 100644 --- a/apps/files_sharing/l10n/fr.js +++ b/apps/files_sharing/l10n/fr.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Dépôt de fichier", "Upload files to {foldername}." : "Téléverser les fichiers vers {foldername}.", "By uploading files, you agree to the terms of service." : "En téléversant des fichiers, vous acceptez les conditions d'utilisation du service.", + "Successfully uploaded files" : "Fichiers téléversés avec succès", "View terms of service" : "Voir les conditions d'utilisation du service", "Terms of service" : "Conditions d'utilisation", "Upload files to {folder}" : "Téléverser les fichiers dans {folder}", diff --git a/apps/files_sharing/l10n/fr.json b/apps/files_sharing/l10n/fr.json index 58055c96295..ecec9e15f07 100644 --- a/apps/files_sharing/l10n/fr.json +++ b/apps/files_sharing/l10n/fr.json @@ -255,6 +255,7 @@ "File drop" : "Dépôt de fichier", "Upload files to {foldername}." : "Téléverser les fichiers vers {foldername}.", "By uploading files, you agree to the terms of service." : "En téléversant des fichiers, vous acceptez les conditions d'utilisation du service.", + "Successfully uploaded files" : "Fichiers téléversés avec succès", "View terms of service" : "Voir les conditions d'utilisation du service", "Terms of service" : "Conditions d'utilisation", "Upload files to {folder}" : "Téléverser les fichiers dans {folder}", diff --git a/apps/files_sharing/l10n/ja.js b/apps/files_sharing/l10n/ja.js index 3c82171b04b..6185d4fcfc2 100644 --- a/apps/files_sharing/l10n/ja.js +++ b/apps/files_sharing/l10n/ja.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "ファイルを転送", "Upload files to {foldername}." : "{foldername}にファイルをアップロード", "By uploading files, you agree to the terms of service." : "ファイルをアップロードすることで、利用規約に同意したことになります。", + "Successfully uploaded files" : "ファイルのアップロードに成功しました", "View terms of service" : "利用規約を見る", "Terms of service" : "サービス利用規約", "Upload files to {folder}" : "{folder}にファイルをアップロード", diff --git a/apps/files_sharing/l10n/ja.json b/apps/files_sharing/l10n/ja.json index 30b967a6848..fe3629aa4da 100644 --- a/apps/files_sharing/l10n/ja.json +++ b/apps/files_sharing/l10n/ja.json @@ -255,6 +255,7 @@ "File drop" : "ファイルを転送", "Upload files to {foldername}." : "{foldername}にファイルをアップロード", "By uploading files, you agree to the terms of service." : "ファイルをアップロードすることで、利用規約に同意したことになります。", + "Successfully uploaded files" : "ファイルのアップロードに成功しました", "View terms of service" : "利用規約を見る", "Terms of service" : "サービス利用規約", "Upload files to {folder}" : "{folder}にファイルをアップロード", diff --git a/apps/files_sharing/l10n/pt_BR.js b/apps/files_sharing/l10n/pt_BR.js index f75b225aae5..b8c05daa750 100644 --- a/apps/files_sharing/l10n/pt_BR.js +++ b/apps/files_sharing/l10n/pt_BR.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Depósito de arquivos", "Upload files to {foldername}." : "Subir arquivos para {foldername}.", "By uploading files, you agree to the terms of service." : "Ao enviar arquivos, você concorda com os termos de serviço.", + "Successfully uploaded files" : "Arquivos carregados com sucesso", "View terms of service" : "Ver os termos de serviço", "Terms of service" : "Termos de serviço", "Upload files to {folder}" : "Enviar arquivos para {folder}", diff --git a/apps/files_sharing/l10n/pt_BR.json b/apps/files_sharing/l10n/pt_BR.json index d1b9e77d278..827e07c452b 100644 --- a/apps/files_sharing/l10n/pt_BR.json +++ b/apps/files_sharing/l10n/pt_BR.json @@ -255,6 +255,7 @@ "File drop" : "Depósito de arquivos", "Upload files to {foldername}." : "Subir arquivos para {foldername}.", "By uploading files, you agree to the terms of service." : "Ao enviar arquivos, você concorda com os termos de serviço.", + "Successfully uploaded files" : "Arquivos carregados com sucesso", "View terms of service" : "Ver os termos de serviço", "Terms of service" : "Termos de serviço", "Upload files to {folder}" : "Enviar arquivos para {folder}", diff --git a/apps/files_sharing/l10n/sr.js b/apps/files_sharing/l10n/sr.js index 48323c82d47..4a2c7230e0e 100644 --- a/apps/files_sharing/l10n/sr.js +++ b/apps/files_sharing/l10n/sr.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Место за упуштање фајлова", "Upload files to {foldername}." : "Отпреми фајлове у {foldername}.", "By uploading files, you agree to the terms of service." : "Отпремањем фајлова, слажете се са условима коришћења.", + "Successfully uploaded files" : "Фајлови су успешно отпремљени", "View terms of service" : "Прикажи услове коришћења", "Terms of service" : "Услови коришћења", "Upload files to {folder}" : "Отпреми фајлове у {folder}", diff --git a/apps/files_sharing/l10n/sr.json b/apps/files_sharing/l10n/sr.json index 04897bc3598..64fb1ab2187 100644 --- a/apps/files_sharing/l10n/sr.json +++ b/apps/files_sharing/l10n/sr.json @@ -255,6 +255,7 @@ "File drop" : "Место за упуштање фајлова", "Upload files to {foldername}." : "Отпреми фајлове у {foldername}.", "By uploading files, you agree to the terms of service." : "Отпремањем фајлова, слажете се са условима коришћења.", + "Successfully uploaded files" : "Фајлови су успешно отпремљени", "View terms of service" : "Прикажи услове коришћења", "Terms of service" : "Услови коришћења", "Upload files to {folder}" : "Отпреми фајлове у {folder}", diff --git a/apps/files_sharing/l10n/sv.js b/apps/files_sharing/l10n/sv.js index e5af3c5e4c3..afd677b187b 100644 --- a/apps/files_sharing/l10n/sv.js +++ b/apps/files_sharing/l10n/sv.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "Filinkast", "Upload files to {foldername}." : "Ladda upp filer till {foldername}.", "By uploading files, you agree to the terms of service." : "Genom att ladda upp filer godkänner du användarvillkoren.", + "Successfully uploaded files" : "Filer har laddats upp", "View terms of service" : "Visa användarvillkoren", "Terms of service" : "Användarvillkor", "Upload files to {folder}" : "Ladda upp filer till {folder}", diff --git a/apps/files_sharing/l10n/sv.json b/apps/files_sharing/l10n/sv.json index 8be901a9c3d..89e44650c43 100644 --- a/apps/files_sharing/l10n/sv.json +++ b/apps/files_sharing/l10n/sv.json @@ -255,6 +255,7 @@ "File drop" : "Filinkast", "Upload files to {foldername}." : "Ladda upp filer till {foldername}.", "By uploading files, you agree to the terms of service." : "Genom att ladda upp filer godkänner du användarvillkoren.", + "Successfully uploaded files" : "Filer har laddats upp", "View terms of service" : "Visa användarvillkoren", "Terms of service" : "Användarvillkor", "Upload files to {folder}" : "Ladda upp filer till {folder}", diff --git a/apps/files_sharing/l10n/zh_CN.js b/apps/files_sharing/l10n/zh_CN.js index 404be9f7ab4..5d051eb9950 100644 --- a/apps/files_sharing/l10n/zh_CN.js +++ b/apps/files_sharing/l10n/zh_CN.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "文件拖放", "Upload files to {foldername}." : "将文件上传到 {foldername}。", "By uploading files, you agree to the terms of service." : "上传文件即表示您同意服务条款。", + "Successfully uploaded files" : "已成功上传文件", "View terms of service" : "查看服务条款", "Terms of service" : "服务条款", "Upload files to {folder}" : "将文件上传到 {folder}", diff --git a/apps/files_sharing/l10n/zh_CN.json b/apps/files_sharing/l10n/zh_CN.json index 2ea3efde3bb..5cd693a66be 100644 --- a/apps/files_sharing/l10n/zh_CN.json +++ b/apps/files_sharing/l10n/zh_CN.json @@ -255,6 +255,7 @@ "File drop" : "文件拖放", "Upload files to {foldername}." : "将文件上传到 {foldername}。", "By uploading files, you agree to the terms of service." : "上传文件即表示您同意服务条款。", + "Successfully uploaded files" : "已成功上传文件", "View terms of service" : "查看服务条款", "Terms of service" : "服务条款", "Upload files to {folder}" : "将文件上传到 {folder}", diff --git a/apps/files_sharing/l10n/zh_HK.js b/apps/files_sharing/l10n/zh_HK.js index dd435890210..b06485d52ae 100644 --- a/apps/files_sharing/l10n/zh_HK.js +++ b/apps/files_sharing/l10n/zh_HK.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "檔案拖放", "Upload files to {foldername}." : "上傳檔案至 {foldername}。", "By uploading files, you agree to the terms of service." : "上傳檔案即表示您同意服務條款。", + "Successfully uploaded files" : "檔案上傳成功", "View terms of service" : "檢視服務條款", "Terms of service" : "服務條款", "Upload files to {folder}" : "上傳檔案到 {folder}", diff --git a/apps/files_sharing/l10n/zh_HK.json b/apps/files_sharing/l10n/zh_HK.json index 4f6fe38e858..67d1f31894f 100644 --- a/apps/files_sharing/l10n/zh_HK.json +++ b/apps/files_sharing/l10n/zh_HK.json @@ -255,6 +255,7 @@ "File drop" : "檔案拖放", "Upload files to {foldername}." : "上傳檔案至 {foldername}。", "By uploading files, you agree to the terms of service." : "上傳檔案即表示您同意服務條款。", + "Successfully uploaded files" : "檔案上傳成功", "View terms of service" : "檢視服務條款", "Terms of service" : "服務條款", "Upload files to {folder}" : "上傳檔案到 {folder}", diff --git a/apps/files_sharing/l10n/zh_TW.js b/apps/files_sharing/l10n/zh_TW.js index fc86c1306e7..9f2a7ae3b85 100644 --- a/apps/files_sharing/l10n/zh_TW.js +++ b/apps/files_sharing/l10n/zh_TW.js @@ -257,6 +257,7 @@ OC.L10N.register( "File drop" : "檔案投遞", "Upload files to {foldername}." : "上傳檔案至 {foldername}。", "By uploading files, you agree to the terms of service." : "上傳檔案即表示您同意服務條款。", + "Successfully uploaded files" : "已成功上傳檔案", "View terms of service" : "檢視服務條款", "Terms of service" : "服務條款", "Upload files to {folder}" : "上傳檔案到 {folder}", diff --git a/apps/files_sharing/l10n/zh_TW.json b/apps/files_sharing/l10n/zh_TW.json index af5b6ecabf5..35e7ec603d5 100644 --- a/apps/files_sharing/l10n/zh_TW.json +++ b/apps/files_sharing/l10n/zh_TW.json @@ -255,6 +255,7 @@ "File drop" : "檔案投遞", "Upload files to {foldername}." : "上傳檔案至 {foldername}。", "By uploading files, you agree to the terms of service." : "上傳檔案即表示您同意服務條款。", + "Successfully uploaded files" : "已成功上傳檔案", "View terms of service" : "檢視服務條款", "Terms of service" : "服務條款", "Upload files to {folder}" : "上傳檔案到 {folder}", diff --git a/apps/files_trashbin/l10n/cs.js b/apps/files_trashbin/l10n/cs.js index de43bf97faf..48eabc39b81 100644 --- a/apps/files_trashbin/l10n/cs.js +++ b/apps/files_trashbin/l10n/cs.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Tato aplikace umožňuje lidem obnovovat soubory, které byly ze systému vymazány.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Tato aplikace lidem umožňuje obnovovat soubory, které byly ze systému vymazány. Ve webovém rozhraní zobrazuje seznam smazaných souborů a má volby pro obnovení těchto souborů zpět do složek se soubory lidí nebo jejich trvalé odebrání. Obnovení souboru také obnoví jeho související verze (pokud je zapnutá aplikace pro správu verzí). Když je soubor smazán ze sdílení, je možné ho obnovit stejným způsobem, ačkoli už nebude sdílený. Ve výchozím stavu, tyto soubory jsou ponechávány v koši po dobu 30 dnů.\nAby lidé nezaplnili celý disk, aplikace Smazané soubory pro ně nevyužije více než 50% kvóty. Pokud smazané soubory přesahují tento limit, aplikace maže nejstarší soubory, dokud se nedostane pod limit. Další informace jsou k dispozici v dokumentaci ke Smazané soubory.", "Restore" : "Obnovit", + "Not enough free space to restore the file/folder" : "Nedostatek volného místa pro obnovení souboru/složky", "Empty deleted files" : "Vyprázdnit smazané soubory", "Confirm permanent deletion" : "Potvrdit nevratné smazání", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Opravdu chcete nevratně smazat veškeré soubory a složky v koši? Toto nelze vzít zpět!", diff --git a/apps/files_trashbin/l10n/cs.json b/apps/files_trashbin/l10n/cs.json index 791bdf1d481..cc0e06dab41 100644 --- a/apps/files_trashbin/l10n/cs.json +++ b/apps/files_trashbin/l10n/cs.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Tato aplikace umožňuje lidem obnovovat soubory, které byly ze systému vymazány.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Tato aplikace lidem umožňuje obnovovat soubory, které byly ze systému vymazány. Ve webovém rozhraní zobrazuje seznam smazaných souborů a má volby pro obnovení těchto souborů zpět do složek se soubory lidí nebo jejich trvalé odebrání. Obnovení souboru také obnoví jeho související verze (pokud je zapnutá aplikace pro správu verzí). Když je soubor smazán ze sdílení, je možné ho obnovit stejným způsobem, ačkoli už nebude sdílený. Ve výchozím stavu, tyto soubory jsou ponechávány v koši po dobu 30 dnů.\nAby lidé nezaplnili celý disk, aplikace Smazané soubory pro ně nevyužije více než 50% kvóty. Pokud smazané soubory přesahují tento limit, aplikace maže nejstarší soubory, dokud se nedostane pod limit. Další informace jsou k dispozici v dokumentaci ke Smazané soubory.", "Restore" : "Obnovit", + "Not enough free space to restore the file/folder" : "Nedostatek volného místa pro obnovení souboru/složky", "Empty deleted files" : "Vyprázdnit smazané soubory", "Confirm permanent deletion" : "Potvrdit nevratné smazání", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Opravdu chcete nevratně smazat veškeré soubory a složky v koši? Toto nelze vzít zpět!", diff --git a/apps/files_trashbin/l10n/de.js b/apps/files_trashbin/l10n/de.js index 30f503f52d9..75a7ce7d443 100644 --- a/apps/files_trashbin/l10n/de.js +++ b/apps/files_trashbin/l10n/de.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die vom System gelöscht wurden.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die aus dem System gelöscht wurden. Es zeigt eine Liste der gelöschten Dateien in der Web-Oberfläche an und bietet die Möglichkeit, diese gelöschten Dateien in die Verzeichnisse der Personen wiederherzustellen oder sie dauerhaft aus dem System zu entfernen. Beim Wiederherstellen einer Datei werden auch die zugehörigen Dateiversionen wiederhergestellt, sofern die Versionsanwendung aktiviert ist. Wenn eine Datei aus einer Freigabe gelöscht wird, kann sie auf dem gleichen Weg wiederhergestellt werden, ist jedoch nicht mehr geteilt. Standardmäßig verbleiben gelöschte Dateien 30 Tage lang im Papierkorb.\nUm zu verhindern, dass einem Konto der Speicherplatz ausgeht, nutzt die Anwendung für gelöschte Dateien maximal 50 % des aktuell verfügbaren freien Kontingents. Wenn die gelöschten Dateien dieses Limit überschreiten, löscht die Anwendung die ältesten Dateien, bis sie unter dieses Limit fällt. Weitere Informationen findest du in der Dokumentation zu gelöschten Dateien.", "Restore" : "Wiederherstellen", + "Not enough free space to restore the file/folder" : "Nicht genügend freier Speicherplatz zum Wiederherstellen der Datei/des Ordners", "Empty deleted files" : "Gelöschte Dateien leeren", "Confirm permanent deletion" : "Endgültiges Löschen bestätigen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Möchtest du wirklich alle Dateien und Ordner im Papierkorb endgültig löschen? Dies kann nicht rückgängig gemacht werden.", diff --git a/apps/files_trashbin/l10n/de.json b/apps/files_trashbin/l10n/de.json index 9017b23b0ca..6085c3ba2ee 100644 --- a/apps/files_trashbin/l10n/de.json +++ b/apps/files_trashbin/l10n/de.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die vom System gelöscht wurden.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die aus dem System gelöscht wurden. Es zeigt eine Liste der gelöschten Dateien in der Web-Oberfläche an und bietet die Möglichkeit, diese gelöschten Dateien in die Verzeichnisse der Personen wiederherzustellen oder sie dauerhaft aus dem System zu entfernen. Beim Wiederherstellen einer Datei werden auch die zugehörigen Dateiversionen wiederhergestellt, sofern die Versionsanwendung aktiviert ist. Wenn eine Datei aus einer Freigabe gelöscht wird, kann sie auf dem gleichen Weg wiederhergestellt werden, ist jedoch nicht mehr geteilt. Standardmäßig verbleiben gelöschte Dateien 30 Tage lang im Papierkorb.\nUm zu verhindern, dass einem Konto der Speicherplatz ausgeht, nutzt die Anwendung für gelöschte Dateien maximal 50 % des aktuell verfügbaren freien Kontingents. Wenn die gelöschten Dateien dieses Limit überschreiten, löscht die Anwendung die ältesten Dateien, bis sie unter dieses Limit fällt. Weitere Informationen findest du in der Dokumentation zu gelöschten Dateien.", "Restore" : "Wiederherstellen", + "Not enough free space to restore the file/folder" : "Nicht genügend freier Speicherplatz zum Wiederherstellen der Datei/des Ordners", "Empty deleted files" : "Gelöschte Dateien leeren", "Confirm permanent deletion" : "Endgültiges Löschen bestätigen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Möchtest du wirklich alle Dateien und Ordner im Papierkorb endgültig löschen? Dies kann nicht rückgängig gemacht werden.", diff --git a/apps/files_trashbin/l10n/de_DE.js b/apps/files_trashbin/l10n/de_DE.js index 291f3733b02..179a3689d7e 100644 --- a/apps/files_trashbin/l10n/de_DE.js +++ b/apps/files_trashbin/l10n/de_DE.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die vom System gelöscht wurden.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die aus dem System gelöscht wurden. Es zeigt eine Liste der gelöschten Dateien in der Web-Oberfläche an und bietet die Möglichkeit, diese gelöschten Dateien in die Verzeichnisse der Personen wiederherzustellen oder sie dauerhaft aus dem System zu entfernen. Beim Wiederherstellen einer Datei werden auch die zugehörigen Dateiversionen wiederhergestellt, sofern die Versionsanwendung aktiviert ist. Wenn eine Datei aus einer Freigabe gelöscht wird, kann sie auf dem gleichen Weg wiederhergestellt werden, ist jedoch nicht mehr geteilt. Standardmäßig verbleiben gelöschte Dateien 30 Tage lang im Papierkorb.\nUm zu verhindern, dass einem Konto der Speicherplatz ausgeht, nutzt die Anwendung für gelöschte Dateien maximal 50 % des aktuell verfügbaren freien Kontingents. Wenn die gelöschten Dateien dieses Limit überschreiten, löscht die Anwendung die ältesten Dateien, bis sie unter dieses Limit fällt. Weitere Informationen finden Sie in der Dokumentation zu gelöschten Dateien.", "Restore" : "Wiederherstellen", + "Not enough free space to restore the file/folder" : "Nicht genügend freier Speicherplatz zum Wiederherstellen der Datei/des Ordners", "Empty deleted files" : "Gelöschte Dateien leeren", "Confirm permanent deletion" : "Endgültiges Löschen bestätigen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Möchten Sie wirklich alle Dateien und Ordner im Papierkorb endgültig löschen? Dies kann nicht rückgängig gemacht werden.", diff --git a/apps/files_trashbin/l10n/de_DE.json b/apps/files_trashbin/l10n/de_DE.json index 645f7a146a0..974d0a02b90 100644 --- a/apps/files_trashbin/l10n/de_DE.json +++ b/apps/files_trashbin/l10n/de_DE.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die vom System gelöscht wurden.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Diese Anwendung ermöglicht es Personen, Dateien wiederherzustellen, die aus dem System gelöscht wurden. Es zeigt eine Liste der gelöschten Dateien in der Web-Oberfläche an und bietet die Möglichkeit, diese gelöschten Dateien in die Verzeichnisse der Personen wiederherzustellen oder sie dauerhaft aus dem System zu entfernen. Beim Wiederherstellen einer Datei werden auch die zugehörigen Dateiversionen wiederhergestellt, sofern die Versionsanwendung aktiviert ist. Wenn eine Datei aus einer Freigabe gelöscht wird, kann sie auf dem gleichen Weg wiederhergestellt werden, ist jedoch nicht mehr geteilt. Standardmäßig verbleiben gelöschte Dateien 30 Tage lang im Papierkorb.\nUm zu verhindern, dass einem Konto der Speicherplatz ausgeht, nutzt die Anwendung für gelöschte Dateien maximal 50 % des aktuell verfügbaren freien Kontingents. Wenn die gelöschten Dateien dieses Limit überschreiten, löscht die Anwendung die ältesten Dateien, bis sie unter dieses Limit fällt. Weitere Informationen finden Sie in der Dokumentation zu gelöschten Dateien.", "Restore" : "Wiederherstellen", + "Not enough free space to restore the file/folder" : "Nicht genügend freier Speicherplatz zum Wiederherstellen der Datei/des Ordners", "Empty deleted files" : "Gelöschte Dateien leeren", "Confirm permanent deletion" : "Endgültiges Löschen bestätigen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Möchten Sie wirklich alle Dateien und Ordner im Papierkorb endgültig löschen? Dies kann nicht rückgängig gemacht werden.", diff --git a/apps/files_trashbin/l10n/en_GB.js b/apps/files_trashbin/l10n/en_GB.js index 6a42b161815..6f450e00473 100644 --- a/apps/files_trashbin/l10n/en_GB.js +++ b/apps/files_trashbin/l10n/en_GB.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "This application enables people to restore files that were deleted from the system.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation.", "Restore" : "Restore", + "Not enough free space to restore the file/folder" : "Not enough free space to restore the file/folder", "Empty deleted files" : "Empty deleted files", "Confirm permanent deletion" : "Confirm permanent deletion", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone.", diff --git a/apps/files_trashbin/l10n/en_GB.json b/apps/files_trashbin/l10n/en_GB.json index b4f372b73ca..d48e62ffc1b 100644 --- a/apps/files_trashbin/l10n/en_GB.json +++ b/apps/files_trashbin/l10n/en_GB.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "This application enables people to restore files that were deleted from the system.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation.", "Restore" : "Restore", + "Not enough free space to restore the file/folder" : "Not enough free space to restore the file/folder", "Empty deleted files" : "Empty deleted files", "Confirm permanent deletion" : "Confirm permanent deletion", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone.", diff --git a/apps/files_trashbin/l10n/et_EE.js b/apps/files_trashbin/l10n/et_EE.js index a91297dee6c..1ff6f43e96f 100644 --- a/apps/files_trashbin/l10n/et_EE.js +++ b/apps/files_trashbin/l10n/et_EE.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "See rakendus võimaldab inimestel taastada faile mis nad süsteemist kustutasid.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "See rakendus võimaldab inimestel taastada süsteemist kustutatud faile. See kuvab veebiliideses kustutatud failide loendi ja pakub võimalusi kustutatud failide taastamiseks inimeste failikataloogidesse või süsteemist jäädavalt eemaldamiseks. Faili taastamine taastab ka seotud failiversioonid, kui versioonirakendus on lubatud. Kui fail ühiskasutusest kustutatakse, saab selle taastada samal viisil, kuigi seda enam ei jagata. Vaikimisi jäävad need failid prügikasti 30 päevaks.\nKonto kettaruumi tühjenemise vältimiseks ei kasuta rakendus Kustutatud failid rohkem kui 50% praegu saadaolevast kustutatud failide tasuta kvoodist. Kui kustutatud failid ületavad selle limiidi, kustutab rakendus vanimad failid, kuni need jäävad sellest limiidist allapoole. Lisateavet leiate kustutatud failide dokumentatsioonist.", "Restore" : "Taasta", + "Not enough free space to restore the file/folder" : "Faili või kausta taastamiseks pole piisavalt vaba ruumi", "Empty deleted files" : "Tühjenda kustutatud failid", "Confirm permanent deletion" : "Kinnita lõplik kustutamine", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Kas oled kindel, et tahad lõplikult kustutada kõik prügikastis olevad failid ja kaustad? Seda ei saa tagasi keerata.", diff --git a/apps/files_trashbin/l10n/et_EE.json b/apps/files_trashbin/l10n/et_EE.json index 5b5f3804b26..b678a274fa3 100644 --- a/apps/files_trashbin/l10n/et_EE.json +++ b/apps/files_trashbin/l10n/et_EE.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "See rakendus võimaldab inimestel taastada faile mis nad süsteemist kustutasid.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "See rakendus võimaldab inimestel taastada süsteemist kustutatud faile. See kuvab veebiliideses kustutatud failide loendi ja pakub võimalusi kustutatud failide taastamiseks inimeste failikataloogidesse või süsteemist jäädavalt eemaldamiseks. Faili taastamine taastab ka seotud failiversioonid, kui versioonirakendus on lubatud. Kui fail ühiskasutusest kustutatakse, saab selle taastada samal viisil, kuigi seda enam ei jagata. Vaikimisi jäävad need failid prügikasti 30 päevaks.\nKonto kettaruumi tühjenemise vältimiseks ei kasuta rakendus Kustutatud failid rohkem kui 50% praegu saadaolevast kustutatud failide tasuta kvoodist. Kui kustutatud failid ületavad selle limiidi, kustutab rakendus vanimad failid, kuni need jäävad sellest limiidist allapoole. Lisateavet leiate kustutatud failide dokumentatsioonist.", "Restore" : "Taasta", + "Not enough free space to restore the file/folder" : "Faili või kausta taastamiseks pole piisavalt vaba ruumi", "Empty deleted files" : "Tühjenda kustutatud failid", "Confirm permanent deletion" : "Kinnita lõplik kustutamine", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Kas oled kindel, et tahad lõplikult kustutada kõik prügikastis olevad failid ja kaustad? Seda ei saa tagasi keerata.", diff --git a/apps/files_trashbin/l10n/fa.js b/apps/files_trashbin/l10n/fa.js index da76294a244..55b89e58982 100644 --- a/apps/files_trashbin/l10n/fa.js +++ b/apps/files_trashbin/l10n/fa.js @@ -6,10 +6,12 @@ OC.L10N.register( "Deleted files and folders in the trash bin (may expire during export if you are low on storage space)" : "Deleted files and folders in the trash bin (may expire during export if you are low on storage space)", "Restore" : "بازیابی", "Cancel" : "منصرف شدن", + "Deletion cancelled" : "Deletion cancelled", "Deleted" : "حذف شده", "A long time ago" : "مدت ها پیش", "Unknown" : "ناشناخته", "All files" : "تمامی فایلها", + "You" : "You", "List of files that have been deleted." : "List of files that have been deleted.", "No deleted files" : "هیچ فایل حذف شده وجود ندارد", "Files and folders you have deleted will show up here" : "Files and folders you have deleted will show up here" diff --git a/apps/files_trashbin/l10n/fa.json b/apps/files_trashbin/l10n/fa.json index 22ee88dd2f0..18cdca47044 100644 --- a/apps/files_trashbin/l10n/fa.json +++ b/apps/files_trashbin/l10n/fa.json @@ -4,10 +4,12 @@ "Deleted files and folders in the trash bin (may expire during export if you are low on storage space)" : "Deleted files and folders in the trash bin (may expire during export if you are low on storage space)", "Restore" : "بازیابی", "Cancel" : "منصرف شدن", + "Deletion cancelled" : "Deletion cancelled", "Deleted" : "حذف شده", "A long time ago" : "مدت ها پیش", "Unknown" : "ناشناخته", "All files" : "تمامی فایلها", + "You" : "You", "List of files that have been deleted." : "List of files that have been deleted.", "No deleted files" : "هیچ فایل حذف شده وجود ندارد", "Files and folders you have deleted will show up here" : "Files and folders you have deleted will show up here" diff --git a/apps/files_trashbin/l10n/fr.js b/apps/files_trashbin/l10n/fr.js index db2e6d58272..80f31b30437 100644 --- a/apps/files_trashbin/l10n/fr.js +++ b/apps/files_trashbin/l10n/fr.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Cette application permet aux personnes de restaurer des fichiers qui ont été supprimés du système.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Cette application permet aux personnes de restaurer les fichiers qui ont été supprimés du système. Il affiche une liste de fichiers supprimés dans l'interface Web et dispose d'options pour restaurer ces fichiers supprimés dans les dossiers de fichiers des personnes ou les supprimer définitivement du système. La restauration d'un fichier restaure également les versions de fichiers associées, si l'application de versions est activée. Lorsqu'un fichier est supprimé d'un partage, il peut être restauré de la même manière, bien qu'il ne soit plus partagé. Par défaut, ces fichiers restent dans la corbeille pendant 30 jours.\n\nPour empêcher un compte de manquer d'espace disque, l'application \"Fichiers supprimés\" n'utilisera pas plus de 50 % du quota actuellement disponible pour les fichiers supprimés. Si les fichiers supprimés dépassent cette limite, l'application supprime les fichiers les plus anciens jusqu'à ce qu'elle soit inférieure à cette limite. Plus d'informations sont disponibles dans la documentation Fichiers supprimés.", "Restore" : "Restaurer", + "Not enough free space to restore the file/folder" : "Espace libre insuffisant pour restaurer le fichier/dossier", "Empty deleted files" : "Vider les fichiers supprimés", "Confirm permanent deletion" : "Confirmer la suppression définitive", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Êtes-vous sûr de vouloir supprimer définitivement tous les fichiers et dossiers dans la corbeille ? Cette action est irréversible.", diff --git a/apps/files_trashbin/l10n/fr.json b/apps/files_trashbin/l10n/fr.json index 2c27f497191..d1de6ea7032 100644 --- a/apps/files_trashbin/l10n/fr.json +++ b/apps/files_trashbin/l10n/fr.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Cette application permet aux personnes de restaurer des fichiers qui ont été supprimés du système.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Cette application permet aux personnes de restaurer les fichiers qui ont été supprimés du système. Il affiche une liste de fichiers supprimés dans l'interface Web et dispose d'options pour restaurer ces fichiers supprimés dans les dossiers de fichiers des personnes ou les supprimer définitivement du système. La restauration d'un fichier restaure également les versions de fichiers associées, si l'application de versions est activée. Lorsqu'un fichier est supprimé d'un partage, il peut être restauré de la même manière, bien qu'il ne soit plus partagé. Par défaut, ces fichiers restent dans la corbeille pendant 30 jours.\n\nPour empêcher un compte de manquer d'espace disque, l'application \"Fichiers supprimés\" n'utilisera pas plus de 50 % du quota actuellement disponible pour les fichiers supprimés. Si les fichiers supprimés dépassent cette limite, l'application supprime les fichiers les plus anciens jusqu'à ce qu'elle soit inférieure à cette limite. Plus d'informations sont disponibles dans la documentation Fichiers supprimés.", "Restore" : "Restaurer", + "Not enough free space to restore the file/folder" : "Espace libre insuffisant pour restaurer le fichier/dossier", "Empty deleted files" : "Vider les fichiers supprimés", "Confirm permanent deletion" : "Confirmer la suppression définitive", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Êtes-vous sûr de vouloir supprimer définitivement tous les fichiers et dossiers dans la corbeille ? Cette action est irréversible.", diff --git a/apps/files_trashbin/l10n/ja.js b/apps/files_trashbin/l10n/ja.js index cb018fc6275..a69b4f5179f 100644 --- a/apps/files_trashbin/l10n/ja.js +++ b/apps/files_trashbin/l10n/ja.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "このアプリケーションを使用すると、利用者はシステムから削除されたファイルを復元できます。", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "このアプリケーションを使用すると、システムから削除されたファイルを復元できます。Webインターフェイスには削除されたファイルのリストが表示され、これらの削除されたファイルを元の場所に復元するか、システムから完全に削除するかを選択できます。バージョン管理アプリが有効になっている場合、ファイルを復元すると関連するファイルのバージョンも復元されます。削除された共有ファイルは同じ方法で復元できますが、共有は復元されません。デフォルトでは、これらのファイルは30日間ごみ箱に残ります。\nアカウントのディスク容量が不足しないようにするため、削除済みファイルアプリでは削除済みファイルに現在利用可能な割り当て容量の50%を超える容量は使用されません。削除されたファイルがこの制限を超えると、この制限以下になるまでアプリは最も古いファイルを削除し続けます。詳細は「削除済みファイル」のドキュメントで確認できます。", "Restore" : "復元", + "Not enough free space to restore the file/folder" : "ファイル/フォルダーを復元するのに十分な空き容量がありません", "Empty deleted files" : "削除済みファイルを空にする", "Confirm permanent deletion" : "完全削除を承認", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "ごみ箱のすべてのファイルとフォルダーを完全に削除しますか?この操作は元に戻すことができません。", diff --git a/apps/files_trashbin/l10n/ja.json b/apps/files_trashbin/l10n/ja.json index 42e94b18508..b6f02fd21b7 100644 --- a/apps/files_trashbin/l10n/ja.json +++ b/apps/files_trashbin/l10n/ja.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "このアプリケーションを使用すると、利用者はシステムから削除されたファイルを復元できます。", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "このアプリケーションを使用すると、システムから削除されたファイルを復元できます。Webインターフェイスには削除されたファイルのリストが表示され、これらの削除されたファイルを元の場所に復元するか、システムから完全に削除するかを選択できます。バージョン管理アプリが有効になっている場合、ファイルを復元すると関連するファイルのバージョンも復元されます。削除された共有ファイルは同じ方法で復元できますが、共有は復元されません。デフォルトでは、これらのファイルは30日間ごみ箱に残ります。\nアカウントのディスク容量が不足しないようにするため、削除済みファイルアプリでは削除済みファイルに現在利用可能な割り当て容量の50%を超える容量は使用されません。削除されたファイルがこの制限を超えると、この制限以下になるまでアプリは最も古いファイルを削除し続けます。詳細は「削除済みファイル」のドキュメントで確認できます。", "Restore" : "復元", + "Not enough free space to restore the file/folder" : "ファイル/フォルダーを復元するのに十分な空き容量がありません", "Empty deleted files" : "削除済みファイルを空にする", "Confirm permanent deletion" : "完全削除を承認", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "ごみ箱のすべてのファイルとフォルダーを完全に削除しますか?この操作は元に戻すことができません。", diff --git a/apps/files_trashbin/l10n/pt_BR.js b/apps/files_trashbin/l10n/pt_BR.js index 59a67c33b48..6b13836148f 100644 --- a/apps/files_trashbin/l10n/pt_BR.js +++ b/apps/files_trashbin/l10n/pt_BR.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Este aplicativo permite que as pessoas restaurem arquivos que foram excluídos do sistema.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Este aplicativo permite que as pessoas restaurem arquivos que foram excluídos do sistema. Ele exibe uma lista de arquivos excluídos na interface da web e tem opções para restaurar esses arquivos excluídos de volta aos diretórios de arquivos de pessoas ou removê-los permanentemente do sistema. A restauração de um arquivo também restaura versões de arquivos relacionadas, se o aplicativo de versões estiver ativado. Quando um arquivo é excluído de um compartilhamento, ele pode ser restaurado da mesma maneira, embora não seja mais compartilhado. Por padrão, esses arquivos permanecem na lixeira por 30 dias. \nPara evitar que uma conta fique sem espaço em disco, o aplicativo Arquivos excluídos não utilizará mais de 50% da cota livre atualmente disponível para arquivos excluídos. Se os arquivos excluídos excederem esse limite, o aplicativo excluirá os arquivos mais antigos até ficarem abaixo desse limite. Mais informações estão disponíveis na documentação Arquivos Excluídos.", "Restore" : "Restaurar", + "Not enough free space to restore the file/folder" : "Não há espaço livre suficiente para restaurar o arquivo/pasta", "Empty deleted files" : "Esvaziar arquivos excluídos", "Confirm permanent deletion" : "Confirme exclusão permanente", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Tem certeza de que deseja excluir permanentemente todos os arquivos e pastas na lixeira? Isso não pode ser desfeito.", diff --git a/apps/files_trashbin/l10n/pt_BR.json b/apps/files_trashbin/l10n/pt_BR.json index 3cdbaad0f17..c2f8ba9a033 100644 --- a/apps/files_trashbin/l10n/pt_BR.json +++ b/apps/files_trashbin/l10n/pt_BR.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Este aplicativo permite que as pessoas restaurem arquivos que foram excluídos do sistema.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Este aplicativo permite que as pessoas restaurem arquivos que foram excluídos do sistema. Ele exibe uma lista de arquivos excluídos na interface da web e tem opções para restaurar esses arquivos excluídos de volta aos diretórios de arquivos de pessoas ou removê-los permanentemente do sistema. A restauração de um arquivo também restaura versões de arquivos relacionadas, se o aplicativo de versões estiver ativado. Quando um arquivo é excluído de um compartilhamento, ele pode ser restaurado da mesma maneira, embora não seja mais compartilhado. Por padrão, esses arquivos permanecem na lixeira por 30 dias. \nPara evitar que uma conta fique sem espaço em disco, o aplicativo Arquivos excluídos não utilizará mais de 50% da cota livre atualmente disponível para arquivos excluídos. Se os arquivos excluídos excederem esse limite, o aplicativo excluirá os arquivos mais antigos até ficarem abaixo desse limite. Mais informações estão disponíveis na documentação Arquivos Excluídos.", "Restore" : "Restaurar", + "Not enough free space to restore the file/folder" : "Não há espaço livre suficiente para restaurar o arquivo/pasta", "Empty deleted files" : "Esvaziar arquivos excluídos", "Confirm permanent deletion" : "Confirme exclusão permanente", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Tem certeza de que deseja excluir permanentemente todos os arquivos e pastas na lixeira? Isso não pode ser desfeito.", diff --git a/apps/files_trashbin/l10n/sr.js b/apps/files_trashbin/l10n/sr.js index 8b7cdafed96..cf8b15bda0e 100644 --- a/apps/files_trashbin/l10n/sr.js +++ b/apps/files_trashbin/l10n/sr.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Ова апликација омогућава људима да опораве фајлове који су обрисани са система.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Ова апликација омогућава корисницима да опораве фајлове који су обрисани са система . Она у веб интерфејсу приказује списак обрисаних фајлова и има опције да се они опораве назад у директоријуме или да се неповратно обришу са система. Ако је укључена апликација за управљање верзијама, враћање фајла такође враћа и све његове верзије. Када се фајл избрише из дељене фасцикле, може се повратити на исти начин, али више није дељен. Подразумевано, ови фајлови остају у канти 30 дана.\nДа би се спречило да налог остане без простора на диску, апликација за обрисане фајлове неће користити више од 50% тренутно доступне квоте. Ако обрисани фајлови пређу ову границу, апликација ће брисати најстарије фајлове док величина заузетих фајлова не падне испод ове границе. Више информација је доступно у документацији за Обрисане фајлове.", "Restore" : "Врати", + "Not enough free space to restore the file/folder" : "Нема довољно слободног простора за враћање фајла/фолдера", "Empty deleted files" : "Испразни обрисане фајлове", "Confirm permanent deletion" : "Потврдите трајно брисање", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Да ли сте сигурни да желите трајно да обришете све фајлове и фолдере у корпи за отпад? Ово не може да се поништи.", diff --git a/apps/files_trashbin/l10n/sr.json b/apps/files_trashbin/l10n/sr.json index 31f8cd3b448..113eda95347 100644 --- a/apps/files_trashbin/l10n/sr.json +++ b/apps/files_trashbin/l10n/sr.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Ова апликација омогућава људима да опораве фајлове који су обрисани са система.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Ова апликација омогућава корисницима да опораве фајлове који су обрисани са система . Она у веб интерфејсу приказује списак обрисаних фајлова и има опције да се они опораве назад у директоријуме или да се неповратно обришу са система. Ако је укључена апликација за управљање верзијама, враћање фајла такође враћа и све његове верзије. Када се фајл избрише из дељене фасцикле, може се повратити на исти начин, али више није дељен. Подразумевано, ови фајлови остају у канти 30 дана.\nДа би се спречило да налог остане без простора на диску, апликација за обрисане фајлове неће користити више од 50% тренутно доступне квоте. Ако обрисани фајлови пређу ову границу, апликација ће брисати најстарије фајлове док величина заузетих фајлова не падне испод ове границе. Више информација је доступно у документацији за Обрисане фајлове.", "Restore" : "Врати", + "Not enough free space to restore the file/folder" : "Нема довољно слободног простора за враћање фајла/фолдера", "Empty deleted files" : "Испразни обрисане фајлове", "Confirm permanent deletion" : "Потврдите трајно брисање", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Да ли сте сигурни да желите трајно да обришете све фајлове и фолдере у корпи за отпад? Ово не може да се поништи.", diff --git a/apps/files_trashbin/l10n/sv.js b/apps/files_trashbin/l10n/sv.js index 39fe5bd3f27..fd50574e6fc 100644 --- a/apps/files_trashbin/l10n/sv.js +++ b/apps/files_trashbin/l10n/sv.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "Denna app gör det möjligt för användare att återställa filer som raderats från systemet.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Denna applikation gör det möjligt för användare att återställa filer som tagits bort från systemet. Den visar en lista över borttagna filer i webbgränssnittet, och har alternativ för att återställa de borttagna filerna tillbaka till användarfilkataloger eller ta bort dem permanent från systemet. Återställa en fil återställer också relaterade filversioner, om versionsprogrammet är aktiverat. När en delad fil tas bort från kan den återställas på samma sätt, med är inte längre delad. Som standard ligger filerna i papperskorgen i 30 dagar.\nFör att förhindra att en användare får slut på diskutrymme kommer appen Borttagna filer inte att använda mer än 50% av den tillgängliga oanvända utrymmeskvoten för att lagra borttagna filer. Om storleken på borttagna filerna överskrider gränsen raderar appen de äldsta filerna tills den kommer under gränsen. Mer information finns i dokumentationen för Borttagna filer.", "Restore" : "Återskapa", + "Not enough free space to restore the file/folder" : "Inte tillräckligt med ledigt utrymme för att återställa filen/mappen", "Empty deleted files" : "Töm raderade filer", "Confirm permanent deletion" : "Bekräfta permanent radering", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Är du säker på att du vill radera alla filer och mappar i papperskorgen permanent? Detta kan inte ångras.", diff --git a/apps/files_trashbin/l10n/sv.json b/apps/files_trashbin/l10n/sv.json index 5cc6c187a71..1bf54bf7379 100644 --- a/apps/files_trashbin/l10n/sv.json +++ b/apps/files_trashbin/l10n/sv.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "Denna app gör det möjligt för användare att återställa filer som raderats från systemet.", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "Denna applikation gör det möjligt för användare att återställa filer som tagits bort från systemet. Den visar en lista över borttagna filer i webbgränssnittet, och har alternativ för att återställa de borttagna filerna tillbaka till användarfilkataloger eller ta bort dem permanent från systemet. Återställa en fil återställer också relaterade filversioner, om versionsprogrammet är aktiverat. När en delad fil tas bort från kan den återställas på samma sätt, med är inte längre delad. Som standard ligger filerna i papperskorgen i 30 dagar.\nFör att förhindra att en användare får slut på diskutrymme kommer appen Borttagna filer inte att använda mer än 50% av den tillgängliga oanvända utrymmeskvoten för att lagra borttagna filer. Om storleken på borttagna filerna överskrider gränsen raderar appen de äldsta filerna tills den kommer under gränsen. Mer information finns i dokumentationen för Borttagna filer.", "Restore" : "Återskapa", + "Not enough free space to restore the file/folder" : "Inte tillräckligt med ledigt utrymme för att återställa filen/mappen", "Empty deleted files" : "Töm raderade filer", "Confirm permanent deletion" : "Bekräfta permanent radering", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Är du säker på att du vill radera alla filer och mappar i papperskorgen permanent? Detta kan inte ångras.", diff --git a/apps/files_trashbin/l10n/zh_CN.js b/apps/files_trashbin/l10n/zh_CN.js index 83cdeb467d4..01d38f9b146 100644 --- a/apps/files_trashbin/l10n/zh_CN.js +++ b/apps/files_trashbin/l10n/zh_CN.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "此应用程序使人们能够恢复从系统中删除的文件。", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此应用程序使人们能够恢复从系统中删除的文件。它在web界面中显示已删除文件的列表,并可以选择将这些已删除的文件还原回人员文件目录或从系统中永久删除这些文件。如果启用了版本应用程序,恢复文件也会恢复相关的文件版本。当文件从共享中删除时,可以以相同的方式恢复,尽管不再共享。默认情况下,这些文件将在垃圾桶中保留30天。\n为了防止帐户磁盘空间不足,“已删除文件”应用程序将不会为已删除文件使用超过当前可用可用配额的50%。如果删除的文件超过此限制,应用程序将删除最旧的文件,直到其低于此限制。有关详细信息,请参阅“已删除的文件”文档。", "Restore" : "恢复", + "Not enough free space to restore the file/folder" : "空间不足,无法恢复文件/文件夹", "Empty deleted files" : "清空已删除的文件", "Confirm permanent deletion" : "确认永久删除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "是否确定要永久删除回收站中的所有文件和文件夹?此操作无法撤销。", diff --git a/apps/files_trashbin/l10n/zh_CN.json b/apps/files_trashbin/l10n/zh_CN.json index a1f624394cc..6e6f307f2f6 100644 --- a/apps/files_trashbin/l10n/zh_CN.json +++ b/apps/files_trashbin/l10n/zh_CN.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "此应用程序使人们能够恢复从系统中删除的文件。", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此应用程序使人们能够恢复从系统中删除的文件。它在web界面中显示已删除文件的列表,并可以选择将这些已删除的文件还原回人员文件目录或从系统中永久删除这些文件。如果启用了版本应用程序,恢复文件也会恢复相关的文件版本。当文件从共享中删除时,可以以相同的方式恢复,尽管不再共享。默认情况下,这些文件将在垃圾桶中保留30天。\n为了防止帐户磁盘空间不足,“已删除文件”应用程序将不会为已删除文件使用超过当前可用可用配额的50%。如果删除的文件超过此限制,应用程序将删除最旧的文件,直到其低于此限制。有关详细信息,请参阅“已删除的文件”文档。", "Restore" : "恢复", + "Not enough free space to restore the file/folder" : "空间不足,无法恢复文件/文件夹", "Empty deleted files" : "清空已删除的文件", "Confirm permanent deletion" : "确认永久删除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "是否确定要永久删除回收站中的所有文件和文件夹?此操作无法撤销。", diff --git a/apps/files_trashbin/l10n/zh_HK.js b/apps/files_trashbin/l10n/zh_HK.js index 9a13dce5326..b42546937ab 100644 --- a/apps/files_trashbin/l10n/zh_HK.js +++ b/apps/files_trashbin/l10n/zh_HK.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "此應用程式讓人仕可以還原他們在系統當中刪除的檔案", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此應用程式讓使用可以還原從系統中刪除的檔案。其會在網路界面中顯示已刪除的檔案列表,並有選項可以復原那些檔案到用戶的檔案目錄,或是將它們從系統中永久移除。若啟用了版本應用程式,復原檔案也會復原相關的檔案版本。當檔案從分享中刪除時,雖然不再共享,但可以用相同的方式來還原。預設情況下,這些檔案會在回收桶中保留30天。\n為了避免帳戶耗盡磁碟空間,「已刪除檔案」應用程式將不會用於超過目前可用配額 50% 的已刪除檔案。如果已刪除的檔案超過此限制,應用程式將會刪除最舊的檔案,直到低於此限制為止。更多資訊在「已刪除檔案」的說明書中提供。", "Restore" : "還原", + "Not enough free space to restore the file/folder" : "空間不足,不能還原檔案/資料夾", "Empty deleted files" : "清空已刪除的檔案", "Confirm permanent deletion" : "確認永久刪除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "您確定要永久刪除回收桶中的所有檔案與資料夾嗎?這無法還原。", diff --git a/apps/files_trashbin/l10n/zh_HK.json b/apps/files_trashbin/l10n/zh_HK.json index d45a562fcb2..2c0fc46bb03 100644 --- a/apps/files_trashbin/l10n/zh_HK.json +++ b/apps/files_trashbin/l10n/zh_HK.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "此應用程式讓人仕可以還原他們在系統當中刪除的檔案", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此應用程式讓使用可以還原從系統中刪除的檔案。其會在網路界面中顯示已刪除的檔案列表,並有選項可以復原那些檔案到用戶的檔案目錄,或是將它們從系統中永久移除。若啟用了版本應用程式,復原檔案也會復原相關的檔案版本。當檔案從分享中刪除時,雖然不再共享,但可以用相同的方式來還原。預設情況下,這些檔案會在回收桶中保留30天。\n為了避免帳戶耗盡磁碟空間,「已刪除檔案」應用程式將不會用於超過目前可用配額 50% 的已刪除檔案。如果已刪除的檔案超過此限制,應用程式將會刪除最舊的檔案,直到低於此限制為止。更多資訊在「已刪除檔案」的說明書中提供。", "Restore" : "還原", + "Not enough free space to restore the file/folder" : "空間不足,不能還原檔案/資料夾", "Empty deleted files" : "清空已刪除的檔案", "Confirm permanent deletion" : "確認永久刪除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "您確定要永久刪除回收桶中的所有檔案與資料夾嗎?這無法還原。", diff --git a/apps/files_trashbin/l10n/zh_TW.js b/apps/files_trashbin/l10n/zh_TW.js index 879c5aee231..2deb89b49de 100644 --- a/apps/files_trashbin/l10n/zh_TW.js +++ b/apps/files_trashbin/l10n/zh_TW.js @@ -7,6 +7,7 @@ OC.L10N.register( "This application enables people to restore files that were deleted from the system." : "此應用程式讓使用者可以還原他們在系統當中刪除的檔案", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此應用程式讓使用可以還原從系統中刪除的檔案。其會在網路介面中顯示已刪除的檔案列表,並有選項可以復原那些檔案到使用者的檔案目錄,或是將它們從系統中永久移除。若啟用了版本應用程式,復原檔案也會復原相關的檔案版本。當檔案從分享中刪除時,雖然不再共享,但可以用相同的方式來還原。預設情況下,這些檔案會在回收桶中保留30天。\n為了避免使用者耗盡磁碟空間,「回收桶」應用程式將不會用於超過目前可用配額 50% 的已刪除檔案。如果已刪除的檔案超過此限制,應用程式將會刪除最舊的檔案,直到低於此限制為止。更多資訊在「回收桶」的文件中提供。", "Restore" : "還原", + "Not enough free space to restore the file/folder" : "空間不足,無法還原檔案/資料夾", "Empty deleted files" : "清空已刪除的檔案", "Confirm permanent deletion" : "確認永久刪除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "您確定您想要永久刪除回收桶中的所有檔案與資料夾嗎?這無法還原。", diff --git a/apps/files_trashbin/l10n/zh_TW.json b/apps/files_trashbin/l10n/zh_TW.json index 176a8861e08..ba719d2b0e6 100644 --- a/apps/files_trashbin/l10n/zh_TW.json +++ b/apps/files_trashbin/l10n/zh_TW.json @@ -5,6 +5,7 @@ "This application enables people to restore files that were deleted from the system." : "此應用程式讓使用者可以還原他們在系統當中刪除的檔案", "This application enables people to restore files that were deleted from the system. It displays a list of deleted files in the web interface, and has options to restore those deleted files back to the people file directories or remove them permanently from the system. Restoring a file also restores related file versions, if the versions application is enabled. When a file is deleted from a share, it can be restored in the same manner, though it is no longer shared. By default, these files remain in the trash bin for 30 days.\nTo prevent an account from running out of disk space, the Deleted files app will not utilize more than 50% of the currently available free quota for deleted files. If the deleted files exceed this limit, the app deletes the oldest files until it gets below this limit. More information is available in the Deleted Files documentation." : "此應用程式讓使用可以還原從系統中刪除的檔案。其會在網路介面中顯示已刪除的檔案列表,並有選項可以復原那些檔案到使用者的檔案目錄,或是將它們從系統中永久移除。若啟用了版本應用程式,復原檔案也會復原相關的檔案版本。當檔案從分享中刪除時,雖然不再共享,但可以用相同的方式來還原。預設情況下,這些檔案會在回收桶中保留30天。\n為了避免使用者耗盡磁碟空間,「回收桶」應用程式將不會用於超過目前可用配額 50% 的已刪除檔案。如果已刪除的檔案超過此限制,應用程式將會刪除最舊的檔案,直到低於此限制為止。更多資訊在「回收桶」的文件中提供。", "Restore" : "還原", + "Not enough free space to restore the file/folder" : "空間不足,無法還原檔案/資料夾", "Empty deleted files" : "清空已刪除的檔案", "Confirm permanent deletion" : "確認永久刪除", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "您確定您想要永久刪除回收桶中的所有檔案與資料夾嗎?這無法還原。", diff --git a/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php b/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php index ee833e6beb8..9468fb7add0 100644 --- a/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php +++ b/apps/files_trashbin/tests/BackgroundJob/ExpireTrashTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,23 +20,12 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class ExpireTrashTest extends TestCase { - /** @var IAppConfig&MockObject */ - private $appConfig; - - /** @var IUserManager&MockObject */ - private $userManager; - - /** @var Expiration&MockObject */ - private $expiration; - - /** @var IJobList&MockObject */ - private $jobList; - - /** @var LoggerInterface&MockObject */ - private $logger; - - /** @var ITimeFactory&MockObject */ - private $time; + private IAppConfig&MockObject $appConfig; + private IUserManager&MockObject $userManager; + private Expiration&MockObject $expiration; + private IJobList&MockObject $jobList; + private LoggerInterface&MockObject $logger; + private ITimeFactory&MockObject $time; protected function setUp(): void { parent::setUp(); diff --git a/apps/files_trashbin/tests/CapabilitiesTest.php b/apps/files_trashbin/tests/CapabilitiesTest.php index a5e4e79aefd..1c460cc5665 100644 --- a/apps/files_trashbin/tests/CapabilitiesTest.php +++ b/apps/files_trashbin/tests/CapabilitiesTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -9,9 +11,7 @@ use OCA\Files_Trashbin\Capabilities; use Test\TestCase; class CapabilitiesTest extends TestCase { - - /** @var Capabilities */ - private $capabilities; + private Capabilities $capabilities; protected function setUp(): void { parent::setUp(); diff --git a/apps/files_trashbin/tests/Command/CleanUpTest.php b/apps/files_trashbin/tests/Command/CleanUpTest.php index 25d38752e91..3dce8f0c92e 100644 --- a/apps/files_trashbin/tests/Command/CleanUpTest.php +++ b/apps/files_trashbin/tests/Command/CleanUpTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -6,12 +8,13 @@ */ namespace OCA\Files_Trashbin\Tests\Command; -use OC\User\Manager; use OCA\Files_Trashbin\Command\CleanUp; use OCP\Files\IRootFolder; use OCP\IDBConnection; +use OCP\IUserManager; use OCP\Server; use OCP\UserInterface; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Exception\InvalidOptionException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\NullOutput; @@ -26,31 +29,17 @@ use Test\TestCase; * @package OCA\Files_Trashbin\Tests\Command */ class CleanUpTest extends TestCase { - - /** @var CleanUp */ - protected $cleanup; - - /** @var \PHPUnit\Framework\MockObject\MockObject | Manager */ - protected $userManager; - - /** @var \PHPUnit\Framework\MockObject\MockObject | IRootFolder */ - protected $rootFolder; - - /** @var IDBConnection */ - protected $dbConnection; - - /** @var string */ - protected $trashTable = 'files_trash'; - - /** @var string */ - protected $user0 = 'user0'; + protected IUserManager&MockObject $userManager; + protected IRootFolder&MockObject $rootFolder; + protected IDBConnection $dbConnection; + protected CleanUp $cleanup; + protected string $trashTable = 'files_trash'; + protected string $user0 = 'user0'; protected function setUp(): void { parent::setUp(); - $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder') - ->disableOriginalConstructor()->getMock(); - $this->userManager = $this->getMockBuilder('OC\User\Manager') - ->disableOriginalConstructor()->getMock(); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->userManager = $this->createMock(IUserManager::class); $this->dbConnection = Server::get(IDBConnection::class); @@ -60,9 +49,9 @@ class CleanUpTest extends TestCase { /** * populate files_trash table with 10 dummy values */ - public function initTable() { + public function initTable(): void { $query = $this->dbConnection->getQueryBuilder(); - $query->delete($this->trashTable)->execute(); + $query->delete($this->trashTable)->executeStatement(); for ($i = 0; $i < 10; $i++) { $query->insert($this->trashTable) ->values([ @@ -70,19 +59,18 @@ class CleanUpTest extends TestCase { 'timestamp' => $query->expr()->literal($i), 'location' => $query->expr()->literal('.'), 'user' => $query->expr()->literal('user' . $i % 2) - ])->execute(); + ])->executeStatement(); } $getAllQuery = $this->dbConnection->getQueryBuilder(); $result = $getAllQuery->select('id') ->from($this->trashTable) - ->execute() + ->executeQuery() ->fetchAll(); - $this->assertSame(10, count($result)); + $this->assertCount(10, $result); } /** * @dataProvider dataTestRemoveDeletedFiles - * @param boolean $nodeExists */ public function testRemoveDeletedFiles(bool $nodeExists): void { $this->initTable(); @@ -101,7 +89,7 @@ class CleanUpTest extends TestCase { $this->rootFolder->expects($this->never())->method('get'); $this->rootFolder->expects($this->never())->method('delete'); } - $this->invokePrivate($this->cleanup, 'removeDeletedFiles', [$this->user0, new NullOutput(), false]); + self::invokePrivate($this->cleanup, 'removeDeletedFiles', [$this->user0, new NullOutput(), false]); if ($nodeExists) { // if the delete operation was executed only files from user1 @@ -110,11 +98,11 @@ class CleanUpTest extends TestCase { $query->select('user') ->from($this->trashTable); - $qResult = $query->execute(); + $qResult = $query->executeQuery(); $result = $qResult->fetchAll(); $qResult->closeCursor(); - $this->assertSame(5, count($result)); + $this->assertCount(5, $result); foreach ($result as $r) { $this->assertSame('user1', $r['user']); } @@ -124,12 +112,12 @@ class CleanUpTest extends TestCase { $getAllQuery = $this->dbConnection->getQueryBuilder(); $result = $getAllQuery->select('id') ->from($this->trashTable) - ->execute() + ->executeQuery() ->fetchAll(); - $this->assertSame(10, count($result)); + $this->assertCount(10, $result); } } - public function dataTestRemoveDeletedFiles() { + public static function dataTestRemoveDeletedFiles(): array { return [ [true], [false] @@ -141,8 +129,8 @@ class CleanUpTest extends TestCase { */ public function testExecuteDeleteListOfUsers(): void { $userIds = ['user1', 'user2', 'user3']; - $instance = $this->getMockBuilder('OCA\Files_Trashbin\Command\CleanUp') - ->setMethods(['removeDeletedFiles']) + $instance = $this->getMockBuilder(\OCA\Files_Trashbin\Command\CleanUp::class) + ->onlyMethods(['removeDeletedFiles']) ->setConstructorArgs([$this->rootFolder, $this->userManager, $this->dbConnection]) ->getMock(); $instance->expects($this->exactly(count($userIds))) @@ -152,8 +140,7 @@ class CleanUpTest extends TestCase { }); $this->userManager->expects($this->exactly(count($userIds))) ->method('userExists')->willReturn(true); - $inputInterface = $this->getMockBuilder('\Symfony\Component\Console\Input\InputInterface') - ->disableOriginalConstructor()->getMock(); + $inputInterface = $this->createMock(\Symfony\Component\Console\Input\InputInterface::class); $inputInterface->method('getArgument') ->with('user_id') ->willReturn($userIds); @@ -162,9 +149,8 @@ class CleanUpTest extends TestCase { ['all-users', false], ['verbose', false], ]); - $outputInterface = $this->getMockBuilder('\Symfony\Component\Console\Output\OutputInterface') - ->disableOriginalConstructor()->getMock(); - $this->invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]); + $outputInterface = $this->createMock(\Symfony\Component\Console\Output\OutputInterface::class); + self::invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]); } /** @@ -173,8 +159,8 @@ class CleanUpTest extends TestCase { public function testExecuteAllUsers(): void { $userIds = []; $backendUsers = ['user1', 'user2']; - $instance = $this->getMockBuilder('OCA\Files_Trashbin\Command\CleanUp') - ->setMethods(['removeDeletedFiles']) + $instance = $this->getMockBuilder(\OCA\Files_Trashbin\Command\CleanUp::class) + ->onlyMethods(['removeDeletedFiles']) ->setConstructorArgs([$this->rootFolder, $this->userManager, $this->dbConnection]) ->getMock(); $backend = $this->createMock(UserInterface::class); @@ -199,7 +185,7 @@ class CleanUpTest extends TestCase { $this->userManager ->method('getBackends') ->willReturn([$backend]); - $this->invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]); + self::invokePrivate($instance, 'execute', [$inputInterface, $outputInterface]); } public function testExecuteNoUsersAndNoAllUsers(): void { @@ -217,7 +203,7 @@ class CleanUpTest extends TestCase { $this->expectException(InvalidOptionException::class); $this->expectExceptionMessage('Either specify a user_id or --all-users'); - $this->invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]); + self::invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]); } public function testExecuteUsersAndAllUsers(): void { @@ -235,6 +221,6 @@ class CleanUpTest extends TestCase { $this->expectException(InvalidOptionException::class); $this->expectExceptionMessage('Either specify a user_id or --all-users'); - $this->invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]); + self::invokePrivate($this->cleanup, 'execute', [$inputInterface, $outputInterface]); } } diff --git a/apps/files_trashbin/tests/Command/ExpireTest.php b/apps/files_trashbin/tests/Command/ExpireTest.php index 4402e07bbb0..5a66dac8c6e 100644 --- a/apps/files_trashbin/tests/Command/ExpireTest.php +++ b/apps/files_trashbin/tests/Command/ExpireTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/files_trashbin/tests/Controller/PreviewControllerTest.php b/apps/files_trashbin/tests/Controller/PreviewControllerTest.php index 1076870bb9f..bb951c9c8c7 100644 --- a/apps/files_trashbin/tests/Controller/PreviewControllerTest.php +++ b/apps/files_trashbin/tests/Controller/PreviewControllerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -20,32 +22,18 @@ use OCP\IPreview; use OCP\IRequest; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class PreviewControllerTest extends TestCase { - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var string */ - private $userId; - - /** @var IMimeTypeDetector|\PHPUnit\Framework\MockObject\MockObject */ - private $mimeTypeDetector; - - /** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */ - private $previewManager; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $time; - - /** @var PreviewController */ - private $controller; - - /** @var ITrashManager|\PHPUnit\Framework\MockObject\MockObject */ - private $trashManager; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - private $userSession; + private IRootFolder&MockObject $rootFolder; + private string $userId; + private IMimeTypeDetector&MockObject $mimeTypeDetector; + private IPreview&MockObject $previewManager; + private ITimeFactory&MockObject $time; + private ITrashManager&MockObject $trashManager; + private IUserSession&MockObject $userSession; + private PreviewController $controller; protected function setUp(): void { parent::setUp(); diff --git a/apps/files_trashbin/tests/ExpirationTest.php b/apps/files_trashbin/tests/ExpirationTest.php index 7f026c16806..aab07de8162 100644 --- a/apps/files_trashbin/tests/ExpirationTest.php +++ b/apps/files_trashbin/tests/ExpirationTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -16,7 +18,7 @@ class ExpirationTest extends \Test\TestCase { public const FAKE_TIME_NOW = 1000000; - public function expirationData() { + public static function expirationData(): array { $today = 100 * self::SECONDS_PER_DAY; $back10Days = (100 - 10) * self::SECONDS_PER_DAY; $back20Days = (100 - 20) * self::SECONDS_PER_DAY; @@ -82,14 +84,8 @@ class ExpirationTest extends \Test\TestCase { /** * @dataProvider expirationData - * - * @param string $retentionObligation - * @param int $timeNow - * @param int $timestamp - * @param bool $quotaExceeded - * @param string $expectedResult */ - public function testExpiration($retentionObligation, $timeNow, $timestamp, $quotaExceeded, $expectedResult): void { + public function testExpiration(string $retentionObligation, int $timeNow, int $timestamp, bool $quotaExceeded, bool $expectedResult): void { $mockedConfig = $this->getMockedConfig($retentionObligation); $mockedTimeFactory = $this->getMockedTimeFactory($timeNow); @@ -100,7 +96,7 @@ class ExpirationTest extends \Test\TestCase { } - public function timestampTestData(): array { + public static function timestampTestData(): array { return [ [ 'disabled', false], [ 'auto', false ], @@ -116,11 +112,8 @@ class ExpirationTest extends \Test\TestCase { /** * @dataProvider timestampTestData - * - * @param string $configValue - * @param int $expectedMaxAgeTimestamp */ - public function testGetMaxAgeAsTimestamp($configValue, $expectedMaxAgeTimestamp): void { + public function testGetMaxAgeAsTimestamp(string $configValue, bool|int $expectedMaxAgeTimestamp): void { $mockedConfig = $this->getMockedConfig($configValue); $mockedTimeFactory = $this->getMockedTimeFactory( self::FAKE_TIME_NOW @@ -132,10 +125,9 @@ class ExpirationTest extends \Test\TestCase { } /** - * @param int $time * @return ITimeFactory|MockObject */ - private function getMockedTimeFactory($time) { + private function getMockedTimeFactory(int $time) { $mockedTimeFactory = $this->createMock(ITimeFactory::class); $mockedTimeFactory->expects($this->any()) ->method('getTime') @@ -145,10 +137,9 @@ class ExpirationTest extends \Test\TestCase { } /** - * @param string $returnValue * @return IConfig|MockObject */ - private function getMockedConfig($returnValue) { + private function getMockedConfig(string $returnValue) { $mockedConfig = $this->createMock(IConfig::class); $mockedConfig->expects($this->any()) ->method('getSystemValue') diff --git a/apps/files_trashbin/tests/Sabre/TrashbinPluginTest.php b/apps/files_trashbin/tests/Sabre/TrashbinPluginTest.php index 60cc69ba09d..6c566afc738 100644 --- a/apps/files_trashbin/tests/Sabre/TrashbinPluginTest.php +++ b/apps/files_trashbin/tests/Sabre/TrashbinPluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -33,19 +34,23 @@ class TrashbinPluginTest extends TestCase { */ public function testQuota(int $quota, int $fileSize, bool $expectedResult): void { $fileInfo = $this->createMock(ITrashItem::class); - $fileInfo->method('getSize')->willReturn($fileSize); + $fileInfo->method('getSize') + ->willReturn($fileSize); $trashNode = $this->createMock(ITrash::class); - $trashNode->method('getFileInfo')->willReturn($fileInfo); + $trashNode->method('getFileInfo') + ->willReturn($fileInfo); $restoreNode = $this->createMock(RestoreFolder::class); - $this->server->tree->method('getNodeForPath')->willReturn($trashNode, $restoreNode); + $this->server->tree->method('getNodeForPath') + ->willReturn($trashNode, $restoreNode); $previewManager = $this->createMock(IPreview::class); $view = $this->createMock(View::class); - $view->method('free_space')->willReturn($quota); + $view->method('free_space') + ->willReturn($quota); $plugin = new TrashbinPlugin($previewManager, $view); $plugin->initialize($this->server); @@ -55,7 +60,7 @@ class TrashbinPluginTest extends TestCase { $this->assertEquals($expectedResult, $plugin->beforeMove($sourcePath, $destinationPath)); } - public function quotaProvider(): array { + public static function quotaProvider(): array { return [ [ 1024, 512, true ], [ 512, 513, false ], diff --git a/apps/files_trashbin/tests/StorageTest.php b/apps/files_trashbin/tests/StorageTest.php index 5c73e47b307..2b2508a358b 100644 --- a/apps/files_trashbin/tests/StorageTest.php +++ b/apps/files_trashbin/tests/StorageTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -27,6 +29,7 @@ use OCP\IUserManager; use OCP\Lock\ILockingProvider; use OCP\Server; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\Traits\MountProviderTrait; @@ -50,20 +53,9 @@ class TemporaryNoCross extends Temporary { class StorageTest extends \Test\TestCase { use MountProviderTrait; - /** - * @var string - */ - private $user; - - /** - * @var View - */ - private $rootView; - - /** - * @var View - */ - private $userView; + private string $user; + private View $rootView; + private View $userView; // 239 chars so appended timestamp of 12 chars will exceed max length of 250 chars private const LONG_FILENAME = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt'; @@ -121,7 +113,7 @@ class StorageTest extends \Test\TestCase { // check if file is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('test.txt', substr($name, 0, strrpos($name, '.'))); } @@ -138,7 +130,7 @@ class StorageTest extends \Test\TestCase { // check if folder is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('folder', substr($name, 0, strrpos($name, '.'))); @@ -162,7 +154,7 @@ class StorageTest extends \Test\TestCase { // check if file is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals($truncatedFilename, substr($name, 0, strrpos($name, '.'))); } @@ -181,7 +173,7 @@ class StorageTest extends \Test\TestCase { // check if file is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals($truncatedFilename, substr($name, 0, strrpos($name, '.'))); } @@ -207,7 +199,7 @@ class StorageTest extends \Test\TestCase { // check if file is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('subfile.txt', substr($name, 0, strrpos($name, '.'))); } @@ -234,12 +226,12 @@ class StorageTest extends \Test\TestCase { // check if folder is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('folder', substr($name, 0, strrpos($name, '.'))); $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/' . $name . '/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('subfile.txt', $name); } @@ -262,13 +254,13 @@ class StorageTest extends \Test\TestCase { // check if versions are in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -279,7 +271,7 @@ class StorageTest extends \Test\TestCase { $this->userView->file_put_contents('folder/inside.txt', 'v1'); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/folder/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $this->userView->rmdir('folder'); @@ -289,19 +281,19 @@ class StorageTest extends \Test\TestCase { // check if versions are in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('folder.d', substr($name, 0, strlen('folder.d'))); // check if versions are in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/' . $name . '/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('inside.txt.v', substr($name, 0, strlen('inside.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/folder/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -314,12 +306,12 @@ class StorageTest extends \Test\TestCase { $this->userView->file_put_contents('share/test.txt', 'v2'); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $recipientUser = $this->getUniqueId('recipient_'); Server::get(IUserManager::class)->createUser($recipientUser, $recipientUser); - $node = \OC::$server->getUserFolder($this->user)->get('share'); + $node = \OCP\Server::get(IRootFolder::class)->getUserFolder($this->user)->get('share'); $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setNode($node) ->setShareType(IShare::TYPE_USER) @@ -341,18 +333,18 @@ class StorageTest extends \Test\TestCase { // check if versions are in trashbin for both users $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); - $this->assertEquals(1, count($results), 'Versions in owner\'s trashbin'); + $this->assertCount(1, $results, 'Versions in owner\'s trashbin'); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions'); - $this->assertEquals(1, count($results), 'Versions in recipient\'s trashbin'); + $this->assertCount(1, $results, 'Versions in recipient\'s trashbin'); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -366,12 +358,11 @@ class StorageTest extends \Test\TestCase { $this->userView->file_put_contents('share/folder/test.txt', 'v2'); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/folder/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $recipientUser = $this->getUniqueId('recipient_'); Server::get(IUserManager::class)->createUser($recipientUser, $recipientUser); - - $node = \OC::$server->getUserFolder($this->user)->get('share'); + $node = \OCP\Server::get(IRootFolder::class)->getUserFolder($this->user)->get('share'); $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setNode($node) ->setShareType(IShare::TYPE_USER) @@ -393,31 +384,31 @@ class StorageTest extends \Test\TestCase { // check if versions are in trashbin for owner $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('folder.d', substr($name, 0, strlen('folder.d'))); // check if file versions are in trashbin for owner $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/' . $name . '/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // check if versions are in trashbin for recipient $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('folder.d', substr($name, 0, strlen('folder.d'))); // check if file versions are in trashbin for recipient $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions/' . $name . '/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($recipientUser . '/files_versions/share/folder/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -433,10 +424,10 @@ class StorageTest extends \Test\TestCase { $this->userView->file_put_contents('test.txt', 'v1'); $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); // move to another storage $this->userView->rename('test.txt', 'substorage/test.txt'); @@ -448,15 +439,15 @@ class StorageTest extends \Test\TestCase { // versions were moved too $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/substorage'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); // check that nothing got trashed by the rename's unlink() call $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); // check that versions were moved and not trashed $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -472,10 +463,10 @@ class StorageTest extends \Test\TestCase { $this->userView->file_put_contents('folder/inside.txt', 'v1'); $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/folder/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); // move to another storage $this->userView->rename('folder', 'substorage/folder'); @@ -487,15 +478,15 @@ class StorageTest extends \Test\TestCase { // versions were moved too $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/substorage/folder/'); - $this->assertEquals(1, count($results)); + $this->assertCount(1, $results); // check that nothing got trashed by the rename's unlink() call $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); // check that versions were moved and not trashed $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -503,11 +494,11 @@ class StorageTest extends \Test\TestCase { */ public function testSingleStorageDeleteFileFail(): void { /** - * @var Temporary|\PHPUnit\Framework\MockObject\MockObject $storage + * @var Temporary&MockObject $storage */ - $storage = $this->getMockBuilder('\OC\Files\Storage\Temporary') + $storage = $this->getMockBuilder(\OC\Files\Storage\Temporary::class) ->setConstructorArgs([[]]) - ->setMethods(['rename', 'unlink', 'moveFromStorage']) + ->onlyMethods(['rename', 'unlink', 'moveFromStorage']) ->getMock(); $storage->expects($this->any()) @@ -532,7 +523,7 @@ class StorageTest extends \Test\TestCase { // file should not be in the trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** @@ -540,11 +531,11 @@ class StorageTest extends \Test\TestCase { */ public function testSingleStorageDeleteFolderFail(): void { /** - * @var Temporary|\PHPUnit\Framework\MockObject\MockObject $storage + * @var Temporary&MockObject $storage */ - $storage = $this->getMockBuilder('\OC\Files\Storage\Temporary') + $storage = $this->getMockBuilder(\OC\Files\Storage\Temporary::class) ->setConstructorArgs([[]]) - ->setMethods(['rename', 'unlink', 'rmdir']) + ->onlyMethods(['rename', 'unlink', 'rmdir']) ->getMock(); $storage->expects($this->any()) @@ -566,18 +557,17 @@ class StorageTest extends \Test\TestCase { // file should not be in the trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files/'); - $this->assertEquals(0, count($results)); + $this->assertCount(0, $results); } /** * @dataProvider dataTestShouldMoveToTrash */ - public function testShouldMoveToTrash($mountPoint, $path, $userExists, $appDisablesTrash, $expected): void { + public function testShouldMoveToTrash(string $mountPoint, string $path, bool $userExists, bool $appDisablesTrash, bool $expected): void { $fileID = 1; $cache = $this->createMock(ICache::class); $cache->expects($this->any())->method('getId')->willReturn($fileID); - $tmpStorage = $this->getMockBuilder('\OC\Files\Storage\Temporary') - ->disableOriginalConstructor()->getMock($cache); + $tmpStorage = $this->createMock(\OC\Files\Storage\Temporary::class); $tmpStorage->expects($this->any())->method('getCache')->willReturn($cache); $userManager = $this->getMockBuilder(IUserManager::class) ->disableOriginalConstructor()->getMock(); @@ -606,7 +596,9 @@ class StorageTest extends \Test\TestCase { $eventDispatcher, $rootFolder ] - )->setMethods(['createMoveToTrashEvent'])->getMock(); + ) + ->onlyMethods(['createMoveToTrashEvent']) + ->getMock(); $storage->expects($this->any())->method('createMoveToTrashEvent')->with($node) ->willReturn($event); @@ -616,7 +608,7 @@ class StorageTest extends \Test\TestCase { ); } - public function dataTestShouldMoveToTrash() { + public static function dataTestShouldMoveToTrash(): array { return [ ['/schiesbn/', '/files/test.txt', true, false, true], ['/schiesbn/', '/files/test.txt', false, false, false], diff --git a/apps/files_trashbin/tests/TrashbinTest.php b/apps/files_trashbin/tests/TrashbinTest.php index 3d2ceee0dcd..d8486ccbdc2 100644 --- a/apps/files_trashbin/tests/TrashbinTest.php +++ b/apps/files_trashbin/tests/TrashbinTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -22,6 +24,7 @@ use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Constants; use OCP\Files\FileInfo; +use OCP\Files\IRootFolder; use OCP\IConfig; use OCP\IDBConnection; use OCP\IUserManager; @@ -41,16 +44,8 @@ class TrashbinTest extends \Test\TestCase { private $trashRoot2; private static $rememberRetentionObligation; - - /** - * @var bool - */ - private static $trashBinStatus; - - /** - * @var View - */ - private $rootView; + private static bool $trashBinStatus; + private View $rootView; public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); @@ -74,7 +69,7 @@ class TrashbinTest extends \Test\TestCase { $config = Server::get(IConfig::class); //configure trashbin - self::$rememberRetentionObligation = $config->getSystemValue('trashbin_retention_obligation', Expiration::DEFAULT_RETENTION_OBLIGATION); + self::$rememberRetentionObligation = (string)$config->getSystemValue('trashbin_retention_obligation', Expiration::DEFAULT_RETENTION_OBLIGATION); /** @var Expiration $expiration */ $expiration = Server::get(Expiration::class); $expiration->setRetentionObligation('auto, 2'); @@ -190,14 +185,14 @@ class TrashbinTest extends \Test\TestCase { // only file2.txt should be left $remainingFiles = array_slice($manipulatedList, $count); - $this->assertSame(1, count($remainingFiles)); + $this->assertCount(1, $remainingFiles); $remainingFile = reset($remainingFiles); // TODO: failing test #$this->assertSame('file2.txt', $remainingFile['name']); // check that file1.txt and file3.txt was really deleted $newTrashContent = Helper::getTrashFiles('/', self::TEST_TRASHBIN_USER1); - $this->assertSame(1, count($newTrashContent)); + $this->assertCount(1, $newTrashContent); $element = reset($newTrashContent); // TODO: failing test #$this->assertSame('file2.txt', $element['name']); @@ -285,8 +280,8 @@ class TrashbinTest extends \Test\TestCase { * @param FileInfo[] $result * @param string[] $expected */ - private function verifyArray($result, $expected) { - $this->assertSame(count($expected), count($result)); + private function verifyArray(array $result, array $expected): void { + $this->assertCount(count($expected), $result); foreach ($expected as $expectedFile) { $found = false; foreach ($result as $fileInTrash) { @@ -304,10 +299,8 @@ class TrashbinTest extends \Test\TestCase { /** * @param FileInfo[] $files - * @param string $trashRoot - * @param integer $expireDate */ - private function manipulateDeleteTime($files, $trashRoot, $expireDate) { + private function manipulateDeleteTime(array $files, string $trashRoot, int $expireDate): array { $counter = 0; foreach ($files as &$file) { // modify every second file @@ -361,7 +354,7 @@ class TrashbinTest extends \Test\TestCase { * Test restoring a file */ public function testRestoreFileInRoot(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $file = $userFolder->newFile('file1.txt'); $file->putContent('foo'); @@ -393,7 +386,7 @@ class TrashbinTest extends \Test\TestCase { * Test restoring a file in subfolder */ public function testRestoreFileInSubfolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -426,7 +419,7 @@ class TrashbinTest extends \Test\TestCase { * Test restoring a folder */ public function testRestoreFolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -459,7 +452,7 @@ class TrashbinTest extends \Test\TestCase { * Test restoring a file from inside a trashed folder */ public function testRestoreFileFromTrashedSubfolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -493,7 +486,7 @@ class TrashbinTest extends \Test\TestCase { * The file should then land in the root. */ public function testRestoreFileWithMissingSourceFolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -530,7 +523,7 @@ class TrashbinTest extends \Test\TestCase { * with the same name in the root folder */ public function testRestoreFileDoesNotOverwriteExistingInRoot(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $file = $userFolder->newFile('file1.txt'); $file->putContent('foo'); @@ -570,7 +563,7 @@ class TrashbinTest extends \Test\TestCase { * with the same name in the source folder */ public function testRestoreFileDoesNotOverwriteExistingInSubfolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -624,7 +617,7 @@ class TrashbinTest extends \Test\TestCase { * the file to root instead */ public function testRestoreFileIntoReadOnlySourceFolder(): void { - $userFolder = \OC::$server->getUserFolder(); + $userFolder = \OCP\Server::get(IRootFolder::class)->getUserFolder(self::TEST_TRASHBIN_USER1); $folder = $userFolder->newFolder('folder'); $file = $folder->newFile('file1.txt'); $file->putContent('foo'); @@ -680,7 +673,7 @@ class TrashbinTest extends \Test\TestCase { Filesystem::tearDown(); \OC_User::setUserId($user); \OC_Util::setupFS($user); - \OC::$server->getUserFolder($user); + \OCP\Server::get(IRootFolder::class)->getUserFolder($user); } } diff --git a/apps/files_versions/l10n/fa.js b/apps/files_versions/l10n/fa.js index c2bbbcd6487..6f50077efdc 100644 --- a/apps/files_versions/l10n/fa.js +++ b/apps/files_versions/l10n/fa.js @@ -4,6 +4,7 @@ OC.L10N.register( "Versions" : "نسخه ها", "This application automatically maintains older versions of files that are changed." : "این برنامه به طور خودکار نسخه های قدیمی تر پرونده های تغییر یافته را حفظ می کند.", "Current version" : "نسخه فعلی", + "You" : "You", "Name this version" : "Name this version", "Edit version name" : "Edit version name", "Compare to current version" : "Compare to current version", diff --git a/apps/files_versions/l10n/fa.json b/apps/files_versions/l10n/fa.json index a5afce9ed79..a96d8d4cd31 100644 --- a/apps/files_versions/l10n/fa.json +++ b/apps/files_versions/l10n/fa.json @@ -2,6 +2,7 @@ "Versions" : "نسخه ها", "This application automatically maintains older versions of files that are changed." : "این برنامه به طور خودکار نسخه های قدیمی تر پرونده های تغییر یافته را حفظ می کند.", "Current version" : "نسخه فعلی", + "You" : "You", "Name this version" : "Name this version", "Edit version name" : "Edit version name", "Compare to current version" : "Compare to current version", diff --git a/apps/files_versions/src/views/VersionTab.vue b/apps/files_versions/src/views/VersionTab.vue index 48e07b7c786..a643aef439d 100644 --- a/apps/files_versions/src/views/VersionTab.vue +++ b/apps/files_versions/src/views/VersionTab.vue @@ -203,7 +203,7 @@ export default { try { await restoreVersion(version) - if (version.label !== '') { + if (version.label) { showSuccess(t('files_versions', `${version.label} restored`)) } else if (version.mtime === this.initialVersionMtime) { showSuccess(t('files_versions', 'Initial version restored')) diff --git a/apps/settings/appinfo/routes.php b/apps/settings/appinfo/routes.php index 5038cf33348..b0ce73113f4 100644 --- a/apps/settings/appinfo/routes.php +++ b/apps/settings/appinfo/routes.php @@ -67,6 +67,7 @@ return [ ], 'ocs' => [ ['name' => 'DeclarativeSettings#setValue', 'url' => '/settings/api/declarative/value', 'verb' => 'POST', 'root' => ''], + ['name' => 'DeclarativeSettings#setSensitiveValue', 'url' => '/settings/api/declarative/value-sensitive', 'verb' => 'POST', 'root' => ''], ['name' => 'DeclarativeSettings#getForms', 'url' => '/settings/api/declarative/forms', 'verb' => 'GET', 'root' => ''], ], ]; diff --git a/apps/settings/l10n/ar.js b/apps/settings/l10n/ar.js index 090a78608d1..0a9d06a2801 100644 --- a/apps/settings/l10n/ar.js +++ b/apps/settings/l10n/ar.js @@ -561,6 +561,7 @@ OC.L10N.register( "Unable to update profile default setting" : "تعذّر تحديث الإعدادات التلقائية لملف التعريف الشخصي profile", "Profile" : "الملف الشخصي", "Enable or disable profile by default for new accounts." : "تمكين أو تعطيل الملف الشخصي بشكل افتراضي للحسابات الجديدة.", + "Password confirmation is required" : "مِن الواجب تأكيد كلمة السر", "Failed to save setting" : "فشل في حفظ الإعداد", "{app}'s declarative setting field: {name}" : "حقل الإعدادات التصريحي للتطبيق {app} : {name}", "Unable to update server side encryption config" : "تعذر تحديث تهيئة التشفير من جانب الخادم", diff --git a/apps/settings/l10n/ar.json b/apps/settings/l10n/ar.json index 17a3dfd8ab1..a4dc6b6f069 100644 --- a/apps/settings/l10n/ar.json +++ b/apps/settings/l10n/ar.json @@ -559,6 +559,7 @@ "Unable to update profile default setting" : "تعذّر تحديث الإعدادات التلقائية لملف التعريف الشخصي profile", "Profile" : "الملف الشخصي", "Enable or disable profile by default for new accounts." : "تمكين أو تعطيل الملف الشخصي بشكل افتراضي للحسابات الجديدة.", + "Password confirmation is required" : "مِن الواجب تأكيد كلمة السر", "Failed to save setting" : "فشل في حفظ الإعداد", "{app}'s declarative setting field: {name}" : "حقل الإعدادات التصريحي للتطبيق {app} : {name}", "Unable to update server side encryption config" : "تعذر تحديث تهيئة التشفير من جانب الخادم", diff --git a/apps/settings/l10n/ast.js b/apps/settings/l10n/ast.js index 486987db360..b907cc087a2 100644 --- a/apps/settings/l10n/ast.js +++ b/apps/settings/l10n/ast.js @@ -317,6 +317,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Nun ye posible anovar la opción predeterminada del sirvidor", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Des/activa'l perfil predetermináu pa les cuentes nueves.", + "Password confirmation is required" : "Ríquese la contraseña de confirmación", "Failed to save setting" : "Nun se pue guardar la opción", "Unable to update server side encryption config" : "Nun ye posible anovar la configuración del cifráu del sirvidor", "Server-side encryption" : "Cifráu de llau del sirvidor", diff --git a/apps/settings/l10n/ast.json b/apps/settings/l10n/ast.json index 5bc8daf9690..0c193d60c9e 100644 --- a/apps/settings/l10n/ast.json +++ b/apps/settings/l10n/ast.json @@ -315,6 +315,7 @@ "Unable to update profile default setting" : "Nun ye posible anovar la opción predeterminada del sirvidor", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Des/activa'l perfil predetermináu pa les cuentes nueves.", + "Password confirmation is required" : "Ríquese la contraseña de confirmación", "Failed to save setting" : "Nun se pue guardar la opción", "Unable to update server side encryption config" : "Nun ye posible anovar la configuración del cifráu del sirvidor", "Server-side encryption" : "Cifráu de llau del sirvidor", diff --git a/apps/settings/l10n/ca.js b/apps/settings/l10n/ca.js index 48c3db87cc9..78317fdb107 100644 --- a/apps/settings/l10n/ca.js +++ b/apps/settings/l10n/ca.js @@ -556,6 +556,7 @@ OC.L10N.register( "Unable to update profile default setting" : "No s'ha pogut actualitzar els paràmetres predeterminats del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilita o deshabilita el perfil de manera predeterminada per als comptes nous.", + "Password confirmation is required" : "Cal una confirmació de la contrasenya", "Failed to save setting" : "No s'ha pogut desar el paràmetre", "{app}'s declarative setting field: {name}" : "Camp de paràmetre declaratiu de {app}: {name}", "Unable to update server side encryption config" : "No es pot actualitzar la configuració del xifratge de la banda del servidor", diff --git a/apps/settings/l10n/ca.json b/apps/settings/l10n/ca.json index 7326c853f79..7115c52cd4f 100644 --- a/apps/settings/l10n/ca.json +++ b/apps/settings/l10n/ca.json @@ -554,6 +554,7 @@ "Unable to update profile default setting" : "No s'ha pogut actualitzar els paràmetres predeterminats del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilita o deshabilita el perfil de manera predeterminada per als comptes nous.", + "Password confirmation is required" : "Cal una confirmació de la contrasenya", "Failed to save setting" : "No s'ha pogut desar el paràmetre", "{app}'s declarative setting field: {name}" : "Camp de paràmetre declaratiu de {app}: {name}", "Unable to update server side encryption config" : "No es pot actualitzar la configuració del xifratge de la banda del servidor", diff --git a/apps/settings/l10n/cs.js b/apps/settings/l10n/cs.js index 43dcbe059d8..a39adab6030 100644 --- a/apps/settings/l10n/cs.js +++ b/apps/settings/l10n/cs.js @@ -316,6 +316,9 @@ OC.L10N.register( "64-bit" : "64bit", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Zdá se, že provozujete 32bitovou verzi PHP. Aby správně fungoval, potřebuje Nextcloud 64bit. Přejděte na 64bit instalaci operačního systému a PHP!", "Task Processing pickup speed" : "Rychlost vyzvedávání zpracovávání úkolů", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."], "Temporary space available" : "Dočasný prostor k dispozici", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Chyba při kontrole popisu umístění dočasných souborů PHP – nebylo správně nastaveno na složku. Vrácená hodnota: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funkce „disk_free_space“ je vypnutá, což brání v kontrolách zda je k dispozici dostatek místa ve složkách pro dočasná data.", @@ -562,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Nedaří se aktualizovat výchozí nastavení pro profily", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profily nově vytvářených účtů ve výchozím stavu zpřístupňovat nebo nezpřístupňovat.", + "Password confirmation is required" : "Je vyžadováno potvrzení hesla", "Failed to save setting" : "Nastavení se nepodařilo uložit", "{app}'s declarative setting field: {name}" : "Kolonka deklarativního nastavení {app}: {name}", "Unable to update server side encryption config" : "Nedaří se zaktualizovat nastavení šifrování na straně serveru", @@ -584,9 +588,12 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Je vždy dobré vytvářet pravidelné zálohy svých dat. V případě zapnutého šifrování také společně s daty zajistěte zálohu šifrovacích klíčů k nim.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Ohledně toho, jak ručně zašifrovat také existující soubory, nahlédněte do dokumentace pro správce.", "This is the final warning: Do you really want to enable encryption?" : "Toto je poslední varování: Opravdu chcete zapnout šifrování?", + "Failed to delete group \"{group}\"" : "Nepodařilo se vytvořit skupinu „{group}“", "Please confirm the group removal" : "Potvrďte odstranění skupiny", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Chystáte se smazat skupinu „{group}“. Účty k ní přiřazené nebudou smazány.", "Submit" : "Odeslat", "Rename group" : "Přejmenovat skupinu", + "Delete group" : "Smazat skupinu", "Current password" : "Stávající heslo", "New password" : "Nové heslo", "Change password" : "Změnit heslo", diff --git a/apps/settings/l10n/cs.json b/apps/settings/l10n/cs.json index d9170738a45..7f9ab60d49f 100644 --- a/apps/settings/l10n/cs.json +++ b/apps/settings/l10n/cs.json @@ -314,6 +314,9 @@ "64-bit" : "64bit", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Zdá se, že provozujete 32bitovou verzi PHP. Aby správně fungoval, potřebuje Nextcloud 64bit. Přejděte na 64bit instalaci operačního systému a PHP!", "Task Processing pickup speed" : "Rychlost vyzvedávání zpracovávání úkolů", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."], "Temporary space available" : "Dočasný prostor k dispozici", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Chyba při kontrole popisu umístění dočasných souborů PHP – nebylo správně nastaveno na složku. Vrácená hodnota: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funkce „disk_free_space“ je vypnutá, což brání v kontrolách zda je k dispozici dostatek místa ve složkách pro dočasná data.", @@ -560,6 +563,7 @@ "Unable to update profile default setting" : "Nedaří se aktualizovat výchozí nastavení pro profily", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profily nově vytvářených účtů ve výchozím stavu zpřístupňovat nebo nezpřístupňovat.", + "Password confirmation is required" : "Je vyžadováno potvrzení hesla", "Failed to save setting" : "Nastavení se nepodařilo uložit", "{app}'s declarative setting field: {name}" : "Kolonka deklarativního nastavení {app}: {name}", "Unable to update server side encryption config" : "Nedaří se zaktualizovat nastavení šifrování na straně serveru", @@ -582,9 +586,12 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Je vždy dobré vytvářet pravidelné zálohy svých dat. V případě zapnutého šifrování také společně s daty zajistěte zálohu šifrovacích klíčů k nim.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Ohledně toho, jak ručně zašifrovat také existující soubory, nahlédněte do dokumentace pro správce.", "This is the final warning: Do you really want to enable encryption?" : "Toto je poslední varování: Opravdu chcete zapnout šifrování?", + "Failed to delete group \"{group}\"" : "Nepodařilo se vytvořit skupinu „{group}“", "Please confirm the group removal" : "Potvrďte odstranění skupiny", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Chystáte se smazat skupinu „{group}“. Účty k ní přiřazené nebudou smazány.", "Submit" : "Odeslat", "Rename group" : "Přejmenovat skupinu", + "Delete group" : "Smazat skupinu", "Current password" : "Stávající heslo", "New password" : "Nové heslo", "Change password" : "Změnit heslo", diff --git a/apps/settings/l10n/da.js b/apps/settings/l10n/da.js index 25a420a553c..69c8621816f 100644 --- a/apps/settings/l10n/da.js +++ b/apps/settings/l10n/da.js @@ -561,6 +561,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Kan ikke opdatere profilens standardindstilling", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktiver eller deaktiver profil som standard for nye konti.", + "Password confirmation is required" : "Password beskæftigelse er påkrævet", "Failed to save setting" : "Kunne ikke gemme indstillingerne", "{app}'s declarative setting field: {name}" : "{app}'s deklarative indstillingsfelt: {name}", "Unable to update server side encryption config" : "Kan ikke opdatere krypteringskonfigurationen på serversiden", diff --git a/apps/settings/l10n/da.json b/apps/settings/l10n/da.json index 785504a66d6..95c703ca492 100644 --- a/apps/settings/l10n/da.json +++ b/apps/settings/l10n/da.json @@ -559,6 +559,7 @@ "Unable to update profile default setting" : "Kan ikke opdatere profilens standardindstilling", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktiver eller deaktiver profil som standard for nye konti.", + "Password confirmation is required" : "Password beskæftigelse er påkrævet", "Failed to save setting" : "Kunne ikke gemme indstillingerne", "{app}'s declarative setting field: {name}" : "{app}'s deklarative indstillingsfelt: {name}", "Unable to update server side encryption config" : "Kan ikke opdatere krypteringskonfigurationen på serversiden", diff --git a/apps/settings/l10n/de.js b/apps/settings/l10n/de.js index 3602e2d006f..91e260f30d2 100644 --- a/apps/settings/l10n/de.js +++ b/apps/settings/l10n/de.js @@ -565,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.", + "Password confirmation is required" : "Passwortbestätigung erforderlich", "Failed to save setting" : "Einstellung konnte nicht gespeichert werden", "{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}", "Unable to update server side encryption config" : "Die Serverseitige Verschlüsselungskonfiguration kann nicht aktualisiert werden.", diff --git a/apps/settings/l10n/de.json b/apps/settings/l10n/de.json index 99d27a1fda2..b16e4a100ca 100644 --- a/apps/settings/l10n/de.json +++ b/apps/settings/l10n/de.json @@ -563,6 +563,7 @@ "Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.", + "Password confirmation is required" : "Passwortbestätigung erforderlich", "Failed to save setting" : "Einstellung konnte nicht gespeichert werden", "{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}", "Unable to update server side encryption config" : "Die Serverseitige Verschlüsselungskonfiguration kann nicht aktualisiert werden.", diff --git a/apps/settings/l10n/de_DE.js b/apps/settings/l10n/de_DE.js index 42a07d455f6..70a2c10b712 100644 --- a/apps/settings/l10n/de_DE.js +++ b/apps/settings/l10n/de_DE.js @@ -565,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.", + "Password confirmation is required" : "Passwortbestätigung erforderlich", "Failed to save setting" : "Einstellung konnte nicht gespeichert werden", "{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}", "Unable to update server side encryption config" : "Serverseitige Verschlüsselungskonfiguration kann nicht aktualisiert werden", diff --git a/apps/settings/l10n/de_DE.json b/apps/settings/l10n/de_DE.json index 88cf5adad09..3f18effb1af 100644 --- a/apps/settings/l10n/de_DE.json +++ b/apps/settings/l10n/de_DE.json @@ -563,6 +563,7 @@ "Unable to update profile default setting" : "Standardeinstellung des Profils kann nicht aktualisiert werden", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Profil für neue Konten standardmäßig aktivieren oder deaktivieren.", + "Password confirmation is required" : "Passwortbestätigung erforderlich", "Failed to save setting" : "Einstellung konnte nicht gespeichert werden", "{app}'s declarative setting field: {name}" : "Deklaratives Einstellungsfeld von {app}: {name}", "Unable to update server side encryption config" : "Serverseitige Verschlüsselungskonfiguration kann nicht aktualisiert werden", diff --git a/apps/settings/l10n/el.js b/apps/settings/l10n/el.js index 35428772687..cb72e8d87e8 100644 --- a/apps/settings/l10n/el.js +++ b/apps/settings/l10n/el.js @@ -556,6 +556,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Δεν είναι δυνατή η ενημέρωση της προεπιλεγμένης ρύθμισης προφίλ", "Profile" : "Προφίλ", "Enable or disable profile by default for new accounts." : "Ενεργοποίηση ή απενεργοποίηση του προφίλ από προεπιλογή για νέους λογαριασμούς.", + "Password confirmation is required" : "Απαιτείται επιβεβαίωση συνθηματικού", "Failed to save setting" : "Αποτυχία αποθήκευσης ρύθμισης", "{app}'s declarative setting field: {name}" : "Δηλωτικό πεδίο ρύθμισης της {app}: {name}", "Unable to update server side encryption config" : "Δεν είναι δυνατή η ενημέρωση της διαμόρφωσης κρυπτογράφησης από τον διακομιστή", diff --git a/apps/settings/l10n/el.json b/apps/settings/l10n/el.json index 5581a729e84..3ed97a9b0d2 100644 --- a/apps/settings/l10n/el.json +++ b/apps/settings/l10n/el.json @@ -554,6 +554,7 @@ "Unable to update profile default setting" : "Δεν είναι δυνατή η ενημέρωση της προεπιλεγμένης ρύθμισης προφίλ", "Profile" : "Προφίλ", "Enable or disable profile by default for new accounts." : "Ενεργοποίηση ή απενεργοποίηση του προφίλ από προεπιλογή για νέους λογαριασμούς.", + "Password confirmation is required" : "Απαιτείται επιβεβαίωση συνθηματικού", "Failed to save setting" : "Αποτυχία αποθήκευσης ρύθμισης", "{app}'s declarative setting field: {name}" : "Δηλωτικό πεδίο ρύθμισης της {app}: {name}", "Unable to update server side encryption config" : "Δεν είναι δυνατή η ενημέρωση της διαμόρφωσης κρυπτογράφησης από τον διακομιστή", diff --git a/apps/settings/l10n/en_GB.js b/apps/settings/l10n/en_GB.js index 6fe88855e2a..6d127073390 100644 --- a/apps/settings/l10n/en_GB.js +++ b/apps/settings/l10n/en_GB.js @@ -565,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Unable to update profile default setting", "Profile" : "Profile", "Enable or disable profile by default for new accounts." : "Enable or disable profile by default for new accounts.", + "Password confirmation is required" : "Password confirmation is required", "Failed to save setting" : "Failed to save setting", "{app}'s declarative setting field: {name}" : "{app}'s declarative setting field: {name}", "Unable to update server side encryption config" : "Unable to update server side encryption config", diff --git a/apps/settings/l10n/en_GB.json b/apps/settings/l10n/en_GB.json index 6edf3535719..43c5bd06674 100644 --- a/apps/settings/l10n/en_GB.json +++ b/apps/settings/l10n/en_GB.json @@ -563,6 +563,7 @@ "Unable to update profile default setting" : "Unable to update profile default setting", "Profile" : "Profile", "Enable or disable profile by default for new accounts." : "Enable or disable profile by default for new accounts.", + "Password confirmation is required" : "Password confirmation is required", "Failed to save setting" : "Failed to save setting", "{app}'s declarative setting field: {name}" : "{app}'s declarative setting field: {name}", "Unable to update server side encryption config" : "Unable to update server side encryption config", diff --git a/apps/settings/l10n/eo.js b/apps/settings/l10n/eo.js index 350d94047ed..06e28ba9947 100644 --- a/apps/settings/l10n/eo.js +++ b/apps/settings/l10n/eo.js @@ -184,6 +184,7 @@ OC.L10N.register( "Password" : "Pasvorto", "Show QR code for mobile apps" : "Montri rapidrespondan (QR) kodon por porteblaj aplikaĵoj", "Use system cron service to call the cron.php file every 5 minutes." : "Uzu la sisteman „cron“-servon por voki cron.php ĉiujn 5 minutojn.", + "Password confirmation is required" : "Konfirmo per pasvorto estas bezonata", "Server-side encryption" : "Ĉeservila ĉifrado", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Ĉeservila ĉifrado elbigas ĉifri ĉiujn alŝutitajn dosierojn al la servilo. Tio havas kelkajn limigojn kiel pli malbonan rendimenton, do ŝaltu tion nur se necese.", "Enable server-side encryption" : "Ŝalti ĉeservilan ĉifradon", diff --git a/apps/settings/l10n/eo.json b/apps/settings/l10n/eo.json index a544b30e3b8..69066da132a 100644 --- a/apps/settings/l10n/eo.json +++ b/apps/settings/l10n/eo.json @@ -182,6 +182,7 @@ "Password" : "Pasvorto", "Show QR code for mobile apps" : "Montri rapidrespondan (QR) kodon por porteblaj aplikaĵoj", "Use system cron service to call the cron.php file every 5 minutes." : "Uzu la sisteman „cron“-servon por voki cron.php ĉiujn 5 minutojn.", + "Password confirmation is required" : "Konfirmo per pasvorto estas bezonata", "Server-side encryption" : "Ĉeservila ĉifrado", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Ĉeservila ĉifrado elbigas ĉifri ĉiujn alŝutitajn dosierojn al la servilo. Tio havas kelkajn limigojn kiel pli malbonan rendimenton, do ŝaltu tion nur se necese.", "Enable server-side encryption" : "Ŝalti ĉeservilan ĉifradon", diff --git a/apps/settings/l10n/es.js b/apps/settings/l10n/es.js index 16acba246bd..a3fa87392a5 100644 --- a/apps/settings/l10n/es.js +++ b/apps/settings/l10n/es.js @@ -561,6 +561,7 @@ OC.L10N.register( "Unable to update profile default setting" : "No se pudo actualizar la configuración por defecto del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para nuevas cuentas.", + "Password confirmation is required" : "Se requiere confirmar la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No ha sido posible actualizar la configuración de cifrado del lado del servidor", diff --git a/apps/settings/l10n/es.json b/apps/settings/l10n/es.json index 785ac75f4e2..5eef24dc6d8 100644 --- a/apps/settings/l10n/es.json +++ b/apps/settings/l10n/es.json @@ -559,6 +559,7 @@ "Unable to update profile default setting" : "No se pudo actualizar la configuración por defecto del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para nuevas cuentas.", + "Password confirmation is required" : "Se requiere confirmar la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No ha sido posible actualizar la configuración de cifrado del lado del servidor", diff --git a/apps/settings/l10n/es_419.js b/apps/settings/l10n/es_419.js index 060169db3c5..3c98bd49c67 100644 --- a/apps/settings/l10n/es_419.js +++ b/apps/settings/l10n/es_419.js @@ -141,6 +141,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_419.json b/apps/settings/l10n/es_419.json index 7e9807a489e..b12d7325c09 100644 --- a/apps/settings/l10n/es_419.json +++ b/apps/settings/l10n/es_419.json @@ -139,6 +139,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_AR.js b/apps/settings/l10n/es_AR.js index 41041921d38..d59ef68822e 100644 --- a/apps/settings/l10n/es_AR.js +++ b/apps/settings/l10n/es_AR.js @@ -321,6 +321,7 @@ OC.L10N.register( "Unable to update profile default setting" : "No se pudo actualizar la configuración por defecto del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para cuentas nuevas.", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado en el servidor", diff --git a/apps/settings/l10n/es_AR.json b/apps/settings/l10n/es_AR.json index 06007be894b..fcde0dc6f29 100644 --- a/apps/settings/l10n/es_AR.json +++ b/apps/settings/l10n/es_AR.json @@ -319,6 +319,7 @@ "Unable to update profile default setting" : "No se pudo actualizar la configuración por defecto del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para cuentas nuevas.", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado en el servidor", diff --git a/apps/settings/l10n/es_CL.js b/apps/settings/l10n/es_CL.js index 6c7dd7dc07b..1d8832fb00c 100644 --- a/apps/settings/l10n/es_CL.js +++ b/apps/settings/l10n/es_CL.js @@ -146,6 +146,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_CL.json b/apps/settings/l10n/es_CL.json index f2d5ffcc24b..e677524d91f 100644 --- a/apps/settings/l10n/es_CL.json +++ b/apps/settings/l10n/es_CL.json @@ -144,6 +144,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_CO.js b/apps/settings/l10n/es_CO.js index 1cdef45ea23..6ebc01eed9b 100644 --- a/apps/settings/l10n/es_CO.js +++ b/apps/settings/l10n/es_CO.js @@ -145,6 +145,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_CO.json b/apps/settings/l10n/es_CO.json index 5b848033331..bcfd961d441 100644 --- a/apps/settings/l10n/es_CO.json +++ b/apps/settings/l10n/es_CO.json @@ -143,6 +143,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_CR.js b/apps/settings/l10n/es_CR.js index afd38b6a676..05e8a04a4e4 100644 --- a/apps/settings/l10n/es_CR.js +++ b/apps/settings/l10n/es_CR.js @@ -145,6 +145,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_CR.json b/apps/settings/l10n/es_CR.json index 29af8abae99..ec1cf0e5c10 100644 --- a/apps/settings/l10n/es_CR.json +++ b/apps/settings/l10n/es_CR.json @@ -143,6 +143,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_DO.js b/apps/settings/l10n/es_DO.js index 01f57aaff73..59ebda24f9f 100644 --- a/apps/settings/l10n/es_DO.js +++ b/apps/settings/l10n/es_DO.js @@ -144,6 +144,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_DO.json b/apps/settings/l10n/es_DO.json index 49339aeba6b..3efba9cb8dd 100644 --- a/apps/settings/l10n/es_DO.json +++ b/apps/settings/l10n/es_DO.json @@ -142,6 +142,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_EC.js b/apps/settings/l10n/es_EC.js index 7dd6f5d44ea..b59d456ffe7 100644 --- a/apps/settings/l10n/es_EC.js +++ b/apps/settings/l10n/es_EC.js @@ -242,6 +242,7 @@ OC.L10N.register( "Cron (Recommended)" : "Cron (recomendado)", "Unable to update profile default setting" : "No se pudo actualizar la configuración predeterminada del perfil", "Profile" : "Perfil", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado en el servidor", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", diff --git a/apps/settings/l10n/es_EC.json b/apps/settings/l10n/es_EC.json index c1de3ff4f27..3de1fd6a3d7 100644 --- a/apps/settings/l10n/es_EC.json +++ b/apps/settings/l10n/es_EC.json @@ -240,6 +240,7 @@ "Cron (Recommended)" : "Cron (recomendado)", "Unable to update profile default setting" : "No se pudo actualizar la configuración predeterminada del perfil", "Profile" : "Perfil", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado en el servidor", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", diff --git a/apps/settings/l10n/es_GT.js b/apps/settings/l10n/es_GT.js index 1cb624e5b2a..2b01a8a4322 100644 --- a/apps/settings/l10n/es_GT.js +++ b/apps/settings/l10n/es_GT.js @@ -146,6 +146,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_GT.json b/apps/settings/l10n/es_GT.json index bf18aa594c3..bf45aa94919 100644 --- a/apps/settings/l10n/es_GT.json +++ b/apps/settings/l10n/es_GT.json @@ -144,6 +144,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_HN.js b/apps/settings/l10n/es_HN.js index 89f96aafe91..36887b920bc 100644 --- a/apps/settings/l10n/es_HN.js +++ b/apps/settings/l10n/es_HN.js @@ -140,6 +140,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_HN.json b/apps/settings/l10n/es_HN.json index b3dd690d60f..8218f1cd3eb 100644 --- a/apps/settings/l10n/es_HN.json +++ b/apps/settings/l10n/es_HN.json @@ -138,6 +138,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_MX.js b/apps/settings/l10n/es_MX.js index 450fd640b6f..89c92147826 100644 --- a/apps/settings/l10n/es_MX.js +++ b/apps/settings/l10n/es_MX.js @@ -452,6 +452,7 @@ OC.L10N.register( "Unable to update profile default setting" : "No se pudo actualizar la configuración predeterminada del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para nuevos usuarios.", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado del lado del servidor", diff --git a/apps/settings/l10n/es_MX.json b/apps/settings/l10n/es_MX.json index 171a15777a4..c078d42a628 100644 --- a/apps/settings/l10n/es_MX.json +++ b/apps/settings/l10n/es_MX.json @@ -450,6 +450,7 @@ "Unable to update profile default setting" : "No se pudo actualizar la configuración predeterminada del perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Habilitar o deshabilitar el perfil por defecto para nuevos usuarios.", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Failed to save setting" : "No se pudo guardar la configuración", "{app}'s declarative setting field: {name}" : "Campo de configuración declarativa de {app}: {name}", "Unable to update server side encryption config" : "No se pudo actualizar la configuración de cifrado del lado del servidor", diff --git a/apps/settings/l10n/es_NI.js b/apps/settings/l10n/es_NI.js index 1f2eb8600bc..a079e9af242 100644 --- a/apps/settings/l10n/es_NI.js +++ b/apps/settings/l10n/es_NI.js @@ -139,6 +139,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_NI.json b/apps/settings/l10n/es_NI.json index 42050e0f282..53aee7c602f 100644 --- a/apps/settings/l10n/es_NI.json +++ b/apps/settings/l10n/es_NI.json @@ -137,6 +137,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PA.js b/apps/settings/l10n/es_PA.js index 8f4f7bc1c4c..3f2e760215b 100644 --- a/apps/settings/l10n/es_PA.js +++ b/apps/settings/l10n/es_PA.js @@ -139,6 +139,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PA.json b/apps/settings/l10n/es_PA.json index b65f1115a57..4919eccf8ee 100644 --- a/apps/settings/l10n/es_PA.json +++ b/apps/settings/l10n/es_PA.json @@ -137,6 +137,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PE.js b/apps/settings/l10n/es_PE.js index ba80293df17..492f10fe19f 100644 --- a/apps/settings/l10n/es_PE.js +++ b/apps/settings/l10n/es_PE.js @@ -138,6 +138,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PE.json b/apps/settings/l10n/es_PE.json index 72e7f2ef6ad..7fc994c1cd5 100644 --- a/apps/settings/l10n/es_PE.json +++ b/apps/settings/l10n/es_PE.json @@ -136,6 +136,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PR.js b/apps/settings/l10n/es_PR.js index 8f4f7bc1c4c..3f2e760215b 100644 --- a/apps/settings/l10n/es_PR.js +++ b/apps/settings/l10n/es_PR.js @@ -139,6 +139,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PR.json b/apps/settings/l10n/es_PR.json index b65f1115a57..4919eccf8ee 100644 --- a/apps/settings/l10n/es_PR.json +++ b/apps/settings/l10n/es_PR.json @@ -137,6 +137,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PY.js b/apps/settings/l10n/es_PY.js index bbffec9fd0c..77b625b06cf 100644 --- a/apps/settings/l10n/es_PY.js +++ b/apps/settings/l10n/es_PY.js @@ -139,6 +139,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_PY.json b/apps/settings/l10n/es_PY.json index cf3c5d477bf..d1d464dc2fa 100644 --- a/apps/settings/l10n/es_PY.json +++ b/apps/settings/l10n/es_PY.json @@ -137,6 +137,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_SV.js b/apps/settings/l10n/es_SV.js index 1cb624e5b2a..2b01a8a4322 100644 --- a/apps/settings/l10n/es_SV.js +++ b/apps/settings/l10n/es_SV.js @@ -146,6 +146,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_SV.json b/apps/settings/l10n/es_SV.json index bf18aa594c3..bf45aa94919 100644 --- a/apps/settings/l10n/es_SV.json +++ b/apps/settings/l10n/es_SV.json @@ -144,6 +144,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_UY.js b/apps/settings/l10n/es_UY.js index a980eaf2c04..6da1a34b7c8 100644 --- a/apps/settings/l10n/es_UY.js +++ b/apps/settings/l10n/es_UY.js @@ -138,6 +138,7 @@ OC.L10N.register( "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/es_UY.json b/apps/settings/l10n/es_UY.json index e9c33a86cc9..5ce26032a55 100644 --- a/apps/settings/l10n/es_UY.json +++ b/apps/settings/l10n/es_UY.json @@ -136,6 +136,7 @@ "Create new app password" : "Crear una nueva contraseña de aplicación", "Login" : "Iniciar sesión", "Password" : "Contraseña", + "Password confirmation is required" : "Se requiere la confirmación de la contraseña", "Server-side encryption" : "Encripción del lado del servidor", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La encripción del lado del servidor hace posible encriptar archivos que serán cargados a este servidor. Esto trae consigo algunas limitaciónes como penalizaciones en el desemeño, asi que habilítalo sólo si es necesario. ", "Enable server-side encryption" : "Habilitar encripción del lado del servidor", diff --git a/apps/settings/l10n/et_EE.js b/apps/settings/l10n/et_EE.js index 285f952e240..e7fe29f42dd 100644 --- a/apps/settings/l10n/et_EE.js +++ b/apps/settings/l10n/et_EE.js @@ -365,6 +365,7 @@ OC.L10N.register( "Last job ran {relativeTime}." : "Viimane käivitus kestis {relativeTime}.", "Unable to update profile default setting" : "Profiili vaikimisi seadistuste uuendamine ei õnnestu", "Profile" : "Profiil", + "Password confirmation is required" : "Salasõna kinnitamine on vajalik", "Failed to save setting" : "Seadistuse salvestamine ei õnnestunud", "Unable to update server side encryption config" : "Serveripoolse krüptimise seadistusi ei õnnestu uuendada", "Server-side encryption" : "Serveripoolne krüptimine", diff --git a/apps/settings/l10n/et_EE.json b/apps/settings/l10n/et_EE.json index 2b8aa5ff9e9..a27534910f2 100644 --- a/apps/settings/l10n/et_EE.json +++ b/apps/settings/l10n/et_EE.json @@ -363,6 +363,7 @@ "Last job ran {relativeTime}." : "Viimane käivitus kestis {relativeTime}.", "Unable to update profile default setting" : "Profiili vaikimisi seadistuste uuendamine ei õnnestu", "Profile" : "Profiil", + "Password confirmation is required" : "Salasõna kinnitamine on vajalik", "Failed to save setting" : "Seadistuse salvestamine ei õnnestunud", "Unable to update server side encryption config" : "Serveripoolse krüptimise seadistusi ei õnnestu uuendada", "Server-side encryption" : "Serveripoolne krüptimine", diff --git a/apps/settings/l10n/eu.js b/apps/settings/l10n/eu.js index 7de527044a4..3f16da14521 100644 --- a/apps/settings/l10n/eu.js +++ b/apps/settings/l10n/eu.js @@ -522,6 +522,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Ezin izan da eguneratu profilaren ezarpen lehenetsia", "Profile" : "Profila", "Enable or disable profile by default for new accounts." : "Gaitu edo desgaitu profila lehenespenez kontu berrientzat.", + "Password confirmation is required" : "Pasahitza konfirmatzea beharrezkoa da", "Failed to save setting" : "Ezarpena gordetzeak huts egin du", "{app}'s declarative setting field: {name}" : "{app}-ren ezarpen deklaratiboaren eremua: {name}", "Unable to update server side encryption config" : "Ezin izan da zerbitzariaren aldeko zifratzearen konfigurazioa eguneratu", diff --git a/apps/settings/l10n/eu.json b/apps/settings/l10n/eu.json index f9f8bba0155..85ca513ce05 100644 --- a/apps/settings/l10n/eu.json +++ b/apps/settings/l10n/eu.json @@ -520,6 +520,7 @@ "Unable to update profile default setting" : "Ezin izan da eguneratu profilaren ezarpen lehenetsia", "Profile" : "Profila", "Enable or disable profile by default for new accounts." : "Gaitu edo desgaitu profila lehenespenez kontu berrientzat.", + "Password confirmation is required" : "Pasahitza konfirmatzea beharrezkoa da", "Failed to save setting" : "Ezarpena gordetzeak huts egin du", "{app}'s declarative setting field: {name}" : "{app}-ren ezarpen deklaratiboaren eremua: {name}", "Unable to update server side encryption config" : "Ezin izan da zerbitzariaren aldeko zifratzearen konfigurazioa eguneratu", diff --git a/apps/settings/l10n/fi.js b/apps/settings/l10n/fi.js index 466891fcfd4..dd838928d3c 100644 --- a/apps/settings/l10n/fi.js +++ b/apps/settings/l10n/fi.js @@ -289,6 +289,7 @@ OC.L10N.register( "Cron (Recommended)" : "Cron (suositeltu)", "Unable to update profile default setting" : "Profiilin oletusasetuksen päivittäminen ei onnistunut", "Profile" : "Profiili", + "Password confirmation is required" : "Salasanavahvistus vaaditaan", "Server-side encryption" : "Palvelinpään salaus", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Palvelimelle ladatut tiedostot voidaan salata. Salaus aiheuttaa muun muassa palvelimen suorituskyvyn laskua, joten ota salaus käyttöön vain tarvittaessa.", "Enable server-side encryption" : "Käytä palvelinpään salausta", diff --git a/apps/settings/l10n/fi.json b/apps/settings/l10n/fi.json index aa7dca8843c..6ce239de38d 100644 --- a/apps/settings/l10n/fi.json +++ b/apps/settings/l10n/fi.json @@ -287,6 +287,7 @@ "Cron (Recommended)" : "Cron (suositeltu)", "Unable to update profile default setting" : "Profiilin oletusasetuksen päivittäminen ei onnistunut", "Profile" : "Profiili", + "Password confirmation is required" : "Salasanavahvistus vaaditaan", "Server-side encryption" : "Palvelinpään salaus", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Palvelimelle ladatut tiedostot voidaan salata. Salaus aiheuttaa muun muassa palvelimen suorituskyvyn laskua, joten ota salaus käyttöön vain tarvittaessa.", "Enable server-side encryption" : "Käytä palvelinpään salausta", diff --git a/apps/settings/l10n/fr.js b/apps/settings/l10n/fr.js index 4997964b751..451d1ffc42f 100644 --- a/apps/settings/l10n/fr.js +++ b/apps/settings/l10n/fr.js @@ -558,6 +558,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Impossible de mettre à jour les paramètres par défaut du profil", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Active ou désactive le profil par défaut pour les nouveaux comptes.", + "Password confirmation is required" : "Confirmation par mot de passe est requise", "Failed to save setting" : "Échec de la sauvegarde des paramètres", "{app}'s declarative setting field: {name}" : "champ de paramètre déclaratif de l'{app}: {name}", "Unable to update server side encryption config" : "Impossible de mettre à jour la configuration du chiffrement côté serveur", @@ -579,9 +580,11 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Il est opportun de sauvegarder régulièrement vos données. Si ces données sont chiffrées, n’oubliez pas de sauvegarder aussi les clés de chiffrement.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Reportez-vous à la documentation d'administration pour savoir comment chiffrer manuellement les fichiers existants.", "This is the final warning: Do you really want to enable encryption?" : "Dernier avertissement : Voulez-vous vraiment activer le chiffrement ?", + "Failed to delete group \"{group}\"" : "Échec de la suppression du groupe \"{group}\"", "Please confirm the group removal" : "Merci de confirmer la suppression du groupe", "Submit" : "Soumettre", "Rename group" : "Renommer le groupe", + "Delete group" : "Supprimer le groupe", "Current password" : "Mot de passe actuel", "New password" : "Nouveau mot de passe", "Change password" : "Changer de mot de passe", diff --git a/apps/settings/l10n/fr.json b/apps/settings/l10n/fr.json index 3824a7302a1..1c4d36bd04e 100644 --- a/apps/settings/l10n/fr.json +++ b/apps/settings/l10n/fr.json @@ -556,6 +556,7 @@ "Unable to update profile default setting" : "Impossible de mettre à jour les paramètres par défaut du profil", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Active ou désactive le profil par défaut pour les nouveaux comptes.", + "Password confirmation is required" : "Confirmation par mot de passe est requise", "Failed to save setting" : "Échec de la sauvegarde des paramètres", "{app}'s declarative setting field: {name}" : "champ de paramètre déclaratif de l'{app}: {name}", "Unable to update server side encryption config" : "Impossible de mettre à jour la configuration du chiffrement côté serveur", @@ -577,9 +578,11 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Il est opportun de sauvegarder régulièrement vos données. Si ces données sont chiffrées, n’oubliez pas de sauvegarder aussi les clés de chiffrement.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Reportez-vous à la documentation d'administration pour savoir comment chiffrer manuellement les fichiers existants.", "This is the final warning: Do you really want to enable encryption?" : "Dernier avertissement : Voulez-vous vraiment activer le chiffrement ?", + "Failed to delete group \"{group}\"" : "Échec de la suppression du groupe \"{group}\"", "Please confirm the group removal" : "Merci de confirmer la suppression du groupe", "Submit" : "Soumettre", "Rename group" : "Renommer le groupe", + "Delete group" : "Supprimer le groupe", "Current password" : "Mot de passe actuel", "New password" : "Nouveau mot de passe", "Change password" : "Changer de mot de passe", diff --git a/apps/settings/l10n/gl.js b/apps/settings/l10n/gl.js index 503d30e510d..74038c39895 100644 --- a/apps/settings/l10n/gl.js +++ b/apps/settings/l10n/gl.js @@ -556,6 +556,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Non é posíbel actualizar a configuración predeterminada do perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Activar ou desactivar o perfil predeterminado para as novas contas.", + "Password confirmation is required" : "Requírese a confirmación do contrasinal", "Failed to save setting" : "Produciuse un fallo ao gardar o axuste", "{app}'s declarative setting field: {name}" : "Campo de axuste declarativo de {app}: {name}", "Unable to update server side encryption config" : "Non é posíbel actualizar a configuración de cifrado do servidor", diff --git a/apps/settings/l10n/gl.json b/apps/settings/l10n/gl.json index 21d0e593e40..bfc2f16171e 100644 --- a/apps/settings/l10n/gl.json +++ b/apps/settings/l10n/gl.json @@ -554,6 +554,7 @@ "Unable to update profile default setting" : "Non é posíbel actualizar a configuración predeterminada do perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Activar ou desactivar o perfil predeterminado para as novas contas.", + "Password confirmation is required" : "Requírese a confirmación do contrasinal", "Failed to save setting" : "Produciuse un fallo ao gardar o axuste", "{app}'s declarative setting field: {name}" : "Campo de axuste declarativo de {app}: {name}", "Unable to update server side encryption config" : "Non é posíbel actualizar a configuración de cifrado do servidor", diff --git a/apps/settings/l10n/he.js b/apps/settings/l10n/he.js index b4d8fd983c0..298c1e232d7 100644 --- a/apps/settings/l10n/he.js +++ b/apps/settings/l10n/he.js @@ -200,6 +200,7 @@ OC.L10N.register( "Show QR code for mobile apps" : "הצגת קוד QR ליישומונים לניידים", "Use system cron service to call the cron.php file every 5 minutes." : "להשתמש בשירות ה־cron של המערכת כדי לקרוא לקובץ cron.php כל 5 דקות.", "Profile" : "פרופיל", + "Password confirmation is required" : "נדרש אימות ססמה", "Server-side encryption" : "הצפנת צד שרת", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "הצפנה בצד השרת מאפשרת להצפין קבצים שנשלחים לשרת. לתכונה זו יש מגבלות כגון ירידה בביצועים, מומלץ להפעיל רק אם יש צורך.", "Enable server-side encryption" : "הפעלת הצפנה בצד שרת", diff --git a/apps/settings/l10n/he.json b/apps/settings/l10n/he.json index 82d58fe7b1b..596aee779ac 100644 --- a/apps/settings/l10n/he.json +++ b/apps/settings/l10n/he.json @@ -198,6 +198,7 @@ "Show QR code for mobile apps" : "הצגת קוד QR ליישומונים לניידים", "Use system cron service to call the cron.php file every 5 minutes." : "להשתמש בשירות ה־cron של המערכת כדי לקרוא לקובץ cron.php כל 5 דקות.", "Profile" : "פרופיל", + "Password confirmation is required" : "נדרש אימות ססמה", "Server-side encryption" : "הצפנת צד שרת", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "הצפנה בצד השרת מאפשרת להצפין קבצים שנשלחים לשרת. לתכונה זו יש מגבלות כגון ירידה בביצועים, מומלץ להפעיל רק אם יש צורך.", "Enable server-side encryption" : "הפעלת הצפנה בצד שרת", diff --git a/apps/settings/l10n/hu.js b/apps/settings/l10n/hu.js index aed3e3a823e..b7ddd874edb 100644 --- a/apps/settings/l10n/hu.js +++ b/apps/settings/l10n/hu.js @@ -385,6 +385,7 @@ OC.L10N.register( "Cron (Recommended)" : "Cron (ajánlott)", "Unable to update profile default setting" : "A profil alapértelmezett beállítása nem frissíthető", "Profile" : "Profil", + "Password confirmation is required" : "Jelszó megerősítés szükséges", "Unable to update server side encryption config" : "A kiszolgálóoldali titkosítás beállításai nem frissíthetők", "Server-side encryption" : "Kiszolgálóoldali titkosítás", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "A kiszolgálóoldali titkosítás segítségével a tárolt fájlok titkosítva lesznek tárolva a kiszolgálón. Ez korlátozásokkal jár, például teljesítménycsökkenést okoz, így csak akkor kapcsolja be, ha szükséges.", diff --git a/apps/settings/l10n/hu.json b/apps/settings/l10n/hu.json index a56b135a8cf..e18c4deff92 100644 --- a/apps/settings/l10n/hu.json +++ b/apps/settings/l10n/hu.json @@ -383,6 +383,7 @@ "Cron (Recommended)" : "Cron (ajánlott)", "Unable to update profile default setting" : "A profil alapértelmezett beállítása nem frissíthető", "Profile" : "Profil", + "Password confirmation is required" : "Jelszó megerősítés szükséges", "Unable to update server side encryption config" : "A kiszolgálóoldali titkosítás beállításai nem frissíthetők", "Server-side encryption" : "Kiszolgálóoldali titkosítás", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "A kiszolgálóoldali titkosítás segítségével a tárolt fájlok titkosítva lesznek tárolva a kiszolgálón. Ez korlátozásokkal jár, például teljesítménycsökkenést okoz, így csak akkor kapcsolja be, ha szükséges.", diff --git a/apps/settings/l10n/is.js b/apps/settings/l10n/is.js index 69b1cc2a708..44a73887399 100644 --- a/apps/settings/l10n/is.js +++ b/apps/settings/l10n/is.js @@ -399,6 +399,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Tókst ekki að uppfæra sjálfgefna stillingu notandasniðs", "Profile" : "Notandasnið", "Enable or disable profile by default for new accounts." : "Virkja eða gera notandasnið óvirkt sjálfgefið fyrir nýja notendaaðganga.", + "Password confirmation is required" : "Þörf á staðfestingu lykilorðs", "Failed to save setting" : "Mistókst að vista stillingu", "Unable to update server side encryption config" : " Get ekki uppfært uppsetningu fyrir dulritun á þjóni", "Server-side encryption" : "Dulritun á þjóni", diff --git a/apps/settings/l10n/is.json b/apps/settings/l10n/is.json index 166f3574339..534c9c2c0b2 100644 --- a/apps/settings/l10n/is.json +++ b/apps/settings/l10n/is.json @@ -397,6 +397,7 @@ "Unable to update profile default setting" : "Tókst ekki að uppfæra sjálfgefna stillingu notandasniðs", "Profile" : "Notandasnið", "Enable or disable profile by default for new accounts." : "Virkja eða gera notandasnið óvirkt sjálfgefið fyrir nýja notendaaðganga.", + "Password confirmation is required" : "Þörf á staðfestingu lykilorðs", "Failed to save setting" : "Mistókst að vista stillingu", "Unable to update server side encryption config" : " Get ekki uppfært uppsetningu fyrir dulritun á þjóni", "Server-side encryption" : "Dulritun á þjóni", diff --git a/apps/settings/l10n/it.js b/apps/settings/l10n/it.js index fd6d44655e1..c1db5c0be0c 100644 --- a/apps/settings/l10n/it.js +++ b/apps/settings/l10n/it.js @@ -447,6 +447,7 @@ OC.L10N.register( "Cron (Recommended)" : "Cron (Consigliato)", "Unable to update profile default setting" : "Impossibile aggiornare l'impostazione predefinita del profilo", "Profile" : "Profilo", + "Password confirmation is required" : "La conferma della password è richiesta", "Unable to update server side encryption config" : "Impossibile aggiornare la configurazione della crittografia lato server", "Server-side encryption" : "Cifratura lato server", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La cifratura lato server rende possibile cifrare i file caricati sul server. Ciò presenta dei limiti, come una riduzione delle prestazioni, perciò abilita questa funzione solo se necessario.", diff --git a/apps/settings/l10n/it.json b/apps/settings/l10n/it.json index 43078787144..dbe163f0346 100644 --- a/apps/settings/l10n/it.json +++ b/apps/settings/l10n/it.json @@ -445,6 +445,7 @@ "Cron (Recommended)" : "Cron (Consigliato)", "Unable to update profile default setting" : "Impossibile aggiornare l'impostazione predefinita del profilo", "Profile" : "Profilo", + "Password confirmation is required" : "La conferma della password è richiesta", "Unable to update server side encryption config" : "Impossibile aggiornare la configurazione della crittografia lato server", "Server-side encryption" : "Cifratura lato server", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "La cifratura lato server rende possibile cifrare i file caricati sul server. Ciò presenta dei limiti, come una riduzione delle prestazioni, perciò abilita questa funzione solo se necessario.", diff --git a/apps/settings/l10n/ja.js b/apps/settings/l10n/ja.js index 5fa8e66adf9..87cfe42f3ea 100644 --- a/apps/settings/l10n/ja.js +++ b/apps/settings/l10n/ja.js @@ -316,6 +316,9 @@ OC.L10N.register( "64-bit" : "64ビット", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "このシステムは32ビット版のPHPで動いているようです。Nextcloudを正常に動かすには64ビット版が必要です。OSとPHPを64ビット版にアップグレードしてください!", "Task Processing pickup speed" : "タスク処理のピックアップ速度", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["直近の%n時間に予定されたタスクはありません。"], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["タスクのピックアップ速度は、過去%n時間に問題ありませんでした。"], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["過去%n時間タスクのピックアップ速度が遅くなっています。多くのタスクが取得に4分以上かかりました。バックグラウンドでタスクを処理するようにワーカーを設定することを検討してください。"], "Temporary space available" : "テンポラリ領域が利用可能です", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "PHP のテンポラリパスのチェック中にエラーが発生しました - ディレクトリが正しく設定されていませんでした。返された値:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHPの関数 \"disk_free_space\"が無効になっており、一時的なディレクトリに十分な空き容量があるかどうかをチェックできません。", @@ -562,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "プロフィールのデフォルト設定を更新できませんでした", "Profile" : "プロフィール", "Enable or disable profile by default for new accounts." : "新しいアカウントの場合、デフォルトでプロフィールを有効または無効にします。", + "Password confirmation is required" : "パスワードの確認が必要です", "Failed to save setting" : "設定の保存に失敗しました", "{app}'s declarative setting field: {name}" : "{app}の宣言的設定フィールド: {name}", "Unable to update server side encryption config" : "サーバー側暗号化の設定を更新できませんでした", @@ -584,9 +588,12 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "暗号化した場合には必ず、あなたのデータと共に暗号化キーをバックアップすることを確認し、定期的にデータをバックアップを作成することをお勧めします。", "Refer to the admin documentation on how to manually also encrypt existing files." : "既存のファイルを手動で暗号化する方法については、管理者のドキュメントを参照してください。", "This is the final warning: Do you really want to enable encryption?" : "これが最後の警告です:本当に暗号化を有効にしますか?", + "Failed to delete group \"{group}\"" : "グループ \"{group}\"の削除に失敗しました", "Please confirm the group removal" : "グループの削除を確認してください", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", "Submit" : "送信", "Rename group" : "グループの名称変更", + "Delete group" : "グループを削除", "Current password" : "現在のパスワード", "New password" : "新しいパスワード", "Change password" : "パスワードを変更", diff --git a/apps/settings/l10n/ja.json b/apps/settings/l10n/ja.json index 4543a0e66c6..a1ecd71d95e 100644 --- a/apps/settings/l10n/ja.json +++ b/apps/settings/l10n/ja.json @@ -314,6 +314,9 @@ "64-bit" : "64ビット", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "このシステムは32ビット版のPHPで動いているようです。Nextcloudを正常に動かすには64ビット版が必要です。OSとPHPを64ビット版にアップグレードしてください!", "Task Processing pickup speed" : "タスク処理のピックアップ速度", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["直近の%n時間に予定されたタスクはありません。"], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["タスクのピックアップ速度は、過去%n時間に問題ありませんでした。"], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["過去%n時間タスクのピックアップ速度が遅くなっています。多くのタスクが取得に4分以上かかりました。バックグラウンドでタスクを処理するようにワーカーを設定することを検討してください。"], "Temporary space available" : "テンポラリ領域が利用可能です", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "PHP のテンポラリパスのチェック中にエラーが発生しました - ディレクトリが正しく設定されていませんでした。返された値:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHPの関数 \"disk_free_space\"が無効になっており、一時的なディレクトリに十分な空き容量があるかどうかをチェックできません。", @@ -560,6 +563,7 @@ "Unable to update profile default setting" : "プロフィールのデフォルト設定を更新できませんでした", "Profile" : "プロフィール", "Enable or disable profile by default for new accounts." : "新しいアカウントの場合、デフォルトでプロフィールを有効または無効にします。", + "Password confirmation is required" : "パスワードの確認が必要です", "Failed to save setting" : "設定の保存に失敗しました", "{app}'s declarative setting field: {name}" : "{app}の宣言的設定フィールド: {name}", "Unable to update server side encryption config" : "サーバー側暗号化の設定を更新できませんでした", @@ -582,9 +586,12 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "暗号化した場合には必ず、あなたのデータと共に暗号化キーをバックアップすることを確認し、定期的にデータをバックアップを作成することをお勧めします。", "Refer to the admin documentation on how to manually also encrypt existing files." : "既存のファイルを手動で暗号化する方法については、管理者のドキュメントを参照してください。", "This is the final warning: Do you really want to enable encryption?" : "これが最後の警告です:本当に暗号化を有効にしますか?", + "Failed to delete group \"{group}\"" : "グループ \"{group}\"の削除に失敗しました", "Please confirm the group removal" : "グループの削除を確認してください", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", "Submit" : "送信", "Rename group" : "グループの名称変更", + "Delete group" : "グループを削除", "Current password" : "現在のパスワード", "New password" : "新しいパスワード", "Change password" : "パスワードを変更", diff --git a/apps/settings/l10n/ka_GE.js b/apps/settings/l10n/ka_GE.js index 2de4c3522a7..03e608f6ff2 100644 --- a/apps/settings/l10n/ka_GE.js +++ b/apps/settings/l10n/ka_GE.js @@ -143,6 +143,7 @@ OC.L10N.register( "Create new app password" : "ახალი აპლიკაციის პაროლის შექმნა", "Login" : "ლოგინი", "Password" : "პაროლი", + "Password confirmation is required" : "საჭიროა პაროლის დამოწმება", "Server-side encryption" : "სერვერული-მხარის შიფრაცია", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "სერვერული-მხარის შიფრაცია იძლევა სერვერზე ატვირთული ფაილების შიფრაციის საშუალებას. ეს ფუნქცია ლიმიტს აწესებს მოქმედებაზე, ასე რომ გააქტიურედ მხოლოდ აუცილებლობისას.", "Enable server-side encryption" : "სერვერული-მხარის შიფრაციის ამოქმედება", diff --git a/apps/settings/l10n/ka_GE.json b/apps/settings/l10n/ka_GE.json index e8ccd67dd94..723779ba198 100644 --- a/apps/settings/l10n/ka_GE.json +++ b/apps/settings/l10n/ka_GE.json @@ -141,6 +141,7 @@ "Create new app password" : "ახალი აპლიკაციის პაროლის შექმნა", "Login" : "ლოგინი", "Password" : "პაროლი", + "Password confirmation is required" : "საჭიროა პაროლის დამოწმება", "Server-side encryption" : "სერვერული-მხარის შიფრაცია", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "სერვერული-მხარის შიფრაცია იძლევა სერვერზე ატვირთული ფაილების შიფრაციის საშუალებას. ეს ფუნქცია ლიმიტს აწესებს მოქმედებაზე, ასე რომ გააქტიურედ მხოლოდ აუცილებლობისას.", "Enable server-side encryption" : "სერვერული-მხარის შიფრაციის ამოქმედება", diff --git a/apps/settings/l10n/ko.js b/apps/settings/l10n/ko.js index 15d651c7b4c..a6c59849d7b 100644 --- a/apps/settings/l10n/ko.js +++ b/apps/settings/l10n/ko.js @@ -467,6 +467,7 @@ OC.L10N.register( "Unable to update profile default setting" : "프로필 기본 설정을 업데이트 할 수 없음", "Profile" : "프로필", "Enable or disable profile by default for new accounts." : "신규 계정에 대한 프로필 기본 사용 여부를 설정하십시오.", + "Password confirmation is required" : "암호 확인이 필요합니다", "Failed to save setting" : "설정 저장 실패", "Unable to update server side encryption config" : "서버 측 암호화 설정을 갱신할 수 없음", "Server-side encryption" : "서버 측 암호화", diff --git a/apps/settings/l10n/ko.json b/apps/settings/l10n/ko.json index 21332b20104..c017e41ad38 100644 --- a/apps/settings/l10n/ko.json +++ b/apps/settings/l10n/ko.json @@ -465,6 +465,7 @@ "Unable to update profile default setting" : "프로필 기본 설정을 업데이트 할 수 없음", "Profile" : "프로필", "Enable or disable profile by default for new accounts." : "신규 계정에 대한 프로필 기본 사용 여부를 설정하십시오.", + "Password confirmation is required" : "암호 확인이 필요합니다", "Failed to save setting" : "설정 저장 실패", "Unable to update server side encryption config" : "서버 측 암호화 설정을 갱신할 수 없음", "Server-side encryption" : "서버 측 암호화", diff --git a/apps/settings/l10n/lt_LT.js b/apps/settings/l10n/lt_LT.js index 24d7e9aa8c2..cf411ff2897 100644 --- a/apps/settings/l10n/lt_LT.js +++ b/apps/settings/l10n/lt_LT.js @@ -257,6 +257,7 @@ OC.L10N.register( "Webcron" : "„Webcron“", "Cron (Recommended)" : "„Cron“ (Rekomenduojama)", "Profile" : "Profilis", + "Password confirmation is required" : "Reikalingas slaptažodžio patvirtinimas", "Failed to save setting" : "Nepavyko įrašyti nustatymo", "Server-side encryption" : "Šifravimas serverio pusėje", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Šifravimas serverio pusėje leidžia užšifruoti failus, kurie yra įkelti į serverį. Įjungti tik ik būtinais atvejais.", diff --git a/apps/settings/l10n/lt_LT.json b/apps/settings/l10n/lt_LT.json index eb77b76188e..c0651ac3054 100644 --- a/apps/settings/l10n/lt_LT.json +++ b/apps/settings/l10n/lt_LT.json @@ -255,6 +255,7 @@ "Webcron" : "„Webcron“", "Cron (Recommended)" : "„Cron“ (Rekomenduojama)", "Profile" : "Profilis", + "Password confirmation is required" : "Reikalingas slaptažodžio patvirtinimas", "Failed to save setting" : "Nepavyko įrašyti nustatymo", "Server-side encryption" : "Šifravimas serverio pusėje", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Šifravimas serverio pusėje leidžia užšifruoti failus, kurie yra įkelti į serverį. Įjungti tik ik būtinais atvejais.", diff --git a/apps/settings/l10n/lv.js b/apps/settings/l10n/lv.js index d9d71665874..f22d5e9ac96 100644 --- a/apps/settings/l10n/lv.js +++ b/apps/settings/l10n/lv.js @@ -34,7 +34,7 @@ OC.L10N.register( "Invalid account" : "Nederīgs konts", "Invalid mail address" : "Nepareiza e-pasta adrese", "Settings saved" : "Iestatījumi saglabāti", - "Unable to change full name" : "Nav iespējams nomainīt jūsu pilno vārdu", + "Unable to change full name" : "Nevar nomainīt pilno vārdu", "Unable to change email address" : "Nevar mainīt e-pasta adresi", "In order to verify your Website, store the following content in your web-root at '.well-known/CloudIdVerificationCode.txt' (please make sure that the complete text is in one line):" : "Lai apliecinātu savu tīmekļvietni, zemāk esošais saturs ir jāglabā tīmekļvietnes pamatmapē kā `.well-known/CloudIdVerificationCode.txt` (lūgums pārliecināties, ka viss teksts ir vienā rindiņā):", "Your %s account was created" : "Konts %s ir izveidots", @@ -60,7 +60,7 @@ OC.L10N.register( "This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features." : "Šim serverim nav strādājoša savienojuma ar internetu: vairākus galamērķus nevarēja sasniegt. Tas nozīmē, ka dažas no iespējām, piemēram, ārējas krātuves piemontēšana, paziņojumi par atjauninājumiem vai trešo pušu lietotņu uzstādīšana, nedarbosies. Varētu nedarboties arī attālā piekļūšana datnēm paziņojumu e-pasta ziņojumu nosūtīšana. Šim serverim jānodrošina savienojums ar internetu, lai izmantotu visas iespējas.", "Disabled" : "Atspējots", "PHP does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP nešķiet pareizi uzstādīts lai veiktu sistēmas vides mainīgo vaicājumus. Tests ar getenv(\"PATH\") atgriež tikai tukšu atbildi.", - "The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Ir iespējots tikai lasāma konfigurācija. Tas neatļauj iestatīt un mainīt dažas konfigurācijas caur tīmekļa interfeisu. Šī datne būs manuāli jāpārveido par rakstāmu, pirms katra atjauninājuma instalēšanas.", + "The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Ir iespējota tikai lasāma konfigurācija. Tas neatļauj iestatīt atsevišķu konfigurāciju tīmekļa saskarnē. Turklāt šī datne pašrocīgi jāpadara par rakstāmu katram atjauninājumam.", "Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Datubāze nedarbojas ar \"READ COMMITED\" transakciju izolācijas līmeni. Tas var radīt sarežģījumus, kad vienlaicīgi tiek veiktas vairākas darbības.", "Nextcloud settings" : "Nextcloud iestatījumi", "Enable" : "Aktivēt", @@ -71,6 +71,7 @@ OC.L10N.register( "Restrict users to only share with users in their groups" : "Ierobežot lietotājiem koplietot tikai ar lietotājiem savās grupās", "Allow public uploads" : "Atļaut publisko augšupielādi", "Enforce password protection" : "Ieviest paroles aizsardzību", + "Set default expiration date for internal shares" : "Iestatīt noklusējuma beigu datumu iekšējiem koplietojumiem", "Enforce expiration date" : "Uzspiest beigu datumu", "Privacy settings for sharing" : "Kopīgošanas privātuma iestatījumi", "Two-Factor Authentication" : "Divpakāpju pieteikšanās", @@ -125,6 +126,7 @@ OC.L10N.register( "Password" : "Parole", "Show QR code for mobile apps" : "Parādīt kvadrātkodu tālruņa lietotnēm", "Profile" : "Profils", + "Password confirmation is required" : "Nepieciešams paroles apstiprinājums", "Server-side encryption" : "Servera šifrēšana", "Enable server-side encryption" : "Ieslēgt servera šifrēšanu", "No encryption module loaded, please enable an encryption module in the app menu." : "Nav ielādēts šifrēšanas moduļis, lūdzu, aktivizējiet šifrēšanas moduli lietotņu izvēlnē.", @@ -134,6 +136,7 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Jāapzinās, ka šifrēšanas vienmēr palielina datnes lielumu.", "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Vienmēr ir ieteicams regulāri veidot datu rezerves kopijas, un šifrēšanas gadījumā jāpārliecinās, ka līdz ar datiem rezerves kopijas ir izveidotas arī šifrēšanas atslēgām.", "This is the final warning: Do you really want to enable encryption?" : "Šis ir pēdējais brīdinājums: vai tiešām iespējot šifrēšanu?", + "Failed to delete group \"{group}\"" : "Neizdevās izdzēst kopu \"{group}\"", "Submit" : "Iesniegt", "Rename group" : "Pārdēvēt kopu", "Current password" : "Pašreizējā parole", @@ -141,9 +144,9 @@ OC.L10N.register( "Change password" : "Mainīt paroli", "The file must be a PNG or JPG" : "Datnei jābūt PNG vai JPG", "Unable to update date of birth" : "Nevarēja atjaunināt dzimšanas datumu", - "Enter your date of birth" : "Ievadiet Jūsu dzimšanas datumu", - "You are using {s}{usage}{/s}" : "Jūs izmantojat {s}{usage}{/s}", - "You are using {s}{usage}{/s} of {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})" : "Jūs izmantojat {s}{usage}{/s} no {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})", + "Enter your date of birth" : "Ievadi savu dzimšanas datumu", + "You are using {s}{usage}{/s}" : "Tu izmanto {s}{usage}{/s}", + "You are using {s}{usage}{/s} of {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})" : "Tu izmanto {s}{usage}{/s} no {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})", "You are a member of the following groups:" : "Tu esi zemāk uzskaitīto kopu dalībnieks:", "This address is not confirmed" : "Šī adrese nav apstiprināta", "Primary email for password reset and notifications" : "Primārā e-pasta adrese paroles atjaunošanai un paziņojumiem", @@ -153,10 +156,10 @@ OC.L10N.register( "Locales" : "Lokalizācijas", "Week starts on {firstDayOfWeek}" : "Nedēļa sākas {firstDayOfWeek}", "No locale set" : "Lokalizācija nav iestatīta", - "Your phone number" : "Jūsu tālruņa numurs", - "Edit your Profile visibility" : "Labot Jūsu profila redzamību", - "Your role" : "Jūsu loma", - "Your website" : "Jūsu mājaslapa", + "Your phone number" : "Tavs tālruņa numurs", + "Edit your Profile visibility" : "Labot sava profila redzamību", + "Your role" : "Tava loma", + "Your website" : "Tava tīmekļvietne", "Add" : "Pievienot", "Create" : "Izveidot", "Change" : "Mainīt", @@ -182,6 +185,7 @@ OC.L10N.register( "Visibility" : "Redzamība", "Show last login" : "Rādīt pēdējo autorizāciju", "Send email" : "Nosūtīt e-pasta ziņojumu", + "Send welcome email to new accounts" : "Nosūtīt sasveicināšanās e-pasta ziņojumu jauniem lietotājiem", "Default quota" : "Apjoms pēc noklusējuma", "Admins" : "Pārvaldītāji", "Sending…" : "Sūta …", @@ -224,8 +228,8 @@ OC.L10N.register( "Developed by the {communityopen}Nextcloud community{linkclose}, the {githubopen}source code{linkclose} is licensed under the {licenseopen}AGPL{linkclose}." : "Izstrādātās {communityopen}Nextcloud kopiena {linkclose}, {githubopen} avota kods {linkclose} licencēts saskaņā ar {licenseopen}AGPL{linkclose}.", "Use a second factor besides your password to increase security for your account." : "Vēl viena apliecināšanas līdzekļa izmantošana papildus parolei, lai palielinātu sava konta drošību.", "If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Ja izmanto trešo pušu lietotnes, lai savienotos ar Nextcloud, lūgums ņemt vērā, ka pirms divpakāpju pieteikšanās iespējošanas katrai no tām ir nepieciešams izveidot un izmantot lietotnes paroli.", - "Your biography" : "Jūsu biogrāfija", - "You are using <strong>{usage}</strong>" : "Jūs izmantojat <strong>{usage}</strong>", - "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Jūs izmantojat <strong>{usage}</strong> no <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" + "Your biography" : "Apraksts par sevi", + "You are using <strong>{usage}</strong>" : "Tu izmanto <strong>{usage}</strong>", + "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Tu izmanto <strong>{usage}</strong> no <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/apps/settings/l10n/lv.json b/apps/settings/l10n/lv.json index 05f5c97cb1a..5c87992b05b 100644 --- a/apps/settings/l10n/lv.json +++ b/apps/settings/l10n/lv.json @@ -32,7 +32,7 @@ "Invalid account" : "Nederīgs konts", "Invalid mail address" : "Nepareiza e-pasta adrese", "Settings saved" : "Iestatījumi saglabāti", - "Unable to change full name" : "Nav iespējams nomainīt jūsu pilno vārdu", + "Unable to change full name" : "Nevar nomainīt pilno vārdu", "Unable to change email address" : "Nevar mainīt e-pasta adresi", "In order to verify your Website, store the following content in your web-root at '.well-known/CloudIdVerificationCode.txt' (please make sure that the complete text is in one line):" : "Lai apliecinātu savu tīmekļvietni, zemāk esošais saturs ir jāglabā tīmekļvietnes pamatmapē kā `.well-known/CloudIdVerificationCode.txt` (lūgums pārliecināties, ka viss teksts ir vienā rindiņā):", "Your %s account was created" : "Konts %s ir izveidots", @@ -58,7 +58,7 @@ "This server has no working internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the internet to enjoy all features." : "Šim serverim nav strādājoša savienojuma ar internetu: vairākus galamērķus nevarēja sasniegt. Tas nozīmē, ka dažas no iespējām, piemēram, ārējas krātuves piemontēšana, paziņojumi par atjauninājumiem vai trešo pušu lietotņu uzstādīšana, nedarbosies. Varētu nedarboties arī attālā piekļūšana datnēm paziņojumu e-pasta ziņojumu nosūtīšana. Šim serverim jānodrošina savienojums ar internetu, lai izmantotu visas iespējas.", "Disabled" : "Atspējots", "PHP does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP nešķiet pareizi uzstādīts lai veiktu sistēmas vides mainīgo vaicājumus. Tests ar getenv(\"PATH\") atgriež tikai tukšu atbildi.", - "The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Ir iespējots tikai lasāma konfigurācija. Tas neatļauj iestatīt un mainīt dažas konfigurācijas caur tīmekļa interfeisu. Šī datne būs manuāli jāpārveido par rakstāmu, pirms katra atjauninājuma instalēšanas.", + "The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Ir iespējota tikai lasāma konfigurācija. Tas neatļauj iestatīt atsevišķu konfigurāciju tīmekļa saskarnē. Turklāt šī datne pašrocīgi jāpadara par rakstāmu katram atjauninājumam.", "Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Datubāze nedarbojas ar \"READ COMMITED\" transakciju izolācijas līmeni. Tas var radīt sarežģījumus, kad vienlaicīgi tiek veiktas vairākas darbības.", "Nextcloud settings" : "Nextcloud iestatījumi", "Enable" : "Aktivēt", @@ -69,6 +69,7 @@ "Restrict users to only share with users in their groups" : "Ierobežot lietotājiem koplietot tikai ar lietotājiem savās grupās", "Allow public uploads" : "Atļaut publisko augšupielādi", "Enforce password protection" : "Ieviest paroles aizsardzību", + "Set default expiration date for internal shares" : "Iestatīt noklusējuma beigu datumu iekšējiem koplietojumiem", "Enforce expiration date" : "Uzspiest beigu datumu", "Privacy settings for sharing" : "Kopīgošanas privātuma iestatījumi", "Two-Factor Authentication" : "Divpakāpju pieteikšanās", @@ -123,6 +124,7 @@ "Password" : "Parole", "Show QR code for mobile apps" : "Parādīt kvadrātkodu tālruņa lietotnēm", "Profile" : "Profils", + "Password confirmation is required" : "Nepieciešams paroles apstiprinājums", "Server-side encryption" : "Servera šifrēšana", "Enable server-side encryption" : "Ieslēgt servera šifrēšanu", "No encryption module loaded, please enable an encryption module in the app menu." : "Nav ielādēts šifrēšanas moduļis, lūdzu, aktivizējiet šifrēšanas moduli lietotņu izvēlnē.", @@ -132,6 +134,7 @@ "Be aware that encryption always increases the file size." : "Jāapzinās, ka šifrēšanas vienmēr palielina datnes lielumu.", "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Vienmēr ir ieteicams regulāri veidot datu rezerves kopijas, un šifrēšanas gadījumā jāpārliecinās, ka līdz ar datiem rezerves kopijas ir izveidotas arī šifrēšanas atslēgām.", "This is the final warning: Do you really want to enable encryption?" : "Šis ir pēdējais brīdinājums: vai tiešām iespējot šifrēšanu?", + "Failed to delete group \"{group}\"" : "Neizdevās izdzēst kopu \"{group}\"", "Submit" : "Iesniegt", "Rename group" : "Pārdēvēt kopu", "Current password" : "Pašreizējā parole", @@ -139,9 +142,9 @@ "Change password" : "Mainīt paroli", "The file must be a PNG or JPG" : "Datnei jābūt PNG vai JPG", "Unable to update date of birth" : "Nevarēja atjaunināt dzimšanas datumu", - "Enter your date of birth" : "Ievadiet Jūsu dzimšanas datumu", - "You are using {s}{usage}{/s}" : "Jūs izmantojat {s}{usage}{/s}", - "You are using {s}{usage}{/s} of {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})" : "Jūs izmantojat {s}{usage}{/s} no {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})", + "Enter your date of birth" : "Ievadi savu dzimšanas datumu", + "You are using {s}{usage}{/s}" : "Tu izmanto {s}{usage}{/s}", + "You are using {s}{usage}{/s} of {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})" : "Tu izmanto {s}{usage}{/s} no {s}{totalSpace}{/s} ({s}{usageRelative}%{/s})", "You are a member of the following groups:" : "Tu esi zemāk uzskaitīto kopu dalībnieks:", "This address is not confirmed" : "Šī adrese nav apstiprināta", "Primary email for password reset and notifications" : "Primārā e-pasta adrese paroles atjaunošanai un paziņojumiem", @@ -151,10 +154,10 @@ "Locales" : "Lokalizācijas", "Week starts on {firstDayOfWeek}" : "Nedēļa sākas {firstDayOfWeek}", "No locale set" : "Lokalizācija nav iestatīta", - "Your phone number" : "Jūsu tālruņa numurs", - "Edit your Profile visibility" : "Labot Jūsu profila redzamību", - "Your role" : "Jūsu loma", - "Your website" : "Jūsu mājaslapa", + "Your phone number" : "Tavs tālruņa numurs", + "Edit your Profile visibility" : "Labot sava profila redzamību", + "Your role" : "Tava loma", + "Your website" : "Tava tīmekļvietne", "Add" : "Pievienot", "Create" : "Izveidot", "Change" : "Mainīt", @@ -180,6 +183,7 @@ "Visibility" : "Redzamība", "Show last login" : "Rādīt pēdējo autorizāciju", "Send email" : "Nosūtīt e-pasta ziņojumu", + "Send welcome email to new accounts" : "Nosūtīt sasveicināšanās e-pasta ziņojumu jauniem lietotājiem", "Default quota" : "Apjoms pēc noklusējuma", "Admins" : "Pārvaldītāji", "Sending…" : "Sūta …", @@ -222,8 +226,8 @@ "Developed by the {communityopen}Nextcloud community{linkclose}, the {githubopen}source code{linkclose} is licensed under the {licenseopen}AGPL{linkclose}." : "Izstrādātās {communityopen}Nextcloud kopiena {linkclose}, {githubopen} avota kods {linkclose} licencēts saskaņā ar {licenseopen}AGPL{linkclose}.", "Use a second factor besides your password to increase security for your account." : "Vēl viena apliecināšanas līdzekļa izmantošana papildus parolei, lai palielinātu sava konta drošību.", "If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Ja izmanto trešo pušu lietotnes, lai savienotos ar Nextcloud, lūgums ņemt vērā, ka pirms divpakāpju pieteikšanās iespējošanas katrai no tām ir nepieciešams izveidot un izmantot lietotnes paroli.", - "Your biography" : "Jūsu biogrāfija", - "You are using <strong>{usage}</strong>" : "Jūs izmantojat <strong>{usage}</strong>", - "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Jūs izmantojat <strong>{usage}</strong> no <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" + "Your biography" : "Apraksts par sevi", + "You are using <strong>{usage}</strong>" : "Tu izmanto <strong>{usage}</strong>", + "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Tu izmanto <strong>{usage}</strong> no <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" }
\ No newline at end of file diff --git a/apps/settings/l10n/nb.js b/apps/settings/l10n/nb.js index 3a839e5fabf..eeb6c9e37ac 100644 --- a/apps/settings/l10n/nb.js +++ b/apps/settings/l10n/nb.js @@ -509,6 +509,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Kan ikke oppdatere profilens standardinnstilling", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktiver eller deaktiver profil som standard for nye kontoer.", + "Password confirmation is required" : "Passord bekreftelse er nødvendig", "Failed to save setting" : "Lagring av innstilling feilet", "{app}'s declarative setting field: {name}" : "{app}s deklarative innstillingsfelt: {name}", "Unable to update server side encryption config" : "Kan ikke oppdatere konfigurasjonen av server-side-kryptering", diff --git a/apps/settings/l10n/nb.json b/apps/settings/l10n/nb.json index 8ce81d0cce9..7a55894aded 100644 --- a/apps/settings/l10n/nb.json +++ b/apps/settings/l10n/nb.json @@ -507,6 +507,7 @@ "Unable to update profile default setting" : "Kan ikke oppdatere profilens standardinnstilling", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktiver eller deaktiver profil som standard for nye kontoer.", + "Password confirmation is required" : "Passord bekreftelse er nødvendig", "Failed to save setting" : "Lagring av innstilling feilet", "{app}'s declarative setting field: {name}" : "{app}s deklarative innstillingsfelt: {name}", "Unable to update server side encryption config" : "Kan ikke oppdatere konfigurasjonen av server-side-kryptering", diff --git a/apps/settings/l10n/nl.js b/apps/settings/l10n/nl.js index 24221d8819a..fa192c83ba9 100644 --- a/apps/settings/l10n/nl.js +++ b/apps/settings/l10n/nl.js @@ -353,6 +353,7 @@ OC.L10N.register( "AJAX" : "AJAX", "Webcron" : "Webcron", "Profile" : "Profiel", + "Password confirmation is required" : "Wachtwoordbevestiging vereist", "Server-side encryption" : "Server-side versleuteling", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Server-side versleuteling maakt het mogelijk om bestanden te versleutelen die worden geüploaded. Dit betekent wel enig prestatieverlies, dus schakel het alleen in als het nodig is.", "Enable server-side encryption" : "Server-side versleuteling inschakelen", diff --git a/apps/settings/l10n/nl.json b/apps/settings/l10n/nl.json index 5784605a112..e1e5d2fdc3f 100644 --- a/apps/settings/l10n/nl.json +++ b/apps/settings/l10n/nl.json @@ -351,6 +351,7 @@ "AJAX" : "AJAX", "Webcron" : "Webcron", "Profile" : "Profiel", + "Password confirmation is required" : "Wachtwoordbevestiging vereist", "Server-side encryption" : "Server-side versleuteling", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Server-side versleuteling maakt het mogelijk om bestanden te versleutelen die worden geüploaded. Dit betekent wel enig prestatieverlies, dus schakel het alleen in als het nodig is.", "Enable server-side encryption" : "Server-side versleuteling inschakelen", diff --git a/apps/settings/l10n/pl.js b/apps/settings/l10n/pl.js index 7d6503244d1..81751a36bd0 100644 --- a/apps/settings/l10n/pl.js +++ b/apps/settings/l10n/pl.js @@ -455,6 +455,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Nie można zaktualizować domyślnych ustawień profilu", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Włącz lub wyłącz profil domyślnie dla nowych kont.", + "Password confirmation is required" : "Wymagane jest potwierdzenie hasła", "Failed to save setting" : "Nie udało się zapisać ustawienia", "{app}'s declarative setting field: {name}" : "Pole ustawień deklaratywnych aplikacji {app}: {name}", "Unable to update server side encryption config" : "Nie można zaktualizować konfiguracji szyfrowania po stronie serwera", diff --git a/apps/settings/l10n/pl.json b/apps/settings/l10n/pl.json index 20c3852ddc4..975d96f7654 100644 --- a/apps/settings/l10n/pl.json +++ b/apps/settings/l10n/pl.json @@ -453,6 +453,7 @@ "Unable to update profile default setting" : "Nie można zaktualizować domyślnych ustawień profilu", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Włącz lub wyłącz profil domyślnie dla nowych kont.", + "Password confirmation is required" : "Wymagane jest potwierdzenie hasła", "Failed to save setting" : "Nie udało się zapisać ustawienia", "{app}'s declarative setting field: {name}" : "Pole ustawień deklaratywnych aplikacji {app}: {name}", "Unable to update server side encryption config" : "Nie można zaktualizować konfiguracji szyfrowania po stronie serwera", diff --git a/apps/settings/l10n/pt_BR.js b/apps/settings/l10n/pt_BR.js index a714adb6a7d..f6056caf78c 100644 --- a/apps/settings/l10n/pt_BR.js +++ b/apps/settings/l10n/pt_BR.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Arquitetura", "64-bit" : "64-bit", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Parece que você está executando uma versão PHP de 32 bits. Nextcloud precisa de 64 bits para funcionar bem. Atualize seu sistema operacional e PHP para 64 bits!", + "Task Processing pickup speed" : "Velocidade de captação do Processamento de Tarefas", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Nenhuma tarefa agendada na última %n hora.","Nenhuma tarefa agendada nas últimas %n horas.","Nenhuma tarefa agendada nas últimas %n horas."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["A velocidade de captação do processamento de tarefas tem sido boa na última %n hora.","A velocidade de captação do processamento de tarefas tem sido boa nas últimas %n horas.","A velocidade de captação do processamento de tarefas tem sido boa nas últimas %n horas."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["A velocidade de captação do processamento de tarefas tem sido lenta na última %n hora. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano.","A velocidade de captação do processamento de tarefas tem sido lenta nas últimas %n horas. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano.","A velocidade de captação do processamento de tarefas tem sido lenta nas últimas %n horas. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano."], "Temporary space available" : "Espaço temporário disponível", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Erro ao verificar o caminho temporário do PHP - ele não foi configurado corretamente para um diretório. Valor retornado:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "A função PHP \"disk_free_space\" está desativada, o que impede a verificação de espaço suficiente nos diretórios temporários.", @@ -426,7 +430,7 @@ OC.L10N.register( "Actions" : "Ações", "Results from other categories" : "Resultados de outras categorias", "No apps found for your version" : "Nenhum aplicativo encontrado para a sua versão", - "_%n app has an update available_::_%n apps have an update available_" : ["%n aplicativo tem atualização disponível","%n aplicativos tem atualização disponível","%n aplicativos tem atualização disponível"], + "_%n app has an update available_::_%n apps have an update available_" : ["%n aplicativo tem atualização disponível","%n de aplicativos tem atualização disponível","%n aplicativos tem atualização disponível"], "_Update_::_Update all_" : ["Atualizar","Atualizar todos","Atualizar todos"], "Failed to load groups" : "Falha ao carregar grupos", "Failed to create group" : "Falha ao criar grupo", @@ -561,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Não foi possível atualizar a configuração padrão do perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Ativar ou desativar o perfil por padrão para novas contas.", + "Password confirmation is required" : "A confirmação da senha é necessária", "Failed to save setting" : "Falha ao salvar a configuração", "{app}'s declarative setting field: {name}" : "Campo de configuração declarativa de {app}: {name}", "Unable to update server side encryption config" : "Não foi possível atualizar a configuração de criptografia do lado do servidor", @@ -583,9 +588,12 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "É sempre bom criar backups regulares dos seus dados. No caso de criptografia, certifique-se de fazer backup das chaves de criptografia juntamente com os seus dados.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulte a documentação do administrador para saber como criptografar manualmente também os arquivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Este é o aviso final: Você realmente quer ativar a criptografia?", + "Failed to delete group \"{group}\"" : "Falha ao excluir grupo \"{group}\"", "Please confirm the group removal" : "Por favor confirme a remoção do grupo", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Você está prestes a excluir o grupo \"{group}\". As contas NÃO serão excluídas.", "Submit" : "Enviar", "Rename group" : "Renomear grupo", + "Delete group" : "Excluir grupo", "Current password" : "Senha atual", "New password" : "Nova senha", "Change password" : "Alterar senha", @@ -692,8 +700,8 @@ OC.L10N.register( "Language" : "Idioma", "Set default language" : "Definir idioma padrão", "Add new account" : "Adicionar nova conta", - "_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} conta …","{userCount} contas …","{userCount} contas …"], - "_{userCount} account_::_{userCount} accounts_" : ["{userCount} conta","{userCount} contas","{userCount} contas"], + "_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} conta …","{userCount} de contas …","{userCount} contas …"], + "_{userCount} account_::_{userCount} accounts_" : ["{userCount} conta","{userCount} de contas","{userCount} contas"], "Total rows summary" : "Resumo do total de linhas", "Scroll to load more rows" : "Role para carregar mais linhas", "Password or insufficient permissions message" : "Mensagem de senha ou permissões insuficientes", diff --git a/apps/settings/l10n/pt_BR.json b/apps/settings/l10n/pt_BR.json index 5f9db6652aa..7dad6ae794d 100644 --- a/apps/settings/l10n/pt_BR.json +++ b/apps/settings/l10n/pt_BR.json @@ -313,6 +313,10 @@ "Architecture" : "Arquitetura", "64-bit" : "64-bit", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Parece que você está executando uma versão PHP de 32 bits. Nextcloud precisa de 64 bits para funcionar bem. Atualize seu sistema operacional e PHP para 64 bits!", + "Task Processing pickup speed" : "Velocidade de captação do Processamento de Tarefas", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Nenhuma tarefa agendada na última %n hora.","Nenhuma tarefa agendada nas últimas %n horas.","Nenhuma tarefa agendada nas últimas %n horas."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["A velocidade de captação do processamento de tarefas tem sido boa na última %n hora.","A velocidade de captação do processamento de tarefas tem sido boa nas últimas %n horas.","A velocidade de captação do processamento de tarefas tem sido boa nas últimas %n horas."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["A velocidade de captação do processamento de tarefas tem sido lenta na última %n hora. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano.","A velocidade de captação do processamento de tarefas tem sido lenta nas últimas %n horas. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano.","A velocidade de captação do processamento de tarefas tem sido lenta nas últimas %n horas. Muitas tarefas levaram mais de 4 minutos para serem coletadas. Considere a possibilidade de configurar um trabalhador para processar tarefas em segundo plano."], "Temporary space available" : "Espaço temporário disponível", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Erro ao verificar o caminho temporário do PHP - ele não foi configurado corretamente para um diretório. Valor retornado:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "A função PHP \"disk_free_space\" está desativada, o que impede a verificação de espaço suficiente nos diretórios temporários.", @@ -424,7 +428,7 @@ "Actions" : "Ações", "Results from other categories" : "Resultados de outras categorias", "No apps found for your version" : "Nenhum aplicativo encontrado para a sua versão", - "_%n app has an update available_::_%n apps have an update available_" : ["%n aplicativo tem atualização disponível","%n aplicativos tem atualização disponível","%n aplicativos tem atualização disponível"], + "_%n app has an update available_::_%n apps have an update available_" : ["%n aplicativo tem atualização disponível","%n de aplicativos tem atualização disponível","%n aplicativos tem atualização disponível"], "_Update_::_Update all_" : ["Atualizar","Atualizar todos","Atualizar todos"], "Failed to load groups" : "Falha ao carregar grupos", "Failed to create group" : "Falha ao criar grupo", @@ -559,6 +563,7 @@ "Unable to update profile default setting" : "Não foi possível atualizar a configuração padrão do perfil", "Profile" : "Perfil", "Enable or disable profile by default for new accounts." : "Ativar ou desativar o perfil por padrão para novas contas.", + "Password confirmation is required" : "A confirmação da senha é necessária", "Failed to save setting" : "Falha ao salvar a configuração", "{app}'s declarative setting field: {name}" : "Campo de configuração declarativa de {app}: {name}", "Unable to update server side encryption config" : "Não foi possível atualizar a configuração de criptografia do lado do servidor", @@ -581,9 +586,12 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "É sempre bom criar backups regulares dos seus dados. No caso de criptografia, certifique-se de fazer backup das chaves de criptografia juntamente com os seus dados.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulte a documentação do administrador para saber como criptografar manualmente também os arquivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Este é o aviso final: Você realmente quer ativar a criptografia?", + "Failed to delete group \"{group}\"" : "Falha ao excluir grupo \"{group}\"", "Please confirm the group removal" : "Por favor confirme a remoção do grupo", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Você está prestes a excluir o grupo \"{group}\". As contas NÃO serão excluídas.", "Submit" : "Enviar", "Rename group" : "Renomear grupo", + "Delete group" : "Excluir grupo", "Current password" : "Senha atual", "New password" : "Nova senha", "Change password" : "Alterar senha", @@ -690,8 +698,8 @@ "Language" : "Idioma", "Set default language" : "Definir idioma padrão", "Add new account" : "Adicionar nova conta", - "_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} conta …","{userCount} contas …","{userCount} contas …"], - "_{userCount} account_::_{userCount} accounts_" : ["{userCount} conta","{userCount} contas","{userCount} contas"], + "_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} conta …","{userCount} de contas …","{userCount} contas …"], + "_{userCount} account_::_{userCount} accounts_" : ["{userCount} conta","{userCount} de contas","{userCount} contas"], "Total rows summary" : "Resumo do total de linhas", "Scroll to load more rows" : "Role para carregar mais linhas", "Password or insufficient permissions message" : "Mensagem de senha ou permissões insuficientes", diff --git a/apps/settings/l10n/pt_PT.js b/apps/settings/l10n/pt_PT.js index 89adb5c5e84..c0124eb9dda 100644 --- a/apps/settings/l10n/pt_PT.js +++ b/apps/settings/l10n/pt_PT.js @@ -179,6 +179,7 @@ OC.L10N.register( "Login" : "Iniciar Sessão", "Password" : "Palavra-passe", "Profile" : "Perfil", + "Password confirmation is required" : "Confirmação de senha necessária", "Server-side encryption" : "Atualizar App", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "A cifra do lado do servidor possibilita cifrar os ficheiros que serão enviados para este servidor. Isto implica um impacto no desempenho e só deverá ser ativo quando necessário.", "Enable server-side encryption" : "Ativar encriptação do lado do servidor", diff --git a/apps/settings/l10n/pt_PT.json b/apps/settings/l10n/pt_PT.json index 8cef2649872..13559db25fd 100644 --- a/apps/settings/l10n/pt_PT.json +++ b/apps/settings/l10n/pt_PT.json @@ -177,6 +177,7 @@ "Login" : "Iniciar Sessão", "Password" : "Palavra-passe", "Profile" : "Perfil", + "Password confirmation is required" : "Confirmação de senha necessária", "Server-side encryption" : "Atualizar App", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "A cifra do lado do servidor possibilita cifrar os ficheiros que serão enviados para este servidor. Isto implica um impacto no desempenho e só deverá ser ativo quando necessário.", "Enable server-side encryption" : "Ativar encriptação do lado do servidor", diff --git a/apps/settings/l10n/ro.js b/apps/settings/l10n/ro.js index c512d713c00..0357adbac64 100644 --- a/apps/settings/l10n/ro.js +++ b/apps/settings/l10n/ro.js @@ -183,6 +183,7 @@ OC.L10N.register( "Create new app password" : "Crează o nouă parolă pentru aplicație", "Login" : "Autentificare", "Password" : "Parolă", + "Password confirmation is required" : "Confirmarea parolei este necesară", "Server-side encryption" : "Criptare la nivel de server", "Enable server-side encryption" : "Activează criptarea pe server", "Select default encryption module:" : "Selectează modulul implicit de criptare:", diff --git a/apps/settings/l10n/ro.json b/apps/settings/l10n/ro.json index 15ff59a23b1..04560361dbc 100644 --- a/apps/settings/l10n/ro.json +++ b/apps/settings/l10n/ro.json @@ -181,6 +181,7 @@ "Create new app password" : "Crează o nouă parolă pentru aplicație", "Login" : "Autentificare", "Password" : "Parolă", + "Password confirmation is required" : "Confirmarea parolei este necesară", "Server-side encryption" : "Criptare la nivel de server", "Enable server-side encryption" : "Activează criptarea pe server", "Select default encryption module:" : "Selectează modulul implicit de criptare:", diff --git a/apps/settings/l10n/ru.js b/apps/settings/l10n/ru.js index 13b0dd8aa55..6d52776f80b 100644 --- a/apps/settings/l10n/ru.js +++ b/apps/settings/l10n/ru.js @@ -561,6 +561,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Не удалось обновить состояние использования профилей по умолчанию", "Profile" : "Профиль", "Enable or disable profile by default for new accounts." : "Включите или отключите профиль по умолчанию для новых учетных записей.", + "Password confirmation is required" : "Требуется подтверждение пароля", "Failed to save setting" : "Не удалось сохранить параметры", "{app}'s declarative setting field: {name}" : "{app} поле декларативной настройки: {name}", "Unable to update server side encryption config" : "Не удалось обновить параметры шифрования на стороне сервера", diff --git a/apps/settings/l10n/ru.json b/apps/settings/l10n/ru.json index 663262e7d55..c44c2c68b59 100644 --- a/apps/settings/l10n/ru.json +++ b/apps/settings/l10n/ru.json @@ -559,6 +559,7 @@ "Unable to update profile default setting" : "Не удалось обновить состояние использования профилей по умолчанию", "Profile" : "Профиль", "Enable or disable profile by default for new accounts." : "Включите или отключите профиль по умолчанию для новых учетных записей.", + "Password confirmation is required" : "Требуется подтверждение пароля", "Failed to save setting" : "Не удалось сохранить параметры", "{app}'s declarative setting field: {name}" : "{app} поле декларативной настройки: {name}", "Unable to update server side encryption config" : "Не удалось обновить параметры шифрования на стороне сервера", diff --git a/apps/settings/l10n/sk.js b/apps/settings/l10n/sk.js index 8c9c8cbe755..758bf38f889 100644 --- a/apps/settings/l10n/sk.js +++ b/apps/settings/l10n/sk.js @@ -560,6 +560,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Nie je možné aktualizovať predvolené nastavenie profilu", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Predvolene povoliť alebo zakázať profil pre nové účty.", + "Password confirmation is required" : "Vyžaduje sa overenie heslom", "Failed to save setting" : "Nepodarilo sa uložiť nastavenie", "{app}'s declarative setting field: {name}" : "Pole deklaratívneho nastavenia aplikácie {app}: {name}", "Unable to update server side encryption config" : "Nedá sa aktualizovať konfigurácia šifrovania na strane servera", diff --git a/apps/settings/l10n/sk.json b/apps/settings/l10n/sk.json index b14b6a769dd..264fcc0dc03 100644 --- a/apps/settings/l10n/sk.json +++ b/apps/settings/l10n/sk.json @@ -558,6 +558,7 @@ "Unable to update profile default setting" : "Nie je možné aktualizovať predvolené nastavenie profilu", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Predvolene povoliť alebo zakázať profil pre nové účty.", + "Password confirmation is required" : "Vyžaduje sa overenie heslom", "Failed to save setting" : "Nepodarilo sa uložiť nastavenie", "{app}'s declarative setting field: {name}" : "Pole deklaratívneho nastavenia aplikácie {app}: {name}", "Unable to update server side encryption config" : "Nedá sa aktualizovať konfigurácia šifrovania na strane servera", diff --git a/apps/settings/l10n/sq.js b/apps/settings/l10n/sq.js index e8303cccc38..51619af59c0 100644 --- a/apps/settings/l10n/sq.js +++ b/apps/settings/l10n/sq.js @@ -135,6 +135,7 @@ OC.L10N.register( "Create new app password" : "Krijoni fjalëkalim aplikacioni të ri", "Login" : "Hyrje", "Password" : "Fjalëkalim", + "Password confirmation is required" : "Kërkohet konfirmimi i fjalëkalimit", "Server-side encryption" : "Fshehtëzim më anë shërbyesi", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Enkriptimi nga ana e serverit bën të mundur enkriptimin e skedarëve të ngarkuar në këtë server. Kjo vjen me kufizime si një ndëshkim për performancën, prandaj e lejoni këtë vetëm nëse është e nevojshme.", "Enable server-side encryption" : "Aktivizo fshehtëzim më anë të shërbyesit", diff --git a/apps/settings/l10n/sq.json b/apps/settings/l10n/sq.json index f5a3020cb78..544389daab3 100644 --- a/apps/settings/l10n/sq.json +++ b/apps/settings/l10n/sq.json @@ -133,6 +133,7 @@ "Create new app password" : "Krijoni fjalëkalim aplikacioni të ri", "Login" : "Hyrje", "Password" : "Fjalëkalim", + "Password confirmation is required" : "Kërkohet konfirmimi i fjalëkalimit", "Server-side encryption" : "Fshehtëzim më anë shërbyesi", "Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Enkriptimi nga ana e serverit bën të mundur enkriptimin e skedarëve të ngarkuar në këtë server. Kjo vjen me kufizime si një ndëshkim për performancën, prandaj e lejoni këtë vetëm nëse është e nevojshme.", "Enable server-side encryption" : "Aktivizo fshehtëzim më anë të shërbyesit", diff --git a/apps/settings/l10n/sr.js b/apps/settings/l10n/sr.js index 10ed78edc66..904dca70386 100644 --- a/apps/settings/l10n/sr.js +++ b/apps/settings/l10n/sr.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Архитектура", "64-bit" : "64-бита", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Изгледа да покрећете 32-битну PHP верзију. За правилно извршавање Nextcloud захтева 64-битну верзију. Молимо вас да ажурирате свој оперативни систем и PHP на 64-бита!", + "Task Processing pickup speed" : "Брзина прихватања Обраде задатака", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Нема ниједног заказаног задатка у последњих %n сат.","Нема ниједног заказаног задатка у последњих %n сата.","Нема ниједног заказаног задатка у последњих %n сати."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Брзина прихватања задатака је била у реду током последњег %n сата.","Брзина прихватања задатака је била у реду током последња %n сата.","Брзина прихватања задатака је била у реду током последњих %n сати."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Брзина прихватања задатака је била спора током последњег %n сата. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини.","Брзина прихватања задатака је била спора током последња %n сата. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини.","Брзина прихватања задатака је била спора током последњих %n сати. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини."], "Temporary space available" : "Доступан привремени простор", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Грешка приликом провере привремене PHP путање - није била исправно постављена на директоријум. Враћена вредност је: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Искључена је PHP функција „disk_free_space”, па не може да се провери довољна количина слободног простора у привременим директоријумима.", @@ -561,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Подразумевано подешавање профила не може да се ажурира", "Profile" : "Профил", "Enable or disable profile by default for new accounts." : "Профил нових налога се подразумевано укључује или искључује.", + "Password confirmation is required" : "Потребна је потврда лозинке", "Failed to save setting" : "Није успело чување подешавања", "{app}'s declarative setting field: {name}" : "поље декларативног подешавања апликације {app}: {name}", "Unable to update server side encryption config" : "Конфигурација енкрипције на страни сервера не може да се ажурира", @@ -583,9 +588,12 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Увек је паметно да правите редовне резервне копије података. У случају када су подаци шифровани, онда поред њих и резервне копије кључева за шифровања.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Погледајте админ документацију у вези са ручним шифровањем постојећих фајлова.", "This is the final warning: Do you really want to enable encryption?" : "Ово је последње упозорење: Да ли стварно желите да укључите шифровање?", + "Failed to delete group \"{group}\"" : "Није успело брисање групе „{group}”", "Please confirm the group removal" : "Молимо вас да потврдите уклањање групе", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете обрисати групу „{group}”. Налози се НЕЋЕ обрисати.", "Submit" : "Пошаљи", "Rename group" : "Промени име групе", + "Delete group" : "Брисање групе", "Current password" : "Тренутна лозинка", "New password" : "Нова лозинка", "Change password" : "Измени лозинку", diff --git a/apps/settings/l10n/sr.json b/apps/settings/l10n/sr.json index aa14719400e..a360c48f907 100644 --- a/apps/settings/l10n/sr.json +++ b/apps/settings/l10n/sr.json @@ -313,6 +313,10 @@ "Architecture" : "Архитектура", "64-bit" : "64-бита", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Изгледа да покрећете 32-битну PHP верзију. За правилно извршавање Nextcloud захтева 64-битну верзију. Молимо вас да ажурирате свој оперативни систем и PHP на 64-бита!", + "Task Processing pickup speed" : "Брзина прихватања Обраде задатака", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Нема ниједног заказаног задатка у последњих %n сат.","Нема ниједног заказаног задатка у последњих %n сата.","Нема ниједног заказаног задатка у последњих %n сати."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Брзина прихватања задатака је била у реду током последњег %n сата.","Брзина прихватања задатака је била у реду током последња %n сата.","Брзина прихватања задатака је била у реду током последњих %n сати."], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Брзина прихватања задатака је била спора током последњег %n сата. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини.","Брзина прихватања задатака је била спора током последња %n сата. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини.","Брзина прихватања задатака је била спора током последњих %n сати. За многе задатке је требало више од 4 минута да се прихвате. Размислите о подешавању радник-процеса за обраду задатака у позадини."], "Temporary space available" : "Доступан привремени простор", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Грешка приликом провере привремене PHP путање - није била исправно постављена на директоријум. Враћена вредност је: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Искључена је PHP функција „disk_free_space”, па не може да се провери довољна количина слободног простора у привременим директоријумима.", @@ -559,6 +563,7 @@ "Unable to update profile default setting" : "Подразумевано подешавање профила не може да се ажурира", "Profile" : "Профил", "Enable or disable profile by default for new accounts." : "Профил нових налога се подразумевано укључује или искључује.", + "Password confirmation is required" : "Потребна је потврда лозинке", "Failed to save setting" : "Није успело чување подешавања", "{app}'s declarative setting field: {name}" : "поље декларативног подешавања апликације {app}: {name}", "Unable to update server side encryption config" : "Конфигурација енкрипције на страни сервера не може да се ажурира", @@ -581,9 +586,12 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Увек је паметно да правите редовне резервне копије података. У случају када су подаци шифровани, онда поред њих и резервне копије кључева за шифровања.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Погледајте админ документацију у вези са ручним шифровањем постојећих фајлова.", "This is the final warning: Do you really want to enable encryption?" : "Ово је последње упозорење: Да ли стварно желите да укључите шифровање?", + "Failed to delete group \"{group}\"" : "Није успело брисање групе „{group}”", "Please confirm the group removal" : "Молимо вас да потврдите уклањање групе", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете обрисати групу „{group}”. Налози се НЕЋЕ обрисати.", "Submit" : "Пошаљи", "Rename group" : "Промени име групе", + "Delete group" : "Брисање групе", "Current password" : "Тренутна лозинка", "New password" : "Нова лозинка", "Change password" : "Измени лозинку", diff --git a/apps/settings/l10n/sv.js b/apps/settings/l10n/sv.js index 544ebbe2592..3fa5b1f24d3 100644 --- a/apps/settings/l10n/sv.js +++ b/apps/settings/l10n/sv.js @@ -404,6 +404,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Det gick inte att uppdatera profilens standardinställning", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktivera eller inaktivera profil som standard för nya konton.", + "Password confirmation is required" : "Lösenordsbekräftelse krävs", "Failed to save setting" : "Kunde inte spara inställning", "Unable to update server side encryption config" : "Kunde inte uppdatera serversidans krypteringskonfiguration", "Server-side encryption" : "Serverkryptering", diff --git a/apps/settings/l10n/sv.json b/apps/settings/l10n/sv.json index ef882b481ae..7cffffd15f0 100644 --- a/apps/settings/l10n/sv.json +++ b/apps/settings/l10n/sv.json @@ -402,6 +402,7 @@ "Unable to update profile default setting" : "Det gick inte att uppdatera profilens standardinställning", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Aktivera eller inaktivera profil som standard för nya konton.", + "Password confirmation is required" : "Lösenordsbekräftelse krävs", "Failed to save setting" : "Kunde inte spara inställning", "Unable to update server side encryption config" : "Kunde inte uppdatera serversidans krypteringskonfiguration", "Server-side encryption" : "Serverkryptering", diff --git a/apps/settings/l10n/tr.js b/apps/settings/l10n/tr.js index 67fa29730ba..f1308a79a80 100644 --- a/apps/settings/l10n/tr.js +++ b/apps/settings/l10n/tr.js @@ -561,6 +561,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Profil varsayılan ayarı güncellenemedi", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Bu seçenek kullanıma alındığında, profil yeni hesaplar için varsayılan olur.", + "Password confirmation is required" : "Parola onayının yazılması zorunludur", "Failed to save setting" : "Ayar kaydedilemedi", "{app}'s declarative setting field: {name}" : "{app} uygulamasının bildirdiği ayar alanı: {name}", "Unable to update server side encryption config" : "Sunucu tarafı şifreleme yapılandırması güncellenemedi", diff --git a/apps/settings/l10n/tr.json b/apps/settings/l10n/tr.json index 1a60c3f9d0d..740c010553e 100644 --- a/apps/settings/l10n/tr.json +++ b/apps/settings/l10n/tr.json @@ -559,6 +559,7 @@ "Unable to update profile default setting" : "Profil varsayılan ayarı güncellenemedi", "Profile" : "Profil", "Enable or disable profile by default for new accounts." : "Bu seçenek kullanıma alındığında, profil yeni hesaplar için varsayılan olur.", + "Password confirmation is required" : "Parola onayının yazılması zorunludur", "Failed to save setting" : "Ayar kaydedilemedi", "{app}'s declarative setting field: {name}" : "{app} uygulamasının bildirdiği ayar alanı: {name}", "Unable to update server side encryption config" : "Sunucu tarafı şifreleme yapılandırması güncellenemedi", diff --git a/apps/settings/l10n/uk.js b/apps/settings/l10n/uk.js index c87a948b6a3..398369ee18d 100644 --- a/apps/settings/l10n/uk.js +++ b/apps/settings/l10n/uk.js @@ -457,6 +457,7 @@ OC.L10N.register( "Unable to update profile default setting" : "Не вдалося оновити стандартні налаштування профілю", "Profile" : "Профіль", "Enable or disable profile by default for new accounts." : "Увімкнути або вимкнути стандартний профіль для нових акаунтів.", + "Password confirmation is required" : "Необхідне підтвердження паролем", "Failed to save setting" : "Не вдалося зберегти налаштування", "Unable to update server side encryption config" : "Не вдалося оновити конфігурацію шифрування на стороні сервера", "Server-side encryption" : "Шифрування на сервері", diff --git a/apps/settings/l10n/uk.json b/apps/settings/l10n/uk.json index f0f485c58c2..03d59910e56 100644 --- a/apps/settings/l10n/uk.json +++ b/apps/settings/l10n/uk.json @@ -455,6 +455,7 @@ "Unable to update profile default setting" : "Не вдалося оновити стандартні налаштування профілю", "Profile" : "Профіль", "Enable or disable profile by default for new accounts." : "Увімкнути або вимкнути стандартний профіль для нових акаунтів.", + "Password confirmation is required" : "Необхідне підтвердження паролем", "Failed to save setting" : "Не вдалося зберегти налаштування", "Unable to update server side encryption config" : "Не вдалося оновити конфігурацію шифрування на стороні сервера", "Server-side encryption" : "Шифрування на сервері", diff --git a/apps/settings/l10n/zh_CN.js b/apps/settings/l10n/zh_CN.js index 97c083e3a4e..4d1cb4663a5 100644 --- a/apps/settings/l10n/zh_CN.js +++ b/apps/settings/l10n/zh_CN.js @@ -565,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "无法更新个人资料默认设置", "Profile" : "个人资料", "Enable or disable profile by default for new accounts." : "默认情况下为新账号启用或禁用配置文件。", + "Password confirmation is required" : "需要密码确认", "Failed to save setting" : "保存设置失败", "{app}'s declarative setting field: {name}" : "{app} 的声明性设置字段:{name}", "Unable to update server side encryption config" : "无法更新服务端加密设置", diff --git a/apps/settings/l10n/zh_CN.json b/apps/settings/l10n/zh_CN.json index b7f8ccf6f40..34ea100b230 100644 --- a/apps/settings/l10n/zh_CN.json +++ b/apps/settings/l10n/zh_CN.json @@ -563,6 +563,7 @@ "Unable to update profile default setting" : "无法更新个人资料默认设置", "Profile" : "个人资料", "Enable or disable profile by default for new accounts." : "默认情况下为新账号启用或禁用配置文件。", + "Password confirmation is required" : "需要密码确认", "Failed to save setting" : "保存设置失败", "{app}'s declarative setting field: {name}" : "{app} 的声明性设置字段:{name}", "Unable to update server side encryption config" : "无法更新服务端加密设置", diff --git a/apps/settings/l10n/zh_HK.js b/apps/settings/l10n/zh_HK.js index e6e9d177ca4..ab2f321716b 100644 --- a/apps/settings/l10n/zh_HK.js +++ b/apps/settings/l10n/zh_HK.js @@ -565,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "無法更新個人檔案默認設定。", "Profile" : "個人設定", "Enable or disable profile by default for new accounts." : "預設情況下為新帳戶啟用或停用個人檔案。", + "Password confirmation is required" : "需要密碼確認", "Failed to save setting" : "儲存設定失敗", "{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}", "Unable to update server side encryption config" : "無法更新伺服器端加密配置", diff --git a/apps/settings/l10n/zh_HK.json b/apps/settings/l10n/zh_HK.json index 398f2554973..6f4a48888ef 100644 --- a/apps/settings/l10n/zh_HK.json +++ b/apps/settings/l10n/zh_HK.json @@ -563,6 +563,7 @@ "Unable to update profile default setting" : "無法更新個人檔案默認設定。", "Profile" : "個人設定", "Enable or disable profile by default for new accounts." : "預設情況下為新帳戶啟用或停用個人檔案。", + "Password confirmation is required" : "需要密碼確認", "Failed to save setting" : "儲存設定失敗", "{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}", "Unable to update server side encryption config" : "無法更新伺服器端加密配置", diff --git a/apps/settings/l10n/zh_TW.js b/apps/settings/l10n/zh_TW.js index 542a725bf9a..d5628c8501a 100644 --- a/apps/settings/l10n/zh_TW.js +++ b/apps/settings/l10n/zh_TW.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "架構", "64-bit" : "64 位元", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "您似乎正在執行 32 位元版本的 PHP。Nextcloud 需要 64 位元才能運作良好。請將您的作業系統與 PHP 升級至 64 位元!", + "Task Processing pickup speed" : "任務處理擷取速度", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["最近%n小時內沒有安排好的任務。"], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["最近%n小時內的任務擷取速度正常。"], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["最近%n小時內,任務擷取速度緩慢。許多任務的擷取時間超過4分鐘。請考慮設定 worker 在背景處理任務。"], "Temporary space available" : "可用臨時空間", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "檢查臨時 PHP 路徑時發生錯誤 - 未正確設定為目錄。回傳值:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP 函式「disk_free_space」已停用,這會阻止檢查暫存目錄中是否有足夠的空間。", @@ -561,6 +565,7 @@ OC.L10N.register( "Unable to update profile default setting" : "無法更新個人檔案預設設定", "Profile" : "個人檔案", "Enable or disable profile by default for new accounts." : "預設情況下為新帳號啟用或停用個人檔案", + "Password confirmation is required" : "需要密碼確認", "Failed to save setting" : "儲存設定失敗", "{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}", "Unable to update server side encryption config" : "無法更新伺服器端加密組態設定", @@ -583,9 +588,12 @@ OC.L10N.register( "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "定期備份您的資料常有幫助,若您有啟用加密,請確保您也有備份加密金鑰。", "Refer to the admin documentation on how to manually also encrypt existing files." : "請參考管理說明文件,了解如何手動加密現有檔案。", "This is the final warning: Do you really want to enable encryption?" : "這是最後的警告:請問您真的要開啟加密模式?", + "Failed to delete group \"{group}\"" : "刪除群組「{group}」失敗", "Please confirm the group removal" : "請確認移除群組", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳號將不會被刪除。", "Submit" : "提交", "Rename group" : "重新命名群組", + "Delete group" : "刪除群組", "Current password" : "目前密碼", "New password" : "新密碼", "Change password" : "變更密碼", diff --git a/apps/settings/l10n/zh_TW.json b/apps/settings/l10n/zh_TW.json index 07fa8616ba3..0f2c6f6653e 100644 --- a/apps/settings/l10n/zh_TW.json +++ b/apps/settings/l10n/zh_TW.json @@ -313,6 +313,10 @@ "Architecture" : "架構", "64-bit" : "64 位元", "It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "您似乎正在執行 32 位元版本的 PHP。Nextcloud 需要 64 位元才能運作良好。請將您的作業系統與 PHP 升級至 64 位元!", + "Task Processing pickup speed" : "任務處理擷取速度", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["最近%n小時內沒有安排好的任務。"], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["最近%n小時內的任務擷取速度正常。"], + "_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["最近%n小時內,任務擷取速度緩慢。許多任務的擷取時間超過4分鐘。請考慮設定 worker 在背景處理任務。"], "Temporary space available" : "可用臨時空間", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "檢查臨時 PHP 路徑時發生錯誤 - 未正確設定為目錄。回傳值:%s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP 函式「disk_free_space」已停用,這會阻止檢查暫存目錄中是否有足夠的空間。", @@ -559,6 +563,7 @@ "Unable to update profile default setting" : "無法更新個人檔案預設設定", "Profile" : "個人檔案", "Enable or disable profile by default for new accounts." : "預設情況下為新帳號啟用或停用個人檔案", + "Password confirmation is required" : "需要密碼確認", "Failed to save setting" : "儲存設定失敗", "{app}'s declarative setting field: {name}" : "{app} 的聲明性設定欄位:{name}", "Unable to update server side encryption config" : "無法更新伺服器端加密組態設定", @@ -581,9 +586,12 @@ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "定期備份您的資料常有幫助,若您有啟用加密,請確保您也有備份加密金鑰。", "Refer to the admin documentation on how to manually also encrypt existing files." : "請參考管理說明文件,了解如何手動加密現有檔案。", "This is the final warning: Do you really want to enable encryption?" : "這是最後的警告:請問您真的要開啟加密模式?", + "Failed to delete group \"{group}\"" : "刪除群組「{group}」失敗", "Please confirm the group removal" : "請確認移除群組", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳號將不會被刪除。", "Submit" : "提交", "Rename group" : "重新命名群組", + "Delete group" : "刪除群組", "Current password" : "目前密碼", "New password" : "新密碼", "Change password" : "變更密碼", diff --git a/apps/settings/lib/Controller/CommonSettingsTrait.php b/apps/settings/lib/Controller/CommonSettingsTrait.php index 56760c10f81..67398d1357b 100644 --- a/apps/settings/lib/Controller/CommonSettingsTrait.php +++ b/apps/settings/lib/Controller/CommonSettingsTrait.php @@ -144,6 +144,14 @@ trait CommonSettingsTrait { $this->declarativeSettingsManager->loadSchemas(); $declarativeSettings = $this->declarativeSettingsManager->getFormsWithValues($user, $type, $section); + foreach ($declarativeSettings as &$form) { + foreach ($form['fields'] as &$field) { + if (isset($field['sensitive']) && $field['sensitive'] === true && !empty($field['value'])) { + $field['value'] = 'dummySecret'; + } + } + } + if ($type === 'personal') { $settings = array_values($this->settingsManager->getPersonalSettings($section)); if ($section === 'theming') { diff --git a/apps/settings/lib/Controller/DeclarativeSettingsController.php b/apps/settings/lib/Controller/DeclarativeSettingsController.php index eb9d45839de..4e4bee4043c 100644 --- a/apps/settings/lib/Controller/DeclarativeSettingsController.php +++ b/apps/settings/lib/Controller/DeclarativeSettingsController.php @@ -15,6 +15,7 @@ use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; use OCA\Settings\ResponseDefinitions; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCSController; @@ -53,6 +54,45 @@ class DeclarativeSettingsController extends OCSController { */ #[NoAdminRequired] public function setValue(string $app, string $formId, string $fieldId, mixed $value): DataResponse { + return $this->saveValue($app, $formId, $fieldId, $value); + } + + /** + * Sets a declarative settings value. + * Password confirmation is required for sensitive values. + * + * @param string $app ID of the app + * @param string $formId ID of the form + * @param string $fieldId ID of the field + * @param mixed $value Value to be saved + * @return DataResponse<Http::STATUS_OK, null, array{}> + * @throws NotLoggedInException Not logged in or not an admin user + * @throws NotAdminException Not logged in or not an admin user + * @throws OCSBadRequestException Invalid arguments to save value + * + * 200: Value set successfully + */ + #[NoAdminRequired] + #[PasswordConfirmationRequired] + public function setSensitiveValue(string $app, string $formId, string $fieldId, mixed $value): DataResponse { + return $this->saveValue($app, $formId, $fieldId, $value); + } + + /** + * Sets a declarative settings value. + * + * @param string $app ID of the app + * @param string $formId ID of the form + * @param string $fieldId ID of the field + * @param mixed $value Value to be saved + * @return DataResponse<Http::STATUS_OK, null, array{}> + * @throws NotLoggedInException Not logged in or not an admin user + * @throws NotAdminException Not logged in or not an admin user + * @throws OCSBadRequestException Invalid arguments to save value + * + * 200: Value set successfully + */ + private function saveValue(string $app, string $formId, string $fieldId, mixed $value): DataResponse { $user = $this->userSession->getUser(); if ($user === null) { throw new NotLoggedInException(); diff --git a/apps/settings/lib/ResponseDefinitions.php b/apps/settings/lib/ResponseDefinitions.php index 0f3d6bffccf..12adefda91f 100644 --- a/apps/settings/lib/ResponseDefinitions.php +++ b/apps/settings/lib/ResponseDefinitions.php @@ -20,6 +20,7 @@ namespace OCA\Settings; * default: mixed, * options?: list<string|array{name: string, value: mixed}>, * value: string|int|float|bool|list<string>, + * sensitive?: boolean, * } * * @psalm-type SettingsDeclarativeForm = array{ diff --git a/apps/settings/openapi-full.json b/apps/settings/openapi-full.json index e12598a2584..d592051507b 100644 --- a/apps/settings/openapi-full.json +++ b/apps/settings/openapi-full.json @@ -169,6 +169,9 @@ } } ] + }, + "sensitive": { + "type": "boolean" } } }, @@ -373,6 +376,140 @@ } } }, + "/ocs/v2.php/settings/api/declarative/value-sensitive": { + "post": { + "operationId": "declarative_settings-set-sensitive-value", + "summary": "Sets a declarative settings value. Password confirmation is required for sensitive values.", + "description": "This endpoint requires password confirmation", + "tags": [ + "declarative_settings" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "app", + "formId", + "fieldId", + "value" + ], + "properties": { + "app": { + "type": "string", + "description": "ID of the app" + }, + "formId": { + "type": "string", + "description": "ID of the form" + }, + "fieldId": { + "type": "string", + "description": "ID of the field" + }, + "value": { + "type": "object", + "description": "Value to be saved" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Value set successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "nullable": true + } + } + } + } + } + } + } + }, + "500": { + "description": "Not logged in or not an admin user", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Invalid arguments to save value", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/settings/api/declarative/forms": { "get": { "operationId": "declarative_settings-get-forms", diff --git a/apps/settings/openapi.json b/apps/settings/openapi.json index f81b18bdc70..f38960aa244 100644 --- a/apps/settings/openapi.json +++ b/apps/settings/openapi.json @@ -169,6 +169,9 @@ } } ] + }, + "sensitive": { + "type": "boolean" } } }, @@ -332,6 +335,140 @@ } } }, + "/ocs/v2.php/settings/api/declarative/value-sensitive": { + "post": { + "operationId": "declarative_settings-set-sensitive-value", + "summary": "Sets a declarative settings value. Password confirmation is required for sensitive values.", + "description": "This endpoint requires password confirmation", + "tags": [ + "declarative_settings" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "app", + "formId", + "fieldId", + "value" + ], + "properties": { + "app": { + "type": "string", + "description": "ID of the app" + }, + "formId": { + "type": "string", + "description": "ID of the form" + }, + "fieldId": { + "type": "string", + "description": "ID of the field" + }, + "value": { + "type": "object", + "description": "Value to be saved" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Value set successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "nullable": true + } + } + } + } + } + } + } + }, + "500": { + "description": "Not logged in or not an admin user", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Invalid arguments to save value", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/settings/api/declarative/forms": { "get": { "operationId": "declarative_settings-get-forms", diff --git a/apps/settings/src/components/DeclarativeSettings/DeclarativeSection.vue b/apps/settings/src/components/DeclarativeSettings/DeclarativeSection.vue index 334739337e1..9ee1680516e 100644 --- a/apps/settings/src/components/DeclarativeSettings/DeclarativeSection.vue +++ b/apps/settings/src/components/DeclarativeSettings/DeclarativeSection.vue @@ -119,6 +119,7 @@ import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection' import NcInputField from '@nextcloud/vue/components/NcInputField' import NcSelect from '@nextcloud/vue/components/NcSelect' import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch' +import { confirmPassword } from '@nextcloud/password-confirmation' export default { name: 'DeclarativeSection', @@ -202,9 +203,19 @@ export default { } }, - updateDeclarativeSettingsValue(formField, value = null) { + async updateDeclarativeSettingsValue(formField, value = null) { try { - return axios.post(generateOcsUrl('settings/api/declarative/value'), { + let url = generateOcsUrl('settings/api/declarative/value') + if (formField?.sensitive === true) { + url = generateOcsUrl('settings/api/declarative/value-sensitive') + try { + await confirmPassword() + } catch (err) { + showError(t('settings', 'Password confirmation is required')) + return + } + } + return axios.post(url, { app: this.formApp, formId: this.form.id.replace(this.formApp + '_', ''), // Remove app prefix to send clean form id fieldId: formField.id, diff --git a/apps/settings/src/main-declarative-settings-forms.ts b/apps/settings/src/main-declarative-settings-forms.ts index 6e2d71b69ca..d6f5973baea 100644 --- a/apps/settings/src/main-declarative-settings-forms.ts +++ b/apps/settings/src/main-declarative-settings-forms.ts @@ -20,6 +20,7 @@ interface DeclarativeFormField { options: Array<unknown>|null, value: unknown, default: unknown, + sensitive: boolean, } interface DeclarativeForm { diff --git a/apps/systemtags/l10n/fa.js b/apps/systemtags/l10n/fa.js index 3fee766ae74..ff0c4bba17b 100644 --- a/apps/systemtags/l10n/fa.js +++ b/apps/systemtags/l10n/fa.js @@ -53,6 +53,7 @@ OC.L10N.register( "Update" : "به روز رسانی", "Delete" : "حذف", "Reset" : "ریست", + "Loading …" : "در حال بارگذاری...", "Manage tags" : "مدیریت برچسب ها", "Cancel" : "منصرف شدن", "Failed to load tags" : "بارگیری برچسب ها انجام نشد", diff --git a/apps/systemtags/l10n/fa.json b/apps/systemtags/l10n/fa.json index d7e21f03c45..7a542ff1a52 100644 --- a/apps/systemtags/l10n/fa.json +++ b/apps/systemtags/l10n/fa.json @@ -51,6 +51,7 @@ "Update" : "به روز رسانی", "Delete" : "حذف", "Reset" : "ریست", + "Loading …" : "در حال بارگذاری...", "Manage tags" : "مدیریت برچسب ها", "Cancel" : "منصرف شدن", "Failed to load tags" : "بارگیری برچسب ها انجام نشد", diff --git a/apps/systemtags/l10n/lv.js b/apps/systemtags/l10n/lv.js index 437dd173c1a..6bbd17c5d52 100644 --- a/apps/systemtags/l10n/lv.js +++ b/apps/systemtags/l10n/lv.js @@ -46,16 +46,19 @@ OC.L10N.register( "Invisible" : "Neredzama", "Updated tag" : "Birka atjaunināta", "Failed to update tag" : "Birku neizdevās atjaunināt", + "Failed to delete tag" : "Neizdevās izdzēst birku", "Create" : "Izveidot", "Update" : "Atjaunināt", "Delete" : "Izdzēst", "Reset" : "Atiestatīt", "Loading …" : "Ielādē…", "Cancel" : "Atcelt", + "Failed to load selected tags" : "Neizdevās ielādēt atlasītās birkas", "System admin disabled tag creation. You can only use existing ones." : "Sistēmas pārvaldītājs atspējoja birku izveidošanu. Ir iespējams izmantot tikai esošās.", "System tag creation is now restricted to administrators" : "Sistēmas birku izveidošana tagad ir pieejama tikai pārvaldītājiem", "System tag creation is now allowed for everybody" : "Sistēmas birku izveidošana tagad ir ļauta visiem", "Collaborative tags are available for all users. Restricted tags are visible to users but cannot be assigned by them. Invisible tags are for internal use, since users cannot see or assign them." : "Sadarbības birkas ir pieejamas visiem lietotājiem. Ierobežotās birkas ir redzamas lietotājiem, bet viņi tās nevar piešķirt. Neredzamās birkas ir paredzētas iekšējai lietošanai, jo lietotāji nevar tās redzēt vai piešķirt.", - "No tags found" : "Netika atrasta neviena birka" + "No tags found" : "Netika atrasta neviena birka", + "Failed to delete tag for file" : "Neizdevās izdzēst birku vai datni" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"); diff --git a/apps/systemtags/l10n/lv.json b/apps/systemtags/l10n/lv.json index 78723f0c006..254571a47ef 100644 --- a/apps/systemtags/l10n/lv.json +++ b/apps/systemtags/l10n/lv.json @@ -44,16 +44,19 @@ "Invisible" : "Neredzama", "Updated tag" : "Birka atjaunināta", "Failed to update tag" : "Birku neizdevās atjaunināt", + "Failed to delete tag" : "Neizdevās izdzēst birku", "Create" : "Izveidot", "Update" : "Atjaunināt", "Delete" : "Izdzēst", "Reset" : "Atiestatīt", "Loading …" : "Ielādē…", "Cancel" : "Atcelt", + "Failed to load selected tags" : "Neizdevās ielādēt atlasītās birkas", "System admin disabled tag creation. You can only use existing ones." : "Sistēmas pārvaldītājs atspējoja birku izveidošanu. Ir iespējams izmantot tikai esošās.", "System tag creation is now restricted to administrators" : "Sistēmas birku izveidošana tagad ir pieejama tikai pārvaldītājiem", "System tag creation is now allowed for everybody" : "Sistēmas birku izveidošana tagad ir ļauta visiem", "Collaborative tags are available for all users. Restricted tags are visible to users but cannot be assigned by them. Invisible tags are for internal use, since users cannot see or assign them." : "Sadarbības birkas ir pieejamas visiem lietotājiem. Ierobežotās birkas ir redzamas lietotājiem, bet viņi tās nevar piešķirt. Neredzamās birkas ir paredzētas iekšējai lietošanai, jo lietotāji nevar tās redzēt vai piešķirt.", - "No tags found" : "Netika atrasta neviena birka" + "No tags found" : "Netika atrasta neviena birka", + "Failed to delete tag for file" : "Neizdevās izdzēst birku vai datni" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" }
\ No newline at end of file diff --git a/apps/testing/lib/Settings/DeclarativeSettingsForm.php b/apps/testing/lib/Settings/DeclarativeSettingsForm.php index dd83e9c9e89..55e44cbcbea 100644 --- a/apps/testing/lib/Settings/DeclarativeSettingsForm.php +++ b/apps/testing/lib/Settings/DeclarativeSettingsForm.php @@ -169,6 +169,36 @@ class DeclarativeSettingsForm implements IDeclarativeSettingsForm { ], ], ], + [ + 'id' => 'test_sensitive_field', + 'title' => 'Sensitive text field', + 'description' => 'Set some secure value setting that is stored encrypted', + 'type' => DeclarativeSettingsTypes::TEXT, + 'label' => 'Sensitive field', + 'placeholder' => 'Set secure value', + 'default' => '', + 'sensitive' => true, // only for TEXT, PASSWORD types + ], + [ + 'id' => 'test_sensitive_field_2', + 'title' => 'Sensitive password field', + 'description' => 'Set some password setting that is stored encrypted', + 'type' => DeclarativeSettingsTypes::PASSWORD, + 'label' => 'Sensitive field', + 'placeholder' => 'Set secure value', + 'default' => '', + 'sensitive' => true, // only for TEXT, PASSWORD types + ], + [ + 'id' => 'test_non_sensitive_field', + 'title' => 'Password field', + 'description' => 'Set some password setting', + 'type' => DeclarativeSettingsTypes::PASSWORD, + 'label' => 'Password field', + 'placeholder' => 'Set secure value', + 'default' => '', + 'sensitive' => false, + ], ], ]; } diff --git a/apps/theming/l10n/fr.js b/apps/theming/l10n/fr.js index 0e0b8ba0a00..5827c084230 100644 --- a/apps/theming/l10n/fr.js +++ b/apps/theming/l10n/fr.js @@ -76,6 +76,7 @@ OC.L10N.register( "Advanced options" : "Options avancées", "Install the ImageMagick PHP extension with support for SVG images to automatically generate favicons based on the uploaded logo and color." : "Installez l'extension PHP ImageMagick qui prend en charge les images SVG pour générer automatiquement des favicons à partir du logo téléversé et de la couleur indiquée.", "If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Si vous rencontrez des problèmes, n'hésitez pas à les signaler sur {issuetracker}notre outil de suivi des problèmes{linkend}. Et si vous voulez vous impliquer, venez rejoindre {designteam}notre équipe de design{linkend} !", + "Unable to apply the setting." : "Impossible d'appliquer le réglage.", "Appearance and accessibility settings" : "Paramètres d’apparence et d’accessibilité", "Misc accessibility options" : "Diverses options d'accessibilité", "Enable blur background filter (may increase GPU load)" : "Activer le filtre flou de l'arrière-plan (peut augmenter la charge du GPU)", @@ -117,6 +118,7 @@ OC.L10N.register( "Reset to default" : "Restaurer les valeurs par défaut", "Upload" : "Téléverser", "Remove background image" : "Retirer l'image d'arrière-plan", - "Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "L'accès universel est très important pour nous. Nous suivons les standards du web et nous vérifions que tout est utilisable même sans souris et sans logiciel d'assistance comme les lecteurs d'écran. Nous visons à respecter les {guidelines}Règles pour l'accessibilité des contenus Web{linkend} 2.1 de niveau AA et même de niveau AAA avec le thème à fort contraste." + "Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "L'accès universel est très important pour nous. Nous suivons les standards du web et nous vérifions que tout est utilisable même sans souris et sans logiciel d'assistance comme les lecteurs d'écran. Nous visons à respecter les {guidelines}Règles pour l'accessibilité des contenus Web{linkend} 2.1 de niveau AA et même de niveau AAA avec le thème à fort contraste.", + ". Unable to apply the setting." : ". Impossible d'appliquer le réglage." }, "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/theming/l10n/fr.json b/apps/theming/l10n/fr.json index 4902c6ab2f1..4212fb59560 100644 --- a/apps/theming/l10n/fr.json +++ b/apps/theming/l10n/fr.json @@ -74,6 +74,7 @@ "Advanced options" : "Options avancées", "Install the ImageMagick PHP extension with support for SVG images to automatically generate favicons based on the uploaded logo and color." : "Installez l'extension PHP ImageMagick qui prend en charge les images SVG pour générer automatiquement des favicons à partir du logo téléversé et de la couleur indiquée.", "If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Si vous rencontrez des problèmes, n'hésitez pas à les signaler sur {issuetracker}notre outil de suivi des problèmes{linkend}. Et si vous voulez vous impliquer, venez rejoindre {designteam}notre équipe de design{linkend} !", + "Unable to apply the setting." : "Impossible d'appliquer le réglage.", "Appearance and accessibility settings" : "Paramètres d’apparence et d’accessibilité", "Misc accessibility options" : "Diverses options d'accessibilité", "Enable blur background filter (may increase GPU load)" : "Activer le filtre flou de l'arrière-plan (peut augmenter la charge du GPU)", @@ -115,6 +116,7 @@ "Reset to default" : "Restaurer les valeurs par défaut", "Upload" : "Téléverser", "Remove background image" : "Retirer l'image d'arrière-plan", - "Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "L'accès universel est très important pour nous. Nous suivons les standards du web et nous vérifions que tout est utilisable même sans souris et sans logiciel d'assistance comme les lecteurs d'écran. Nous visons à respecter les {guidelines}Règles pour l'accessibilité des contenus Web{linkend} 2.1 de niveau AA et même de niveau AAA avec le thème à fort contraste." + "Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {guidelines}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "L'accès universel est très important pour nous. Nous suivons les standards du web et nous vérifions que tout est utilisable même sans souris et sans logiciel d'assistance comme les lecteurs d'écran. Nous visons à respecter les {guidelines}Règles pour l'accessibilité des contenus Web{linkend} 2.1 de niveau AA et même de niveau AAA avec le thème à fort contraste.", + ". Unable to apply the setting." : ". Impossible d'appliquer le réglage." },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/twofactor_backupcodes/l10n/lv.js b/apps/twofactor_backupcodes/l10n/lv.js index a967bacd30c..7c0eaf63c4b 100644 --- a/apps/twofactor_backupcodes/l10n/lv.js +++ b/apps/twofactor_backupcodes/l10n/lv.js @@ -1,7 +1,7 @@ OC.L10N.register( "twofactor_backupcodes", { - "You created two-factor backup codes for your account" : "Jūs izveidojāt divpakāpju dublējumu kodus savam kontam", + "You created two-factor backup codes for your account" : "Tu savam kontam izveidoji divpakāpju rezerves kopiju kodus", "Second-factor backup codes" : "Second-factor dublēšanas kodi", "Generate backup codes" : "Izveidot rezerves kodus", "Backup code" : "Dublēšanas kods", diff --git a/apps/twofactor_backupcodes/l10n/lv.json b/apps/twofactor_backupcodes/l10n/lv.json index 2ed41345eea..871dee78b2c 100644 --- a/apps/twofactor_backupcodes/l10n/lv.json +++ b/apps/twofactor_backupcodes/l10n/lv.json @@ -1,5 +1,5 @@ { "translations": { - "You created two-factor backup codes for your account" : "Jūs izveidojāt divpakāpju dublējumu kodus savam kontam", + "You created two-factor backup codes for your account" : "Tu savam kontam izveidoji divpakāpju rezerves kopiju kodus", "Second-factor backup codes" : "Second-factor dublēšanas kodi", "Generate backup codes" : "Izveidot rezerves kodus", "Backup code" : "Dublēšanas kods", diff --git a/apps/user_ldap/l10n/et_EE.js b/apps/user_ldap/l10n/et_EE.js index 6cec49027af..a024012d43d 100644 --- a/apps/user_ldap/l10n/et_EE.js +++ b/apps/user_ldap/l10n/et_EE.js @@ -10,14 +10,15 @@ OC.L10N.register( "No action specified" : "Tegevusi pole määratletud", "No configuration specified" : "Seadistust pole määratletud", "No data specified" : "Andmeid pole määratletud", + "Invalid data specified" : "Kirjeldatud on vigased andmed", "Could not set configuration %1$s to %2$s" : "Ei õnnestunud muuta „%1$s“ seadistuse väärtuseks „%2$s“", "Action does not exist" : "Toimingut pole olemas", "Renewing …" : "Värskendamine ...", - "Very weak password" : "Väga nõrk parool", - "Weak password" : "Nõrk parool", - "So-so password" : "Enam-vähem sobiv parool", - "Good password" : "Hea parool", - "Strong password" : "Väga hea parool", + "Very weak password" : "Väga nõrk salasõna", + "Weak password" : "Nõrk salasõna", + "So-so password" : "Enam-vähem sobiv salasõna", + "Good password" : "Hea salasõna", + "Strong password" : "Väga hea salasõna", "The Base DN appears to be wrong" : "Näib, et Base DN on vale", "Testing configuration…" : "Seadistuse testimine", "Configuration incorrect" : "Seadistus on vigane", @@ -47,10 +48,19 @@ OC.L10N.register( "Password change rejected. Hint: %s" : "Salasõna muutmine polnud võimalik. Selgitus: %s", "Mandatory field \"%s\" left empty" : "Kohustuslik väli „%s“ on jäänud tühjaks", "Login filter does not contain %s placeholder." : "Kasutajanimede filtris puudub kohatäitja „%s“", - "Please login with the new password" : "Palun logi uue parooliga sisse", - "Your password will expire tomorrow." : "Su parool aegub homme.", - "Your password will expire today." : "Su parool aegub täna.", - "_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Su parool aegub %n päeva jooksul.","Su parool aegub %n päeva jooksul."], + "Please login with the new password" : "Palun logi uue salasõnaga sisse", + "LDAP User backend" : "LPAD-i põhine tausteteenus kasutajate jaoks", + "Your password will expire tomorrow." : "Su salasõna aegub homme.", + "Your password will expire today." : "Su salasõna aegub täna.", + "_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Su salasõna aegub %n päeva jooksul.","Su salasõna aegub %n päeva jooksul."], + "LDAP/AD integration" : "LDAP/AD lõiming", + "LDAP Connection" : "LDAP ühendus", + "Invalid LDAP UUIDs" : "Vigased LDAP UUID-d", + "None found" : "Mitte midagi ei leidu", + "_%n group found_::_%n groups found_" : ["Leidus %n grupp","Leidus %n gruppi"], + "> 1000 groups found" : "Leidus üle 1000 grupi", + "> 1000 users found" : "Leidus üle 1000 kasutaja", + "_%n user found_::_%n users found_" : ["Leidus %n kasutaja","Leidus %n kasutajat"], "Could not find the desired feature" : "Ei suuda leida soovitud funktsioonaalsust", "Invalid Host" : "Vigane server", "Test Configuration" : "Testi seadistust", @@ -73,9 +83,9 @@ OC.L10N.register( "Port" : "Port", "Detect Port" : "Tuvasta port", "User DN" : "Kasutaja DN", - "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", - "Password" : "Parool", - "For anonymous access, leave DN and Password empty." : "Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja salasõna tühjaks.", + "Password" : "Salasõna", + "For anonymous access, leave DN and Password empty." : "Anonüümseks ligipääsuks jäta DN ja salasõna tühjaks.", "Save Credentials" : "Salvesta kasutajaandmed", "One Base DN per line" : "Üks baas-DN rea kohta", "You can specify Base DN for users and groups in the Advanced tab" : "Sa saad kasutajate ja gruppide baas DN-i määrata lisavalikute vahekaardilt", @@ -89,13 +99,13 @@ OC.L10N.register( "Saving" : "Salvestamine", "Back" : "Tagasi", "Continue" : "Jätka", - "Please renew your password." : "Palun uuenda oma parool.", + "Please renew your password." : "Palun uuenda oma salasõna.", "An internal error occurred." : "Tekkis sisemine tõrge.", "Please try again or contact your administrator." : "Proovi uuesti või võta ühendust administraatoriga.", - "Current password" : "Praegune parool", - "New password" : "Uus parool", - "Renew password" : "Uuenda parooli", - "Wrong password." : "Vale parool.", + "Current password" : "Praegune salasõna", + "New password" : "Uus salasõna", + "Renew password" : "Uuenda salasõna", + "Wrong password." : "Vale salasõna.", "Cancel" : "Loobu", "Server" : "Server", "Users" : "Kasutajad", diff --git a/apps/user_ldap/l10n/et_EE.json b/apps/user_ldap/l10n/et_EE.json index 52d283fdf5b..3d90e2d17ce 100644 --- a/apps/user_ldap/l10n/et_EE.json +++ b/apps/user_ldap/l10n/et_EE.json @@ -8,14 +8,15 @@ "No action specified" : "Tegevusi pole määratletud", "No configuration specified" : "Seadistust pole määratletud", "No data specified" : "Andmeid pole määratletud", + "Invalid data specified" : "Kirjeldatud on vigased andmed", "Could not set configuration %1$s to %2$s" : "Ei õnnestunud muuta „%1$s“ seadistuse väärtuseks „%2$s“", "Action does not exist" : "Toimingut pole olemas", "Renewing …" : "Värskendamine ...", - "Very weak password" : "Väga nõrk parool", - "Weak password" : "Nõrk parool", - "So-so password" : "Enam-vähem sobiv parool", - "Good password" : "Hea parool", - "Strong password" : "Väga hea parool", + "Very weak password" : "Väga nõrk salasõna", + "Weak password" : "Nõrk salasõna", + "So-so password" : "Enam-vähem sobiv salasõna", + "Good password" : "Hea salasõna", + "Strong password" : "Väga hea salasõna", "The Base DN appears to be wrong" : "Näib, et Base DN on vale", "Testing configuration…" : "Seadistuse testimine", "Configuration incorrect" : "Seadistus on vigane", @@ -45,10 +46,19 @@ "Password change rejected. Hint: %s" : "Salasõna muutmine polnud võimalik. Selgitus: %s", "Mandatory field \"%s\" left empty" : "Kohustuslik väli „%s“ on jäänud tühjaks", "Login filter does not contain %s placeholder." : "Kasutajanimede filtris puudub kohatäitja „%s“", - "Please login with the new password" : "Palun logi uue parooliga sisse", - "Your password will expire tomorrow." : "Su parool aegub homme.", - "Your password will expire today." : "Su parool aegub täna.", - "_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Su parool aegub %n päeva jooksul.","Su parool aegub %n päeva jooksul."], + "Please login with the new password" : "Palun logi uue salasõnaga sisse", + "LDAP User backend" : "LPAD-i põhine tausteteenus kasutajate jaoks", + "Your password will expire tomorrow." : "Su salasõna aegub homme.", + "Your password will expire today." : "Su salasõna aegub täna.", + "_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Su salasõna aegub %n päeva jooksul.","Su salasõna aegub %n päeva jooksul."], + "LDAP/AD integration" : "LDAP/AD lõiming", + "LDAP Connection" : "LDAP ühendus", + "Invalid LDAP UUIDs" : "Vigased LDAP UUID-d", + "None found" : "Mitte midagi ei leidu", + "_%n group found_::_%n groups found_" : ["Leidus %n grupp","Leidus %n gruppi"], + "> 1000 groups found" : "Leidus üle 1000 grupi", + "> 1000 users found" : "Leidus üle 1000 kasutaja", + "_%n user found_::_%n users found_" : ["Leidus %n kasutaja","Leidus %n kasutajat"], "Could not find the desired feature" : "Ei suuda leida soovitud funktsioonaalsust", "Invalid Host" : "Vigane server", "Test Configuration" : "Testi seadistust", @@ -71,9 +81,9 @@ "Port" : "Port", "Detect Port" : "Tuvasta port", "User DN" : "Kasutaja DN", - "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", - "Password" : "Parool", - "For anonymous access, leave DN and Password empty." : "Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", + "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." : "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja salasõna tühjaks.", + "Password" : "Salasõna", + "For anonymous access, leave DN and Password empty." : "Anonüümseks ligipääsuks jäta DN ja salasõna tühjaks.", "Save Credentials" : "Salvesta kasutajaandmed", "One Base DN per line" : "Üks baas-DN rea kohta", "You can specify Base DN for users and groups in the Advanced tab" : "Sa saad kasutajate ja gruppide baas DN-i määrata lisavalikute vahekaardilt", @@ -87,13 +97,13 @@ "Saving" : "Salvestamine", "Back" : "Tagasi", "Continue" : "Jätka", - "Please renew your password." : "Palun uuenda oma parool.", + "Please renew your password." : "Palun uuenda oma salasõna.", "An internal error occurred." : "Tekkis sisemine tõrge.", "Please try again or contact your administrator." : "Proovi uuesti või võta ühendust administraatoriga.", - "Current password" : "Praegune parool", - "New password" : "Uus parool", - "Renew password" : "Uuenda parooli", - "Wrong password." : "Vale parool.", + "Current password" : "Praegune salasõna", + "New password" : "Uus salasõna", + "Renew password" : "Uuenda salasõna", + "Wrong password." : "Vale salasõna.", "Cancel" : "Loobu", "Server" : "Server", "Users" : "Kasutajad", diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php index dba6e5480d5..86ce2aff854 100644 --- a/apps/user_ldap/tests/AccessTest.php +++ b/apps/user_ldap/tests/AccessTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -41,36 +43,25 @@ use Test\TestCase; * @package OCA\User_LDAP\Tests */ class AccessTest extends TestCase { - /** @var UserMapping|MockObject */ - protected $userMapper; - /** @var IManager|MockObject */ - protected $shareManager; - /** @var GroupMapping|MockObject */ - protected $groupMapper; - /** @var Connection|MockObject */ - private $connection; - /** @var LDAP|MockObject */ - private $ldap; - /** @var Manager|MockObject */ - private $userManager; - /** @var Helper|MockObject */ - private $helper; - /** @var IConfig|MockObject */ - private $config; - /** @var IUserManager|MockObject */ - private $ncUserManager; - + protected UserMapping&MockObject $userMapper; + protected IManager&MockObject $shareManager; + protected GroupMapping&MockObject $groupMapper; + private Connection&MockObject $connection; + private LDAP&MockObject $ldap; + private Manager&MockObject $userManager; + private Helper&MockObject $helper; + private IConfig&MockObject $config; + private IUserManager&MockObject $ncUserManager; private LoggerInterface&MockObject $logger; - private IAppConfig&MockObject $appConfig; - - /** @var IEventDispatcher|MockObject */ - private $dispatcher; + private IEventDispatcher&MockObject $dispatcher; private Access $access; protected function setUp(): void { - $this->connection = $this->createMock(Connection::class); $this->ldap = $this->createMock(LDAP::class); + $this->connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->ldap]) + ->getMock(); $this->userManager = $this->createMock(Manager::class); $this->helper = $this->createMock(Helper::class); $this->config = $this->createMock(IConfig::class); @@ -126,19 +117,19 @@ class AccessTest extends TestCase { public function testEscapeFilterPartValidChars(): void { $input = 'okay'; - $this->assertTrue($input === $this->access->escapeFilterPart($input)); + $this->assertSame($input, $this->access->escapeFilterPart($input)); } public function testEscapeFilterPartEscapeWildcard(): void { $input = '*'; $expected = '\\2a'; - $this->assertTrue($expected === $this->access->escapeFilterPart($input)); + $this->assertSame($expected, $this->access->escapeFilterPart($input)); } public function testEscapeFilterPartEscapeWildcard2(): void { $input = 'foo*bar'; $expected = 'foo\\2abar'; - $this->assertTrue($expected === $this->access->escapeFilterPart($input)); + $this->assertSame($expected, $this->access->escapeFilterPart($input)); } /** @@ -151,7 +142,7 @@ class AccessTest extends TestCase { $this->assertSame($sidExpected, $this->access->convertSID2Str($sidBinary)); } - public function convertSID2StrSuccessData() { + public static function convertSID2StrSuccessData(): array { return [ [ [ @@ -209,55 +200,53 @@ class AccessTest extends TestCase { $this->assertSame($expected, $this->access->getDomainDNFromDN($inputDN)); } - public function dnInputDataProvider() { - return [[ + public static function dnInputDataProvider(): array { + return [ [ - 'input' => 'foo=bar,bar=foo,dc=foobar', - 'interResult' => [ + 'foo=bar,bar=foo,dc=foobar', + [ 'count' => 3, 0 => 'foo=bar', 1 => 'bar=foo', 2 => 'dc=foobar' ], - 'expectedResult' => true + true ], [ - 'input' => 'foobarbarfoodcfoobar', - 'interResult' => false, - 'expectedResult' => false + 'foobarbarfoodcfoobar', + false, + false ] - ]]; + ]; } /** * @dataProvider dnInputDataProvider - * @param array $case */ - public function testStringResemblesDN($case): void { + public function testStringResemblesDN(string $input, array|bool $interResult, bool $expectedResult): void { [$lw, $con, $um, $helper] = $this->getConnectorAndLdapMock(); - /** @var IConfig|MockObject $config */ + /** @var IConfig&MockObject $config */ $config = $this->createMock(IConfig::class); $access = new Access($lw, $con, $um, $helper, $config, $this->ncUserManager, $this->logger, $this->appConfig, $this->dispatcher); $lw->expects($this->exactly(1)) ->method('explodeDN') - ->willReturnCallback(function ($dn) use ($case) { - if ($dn === $case['input']) { - return $case['interResult']; + ->willReturnCallback(function ($dn) use ($input, $interResult) { + if ($dn === $input) { + return $interResult; } return null; }); - $this->assertSame($case['expectedResult'], $access->stringResemblesDN($case['input'])); + $this->assertSame($expectedResult, $access->stringResemblesDN($input)); } /** * @dataProvider dnInputDataProvider - * @param $case */ - public function testStringResemblesDNLDAPmod($case): void { + public function testStringResemblesDNLDAPmod(string $input, array|bool $interResult, bool $expectedResult): void { [, $con, $um, $helper] = $this->getConnectorAndLdapMock(); - /** @var IConfig|MockObject $config */ + /** @var IConfig&MockObject $config */ $config = $this->createMock(IConfig::class); $lw = new LDAP(); $access = new Access($lw, $con, $um, $helper, $config, $this->ncUserManager, $this->logger, $this->appConfig, $this->dispatcher); @@ -266,7 +255,7 @@ class AccessTest extends TestCase { $this->markTestSkipped('LDAP Module not available'); } - $this->assertSame($case['expectedResult'], $access->stringResemblesDN($case['input'])); + $this->assertSame($expectedResult, $access->stringResemblesDN($input)); } public function testCacheUserHome(): void { @@ -290,7 +279,7 @@ class AccessTest extends TestCase { ->method('getAttributes') ->willReturn(['displayname' => ['bar', 'count' => 1]]); - /** @var UserMapping|MockObject $mapperMock */ + /** @var UserMapping&MockObject $mapperMock */ $mapperMock = $this->createMock(UserMapping::class); $mapperMock->expects($this->any()) ->method('getNameByDN') @@ -335,7 +324,7 @@ class AccessTest extends TestCase { } public function testBatchApplyUserAttributesSkipped(): void { - /** @var UserMapping|MockObject $mapperMock */ + /** @var UserMapping&MockObject $mapperMock */ $mapperMock = $this->createMock(UserMapping::class); $mapperMock->expects($this->any()) ->method('getNameByDN') @@ -376,7 +365,7 @@ class AccessTest extends TestCase { } public function testBatchApplyUserAttributesDontSkip(): void { - /** @var UserMapping|MockObject $mapperMock */ + /** @var UserMapping&MockObject $mapperMock */ $mapperMock = $this->createMock(UserMapping::class); $mapperMock->expects($this->any()) ->method('getNameByDN') @@ -416,7 +405,7 @@ class AccessTest extends TestCase { $this->access->batchApplyUserAttributes($data); } - public function dNAttributeProvider() { + public static function dNAttributeProvider(): array { // corresponds to Access::resemblesDN() return [ 'dn' => ['dn'], @@ -428,11 +417,10 @@ class AccessTest extends TestCase { /** * @dataProvider dNAttributeProvider - * @param $attribute */ - public function testSanitizeDN($attribute): void { + public function testSanitizeDN(string $attribute): void { [$lw, $con, $um, $helper] = $this->getConnectorAndLdapMock(); - /** @var IConfig|MockObject $config */ + /** @var IConfig&MockObject $config */ $config = $this->createMock(IConfig::class); $dnFromServer = 'cn=Mixed Cases,ou=Are Sufficient To,ou=Test,dc=example,dc=org'; @@ -628,7 +616,7 @@ class AccessTest extends TestCase { $this->userMapper->expects($this->exactly($fakeLdapEntries['count'])) ->method('getNameByDN') ->willReturnCallback(function ($fdn) { - $parts = ldap_explode_dn($fdn, false); + $parts = ldap_explode_dn($fdn, 0); return $parts[0]; }); @@ -676,7 +664,7 @@ class AccessTest extends TestCase { $this->assertSame('Another Good Team', $groups[1]['cn'][0]); } - public function intUsernameProvider() { + public static function intUsernameProvider(): array { return [ ['alice', 'alice'], ['b/ob', 'bob'], @@ -694,7 +682,7 @@ class AccessTest extends TestCase { ]; } - public function groupIDCandidateProvider() { + public static function groupIDCandidateProvider(): array { return [ ['alice', 'alice'], ['b/ob', 'b/ob'], @@ -713,11 +701,8 @@ class AccessTest extends TestCase { /** * @dataProvider intUsernameProvider - * - * @param $name - * @param $expected */ - public function testSanitizeUsername($name, $expected): void { + public function testSanitizeUsername(string $name, ?string $expected): void { if ($expected === null) { $this->expectException(\InvalidArgumentException::class); } @@ -752,7 +737,7 @@ class AccessTest extends TestCase { ->with('detta') ->willReturnOnConsecutiveCalls($offlineUserMock, $regularUserMock); - /** @var UserMapping|MockObject $mapperMock */ + /** @var UserMapping&MockObject $mapperMock */ $mapperMock = $this->createMock(UserMapping::class); $mapperMock->expects($this->any()) ->method('getNameByDN') diff --git a/apps/user_ldap/tests/ConfigurationTest.php b/apps/user_ldap/tests/ConfigurationTest.php index cced8334bf5..dd6bd020f7b 100644 --- a/apps/user_ldap/tests/ConfigurationTest.php +++ b/apps/user_ldap/tests/ConfigurationTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,15 +11,14 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\Configuration; class ConfigurationTest extends \Test\TestCase { - /** @var Configuration */ - protected $configuration; + protected Configuration $configuration; protected function setUp(): void { parent::setUp(); $this->configuration = new Configuration('t01', false); } - public function configurationDataProvider() { + public static function configurationDataProvider(): array { $inputWithDN = [ 'cn=someUsers,dc=example,dc=org', ' ', @@ -89,12 +89,12 @@ class ConfigurationTest extends \Test\TestCase { /** * @dataProvider configurationDataProvider */ - public function testSetValue($key, $input, $expected): void { + public function testSetValue(string $key, string|array $input, string|array $expected): void { $this->configuration->setConfiguration([$key => $input]); $this->assertSame($this->configuration->$key, $expected); } - public function avatarRuleValueProvider() { + public static function avatarRuleValueProvider(): array { return [ ['none', []], ['data:selfie', ['selfie']], @@ -108,7 +108,7 @@ class ConfigurationTest extends \Test\TestCase { /** * @dataProvider avatarRuleValueProvider */ - public function testGetAvatarAttributes($setting, $expected): void { + public function testGetAvatarAttributes(string $setting, array $expected): void { $this->configuration->setConfiguration(['ldapUserAvatarRule' => $setting]); $this->assertSame($expected, $this->configuration->getAvatarAttributes()); } @@ -116,7 +116,7 @@ class ConfigurationTest extends \Test\TestCase { /** * @dataProvider avatarRuleValueProvider */ - public function testResolveRule($setting, $expected): void { + public function testResolveRule(string $setting, array $expected): void { $this->configuration->setConfiguration(['ldapUserAvatarRule' => $setting]); // so far the only thing that can get resolved :) $this->assertSame($expected, $this->configuration->resolveRule('avatar')); diff --git a/apps/user_ldap/tests/ConnectionTest.php b/apps/user_ldap/tests/ConnectionTest.php index 9cb19891b3d..601611fcc2f 100644 --- a/apps/user_ldap/tests/ConnectionTest.php +++ b/apps/user_ldap/tests/ConnectionTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,6 +11,7 @@ namespace OCA\User_LDAP\Tests; use OC\ServerNotAvailableException; use OCA\User_LDAP\Connection; use OCA\User_LDAP\ILDAPWrapper; +use PHPUnit\Framework\MockObject\MockObject; /** * Class Test_Connection @@ -19,19 +21,16 @@ use OCA\User_LDAP\ILDAPWrapper; * @package OCA\User_LDAP\Tests */ class ConnectionTest extends \Test\TestCase { - /** @var ILDAPWrapper|\PHPUnit\Framework\MockObject\MockObject */ - protected $ldap; - - /** @var Connection */ - protected $connection; + protected ILDAPWrapper&MockObject $ldap; + protected Connection $connection; protected function setUp(): void { parent::setUp(); $this->ldap = $this->createMock(ILDAPWrapper::class); // we use a mock here to replace the cache mechanism, due to missing DI in LDAP backend. - $this->connection = $this->getMockBuilder('OCA\User_LDAP\Connection') - ->setMethods(['getFromCache', 'writeToCache']) + $this->connection = $this->getMockBuilder(Connection::class) + ->onlyMethods(['getFromCache', 'writeToCache']) ->setConstructorArgs([$this->ldap, '', null]) ->getMock(); diff --git a/apps/user_ldap/tests/GroupLDAPPluginTest.php b/apps/user_ldap/tests/GroupLDAPPluginTest.php index f67de32c2e9..9f4cff64d6b 100644 --- a/apps/user_ldap/tests/GroupLDAPPluginTest.php +++ b/apps/user_ldap/tests/GroupLDAPPluginTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -9,27 +11,23 @@ use OCA\User_LDAP\GroupPluginManager; use OCP\GroupInterface; class GroupLDAPPluginTest extends \Test\TestCase { - - /** - * @return GroupPluginManager - */ - private function getGroupPluginManager() { + private function getGroupPluginManager(): GroupPluginManager { return new GroupPluginManager(); } public function testImplementsActions(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions']) ->getMock(); $plugin->expects($this->any()) ->method('respondToActions') ->willReturn(GroupInterface::CREATE_GROUP); - $plugin2 = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions']) + $plugin2 = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions']) ->getMock(); $plugin2->expects($this->any()) @@ -47,8 +45,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testCreateGroup(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'createGroup']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'createGroup']) ->getMock(); $plugin->expects($this->any()) @@ -77,8 +75,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testDeleteGroup(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'deleteGroup']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'deleteGroup']) ->getMock(); $plugin->expects($this->any()) @@ -107,8 +105,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testAddToGroup(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'addToGroup']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'addToGroup']) ->getMock(); $plugin->expects($this->any()) @@ -138,8 +136,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testRemoveFromGroup(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'removeFromGroup']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'removeFromGroup']) ->getMock(); $plugin->expects($this->any()) @@ -169,8 +167,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testCountUsersInGroup(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'countUsersInGroup']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'countUsersInGroup']) ->getMock(); $plugin->expects($this->any()) @@ -200,8 +198,8 @@ class GroupLDAPPluginTest extends \Test\TestCase { public function testgetGroupDetails(): void { $pluginManager = $this->getGroupPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPGroupPluginDummy') - ->setMethods(['respondToActions', 'getGroupDetails']) + $plugin = $this->getMockBuilder(LDAPGroupPluginDummy::class) + ->onlyMethods(['respondToActions', 'getGroupDetails']) ->getMock(); $plugin->expects($this->any()) diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php index ad97d5024b1..d2634548f4f 100644 --- a/apps/user_ldap/tests/Group_LDAPTest.php +++ b/apps/user_ldap/tests/Group_LDAPTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -34,10 +35,10 @@ use Test\TestCase; * @package OCA\User_LDAP\Tests */ class Group_LDAPTest extends TestCase { - private MockObject|Access $access; - private MockObject|GroupPluginManager $pluginManager; - private MockObject|IConfig $config; - private MockObject|IUserManager $ncUserManager; + private Access&MockObject $access; + private GroupPluginManager&MockObject $pluginManager; + private IConfig&MockObject $config; + private IUserManager&MockObject $ncUserManager; private GroupLDAP $groupBackend; public function setUp(): void { @@ -96,30 +97,19 @@ class Group_LDAPTest extends TestCase { * @return MockObject|Access */ private function getAccessMock() { - static $conMethods; - static $accMethods; - - if (is_null($conMethods) || is_null($accMethods)) { - $conMethods = get_class_methods(Connection::class); - $accMethods = get_class_methods(Access::class); - } $lw = $this->createMock(ILDAPWrapper::class); - $connector = $this->getMockBuilder(Connection::class) - ->setMethods($conMethods) ->setConstructorArgs([$lw, '', null]) ->getMock(); $this->access = $this->createMock(Access::class); - $this->access->connection = $connector; - $this->access->userManager = $this->createMock(Manager::class); return $this->access; } - private function enableGroups() { + private function enableGroups(): void { $this->access->connection->expects($this->any()) ->method('__get') ->willReturnCallback(function ($name) { @@ -179,7 +169,7 @@ class Group_LDAPTest extends TestCase { public function testCountUsersWithPlugin(): void { /** @var GroupPluginManager|MockObject $pluginManager */ $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'countUsersInGroup']) + ->onlyMethods(['implementsActions', 'countUsersInGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -470,7 +460,7 @@ class Group_LDAPTest extends TestCase { $this->groupBackend->inGroup($uid, $gid); } - public function groupWithMembersProvider() { + public static function groupWithMembersProvider(): array { return [ [ 'someGroup', @@ -574,7 +564,7 @@ class Group_LDAPTest extends TestCase { $memberUids = []; $userRecords = []; foreach ($memberDNs as $dn) { - $memberUids[] = ldap_explode_dn($dn, false)[0]; + $memberUids[] = ldap_explode_dn($dn, 0)[0]; $userRecords[] = ['dn' => [$dn]]; } @@ -876,8 +866,8 @@ class Group_LDAPTest extends TestCase { $this->initBackend(); $returnedGroups = $this->groupBackend->getUserGroups('userX'); $this->assertCount(2, $returnedGroups); - $this->assertTrue(in_array('groupB', $returnedGroups)); - $this->assertTrue(in_array('groupF', $returnedGroups)); + $this->assertContains('groupB', $returnedGroups); + $this->assertContains('groupF', $returnedGroups); } /** @@ -903,8 +893,8 @@ class Group_LDAPTest extends TestCase { $this->initBackend(); $returnedGroups = $this->groupBackend->getUserGroups('userX'); $this->assertCount(2, $returnedGroups); - $this->assertTrue(in_array('groupB', $returnedGroups)); - $this->assertTrue(in_array('groupF', $returnedGroups)); + $this->assertContains('groupB', $returnedGroups); + $this->assertContains('groupF', $returnedGroups); } public function testGetUserGroupsUnrecognizedOfflineUser(): void { @@ -946,11 +936,11 @@ class Group_LDAPTest extends TestCase { $this->initBackend(); $returnedGroups = $this->groupBackend->getUserGroups('userX'); $this->assertCount(2, $returnedGroups); - $this->assertTrue(in_array('groupB', $returnedGroups)); - $this->assertTrue(in_array('groupF', $returnedGroups)); + $this->assertContains('groupB', $returnedGroups); + $this->assertContains('groupF', $returnedGroups); } - public function nestedGroupsProvider(): array { + public static function nestedGroupsProvider(): array { return [ [true], [false], @@ -1076,7 +1066,7 @@ class Group_LDAPTest extends TestCase { public function testCreateGroupWithPlugin(): void { $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'createGroup']) + ->onlyMethods(['implementsActions', 'createGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1090,7 +1080,7 @@ class Group_LDAPTest extends TestCase { ->willReturn('result'); $this->initBackend(); - $this->assertEquals($this->groupBackend->createGroup('gid'), true); + $this->assertTrue($this->groupBackend->createGroup('gid')); } @@ -1098,7 +1088,7 @@ class Group_LDAPTest extends TestCase { $this->expectException(\Exception::class); $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'createGroup']) + ->onlyMethods(['implementsActions', 'createGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1112,7 +1102,7 @@ class Group_LDAPTest extends TestCase { public function testDeleteGroupWithPlugin(): void { $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'deleteGroup']) + ->onlyMethods(['implementsActions', 'deleteGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1126,7 +1116,7 @@ class Group_LDAPTest extends TestCase { ->willReturn(true); $mapper = $this->getMockBuilder(GroupMapping::class) - ->setMethods(['unmap']) + ->onlyMethods(['unmap']) ->disableOriginalConstructor() ->getMock(); @@ -1143,7 +1133,7 @@ class Group_LDAPTest extends TestCase { $this->expectException(\Exception::class); $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'deleteGroup']) + ->onlyMethods(['implementsActions', 'deleteGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1157,7 +1147,7 @@ class Group_LDAPTest extends TestCase { public function testAddToGroupWithPlugin(): void { $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'addToGroup']) + ->onlyMethods(['implementsActions', 'addToGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1171,7 +1161,7 @@ class Group_LDAPTest extends TestCase { ->willReturn('result'); $this->initBackend(); - $this->assertEquals($this->groupBackend->addToGroup('uid', 'gid'), 'result'); + $this->assertEquals('result', $this->groupBackend->addToGroup('uid', 'gid')); } @@ -1179,7 +1169,7 @@ class Group_LDAPTest extends TestCase { $this->expectException(\Exception::class); $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'addToGroup']) + ->onlyMethods(['implementsActions', 'addToGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1193,7 +1183,7 @@ class Group_LDAPTest extends TestCase { public function testRemoveFromGroupWithPlugin(): void { $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'removeFromGroup']) + ->onlyMethods(['implementsActions', 'removeFromGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1207,7 +1197,7 @@ class Group_LDAPTest extends TestCase { ->willReturn('result'); $this->initBackend(); - $this->assertEquals($this->groupBackend->removeFromGroup('uid', 'gid'), 'result'); + $this->assertEquals('result', $this->groupBackend->removeFromGroup('uid', 'gid')); } @@ -1215,7 +1205,7 @@ class Group_LDAPTest extends TestCase { $this->expectException(\Exception::class); $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'removeFromGroup']) + ->onlyMethods(['implementsActions', 'removeFromGroup']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1230,7 +1220,7 @@ class Group_LDAPTest extends TestCase { public function testGetGroupDetailsWithPlugin(): void { /** @var GroupPluginManager|MockObject $pluginManager */ $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'getGroupDetails']) + ->onlyMethods(['implementsActions', 'getGroupDetails']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1244,14 +1234,14 @@ class Group_LDAPTest extends TestCase { ->willReturn('result'); $this->initBackend(); - $this->assertEquals($this->groupBackend->getGroupDetails('gid'), 'result'); + $this->assertEquals('result', $this->groupBackend->getGroupDetails('gid')); } public function testGetGroupDetailsFailing(): void { $this->expectException(\Exception::class); $this->pluginManager = $this->getMockBuilder(GroupPluginManager::class) - ->setMethods(['implementsActions', 'getGroupDetails']) + ->onlyMethods(['implementsActions', 'getGroupDetails']) ->getMock(); $this->pluginManager->expects($this->once()) @@ -1263,7 +1253,7 @@ class Group_LDAPTest extends TestCase { $this->groupBackend->getGroupDetails('gid'); } - public function groupMemberProvider() { + public static function groupMemberProvider(): array { $base = 'dc=species,dc=earth'; $birdsDn = [ @@ -1332,10 +1322,9 @@ class Group_LDAPTest extends TestCase { } /** - * @param string[] $expectedMembers * @dataProvider groupMemberProvider */ - public function testGroupMembers(array $expectedResult, ?array $groupsInfo = null): void { + public function testGroupMembers(array $expectedResult, array $groupsInfo): void { $this->access->expects($this->any()) ->method('readAttribute') ->willReturnCallback(function ($group) use ($groupsInfo) { @@ -1360,11 +1349,13 @@ class Group_LDAPTest extends TestCase { foreach ($expectedResult as $groupDN => $expectedMembers) { $resultingMembers = $this->invokePrivate($this->groupBackend, '_groupMembers', [$groupDN]); - $this->assertEqualsCanonicalizing($expectedMembers, $resultingMembers); + sort($expectedMembers); + sort($resultingMembers); + $this->assertEquals($expectedMembers, $resultingMembers); } } - public function displayNameProvider() { + public static function displayNameProvider(): array { return [ ['Graphic Novelists', ['Graphic Novelists']], ['', false], @@ -1374,7 +1365,7 @@ class Group_LDAPTest extends TestCase { /** * @dataProvider displayNameProvider */ - public function testGetDisplayName(string $expected, $ldapResult): void { + public function testGetDisplayName(string $expected, bool|array $ldapResult): void { $gid = 'graphic_novelists'; $this->access->expects($this->atLeastOnce()) diff --git a/apps/user_ldap/tests/HelperTest.php b/apps/user_ldap/tests/HelperTest.php index eee5c162b53..470b67c5531 100644 --- a/apps/user_ldap/tests/HelperTest.php +++ b/apps/user_ldap/tests/HelperTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -9,17 +11,15 @@ use OCA\User_LDAP\Helper; use OCP\IConfig; use OCP\IDBConnection; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; /** * @group DB */ class HelperTest extends \Test\TestCase { + private IConfig&MockObject $config; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - - /** @var Helper */ - private $helper; + private Helper $helper; protected function setUp(): void { parent::setUp(); diff --git a/apps/user_ldap/tests/Integration/Lib/IntegrationTestAttributeDetection.php b/apps/user_ldap/tests/Integration/Lib/IntegrationTestAttributeDetection.php index e45238fa978..ae1709edd22 100644 --- a/apps/user_ldap/tests/Integration/Lib/IntegrationTestAttributeDetection.php +++ b/apps/user_ldap/tests/Integration/Lib/IntegrationTestAttributeDetection.php @@ -3,7 +3,7 @@ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\user_ldap\tests\Integration\Lib; +namespace OCA\User_LDAP\Tests\Integration\Lib; use OCA\User_LDAP\Group_LDAP; use OCA\User_LDAP\GroupPluginManager; diff --git a/apps/user_ldap/tests/Jobs/CleanUpTest.php b/apps/user_ldap/tests/Jobs/CleanUpTest.php index 582b6fba5d7..cefc9cc86b5 100644 --- a/apps/user_ldap/tests/Jobs/CleanUpTest.php +++ b/apps/user_ldap/tests/Jobs/CleanUpTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,13 +19,11 @@ use OCP\IDBConnection; use Test\TestCase; class CleanUpTest extends TestCase { - /** @var CleanUp */ - protected $bgJob; - - /** @var array */ - protected $mocks; + protected CleanUp $bgJob; + protected array $mocks; public function setUp(): void { + parent::setUp(); $this->createMocks(); $this->bgJob = new CleanUp($this->mocks['timeFactory'], $this->mocks['userBackend'], $this->mocks['deletedUsersIndex']); $this->bgJob->setArguments($this->mocks); diff --git a/apps/user_ldap/tests/Jobs/SyncTest.php b/apps/user_ldap/tests/Jobs/SyncTest.php index 8277e7d48a9..20489ea0901 100644 --- a/apps/user_ldap/tests/Jobs/SyncTest.php +++ b/apps/user_ldap/tests/Jobs/SyncTest.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -26,32 +27,23 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; +/** + * @group DB + */ class SyncTest extends TestCase { - /** @var array */ - protected $arguments; - /** @var Helper|MockObject */ - protected $helper; - /** @var LDAP|MockObject */ - protected $ldapWrapper; - /** @var Manager|MockObject */ - protected $userManager; - /** @var UserMapping|MockObject */ - protected $mapper; + protected Helper&MockObject $helper; + protected LDAP&MockObject $ldapWrapper; + protected Manager&MockObject $userManager; + protected UserMapping&MockObject $mapper; + protected IConfig&MockObject $config; + protected IAvatarManager&MockObject $avatarManager; + protected IDBConnection&MockObject $dbc; + protected IUserManager&MockObject $ncUserManager; + protected IManager&MockObject $notificationManager; + protected ConnectionFactory&MockObject $connectionFactory; + protected AccessFactory&MockObject $accessFactory; + protected array $arguments = []; protected Sync $sync; - /** @var IConfig|MockObject */ - protected $config; - /** @var IAvatarManager|MockObject */ - protected $avatarManager; - /** @var IDBConnection|MockObject */ - protected $dbc; - /** @var IUserManager|MockObject */ - protected $ncUserManager; - /** @var IManager|MockObject */ - protected $notificationManager; - /** @var ConnectionFactory|MockObject */ - protected $connectionFactory; - /** @var AccessFactory|MockObject */ - protected $accessFactory; protected function setUp(): void { parent::setUp(); @@ -65,7 +57,11 @@ class SyncTest extends TestCase { $this->dbc = $this->createMock(IDBConnection::class); $this->ncUserManager = $this->createMock(IUserManager::class); $this->notificationManager = $this->createMock(IManager::class); - $this->connectionFactory = $this->createMock(ConnectionFactory::class); + $this->connectionFactory = $this->getMockBuilder(ConnectionFactory::class) + ->setConstructorArgs([ + $this->ldapWrapper, + ]) + ->getMock(); $this->accessFactory = $this->createMock(AccessFactory::class); $this->sync = new Sync( @@ -86,7 +82,7 @@ class SyncTest extends TestCase { $this->sync->overwritePropertiesForTest($this->ldapWrapper); } - public function intervalDataProvider(): array { + public static function intervalDataProvider(): array { return [ [ 0, 1000, 750 @@ -139,7 +135,7 @@ class SyncTest extends TestCase { $this->sync->updateInterval(); } - public function moreResultsProvider() { + public static function moreResultsProvider(): array { return [ [ 3, 3, true ], [ 3, 5, true ], @@ -153,7 +149,11 @@ class SyncTest extends TestCase { * @dataProvider moreResultsProvider */ public function testMoreResults($pagingSize, $results, $expected): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([ + $this->ldapWrapper, + ]) + ->getMock(); $this->connectionFactory->expects($this->any()) ->method('get') ->willReturn($connection); @@ -166,7 +166,7 @@ class SyncTest extends TestCase { return null; }); - /** @var Access|MockObject $access */ + /** @var Access&MockObject $access */ $access = $this->createMock(Access::class); $this->accessFactory->expects($this->any()) ->method('get') @@ -191,7 +191,7 @@ class SyncTest extends TestCase { $this->assertSame($expected, $hasMoreResults); } - public function cycleDataProvider() { + public static function cycleDataProvider(): array { $lastCycle = ['prefix' => 's01', 'offset' => 1000]; $lastCycle2 = ['prefix' => '', 'offset' => 1000]; return [ @@ -207,19 +207,23 @@ class SyncTest extends TestCase { /** * @dataProvider cycleDataProvider */ - public function testDetermineNextCycle($cycleData, $prefixes, $expectedCycle): void { + public function testDetermineNextCycle(?array $cycleData, array $prefixes, ?array $expectedCycle): void { $this->helper->expects($this->any()) ->method('getServerConfigurationPrefixes') ->with(true) ->willReturn($prefixes); if (is_array($expectedCycle)) { + $calls = [ + ['user_ldap', 'background_sync_prefix', $expectedCycle['prefix']], + ['user_ldap', 'background_sync_offset', $expectedCycle['offset']], + ]; $this->config->expects($this->exactly(2)) ->method('setAppValue') - ->withConsecutive( - ['user_ldap', 'background_sync_prefix', $expectedCycle['prefix']], - ['user_ldap', 'background_sync_offset', $expectedCycle['offset']] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); } else { $this->config->expects($this->never()) ->method('setAppValue'); @@ -248,7 +252,7 @@ class SyncTest extends TestCase { $this->assertFalse($this->sync->qualifiesToRun($cycleData)); } - public function runDataProvider(): array { + public static function runDataProvider(): array { return [ #0 - one LDAP server, reset [[ @@ -283,7 +287,7 @@ class SyncTest extends TestCase { /** * @dataProvider runDataProvider */ - public function testRun($runData): void { + public function testRun(array $runData): void { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback(function ($app, $key, $default) use ($runData) { @@ -310,13 +314,18 @@ class SyncTest extends TestCase { return $default; }); + + $calls = [ + ['user_ldap', 'background_sync_prefix', $runData['expectedNextCycle']['prefix']], + ['user_ldap', 'background_sync_offset', $runData['expectedNextCycle']['offset']], + ['user_ldap', 'background_sync_interval', '43200'], + ]; $this->config->expects($this->exactly(3)) ->method('setAppValue') - ->withConsecutive( - ['user_ldap', 'background_sync_prefix', $runData['expectedNextCycle']['prefix']], - ['user_ldap', 'background_sync_offset', $runData['expectedNextCycle']['offset']], - ['user_ldap', 'background_sync_interval', $this->anything()] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $this->config->expects($this->any()) ->method('getAppKeys') ->with('user_ldap') @@ -327,7 +336,11 @@ class SyncTest extends TestCase { ->with(true) ->willReturn($runData['prefixes']); - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([ + $this->ldapWrapper, + ]) + ->getMock(); $this->connectionFactory->expects($this->any()) ->method('get') ->willReturn($connection); @@ -340,7 +353,7 @@ class SyncTest extends TestCase { return null; }); - /** @var Access|MockObject $access */ + /** @var Access&MockObject $access */ $access = $this->createMock(Access::class); $this->accessFactory->expects($this->any()) ->method('get') diff --git a/apps/user_ldap/tests/LDAPGroupPluginDummy.php b/apps/user_ldap/tests/LDAPGroupPluginDummy.php index 0d47fbbd290..5ea1a491f14 100644 --- a/apps/user_ldap/tests/LDAPGroupPluginDummy.php +++ b/apps/user_ldap/tests/LDAPGroupPluginDummy.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/apps/user_ldap/tests/LDAPProviderTest.php b/apps/user_ldap/tests/LDAPProviderTest.php index 9b0830ae513..a4da4a91948 100644 --- a/apps/user_ldap/tests/LDAPProviderTest.php +++ b/apps/user_ldap/tests/LDAPProviderTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -12,6 +14,7 @@ use OCA\User_LDAP\Connection; use OCA\User_LDAP\Group_LDAP; use OCA\User_LDAP\Helper; use OCA\User_LDAP\IGroupLDAP; +use OCA\User_LDAP\ILDAPWrapper; use OCA\User_LDAP\IUserLDAP; use OCA\User_LDAP\LDAPProviderFactory; use OCA\User_LDAP\User_LDAP; @@ -31,13 +34,9 @@ use Psr\Log\LoggerInterface; * @package OCA\User_LDAP\Tests */ class LDAPProviderTest extends \Test\TestCase { - protected function setUp(): void { - parent::setUp(); - } - private function getServerMock(IUserLDAP $userBackend, IGroupLDAP $groupBackend) { $server = $this->getMockBuilder('OC\Server') - ->setMethods(['getUserManager', 'getBackends', 'getGroupManager']) + ->onlyMethods(['getUserManager', 'getGroupManager']) ->setConstructorArgs(['', new Config(\OC::$configDir)]) ->getMock(); $server->expects($this->any()) @@ -46,16 +45,13 @@ class LDAPProviderTest extends \Test\TestCase { $server->expects($this->any()) ->method('getGroupManager') ->willReturn($this->getGroupManagerMock($groupBackend)); - $server->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); return $server; } private function getUserManagerMock(IUserLDAP $userBackend) { $userManager = $this->getMockBuilder(Manager::class) - ->setMethods(['getBackends']) + ->onlyMethods(['getBackends']) ->setConstructorArgs([ $this->createMock(IConfig::class), $this->createMock(ICacheFactory::class), @@ -71,7 +67,7 @@ class LDAPProviderTest extends \Test\TestCase { private function getGroupManagerMock(IGroupLDAP $groupBackend) { $groupManager = $this->getMockBuilder('OC\Group\Manager') - ->setMethods(['getBackends']) + ->onlyMethods(['getBackends']) ->disableOriginalConstructor() ->getMock(); $groupManager->expects($this->any()) @@ -98,8 +94,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -110,20 +106,25 @@ class LDAPProviderTest extends \Test\TestCase { $ldapProvider->getUserDN('nonexisting_user'); } + public function testGetUserDN(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'username2dn']) + $userAccess = $this->getMockBuilder(Access::class) + ->onlyMethods(['username2dn']) + ->disableOriginalConstructor() + ->getMock(); + $userAccess->expects($this->once()) + ->method('username2dn') + ->willReturn('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'); + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->once()) ->method('userExists') ->willReturn(true); - $userBackend->expects($this->once()) - ->method('username2dn') - ->willReturn('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'); $userBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($userAccess); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -137,12 +138,9 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('Group id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() - ->getMock(); - - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists']) + $userBackend = $this->createMock(User_LDAP::class); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists']) ->disableOriginalConstructor() ->getMock(); @@ -155,25 +153,23 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetGroupDN(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'username2dn']) - ->disableOriginalConstructor() - ->getMock(); + $userBackend = $this->createMock(User_LDAP::class); - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists', 'getLDAPAccess', 'groupname2dn']) + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); + $groupAccess = $this->createMock(Access::class); + $groupAccess->expects($this->once()) + ->method('groupname2dn') + ->willReturn('cn=existing_group,ou=Are Sufficient To,ou=Test,dc=example,dc=org'); $groupBackend->expects($this->once()) ->method('groupExists') ->willReturn(true); - $groupBackend->expects($this->once()) - ->method('groupname2dn') - ->willReturn('cn=existing_group,ou=Are Sufficient To,ou=Test,dc=example,dc=org'); $groupBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($groupAccess); $server = $this->getServerMock($userBackend, $groupBackend); @@ -183,8 +179,8 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetUserName(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['dn2UserName']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['dn2UserName']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any()) @@ -199,10 +195,7 @@ class LDAPProviderTest extends \Test\TestCase { } public function testDNasBaseParameter(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); + $userBackend = $this->createMock(User_LDAP::class); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -215,10 +208,7 @@ class LDAPProviderTest extends \Test\TestCase { } public function testSanitizeDN(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); + $userBackend = $this->createMock(User_LDAP::class); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -235,10 +225,7 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) - ->disableOriginalConstructor() - ->getMock(); + $userBackend = $this->createMock(User_LDAP::class); $userBackend->expects($this->any())->method('userExists')->willReturn(false); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -248,8 +235,8 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetLDAPConnection(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getNewLDAPConnection']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getNewLDAPConnection']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any()) @@ -271,12 +258,9 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('Group id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() - ->getMock(); - - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists']) + $userBackend = $this->createMock(User_LDAP::class); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists']) ->disableOriginalConstructor() ->getMock(); @@ -289,12 +273,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetGroupLDAPConnection(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() - ->getMock(); - - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists','getNewLDAPConnection']) + $userBackend = $this->createMock(User_LDAP::class); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists','getNewLDAPConnection']) ->disableOriginalConstructor() ->getMock(); @@ -318,8 +299,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -337,7 +318,9 @@ class LDAPProviderTest extends \Test\TestCase { ]; $dn = 'uid=malik,' . $bases[1]; - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects($this->any()) ->method('__get') ->willReturnCallback(function ($key) use ($bases) { @@ -359,8 +342,8 @@ class LDAPProviderTest extends \Test\TestCase { ->method('username2dn') ->willReturn($dn); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->atLeastOnce()) @@ -381,8 +364,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -399,7 +382,9 @@ class LDAPProviderTest extends \Test\TestCase { 'ou=groups,ou=barfoo,dc=example,dc=org', ]; - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects($this->any()) ->method('__get') ->willReturnCallback(function ($key) use ($bases) { @@ -415,8 +400,8 @@ class LDAPProviderTest extends \Test\TestCase { ->method('getConnection') ->willReturn($connection); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any()) @@ -437,8 +422,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -450,19 +435,25 @@ class LDAPProviderTest extends \Test\TestCase { } public function testClearCache(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'clearCache']) + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); + $connection->expects($this->once()) + ->method('clearCache') + ->willReturn(true); + $access = $this->createMock(Access::class); + $access->method('getConnection') + ->willReturn($connection); + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->once()) ->method('userExists') ->willReturn(true); - $userBackend->expects($this->once()) - ->method('clearCache') - ->willReturn(true); $userBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($access); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -476,11 +467,11 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('Group id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') + $userBackend = $this->getMockBuilder(User_LDAP::class) ->disableOriginalConstructor() ->getMock(); - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists']) + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists']) ->disableOriginalConstructor() ->getMock(); $groupBackend->expects($this->any())->method('groupExists')->willReturn(false); @@ -492,22 +483,26 @@ class LDAPProviderTest extends \Test\TestCase { } public function testClearGroupCache(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() + $userBackend = $this->createMock(User_LDAP::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) ->getMock(); - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists', 'getLDAPAccess', 'getConnection', 'clearCache']) + $connection->expects($this->once()) + ->method('clearCache') + ->willReturn(true); + $access = $this->createMock(Access::class); + $access->method('getConnection') + ->willReturn($connection); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $groupBackend->expects($this->once()) ->method('groupExists') ->willReturn(true); - $groupBackend->expects($this->once()) - ->method('clearCache') - ->willReturn(true); $groupBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($access); $server = $this->getServerMock($userBackend, $groupBackend); @@ -517,8 +512,8 @@ class LDAPProviderTest extends \Test\TestCase { } public function testDnExists(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['dn2UserName']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['dn2UserName']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any()) @@ -532,11 +527,7 @@ class LDAPProviderTest extends \Test\TestCase { } public function testFlagRecord(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); - + $userBackend = $this->createMock(User_LDAP::class); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); $ldapProvider = $this->getLDAPProvider($server); @@ -545,11 +536,7 @@ class LDAPProviderTest extends \Test\TestCase { } public function testUnflagRecord(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); - + $userBackend = $this->createMock(User_LDAP::class); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); $ldapProvider = $this->getLDAPProvider($server); @@ -562,8 +549,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -575,19 +562,25 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetLDAPDisplayNameField(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration']) + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); + $connection->expects($this->once()) + ->method('getConfiguration') + ->willReturn(['ldap_display_name' => 'displayName']); + $access = $this->createMock(Access::class); + $access->method('getConnection') + ->willReturn($connection); + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->once()) ->method('userExists') ->willReturn(true); - $userBackend->expects($this->once()) - ->method('getConfiguration') - ->willReturn(['ldap_display_name' => 'displayName']); $userBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($access); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -600,8 +593,8 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('User id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists']) + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->any())->method('userExists')->willReturn(false); @@ -613,19 +606,25 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetLDAPEmailField(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration']) + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); + $connection->expects($this->once()) + ->method('getConfiguration') + ->willReturn(['ldap_email_attr' => 'mail']); + $access = $this->createMock(Access::class); + $access->method('getConnection') + ->willReturn($connection); + $userBackend = $this->getMockBuilder(User_LDAP::class) + ->onlyMethods(['userExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); $userBackend->expects($this->once()) ->method('userExists') ->willReturn(true); - $userBackend->expects($this->once()) - ->method('getConfiguration') - ->willReturn(['ldap_email_attr' => 'mail']); $userBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($access); $server = $this->getServerMock($userBackend, $this->getDefaultGroupBackendMock()); @@ -638,16 +637,15 @@ class LDAPProviderTest extends \Test\TestCase { $this->expectException(\Exception::class); $this->expectExceptionMessage('Group id not found in LDAP'); - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() - ->getMock(); - - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists']) + $userBackend = $this->createMock(User_LDAP::class); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists']) ->disableOriginalConstructor() ->getMock(); - $groupBackend->expects($this->any())->method('groupExists')->willReturn(false); + $groupBackend->expects($this->any()) + ->method('groupExists') + ->willReturn(false); $server = $this->getServerMock($userBackend, $groupBackend); @@ -656,12 +654,19 @@ class LDAPProviderTest extends \Test\TestCase { } public function testgetLDAPGroupMemberAssoc(): void { - $userBackend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP') - ->disableOriginalConstructor() - ->getMock(); + $userBackend = $this->createMock(User_LDAP::class); - $groupBackend = $this->getMockBuilder('OCA\User_LDAP\Group_LDAP') - ->setMethods(['groupExists', 'getLDAPAccess', 'getConnection', 'getConfiguration']) + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); + $connection->expects($this->once()) + ->method('getConfiguration') + ->willReturn(['ldap_group_member_assoc_attribute' => 'assoc_type']); + $access = $this->createMock(Access::class); + $access->method('getConnection') + ->willReturn($connection); + $groupBackend = $this->getMockBuilder(Group_LDAP::class) + ->onlyMethods(['groupExists', 'getLDAPAccess']) ->disableOriginalConstructor() ->getMock(); @@ -669,11 +674,8 @@ class LDAPProviderTest extends \Test\TestCase { ->method('groupExists') ->willReturn(true); $groupBackend->expects($this->any()) - ->method('getConfiguration') - ->willReturn(['ldap_group_member_assoc_attribute' => 'assoc_type']); - $groupBackend->expects($this->any()) - ->method($this->anything()) - ->willReturnSelf(); + ->method('getLDAPAccess') + ->willReturn($access); $server = $this->getServerMock($userBackend, $groupBackend); @@ -698,7 +700,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetMultiValueUserAttributeCacheHit(): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects(self::once()) ->method('getFromCache') ->with('admin-mailAlias') @@ -723,7 +727,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetMultiValueUserAttributeLdapError(): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects(self::once()) ->method('getFromCache') ->with('admin-mailAlias') @@ -760,7 +766,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetMultiValueUserAttribute(): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects(self::once()) ->method('getFromCache') ->with('admin-mailAlias') @@ -797,7 +805,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetUserAttributeLdapError(): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects(self::once()) ->method('getFromCache') ->with('admin-mailAlias') @@ -834,7 +844,9 @@ class LDAPProviderTest extends \Test\TestCase { } public function testGetUserAttribute(): void { - $connection = $this->createMock(Connection::class); + $connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $connection->expects(self::once()) ->method('getFromCache') ->with('admin-mailAlias') diff --git a/apps/user_ldap/tests/LDAPTest.php b/apps/user_ldap/tests/LDAPTest.php index a29751555cb..936a1a27d3d 100644 --- a/apps/user_ldap/tests/LDAPTest.php +++ b/apps/user_ldap/tests/LDAPTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,20 +8,20 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\LDAP; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class LDAPTest extends TestCase { - /** @var LDAP|\PHPUnit\Framework\MockObject\MockObject */ - private $ldap; + private LDAP&MockObject $ldap; protected function setUp(): void { parent::setUp(); $this->ldap = $this->getMockBuilder(LDAP::class) - ->setMethods(['invokeLDAPMethod']) + ->onlyMethods(['invokeLDAPMethod']) ->getMock(); } - public function errorProvider() { + public static function errorProvider(): array { return [ [ 'ldap_search(): Partial search results returned: Sizelimit exceeded at /srv/http/nextcloud/master/apps/user_ldap/lib/LDAP.php#292', @@ -32,8 +34,6 @@ class LDAPTest extends TestCase { } /** - * @param string $errorMessage - * @param bool $passThrough * @dataProvider errorProvider */ public function testSearchWithErrorHandler(string $errorMessage, bool $passThrough): void { diff --git a/apps/user_ldap/tests/LDAPUserPluginDummy.php b/apps/user_ldap/tests/LDAPUserPluginDummy.php index f6edf3df63b..8d4870406ae 100644 --- a/apps/user_ldap/tests/LDAPUserPluginDummy.php +++ b/apps/user_ldap/tests/LDAPUserPluginDummy.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -39,4 +41,12 @@ class LDAPUserPluginDummy implements ILDAPUserPlugin { public function countUsers() { return null; } + + public function canDeleteUser() { + return true; + } + + public function deleteUser($uid) { + return null; + } } diff --git a/apps/user_ldap/tests/Mapping/AbstractMappingTest.php b/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php index f1e9b1b67bc..8efee4e2085 100644 --- a/apps/user_ldap/tests/Mapping/AbstractMappingTest.php +++ b/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -11,7 +12,7 @@ use OCA\User_LDAP\Mapping\AbstractMapping; use OCP\IDBConnection; use OCP\Server; -abstract class AbstractMappingTest extends \Test\TestCase { +abstract class AbstractMappingTestCase extends \Test\TestCase { abstract public function getMapper(IDBConnection $dbMock); /** @@ -29,8 +30,8 @@ abstract class AbstractMappingTest extends \Test\TestCase { * returns an array of test entries with dn, name and uuid as keys * @return array */ - protected function getTestData() { - $data = [ + protected static function getTestData(): array { + return [ [ 'dn' => 'uid=foobar,dc=example,dc=org', 'name' => 'Foobar', @@ -47,8 +48,6 @@ abstract class AbstractMappingTest extends \Test\TestCase { 'uuid' => '3333-CCCC-1234-CDEF', ] ]; - - return $data; } /** @@ -56,7 +55,7 @@ abstract class AbstractMappingTest extends \Test\TestCase { * @param AbstractMapping $mapper * @param array $data */ - protected function mapEntries($mapper, $data) { + protected function mapEntries(AbstractMapping $mapper, array $data): void { foreach ($data as $entry) { $done = $mapper->map($entry['dn'], $entry['name'], $entry['uuid']); $this->assertTrue($done); @@ -70,7 +69,7 @@ abstract class AbstractMappingTest extends \Test\TestCase { * @return array 0 = \OCA\User_LDAP\Mapping\AbstractMapping, 1 = array of * users or groups */ - private function initTest() { + private function initTest(): array { $dbc = Server::get(IDBConnection::class); $mapper = $this->getMapper($dbc); $data = $this->getTestData(); @@ -157,13 +156,13 @@ abstract class AbstractMappingTest extends \Test\TestCase { [$mapper,] = $this->initTest(); $names = $mapper->getNamesBySearch('oo', '%', '%'); - $this->assertTrue(is_array($names)); + $this->assertIsArray($names); $this->assertSame(2, count($names)); - $this->assertTrue(in_array('Foobar', $names)); - $this->assertTrue(in_array('Barfoo', $names)); + $this->assertContains('Foobar', $names); + $this->assertContains('Barfoo', $names); $names = $mapper->getNamesBySearch('nada'); - $this->assertTrue(is_array($names)); - $this->assertSame(0, count($names)); + $this->assertIsArray($names); + $this->assertCount(0, $names); } /** @@ -250,20 +249,20 @@ abstract class AbstractMappingTest extends \Test\TestCase { // get all entries without specifying offset or limit $results = $mapper->getList(); - $this->assertSame(3, count($results)); + $this->assertCount(3, $results); // get all-1 entries by specifying offset, and an high limit // specifying only offset without limit will not work by underlying lib $results = $mapper->getList(1, 999); - $this->assertSame(count($data) - 1, count($results)); + $this->assertCount(count($data) - 1, $results); // get first 2 entries by limit, but not offset $results = $mapper->getList(0, 2); - $this->assertSame(2, count($results)); + $this->assertCount(2, $results); // get 2nd entry by specifying both offset and limit $results = $mapper->getList(1, 1); - $this->assertSame(1, count($results)); + $this->assertCount(1, $results); } public function testGetListOfIdsByDn(): void { @@ -282,6 +281,6 @@ abstract class AbstractMappingTest extends \Test\TestCase { } $result = $mapper->getListOfIdsByDn($listOfDNs); - $this->assertSame(66640 / 20, count($result)); + $this->assertCount(66640 / 20, $result); } } diff --git a/apps/user_ldap/tests/Mapping/GroupMappingTest.php b/apps/user_ldap/tests/Mapping/GroupMappingTest.php index efa42e47863..5729058d10e 100644 --- a/apps/user_ldap/tests/Mapping/GroupMappingTest.php +++ b/apps/user_ldap/tests/Mapping/GroupMappingTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -17,7 +18,7 @@ use OCP\IDBConnection; * * @package OCA\User_LDAP\Tests\Mapping */ -class GroupMappingTest extends AbstractMappingTest { +class GroupMappingTest extends AbstractMappingTestCase { public function getMapper(IDBConnection $dbMock) { return new GroupMapping($dbMock); } diff --git a/apps/user_ldap/tests/Mapping/UserMappingTest.php b/apps/user_ldap/tests/Mapping/UserMappingTest.php index 07980ba470c..4346fe1d23f 100644 --- a/apps/user_ldap/tests/Mapping/UserMappingTest.php +++ b/apps/user_ldap/tests/Mapping/UserMappingTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,7 +19,7 @@ use OCP\Support\Subscription\IAssertion; * * @package OCA\User_LDAP\Tests\Mapping */ -class UserMappingTest extends AbstractMappingTest { +class UserMappingTest extends AbstractMappingTestCase { public function getMapper(IDBConnection $dbMock) { return new UserMapping($dbMock, $this->createMock(IAssertion::class)); } diff --git a/apps/user_ldap/tests/Migration/AbstractUUIDFixTest.php b/apps/user_ldap/tests/Migration/AbstractUUIDFixTestCase.php index f8abcaeb482..7a85b885bc1 100644 --- a/apps/user_ldap/tests/Migration/AbstractUUIDFixTest.php +++ b/apps/user_ldap/tests/Migration/AbstractUUIDFixTestCase.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -13,17 +15,18 @@ use OCA\User_LDAP\Migration\UUIDFix; use OCA\User_LDAP\Proxy; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; -abstract class AbstractUUIDFixTest extends TestCase { - protected Helper $helper; - protected IConfig $config; - protected LDAP $ldap; +abstract class AbstractUUIDFixTestCase extends TestCase { + protected Helper&MockObject $helper; + protected IConfig&MockObject $config; + protected LDAP&MockObject $ldap; protected AbstractMapping $mapper; protected UUIDFix $job; protected Proxy $proxy; - protected Access $access; - protected ITimeFactory $time; + protected Access&MockObject $access; + protected ITimeFactory&MockObject $time; protected bool $isUser = true; protected function setUp(): void { @@ -141,19 +144,23 @@ abstract class AbstractUUIDFixTest extends TestCase { $this->access->expects($this->exactly(3)) ->method('getUUID') - ->withConsecutive( - [$args['records'][0]['dn'], $this->isUser], - [$args['records'][1]['dn'], $this->isUser], - [$args['records'][2]['dn'], $this->isUser] - ) - ->willReturnOnConsecutiveCalls($correctUUIDs[0], $correctUUIDs[1], $correctUUIDs[2]); - + ->willReturnMap([ + [$args['records'][0]['dn'], $this->isUser, null, $correctUUIDs[0]], + [$args['records'][1]['dn'], $this->isUser, null, $correctUUIDs[1]], + [$args['records'][2]['dn'], $this->isUser, null, $correctUUIDs[2]], + ]); + + $calls = [ + [$correctUUIDs[0], $args['records'][0]['dn']], + [$correctUUIDs[2], $args['records'][2]['dn']], + ]; $this->mapper->expects($this->exactly(2)) ->method('setUUIDbyDN') - ->withConsecutive( - [$correctUUIDs[0], $args['records'][0]['dn']], - [$correctUUIDs[2], $args['records'][2]['dn']] - ); + ->willReturnCallback(function ($i, $j) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return true; + }); $this->job->run($args); } diff --git a/apps/user_ldap/tests/Migration/UUIDFixGroupTest.php b/apps/user_ldap/tests/Migration/UUIDFixGroupTest.php index ab8fe03d6d2..89d880f4acb 100644 --- a/apps/user_ldap/tests/Migration/UUIDFixGroupTest.php +++ b/apps/user_ldap/tests/Migration/UUIDFixGroupTest.php @@ -1,14 +1,15 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Group_LDAP\Tests\Migration; +namespace OCA\User_LDAP\Tests\Migration; use OCA\User_LDAP\Group_Proxy; use OCA\User_LDAP\Mapping\GroupMapping; use OCA\User_LDAP\Migration\UUIDFixGroup; -use OCA\User_LDAP\Tests\Migration\AbstractUUIDFixTest; /** * Class UUIDFixGroupTest @@ -16,7 +17,7 @@ use OCA\User_LDAP\Tests\Migration\AbstractUUIDFixTest; * @package OCA\Group_LDAP\Tests\Migration * @group DB */ -class UUIDFixGroupTest extends AbstractUUIDFixTest { +class UUIDFixGroupTest extends AbstractUUIDFixTestCase { protected function setUp(): void { $this->isUser = false; parent::setUp(); diff --git a/apps/user_ldap/tests/Migration/UUIDFixInsertTest.php b/apps/user_ldap/tests/Migration/UUIDFixInsertTest.php index f31da43c584..0fc601c7d2e 100644 --- a/apps/user_ldap/tests/Migration/UUIDFixInsertTest.php +++ b/apps/user_ldap/tests/Migration/UUIDFixInsertTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -11,23 +13,15 @@ use OCA\User_LDAP\Migration\UUIDFixInsert; use OCP\BackgroundJob\IJobList; use OCP\IConfig; use OCP\Migration\IOutput; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class UUIDFixInsertTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - - /** @var UserMapping|\PHPUnit\Framework\MockObject\MockObject */ - protected $userMapper; - - /** @var GroupMapping|\PHPUnit\Framework\MockObject\MockObject */ - protected $groupMapper; - - /** @var IJobList|\PHPUnit\Framework\MockObject\MockObject */ - protected $jobList; - - /** @var UUIDFixInsert */ - protected $job; + protected IConfig&MockObject $config; + protected UserMapping&MockObject $userMapper; + protected GroupMapping&MockObject $groupMapper; + protected IJobList&MockObject $jobList; + protected UUIDFixInsert $job; protected function setUp(): void { parent::setUp(); @@ -48,13 +42,12 @@ class UUIDFixInsertTest extends TestCase { $this->assertSame('Insert UUIDFix background job for user and group in batches', $this->job->getName()); } - public function recordProvider() { + public static function recordProvider(): array { $record = [ 'dn' => 'cn=somerecord,dc=somewhere', 'name' => 'Something', 'uuid' => 'AB12-3456-CDEF7-8GH9' ]; - array_fill(0, 50, $record); $userBatches = [ 0 => array_fill(0, 50, $record), @@ -71,13 +64,12 @@ class UUIDFixInsertTest extends TestCase { ]; } - public function recordProviderTooLongAndNone() { + public static function recordProviderTooLongAndNone(): array { $record = [ 'dn' => 'cn=somerecord,dc=somewhere', 'name' => 'Something', 'uuid' => 'AB12-3456-CDEF7-8GH9' ]; - array_fill(0, 50, $record); $userBatches = [ 0 => array_fill(0, 50, $record), @@ -97,7 +89,7 @@ class UUIDFixInsertTest extends TestCase { /** * @dataProvider recordProvider */ - public function testRun($userBatches, $groupBatches): void { + public function testRun(array $userBatches, array $groupBatches): void { $this->config->expects($this->once()) ->method('getAppValue') ->with('user_ldap', 'installed_version', '1.2.1') @@ -105,8 +97,11 @@ class UUIDFixInsertTest extends TestCase { $this->userMapper->expects($this->exactly(3)) ->method('getList') - ->withConsecutive([0, 50], [50, 50], [100, 50]) - ->willReturnOnConsecutiveCalls($userBatches[0], $userBatches[1], $userBatches[2]); + ->willReturnMap([ + [0, 50, false, $userBatches[0]], + [50, 50, false, $userBatches[1]], + [100, 50, false, $userBatches[2]], + ]); $this->groupMapper->expects($this->exactly(1)) ->method('getList') @@ -124,7 +119,7 @@ class UUIDFixInsertTest extends TestCase { /** * @dataProvider recordProviderTooLongAndNone */ - public function testRunWithManyAndNone($userBatches, $groupBatches): void { + public function testRunWithManyAndNone(array $userBatches, array $groupBatches): void { $this->config->expects($this->once()) ->method('getAppValue') ->with('user_ldap', 'installed_version', '1.2.1') @@ -132,8 +127,13 @@ class UUIDFixInsertTest extends TestCase { $this->userMapper->expects($this->exactly(5)) ->method('getList') - ->withConsecutive([0, 50], [0, 40], [0, 32], [32, 32], [64, 32]) - ->willReturnOnConsecutiveCalls($userBatches[0], $userBatches[1], $userBatches[2], $userBatches[3], $userBatches[4]); + ->willReturnMap([ + [0, 50, false, $userBatches[0]], + [0, 40, false, $userBatches[1]], + [0, 32, false, $userBatches[2]], + [32, 32, false, $userBatches[3]], + [64, 32, false, $userBatches[4]], + ]); $this->groupMapper->expects($this->once()) ->method('getList') diff --git a/apps/user_ldap/tests/Migration/UUIDFixUserTest.php b/apps/user_ldap/tests/Migration/UUIDFixUserTest.php index dfa1898450f..a582fd677fa 100644 --- a/apps/user_ldap/tests/Migration/UUIDFixUserTest.php +++ b/apps/user_ldap/tests/Migration/UUIDFixUserTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -15,7 +17,7 @@ use OCA\User_LDAP\User_Proxy; * @package OCA\User_LDAP\Tests\Migration * @group DB */ -class UUIDFixUserTest extends AbstractUUIDFixTest { +class UUIDFixUserTest extends AbstractUUIDFixTestCase { protected function setUp(): void { $this->isUser = true; parent::setUp(); diff --git a/apps/user_ldap/tests/Service/BirthdateParserServiceTest.php b/apps/user_ldap/tests/Service/BirthdateParserServiceTest.php index 79450d6913e..85d6a6ba5f7 100644 --- a/apps/user_ldap/tests/Service/BirthdateParserServiceTest.php +++ b/apps/user_ldap/tests/Service/BirthdateParserServiceTest.php @@ -1,11 +1,12 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\user_ldap\tests\Service; +namespace OCA\User_LDAP\Tests\Service; use DateTimeImmutable; use OCA\User_LDAP\Service\BirthdateParserService; @@ -20,7 +21,7 @@ class BirthdateParserServiceTest extends TestCase { $this->service = new BirthdateParserService(); } - public function parseBirthdateDataProvider(): array { + public static function parseBirthdateDataProvider(): array { return [ ['2024-01-01', new DateTimeImmutable('2024-01-01'), false], ['20240101', new DateTimeImmutable('2024-01-01'), false], diff --git a/apps/user_ldap/tests/Service/UpdateGroupsServiceTest.php b/apps/user_ldap/tests/Service/UpdateGroupsServiceTest.php index 84aefb484bb..601aee86602 100644 --- a/apps/user_ldap/tests/Service/UpdateGroupsServiceTest.php +++ b/apps/user_ldap/tests/Service/UpdateGroupsServiceTest.php @@ -6,17 +6,15 @@ declare(strict_types=1); * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\user_ldap\tests\Service; +namespace OCA\User_LDAP\Tests\Service; use OCA\User_LDAP\Db\GroupMembership; use OCA\User_LDAP\Db\GroupMembershipMapper; use OCA\User_LDAP\Group_Proxy; use OCA\User_LDAP\Service\UpdateGroupsService; -use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; use OCP\Group\Events\UserAddedEvent; use OCP\Group\Events\UserRemovedEvent; -use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; @@ -26,23 +24,12 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class UpdateGroupsServiceTest extends TestCase { - /** @var Group_Proxy|MockObject */ - protected $groupBackend; - /** @var IEventDispatcher|MockObject */ - protected $dispatcher; - /** @var IGroupManager|MockObject */ - protected $groupManager; - /** @var IUserManager|MockObject */ - protected $userManager; - /** @var LoggerInterface|MockObject */ - protected $logger; - /** @var GroupMembershipMapper|MockObject */ - protected $groupMembershipMapper; - /** @var IConfig|MockObject */ - protected $config; - /** @var ITimeFactory|MockObject */ - protected $timeFactory; - + protected Group_Proxy&MockObject $groupBackend; + protected IEventDispatcher&MockObject $dispatcher; + protected IGroupManager&MockObject $groupManager; + protected IUserManager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected GroupMembershipMapper&MockObject $groupMembershipMapper; protected UpdateGroupsService $updateGroupsService; public function setUp(): void { @@ -52,8 +39,6 @@ class UpdateGroupsServiceTest extends TestCase { $this->userManager = $this->createMock(IUserManager::class); $this->logger = $this->createMock(LoggerInterface::class); $this->groupMembershipMapper = $this->createMock(GroupMembershipMapper::class); - $this->config = $this->createMock(IConfig::class); - $this->timeFactory = $this->createMock(ITimeFactory::class); $this->updateGroupsService = new UpdateGroupsService( $this->groupBackend, @@ -62,8 +47,6 @@ class UpdateGroupsServiceTest extends TestCase { $this->userManager, $this->logger, $this->groupMembershipMapper, - $this->config, - $this->timeFactory ); } diff --git a/apps/user_ldap/tests/Settings/AdminTest.php b/apps/user_ldap/tests/Settings/AdminTest.php index 05b9697e4c8..b17e96c1a68 100644 --- a/apps/user_ldap/tests/Settings/AdminTest.php +++ b/apps/user_ldap/tests/Settings/AdminTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -20,13 +22,12 @@ use Test\TestCase; */ class AdminTest extends TestCase { private IL10N&MockObject $l10n; - private ITemplateManager $templateManager; private Admin $admin; protected function setUp(): void { parent::setUp(); - $this->l10n = $this->getMockBuilder(IL10N::class)->getMock(); + $this->l10n = $this->createMock(IL10N::class); $this->templateManager = Server::get(ITemplateManager::class); $this->admin = new Admin( @@ -35,9 +36,6 @@ class AdminTest extends TestCase { ); } - /** - * @UseDB - */ public function testGetForm(): void { $prefixes = ['s01']; $hosts = ['s01' => '']; diff --git a/apps/user_ldap/tests/Settings/SectionTest.php b/apps/user_ldap/tests/Settings/SectionTest.php index 722581713d1..3f9ae1e56d4 100644 --- a/apps/user_ldap/tests/Settings/SectionTest.php +++ b/apps/user_ldap/tests/Settings/SectionTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -8,15 +10,13 @@ namespace OCA\User_LDAP\Tests\Settings; use OCA\User_LDAP\Settings\Section; use OCP\IL10N; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class SectionTest extends TestCase { - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - private $url; - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l; - /** @var Section */ - private $section; + private IURLGenerator&MockObject $url; + private IL10N&MockObject $l; + private Section $section; protected function setUp(): void { parent::setUp(); diff --git a/apps/user_ldap/tests/User/DeletedUsersIndexTest.php b/apps/user_ldap/tests/User/DeletedUsersIndexTest.php index 64e443a064f..b245e52fe6e 100644 --- a/apps/user_ldap/tests/User/DeletedUsersIndexTest.php +++ b/apps/user_ldap/tests/User/DeletedUsersIndexTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -11,6 +13,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\Server; use OCP\Share\IManager; +use PHPUnit\Framework\MockObject\MockObject; /** * Class DeletedUsersIndexTest @@ -20,19 +23,11 @@ use OCP\Share\IManager; * @package OCA\User_LDAP\Tests\User */ class DeletedUsersIndexTest extends \Test\TestCase { - /** @var DeletedUsersIndex */ - protected $dui; - - /** @var IConfig */ - protected $config; - - /** @var IDBConnection */ - protected $db; - - /** @var UserMapping|\PHPUnit\Framework\MockObject\MockObject */ - protected $mapping; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $shareManager; + protected DeletedUsersIndex $dui; + protected IConfig $config; + protected IDBConnection $db; + protected UserMapping&MockObject $mapping; + protected IManager&MockObject $shareManager; protected function setUp(): void { parent::setUp(); diff --git a/apps/user_ldap/tests/User/ManagerTest.php b/apps/user_ldap/tests/User/ManagerTest.php index 4f504ff5f7a..3f8b3aa174f 100644 --- a/apps/user_ldap/tests/User/ManagerTest.php +++ b/apps/user_ldap/tests/User/ManagerTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -19,6 +20,7 @@ use OCP\Image; use OCP\IUserManager; use OCP\Notification\IManager as INotificationManager; use OCP\Share\IManager; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; /** @@ -29,40 +31,18 @@ use Psr\Log\LoggerInterface; * @package OCA\User_LDAP\Tests\User */ class ManagerTest extends \Test\TestCase { - /** @var Access|\PHPUnit\Framework\MockObject\MockObject */ - protected $access; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - - /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $avatarManager; - - /** @var Image|\PHPUnit\Framework\MockObject\MockObject */ - protected $image; - - /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ - protected $dbc; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $ncUserManager; - - /** @var INotificationManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $notificationManager; - - /** @var ILDAPWrapper|\PHPUnit\Framework\MockObject\MockObject */ - protected $ldapWrapper; - - /** @var Connection */ - protected $connection; - - /** @var Manager */ - protected $manager; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $shareManager; + protected Access&MockObject $access; + protected IConfig&MockObject $config; + protected LoggerInterface&MockObject $logger; + protected IAvatarManager&MockObject $avatarManager; + protected Image&MockObject $image; + protected IDBConnection&MockObject $dbc; + protected IUserManager&MockObject $ncUserManager; + protected INotificationManager&MockObject $notificationManager; + protected ILDAPWrapper&MockObject $ldapWrapper; + protected Connection $connection; + protected IManager&MockObject $shareManager; + protected Manager $manager; protected function setUp(): void { parent::setUp(); @@ -97,7 +77,7 @@ class ManagerTest extends \Test\TestCase { $this->manager->setLdapAccess($this->access); } - public function dnProvider() { + public static function dnProvider(): array { return [ ['cn=foo,dc=foobar,dc=bar'], ['uid=foo,o=foobar,c=bar'], @@ -197,7 +177,7 @@ class ManagerTest extends \Test\TestCase { $this->assertNull($user); } - public function attributeRequestProvider() { + public static function attributeRequestProvider(): array { return [ [false], [true], @@ -217,10 +197,10 @@ class ManagerTest extends \Test\TestCase { $attributes = $this->manager->getAttributes($minimal); - $this->assertTrue(in_array('dn', $attributes)); - $this->assertTrue(in_array(strtolower($this->access->getConnection()->ldapEmailAttribute), $attributes)); - $this->assertTrue(!in_array($this->access->getConnection()->ldapEmailAttribute, $attributes)); #cases check - $this->assertFalse(in_array('', $attributes)); + $this->assertContains('dn', $attributes); + $this->assertContains(strtolower($this->access->getConnection()->ldapEmailAttribute), $attributes); + $this->assertNotContains($this->access->getConnection()->ldapEmailAttribute, $attributes); #cases check + $this->assertNotContains('', $attributes); $this->assertSame(!$minimal, in_array('jpegphoto', $attributes)); $this->assertSame(!$minimal, in_array('thumbnailphoto', $attributes)); $valueCounts = array_count_values($attributes); diff --git a/apps/user_ldap/tests/User/OfflineUserTest.php b/apps/user_ldap/tests/User/OfflineUserTest.php index e53bfca7f47..5ef89303111 100644 --- a/apps/user_ldap/tests/User/OfflineUserTest.php +++ b/apps/user_ldap/tests/User/OfflineUserTest.php @@ -13,20 +13,15 @@ use OCA\User_LDAP\User\OfflineUser; use OCP\IConfig; use OCP\Share\IManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class OfflineUserTest extends TestCase { - - /** @var OfflineUser */ - protected $offlineUser; - /** @var UserMapping|\PHPUnit\Framework\MockObject\MockObject */ - protected $mapping; - /** @var string */ - protected $uid; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $shareManager; + protected UserMapping&MockObject $mapping; + protected string $uid; + protected IConfig&MockObject $config; + protected IManager&MockObject $shareManager; + protected OfflineUser $offlineUser; public function setUp(): void { $this->uid = 'deborah'; @@ -42,7 +37,7 @@ class OfflineUserTest extends TestCase { ); } - public function shareOwnerProvider(): array { + public static function shareOwnerProvider(): array { return [ [[], false], [[IShare::TYPE_USER], true], diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php index badbca7f476..d9075af1569 100644 --- a/apps/user_ldap/tests/User/UserTest.php +++ b/apps/user_ldap/tests/User/UserTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -9,6 +10,7 @@ namespace OCA\User_LDAP\Tests\User; use OCA\User_LDAP\Access; use OCA\User_LDAP\Connection; +use OCA\User_LDAP\ILDAPWrapper; use OCA\User_LDAP\User\User; use OCP\IAvatar; use OCP\IAvatarManager; @@ -19,6 +21,7 @@ use OCP\IUserManager; use OCP\Notification\IManager as INotificationManager; use OCP\Notification\INotification; use OCP\Util; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; /** @@ -29,33 +32,24 @@ use Psr\Log\LoggerInterface; * @package OCA\User_LDAP\Tests\User */ class UserTest extends \Test\TestCase { - /** @var Access|\PHPUnit\Framework\MockObject\MockObject */ - protected $access; - /** @var Connection|\PHPUnit\Framework\MockObject\MockObject */ - protected $connection; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - /** @var INotificationManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $notificationManager; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var Image|\PHPUnit\Framework\MockObject\MockObject */ - protected $image; - /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $avatarManager; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - /** @var string */ - protected $uid = 'alice'; - /** @var string */ - protected $dn = 'uid=alice,dc=foo,dc=bar'; - /** @var User */ - protected $user; + protected Access&MockObject $access; + protected Connection&MockObject $connection; + protected IConfig&MockObject $config; + protected INotificationManager&MockObject $notificationManager; + protected IUserManager&MockObject $userManager; + protected Image&MockObject $image; + protected IAvatarManager&MockObject $avatarManager; + protected LoggerInterface&MockObject $logger; + protected string $uid = 'alice'; + protected string $dn = 'uid=alice,dc=foo,dc=bar'; + protected User $user; protected function setUp(): void { parent::setUp(); - $this->connection = $this->createMock(Connection::class); + $this->connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $this->access = $this->createMock(Access::class); $this->access->connection = $this->connection; @@ -100,9 +94,7 @@ class UserTest extends \Test\TestCase { $this->equalTo('email')) ->willReturn(['alice@foo.bar']); - $coreUser = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); + $coreUser = $this->createMock(IUser::class); $coreUser->expects($this->once()) ->method('setSystemEMailAddress') ->with('alice@foo.bar'); @@ -506,7 +498,7 @@ class UserTest extends \Test\TestCase { $avatar = $this->createMock(IAvatar::class); $avatar->expects($this->once()) ->method('set') - ->with($this->isInstanceOf($this->image)); + ->with($this->image); $this->avatarManager->expects($this->once()) ->method('getAvatar') @@ -617,7 +609,7 @@ class UserTest extends \Test\TestCase { $avatar = $this->createMock(IAvatar::class); $avatar->expects($this->once()) ->method('set') - ->with($this->isInstanceOf($this->image)); + ->with($this->image); $this->avatarManager->expects($this->once()) ->method('getAvatar') @@ -723,7 +715,7 @@ class UserTest extends \Test\TestCase { $avatar = $this->createMock(IAvatar::class); $avatar->expects($this->once()) ->method('set') - ->with($this->isInstanceOf($this->image)) + ->with($this->image) ->willThrowException(new \Exception()); $this->avatarManager->expects($this->once()) @@ -780,7 +772,7 @@ class UserTest extends \Test\TestCase { $this->user->updateAvatar(); } - public function extStorageHomeDataProvider() { + public static function extStorageHomeDataProvider(): array { return [ [ 'myFolder', null ], [ '', null, false ], @@ -865,7 +857,7 @@ class UserTest extends \Test\TestCase { $this->assertFalse($this->user->getAvatarImage()); } - public function imageDataProvider() { + public static function imageDataProvider(): array { return [ [ false, false ], [ 'corruptData', false ], @@ -884,7 +876,7 @@ class UserTest extends \Test\TestCase { 'updateExtStorageHome', ]; - /** @var User|\PHPUnit\Framework\MockObject\MockObject $userMock */ + /** @var User&MockObject $userMock */ $userMock = $this->getMockBuilder(User::class) ->setConstructorArgs([ $this->uid, @@ -897,7 +889,7 @@ class UserTest extends \Test\TestCase { $this->userManager, $this->notificationManager ]) - ->setMethods($requiredMethods) + ->onlyMethods($requiredMethods) ->getMock(); $this->connection->setConfiguration([ @@ -937,7 +929,7 @@ class UserTest extends \Test\TestCase { \OC_Hook::emit('OC_User', 'post_login', ['uid' => $this->uid]); } - public function emptyHomeFolderAttributeValueProvider() { + public static function emptyHomeFolderAttributeValueProvider(): array { return [ 'empty' => [''], 'prefixOnly' => ['attr:'], @@ -947,7 +939,7 @@ class UserTest extends \Test\TestCase { /** * @dataProvider emptyHomeFolderAttributeValueProvider */ - public function testGetHomePathNotConfigured($attributeValue): void { + public function testGetHomePathNotConfigured(string $attributeValue): void { $this->connection->expects($this->any()) ->method('__get') ->with($this->equalTo('homeFolderNamingRule')) @@ -1011,7 +1003,7 @@ class UserTest extends \Test\TestCase { $this->user->getHomePath(); } - public function displayNameProvider() { + public static function displayNameProvider(): array { return [ ['Roland Deschain', '', 'Roland Deschain', false], ['Roland Deschain', '', 'Roland Deschain', true], @@ -1023,7 +1015,7 @@ class UserTest extends \Test\TestCase { /** * @dataProvider displayNameProvider */ - public function testComposeAndStoreDisplayName($part1, $part2, $expected, $expectTriggerChange): void { + public function testComposeAndStoreDisplayName(string $part1, string $part2, string $expected, bool $expectTriggerChange): void { $this->config->expects($this->once()) ->method('setUserValue'); $oldName = $expectTriggerChange ? 'xxGunslingerxx' : null; diff --git a/apps/user_ldap/tests/UserLDAPPluginTest.php b/apps/user_ldap/tests/UserLDAPPluginTest.php index 5f11f817771..8a065374e61 100644 --- a/apps/user_ldap/tests/UserLDAPPluginTest.php +++ b/apps/user_ldap/tests/UserLDAPPluginTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -9,27 +11,23 @@ use OC\User\Backend; use OCA\User_LDAP\UserPluginManager; class UserLDAPPluginTest extends \Test\TestCase { - - /** - * @return UserPluginManager - */ - private function getUserPluginManager() { + private function getUserPluginManager(): UserPluginManager { return new UserPluginManager(); } public function testImplementsActions(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions']) ->getMock(); $plugin->expects($this->any()) ->method('respondToActions') ->willReturn(Backend::CREATE_USER); - $plugin2 = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions']) + $plugin2 = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions']) ->getMock(); $plugin2->expects($this->any()) @@ -47,8 +45,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testCreateUser(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'createUser']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'createUser']) ->getMock(); $plugin->expects($this->any()) @@ -66,7 +64,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->createUser('user', 'password'); } - + public function testCreateUserNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements createUser in this LDAP Backend.'); @@ -78,8 +76,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testSetPassword(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'setPassword']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'setPassword']) ->getMock(); $plugin->expects($this->any()) @@ -97,7 +95,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->setPassword('user', 'password'); } - + public function testSetPasswordNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements setPassword in this LDAP Backend.'); @@ -109,8 +107,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testGetHome(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'getHome']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'getHome']) ->getMock(); $plugin->expects($this->any()) @@ -127,7 +125,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->getHome('uid'); } - + public function testGetHomeNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements getHome in this LDAP Backend.'); @@ -139,8 +137,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testGetDisplayName(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'getDisplayName']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'getDisplayName']) ->getMock(); $plugin->expects($this->any()) @@ -157,7 +155,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->getDisplayName('uid'); } - + public function testGetDisplayNameNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements getDisplayName in this LDAP Backend.'); @@ -169,8 +167,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testSetDisplayName(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'setDisplayName']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'setDisplayName']) ->getMock(); $plugin->expects($this->any()) @@ -188,7 +186,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->setDisplayName('user', 'password'); } - + public function testSetDisplayNameNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements setDisplayName in this LDAP Backend.'); @@ -200,8 +198,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testCanChangeAvatar(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'canChangeAvatar']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'canChangeAvatar']) ->getMock(); $plugin->expects($this->any()) @@ -218,7 +216,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->canChangeAvatar('uid'); } - + public function testCanChangeAvatarNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements canChangeAvatar in this LDAP Backend.'); @@ -230,8 +228,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testCountUsers(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'countUsers']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'countUsers']) ->getMock(); $plugin->expects($this->any()) @@ -245,7 +243,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->countUsers(); } - + public function testCountUsersNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements countUsers in this LDAP Backend.'); @@ -257,8 +255,8 @@ class UserLDAPPluginTest extends \Test\TestCase { public function testDeleteUser(): void { $pluginManager = $this->getUserPluginManager(); - $plugin = $this->getMockBuilder('OCA\User_LDAP\Tests\LDAPUserPluginDummy') - ->setMethods(['respondToActions', 'canDeleteUser','deleteUser']) + $plugin = $this->getMockBuilder(LDAPUserPluginDummy::class) + ->onlyMethods(['respondToActions', 'canDeleteUser','deleteUser']) ->getMock(); $plugin->expects($this->any()) @@ -281,7 +279,7 @@ class UserLDAPPluginTest extends \Test\TestCase { $pluginManager->deleteUser('uid'); } - + public function testDeleteUserNotRegistered(): void { $this->expectException(\Exception::class); $this->expectExceptionMessage('No plugin implements deleteUser in this LDAP Backend.'); diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php index ede7123bd36..5be01d5e414 100644 --- a/apps/user_ldap/tests/User_LDAPTest.php +++ b/apps/user_ldap/tests/User_LDAPTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -10,6 +11,7 @@ namespace OCA\User_LDAP\Tests; use OC\User\Backend; use OCA\User_LDAP\Access; use OCA\User_LDAP\Connection; +use OCA\User_LDAP\ILDAPWrapper; use OCA\User_LDAP\Mapping\AbstractMapping; use OCA\User_LDAP\Mapping\UserMapping; use OCA\User_LDAP\User\DeletedUsersIndex; @@ -38,24 +40,15 @@ use Test\TestCase; * @package OCA\User_LDAP\Tests */ class User_LDAPTest extends TestCase { - /** @var User_LDAP */ - protected $backend; - /** @var Access|MockObject */ - protected $access; - /** @var OfflineUser|MockObject */ - protected $offlineUser; - /** @var INotificationManager|MockObject */ - protected $notificationManager; - /** @var UserPluginManager|MockObject */ - protected $pluginManager; - /** @var Connection|MockObject */ - protected $connection; - /** @var Manager|MockObject */ - protected $userManager; - /** @var LoggerInterface|MockObject */ - protected $logger; - /** @var DeletedUsersIndex|MockObject */ - protected $deletedUsersIndex; + protected Access&MockObject $access; + protected OfflineUser&MockObject $offlineUser; + protected INotificationManager&MockObject $notificationManager; + protected UserPluginManager&MockObject $pluginManager; + protected Connection&MockObject $connection; + protected Manager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected DeletedUsersIndex&MockObject $deletedUsersIndex; + protected User_LDAP $backend; protected function setUp(): void { parent::setUp(); @@ -63,7 +56,9 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->clearBackends(); Server::get(IGroupManager::class)->clearBackends(); - $this->connection = $this->createMock(Connection::class); + $this->connection = $this->getMockBuilder(Connection::class) + ->setConstructorArgs([$this->createMock(ILDAPWrapper::class)]) + ->getMock(); $this->userManager = $this->createMock(Manager::class); $this->access = $this->createMock(Access::class); @@ -86,7 +81,7 @@ class User_LDAPTest extends TestCase { ); } - private function prepareMockForUserExists() { + private function prepareMockForUserExists(): void { $this->access->expects($this->any()) ->method('username2dn') ->willReturnCallback(function ($uid) { @@ -114,10 +109,8 @@ class User_LDAPTest extends TestCase { /** * Prepares the Access mock for checkPassword tests - * @param bool $noDisplayName - * @return void */ - private function prepareAccessForCheckPassword($noDisplayName = false) { + private function prepareAccessForCheckPassword(bool $noDisplayName = false): void { $this->connection->expects($this->any()) ->method('__get') ->willReturnCallback(function ($name) { @@ -347,7 +340,7 @@ class User_LDAPTest extends TestCase { ->method('invalidate') ->with('uid'); - $this->assertEquals(true, $this->backend->deleteUser('uid')); + $this->assertTrue($this->backend->deleteUser('uid')); } /** @@ -404,7 +397,7 @@ class User_LDAPTest extends TestCase { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $result = $backend->getUsers(); - $this->assertEquals(3, count($result)); + $this->assertCount(3, $result); } public function testGetUsersLimitOffset(): void { @@ -412,7 +405,7 @@ class User_LDAPTest extends TestCase { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $result = $backend->getUsers('', 1, 2); - $this->assertEquals(1, count($result)); + $this->assertCount(1, $result); } public function testGetUsersLimitOffset2(): void { @@ -420,7 +413,7 @@ class User_LDAPTest extends TestCase { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $result = $backend->getUsers('', 2, 1); - $this->assertEquals(2, count($result)); + $this->assertCount(2, $result); } public function testGetUsersSearchWithResult(): void { @@ -428,7 +421,7 @@ class User_LDAPTest extends TestCase { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $result = $backend->getUsers('yo'); - $this->assertEquals(2, count($result)); + $this->assertCount(2, $result); } public function testGetUsersSearchEmptyResult(): void { @@ -436,7 +429,7 @@ class User_LDAPTest extends TestCase { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $result = $backend->getUsers('nix'); - $this->assertEquals(0, count($result)); + $this->assertCount(0, $result); } private function getUsers($search = '', $limit = null, $offset = null) { @@ -453,7 +446,7 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->registerBackend($backend); $result = $this->getUsers(); - $this->assertEquals(3, count($result)); + $this->assertCount(3, $result); } public function testGetUsersViaAPILimitOffset(): void { @@ -462,7 +455,7 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->registerBackend($backend); $result = $this->getUsers('', 1, 2); - $this->assertEquals(1, count($result)); + $this->assertCount(1, $result); } public function testGetUsersViaAPILimitOffset2(): void { @@ -471,7 +464,7 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->registerBackend($backend); $result = $this->getUsers('', 2, 1); - $this->assertEquals(2, count($result)); + $this->assertCount(2, $result); } public function testGetUsersViaAPISearchWithResult(): void { @@ -480,7 +473,7 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->registerBackend($backend); $result = $this->getUsers('yo'); - $this->assertEquals(2, count($result)); + $this->assertCount(2, $result); } public function testGetUsersViaAPISearchEmptyResult(): void { @@ -489,15 +482,13 @@ class User_LDAPTest extends TestCase { Server::get(IUserManager::class)->registerBackend($backend); $result = $this->getUsers('nix'); - $this->assertEquals(0, count($result)); + $this->assertCount(0, $result); } public function testUserExists(): void { $backend = new UserLDAP($this->access, $this->notificationManager, $this->pluginManager, $this->logger, $this->deletedUsersIndex); $this->prepareMockForUserExists(); - $user = $this->createMock(User::class); - $this->userManager->expects($this->never()) ->method('get'); $this->userManager->expects($this->once()) @@ -1182,8 +1173,6 @@ class User_LDAPTest extends TestCase { /** * Prepares the Access mock for setPassword tests - * - * @param bool $enablePasswordChange */ private function prepareAccessForSetPassword($enablePasswordChange = true) { $this->connection->expects($this->any()) @@ -1328,7 +1317,7 @@ class User_LDAPTest extends TestCase { $this->assertEquals($this->backend->setPassword('uid', 'password'), 'result'); } - public function avatarDataProvider() { + public static function avatarDataProvider(): array { return [ [ 'validImageData', false ], [ 'corruptImageData', true ], @@ -1336,8 +1325,10 @@ class User_LDAPTest extends TestCase { ]; } - /** @dataProvider avatarDataProvider */ - public function testCanChangeAvatar($imageData, $expected): void { + /** + * @dataProvider avatarDataProvider + */ + public function testCanChangeAvatar(string|bool $imageData, bool $expected): void { $isValidImage = str_starts_with((string)$imageData, 'valid'); $user = $this->createMock(User::class); @@ -1451,9 +1442,9 @@ class User_LDAPTest extends TestCase { $this->assertFalse($this->backend->createUser('uid', 'password')); } - public function actionProvider() { + public static function actionProvider(): array { return [ - [ 'ldapUserAvatarRule', 'default', Backend::PROVIDE_AVATAR, true] , + [ 'ldapUserAvatarRule', 'default', Backend::PROVIDE_AVATAR, true], [ 'ldapUserAvatarRule', 'data:selfiePhoto', Backend::PROVIDE_AVATAR, true], [ 'ldapUserAvatarRule', 'none', Backend::PROVIDE_AVATAR, false], [ 'turnOnPasswordChange', 0, Backend::SET_PASSWORD, false], @@ -1464,7 +1455,7 @@ class User_LDAPTest extends TestCase { /** * @dataProvider actionProvider */ - public function testImplementsAction($configurable, $value, $actionCode, $expected): void { + public function testImplementsAction(string $configurable, string|int $value, int $actionCode, bool $expected): void { $this->pluginManager->expects($this->once()) ->method('getImplementedActions') ->willReturn(0); diff --git a/apps/user_ldap/tests/User_ProxyTest.php b/apps/user_ldap/tests/User_ProxyTest.php index 4544276a714..38f94af33a7 100644 --- a/apps/user_ldap/tests/User_ProxyTest.php +++ b/apps/user_ldap/tests/User_ProxyTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -17,22 +19,14 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class User_ProxyTest extends TestCase { - /** @var Helper|MockObject */ - protected $helper; - /** @var ILDAPWrapper|MockObject */ - private $ldapWrapper; - /** @var AccessFactory|MockObject */ - private $accessFactory; - /** @var INotificationManager|MockObject */ - private $notificationManager; - /** @var User_Proxy|MockObject */ - private $proxy; - /** @var UserPluginManager|MockObject */ - private $userPluginManager; - /** @var LoggerInterface|MockObject */ - protected $logger; - /** @var DeletedUsersIndex|MockObject */ - protected $deletedUsersIndex; + protected Helper&MockObject $helper; + private ILDAPWrapper&MockObject $ldapWrapper; + private AccessFactory&MockObject $accessFactory; + private INotificationManager&MockObject $notificationManager; + private User_Proxy&MockObject $proxy; + private UserPluginManager&MockObject $userPluginManager; + protected LoggerInterface&MockObject $logger; + protected DeletedUsersIndex&MockObject $deletedUsersIndex; protected function setUp(): void { parent::setUp(); @@ -54,7 +48,7 @@ class User_ProxyTest extends TestCase { $this->logger, $this->deletedUsersIndex, ]) - ->setMethods(['handleRequest']) + ->onlyMethods(['handleRequest']) ->getMock(); } diff --git a/apps/user_ldap/tests/WizardTest.php b/apps/user_ldap/tests/WizardTest.php index 31fd28e2fa1..3ae9a409e88 100644 --- a/apps/user_ldap/tests/WizardTest.php +++ b/apps/user_ldap/tests/WizardTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -35,32 +36,28 @@ class WizardTest extends TestCase { } } - private function getWizardAndMocks() { + private function getWizardAndMocks(): array { static $confMethods; - static $connMethods; - static $accMethods; if (is_null($confMethods)) { $confMethods = get_class_methods('\OCA\User_LDAP\Configuration'); - $connMethods = get_class_methods('\OCA\User_LDAP\Connection'); - $accMethods = get_class_methods('\OCA\User_LDAP\Access'); } - /** @var ILDAPWrapper|\PHPUnit\Framework\MockObject\MockObject $lw */ + /** @var ILDAPWrapper&MockObject $lw */ $lw = $this->createMock(ILDAPWrapper::class); - /** @var Configuration|\PHPUnit\Framework\MockObject\MockObject $conf */ + /** @var Configuration&MockObject $conf */ $conf = $this->getMockBuilder(Configuration::class) - ->setMethods($confMethods) + ->onlyMethods($confMethods) ->setConstructorArgs(['', true]) ->getMock(); - /** @var Access|\PHPUnit\Framework\MockObject\MockObject $access */ + /** @var Access&MockObject $access */ $access = $this->createMock(Access::class); return [new Wizard($conf, $lw, $access), $conf, $lw, $access]; } - private function prepareLdapWrapperForConnections(MockObject &$ldap) { + private function prepareLdapWrapperForConnections(MockObject $ldap) { $ldap->expects($this->once()) ->method('connect') //dummy value @@ -346,7 +343,7 @@ class WizardTest extends TestCase { }); $result = $wizard->detectEmailAttribute(); - $this->assertSame(false, $result->hasChanges()); + $this->assertFalse($result->hasChanges()); } public function testCumulativeSearchOnAttributeSkipReadDN(): void { @@ -423,7 +420,7 @@ class WizardTest extends TestCase { // The following expectations are the real test $filters = ['f1', 'f2', '*']; $resultArray = $wizard->cumulativeSearchOnAttribute($filters, 'cn', 0); - $this->assertSame(6, count($resultArray)); + $this->assertCount(6, $resultArray); unset($mark); } } diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index 9adc13e4dbf..188eb26d1d7 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -167,7 +167,7 @@ class StatusService { $userStatus->setIsBackup(false); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -211,7 +211,7 @@ class StatusService { $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -313,7 +313,7 @@ class StatusService { if ($userStatus->getId() !== null) { return $this->mapper->update($userStatus); } - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } /** @@ -360,7 +360,7 @@ class StatusService { $userStatus->setStatusMessageTimestamp($this->timeFactory->now()->getTimestamp()); if ($userStatus->getId() === null) { - return $this->mapper->insert($userStatus); + return $this->insertWithoutThrowingUniqueConstrain($userStatus); } return $this->mapper->update($userStatus); @@ -584,4 +584,16 @@ class StatusService { // For users that matched restore the previous status $this->mapper->restoreBackupStatuses($restoreIds); } + + protected function insertWithoutThrowingUniqueConstrain(UserStatus $userStatus): UserStatus { + try { + return $this->mapper->insert($userStatus); + } catch (Exception $e) { + // Ignore if a parallel request already set the status + if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { + throw $e; + } + } + return $userStatus; + } } |