diff options
Diffstat (limited to 'apps')
720 files changed, 7435 insertions, 7563 deletions
diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue index fb08778b9d2..c8b2b176f42 100644 --- a/apps/comments/src/components/Comment.vue +++ b/apps/comments/src/components/Comment.vue @@ -364,7 +364,7 @@ $comment-padding: 10px; &__message { white-space: pre-wrap; - word-break: break-word; + word-break: normal; max-height: 70px; overflow: hidden; margin-top: -6px; 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/css/schedule-response.css b/apps/dav/css/schedule-response.css index eef571027c5..85a03cb63e1 100644 --- a/apps/dav/css/schedule-response.css +++ b/apps/dav/css/schedule-response.css @@ -56,6 +56,7 @@ form #selectPartStatForm label span { display: block; line-height: normal; } + form #selectPartStatForm label.ui-state-hover, form #selectPartStatForm label.ui-state-active { color:#000; 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/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php index 41b610542df..f498a47a0b4 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Event.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php @@ -78,14 +78,9 @@ class Event extends Base { // as seen from the affected user. $objectId = base64_encode($this->url->getWebroot() . '/remote.php/dav/calendars/' . $affectedUser . '/' . $calendarUri . '_shared_by_' . $linkData['owner'] . '/' . $linkData['object_uri']); } - $link = [ - 'view' => 'dayGridMonth', - 'timeRange' => 'now', - 'mode' => 'sidebar', + $params['link'] = $this->url->linkToRouteAbsolute('calendar.view.indexdirect.edit', [ 'objectId' => $objectId, - 'recurrenceId' => 'next' - ]; - $params['link'] = $this->url->linkToRouteAbsolute('calendar.view.indexview.timerange.edit', $link); + ]); } catch (\Exception $error) { // Do nothing } 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/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 5643e89d797..1c2b4e54c03 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1538,25 +1538,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription }, $this->db); } - - /** - * @param int $calendarObjectId - * @param int $classification - */ - public function setClassification($calendarObjectId, $classification) { - $this->cachedObjects = []; - if (!in_array($classification, [ - self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL - ])) { - throw new \InvalidArgumentException(); - } - $query = $this->db->getQueryBuilder(); - $query->update('calendarobjects') - ->set('classification', $query->createNamedParameter($classification)) - ->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId))) - ->executeStatement(); - } - /** * Deletes an existing calendar object. * 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/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index de209754ae4..d874ca2ce2b 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -127,7 +127,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { // query for shared addressbooks $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true); - $principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal)); $principals[] = $principalUri; 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/lib/DAV/GroupPrincipalBackend.php b/apps/dav/lib/DAV/GroupPrincipalBackend.php index 143fc7d69f1..ddbd64bdda1 100644 --- a/apps/dav/lib/DAV/GroupPrincipalBackend.php +++ b/apps/dav/lib/DAV/GroupPrincipalBackend.php @@ -50,8 +50,10 @@ class GroupPrincipalBackend implements BackendInterface { $principals = []; if ($prefixPath === self::PRINCIPAL_PREFIX) { - foreach ($this->groupManager->search('') as $user) { - $principals[] = $this->groupToPrincipal($user); + foreach ($this->groupManager->search('') as $group) { + if (!$group->hideFromCollaboration()) { + $principals[] = $this->groupToPrincipal($group); + } } } @@ -77,7 +79,7 @@ class GroupPrincipalBackend implements BackendInterface { $name = urldecode($elements[2]); $group = $this->groupManager->get($name); - if (!is_null($group)) { + if ($group !== null && !$group->hideFromCollaboration()) { return $this->groupToPrincipal($group); } diff --git a/apps/dav/openapi.json b/apps/dav/openapi.json index 48d6ae03ee0..27904636def 100644 --- a/apps/dav/openapi.json +++ b/apps/dav/openapi.json @@ -399,7 +399,8 @@ "description": "location/URL to filter by", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { diff --git a/apps/dav/tests/unit/AppInfo/ApplicationTest.php b/apps/dav/tests/unit/AppInfo/ApplicationTest.php index f8ddd9bb821..336f487e0b8 100644 --- a/apps/dav/tests/unit/AppInfo/ApplicationTest.php +++ b/apps/dav/tests/unit/AppInfo/ApplicationTest.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/AppInfo/PluginManagerTest.php b/apps/dav/tests/unit/AppInfo/PluginManagerTest.php index 7a60888a838..0082aa45286 100644 --- a/apps/dav/tests/unit/AppInfo/PluginManagerTest.php +++ b/apps/dav/tests/unit/AppInfo/PluginManagerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 ownCloud GmbH. * SPDX-License-Identifier: AGPL-3.0-only diff --git a/apps/dav/tests/unit/Avatars/AvatarHomeTest.php b/apps/dav/tests/unit/Avatars/AvatarHomeTest.php index 9699c146c8a..aaa930b6c19 100644 --- a/apps/dav/tests/unit/Avatars/AvatarHomeTest.php +++ b/apps/dav/tests/unit/Avatars/AvatarHomeTest.php @@ -1,27 +1,25 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * 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; use OCP\IAvatar; use OCP\IAvatarManager; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Exception\MethodNotAllowed; use Sabre\DAV\Exception\NotFound; use Test\TestCase; class AvatarHomeTest extends TestCase { - - /** @var AvatarHome */ - private $home; - - /** @var IAvatarManager | \PHPUnit\Framework\MockObject\MockObject */ - private $avatarManager; + private AvatarHome $home; + private IAvatarManager&MockObject $avatarManager; protected function setUp(): void { parent::setUp(); @@ -38,7 +36,7 @@ class AvatarHomeTest extends TestCase { $this->home->$method(''); } - public function providesForbiddenMethods() { + public static function providesForbiddenMethods(): array { return [ ['createFile'], ['createDirectory'], @@ -52,7 +50,7 @@ class AvatarHomeTest extends TestCase { self::assertEquals('admin', $n); } - public function providesTestGetChild() { + public static function providesTestGetChild(): array { return [ [MethodNotAllowed::class, false, ''], [MethodNotAllowed::class, false, 'bla.foo'], @@ -65,7 +63,7 @@ class AvatarHomeTest extends TestCase { /** * @dataProvider providesTestGetChild */ - public function testGetChild($expectedException, $hasAvatar, $path): void { + public function testGetChild(?string $expectedException, bool $hasAvatar, string $path): void { if ($expectedException !== null) { $this->expectException($expectedException); } @@ -92,7 +90,7 @@ class AvatarHomeTest extends TestCase { /** * @dataProvider providesTestGetChild */ - public function testChildExists($expectedException, $hasAvatar, $path): void { + public function testChildExists(?string $expectedException, bool $hasAvatar, string $path): void { $avatar = $this->createMock(IAvatar::class); $avatar->method('exists')->willReturn($hasAvatar); diff --git a/apps/dav/tests/unit/Avatars/AvatarNodeTest.php b/apps/dav/tests/unit/Avatars/AvatarNodeTest.php index 92c02e17ff8..0ca147a1f3b 100644 --- a/apps/dav/tests/unit/Avatars/AvatarNodeTest.php +++ b/apps/dav/tests/unit/Avatars/AvatarNodeTest.php @@ -1,26 +1,28 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors * 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; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class AvatarNodeTest extends TestCase { public function testGetName(): void { - /** @var IAvatar | \PHPUnit\Framework\MockObject\MockObject $a */ + /** @var IAvatar&MockObject $a */ $a = $this->createMock(IAvatar::class); $n = new AvatarNode(1024, 'png', $a); $this->assertEquals('1024.png', $n->getName()); } public function testGetContentType(): void { - /** @var IAvatar | \PHPUnit\Framework\MockObject\MockObject $a */ + /** @var IAvatar&MockObject $a */ $a = $this->createMock(IAvatar::class); $n = new AvatarNode(1024, 'png', $a); $this->assertEquals('image/png', $n->getContentType()); diff --git a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php index 21e999d34be..b2199e3e657 100644 --- a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php @@ -13,17 +13,13 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IExpressionBuilder; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class CleanupInvitationTokenJobTest extends TestCase { - /** @var IDBConnection | \PHPUnit\Framework\MockObject\MockObject */ - private $dbConnection; - - /** @var ITimeFactory | \PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; - - /** @var CleanupInvitationTokenJob */ - private $backgroundJob; + private IDBConnection&MockObject $dbConnection; + private ITimeFactory&MockObject $timeFactory; + private CleanupInvitationTokenJob $backgroundJob; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/BackgroundJob/CleanupOrphanedChildrenJobTest.php b/apps/dav/tests/unit/BackgroundJob/CleanupOrphanedChildrenJobTest.php index fe05616d609..2065b8fe946 100644 --- a/apps/dav/tests/unit/BackgroundJob/CleanupOrphanedChildrenJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/CleanupOrphanedChildrenJobTest.php @@ -103,14 +103,13 @@ class CleanupOrphanedChildrenJobTest extends TestCase { $deleteQb = $this->getMockQueryBuilder(); $result = $this->createMock(IResult::class); - $qbInvocationCount = self::exactly(2); - $this->connection->expects($qbInvocationCount) - ->method('getQueryBuilder') - ->willReturnCallback(function () use ($qbInvocationCount, $selectQb, $deleteQb) { - return match ($qbInvocationCount->getInvocationCount()) { - 1 => $selectQb, - 2 => $deleteQb, - }; + $calls = [ + $selectQb, + $deleteQb, + ]; + $this->connection->method('getQueryBuilder') + ->willReturnCallback(function () use (&$calls) { + return array_shift($calls); }); $selectQb->expects(self::once()) ->method('executeQuery') @@ -140,15 +139,15 @@ class CleanupOrphanedChildrenJobTest extends TestCase { $deleteQb = $this->getMockQueryBuilder(); $result = $this->createMock(IResult::class); - $qbInvocationCount = self::exactly(2); - $this->connection->expects($qbInvocationCount) - ->method('getQueryBuilder') - ->willReturnCallback(function () use ($qbInvocationCount, $selectQb, $deleteQb) { - return match ($qbInvocationCount->getInvocationCount()) { - 1 => $selectQb, - 2 => $deleteQb, - }; + $calls = [ + $selectQb, + $deleteQb, + ]; + $this->connection->method('getQueryBuilder') + ->willReturnCallback(function () use (&$calls) { + return array_shift($calls); }); + $selectQb->expects(self::once()) ->method('executeQuery') ->willReturn($result); diff --git a/apps/dav/tests/unit/BackgroundJob/EventReminderJobTest.php b/apps/dav/tests/unit/BackgroundJob/EventReminderJobTest.php index 1173e516a22..1f70869f211 100644 --- a/apps/dav/tests/unit/BackgroundJob/EventReminderJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/EventReminderJobTest.php @@ -16,17 +16,10 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class EventReminderJobTest extends TestCase { - /** @var ITimeFactory|MockObject */ - private $time; - - /** @var ReminderService|MockObject */ - private $reminderService; - - /** @var IConfig|MockObject */ - private $config; - - /** @var EventReminderJob|MockObject */ - private $backgroundJob; + private ITimeFactory&MockObject $time; + private ReminderService&MockObject $reminderService; + private IConfig&MockObject $config; + private EventReminderJob $backgroundJob; protected function setUp(): void { parent::setUp(); @@ -42,7 +35,7 @@ class EventReminderJobTest extends TestCase { ); } - public function data(): array { + public static function data(): array { return [ [true, true, true], [true, false, false], @@ -61,14 +54,10 @@ class EventReminderJobTest extends TestCase { public function testRun(bool $sendEventReminders, bool $sendEventRemindersMode, bool $expectCall): void { $this->config->expects($this->exactly($sendEventReminders ? 2 : 1)) ->method('getAppValue') - ->withConsecutive( - ['dav', 'sendEventReminders', 'yes'], - ['dav', 'sendEventRemindersMode', 'backgroundjob'], - ) - ->willReturnOnConsecutiveCalls( - $sendEventReminders ? 'yes' : 'no', - $sendEventRemindersMode ? 'backgroundjob' : 'cron' - ); + ->willReturnMap([ + ['dav', 'sendEventReminders', 'yes', ($sendEventReminders ? 'yes' : 'no')], + ['dav', 'sendEventRemindersMode', 'backgroundjob', ($sendEventRemindersMode ? 'backgroundjob' : 'cron')], + ]); if ($expectCall) { $this->reminderService->expects($this->once()) diff --git a/apps/dav/tests/unit/BackgroundJob/GenerateBirthdayCalendarBackgroundJobTest.php b/apps/dav/tests/unit/BackgroundJob/GenerateBirthdayCalendarBackgroundJobTest.php index 82d2251f17a..88a76ae1332 100644 --- a/apps/dav/tests/unit/BackgroundJob/GenerateBirthdayCalendarBackgroundJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/GenerateBirthdayCalendarBackgroundJobTest.php @@ -16,18 +16,10 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class GenerateBirthdayCalendarBackgroundJobTest extends TestCase { - - /** @var ITimeFactory|MockObject */ - private $time; - - /** @var BirthdayService | MockObject */ - private $birthdayService; - - /** @var IConfig | MockObject */ - private $config; - - /** @var GenerateBirthdayCalendarBackgroundJob */ - private $backgroundJob; + private ITimeFactory&MockObject $time; + private BirthdayService&MockObject $birthdayService; + private IConfig&MockObject $config; + private GenerateBirthdayCalendarBackgroundJob $backgroundJob; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/BackgroundJob/OutOfOfficeEventDispatcherJobTest.php b/apps/dav/tests/unit/BackgroundJob/OutOfOfficeEventDispatcherJobTest.php index 5ddd9eba6f8..6135fd00fdc 100644 --- a/apps/dav/tests/unit/BackgroundJob/OutOfOfficeEventDispatcherJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/OutOfOfficeEventDispatcherJobTest.php @@ -25,21 +25,11 @@ use Test\TestCase; class OutOfOfficeEventDispatcherJobTest extends TestCase { private OutOfOfficeEventDispatcherJob $job; - - /** @var MockObject|ITimeFactory */ - private $timeFactory; - - /** @var MockObject|AbsenceMapper */ - private $absenceMapper; - - /** @var MockObject|LoggerInterface */ - private $logger; - - /** @var MockObject|IEventDispatcher */ - private $eventDispatcher; - - /** @var MockObject|IUserManager */ - private $userManager; + private ITimeFactory&MockObject $timeFactory; + private AbsenceMapper&MockObject $absenceMapper; + private LoggerInterface&MockObject $logger; + private IEventDispatcher&MockObject $eventDispatcher; + private IUserManager&MockObject $userManager; private MockObject|TimezoneService $timezoneService; protected function setUp(): void { diff --git a/apps/dav/tests/unit/BackgroundJob/PruneOutdatedSyncTokensJobTest.php b/apps/dav/tests/unit/BackgroundJob/PruneOutdatedSyncTokensJobTest.php index d08d0fd4496..eb471189c24 100644 --- a/apps/dav/tests/unit/BackgroundJob/PruneOutdatedSyncTokensJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/PruneOutdatedSyncTokensJobTest.php @@ -20,21 +20,11 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class PruneOutdatedSyncTokensJobTest extends TestCase { - /** @var ITimeFactory | MockObject */ - private $timeFactory; - - /** @var CalDavBackend | MockObject */ - private $calDavBackend; - - /** @var CardDavBackend | MockObject */ - private $cardDavBackend; - - /** @var IConfig|MockObject */ - private $config; - - /** @var LoggerInterface|MockObject */ - private $logger; - + private ITimeFactory&MockObject $timeFactory; + private CalDavBackend&MockObject $calDavBackend; + private CardDavBackend&MockObject $cardDavBackend; + private IConfig&MockObject $config; + private LoggerInterface&MockObject $logger; private PruneOutdatedSyncTokensJob $backgroundJob; protected function setUp(): void { @@ -84,7 +74,7 @@ class PruneOutdatedSyncTokensJobTest extends TestCase { $this->backgroundJob->run(null); } - public function dataForTestRun(): array { + public static function dataForTestRun(): array { return [ ['100', '2', 100, 7 * 24 * 3600, 2, 3], ['100', '14', 100, 14 * 24 * 3600, 2, 3], diff --git a/apps/dav/tests/unit/BackgroundJob/RefreshWebcalJobTest.php b/apps/dav/tests/unit/BackgroundJob/RefreshWebcalJobTest.php index 2b11223210e..0cdeb6436e2 100644 --- a/apps/dav/tests/unit/BackgroundJob/RefreshWebcalJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/RefreshWebcalJobTest.php @@ -19,20 +19,11 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class RefreshWebcalJobTest extends TestCase { - - /** @var RefreshWebcalService | MockObject */ - private $refreshWebcalService; - - /** @var IConfig | MockObject */ - private $config; - + private RefreshWebcalService&MockObject $refreshWebcalService; + private IConfig&MockObject $config; private LoggerInterface $logger; - - /** @var ITimeFactory | MockObject */ - private $timeFactory; - - /** @var IJobList | MockObject */ - private $jobList; + private ITimeFactory&MockObject $timeFactory; + private IJobList&MockObject $jobList; protected function setUp(): void { parent::setUp(); @@ -97,10 +88,7 @@ class RefreshWebcalJobTest extends TestCase { $backgroundJob->start($this->jobList); } - /** - * @return array - */ - public function runDataProvider():array { + public static function runDataProvider():array { return [ [0, 100000, true], [100000, 100000, false] diff --git a/apps/dav/tests/unit/BackgroundJob/RegisterRegenerateBirthdayCalendarsTest.php b/apps/dav/tests/unit/BackgroundJob/RegisterRegenerateBirthdayCalendarsTest.php index 88493d91d9b..6c9214d0268 100644 --- a/apps/dav/tests/unit/BackgroundJob/RegisterRegenerateBirthdayCalendarsTest.php +++ b/apps/dav/tests/unit/BackgroundJob/RegisterRegenerateBirthdayCalendarsTest.php @@ -14,20 +14,14 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\IUser; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class RegisterRegenerateBirthdayCalendarsTest extends TestCase { - /** @var ITimeFactory | \PHPUnit\Framework\MockObject\MockObject */ - private $time; - - /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - - /** @var IJobList | \PHPUnit\Framework\MockObject\MockObject */ - private $jobList; - - /** @var RegisterRegenerateBirthdayCalendars */ - private $backgroundJob; + private ITimeFactory&MockObject $time; + private IUserManager&MockObject $userManager; + private IJobList&MockObject $jobList; + private RegisterRegenerateBirthdayCalendars $backgroundJob; protected function setUp(): void { parent::setUp(); @@ -59,22 +53,26 @@ class RegisterRegenerateBirthdayCalendarsTest extends TestCase { $closure($user3); }); + $calls = [ + 'uid1', + 'uid2', + 'uid3', + ]; $this->jobList->expects($this->exactly(3)) ->method('add') - ->withConsecutive( - [GenerateBirthdayCalendarBackgroundJob::class, [ - 'userId' => 'uid1', - 'purgeBeforeGenerating' => true - ]], - [GenerateBirthdayCalendarBackgroundJob::class, [ - 'userId' => 'uid2', - 'purgeBeforeGenerating' => true - ]], - [GenerateBirthdayCalendarBackgroundJob::class, [ - 'userId' => 'uid3', - 'purgeBeforeGenerating' => true - ]], - ); + ->willReturnCallback(function () use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals( + [ + GenerateBirthdayCalendarBackgroundJob::class, + [ + 'userId' => $expected, + 'purgeBeforeGenerating' => true + ] + ], + func_get_args() + ); + }); $this->backgroundJob->run([]); } diff --git a/apps/dav/tests/unit/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJobTest.php b/apps/dav/tests/unit/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJobTest.php index 18ee0c5c61d..38a981787cd 100644 --- a/apps/dav/tests/unit/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJobTest.php @@ -18,15 +18,9 @@ use Test\TestCase; class UpdateCalendarResourcesRoomsBackgroundJobTest extends TestCase { private UpdateCalendarResourcesRoomsBackgroundJob $backgroundJob; - - /** @var ITimeFactory|MockObject */ - private $time; - - /** @var IResourceManager|MockObject */ - private $resourceManager; - - /** @var IRoomManager|MockObject */ - private $roomManager; + private ITimeFactory&MockObject $time; + private IResourceManager&MockObject $resourceManager; + private IRoomManager&MockObject $roomManager; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/BackgroundJob/UserStatusAutomationTest.php b/apps/dav/tests/unit/BackgroundJob/UserStatusAutomationTest.php index ce3871aa400..369242ad488 100644 --- a/apps/dav/tests/unit/BackgroundJob/UserStatusAutomationTest.php +++ b/apps/dav/tests/unit/BackgroundJob/UserStatusAutomationTest.php @@ -29,14 +29,13 @@ use Test\TestCase; * @group DB */ class UserStatusAutomationTest extends TestCase { - - protected MockObject|ITimeFactory $time; - protected MockObject|IJobList $jobList; - protected MockObject|LoggerInterface $logger; - protected MockObject|IManager $statusManager; - protected MockObject|IConfig $config; - private IAvailabilityCoordinator|MockObject $coordinator; - private IUserManager|MockObject $userManager; + protected ITimeFactory&MockObject $time; + protected IJobList&MockObject $jobList; + protected LoggerInterface&MockObject $logger; + protected IManager&MockObject $statusManager; + protected IConfig&MockObject $config; + private IAvailabilityCoordinator&MockObject $coordinator; + private IUserManager&MockObject $userManager; protected function setUp(): void { parent::setUp(); @@ -76,11 +75,11 @@ class UserStatusAutomationTest extends TestCase { $this->coordinator, $this->userManager, ]) - ->setMethods($methods) + ->onlyMethods($methods) ->getMock(); } - public function dataRun(): array { + public static function dataRun(): array { return [ ['20230217', '2023-02-24 10:49:36.613834', true], ['20230224', '2023-02-24 10:49:36.613834', true], diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php index c1d8e8609b6..45937d86873 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php @@ -44,12 +44,12 @@ abstract class AbstractCalDavBackend extends TestCase { protected CalDavBackend $backend; - protected Principal|MockObject $principal; - protected IUserManager|MockObject $userManager; - protected IGroupManager|MockObject $groupManager; - protected IEventDispatcher|MockObject $dispatcher; - private LoggerInterface|MockObject $logger; - private IConfig|MockObject $config; + protected Principal&MockObject $principal; + protected IUserManager&MockObject $userManager; + protected IGroupManager&MockObject $groupManager; + protected IEventDispatcher&MockObject $dispatcher; + private LoggerInterface&MockObject $logger; + private IConfig&MockObject $config; private ISecureRandom $random; protected SharingBackend $sharingBackend; protected IDBConnection $db; @@ -77,7 +77,7 @@ abstract class AbstractCalDavBackend extends TestCase { $this->createMock(IConfig::class), $this->createMock(IFactory::class) ]) - ->setMethods(['getPrincipalByPath', 'getGroupMembership', 'findByUri']) + ->onlyMethods(['getPrincipalByPath', 'getGroupMembership', 'findByUri']) ->getMock(); $this->principal->expects($this->any())->method('getPrincipalByPath') ->willReturn([ @@ -143,7 +143,7 @@ abstract class AbstractCalDavBackend extends TestCase { } } - protected function createTestCalendar() { + protected function createTestCalendar(): int { $this->dispatcher->expects(self::any()) ->method('dispatchTyped'); @@ -160,9 +160,7 @@ abstract class AbstractCalDavBackend extends TestCase { $this->assertEquals('#1C4587FF', $color); $this->assertEquals('Example', $calendars[0]['uri']); $this->assertEquals('Example', $calendars[0]['{DAV:}displayname']); - $calendarId = $calendars[0]['id']; - - return $calendarId; + return (int)$calendars[0]['id']; } protected function createTestSubscription() { diff --git a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php index 6ace633b072..ebe989ad815 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.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 @@ -19,21 +21,11 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class BackendTest extends TestCase { - - /** @var IManager|MockObject */ - protected $activityManager; - - /** @var IGroupManager|MockObject */ - protected $groupManager; - - /** @var IUserSession|MockObject */ - protected $userSession; - - /** @var IAppManager|MockObject */ - protected $appManager; - - /** @var IUserManager|MockObject */ - protected $userManager; + protected IManager&MockObject $activityManager; + protected IGroupManager&MockObject $groupManager; + protected IUserSession&MockObject $userSession; + protected IAppManager&MockObject $appManager; + protected IUserManager&MockObject $userManager; protected function setUp(): void { parent::setUp(); @@ -45,10 +37,9 @@ class BackendTest extends TestCase { } /** - * @param array $methods - * @return Backend|MockObject + * @return Backend|(Backend&MockObject) */ - protected function getBackend(array $methods = []) { + protected function getBackend(array $methods = []): Backend { if (empty($methods)) { return new Backend( $this->activityManager, @@ -71,7 +62,7 @@ class BackendTest extends TestCase { } } - public function dataCallTriggerCalendarActivity() { + public static function dataCallTriggerCalendarActivity(): array { return [ ['onCalendarAdd', [['data']], Calendar::SUBJECT_ADD, [['data'], [], []]], ['onCalendarUpdate', [['data'], ['shares'], ['changed-properties']], Calendar::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]], @@ -82,13 +73,8 @@ class BackendTest extends TestCase { /** * @dataProvider dataCallTriggerCalendarActivity - * - * @param string $method - * @param array $payload - * @param string $expectedSubject - * @param array $expectedPayload */ - public function testCallTriggerCalendarActivity($method, array $payload, $expectedSubject, array $expectedPayload): void { + public function testCallTriggerCalendarActivity(string $method, array $payload, string $expectedSubject, array $expectedPayload): void { $backend = $this->getBackend(['triggerCalendarActivity']); $backend->expects($this->once()) ->method('triggerCalendarActivity') @@ -101,7 +87,7 @@ class BackendTest extends TestCase { call_user_func_array([$backend, $method], $payload); } - public function dataTriggerCalendarActivity() { + public static function dataTriggerCalendarActivity(): array { return [ // Add calendar [Calendar::SUBJECT_ADD, [], [], [], '', '', null, []], @@ -184,16 +170,8 @@ class BackendTest extends TestCase { /** * @dataProvider dataTriggerCalendarActivity - * @param string $action - * @param array $data - * @param array $shares - * @param array $changedProperties - * @param string $currentUser - * @param string $author - * @param string[]|null $shareUsers - * @param string[] $users */ - public function testTriggerCalendarActivity($action, array $data, array $shares, array $changedProperties, $currentUser, $author, $shareUsers, array $users): void { + public function testTriggerCalendarActivity(string $action, array $data, array $shares, array $changedProperties, string $currentUser, string $author, ?array $shareUsers, array $users): void { $backend = $this->getBackend(['getUsersForShares']); if ($shareUsers === null) { @@ -278,7 +256,7 @@ class BackendTest extends TestCase { ], [], []]); } - public function dataGetUsersForShares() { + public static function dataGetUsersForShares(): array { return [ [ [], @@ -323,9 +301,6 @@ class BackendTest extends TestCase { /** * @dataProvider dataGetUsersForShares - * @param array $shares - * @param array $groups - * @param array $expected */ public function testGetUsersForShares(array $shares, array $groups, array $expected): void { $backend = $this->getBackend(); @@ -356,7 +331,7 @@ class BackendTest extends TestCase { /** * @param string[] $users - * @return IUser[]|MockObject[] + * @return IUser[]&MockObject[] */ protected function getUsers(array $users) { $list = []; @@ -368,7 +343,7 @@ class BackendTest extends TestCase { /** * @param string $uid - * @return IUser|MockObject + * @return IUser&MockObject */ protected function getUserMock($uid) { $user = $this->createMock(IUser::class); diff --git a/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php index a7c84260f21..a31907b4b0a 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/Filter/CalendarTest.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,15 +11,12 @@ use OCA\DAV\CalDAV\Activity\Filter\Calendar; use OCP\Activity\IFilter; use OCP\IL10N; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class CalendarTest extends TestCase { - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - protected $url; - - /** @var IFilter|\PHPUnit\Framework\MockObject\MockObject */ - protected $filter; + protected IURLGenerator&MockObject $url; + protected IFilter $filter; protected function setUp(): void { parent::setUp(); @@ -48,7 +47,7 @@ class CalendarTest extends TestCase { $this->assertEquals('absolute-path-to-icon', $this->filter->getIcon()); } - public function dataFilterTypes() { + public static function dataFilterTypes(): array { return [ [[], []], [['calendar', 'calendar_event'], ['calendar', 'calendar_event']], @@ -62,7 +61,7 @@ class CalendarTest extends TestCase { * @param string[] $types * @param string[] $expected */ - public function testFilterTypes($types, $expected): void { + public function testFilterTypes(array $types, array $expected): void { $this->assertEquals($expected, $this->filter->filterTypes($types)); } } diff --git a/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php index 392759206ed..468dd15f480 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Filter/GenericTest.php +++ b/apps/dav/tests/unit/CalDAV/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 @@ -15,7 +17,7 @@ use Test\TestCase; * @group DB */ class GenericTest extends TestCase { - public function dataFilters() { + public static function dataFilters(): array { return [ [Calendar::class], [Todo::class], @@ -24,18 +26,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()); @@ -43,9 +43,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()); @@ -53,9 +52,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(); @@ -66,9 +64,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()); @@ -77,9 +74,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([])); @@ -87,9 +83,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/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php b/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php index 6aa47f33750..6ef7289e156 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/Filter/TodoTest.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,15 +11,12 @@ use OCA\DAV\CalDAV\Activity\Filter\Todo; use OCP\Activity\IFilter; use OCP\IL10N; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class TodoTest extends TestCase { - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - protected $url; - - /** @var IFilter|\PHPUnit\Framework\MockObject\MockObject */ - protected $filter; + protected IURLGenerator&MockObject $url; + protected IFilter $filter; protected function setUp(): void { parent::setUp(); @@ -48,7 +47,7 @@ class TodoTest extends TestCase { $this->assertEquals('absolute-path-to-icon', $this->filter->getIcon()); } - public function dataFilterTypes() { + public static function dataFilterTypes(): array { return [ [[], []], [['calendar_todo'], ['calendar_todo']], @@ -62,7 +61,7 @@ class TodoTest extends TestCase { * @param string[] $types * @param string[] $expected */ - public function testFilterTypes($types, $expected): void { + public function testFilterTypes(array $types, array $expected): void { $this->assertEquals($expected, $this->filter->filterTypes($types)); } } diff --git a/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php index ba97c888b0c..113af7ed240 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/Provider/BaseTest.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 @@ -7,7 +9,6 @@ namespace OCA\DAV\Tests\unit\CalDAV\Activity\Provider; use OCA\DAV\CalDAV\Activity\Provider\Base; use OCP\Activity\IEvent; -use OCP\Activity\IProvider; use OCP\IGroupManager; use OCP\IL10N; use OCP\IURLGenerator; @@ -16,17 +17,10 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class BaseTest extends TestCase { - /** @var IUserManager|MockObject */ - protected $userManager; - - /** @var IGroupManager|MockObject */ - protected $groupManager; - - /** @var IURLGenerator|MockObject */ - protected $url; - - /** @var IProvider|Base|MockObject */ - protected $provider; + protected IUserManager&MockObject $userManager; + protected IGroupManager&MockObject $groupManager; + protected IURLGenerator&MockObject $url; + protected Base&MockObject $provider; protected function setUp(): void { parent::setUp(); @@ -39,24 +33,21 @@ class BaseTest extends TestCase { $this->groupManager, $this->url, ]) - ->setMethods(['parse']) + ->onlyMethods(['parse']) ->getMock(); } - public function dataSetSubjects() { + public static function dataSetSubjects(): array { return [ - ['abc', [], 'abc'], - ['{actor} created {calendar}', ['actor' => ['name' => 'abc'], 'calendar' => ['name' => 'xyz']], 'abc created xyz'], + ['abc', []], + ['{actor} created {calendar}', ['actor' => ['name' => 'abc'], 'calendar' => ['name' => 'xyz']]], ]; } /** * @dataProvider dataSetSubjects - * @param string $subject - * @param array $parameters - * @param string $parsedSubject */ - public function testSetSubjects(string $subject, array $parameters, string $parsedSubject): void { + public function testSetSubjects(string $subject, array $parameters): void { $event = $this->createMock(IEvent::class); $event->expects($this->once()) ->method('setRichSubject') @@ -68,7 +59,7 @@ class BaseTest extends TestCase { $this->invokePrivate($this->provider, 'setSubjects', [$event, $subject, $parameters]); } - public function dataGenerateCalendarParameter() { + public static function dataGenerateCalendarParameter(): array { return [ [['id' => 23, 'uri' => 'foo', 'name' => 'bar'], 'bar'], [['id' => 42, 'uri' => 'foo', 'name' => 'Personal'], 'Personal'], @@ -79,8 +70,6 @@ class BaseTest extends TestCase { /** * @dataProvider dataGenerateCalendarParameter - * @param array $data - * @param string $name */ public function testGenerateCalendarParameter(array $data, string $name): void { $l = $this->createMock(IL10N::class); @@ -97,7 +86,7 @@ class BaseTest extends TestCase { ], $this->invokePrivate($this->provider, 'generateCalendarParameter', [$data, $l])); } - public function dataGenerateLegacyCalendarParameter() { + public static function dataGenerateLegacyCalendarParameter(): array { return [ [23, 'c1'], [42, 'c2'], @@ -106,8 +95,6 @@ class BaseTest extends TestCase { /** * @dataProvider dataGenerateLegacyCalendarParameter - * @param int $id - * @param string $name */ public function testGenerateLegacyCalendarParameter(int $id, string $name): void { $this->assertEquals([ @@ -117,7 +104,7 @@ class BaseTest extends TestCase { ], $this->invokePrivate($this->provider, 'generateLegacyCalendarParameter', [$id, $name])); } - public function dataGenerateGroupParameter() { + public static function dataGenerateGroupParameter(): array { return [ ['g1'], ['g2'], @@ -126,7 +113,6 @@ class BaseTest extends TestCase { /** * @dataProvider dataGenerateGroupParameter - * @param string $gid */ public function testGenerateGroupParameter(string $gid): void { $this->assertEquals([ diff --git a/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php b/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php index ec237825731..52d3dfa64cb 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/Provider/EventTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,11 +8,9 @@ namespace OCA\DAV\Tests\unit\CalDAV\Activity\Provider; use InvalidArgumentException; -use OCA\DAV\CalDAV\Activity\Provider\Base; use OCA\DAV\CalDAV\Activity\Provider\Event; use OCP\Activity\IEventMerger; use OCP\Activity\IManager; -use OCP\Activity\IProvider; use OCP\App\IAppManager; use OCP\IGroupManager; use OCP\IURLGenerator; @@ -21,30 +21,14 @@ use Test\TestCase; use TypeError; class EventTest extends TestCase { - - /** @var IUserManager|MockObject */ - protected $userManager; - - /** @var IGroupManager|MockObject */ - protected $groupManager; - - /** @var IURLGenerator|MockObject */ - protected $url; - - /** @var IProvider|Base|MockObject */ - protected $provider; - - /** @var IAppManager|MockObject */ - protected $appManager; - - /** @var IFactory|MockObject */ - protected $i10nFactory; - - /** @var IManager|MockObject */ - protected $activityManager; - - /** @var IEventMerger|MockObject */ - protected $eventMerger; + protected IUserManager&MockObject $userManager; + protected IGroupManager&MockObject $groupManager; + protected IURLGenerator&MockObject $url; + protected IAppManager&MockObject $appManager; + protected IFactory&MockObject $i10nFactory; + protected IManager&MockObject $activityManager; + protected IEventMerger&MockObject $eventMerger; + protected Event&MockObject $provider; protected function setUp(): void { parent::setUp(); @@ -65,11 +49,11 @@ class EventTest extends TestCase { $this->eventMerger, $this->appManager ]) - ->setMethods(['parse']) + ->onlyMethods(['parse']) ->getMock(); } - public function dataGenerateObjectParameter() { + public static function dataGenerateObjectParameter(): array { $link = [ 'object_uri' => 'someuuid.ics', 'calendar_uri' => 'personal', @@ -85,21 +69,13 @@ class EventTest extends TestCase { /** * @dataProvider dataGenerateObjectParameter - * @param int $id - * @param string $name - * @param array|null $link - * @param bool $calendarAppEnabled */ public function testGenerateObjectParameter(int $id, string $name, ?array $link, bool $calendarAppEnabled = true): void { $affectedUser = 'otheruser'; if ($link) { $affectedUser = $link['owner']; $generatedLink = [ - 'view' => 'dayGridMonth', - 'timeRange' => 'now', - 'mode' => 'sidebar', 'objectId' => base64_encode('/remote.php/dav/calendars/' . $link['owner'] . '/' . $link['calendar_uri'] . '/' . $link['object_uri']), - 'recurrenceId' => 'next' ]; $this->appManager->expects($this->once()) ->method('isEnabledForUser') @@ -110,7 +86,7 @@ class EventTest extends TestCase { ->method('getWebroot'); $this->url->expects($this->once()) ->method('linkToRouteAbsolute') - ->with('calendar.view.indexview.timerange.edit', $generatedLink) + ->with('calendar.view.indexdirect.edit', $generatedLink) ->willReturn('fullLink'); } } @@ -174,14 +150,12 @@ class EventTest extends TestCase { ]; } - /** @dataProvider generateObjectParameterLinkEncodingDataProvider */ + /** + * @dataProvider generateObjectParameterLinkEncodingDataProvider + */ public function testGenerateObjectParameterLinkEncoding(array $link, string $objectId): void { $generatedLink = [ - 'view' => 'dayGridMonth', - 'timeRange' => 'now', - 'mode' => 'sidebar', 'objectId' => $objectId, - 'recurrenceId' => 'next' ]; $this->appManager->expects($this->once()) ->method('isEnabledForUser') @@ -191,7 +165,7 @@ class EventTest extends TestCase { ->method('getWebroot'); $this->url->expects($this->once()) ->method('linkToRouteAbsolute') - ->with('calendar.view.indexview.timerange.edit', $generatedLink) + ->with('calendar.view.indexdirect.edit', $generatedLink) ->willReturn('fullLink'); $objectParameter = ['id' => 42, 'name' => 'calendar', 'link' => $link]; $result = [ @@ -203,7 +177,7 @@ class EventTest extends TestCase { $this->assertEquals($result, $this->invokePrivate($this->provider, 'generateObjectParameter', [$objectParameter, 'sharee'])); } - public function dataGenerateObjectParameterThrows() { + public static function dataGenerateObjectParameterThrows(): array { return [ ['event', TypeError::class], [['name' => 'event']], @@ -213,10 +187,8 @@ class EventTest extends TestCase { /** * @dataProvider dataGenerateObjectParameterThrows - * @param mixed $eventData - * @param string $exception */ - public function testGenerateObjectParameterThrows($eventData, string $exception = InvalidArgumentException::class): void { + public function testGenerateObjectParameterThrows(string|array $eventData, string $exception = InvalidArgumentException::class): void { $this->expectException($exception); $this->invokePrivate($this->provider, 'generateObjectParameter', [$eventData, 'no_user']); diff --git a/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php b/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php index 42b565b9d8b..2ed3bab02e6 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/Setting/GenericTest.php +++ b/apps/dav/tests/unit/CalDAV/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 @@ -13,7 +15,7 @@ use OCP\Server; use Test\TestCase; class GenericTest extends TestCase { - public function dataSettings() { + public static function dataSettings(): array { return [ [Calendar::class], [Event::class], @@ -23,18 +25,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()); @@ -42,9 +42,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()); @@ -52,9 +51,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(); @@ -65,9 +63,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()); @@ -75,9 +72,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()); @@ -85,9 +81,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()); @@ -95,9 +90,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/dav/tests/unit/CalDAV/AppCalendar/AppCalendarTest.php b/apps/dav/tests/unit/CalDAV/AppCalendar/AppCalendarTest.php index f7fa114ff28..bac2094f734 100644 --- a/apps/dav/tests/unit/CalDAV/AppCalendar/AppCalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/AppCalendar/AppCalendarTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -16,13 +17,13 @@ use Test\TestCase; use function rewind; class AppCalendarTest extends TestCase { - private $principal = 'principals/users/foo'; + private string $principal = 'principals/users/foo'; private AppCalendar $appCalendar; private AppCalendar $writeableAppCalendar; - private ICalendar|MockObject $calendar; - private ICalendar|MockObject $writeableCalendar; + private ICalendar&MockObject $calendar; + private ICalendar&MockObject $writeableCalendar; protected function setUp(): void { parent::setUp(); @@ -53,9 +54,17 @@ class AppCalendarTest extends TestCase { } public function testCreateFile(): void { + $calls = [ + ['some-name', 'data'], + ['other-name', ''], + ['name', 'some data'], + ]; $this->writeableCalendar->expects($this->exactly(3)) ->method('createFromString') - ->withConsecutive(['some-name', 'data'], ['other-name', ''], ['name', 'some data']); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); // pass data $this->assertNull($this->writeableAppCalendar->createFile('some-name', 'data')); diff --git a/apps/dav/tests/unit/CalDAV/AppCalendar/CalendarObjectTest.php b/apps/dav/tests/unit/CalDAV/AppCalendar/CalendarObjectTest.php index a913c2dde6f..3d72d5c97b8 100644 --- a/apps/dav/tests/unit/CalDAV/AppCalendar/CalendarObjectTest.php +++ b/apps/dav/tests/unit/CalDAV/AppCalendar/CalendarObjectTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -17,9 +18,9 @@ use Test\TestCase; class CalendarObjectTest extends TestCase { private CalendarObject $calendarObject; - private AppCalendar|MockObject $calendar; - private ICalendar|MockObject $backend; - private VCalendar|MockObject $vobject; + private AppCalendar&MockObject $calendar; + private ICalendar&MockObject $backend; + private VCalendar&MockObject $vobject; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/BirthdayCalendar/EnablePluginTest.php b/apps/dav/tests/unit/CalDAV/BirthdayCalendar/EnablePluginTest.php index e60efc6fb19..a5811271ce2 100644 --- a/apps/dav/tests/unit/CalDAV/BirthdayCalendar/EnablePluginTest.php +++ b/apps/dav/tests/unit/CalDAV/BirthdayCalendar/EnablePluginTest.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,24 +13,15 @@ use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\CalendarHome; use OCP\IConfig; use OCP\IUser; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class EnablePluginTest extends TestCase { - - /** @var \Sabre\DAV\Server|\PHPUnit\Framework\MockObject\MockObject */ - protected $server; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - - /** @var BirthdayService |\PHPUnit\Framework\MockObject\MockObject */ - protected $birthdayService; - - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ - protected $user; - - /** @var EnablePlugin $plugin */ - protected $plugin; + protected \Sabre\DAV\Server&MockObject $server; + protected IConfig&MockObject $config; + protected BirthdayService&MockObject $birthdayService; + protected IUser&MockObject $user; + protected EnablePlugin $plugin; protected $request; diff --git a/apps/dav/tests/unit/CalDAV/CachedSubscriptionImplTest.php b/apps/dav/tests/unit/CalDAV/CachedSubscriptionImplTest.php index 2378a75a7d5..935d8314f29 100644 --- a/apps/dav/tests/unit/CalDAV/CachedSubscriptionImplTest.php +++ b/apps/dav/tests/unit/CalDAV/CachedSubscriptionImplTest.php @@ -12,13 +12,14 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\CachedSubscription; use OCA\DAV\CalDAV\CachedSubscriptionImpl; use OCA\DAV\CalDAV\CalDavBackend; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class CachedSubscriptionImplTest extends TestCase { - private CachedSubscription $cachedSubscription; + private CachedSubscription&MockObject $cachedSubscription; private array $cachedSubscriptionInfo; + private CalDavBackend&MockObject $backend; private CachedSubscriptionImpl $cachedSubscriptionImpl; - private CalDavBackend $backend; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/CachedSubscriptionObjectTest.php b/apps/dav/tests/unit/CalDAV/CachedSubscriptionObjectTest.php index 56e4930d3b3..03a2c9f20ee 100644 --- a/apps/dav/tests/unit/CalDAV/CachedSubscriptionObjectTest.php +++ b/apps/dav/tests/unit/CalDAV/CachedSubscriptionObjectTest.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 @@ -32,7 +34,7 @@ class CachedSubscriptionObjectTest extends \Test\TestCase { $this->assertEquals('BEGIN...', $calendarObject->get()); } - + public function testPut(): void { $this->expectException(\Sabre\DAV\Exception\MethodNotAllowed::class); $this->expectExceptionMessage('Creating objects in a cached subscription is not allowed'); @@ -52,7 +54,7 @@ class CachedSubscriptionObjectTest extends \Test\TestCase { $calendarObject->put(''); } - + public function testDelete(): void { $this->expectException(\Sabre\DAV\Exception\MethodNotAllowed::class); $this->expectExceptionMessage('Deleting objects in a cached subscription is not allowed'); diff --git a/apps/dav/tests/unit/CalDAV/CachedSubscriptionProviderTest.php b/apps/dav/tests/unit/CalDAV/CachedSubscriptionProviderTest.php index be47b2bf640..58d5ca7835c 100644 --- a/apps/dav/tests/unit/CalDAV/CachedSubscriptionProviderTest.php +++ b/apps/dav/tests/unit/CalDAV/CachedSubscriptionProviderTest.php @@ -12,11 +12,12 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\CachedSubscriptionImpl; use OCA\DAV\CalDAV\CachedSubscriptionProvider; use OCA\DAV\CalDAV\CalDavBackend; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class CachedSubscriptionProviderTest extends TestCase { - private CalDavBackend $backend; + private CalDavBackend&MockObject $backend; private CachedSubscriptionProvider $provider; protected function setUp(): void { diff --git a/apps/dav/tests/unit/CalDAV/CachedSubscriptionTest.php b/apps/dav/tests/unit/CalDAV/CachedSubscriptionTest.php index e1d22bc3e7b..091ee7a341f 100644 --- a/apps/dav/tests/unit/CalDAV/CachedSubscriptionTest.php +++ b/apps/dav/tests/unit/CalDAV/CachedSubscriptionTest.php @@ -140,19 +140,21 @@ class CachedSubscriptionTest extends \Test\TestCase { 'uri' => 'cal', ]; + $calls = [ + [666, 'foo1', 1, [ + 'id' => 99, + 'uri' => 'foo1' + ]], + [666, 'foo2', 1, null], + ]; $backend->expects($this->exactly(2)) ->method('getCalendarObject') - ->withConsecutive( - [666, 'foo1', 1], - [666, 'foo2', 1], - ) - ->willReturnOnConsecutiveCalls( - [ - 'id' => 99, - 'uri' => 'foo1' - ], - null - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $return = array_pop($expected); + $this->assertEquals($expected, func_get_args()); + return $return; + }); $calendar = new CachedSubscription($backend, $calendarInfo); @@ -250,19 +252,21 @@ class CachedSubscriptionTest extends \Test\TestCase { 'uri' => 'cal', ]; + $calls = [ + [666, 'foo1', 1, [ + 'id' => 99, + 'uri' => 'foo1' + ]], + [666, 'foo2', 1, null], + ]; $backend->expects($this->exactly(2)) ->method('getCalendarObject') - ->withConsecutive( - [666, 'foo1', 1], - [666, 'foo2', 1], - ) - ->willReturnOnConsecutiveCalls( - [ - 'id' => 99, - 'uri' => 'foo1' - ], - null - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $return = array_pop($expected); + $this->assertEquals($expected, func_get_args()); + return $return; + }); $calendar = new CachedSubscription($backend, $calendarInfo); diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index 825d798e7e1..f8368660626 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -28,8 +30,6 @@ use function time; * Class CalDavBackendTest * * @group DB - * - * @package OCA\DAV\Tests\unit\CalDAV */ class CalDavBackendTest extends AbstractCalDavBackend { public function testCalendarOperations(): void { @@ -59,7 +59,7 @@ class CalDavBackendTest extends AbstractCalDavBackend { self::assertEmpty($calendars); } - public function providesSharingData() { + public static function providesSharingData(): array { return [ [true, true, true, false, [ [ @@ -458,7 +458,7 @@ EOD; $this->assertNotNull($co); } - public function providesCalendarQueryParameters() { + public static function providesCalendarQueryParameters(): array { return [ 'all' => [[0, 1, 2, 3], [], []], 'only-todos' => [[], ['name' => 'VTODO'], []], @@ -619,7 +619,7 @@ EOD; $this->assertCount(0, $subscriptions); } - public function providesSchedulingData() { + public static function providesSchedulingData(): array { $data = <<<EOS BEGIN:VCALENDAR VERSION:2.0 @@ -725,7 +725,7 @@ EOS; } } - public function providesCalDataForGetDenormalizedData(): array { + public static function providesCalDataForGetDenormalizedData(): array { return [ 'first occurrence before unix epoch starts' => [0, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"], 'no first occurrence because yearly' => [null, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"], @@ -980,7 +980,7 @@ EOD; $this->assertCount($count, $result); } - public function searchDataProvider() { + public static function searchDataProvider(): array { return [ [false, [], 4], [true, ['timerange' => ['start' => new DateTime('2013-09-12 13:00:00'), 'end' => new DateTime('2013-09-12 14:00:00')]], 2], diff --git a/apps/dav/tests/unit/CalDAV/CalendarHomeTest.php b/apps/dav/tests/unit/CalDAV/CalendarHomeTest.php index 9956c17fff3..e25cc099bd6 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarHomeTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarHomeTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -22,21 +24,11 @@ use Sabre\DAV\MkCol; use Test\TestCase; class CalendarHomeTest extends TestCase { - - /** @var CalDavBackend | MockObject */ - private $backend; - - /** @var array */ - private $principalInfo = []; - - /** @var PluginManager */ - private $pluginManager; - - /** @var CalendarHome */ - private $calendarHome; - - /** @var MockObject|LoggerInterface */ - private $logger; + private CalDavBackend&MockObject $backend; + private array $principalInfo = []; + private PluginManager&MockObject $pluginManager; + private LoggerInterface&MockObject $logger; + private CalendarHome $calendarHome; protected function setUp(): void { parent::setUp(); @@ -62,7 +54,7 @@ class CalendarHomeTest extends TestCase { } public function testCreateCalendarValidName(): void { - /** @var MkCol | MockObject $mkCol */ + /** @var MkCol&MockObject $mkCol */ $mkCol = $this->createMock(MkCol::class); $mkCol->method('getResourceType') @@ -82,7 +74,7 @@ class CalendarHomeTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\MethodNotAllowed::class); $this->expectExceptionMessage('The resource you tried to create has a reserved name'); - /** @var MkCol | MockObject $mkCol */ + /** @var MkCol&MockObject $mkCol */ $mkCol = $this->createMock(MkCol::class); $this->calendarHome->createExtendedCollection('contact_birthdays', $mkCol); @@ -92,7 +84,7 @@ class CalendarHomeTest extends TestCase { $this->expectException(\Sabre\DAV\Exception\MethodNotAllowed::class); $this->expectExceptionMessage('The resource you tried to create has a reserved name'); - /** @var MkCol | MockObject $mkCol */ + /** @var MkCol&MockObject $mkCol */ $mkCol = $this->createMock(MkCol::class); $this->calendarHome->createExtendedCollection('app-generated--example--foo-1', $mkCol); diff --git a/apps/dav/tests/unit/CalDAV/CalendarImplTest.php b/apps/dav/tests/unit/CalDAV/CalendarImplTest.php index 0d5223739f3..88b04326cc9 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarImplTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarImplTest.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,11 +23,10 @@ use Sabre\VObject\ITip\Message; use Sabre\VObject\Reader; class CalendarImplTest extends \Test\TestCase { - - private Calendar|MockObject $calendar; + private Calendar&MockObject $calendar; private array $calendarInfo; - private CalDavBackend|MockObject $backend; - private CalendarImpl|MockObject $calendarImpl; + private CalDavBackend&MockObject $backend; + private CalendarImpl $calendarImpl; private array $mockExportCollection; protected function setUp(): void { @@ -299,7 +300,7 @@ EOF; foreach ($this->calendarImpl->export(null) as $entry) { $exported[] = $entry; } - + // Assert $this->assertCount(1, $exported, 'Invalid exported items count'); } diff --git a/apps/dav/tests/unit/CalDAV/CalendarManagerTest.php b/apps/dav/tests/unit/CalDAV/CalendarManagerTest.php index 63d92dff40d..e8159ffe07c 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarManagerTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarManagerTest.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 @@ -16,20 +18,11 @@ use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class CalendarManagerTest extends \Test\TestCase { - /** @var CalDavBackend | MockObject */ - private $backend; - - /** @var IL10N | MockObject */ - private $l10n; - - /** @var IConfig|MockObject */ - private $config; - - /** @var CalendarManager */ - private $manager; - - /** @var MockObject|LoggerInterface */ - private $logger; + private CalDavBackend&MockObject $backend; + private IL10N&MockObject $l10n; + private IConfig&MockObject $config; + private LoggerInterface&MockObject $logger; + private CalendarManager $manager; protected function setUp(): void { parent::setUp(); @@ -54,7 +47,7 @@ class CalendarManagerTest extends \Test\TestCase { ['id' => 456, 'uri' => 'blablub2'], ]); - /** @var IManager | MockObject $calendarManager */ + /** @var IManager&MockObject $calendarManager */ $calendarManager = $this->createMock(Manager::class); $registeredIds = []; $calendarManager->expects($this->exactly(2)) diff --git a/apps/dav/tests/unit/CalDAV/CalendarTest.php b/apps/dav/tests/unit/CalDAV/CalendarTest.php index 7f2d0052162..0eff72c5c3d 100644 --- a/apps/dav/tests/unit/CalDAV/CalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/CalendarTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -18,20 +20,13 @@ use Sabre\VObject\Reader; use Test\TestCase; class CalendarTest extends TestCase { - - /** @var IL10N */ - protected $l10n; - - /** @var IConfig */ - protected $config; - - /** @var MockObject|LoggerInterface */ - protected $logger; + protected IL10N&MockObject $l10n; + protected IConfig&MockObject $config; + protected LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); - $this->l10n = $this->getMockBuilder(IL10N::class) - ->disableOriginalConstructor()->getMock(); + $this->l10n = $this->createMock(IL10N::class); $this->config = $this->createMock(IConfig::class); $this->logger = $this->createMock(LoggerInterface::class); $this->l10n @@ -80,7 +75,7 @@ class CalendarTest extends TestCase { } public function testDeleteOwn(): void { - /** @var MockObject | CalDavBackend $backend */ + /** @var CalDavBackend&MockObject $backend */ $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->never())->method('updateShares'); $backend->expects($this->never())->method('getShares'); @@ -101,7 +96,7 @@ class CalendarTest extends TestCase { } public function testDeleteBirthdayCalendar(): void { - /** @var MockObject | CalDavBackend $backend */ + /** @var CalDavBackend&MockObject $backend */ $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->once())->method('deleteCalendar') ->with(666); @@ -122,7 +117,7 @@ class CalendarTest extends TestCase { $c->delete(); } - public function dataPropPatch() { + public static function dataPropPatch(): array { return [ ['user1', 'user2', [], true], ['user1', 'user2', [ @@ -152,9 +147,9 @@ class CalendarTest extends TestCase { /** * @dataProvider dataPropPatch */ - public function testPropPatch($ownerPrincipal, $principalUri, $mutations, $shared): void { - /** @var MockObject | CalDavBackend $backend */ - $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); + public function testPropPatch(string $ownerPrincipal, string $principalUri, array $mutations, bool $shared): void { + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); $calendarInfo = [ '{http://owncloud.org/ns}owner-principal' => $ownerPrincipal, 'principaluri' => $principalUri, @@ -177,8 +172,8 @@ class CalendarTest extends TestCase { * @dataProvider providesReadOnlyInfo */ public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet, $uri = 'default'): void { - /** @var MockObject | CalDavBackend $backend */ - $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1); $calendarInfo = [ 'principaluri' => 'user2', @@ -263,7 +258,7 @@ class CalendarTest extends TestCase { $this->assertEquals($expectedAcl, $childAcl); } - public function providesReadOnlyInfo() { + public static function providesReadOnlyInfo(): array { return [ 'read-only property not set' => [true, null, true], 'read-only property is false' => [true, false, true], @@ -277,16 +272,14 @@ class CalendarTest extends TestCase { /** * @dataProvider providesConfidentialClassificationData - * @param int $expectedChildren - * @param bool $isShared */ - public function testPrivateClassification($expectedChildren, $isShared): void { + public function testPrivateClassification(int $expectedChildren, bool $isShared): void { $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC]; $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL]; $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE]; - /** @var MockObject | CalDavBackend $backend */ - $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->any())->method('getCalendarObjects')->willReturn([ $calObject0, $calObject1, $calObject2 ]); @@ -319,10 +312,8 @@ class CalendarTest extends TestCase { /** * @dataProvider providesConfidentialClassificationData - * @param int $expectedChildren - * @param bool $isShared */ - public function testConfidentialClassification($expectedChildren, $isShared): void { + public function testConfidentialClassification(int $expectedChildren, bool $isShared): void { $start = '20160609'; $end = '20160610'; @@ -372,8 +363,8 @@ EOD; $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData]; $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE]; - /** @var MockObject | CalDavBackend $backend */ - $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); + /** @var CalDavBackend&MockObject $backend */ + $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->any())->method('getCalendarObjects')->willReturn([ $calObject0, $calObject1, $calObject2 ]); @@ -437,7 +428,7 @@ EOD; } } - public function providesConfidentialClassificationData() { + public static function providesConfidentialClassificationData(): array { return [ [3, false], [2, true] @@ -540,7 +531,7 @@ EOD; 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $confidentialObjectData]; - /** @var MockObject | CalDavBackend $backend */ + /** @var CalDavBackend&MockObject $backend */ $backend = $this->createMock(CalDavBackend::class); $backend->expects($this->any()) ->method('getCalendarObjects') @@ -619,7 +610,7 @@ EOD; $this->fixLinebreak($confidentialObjectCleaned)); } - private function fixLinebreak($str) { + private function fixLinebreak(string $str): string { return preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $str); } } diff --git a/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php b/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php index 43a7180647f..90b6f9ec0db 100644 --- a/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/EventComparisonServiceTest.php @@ -14,8 +14,7 @@ use Sabre\VObject\Component\VCalendar; use Test\TestCase; class EventComparisonServiceTest extends TestCase { - /** @var EventComparisonService */ - private $eventComparisonService; + private EventComparisonService $eventComparisonService; protected function setUp(): void { $this->eventComparisonService = new EventComparisonService(); diff --git a/apps/dav/tests/unit/CalDAV/Export/ExportServiceTest.php b/apps/dav/tests/unit/CalDAV/Export/ExportServiceTest.php index f1e049c4a80..838dfc18f2f 100644 --- a/apps/dav/tests/unit/CalDAV/Export/ExportServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Export/ExportServiceTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -14,10 +16,9 @@ use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCalendar; class ExportServiceTest extends \Test\TestCase { - - private ServerVersion|MockObject $serverVersion; + private ServerVersion&MockObject $serverVersion; private ExportService $service; - private ICalendarExport|MockObject $calendar; + private ICalendarExport&MockObject $calendar; private array $mockExportCollection; protected function setUp(): void { @@ -36,7 +37,7 @@ class ExportServiceTest extends \Test\TestCase { yield $entry; } } - + public function testExport(): void { // Arrange // construct calendar with a 1 hour event and same start/end time zones diff --git a/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php b/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php index 778df5697f0..67b2ff3555a 100644 --- a/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,10 +8,11 @@ namespace OCA\DAV\Tests\unit\CalDAV\Integration; use OCA\DAV\CalDAV\Integration\ExternalCalendar; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class ExternalCalendarTest extends TestCase { - private $abstractExternalCalendar; + private ExternalCalendar&MockObject $abstractExternalCalendar; protected function setUp(): void { parent::setUp(); @@ -39,7 +42,7 @@ class ExternalCalendarTest extends TestCase { $this->abstractExternalCalendar->setName('other-name'); } - public function createDirectory():void { + public function createDirectory(): void { // Check that the method is final and can't be overridden by other classes $reflectionMethod = new \ReflectionMethod(ExternalCalendar::class, 'createDirectory'); $this->assertTrue($reflectionMethod->isFinal()); @@ -73,7 +76,7 @@ class ExternalCalendarTest extends TestCase { ExternalCalendar::splitAppGeneratedCalendarUri($name); } - public function splitAppGeneratedCalendarUriDataProvider():array { + public static function splitAppGeneratedCalendarUriDataProvider():array { return [ ['personal'], ['foo_shared_by_admin'], diff --git a/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php index b55359cd208..3ba0b832593 100644 --- a/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php +++ b/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -15,20 +17,11 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class CalendarPublicationListenerTest extends TestCase { - - /** @var Backend|MockObject */ - private $activityBackend; - - /** @var LoggerInterface|MockObject */ - private $logger; - + private Backend&MockObject $activityBackend; + private LoggerInterface&MockObject $logger; private CalendarPublicationListener $calendarPublicationListener; - - /** @var CalendarPublishedEvent|MockObject */ - private $publicationEvent; - - /** @var CalendarUnpublishedEvent|MockObject */ - private $unpublicationEvent; + private CalendarPublishedEvent&MockObject $publicationEvent; + private CalendarUnpublishedEvent&MockObject $unpublicationEvent; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php index b8414ecd695..d5697a862db 100644 --- a/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php +++ b/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -14,17 +16,10 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class CalendarShareUpdateListenerTest extends TestCase { - - /** @var Backend|MockObject */ - private $activityBackend; - - /** @var LoggerInterface|MockObject */ - private $logger; - + private Backend&MockObject $activityBackend; + private LoggerInterface&MockObject $logger; private CalendarShareUpdateListener $calendarPublicationListener; - - /** @var CalendarShareUpdatedEvent|MockObject */ - private $event; + private CalendarShareUpdatedEvent&MockObject $event; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php index 589e659b9ea..cbfdfd6b9b7 100644 --- a/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php +++ b/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -18,26 +20,13 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class SubscriptionListenerTest extends TestCase { - - /** @var RefreshWebcalService|MockObject */ - private $refreshWebcalService; - - /** @var Backend|MockObject */ - private $reminderBackend; - - /** @var IJobList|MockObject */ - private $jobList; - - /** @var LoggerInterface|MockObject */ - private $logger; - + private RefreshWebcalService&MockObject $refreshWebcalService; + private Backend&MockObject $reminderBackend; + private IJobList&MockObject $jobList; + private LoggerInterface&MockObject $logger; private SubscriptionListener $calendarPublicationListener; - - /** @var SubscriptionCreatedEvent|MockObject */ - private $subscriptionCreatedEvent; - - /** @var SubscriptionDeletedEvent|MockObject */ - private $subscriptionDeletedEvent; + private SubscriptionCreatedEvent&MockObject $subscriptionCreatedEvent; + private SubscriptionDeletedEvent&MockObject $subscriptionDeletedEvent; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/OutboxTest.php b/apps/dav/tests/unit/CalDAV/OutboxTest.php index def2bd80157..cc0a3f0405f 100644 --- a/apps/dav/tests/unit/CalDAV/OutboxTest.php +++ b/apps/dav/tests/unit/CalDAV/OutboxTest.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,12 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\Outbox; use OCP\IConfig; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class OutboxTest extends TestCase { - - /** @var IConfig */ - private $config; - - /** @var Outbox */ - private $outbox; + private IConfig&MockObject $config; + private Outbox $outbox; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/PluginTest.php b/apps/dav/tests/unit/CalDAV/PluginTest.php index 0915fdf2646..647e4b0da81 100644 --- a/apps/dav/tests/unit/CalDAV/PluginTest.php +++ b/apps/dav/tests/unit/CalDAV/PluginTest.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,8 +11,7 @@ use OCA\DAV\CalDAV\Plugin; use Test\TestCase; class PluginTest extends TestCase { - /** @var Plugin */ - private $plugin; + private Plugin $plugin; protected function setUp(): void { parent::setUp(); @@ -18,7 +19,7 @@ class PluginTest extends TestCase { $this->plugin = new Plugin(); } - public function linkProvider() { + public static function linkProvider(): array { return [ [ 'principals/users/MyUserName', @@ -37,11 +38,8 @@ class PluginTest extends TestCase { /** * @dataProvider linkProvider - * - * @param $input - * @param $expected */ - public function testGetCalendarHomeForPrincipal($input, $expected): void { + public function testGetCalendarHomeForPrincipal(string $input, string $expected): void { $this->assertSame($expected, $this->plugin->getCalendarHomeForPrincipal($input)); } diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php index 075681eff7f..6acceed6f64 100644 --- a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.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,6 +20,7 @@ use OCP\IL10N; use OCP\IUserManager; use OCP\Security\ISecureRandom; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; @@ -30,25 +33,15 @@ use Test\TestCase; */ class PublicCalendarRootTest extends TestCase { public const UNIT_TEST_USER = ''; - /** @var CalDavBackend */ - private $backend; - /** @var PublicCalendarRoot */ - private $publicCalendarRoot; - /** @var IL10N */ - private $l10n; - /** @var Principal|\PHPUnit\Framework\MockObject\MockObject */ - private $principal; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $groupManager; - /** @var IConfig */ - protected $config; - - /** @var ISecureRandom */ - private $random; - /** @var LoggerInterface */ - private $logger; + private CalDavBackend $backend; + private PublicCalendarRoot $publicCalendarRoot; + private IL10N&MockObject $l10n; + private Principal&MockObject $principal; + protected IUserManager&MockObject $userManager; + protected IGroupManager&MockObject $groupManager; + protected IConfig&MockObject $config; + private ISecureRandom $random; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); @@ -82,8 +75,7 @@ class PublicCalendarRootTest extends TestCase { $sharingBackend, false, ); - $this->l10n = $this->getMockBuilder(IL10N::class) - ->disableOriginalConstructor()->getMock(); + $this->l10n = $this->createMock(IL10N::class); $this->config = $this->createMock(IConfig::class); $this->publicCalendarRoot = new PublicCalendarRoot($this->backend, @@ -134,10 +126,7 @@ class PublicCalendarRootTest extends TestCase { $this->assertSame([], $calendarResults); } - /** - * @return Calendar - */ - protected function createPublicCalendar() { + protected function createPublicCalendar(): Calendar { $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', []); $calendarInfo = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER)[0]; diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarTest.php index 0609892c279..7e8f714ef42 100644 --- a/apps/dav/tests/unit/CalDAV/PublicCalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarTest.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 @@ -16,15 +18,13 @@ class PublicCalendarTest extends CalendarTest { /** * @dataProvider providesConfidentialClassificationData - * @param int $expectedChildren - * @param bool $isShared */ - public function testPrivateClassification($expectedChildren, $isShared): void { + public function testPrivateClassification(int $expectedChildren, bool $isShared): void { $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC]; $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL]; $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE]; - /** @var MockObject | CalDavBackend $backend */ + /** @var CalDavBackend&MockObject $backend */ $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); $backend->expects($this->any())->method('getCalendarObjects')->willReturn([ $calObject0, $calObject1, $calObject2 @@ -44,9 +44,9 @@ class PublicCalendarTest extends CalendarTest { 'id' => 666, 'uri' => 'cal', ]; - /** @var MockObject | IConfig $config */ + /** @var IConfig&MockObject $config */ $config = $this->createMock(IConfig::class); - /** @var MockObject | LoggerInterface $logger */ + /** @var LoggerInterface&MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $c = new PublicCalendar($backend, $calendarInfo, $this->l10n, $config, $logger); $children = $c->getChildren(); @@ -59,10 +59,8 @@ class PublicCalendarTest extends CalendarTest { /** * @dataProvider providesConfidentialClassificationData - * @param int $expectedChildren - * @param bool $isShared */ - public function testConfidentialClassification($expectedChildren, $isShared): void { + public function testConfidentialClassification(int $expectedChildren, bool $isShared): void { $start = '20160609'; $end = '20160610'; @@ -112,7 +110,7 @@ EOD; $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData]; $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE]; - /** @var MockObject | CalDavBackend $backend */ + /** @var CalDavBackend&MockObject $backend */ $backend = $this->getMockBuilder(CalDavBackend::class)->disableOriginalConstructor()->getMock(); $backend->expects($this->any())->method('getCalendarObjects')->willReturn([ $calObject0, $calObject1, $calObject2 @@ -132,9 +130,9 @@ EOD; 'id' => 666, 'uri' => 'cal', ]; - /** @var MockObject | IConfig $config */ + /** @var IConfig&MockObject $config */ $config = $this->createMock(IConfig::class); - /** @var MockObject | LoggerInterface $logger */ + /** @var LoggerInterface&MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $c = new PublicCalendar($backend, $calendarInfo, $this->l10n, $config, $logger); diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php index 769e1537646..5344ec5d7cd 100644 --- a/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.php +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublisherTest.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 @@ -43,9 +45,9 @@ class PublisherTest extends TestCase { } - protected $elementMap = []; - protected $namespaceMap = ['DAV:' => 'd']; - protected $contextUri = '/'; + protected array $elementMap = []; + protected array $namespaceMap = ['DAV:' => 'd']; + protected string $contextUri = '/'; private function write($input) { $writer = new Writer(); diff --git a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php index 8aecdf7f0dd..c66a3639040 100644 --- a/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.php +++ b/apps/dav/tests/unit/CalDAV/Publishing/PublishingTest.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 @@ -10,6 +12,7 @@ use OCA\DAV\CalDAV\Publishing\PublishPlugin; use OCP\IConfig; use OCP\IRequest; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\Server; use Sabre\DAV\SimpleCollection; use Sabre\HTTP\Request; @@ -17,31 +20,21 @@ use Sabre\HTTP\Response; use Test\TestCase; class PublishingTest extends TestCase { - - /** @var PublishPlugin */ - private $plugin; - /** @var Server */ - private $server; - /** @var Calendar | \PHPUnit\Framework\MockObject\MockObject */ - private $book; - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; + private PublishPlugin $plugin; + private Server $server; + private Calendar&MockObject $book; + private IConfig&MockObject $config; + private IURLGenerator&MockObject $urlGenerator; protected function setUp(): void { parent::setUp(); - $this->config = $this->getMockBuilder(IConfig::class)-> - disableOriginalConstructor()-> - getMock(); + $this->config = $this->createMock(IConfig::class); $this->config->expects($this->any())->method('getSystemValue') ->with($this->equalTo('secret')) ->willReturn('mysecret'); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)-> - disableOriginalConstructor()-> - getMock(); + $this->urlGenerator = $this->createMock(IURLGenerator::class); /** @var IRequest $request */ $this->plugin = new PublishPlugin($this->config, $this->urlGenerator); diff --git a/apps/dav/tests/unit/CalDAV/Reminder/BackendTest.php b/apps/dav/tests/unit/CalDAV/Reminder/BackendTest.php index e1a0485f8a9..356acf2dd7f 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/BackendTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/BackendTest.php @@ -10,27 +10,20 @@ namespace OCA\DAV\Tests\unit\CalDAV\Reminder; use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend; use OCP\AppFramework\Utility\ITimeFactory; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class BackendTest extends TestCase { - - /** - * Reminder Backend - * - * @var ReminderBackend|\PHPUnit\Framework\MockObject\MockObject - */ - private $reminderBackend; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; + private ReminderBackend $reminderBackend; + private ITimeFactory&MockObject $timeFactory; protected function setUp(): void { parent::setUp(); $query = self::$realDatabase->getQueryBuilder(); - $query->delete('calendar_reminders')->execute(); - $query->delete('calendarobjects')->execute(); - $query->delete('calendars')->execute(); + $query->delete('calendar_reminders')->executeStatement(); + $query->delete('calendarobjects')->executeStatement(); + $query->delete('calendars')->executeStatement(); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->reminderBackend = new ReminderBackend(self::$realDatabase, $this->timeFactory); @@ -40,9 +33,11 @@ class BackendTest extends TestCase { protected function tearDown(): void { $query = self::$realDatabase->getQueryBuilder(); - $query->delete('calendar_reminders')->execute(); - $query->delete('calendarobjects')->execute(); - $query->delete('calendars')->execute(); + $query->delete('calendar_reminders')->executeStatement(); + $query->delete('calendarobjects')->executeStatement(); + $query->delete('calendars')->executeStatement(); + + parent::tearDown(); } @@ -235,7 +230,7 @@ class BackendTest extends TestCase { $query = self::$realDatabase->getQueryBuilder(); $rows = $query->select('*') ->from('calendar_reminders') - ->execute() + ->executeQuery() ->fetchAll(); $this->assertCount(4, $rows); @@ -251,7 +246,7 @@ class BackendTest extends TestCase { $row = $query->select('notification_date') ->from('calendar_reminders') ->where($query->expr()->eq('id', $query->createNamedParameter($reminderId))) - ->execute() + ->executeQuery() ->fetch(); $this->assertEquals((int)$row['notification_date'], 123700); @@ -266,7 +261,7 @@ class BackendTest extends TestCase { 'principaluri' => $query->createNamedParameter('principals/users/user001'), 'displayname' => $query->createNamedParameter('Displayname 123'), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendars') @@ -275,7 +270,7 @@ class BackendTest extends TestCase { 'principaluri' => $query->createNamedParameter('principals/users/user002'), 'displayname' => $query->createNamedParameter('Displayname 99'), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendarobjects') @@ -285,7 +280,7 @@ class BackendTest extends TestCase { 'calendarid' => $query->createNamedParameter(1), 'size' => $query->createNamedParameter(42), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendarobjects') @@ -295,7 +290,7 @@ class BackendTest extends TestCase { 'calendarid' => $query->createNamedParameter(1), 'size' => $query->createNamedParameter(42), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendarobjects') @@ -305,7 +300,7 @@ class BackendTest extends TestCase { 'calendarid' => $query->createNamedParameter(99), 'size' => $query->createNamedParameter(42), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendar_reminders') @@ -323,7 +318,7 @@ class BackendTest extends TestCase { 'notification_date' => $query->createNamedParameter(123456), 'is_repeat_based' => $query->createNamedParameter(0), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendar_reminders') @@ -341,7 +336,7 @@ class BackendTest extends TestCase { 'notification_date' => $query->createNamedParameter(123456), 'is_repeat_based' => $query->createNamedParameter(0), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendar_reminders') @@ -359,7 +354,7 @@ class BackendTest extends TestCase { 'notification_date' => $query->createNamedParameter(123499), 'is_repeat_based' => $query->createNamedParameter(0), ]) - ->execute(); + ->executeStatement(); $query = self::$realDatabase->getQueryBuilder(); $query->insert('calendar_reminders') @@ -377,6 +372,6 @@ class BackendTest extends TestCase { 'notification_date' => $query->createNamedParameter(123600), 'is_repeat_based' => $query->createNamedParameter(0), ]) - ->execute(); + ->executeStatement(); } } diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/AbstractNotificationProviderTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/AbstractNotificationProviderTestCase.php index 60ef1df43d5..70b374298ea 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/AbstractNotificationProviderTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/AbstractNotificationProviderTestCase.php @@ -14,44 +14,21 @@ use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUser; use OCP\L10N\IFactory as L10NFactory; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\VObject\Component\VCalendar; use Test\TestCase; -abstract class AbstractNotificationProviderTest extends TestCase { - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - - /** @var L10NFactory|\PHPUnit\Framework\MockObject\MockObject */ - protected $l10nFactory; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - protected $l10n; - - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ - protected $urlGenerator; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - protected $config; - - /** @var AbstractProvider|\PHPUnit\Framework\MockObject\MockObject */ - protected $provider; - - /** - * @var VCalendar - */ - protected $vcalendar; - - /** - * @var string - */ - protected $calendarDisplayName; - - /** - * @var IUser|\PHPUnit\Framework\MockObject\MockObject - */ - protected $user; +abstract class AbstractNotificationProviderTestCase extends TestCase { + protected LoggerInterface&MockObject $logger; + protected L10NFactory&MockObject $l10nFactory; + protected IL10N&MockObject $l10n; + protected IURLGenerator&MockObject $urlGenerator; + protected IConfig&MockObject $config; + protected AbstractProvider $provider; + protected VCalendar $vcalendar; + protected string $calendarDisplayName; + protected IUser&MockObject $user; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php index 42eb0b0faa3..f7fbac2c407 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/EmailProviderTest.php @@ -18,11 +18,9 @@ use OCP\Util; use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCalendar; -class EmailProviderTest extends AbstractNotificationProviderTest { +class EmailProviderTest extends AbstractNotificationProviderTestCase { public const USER_EMAIL = 'frodo@hobb.it'; - - /** @var IMailer|MockObject */ - private $mailer; + private IMailer&MockObject $mailer; protected function setUp(): void { parent::setUp(); @@ -97,18 +95,12 @@ class EmailProviderTest extends AbstractNotificationProviderTest { $this->mailer->expects($this->exactly(4)) ->method('validateMailAddress') - ->withConsecutive( - ['uid1@example.com'], - ['uid2@example.com'], - ['uid3@example.com'], - ['invalid'], - ) - ->willReturnOnConsecutiveCalls( - true, - true, - true, - false, - ); + ->willReturnMap([ + ['uid1@example.com', true], + ['uid2@example.com', true], + ['uid3@example.com', true], + ['invalid', false], + ]); $this->mailer->expects($this->exactly(3)) ->method('createMessage') @@ -119,14 +111,18 @@ class EmailProviderTest extends AbstractNotificationProviderTest { $message22 ); - $this->mailer->expects($this->exactly(3)) + $calls = [ + [$message11], + [$message21], + [$message22], + ]; + $this->mailer->expects($this->exactly(count($calls))) ->method('send') - ->withConsecutive( - [$message11], - [$message21], - [$message22], - ) - ->willReturn([]); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return []; + }); $this->setupURLGeneratorMock(2); @@ -215,16 +211,22 @@ class EmailProviderTest extends AbstractNotificationProviderTest { $message22, $message23, ); - $this->mailer->expects($this->exactly(6)) + + $calls = [ + [$message11], + [$message12], + [$message13], + [$message21], + [$message22], + [$message23], + ]; + $this->mailer->expects($this->exactly(count($calls))) ->method('send') - ->withConsecutive( - [$message11], - [$message12], - [$message13], - [$message21], - [$message22], - [$message23], - )->willReturn([]); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return []; + }); $this->setupURLGeneratorMock(2); $vcalendar = $this->getAttendeeVCalendar(); @@ -293,12 +295,18 @@ class EmailProviderTest extends AbstractNotificationProviderTest { $message12, $message13, ); - $this->mailer->expects($this->exactly(2)) + + $calls = [ + [$message12], + [$message13], + ]; + $this->mailer->expects($this->exactly(count($calls))) ->method('send') - ->withConsecutive( - [$message12], - [$message13], - )->willReturn([]); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return []; + }); $this->setupURLGeneratorMock(1); $vcalendar = $this->getAttendeeVCalendar(); diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/PushProviderTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/PushProviderTest.php index b090fa0e5e7..c601463363b 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/PushProviderTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProvider/PushProviderTest.php @@ -13,13 +13,11 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\IUser; use OCP\Notification\IManager; use OCP\Notification\INotification; +use PHPUnit\Framework\MockObject\MockObject; -class PushProviderTest extends AbstractNotificationProviderTest { - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $manager; - - /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $timeFactory; +class PushProviderTest extends AbstractNotificationProviderTestCase { + private IManager&MockObject $manager; + private ITimeFactory&MockObject $timeFactory; protected function setUp(): void { parent::setUp(); @@ -96,20 +94,23 @@ class PushProviderTest extends AbstractNotificationProviderTest { $this->manager->expects($this->exactly(3)) ->method('createNotification') - ->with() ->willReturnOnConsecutiveCalls( $notification1, $notification2, $notification3 ); + $calls = [ + $notification1, + $notification2, + $notification3, + ]; $this->manager->expects($this->exactly(3)) ->method('notify') - ->withConsecutive( - [$notification1], - [$notification2], - [$notification3], - ); + ->willReturnCallback(function ($notification) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, $notification); + }); $this->provider->send($this->vcalendar->VEVENT, $this->calendarDisplayName, [], $users); } diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProviderManagerTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProviderManagerTest.php index 6d0e62f505b..6b813ed0228 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotificationProviderManagerTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotificationProviderManagerTest.php @@ -21,9 +21,7 @@ use Test\TestCase; * @group DB */ class NotificationProviderManagerTest extends TestCase { - - /** @var NotificationProviderManager|\PHPUnit\Framework\MockObject\MockObject */ - private $providerManager; + private NotificationProviderManager $providerManager; /** * @throws QueryException diff --git a/apps/dav/tests/unit/CalDAV/Reminder/NotifierTest.php b/apps/dav/tests/unit/CalDAV/Reminder/NotifierTest.php index dcf11a1a6b8..147446152d8 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/NotifierTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/NotifierTest.php @@ -21,20 +21,11 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class NotifierTest extends TestCase { - /** @var Notifier */ - protected $notifier; - - /** @var IFactory|MockObject */ - protected $factory; - - /** @var IURLGenerator|MockObject */ - protected $urlGenerator; - - /** @var IL10N|MockObject */ - protected $l10n; - - /** @var ITimeFactory|MockObject */ - protected $timeFactory; + protected IFactory&MockObject $factory; + protected IURLGenerator&MockObject $urlGenerator; + protected IL10N&MockObject $l10n; + protected ITimeFactory&MockObject $timeFactory; + protected Notifier $notifier; protected function setUp(): void { parent::setUp(); @@ -92,7 +83,7 @@ class NotifierTest extends TestCase { $this->expectException(UnknownNotificationException::class); $this->expectExceptionMessage('Notification not from this app'); - /** @var INotification|MockObject $notification */ + /** @var INotification&MockObject $notification */ $notification = $this->createMock(INotification::class); $notification->expects($this->once()) @@ -109,7 +100,7 @@ class NotifierTest extends TestCase { $this->expectException(UnknownNotificationException::class); $this->expectExceptionMessage('Unknown subject'); - /** @var INotification|MockObject $notification */ + /** @var INotification&MockObject $notification */ $notification = $this->createMock(INotification::class); $notification->expects($this->once()) @@ -130,7 +121,7 @@ class NotifierTest extends TestCase { return $d1->diff($d2)->y < 0; } - public function dataPrepare(): array { + public static function dataPrepare(): array { return [ [ 'calendar_reminder', @@ -181,16 +172,9 @@ class NotifierTest extends TestCase { /** * @dataProvider dataPrepare - * - * @param string $subjectType - * @param array $subjectParams - * @param string $subject - * @param array $messageParams - * @param string $message - * @throws \Exception */ public function testPrepare(string $subjectType, array $subjectParams, string $subject, array $messageParams, string $message): void { - /** @var INotification|MockObject $notification */ + /** @var INotification&MockObject $notification */ $notification = $this->createMock(INotification::class); $notification->expects($this->once()) @@ -235,7 +219,7 @@ class NotifierTest extends TestCase { } public function testPassedEvent(): void { - /** @var INotification|MockObject $notification */ + /** @var INotification&MockObject $notification */ $notification = $this->createMock(INotification::class); $notification->expects($this->once()) diff --git a/apps/dav/tests/unit/CalDAV/Reminder/ReminderServiceTest.php b/apps/dav/tests/unit/CalDAV/Reminder/ReminderServiceTest.php index 198c8d97b12..4b6735ee297 100644 --- a/apps/dav/tests/unit/CalDAV/Reminder/ReminderServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Reminder/ReminderServiceTest.php @@ -26,35 +26,16 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class ReminderServiceTest extends TestCase { - /** @var Backend|MockObject */ - private $backend; - - /** @var NotificationProviderManager|MockObject */ - private $notificationProviderManager; - - /** @var IUserManager|MockObject */ - private $userManager; - - /** @var IGroupManager|MockObject */ - private $groupManager; - - /** @var CalDavBackend|MockObject */ - private $caldavBackend; - - /** @var ITimeFactory|MockObject */ - private $timeFactory; - - /** @var IConfig|MockObject */ - private $config; - - /** @var ReminderService */ - private $reminderService; - - /** @var MockObject|LoggerInterface */ - private $logger; - - /** @var MockObject|Principal */ - private $principalConnector; + private Backend&MockObject $backend; + private NotificationProviderManager&MockObject $notificationProviderManager; + private IUserManager&MockObject $userManager; + private IGroupManager&MockObject $groupManager; + private CalDavBackend&MockObject $caldavBackend; + private ITimeFactory&MockObject $timeFactory; + private IConfig&MockObject $config; + private LoggerInterface&MockObject $logger; + private Principal&MockObject $principalConnector; + private ReminderService $reminderService; public const CALENDAR_DATA = <<<EOD BEGIN:VCALENDAR @@ -252,9 +233,7 @@ END:VTIMEZONE END:VCALENDAR ICS; - - /** @var null|string */ - private $oldTimezone; + private ?string $oldTimezone; protected function setUp(): void { parent::setUp(); @@ -305,13 +284,17 @@ ICS; 'component' => 'vevent', ]; - $this->backend->expects($this->exactly(2)) + $calls = [ + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'de919af7429d3b5c11e8b9d289b411a6', 'EMAIL', true, 1465429500, false], + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', '35b3eae8e792aa2209f0b4e1a302f105', 'DISPLAY', false, 1465344000, false] + ]; + $this->backend->expects($this->exactly(count($calls))) ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'de919af7429d3b5c11e8b9d289b411a6', 'EMAIL', true, 1465429500, false], - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', '35b3eae8e792aa2209f0b4e1a302f105', 'DISPLAY', false, 1465344000, false] - ) - ->willReturn(1); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return 1; + }); $this->timeFactory->expects($this->once()) ->method('getDateTime') @@ -353,12 +336,7 @@ EOD; ]; $this->backend->expects($this->never()) - ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', false, null, false, '5c70531aab15c92b52518ae10a2f78a4', 'de919af7429d3b5c11e8b9d289b411a6', 'EMAIL', true, 1465429500, false], - [1337, 42, 'wej2z68l9h', false, null, false, '5c70531aab15c92b52518ae10a2f78a4', '35b3eae8e792aa2209f0b4e1a302f105', 'DISPLAY', false, 1465344000, false] - ) - ->willReturn(1); + ->method('insertReminder'); $this->reminderService->onCalendarObjectCreate($objectData); } @@ -371,16 +349,20 @@ EOD; 'component' => 'vevent', ]; - $this->backend->expects($this->exactly(5)) + $calls = [ + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429500, false], + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429620, true], + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429740, true], + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429860, true], + [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429980, true] + ]; + $this->backend->expects($this->exactly(count($calls))) ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429500, false], - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429620, true], - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429740, true], - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429860, true], - [1337, 42, 'wej2z68l9h', false, 1465430400, false, '5c70531aab15c92b52518ae10a2f78a4', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1465429980, true] - ) - ->willReturn(1); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return 1; + }); $this->timeFactory->expects($this->once()) ->method('getDateTime') @@ -398,13 +380,17 @@ EOD; 'component' => 'vevent', ]; - $this->backend->expects($this->exactly(2)) + $calls = [ + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'de919af7429d3b5c11e8b9d289b411a6', 'EMAIL', true, 1467243900, false], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467158400, false] + ]; + $this->backend->expects($this->exactly(count($calls))) ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'de919af7429d3b5c11e8b9d289b411a6', 'EMAIL', true, 1467243900, false], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467158400, false] - ) - ->willReturn(1); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return 1; + }); $this->timeFactory->expects($this->once()) ->method('getDateTime') @@ -521,17 +507,23 @@ EOD; ->willReturn([ '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => null, ]); - $this->backend->expects($this->exactly(6)) + + $calls = [ + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467243900, false], + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244020, true], + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244140, true], + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244260, true], + [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244380, true], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467158400, false] + ]; + $this->backend->expects($this->exactly(count($calls))) ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467243900, false], - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244020, true], - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244140, true], - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244260, true], - [1337, 42, 'wej2z68l9h', true, 1467244800, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467244380, true], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467158400, false] - ) - ->willReturn(1); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return 1; + }); + $this->timeFactory->expects($this->once()) ->method('getDateTime') ->with() @@ -556,9 +548,7 @@ EOD; $expectedReminderTimstamp = (new DateTime('2023-02-04T08:00:00', new DateTimeZone('Europe/Vienna')))->getTimestamp(); $this->backend->expects(self::once()) ->method('insertReminder') - ->withConsecutive( - [1337, 42, self::anything(), false, self::anything(), false, self::anything(), self::anything(), self::anything(), true, $expectedReminderTimstamp, false], - ) + ->with(1337, 42, self::anything(), false, self::anything(), false, self::anything(), self::anything(), self::anything(), true, $expectedReminderTimstamp, false) ->willReturn(1); $this->caldavBackend->expects(self::once()) ->method('getCalendarById') @@ -684,22 +674,22 @@ EOD; $provider3 = $this->createMock(INotificationProvider::class); $provider4 = $this->createMock(INotificationProvider::class); $provider5 = $this->createMock(INotificationProvider::class); - $this->notificationProviderManager->expects($this->exactly(5)) + + $getProviderCalls = [ + ['EMAIL', $provider1], + ['EMAIL', $provider2], + ['DISPLAY', $provider3], + ['EMAIL', $provider4], + ['EMAIL', $provider5], + ]; + $this->notificationProviderManager->expects($this->exactly(count($getProviderCalls))) ->method('getProvider') - ->withConsecutive( - ['EMAIL'], - ['EMAIL'], - ['DISPLAY'], - ['EMAIL'], - ['EMAIL'], - ) - ->willReturnOnConsecutiveCalls( - $provider1, - $provider2, - $provider3, - $provider4, - $provider5, - ); + ->willReturnCallback(function () use (&$getProviderCalls) { + $expected = array_shift($getProviderCalls); + $return = array_pop($expected); + $this->assertEquals($expected, func_get_args()); + return $return; + }); $user = $this->createMock(IUser::class); $this->userManager->expects($this->exactly(5)) @@ -748,20 +738,36 @@ EOD; return true; }, 'Displayname 123', $user)); + $removeReminderCalls = [ + [1], + [2], + [3], + [4], + [5], + ]; $this->backend->expects($this->exactly(5)) ->method('removeReminder') - ->withConsecutive([1], [2], [3], [4], [5]); - $this->backend->expects($this->exactly(6)) + ->willReturnCallback(function () use (&$removeReminderCalls) { + $expected = array_shift($removeReminderCalls); + $this->assertEquals($expected, func_get_args()); + }); + + + $insertReminderCalls = [ + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848700, false], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848820, true], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848940, true], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467849060, true], + [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467849180, true], + [1337, 42, 'wej2z68l9h', true, 1468454400, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467763200, false], + ]; + $this->backend->expects($this->exactly(count($insertReminderCalls))) ->method('insertReminder') - ->withConsecutive( - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848700, false], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848820, true], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467848940, true], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467849060, true], - [1337, 42, 'wej2z68l9h', true, 1467849600, false, 'fbdb2726bc0f7dfacac1d881c1453e20', 'ecacbf07d413c3c78d1ac7ad8c469602', 'EMAIL', true, 1467849180, true], - [1337, 42, 'wej2z68l9h', true, 1468454400, false, 'fbdb2726bc0f7dfacac1d881c1453e20', '8996992118817f9f311ac5cc56d1cc97', 'EMAIL', true, 1467763200, false], - ) - ->willReturn(99); + ->willReturnCallback(function () use (&$insertReminderCalls) { + $expected = array_shift($insertReminderCalls); + $this->assertEquals($expected, func_get_args()); + return 99; + }); $this->timeFactory->method('getDateTime') ->willReturn(DateTime::createFromFormat(DateTime::ATOM, '2016-06-08T00:00:00+00:00')); diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTestCase.php index b2fd9cfb93f..26dbcc0f38c 100644 --- a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTestCase.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,22 @@ use OCA\DAV\CalDAV\ResourceBooking\RoomPrincipalBackend; use OCP\IGroupManager; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\DAV\PropPatch; use Test\TestCase; -abstract class AbstractPrincipalBackendTest extends TestCase { - /** @var ResourcePrincipalBackend|RoomPrincipalBackend */ - protected $principalBackend; - - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - protected $userSession; - - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $groupManager; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - - /** @var ProxyMapper|\PHPUnit\Framework\MockObject\MockObject */ - protected $proxyMapper; - - /** @var string */ - protected $mainDbTable; - - /** @var string */ - protected $metadataDbTable; - - /** @var string */ - protected $foreignKey; - - /** @var string */ - protected $principalPrefix; - - /** @var string */ - protected $expectedCUType; +abstract class AbstractPrincipalBackendTestCase extends TestCase { + protected ResourcePrincipalBackend|RoomPrincipalBackend $principalBackend; + protected IUserSession&MockObject $userSession; + protected IGroupManager&MockObject $groupManager; + protected LoggerInterface&MockObject $logger; + protected ProxyMapper&MockObject $proxyMapper; + protected string $mainDbTable; + protected string $metadataDbTable; + protected string $foreignKey; + protected string $principalPrefix; + protected string $expectedCUType; protected function setUp(): void { parent::setUp(); @@ -59,10 +43,10 @@ abstract class AbstractPrincipalBackendTest extends TestCase { protected function tearDown(): void { $query = self::$realDatabase->getQueryBuilder(); - $query->delete('calendar_resources')->execute(); - $query->delete('calendar_resources_md')->execute(); - $query->delete('calendar_rooms')->execute(); - $query->delete('calendar_rooms_md')->execute(); + $query->delete('calendar_resources')->executeStatement(); + $query->delete('calendar_resources_md')->executeStatement(); + $query->delete('calendar_rooms')->executeStatement(); + $query->delete('calendar_rooms_md')->executeStatement(); } public function testGetPrincipalsByPrefix(): void { @@ -214,38 +198,43 @@ abstract class AbstractPrincipalBackendTest extends TestCase { ->with($this->principalPrefix . '/backend1-res1') ->willReturn([]); + $calls = [ + function ($proxy) { + /** @var Proxy $proxy */ + if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') { + return false; + } + if ($proxy->getProxyId() !== $this->principalPrefix . '/backend1-res2') { + return false; + } + if ($proxy->getPermissions() !== 3) { + return false; + } + + return true; + }, + function ($proxy) { + /** @var Proxy $proxy */ + if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') { + return false; + } + if ($proxy->getProxyId() !== $this->principalPrefix . '/backend2-res3') { + return false; + } + if ($proxy->getPermissions() !== 3) { + return false; + } + + return true; + } + ]; $this->proxyMapper->expects($this->exactly(2)) ->method('insert') - ->withConsecutive( - [$this->callback(function ($proxy) { - /** @var Proxy $proxy */ - if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') { - return false; - } - if ($proxy->getProxyId() !== $this->principalPrefix . '/backend1-res2') { - return false; - } - if ($proxy->getPermissions() !== 3) { - return false; - } - - return true; - })], - [$this->callback(function ($proxy) { - /** @var Proxy $proxy */ - if ($proxy->getOwnerId() !== $this->principalPrefix . '/backend1-res1') { - return false; - } - if ($proxy->getProxyId() !== $this->principalPrefix . '/backend2-res3') { - return false; - } - if ($proxy->getPermissions() !== 3) { - return false; - } - - return true; - })], - ); + ->willReturnCallback(function ($proxy) use (&$calls) { + $expected = array_shift($calls); + $this->assertTrue($expected($proxy)); + return $proxy; + }); $this->principalBackend->setGroupMemberSet($this->principalPrefix . '/backend1-res1/calendar-proxy-write', [$this->principalPrefix . '/backend1-res2', $this->principalPrefix . '/backend2-res3']); } @@ -281,7 +270,7 @@ abstract class AbstractPrincipalBackendTest extends TestCase { $actual); } - public function dataSearchPrincipals() { + public static function dataSearchPrincipals(): array { // data providers are called before we subclass // this class, $this->principalPrefix is null // at that point, so we need this hack diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php index d430afb0b01..168e21c3a91 100644 --- a/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/ResourcePrincipalBackendTest.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,7 +9,7 @@ namespace OCA\DAV\Tests\unit\CalDAV\ResourceBooking; use OCA\DAV\CalDAV\ResourceBooking\ResourcePrincipalBackend; -class ResourcePrincipalBackendTest extends AbstractPrincipalBackendTest { +class ResourcePrincipalBackendTest extends AbstractPrincipalBackendTestCase { protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php index cd63a3512ae..8a53b0ee25e 100644 --- a/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/RoomPrincipalBackendTest.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,7 +9,7 @@ namespace OCA\DAV\Tests\unit\CalDAV\ResourceBooking; use OCA\DAV\CalDAV\ResourceBooking\RoomPrincipalBackend; -class RoomPrincipalBackendTest extends AbstractPrincipalBackendTest { +class RoomPrincipalBackendTest extends AbstractPrincipalBackendTestCase { protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php index 896d7e9eb5f..8e71bfa6edf 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -36,54 +38,22 @@ interface IMailServiceMock extends IMailService, IMailMessageSend { } class IMipPluginTest extends TestCase { - - /** @var IMessage|MockObject */ - private $mailMessage; - - /** @var IMailer|MockObject */ - private $mailer; - - /** @var IEMailTemplate|MockObject */ - private $emailTemplate; - - /** @var IAttachment|MockObject */ - private $emailAttachment; - - /** @var ITimeFactory|MockObject */ - private $timeFactory; - - /** @var IAppConfig|MockObject */ - private $config; - - /** @var IUserSession|MockObject */ - private $userSession; - - /** @var IUser|MockObject */ - private $user; - - /** @var IMipPlugin */ - private $plugin; - - /** @var IMipService|MockObject */ - private $service; - - /** @var Defaults|MockObject */ - private $defaults; - - /** @var LoggerInterface|MockObject */ - private $logger; - - /** @var EventComparisonService|MockObject */ - private $eventComparisonService; - - /** @var IMailManager|MockObject */ - private $mailManager; - - /** @var IMailService|IMailMessageSend|MockObject */ - private $mailService; - - /** @var IMailMessageNew|MockObject */ - private $mailMessageNew; + private IMessage&MockObject $mailMessage; + private IMailer&MockObject $mailer; + private IEMailTemplate&MockObject $emailTemplate; + private IAttachment&MockObject $emailAttachment; + private ITimeFactory&MockObject $timeFactory; + private IAppConfig&MockObject $config; + private IUserSession&MockObject $userSession; + private IUser&MockObject $user; + private IMipPlugin $plugin; + private IMipService&MockObject $service; + private Defaults&MockObject $defaults; + private LoggerInterface&MockObject $logger; + private EventComparisonService&MockObject $eventComparisonService; + private IMailManager&MockObject $mailManager; + private IMailServiceMock&MockObject $mailService; + private IMailMessageNew&MockObject $mailMessageNew; protected function setUp(): void { $this->mailMessage = $this->createMock(IMessage::class); diff --git a/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php index abf8cfe3177..2be6a1cf8b1 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -8,15 +9,14 @@ namespace OCA\DAV\Tests\unit\CalDAV\Schedule; -use OC\L10N\L10N; -use OC\L10N\LazyL10N; use OC\URLGenerator; use OCA\DAV\CalDAV\EventReader; use OCA\DAV\CalDAV\Schedule\IMipService; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; use OCP\IDBConnection; -use OCP\L10N\IFactory as L10NFactory; +use OCP\IL10N; +use OCP\L10N\IFactory; use OCP\Security\ISecureRandom; use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCalendar; @@ -24,48 +24,32 @@ use Sabre\VObject\Property\ICalendar\DateTime; use Test\TestCase; class IMipServiceTest extends TestCase { - /** @var URLGenerator|MockObject */ - private $urlGenerator; - - /** @var IConfig|MockObject */ - private $config; - - /** @var IDBConnection|MockObject */ - private $db; - - /** @var ISecureRandom|MockObject */ - private $random; - - /** @var L10NFactory|MockObject */ - private $l10nFactory; - - /** @var L10N|MockObject */ - private $l10n; - - /** @var ITimeFactory|MockObject */ - private $timeFactory; - - /** @var IMipService */ - private $service; - - /** @var VCalendar */ - private $vCalendar1a; - /** @var VCalendar */ - private $vCalendar1b; - /** @var VCalendar */ - private $vCalendar2; - /** @var VCalendar */ - private $vCalendar3; + private URLGenerator&MockObject $urlGenerator; + private IConfig&MockObject $config; + private IDBConnection&MockObject $db; + private ISecureRandom&MockObject $random; + private IFactory&MockObject $l10nFactory; + private IL10N&MockObject $l10n; + private ITimeFactory&MockObject $timeFactory; + private IMipService $service; + + + private VCalendar $vCalendar1a; + private VCalendar $vCalendar1b; + private VCalendar $vCalendar2; + private VCalendar $vCalendar3; /** @var DateTime DateTime object that will be returned by DateTime() or DateTime('now') */ public static $datetimeNow; protected function setUp(): void { + parent::setUp(); + $this->urlGenerator = $this->createMock(URLGenerator::class); $this->config = $this->createMock(IConfig::class); $this->db = $this->createMock(IDBConnection::class); $this->random = $this->createMock(ISecureRandom::class); - $this->l10nFactory = $this->createMock(L10NFactory::class); - $this->l10n = $this->createMock(LazyL10N::class); + $this->l10nFactory = $this->createMock(IFactory::class); + $this->l10n = $this->createMock(IL10N::class); $this->timeFactory = $this->createMock(ITimeFactory::class); $this->l10nFactory->expects(self::once()) ->method('findGenericLanguage') @@ -170,7 +154,7 @@ class IMipServiceTest extends TestCase { } public function testBuildBodyDataCreated(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -218,7 +202,7 @@ class IMipServiceTest extends TestCase { } public function testBuildBodyDataUpdate(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -349,7 +333,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringSingular(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -802,7 +786,7 @@ class IMipServiceTest extends TestCase { 'In 2 months on July 1, 2024 for the entire day', $this->service->generateWhenString($eventReader) ); - + /** test patrial day event in 1 year*/ $vCalendar = clone $this->vCalendar1a; // construct event reader @@ -846,7 +830,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringRecurringDaily(): void { - + // construct l10n return maps $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -960,7 +944,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringRecurringWeekly(): void { - + // construct l10n return maps $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1077,7 +1061,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringRecurringMonthly(): void { - + // construct l10n return maps $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1290,7 +1274,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringRecurringYearly(): void { - + // construct l10n return maps $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1504,7 +1488,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateWhenStringRecurringFixed(): void { - + // construct l10n return maps $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1545,7 +1529,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateOccurringStringWithRrule(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1602,7 +1586,7 @@ class IMipServiceTest extends TestCase { 'In 2 days on July 1, 2024 then on July 3, 2024 and July 5, 2024' ], ]); - + // construct time factory return(s) $this->timeFactory->method('getDateTime')->willReturnOnConsecutiveCalls( (new \DateTime('20240629T170000', (new \DateTimeZone('America/Toronto')))), @@ -1687,7 +1671,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateOccurringStringWithRdate(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -1838,7 +1822,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateOccurringStringWithOneExdate(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { @@ -2022,7 +2006,7 @@ class IMipServiceTest extends TestCase { } public function testGenerateOccurringStringWithTwoExdate(): void { - + // construct l10n return(s) $this->l10n->method('l')->willReturnCallback( function ($v1, $v2, $v3) { diff --git a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php index f656a0fa33c..5dadb753a79 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -35,21 +36,11 @@ use Sabre\Xml\Service; use Test\TestCase; class PluginTest extends TestCase { - - /** @var Plugin */ - private $plugin; - - /** @var Server|MockObject */ - private $server; - - /** @var IConfig|MockObject */ - private $config; - - /** @var LoggerInterface&MockObject */ - private $logger; - - /** @var DefaultCalendarValidator */ - private $calendarValidator; + private Plugin $plugin; + private Server&MockObject $server; + private IConfig&MockObject $config; + private LoggerInterface&MockObject $logger; + private DefaultCalendarValidator $calendarValidator; protected function setUp(): void { parent::setUp(); @@ -59,9 +50,7 @@ class PluginTest extends TestCase { $this->calendarValidator = new DefaultCalendarValidator(); $this->server = $this->createMock(Server::class); - $this->server->httpResponse = $this->getMockBuilder(ResponseInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $this->server->httpResponse = $this->createMock(ResponseInterface::class); $this->server->xml = new Service(); $this->plugin = new Plugin($this->config, $this->logger, $this->calendarValidator); @@ -69,23 +58,26 @@ class PluginTest extends TestCase { } public function testInitialize(): void { - - $this->server->expects($this->exactly(10)) + $calls = [ + // Sabre\CalDAV\Schedule\Plugin events + ['method:POST', [$this->plugin, 'httpPost'], 100], + ['propFind', [$this->plugin, 'propFind'], 100], + ['propPatch', [$this->plugin, 'propPatch'], 100], + ['calendarObjectChange', [$this->plugin, 'calendarObjectChange'], 100], + ['beforeUnbind', [$this->plugin, 'beforeUnbind'], 100], + ['schedule', [$this->plugin, 'scheduleLocalDelivery'], 100], + ['getSupportedPrivilegeSet', [$this->plugin, 'getSupportedPrivilegeSet'], 100], + // OCA\DAV\CalDAV\Schedule\Plugin events + ['propFind', [$this->plugin, 'propFindDefaultCalendarUrl'], 90], + ['afterWriteContent', [$this->plugin, 'dispatchSchedulingResponses'], 100], + ['afterCreateFile', [$this->plugin, 'dispatchSchedulingResponses'], 100], + ]; + $this->server->expects($this->exactly(count($calls))) ->method('on') - ->withConsecutive( - // Sabre\CalDAV\Schedule\Plugin events - ['method:POST', [$this->plugin, 'httpPost']], - ['propFind', [$this->plugin, 'propFind']], - ['propPatch', [$this->plugin, 'propPatch']], - ['calendarObjectChange', [$this->plugin, 'calendarObjectChange']], - ['beforeUnbind', [$this->plugin, 'beforeUnbind']], - ['schedule', [$this->plugin, 'scheduleLocalDelivery']], - ['getSupportedPrivilegeSet', [$this->plugin, 'getSupportedPrivilegeSet']], - // OCA\DAV\CalDAV\Schedule\Plugin events - ['propFind', [$this->plugin, 'propFindDefaultCalendarUrl'], 90], - ['afterWriteContent', [$this->plugin, 'dispatchSchedulingResponses']], - ['afterCreateFile', [$this->plugin, 'dispatchSchedulingResponses']] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $this->plugin->initialize($this->server); } @@ -168,7 +160,7 @@ class PluginTest extends TestCase { $this->assertFalse($this->invokePrivate($this->plugin, 'getAttendeeRSVP', [$property3])); } - public function propFindDefaultCalendarUrlProvider(): array { + public static function propFindDefaultCalendarUrlProvider(): array { return [ [ 'principals/users/myuser', @@ -270,7 +262,7 @@ class PluginTest extends TestCase { ], 0 ); - /** @var IPrincipal|MockObject $node */ + /** @var IPrincipal&MockObject $node */ $node = $this->getMockBuilder(IPrincipal::class) ->disableOriginalConstructor() ->getMock(); @@ -367,7 +359,7 @@ class PluginTest extends TestCase { } } - /** @var Tree|MockObject $tree */ + /** @var Tree&MockObject $tree */ $tree = $this->createMock(Tree::class); $tree->expects($this->once()) ->method('getNodeForPath') diff --git a/apps/dav/tests/unit/CalDAV/Search/Request/CalendarSearchReportTest.php b/apps/dav/tests/unit/CalDAV/Search/Request/CalendarSearchReportTest.php index cbfd4639ed7..a7ca6eb8945 100644 --- a/apps/dav/tests/unit/CalDAV/Search/Request/CalendarSearchReportTest.php +++ b/apps/dav/tests/unit/CalDAV/Search/Request/CalendarSearchReportTest.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 @@ -10,7 +12,7 @@ use Sabre\Xml\Reader; use Test\TestCase; class CalendarSearchReportTest extends TestCase { - private $elementMap = [ + private array $elementMap = [ '{http://nextcloud.com/ns}calendar-search' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport', ]; @@ -112,7 +114,7 @@ XML; ); } - + public function testRequiresCompFilter(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('{http://nextcloud.com/ns}prop-filter or {http://nextcloud.com/ns}param-filter given without any {http://nextcloud.com/ns}comp-filter'); @@ -139,7 +141,7 @@ XML; $this->parse($xml); } - + public function testRequiresFilter(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('The {http://nextcloud.com/ns}filter element is required for this request'); @@ -157,7 +159,7 @@ XML; $this->parse($xml); } - + public function testNoSearchTerm(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('{http://nextcloud.com/ns}search-term is required for this request'); @@ -185,7 +187,7 @@ XML; $this->parse($xml); } - + public function testCompOnly(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('At least one{http://nextcloud.com/ns}prop-filter or {http://nextcloud.com/ns}param-filter is required for this request'); @@ -313,7 +315,7 @@ XML; ); } - private function parse($xml, array $elementMap = []) { + private function parse(string $xml, array $elementMap = []): array { $reader = new Reader(); $reader->elementMap = array_merge($this->elementMap, $elementMap); $reader->xml($xml); diff --git a/apps/dav/tests/unit/CalDAV/Search/SearchPluginTest.php b/apps/dav/tests/unit/CalDAV/Search/SearchPluginTest.php index 0da971dc36b..e576fbae34c 100644 --- a/apps/dav/tests/unit/CalDAV/Search/SearchPluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Search/SearchPluginTest.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/dav/tests/unit/CalDAV/Security/RateLimitingPluginTest.php b/apps/dav/tests/unit/CalDAV/Security/RateLimitingPluginTest.php index fc0bd1502b2..a5cf6a23c66 100644 --- a/apps/dav/tests/unit/CalDAV/Security/RateLimitingPluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Security/RateLimitingPluginTest.php @@ -24,11 +24,11 @@ use Test\TestCase; class RateLimitingPluginTest extends TestCase { - private Limiter|MockObject $limiter; - private CalDavBackend|MockObject $caldavBackend; - private IUserManager|MockObject $userManager; - private LoggerInterface|MockObject $logger; - private IAppConfig|MockObject $config; + private Limiter&MockObject $limiter; + private CalDavBackend&MockObject $caldavBackend; + private IUserManager&MockObject $userManager; + private LoggerInterface&MockObject $logger; + private IAppConfig&MockObject $config; private string $userId = 'user123'; private RateLimitingPlugin $plugin; diff --git a/apps/dav/tests/unit/CalDAV/Status/StatusServiceTest.php b/apps/dav/tests/unit/CalDAV/Status/StatusServiceTest.php index 78e76cf507d..ee0ef2334ec 100644 --- a/apps/dav/tests/unit/CalDAV/Status/StatusServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Status/StatusServiceTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -25,14 +27,14 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class StatusServiceTest extends TestCase { - private ITimeFactory|MockObject $timeFactory; - private IManager|MockObject $calendarManager; - private IUserManager|MockObject $userManager; - private UserStatusService|MockObject $userStatusService; - private IAvailabilityCoordinator|MockObject $availabilityCoordinator; - private ICacheFactory|MockObject $cacheFactory; - private LoggerInterface|MockObject $logger; - private ICache|MockObject $cache; + private ITimeFactory&MockObject $timeFactory; + private IManager&MockObject $calendarManager; + private IUserManager&MockObject $userManager; + private UserStatusService&MockObject $userStatusService; + private IAvailabilityCoordinator&MockObject $availabilityCoordinator; + private ICacheFactory&MockObject $cacheFactory; + private LoggerInterface&MockObject $logger; + private ICache&MockObject $cache; private StatusService $service; protected function setUp(): void { diff --git a/apps/dav/tests/unit/CalDAV/TimeZoneFactoryTest.php b/apps/dav/tests/unit/CalDAV/TimeZoneFactoryTest.php index d5a62a9732f..2d6d0e86358 100644 --- a/apps/dav/tests/unit/CalDAV/TimeZoneFactoryTest.php +++ b/apps/dav/tests/unit/CalDAV/TimeZoneFactoryTest.php @@ -1,7 +1,6 @@ <?php declare(strict_types=1); - /** * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/apps/dav/tests/unit/CalDAV/TimezoneServiceTest.php b/apps/dav/tests/unit/CalDAV/TimezoneServiceTest.php index b01139e4093..5bb87be67c1 100644 --- a/apps/dav/tests/unit/CalDAV/TimezoneServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/TimezoneServiceTest.php @@ -1,11 +1,6 @@ <?php -/** - * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ declare(strict_types=1); - /** * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -26,10 +21,9 @@ use Sabre\VObject\Component\VTimeZone; use Test\TestCase; class TimezoneServiceTest extends TestCase { - - private IConfig|MockObject $config; - private PropertyMapper|MockObject $propertyMapper; - private IManager|MockObject $calendarManager; + private IConfig&MockObject $config; + private PropertyMapper&MockObject $propertyMapper; + private IManager&MockObject $calendarManager; private TimezoneService $service; protected function setUp(): void { diff --git a/apps/dav/tests/unit/CalDAV/TipBrokerTest.php b/apps/dav/tests/unit/CalDAV/TipBrokerTest.php index 3a8e240c1d8..ddf992767d6 100644 --- a/apps/dav/tests/unit/CalDAV/TipBrokerTest.php +++ b/apps/dav/tests/unit/CalDAV/TipBrokerTest.php @@ -1,4 +1,6 @@ <?php + +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -42,7 +44,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnCreate(): void { - + // construct calendar and generate event info for newly created event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = [ @@ -61,7 +63,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnModify(): void { - + // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); @@ -79,7 +81,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnDelete(): void { - + // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); @@ -96,7 +98,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnStatusCancelled(): void { - + // construct calendar and generate event info for modified event with one attendee $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); @@ -114,7 +116,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnAddAttendee(): void { - + // construct calendar and generate event info for modified event with two attendees $calendar = clone $this->vCalendar1a; $previousEventInfo = $this->invokePrivate($this->broker, 'parseEventInfo', [$calendar]); @@ -141,7 +143,7 @@ class TipBrokerTest extends TestCase { } public function testParseEventForOrganizerOnRemoveAttendee(): void { - + // construct calendar and generate event info for modified event with two attendees $calendar = clone $this->vCalendar1a; $calendar->VEVENT->add('ATTENDEE', 'mailto:attendee2@testing.com', [ diff --git a/apps/dav/tests/unit/CalDAV/Validation/CalDavValidatePluginTest.php b/apps/dav/tests/unit/CalDAV/Validation/CalDavValidatePluginTest.php index 0329279af09..74fb4b5e94e 100644 --- a/apps/dav/tests/unit/CalDAV/Validation/CalDavValidatePluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Validation/CalDavValidatePluginTest.php @@ -18,11 +18,11 @@ use Sabre\HTTP\ResponseInterface; use Test\TestCase; class CalDavValidatePluginTest extends TestCase { + private IAppConfig&MockObject $config; + private RequestInterface&MockObject $request; + private ResponseInterface&MockObject $response; private CalDavValidatePlugin $plugin; - private IAppConfig|MockObject $config; - private RequestInterface|MockObject $request; - private ResponseInterface|MockObject $response; protected function setUp(): void { parent::setUp(); @@ -36,7 +36,7 @@ class CalDavValidatePluginTest extends TestCase { } public function testPutSizeLessThenLimit(): void { - + // construct method responses $this->config ->method('getValueInt') @@ -50,11 +50,11 @@ class CalDavValidatePluginTest extends TestCase { $this->assertTrue( $this->plugin->beforePut($this->request, $this->response) ); - + } public function testPutSizeMoreThenLimit(): void { - + // construct method responses $this->config ->method('getValueInt') @@ -67,7 +67,7 @@ class CalDavValidatePluginTest extends TestCase { $this->expectException(Forbidden::class); // test condition $this->plugin->beforePut($this->request, $this->response); - + } } diff --git a/apps/dav/tests/unit/CalDAV/WebcalCaching/ConnectionTest.php b/apps/dav/tests/unit/CalDAV/WebcalCaching/ConnectionTest.php index 5e9caaaeb44..35afc4d7ca7 100644 --- a/apps/dav/tests/unit/CalDAV/WebcalCaching/ConnectionTest.php +++ b/apps/dav/tests/unit/CalDAV/WebcalCaching/ConnectionTest.php @@ -13,7 +13,6 @@ use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; use OCP\Http\Client\LocalServerException; use OCP\IAppConfig; -use OCP\IConfig; use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; @@ -21,9 +20,9 @@ use Test\TestCase; class ConnectionTest extends TestCase { - private IClientService|MockObject $clientService; - private IConfig|MockObject $config; - private LoggerInterface|MockObject $logger; + private IClientService&MockObject $clientService; + private IAppConfig&MockObject $config; + private LoggerInterface&MockObject $logger; private Connection $connection; public function setUp(): void { diff --git a/apps/dav/tests/unit/CalDAV/WebcalCaching/PluginTest.php b/apps/dav/tests/unit/CalDAV/WebcalCaching/PluginTest.php index 82c03c5cf68..804af021d5a 100644 --- a/apps/dav/tests/unit/CalDAV/WebcalCaching/PluginTest.php +++ b/apps/dav/tests/unit/CalDAV/WebcalCaching/PluginTest.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 diff --git a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php index d65a99a15e0..3252322ccff 100644 --- a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php @@ -20,10 +20,10 @@ use Sabre\VObject\Recur\NoInstancesException; use Test\TestCase; class RefreshWebcalServiceTest extends TestCase { - private CalDavBackend|MockObject $caldavBackend; - private Connection|MockObject $connection; - private LoggerInterface|MockObject $logger; - private ITimeFactory|MockObject $time; + private CalDavBackend&MockObject $caldavBackend; + private Connection&MockObject $connection; + private LoggerInterface&MockObject $logger; + private ITimeFactory&MockObject $time; protected function setUp(): void { parent::setUp(); @@ -35,10 +35,6 @@ class RefreshWebcalServiceTest extends TestCase { } /** - * @param string $body - * @param string $contentType - * @param string $result - * * @dataProvider runDataProvider */ public function testRun(string $body, string $contentType, string $result): void { @@ -88,10 +84,6 @@ class RefreshWebcalServiceTest extends TestCase { } /** - * @param string $body - * @param string $contentType - * @param string $result - * * @dataProvider identicalDataProvider */ public function testRunIdentical(string $uid, array $calendarObject, string $body, string $contentType, string $result): void { @@ -209,10 +201,6 @@ class RefreshWebcalServiceTest extends TestCase { } /** - * @param string $body - * @param string $contentType - * @param string $result - * * @dataProvider runDataProvider */ public function testRunCreateCalendarNoException(string $body, string $contentType, string $result): void { @@ -259,10 +247,6 @@ class RefreshWebcalServiceTest extends TestCase { } /** - * @param string $body - * @param string $contentType - * @param string $result - * * @dataProvider runDataProvider */ public function testRunCreateCalendarBadRequest(string $body, string $contentType, string $result): void { @@ -308,10 +292,7 @@ class RefreshWebcalServiceTest extends TestCase { $refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123'); } - /** - * @return array - */ - public static function identicalDataProvider():array { + public static function identicalDataProvider(): array { return [ [ '12345', @@ -330,10 +311,7 @@ class RefreshWebcalServiceTest extends TestCase { ]; } - /** - * @return array - */ - public function runDataProvider():array { + public static function runDataProvider(): array { return [ [ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", 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/CardDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CardDAV/Activity/BackendTest.php index 134a6ca5ca0..4de1cf25cc5 100644 --- a/apps/dav/tests/unit/CardDAV/Activity/BackendTest.php +++ b/apps/dav/tests/unit/CardDAV/Activity/BackendTest.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,20 +22,11 @@ use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class BackendTest extends TestCase { - /** @var IManager|MockObject */ - protected $activityManager; - - /** @var IGroupManager|MockObject */ - protected $groupManager; - - /** @var IUserSession|MockObject */ - protected $userSession; - - /** @var IAppManager|MockObject */ - protected $appManager; - - /** @var IUserManager|MockObject */ - protected $userManager; + protected IManager&MockObject $activityManager; + protected IGroupManager&MockObject $groupManager; + protected IUserSession&MockObject $userSession; + protected IAppManager&MockObject $appManager; + protected IUserManager&MockObject $userManager; protected function setUp(): void { parent::setUp(); @@ -45,10 +38,9 @@ class BackendTest extends TestCase { } /** - * @param array $methods * @return Backend|MockObject */ - protected function getBackend(array $methods = []) { + protected function getBackend(array $methods = []): Backend { if (empty($methods)) { return new Backend( $this->activityManager, @@ -71,7 +63,7 @@ class BackendTest extends TestCase { } } - public function dataCallTriggerAddressBookActivity(): array { + public static function dataCallTriggerAddressBookActivity(): array { return [ ['onAddressbookCreate', [['data']], Addressbook::SUBJECT_ADD, [['data'], [], []]], ['onAddressbookUpdate', [['data'], ['shares'], ['changed-properties']], Addressbook::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]], @@ -95,7 +87,7 @@ class BackendTest extends TestCase { call_user_func_array([$backend, $method], $payload); } - public function dataTriggerAddressBookActivity(): array { + public static function dataTriggerAddressBookActivity(): array { return [ // Add addressbook [Addressbook::SUBJECT_ADD, [], [], [], '', '', null, []], @@ -160,12 +152,6 @@ class BackendTest extends TestCase { /** * @dataProvider dataTriggerAddressBookActivity - * @param string $action - * @param array $data - * @param array $shares - * @param array $changedProperties - * @param string $currentUser - * @param string $author * @param string[]|null $shareUsers * @param string[] $users */ @@ -219,13 +205,13 @@ class BackendTest extends TestCase { ->method('userExists') ->willReturn(true); - $event->expects($this->exactly(sizeof($users))) + $event->expects($this->exactly(count($users))) ->method('setAffectedUser') ->willReturnSelf(); - $event->expects($this->exactly(sizeof($users))) + $event->expects($this->exactly(count($users))) ->method('setSubject') ->willReturnSelf(); - $this->activityManager->expects($this->exactly(sizeof($users))) + $this->activityManager->expects($this->exactly(count($users))) ->method('publish') ->with($event); } else { @@ -261,7 +247,7 @@ class BackendTest extends TestCase { ], [], []]); } - public function dataTriggerCardActivity(): array { + public static function dataTriggerCardActivity(): array { $cardData = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.8//EN\r\nUID:test-user\r\nFN:test-user\r\nN:test-user;;;;\r\nEND:VCARD\r\n\r\n"; return [ @@ -330,12 +316,6 @@ class BackendTest extends TestCase { /** * @dataProvider dataTriggerCardActivity - * @param string $action - * @param array $addressBookData - * @param array $shares - * @param array $cardData - * @param string $currentUser - * @param string $author * @param string[]|null $shareUsers * @param string[] $users */ @@ -385,13 +365,13 @@ class BackendTest extends TestCase { ->with($author) ->willReturnSelf(); - $event->expects($this->exactly(sizeof($users))) + $event->expects($this->exactly(count($users))) ->method('setAffectedUser') ->willReturnSelf(); - $event->expects($this->exactly(sizeof($users))) + $event->expects($this->exactly(count($users))) ->method('setSubject') ->willReturnSelf(); - $this->activityManager->expects($this->exactly(sizeof($users))) + $this->activityManager->expects($this->exactly(count($users))) ->method('publish') ->with($event); } else { @@ -409,7 +389,7 @@ class BackendTest extends TestCase { $this->assertEmpty($this->invokePrivate($backend, 'triggerCardActivity', [Card::SUBJECT_UPDATE, ['principaluri' => 'principals/system/system'], [], []])); } - public function dataGetUsersForShares(): array { + public static function dataGetUsersForShares(): array { return [ [ [], @@ -454,9 +434,6 @@ class BackendTest extends TestCase { /** * @dataProvider dataGetUsersForShares - * @param array $shares - * @param array $groups - * @param array $expected */ public function testGetUsersForShares(array $shares, array $groups, array $expected): void { $backend = $this->getBackend(); @@ -498,10 +475,9 @@ class BackendTest extends TestCase { } /** - * @param string $uid * @return IUser|MockObject */ - protected function getUserMock(string $uid) { + protected function getUserMock(string $uid): IUser { $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') diff --git a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php index a8bfc1b41fd..cfb14a5d567 100644 --- a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php +++ b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php @@ -12,32 +12,20 @@ use OCA\DAV\CardDAV\AddressBookImpl; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Db\PropertyMapper; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCard; use Sabre\VObject\Property\Text; //use Sabre\VObject\Property\; use Test\TestCase; class AddressBookImplTest extends TestCase { - /** @var AddressBookImpl */ - private $addressBookImpl; - - /** @var array */ - private $addressBookInfo; - - /** @var AddressBook | \PHPUnit\Framework\MockObject\MockObject */ - private $addressBook; - - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject */ - private $backend; - - /** @var PropertyMapper | \PHPUnit\Framework\MockObject\MockObject */ - private $propertyMapper; - - /** @var VCard | \PHPUnit\Framework\MockObject\MockObject */ - private $vCard; + private array $addressBookInfo; + private AddressBook&MockObject $addressBook; + private IURLGenerator&MockObject $urlGenerator; + private CardDavBackend&MockObject $backend; + private PropertyMapper&MockObject $propertyMapper; + private VCard&MockObject $vCard; + private AddressBookImpl $addressBookImpl; protected function setUp(): void { parent::setUp(); @@ -48,10 +36,8 @@ class AddressBookImplTest extends TestCase { 'principaluri' => 'principals/system/system', '{DAV:}displayname' => 'display name', ]; - $this->addressBook = $this->getMockBuilder(AddressBook::class) - ->disableOriginalConstructor()->getMock(); - $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->disableOriginalConstructor()->getMock(); + $this->addressBook = $this->createMock(AddressBook::class); + $this->backend = $this->createMock(CardDavBackend::class); $this->vCard = $this->createMock(VCard::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->propertyMapper = $this->createMock(PropertyMapper::class); @@ -77,7 +63,7 @@ class AddressBookImplTest extends TestCase { } public function testSearch(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject | AddressBookImpl $addressBookImpl */ + /** @var MockObject&AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder(AddressBookImpl::class) ->setConstructorArgs( [ @@ -89,7 +75,7 @@ class AddressBookImplTest extends TestCase { null ] ) - ->setMethods(['vCard2Array', 'readCard']) + ->onlyMethods(['vCard2Array', 'readCard']) ->getMock(); $pattern = 'pattern'; @@ -107,10 +93,10 @@ class AddressBookImplTest extends TestCase { $addressBookImpl->expects($this->exactly(2))->method('readCard') ->willReturn($this->vCard); $addressBookImpl->expects($this->exactly(2))->method('vCard2Array') - ->withConsecutive( - ['foo.vcf', $this->vCard], - ['bar.vcf', $this->vCard] - )->willReturn('vCard'); + ->willReturnMap([ + ['foo.vcf', $this->vCard, 'vCard'], + ['bar.vcf', $this->vCard, 'vCard'], + ]); $result = $addressBookImpl->search($pattern, $searchProperties, []); $this->assertTrue((is_array($result))); @@ -119,13 +105,11 @@ class AddressBookImplTest extends TestCase { /** * @dataProvider dataTestCreate - * - * @param array $properties */ - public function testCreate($properties): void { + public function testCreate(array $properties): void { $uid = 'uid'; - /** @var \PHPUnit\Framework\MockObject\MockObject | AddressBookImpl $addressBookImpl */ + /** @var MockObject&AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder(AddressBookImpl::class) ->setConstructorArgs( [ @@ -137,7 +121,7 @@ class AddressBookImplTest extends TestCase { null ] ) - ->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard']) + ->onlyMethods(['vCard2Array', 'createUid', 'createEmptyVCard']) ->getMock(); $expectedProperties = 0; @@ -164,7 +148,7 @@ class AddressBookImplTest extends TestCase { $this->assertTrue($addressBookImpl->createOrUpdate($properties)); } - public function dataTestCreate() { + public static function dataTestCreate(): array { return [ [[]], [['FN' => 'John Doe']], @@ -177,7 +161,7 @@ class AddressBookImplTest extends TestCase { $uri = 'bla.vcf'; $properties = ['URI' => $uri, 'UID' => $uid, 'FN' => 'John Doe']; - /** @var \PHPUnit\Framework\MockObject\MockObject | AddressBookImpl $addressBookImpl */ + /** @var MockObject&AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder(AddressBookImpl::class) ->setConstructorArgs( [ @@ -189,7 +173,7 @@ class AddressBookImplTest extends TestCase { null ] ) - ->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard']) + ->onlyMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard']) ->getMock(); $addressBookImpl->expects($this->never())->method('createUid'); @@ -216,7 +200,7 @@ class AddressBookImplTest extends TestCase { $vCard = new vCard; $textProperty = $vCard->createProperty('KEY', 'value'); - /** @var \PHPUnit\Framework\MockObject\MockObject | AddressBookImpl $addressBookImpl */ + /** @var MockObject&AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder(AddressBookImpl::class) ->setConstructorArgs( [ @@ -228,7 +212,7 @@ class AddressBookImplTest extends TestCase { null ] ) - ->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard']) + ->onlyMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard']) ->getMock(); $this->backend->expects($this->once())->method('getCard') @@ -248,11 +232,8 @@ class AddressBookImplTest extends TestCase { /** * @dataProvider dataTestGetPermissions - * - * @param array $permissions - * @param int $expected */ - public function testGetPermissions($permissions, $expected): void { + public function testGetPermissions(array $permissions, int $expected): void { $this->addressBook->expects($this->once())->method('getACL') ->willReturn($permissions); @@ -261,7 +242,7 @@ class AddressBookImplTest extends TestCase { ); } - public function dataTestGetPermissions() { + public static function dataTestGetPermissions(): array { return [ [[], 0], [[['privilege' => '{DAV:}read']], 1], @@ -299,7 +280,7 @@ class AddressBookImplTest extends TestCase { } public function testCreateUid(): void { - /** @var \PHPUnit\Framework\MockObject\MockObject | AddressBookImpl $addressBookImpl */ + /** @var MockObject&AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder(AddressBookImpl::class) ->setConstructorArgs( [ @@ -311,7 +292,7 @@ class AddressBookImplTest extends TestCase { null ] ) - ->setMethods(['getUid']) + ->onlyMethods(['getUid']) ->getMock(); $addressBookImpl->expects($this->exactly(2)) diff --git a/apps/dav/tests/unit/CardDAV/AddressBookTest.php b/apps/dav/tests/unit/CardDAV/AddressBookTest.php index cbdb9a1402c..043b192e2c8 100644 --- a/apps/dav/tests/unit/CardDAV/AddressBookTest.php +++ b/apps/dav/tests/unit/CardDAV/AddressBookTest.php @@ -1,5 +1,6 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -28,19 +29,20 @@ class AddressBookTest extends TestCase { 'uri' => 'default', ]; $l10n = $this->createMock(IL10N::class); - $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $card = new Card($backend, $addressBookInfo, ['id' => 5, 'carddata' => 'RANDOM VCF DATA', 'uri' => 'something', 'addressbookid' => 23]); - $backend->expects($this->once())->method('moveCard')->with(23, 666, 'something', 'user1')->willReturn(true); + $backend->expects($this->once())->method('moveCard') + ->with(23, 666, 'something', 'user1') + ->willReturn(true); $addressBook->moveInto('new', 'old', $card); } public function testDelete(): void { /** @var MockObject | CardDavBackend $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->once())->method('updateShares'); $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:user2'] @@ -54,7 +56,7 @@ class AddressBookTest extends TestCase { ]; $l10n = $this->createMock(IL10N::class); $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $addressBook->delete(); } @@ -63,7 +65,7 @@ class AddressBookTest extends TestCase { $this->expectException(Forbidden::class); /** @var MockObject | CardDavBackend $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->never())->method('updateShares'); $backend->expects($this->any())->method('getShares')->willReturn([ ['href' => 'principal:group2'] @@ -77,14 +79,14 @@ class AddressBookTest extends TestCase { ]; $l10n = $this->createMock(IL10N::class); $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $addressBook->delete(); } public function testPropPatchShared(): void { /** @var MockObject | CardDavBackend $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->never())->method('updateAddressBook'); $addressBookInfo = [ '{http://owncloud.org/ns}owner-principal' => 'user1', @@ -95,13 +97,13 @@ class AddressBookTest extends TestCase { ]; $l10n = $this->createMock(IL10N::class); $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $addressBook->propPatch(new PropPatch(['{DAV:}displayname' => 'Test address book'])); } public function testPropPatchNotShared(): void { /** @var MockObject | CardDavBackend $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->atLeast(1))->method('updateAddressBook'); $addressBookInfo = [ '{DAV:}displayname' => 'Test address book', @@ -111,16 +113,16 @@ class AddressBookTest extends TestCase { ]; $l10n = $this->createMock(IL10N::class); $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $addressBook->propPatch(new PropPatch(['{DAV:}displayname' => 'Test address book'])); } /** * @dataProvider providesReadOnlyInfo */ - public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet): void { + public function testAcl(bool $expectsWrite, ?bool $readOnlyValue, bool $hasOwnerSet): void { /** @var MockObject | CardDavBackend $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->any())->method('applyShareAcl')->willReturnArgument(1); $addressBookInfo = [ '{DAV:}displayname' => 'Test address book', @@ -136,7 +138,7 @@ class AddressBookTest extends TestCase { } $l10n = $this->createMock(IL10N::class); $logger = $this->createMock(LoggerInterface::class); - $addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger); + $addressBook = new AddressBook($backend, $addressBookInfo, $l10n); $acl = $addressBook->getACL(); $childAcl = $addressBook->getChildACL(); @@ -171,7 +173,7 @@ class AddressBookTest extends TestCase { $this->assertEquals($expectedAcl, $childAcl); } - public function providesReadOnlyInfo(): array { + public static function providesReadOnlyInfo(): array { return [ 'read-only property not set' => [true, null, true], 'read-only property is false' => [true, false, true], diff --git a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php index aeee04fd6ee..5a1210da339 100644 --- a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.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,25 +15,19 @@ use OCA\DAV\DAV\GroupPrincipalBackend; use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\VObject\Component\VCalendar; use Sabre\VObject\Reader; use Test\TestCase; class BirthdayServiceTest extends TestCase { - /** @var BirthdayService */ - private $service; - /** @var CalDavBackend | \PHPUnit\Framework\MockObject\MockObject */ - private $calDav; - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject */ - private $cardDav; - /** @var GroupPrincipalBackend | \PHPUnit\Framework\MockObject\MockObject */ - private $groupPrincipalBackend; - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ - private $config; - /** @var IDBConnection | \PHPUnit\Framework\MockObject\MockObject */ - private $dbConnection; - /** @var IL10N | \PHPUnit\Framework\MockObject\MockObject */ - private $l10n; + private CalDavBackend&MockObject $calDav; + private CardDavBackend&MockObject $cardDav; + private GroupPrincipalBackend&MockObject $groupPrincipalBackend; + private IConfig&MockObject $config; + private IDBConnection&MockObject $dbConnection; + private IL10N&MockObject $l10n; + private BirthdayService $service; protected function setUp(): void { parent::setUp(); @@ -57,16 +52,8 @@ class BirthdayServiceTest extends TestCase { /** * @dataProvider providesVCards - * @param string $expectedSummary - * @param string $expectedDTStart - * @param string $expectedRrule - * @param string $expectedFieldType - * @param string $expectedUnknownYear - * @param string $expectedOriginalYear - * @param string|null $expectedReminder - * @param string | null $data */ - public function testBuildBirthdayFromContact($expectedSummary, $expectedDTStart, $expectedRrule, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Bytes, $configuredReminder): void { + public function testBuildBirthdayFromContact(?string $expectedSummary, ?string $expectedDTStart, ?string $expectedRrule, ?string $expectedFieldType, ?string $expectedUnknownYear, ?string $expectedOriginalYear, ?string $expectedReminder, ?string $data, string $fieldType, string $prefix, bool $supports4Bytes, ?string $configuredReminder): void { $this->dbConnection->method('supports4ByteText')->willReturn($supports4Bytes); $cal = $this->service->buildDateFromContact($data, $fieldType, $prefix, $configuredReminder); @@ -152,13 +139,17 @@ class BirthdayServiceTest extends TestCase { ->willReturn([ 'id' => 1234 ]); - $this->calDav->expects($this->exactly(3)) + $calls = [ + [1234, 'default-gump.vcf.ics'], + [1234, 'default-gump.vcf-death.ics'], + [1234, 'default-gump.vcf-anniversary.ics'], + ]; + $this->calDav->expects($this->exactly(count($calls))) ->method('deleteCalendarObject') - ->withConsecutive( - [1234, 'default-gump.vcf.ics'], - [1234, 'default-gump.vcf-death.ics'], - [1234, 'default-gump.vcf-anniversary.ics'], - ); + ->willReturnCallback(function ($calendarId, $objectUri) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, [$calendarId, $objectUri]); + }); $this->cardDav->expects($this->once())->method('getShares')->willReturn([]); $this->service->onCardDeleted(666, 'gump.vcf'); @@ -173,7 +164,7 @@ class BirthdayServiceTest extends TestCase { $this->cardDav->expects($this->never())->method('getAddressBookById'); $service = $this->getMockBuilder(BirthdayService::class) - ->setMethods(['buildDateFromContact', 'birthdayEvenChanged']) + ->onlyMethods(['buildDateFromContact', 'birthdayEvenChanged']) ->setConstructorArgs([$this->calDav, $this->cardDav, $this->groupPrincipalBackend, $this->config, $this->dbConnection, $this->l10n]) ->getMock(); @@ -200,9 +191,9 @@ class BirthdayServiceTest extends TestCase { $this->cardDav->expects($this->once())->method('getShares')->willReturn([]); $this->calDav->expects($this->never())->method('getCalendarByUri'); - /** @var BirthdayService | \PHPUnit\Framework\MockObject\MockObject $service */ + /** @var BirthdayService&MockObject $service */ $service = $this->getMockBuilder(BirthdayService::class) - ->setMethods(['buildDateFromContact', 'birthdayEvenChanged']) + ->onlyMethods(['buildDateFromContact', 'birthdayEvenChanged']) ->setConstructorArgs([$this->calDav, $this->cardDav, $this->groupPrincipalBackend, $this->config, $this->dbConnection, $this->l10n]) ->getMock(); @@ -212,7 +203,7 @@ class BirthdayServiceTest extends TestCase { /** * @dataProvider providesCardChanges */ - public function testOnCardChanged($expectedOp): void { + public function testOnCardChanged(string $expectedOp): void { $this->config->expects($this->once()) ->method('getAppValue') ->with('dav', 'generateBirthdayCalendar', 'yes') @@ -220,11 +211,10 @@ class BirthdayServiceTest extends TestCase { $this->config->expects($this->exactly(2)) ->method('getUserValue') - ->withConsecutive( - ['user01', 'dav', 'generateBirthdayCalendar', 'yes'], - ['user01', 'dav', 'birthdayCalendarReminderOffset', 'PT9H'], - ) - ->willReturnOnConsecutiveCalls('yes', 'PT9H'); + ->willReturnMap([ + ['user01', 'dav', 'generateBirthdayCalendar', 'yes', 'yes'], + ['user01', 'dav', 'birthdayCalendarReminderOffset', 'PT9H', 'PT9H'], + ]); $this->cardDav->expects($this->once())->method('getAddressBookById') ->with(666) @@ -239,31 +229,45 @@ class BirthdayServiceTest extends TestCase { ]); $this->cardDav->expects($this->once())->method('getShares')->willReturn([]); - /** @var BirthdayService | \PHPUnit\Framework\MockObject\MockObject $service */ + /** @var BirthdayService&MockObject $service */ $service = $this->getMockBuilder(BirthdayService::class) - ->setMethods(['buildDateFromContact', 'birthdayEvenChanged']) + ->onlyMethods(['buildDateFromContact', 'birthdayEvenChanged']) ->setConstructorArgs([$this->calDav, $this->cardDav, $this->groupPrincipalBackend, $this->config, $this->dbConnection, $this->l10n]) ->getMock(); if ($expectedOp === 'delete') { $this->calDav->expects($this->exactly(3))->method('getCalendarObject')->willReturn(''); $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn(null); - $this->calDav->expects($this->exactly(3))->method('deleteCalendarObject')->withConsecutive( + + $calls = [ [1234, 'default-gump.vcf.ics'], [1234, 'default-gump.vcf-death.ics'], [1234, 'default-gump.vcf-anniversary.ics'] - ); + ]; + $this->calDav->expects($this->exactly(count($calls))) + ->method('deleteCalendarObject') + ->willReturnCallback(function ($calendarId, $objectUri) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, [$calendarId, $objectUri]); + }); } if ($expectedOp === 'create') { $vCal = new VCalendar(); $vCal->PRODID = '-//Nextcloud testing//mocked object//'; $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn($vCal); - $this->calDav->expects($this->exactly(3))->method('createCalendarObject')->withConsecutive( + + $createCalendarObjectCalls = [ [1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"], [1234, 'default-gump.vcf-death.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"], [1234, 'default-gump.vcf-anniversary.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"] - ); + ]; + $this->calDav->expects($this->exactly(count($createCalendarObjectCalls))) + ->method('createCalendarObject') + ->willReturnCallback(function ($calendarId, $objectUri, $calendarData) use (&$createCalendarObjectCalls) { + $expected = array_shift($createCalendarObjectCalls); + $this->assertEquals($expected, [$calendarId, $objectUri, $calendarData]); + }); } if ($expectedOp === 'update') { $vCal = new VCalendar(); @@ -272,11 +276,18 @@ class BirthdayServiceTest extends TestCase { $service->expects($this->exactly(3))->method('buildDateFromContact')->willReturn($vCal); $service->expects($this->exactly(3))->method('birthdayEvenChanged')->willReturn(true); $this->calDav->expects($this->exactly(3))->method('getCalendarObject')->willReturn(['calendardata' => '']); - $this->calDav->expects($this->exactly(3))->method('updateCalendarObject')->withConsecutive( + + $updateCalendarObjectCalls = [ [1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"], [1234, 'default-gump.vcf-death.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"], [1234, 'default-gump.vcf-anniversary.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:-//Nextcloud testing//mocked object//\r\nEND:VCALENDAR\r\n"] - ); + ]; + $this->calDav->expects($this->exactly(count($updateCalendarObjectCalls))) + ->method('updateCalendarObject') + ->willReturnCallback(function ($calendarId, $objectUri, $calendarData) use (&$updateCalendarObjectCalls) { + $expected = array_shift($updateCalendarObjectCalls); + $this->assertEquals($expected, [$calendarId, $objectUri, $calendarData]); + }); } $service->onCardChanged(666, 'gump.vcf', ''); @@ -284,11 +295,8 @@ class BirthdayServiceTest extends TestCase { /** * @dataProvider providesBirthday - * @param $expected - * @param $old - * @param $new */ - public function testBirthdayEvenChanged($expected, $old, $new): void { + public function testBirthdayEvenChanged(bool $expected, string $old, string $new): void { $new = Reader::read($new); $this->assertEquals($expected, $this->service->birthdayEvenChanged($old, $new)); } @@ -354,18 +362,22 @@ class BirthdayServiceTest extends TestCase { ->with(42, 0) ->willReturn([['uri' => '1.ics'], ['uri' => '2.ics'], ['uri' => '3.ics']]); - $this->calDav->expects($this->exactly(3)) + $calls = [ + [42, '1.ics', 0], + [42, '2.ics', 0], + [42, '3.ics', 0], + ]; + $this->calDav->expects($this->exactly(count($calls))) ->method('deleteCalendarObject') - ->withConsecutive( - [42, '1.ics', 0], - [42, '2.ics', 0], - [42, '3.ics', 0], - ); + ->willReturnCallback(function ($calendarId, $objectUri, $calendarType) use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, [$calendarId, $objectUri, $calendarType]); + }); $this->service->resetForUser('user123'); } - public function providesBirthday() { + public static function providesBirthday(): array { return [ [true, '', @@ -382,7 +394,7 @@ class BirthdayServiceTest extends TestCase { ]; } - public function providesCardChanges() { + public static function providesCardChanges(): array { return[ ['delete'], ['create'], @@ -390,7 +402,7 @@ class BirthdayServiceTest extends TestCase { ]; } - public function providesVCards() { + public static function providesVCards(): array { return [ // $expectedSummary, $expectedDTStart, $expectedRrule, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Byte, $configuredReminder [null, null, null, null, null, null, null, 'yasfewf', '', '', true, null], diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php index 1516d41ea39..8a279d31b02 100644 --- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php +++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php @@ -29,6 +29,7 @@ use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Server; use OCP\Share\IManager as ShareManager; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\PropPatch; @@ -45,29 +46,15 @@ use function time; * @package OCA\DAV\Tests\unit\CardDAV */ class CardDavBackendTest extends TestCase { - /** @var CardDavBackend */ - private $backend; - - /** @var Principal | \PHPUnit\Framework\MockObject\MockObject */ - private $principal; - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ - private $groupManager; - - /** @var IEventDispatcher|MockObject */ - private $dispatcher; + private Principal&MockObject $principal; + private IUserManager&MockObject $userManager; + private IGroupManager&MockObject $groupManager; + private IEventDispatcher&MockObject $dispatcher; private Backend $sharingBackend; - /** @var IDBConnection */ - private $db; - - /** @var string */ - private $dbCardsTable = 'cards'; - - /** @var string */ - private $dbCardsPropertiesTable = 'cards_properties'; + private IDBConnection $db; + private CardDavBackend $backend; + private string $dbCardsTable = 'cards'; + private string $dbCardsPropertiesTable = 'cards_properties'; public const UNIT_TEST_USER = 'principals/users/carddav-unit-test'; public const UNIT_TEST_USER1 = 'principals/users/carddav-unit-test1'; @@ -122,7 +109,7 @@ class CardDavBackendTest extends TestCase { $this->createMock(IConfig::class), $this->createMock(IFactory::class) ]) - ->setMethods(['getPrincipalByPath', 'getGroupMembership', 'findByUri']) + ->onlyMethods(['getPrincipalByPath', 'getGroupMembership', 'findByUri']) ->getMock(); $this->principal->method('getPrincipalByPath') ->willReturn([ @@ -151,16 +138,20 @@ class CardDavBackendTest extends TestCase { ); // start every test with a empty cards_properties and cards table $query = $this->db->getQueryBuilder(); - $query->delete('cards_properties')->execute(); + $query->delete('cards_properties')->executeStatement(); $query = $this->db->getQueryBuilder(); - $query->delete('cards')->execute(); + $query->delete('cards')->executeStatement(); - $this->tearDown(); + $this->principal->method('getGroupMembership') + ->withAnyParameters() + ->willReturn([self::UNIT_TEST_GROUP]); + $books = $this->backend->getAddressBooksForUser(self::UNIT_TEST_USER); + foreach ($books as $book) { + $this->backend->deleteAddressBook($book['id']); + } } protected function tearDown(): void { - parent::tearDown(); - if (is_null($this->backend)) { return; } @@ -172,6 +163,8 @@ class CardDavBackendTest extends TestCase { foreach ($books as $book) { $this->backend->deleteAddressBook($book['id']); } + + parent::tearDown(); } public function testAddressBookOperations(): void { @@ -236,10 +229,11 @@ class CardDavBackendTest extends TestCase { } public function testCardOperations(): void { - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject $backend */ + /** @var CardDavBackend&MockObject $backend */ $backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->onlyMethods(['updateProperties', 'purgeProperties'])->getMock(); + ->onlyMethods(['updateProperties', 'purgeProperties']) + ->getMock(); // create a new address book $backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -249,12 +243,16 @@ class CardDavBackendTest extends TestCase { $uri = $this->getUniqueID('card'); // updateProperties is expected twice, once for createCard and once for updateCard - $backend->expects($this->exactly(2)) + $calls = [ + [$bookId, $uri, $this->vcardTest0], + [$bookId, $uri, $this->vcardTest1], + ]; + $backend->expects($this->exactly(count($calls))) ->method('updateProperties') - ->withConsecutive( - [$bookId, $uri, $this->vcardTest0], - [$bookId, $uri, $this->vcardTest1], - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); // Expect event $this->dispatcher @@ -294,7 +292,8 @@ class CardDavBackendTest extends TestCase { public function testMultiCard(): void { $this->backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->setMethods(['updateProperties'])->getMock(); + ->onlyMethods(['updateProperties']) + ->getMock(); // create a new address book $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -347,7 +346,8 @@ class CardDavBackendTest extends TestCase { public function testMultipleUIDOnDifferentAddressbooks(): void { $this->backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->onlyMethods(['updateProperties'])->getMock(); + ->onlyMethods(['updateProperties']) + ->getMock(); // create 2 new address books $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -369,7 +369,8 @@ class CardDavBackendTest extends TestCase { public function testMultipleUIDDenied(): void { $this->backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->setMethods(['updateProperties'])->getMock(); + ->onlyMethods(['updateProperties']) + ->getMock(); // create a new address book $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -390,7 +391,8 @@ class CardDavBackendTest extends TestCase { public function testNoValidUID(): void { $this->backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->setMethods(['updateProperties'])->getMock(); + ->onlyMethods(['updateProperties']) + ->getMock(); // create a new address book $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -428,12 +430,17 @@ class CardDavBackendTest extends TestCase { ->method('getCardId') ->with($bookId, $uri) ->willThrowException(new \InvalidArgumentException()); - $this->backend->expects($this->exactly(2)) + + $calls = [ + [$bookId, $uri, 1], + [$bookId, $uri, 3], + ]; + $this->backend->expects($this->exactly(count($calls))) ->method('addChange') - ->withConsecutive( - [$bookId, $uri, 1], - [$bookId, $uri, 3] - ); + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + }); $this->backend->expects($this->never()) ->method('purgeProperties'); @@ -447,7 +454,8 @@ class CardDavBackendTest extends TestCase { public function testSyncSupport(): void { $this->backend = $this->getMockBuilder(CardDavBackend::class) ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->dispatcher, $this->sharingBackend]) - ->setMethods(['updateProperties'])->getMock(); + ->onlyMethods(['updateProperties']) + ->getMock(); // create a new address book $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -639,13 +647,8 @@ class CardDavBackendTest extends TestCase { /** * @dataProvider dataTestSearch - * - * @param string $pattern - * @param array $properties - * @param array $options - * @param array $expected */ - public function testSearch($pattern, $properties, $options, $expected): void { + public function testSearch(string $pattern, array $properties, array $options, array $expected): void { /** @var VCard $vCards */ $vCards = []; $vCards[0] = new VCard(); @@ -756,7 +759,7 @@ class CardDavBackendTest extends TestCase { $this->assertSame(count($expected), count($found)); } - public function dataTestSearch() { + public static function dataTestSearch(): array { return [ ['John', ['FN'], [], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]], ['M. Doe', ['FN'], [], [['uri1', 'John M. Doe']]], diff --git a/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php b/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php index 80f1f2a4445..bdd826f671b 100644 --- a/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php +++ b/apps/dav/tests/unit/CardDAV/ContactsManagerTest.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,16 +14,17 @@ use OCA\DAV\Db\PropertyMapper; use OCP\Contacts\IManager; use OCP\IL10N; use OCP\IURLGenerator; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class ContactsManagerTest extends TestCase { public function test(): void { - /** @var IManager | \PHPUnit\Framework\MockObject\MockObject $cm */ - $cm = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); + /** @var IManager&MockObject $cm */ + $cm = $this->createMock(IManager::class); $cm->expects($this->exactly(2))->method('registerAddressBook'); - $urlGenerator = $this->getMockBuilder(IURLGenerator::class)->disableOriginalConstructor()->getMock(); - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject $backEnd */ - $backEnd = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + $urlGenerator = $this->createMock(IURLGenerator::class); + /** @var CardDavBackend&MockObject $backEnd */ + $backEnd = $this->createMock(CardDavBackend::class); $backEnd->method('getAddressBooksForUser')->willReturn([ ['{DAV:}displayname' => 'Test address book', 'uri' => 'default'], ]); diff --git a/apps/dav/tests/unit/CardDAV/ConverterTest.php b/apps/dav/tests/unit/CardDAV/ConverterTest.php index c29e0db5070..59042ed91d4 100644 --- a/apps/dav/tests/unit/CardDAV/ConverterTest.php +++ b/apps/dav/tests/unit/CardDAV/ConverterTest.php @@ -22,17 +22,10 @@ use Psr\Log\LoggerInterface; use Test\TestCase; class ConverterTest extends TestCase { - - /** @var IAccountManager|\PHPUnit\Framework\MockObject\MockObject */ - private $accountManager; - /** @var IUserManager|(IUserManager&MockObject)|MockObject */ - private IUserManager|MockObject $userManager; - - /** @var IURLGenerator */ - private $urlGenerator; - - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $logger; + private IAccountManager&MockObject $accountManager; + private IUserManager&MockObject $userManager; + private IURLGenerator&MockObject $urlGenerator; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); @@ -44,7 +37,7 @@ class ConverterTest extends TestCase { } /** - * @return IAccountProperty|MockObject + * @return IAccountProperty&MockObject */ protected function getAccountPropertyMock(string $name, ?string $value, string $scope) { $property = $this->createMock(IAccountProperty::class); @@ -77,10 +70,11 @@ class ConverterTest extends TestCase { yield $this->getAccountPropertyMock(IAccountManager::PROPERTY_TWITTER, '', IAccountManager::SCOPE_LOCAL); }); - $accountManager = $this->getMockBuilder(IAccountManager::class) - ->disableOriginalConstructor()->getMock(); + $accountManager = $this->createMock(IAccountManager::class); - $accountManager->expects($this->any())->method('getAccount')->willReturn($account); + $accountManager->expects($this->any()) + ->method('getAccount') + ->willReturn($account); return $accountManager; } @@ -126,7 +120,7 @@ class ConverterTest extends TestCase { ); } - protected function compareData($expected, $data) { + protected function compareData(array $expected, array $data): void { foreach ($expected as $key => $value) { $found = false; foreach ($data[1] as $d) { @@ -141,7 +135,7 @@ class ConverterTest extends TestCase { } } - public function providesNewUsers() { + public static function providesNewUsers(): array { return [ [ null @@ -197,17 +191,15 @@ class ConverterTest extends TestCase { /** * @dataProvider providesNames - * @param $expected - * @param $fullName */ - public function testNameSplitter($expected, $fullName): void { + public function testNameSplitter(string $expected, string $fullName): void { $converter = new Converter($this->accountManager, $this->userManager, $this->urlGenerator, $this->logger); $r = $converter->splitFullName($fullName); $r = implode(';', $r); $this->assertEquals($expected, $r); } - public function providesNames() { + public static function providesNames(): array { return [ ['Sauron;;;;', 'Sauron'], ['Baggins;Bilbo;;;', 'Bilbo Baggins'], @@ -216,16 +208,13 @@ class ConverterTest extends TestCase { } /** - * @param $displayName - * @param $eMailAddress - * @param $cloudId - * @return IUser | \PHPUnit\Framework\MockObject\MockObject + * @return IUser&MockObject */ protected function getUserMock(string $displayName, ?string $eMailAddress, ?string $cloudId) { - $image0 = $this->getMockBuilder(IImage::class)->disableOriginalConstructor()->getMock(); + $image0 = $this->createMock(IImage::class); $image0->method('mimeType')->willReturn('image/jpeg'); $image0->method('data')->willReturn('123456789'); - $user = $this->getMockBuilder(IUser::class)->disableOriginalConstructor()->getMock(); + $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn('12345'); $user->method('getDisplayName')->willReturn($displayName); $user->method('getEMailAddress')->willReturn($eMailAddress); diff --git a/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php index d5c864d3e4e..8396234a819 100644 --- a/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php +++ b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.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,6 +14,7 @@ use OCA\DAV\CardDAV\PhotoCache; use OCP\AppFramework\Http; use OCP\Files\NotFoundException; use OCP\Files\SimpleFS\ISimpleFile; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\CardDAV\Card; use Sabre\DAV\Node; use Sabre\DAV\Server; @@ -22,18 +24,12 @@ use Sabre\HTTP\ResponseInterface; use Test\TestCase; class ImageExportPluginTest extends TestCase { - /** @var ResponseInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $response; - /** @var RequestInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $request; - /** @var ImageExportPlugin|\PHPUnit\Framework\MockObject\MockObject */ - private $plugin; - /** @var Server */ - private $server; - /** @var Tree|\PHPUnit\Framework\MockObject\MockObject */ - private $tree; - /** @var PhotoCache|\PHPUnit\Framework\MockObject\MockObject */ - private $cache; + private ResponseInterface&MockObject $response; + private RequestInterface&MockObject $request; + private Server&MockObject $server; + private Tree&MockObject $tree; + private PhotoCache&MockObject $cache; + private ImageExportPlugin $plugin; protected function setUp(): void { parent::setUp(); @@ -45,24 +41,20 @@ class ImageExportPluginTest extends TestCase { $this->server->tree = $this->tree; $this->cache = $this->createMock(PhotoCache::class); - $this->plugin = $this->getMockBuilder(ImageExportPlugin::class) - ->setMethods(['getPhoto']) - ->setConstructorArgs([$this->cache]) - ->getMock(); + $this->plugin = new ImageExportPlugin($this->cache); $this->plugin->initialize($this->server); } /** * @dataProvider providesQueryParams - * @param $param */ - public function testQueryParams($param): void { + public function testQueryParams(array $param): void { $this->request->expects($this->once())->method('getQueryParameters')->willReturn($param); $result = $this->plugin->httpGet($this->request, $this->response); $this->assertTrue($result); } - public function providesQueryParams() { + public static function providesQueryParams(): array { return [ [[]], [['1']], @@ -87,7 +79,7 @@ class ImageExportPluginTest extends TestCase { $this->assertTrue($result); } - public function dataTestCard() { + public static function dataTestCard(): array { return [ [null, false], [null, true], @@ -98,11 +90,8 @@ class ImageExportPluginTest extends TestCase { /** * @dataProvider dataTestCard - * - * @param $size - * @param bool $photo */ - public function testCard($size, $photo): void { + public function testCard(?int $size, bool $photo): void { $query = ['photo' => null]; if ($size !== null) { $query['size'] = $size; @@ -145,14 +134,18 @@ class ImageExportPluginTest extends TestCase { ->with(1, 'card', $size, $card) ->willReturn($file); - $this->response->expects($this->exactly(4)) + $setHeaderCalls = [ + ['Cache-Control', 'private, max-age=3600, must-revalidate'], + ['Etag', '"myEtag"'], + ['Content-Type', 'image/jpeg'], + ['Content-Disposition', 'attachment; filename=card.jpg'], + ]; + $this->response->expects($this->exactly(count($setHeaderCalls))) ->method('setHeader') - ->withConsecutive( - ['Cache-Control', 'private, max-age=3600, must-revalidate'], - ['Etag', '"myEtag"'], - ['Content-Type', 'image/jpeg'], - ['Content-Disposition', 'attachment; filename=card.jpg'], - ); + ->willReturnCallback(function () use (&$setHeaderCalls) { + $expected = array_shift($setHeaderCalls); + $this->assertEquals($expected, func_get_args()); + }); $this->response->expects($this->once()) ->method('setStatus') @@ -161,12 +154,16 @@ class ImageExportPluginTest extends TestCase { ->method('setBody') ->with('imgdata'); } else { - $this->response->expects($this->exactly(2)) + $setHeaderCalls = [ + ['Cache-Control', 'private, max-age=3600, must-revalidate'], + ['Etag', '"myEtag"'], + ]; + $this->response->expects($this->exactly(count($setHeaderCalls))) ->method('setHeader') - ->withConsecutive( - ['Cache-Control', 'private, max-age=3600, must-revalidate'], - ['Etag', '"myEtag"'], - ); + ->willReturnCallback(function () use (&$setHeaderCalls) { + $expected = array_shift($setHeaderCalls); + $this->assertEquals($expected, func_get_args()); + }); $this->cache->method('get') ->with(1, 'card', $size, $card) ->willThrowException(new NotFoundException()); diff --git a/apps/dav/tests/unit/CardDAV/Security/CardDavRateLimitingPluginTest.php b/apps/dav/tests/unit/CardDAV/Security/CardDavRateLimitingPluginTest.php index 33ab83a74ac..ee599d5a76c 100644 --- a/apps/dav/tests/unit/CardDAV/Security/CardDavRateLimitingPluginTest.php +++ b/apps/dav/tests/unit/CardDAV/Security/CardDavRateLimitingPluginTest.php @@ -24,11 +24,11 @@ use Test\TestCase; class CardDavRateLimitingPluginTest extends TestCase { - private Limiter|MockObject $limiter; - private CardDavBackend|MockObject $cardDavBackend; - private IUserManager|MockObject $userManager; - private LoggerInterface|MockObject $logger; - private IAppConfig|MockObject $config; + private Limiter&MockObject $limiter; + private CardDavBackend&MockObject $cardDavBackend; + private IUserManager&MockObject $userManager; + private LoggerInterface&MockObject $logger; + private IAppConfig&MockObject $config; private string $userId = 'user123'; private CardDavRateLimitingPlugin $plugin; diff --git a/apps/dav/tests/unit/CardDAV/Sharing/PluginTest.php b/apps/dav/tests/unit/CardDAV/Sharing/PluginTest.php index f35eb9f0040..1e934a69a53 100644 --- a/apps/dav/tests/unit/CardDAV/Sharing/PluginTest.php +++ b/apps/dav/tests/unit/CardDAV/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,31 +21,25 @@ 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->method('isDavAuthenticated')->willReturn(true); - - /** @var IRequest $request */ - $request = $this->getMockBuilder(IRequest::class)->disableOriginalConstructor()->getMock(); + $authBackend = $this->createMock(Auth::class); + $authBackend->method('isDavAuthenticated') + ->willReturn(true); + $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->method('getName')->willReturn('addressbook1.vcf'); + $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/CardDAV/SyncServiceTest.php b/apps/dav/tests/unit/CardDAV/SyncServiceTest.php index 5af42e2ea4e..fd31ef36528 100644 --- a/apps/dav/tests/unit/CardDAV/SyncServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/SyncServiceTest.php @@ -20,6 +20,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Http\Client\ClientExceptionInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; @@ -28,15 +29,18 @@ use Test\TestCase; class SyncServiceTest extends TestCase { - protected CardDavBackend $backend; - protected IUserManager $userManager; - protected IDBConnection $dbConnection; + protected CardDavBackend&MockObject $backend; + protected IUserManager&MockObject $userManager; + protected IDBConnection&MockObject $dbConnection; protected LoggerInterface $logger; - protected Converter $converter; - protected IClient $client; - protected IConfig $config; + protected Converter&MockObject $converter; + protected IClient&MockObject $client; + protected IConfig&MockObject $config; protected SyncService $service; + public function setUp(): void { + parent::setUp(); + $addressBook = [ 'id' => 1, 'uri' => 'system', @@ -293,8 +297,8 @@ END:VCARD'; } public function testEnsureSystemAddressBookExists(): void { - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject $backend */ - $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); + /** @var CardDavBackend&MockObject $backend */ + $backend = $this->createMock(CardDavBackend::class); $backend->expects($this->exactly(1))->method('createAddressBook'); $backend->expects($this->exactly(2)) ->method('getAddressBooksByUri') @@ -303,10 +307,9 @@ END:VCARD'; [], ); - /** @var IUserManager $userManager */ - $userManager = $this->getMockBuilder(IUserManager::class)->disableOriginalConstructor()->getMock(); + $userManager = $this->createMock(IUserManager::class); $dbConnection = $this->createMock(IDBConnection::class); - $logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock(); + $logger = $this->createMock(LoggerInterface::class); $converter = $this->createMock(Converter::class); $clientService = $this->createMock(IClientService::class); $config = $this->createMock(IConfig::class); @@ -315,7 +318,7 @@ END:VCARD'; $ss->ensureSystemAddressBookExists('principals/users/adam', 'contacts', []); } - public function dataActivatedUsers() { + public static function dataActivatedUsers(): array { return [ [true, 1, 1, 1], [false, 0, 0, 3], @@ -324,15 +327,9 @@ END:VCARD'; /** * @dataProvider dataActivatedUsers - * - * @param boolean $activated - * @param integer $createCalls - * @param integer $updateCalls - * @param integer $deleteCalls - * @return void */ - public function testUpdateAndDeleteUser($activated, $createCalls, $updateCalls, $deleteCalls): void { - /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject $backend */ + public function testUpdateAndDeleteUser(bool $activated, int $createCalls, int $updateCalls, int $deleteCalls): void { + /** @var CardDavBackend | MockObject $backend */ $backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock(); $logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock(); @@ -348,12 +345,9 @@ END:VCARD'; ->with('principals/system/system', 'system') ->willReturn(['id' => -1]); - /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject $userManager */ - $userManager = $this->getMockBuilder(IUserManager::class)->disableOriginalConstructor()->getMock(); + $userManager = $this->createMock(IUserManager::class); $dbConnection = $this->createMock(IDBConnection::class); - - /** @var IUser | \PHPUnit\Framework\MockObject\MockObject $user */ - $user = $this->getMockBuilder(IUser::class)->disableOriginalConstructor()->getMock(); + $user = $this->createMock(IUser::class); $user->method('getBackendClassName')->willReturn('unittest'); $user->method('getUID')->willReturn('test-user'); $user->method('getCloudId')->willReturn('cloudId'); @@ -475,7 +469,7 @@ END:VCARD'; ); } - public function providerUseAbsoluteUriReport(): array { + public static function providerUseAbsoluteUriReport(): array { return [ ['https://server.internal', 'https://server.internal/remote.php/dav/addressbooks/system/system/system'], ['https://server.internal/', 'https://server.internal/remote.php/dav/addressbooks/system/system/system'], diff --git a/apps/dav/tests/unit/CardDAV/SystemAddressBookTest.php b/apps/dav/tests/unit/CardDAV/SystemAddressBookTest.php index 806c71759f8..4a218fa4616 100644 --- a/apps/dav/tests/unit/CardDAV/SystemAddressBookTest.php +++ b/apps/dav/tests/unit/CardDAV/SystemAddressBookTest.php @@ -30,15 +30,15 @@ use Sabre\VObject\Reader; use Test\TestCase; class SystemAddressBookTest extends TestCase { - private MockObject|BackendInterface $cardDavBackend; + private BackendInterface&MockObject $cardDavBackend; private array $addressBookInfo; - private IL10N|MockObject $l10n; - private IConfig|MockObject $config; + private IL10N&MockObject $l10n; + private IConfig&MockObject $config; private IUserSession $userSession; - private IRequest|MockObject $request; + private IRequest&MockObject $request; private array $server; - private TrustedServers|MockObject $trustedServers; - private IGroupManager|MockObject $groupManager; + private TrustedServers&MockObject $trustedServers; + private IGroupManager&MockObject $groupManager; private SystemAddressbook $addressBook; protected function setUp(): void { diff --git a/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php index 39155aace8b..058735ba32a 100644 --- a/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php +++ b/apps/dav/tests/unit/CardDAV/Validation/CardDavValidatePluginTest.php @@ -20,9 +20,9 @@ use Test\TestCase; class CardDavValidatePluginTest extends TestCase { private CardDavValidatePlugin $plugin; - private IAppConfig|MockObject $config; - private RequestInterface|MockObject $request; - private ResponseInterface|MockObject $response; + private IAppConfig&MockObject $config; + private RequestInterface&MockObject $request; + private ResponseInterface&MockObject $response; protected function setUp(): void { parent::setUp(); @@ -36,7 +36,7 @@ class CardDavValidatePluginTest extends TestCase { } public function testPutSizeLessThenLimit(): void { - + // construct method responses $this->config ->method('getValueInt') @@ -50,11 +50,11 @@ class CardDavValidatePluginTest extends TestCase { $this->assertTrue( $this->plugin->beforePut($this->request, $this->response) ); - + } public function testPutSizeMoreThenLimit(): void { - + // construct method responses $this->config ->method('getValueInt') @@ -67,7 +67,7 @@ class CardDavValidatePluginTest extends TestCase { $this->expectException(Forbidden::class); // test condition $this->plugin->beforePut($this->request, $this->response); - + } } diff --git a/apps/dav/tests/unit/Command/DeleteCalendarTest.php b/apps/dav/tests/unit/Command/DeleteCalendarTest.php index b621e6737d5..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; @@ -28,23 +28,12 @@ class DeleteCalendarTest extends TestCase { public const USER = 'user'; public const NAME = 'calendar'; - /** @var CalDavBackend|MockObject */ - private $calDav; - - /** @var IConfig|MockObject */ - private $config; - - /** @var IL10N|MockObject */ - private $l10n; - - /** @var IUserManager|MockObject */ - private $userManager; - - /** @var DeleteCalendar */ - private $command; - - /** @var MockObject|LoggerInterface */ - private $logger; + private CalDavBackend&MockObject $calDav; + private IConfig&MockObject $config; + private IL10N&MockObject $l10n; + private IUserManager&MockObject $userManager; + private LoggerInterface&MockObject $logger; + private DeleteCalendar $command; protected function setUp(): void { parent::setUp(); diff --git a/apps/dav/tests/unit/Command/ListAddressbooksTest.php b/apps/dav/tests/unit/Command/ListAddressbooksTest.php index 2c6b1579042..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; @@ -20,9 +20,8 @@ use Test\TestCase; * @package OCA\DAV\Tests\Command */ class ListAddressbooksTest extends TestCase { - - private IUserManager|MockObject $userManager; - private CardDavBackend|MockObject $cardDavBackend; + private IUserManager&MockObject $userManager; + private CardDavBackend&MockObject $cardDavBackend; private ListAddressbooks $command; public const USERNAME = 'username'; @@ -72,7 +71,7 @@ class ListAddressbooksTest extends TestCase { $this->assertStringContainsString('User <' . self::USERNAME . "> has no addressbooks\n", $commandTester->getDisplay()); } - public function dataExecute() { + public static function dataExecute(): array { return [ [false, '✓'], [true, 'x'] 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 1f5f9882ac4..247487433eb 100644 --- a/apps/dav/tests/unit/Command/ListCalendarsTest.php +++ b/apps/dav/tests/unit/Command/ListCalendarsTest.php @@ -1,14 +1,17 @@ <?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\Command; +namespace OCA\DAV\Tests\unit\Command; use OCA\DAV\CalDAV\BirthdayService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Command\ListCalendars; use OCP\IUserManager; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Tester\CommandTester; use Test\TestCase; @@ -18,15 +21,9 @@ use Test\TestCase; * @package OCA\DAV\Tests\Command */ class ListCalendarsTest extends TestCase { - - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject $userManager */ - private $userManager; - - /** @var CalDavBackend|\PHPUnit\Framework\MockObject\MockObject $l10n */ - private $calDav; - - /** @var ListCalendars */ - private $command; + private IUserManager&MockObject $userManager; + private CalDavBackend&MockObject $calDav; + private ListCalendars $command; public const USERNAME = 'username'; @@ -75,7 +72,7 @@ class ListCalendarsTest extends TestCase { $this->assertStringContainsString('User <' . self::USERNAME . "> has no calendars\n", $commandTester->getDisplay()); } - public function dataExecute() { + public static function dataExecute(): array { return [ [false, '✓'], [true, 'x'] diff --git a/apps/dav/tests/unit/Command/MoveCalendarTest.php b/apps/dav/tests/unit/Command/MoveCalendarTest.php index 9b935ca3cdb..c481f5cf15b 100644 --- a/apps/dav/tests/unit/Command/MoveCalendarTest.php +++ b/apps/dav/tests/unit/Command/MoveCalendarTest.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\Command; +namespace OCA\DAV\Tests\unit\Command; use InvalidArgumentException; use OCA\DAV\CalDAV\CalDavBackend; @@ -24,29 +26,14 @@ use Test\TestCase; * @package OCA\DAV\Tests\Command */ class MoveCalendarTest extends TestCase { - /** @var IUserManager|MockObject $userManager */ - private $userManager; - - /** @var IGroupManager|MockObject $groupManager */ - private $groupManager; - - /** @var \OCP\Share\IManager|MockObject $shareManager */ - private $shareManager; - - /** @var IConfig|MockObject $l10n */ - private $config; - - /** @var IL10N|MockObject $l10n */ - private $l10n; - - /** @var CalDavBackend|MockObject $l10n */ - private $calDav; - - /** @var MoveCalendar */ - private $command; - - /** @var LoggerInterface|MockObject */ - private $logger; + private IUserManager&MockObject $userManager; + private IGroupManager&MockObject $groupManager; + private \OCP\Share\IManager&MockObject $shareManager; + private IConfig&MockObject $config; + private IL10N&MockObject $l10n; + private CalDavBackend&MockObject $calDav; + private LoggerInterface&MockObject $logger; + private MoveCalendar $command; protected function setUp(): void { parent::setUp(); @@ -70,7 +57,7 @@ class MoveCalendarTest extends TestCase { ); } - public function dataExecute() { + public static function dataExecute(): array { return [ [false, true], [true, false] @@ -79,23 +66,16 @@ class MoveCalendarTest extends TestCase { /** * @dataProvider dataExecute - * - * @param $userOriginExists - * @param $userDestinationExists */ - public function testWithBadUserOrigin($userOriginExists, $userDestinationExists): void { + public function testWithBadUserOrigin(bool $userOriginExists, bool $userDestinationExists): void { $this->expectException(\InvalidArgumentException::class); $this->userManager->expects($this->exactly($userOriginExists ? 2 : 1)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturnOnConsecutiveCalls( - $userOriginExists, - $userDestinationExists, - ); + ->willReturnMap([ + ['user', $userOriginExists], + ['user2', $userDestinationExists], + ]); $commandTester = new CommandTester($this->command); $commandTester->execute([ @@ -112,11 +92,10 @@ class MoveCalendarTest extends TestCase { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->once())->method('getCalendarByUri') ->with('principals/users/user', 'personal') @@ -137,20 +116,20 @@ class MoveCalendarTest extends TestCase { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturn([ - 'id' => 1234, + ->willReturnMap([ + ['principals/users/user', 'personal', [ + 'id' => 1234, + ]], + ['principals/users/user2', 'personal', [ + 'id' => 1234, + ]], ]); $commandTester = new CommandTester($this->command); @@ -164,24 +143,19 @@ class MoveCalendarTest extends TestCase { public function testMove(): void { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturnOnConsecutiveCalls( - [ + ->willReturnMap([ + ['principals/users/user', 'personal', [ 'id' => 1234, - ], - null, - ); + ]], + ['principals/users/user2', 'personal', null], + ]); $this->calDav->expects($this->once())->method('getShares') ->with(1234) @@ -197,7 +171,7 @@ class MoveCalendarTest extends TestCase { $this->assertStringContainsString('[OK] Calendar <personal> was moved from user <user> to <user2>', $commandTester->getDisplay()); } - public function dataTestMoveWithDestinationNotPartOfGroup(): array { + public static function dataTestMoveWithDestinationNotPartOfGroup(): array { return [ [true], [false] @@ -210,25 +184,20 @@ class MoveCalendarTest extends TestCase { public function testMoveWithDestinationNotPartOfGroup(bool $shareWithGroupMembersOnly): void { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturnOnConsecutiveCalls( - [ + ->willReturnMap([ + ['principals/users/user', 'personal', [ 'id' => 1234, 'uri' => 'personal', - ], - null, - ); + ]], + ['principals/users/user2', 'personal', null], + ]); $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly') ->willReturn($shareWithGroupMembersOnly); @@ -254,25 +223,20 @@ class MoveCalendarTest extends TestCase { public function testMoveWithDestinationPartOfGroup(): void { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturnOnConsecutiveCalls( - [ + ->willReturnMap([ + ['principals/users/user', 'personal', [ 'id' => 1234, 'uri' => 'personal', - ], - null, - ); + ]], + ['principals/users/user2', 'personal', null], + ]); $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly') ->willReturn(true); @@ -300,26 +264,21 @@ class MoveCalendarTest extends TestCase { public function testMoveWithDestinationNotPartOfGroupAndForce(): void { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturnOnConsecutiveCalls( - [ + ->willReturnMap([ + ['principals/users/user', 'personal', [ 'id' => 1234, 'uri' => 'personal', '{DAV:}displayname' => 'Personal' - ], - null, - ); + ]], + ['principals/users/user2', 'personal', null], + ]); $this->shareManager->expects($this->once())->method('shareWithGroupMembersOnly') ->willReturn(true); @@ -345,7 +304,7 @@ class MoveCalendarTest extends TestCase { $this->assertStringContainsString('[OK] Calendar <personal> was moved from user <user> to <user2>', $commandTester->getDisplay()); } - public function dataTestMoveWithCalendarAlreadySharedToDestination(): array { + public static function dataTestMoveWithCalendarAlreadySharedToDestination(): array { return [ [true], [false] @@ -358,26 +317,21 @@ class MoveCalendarTest extends TestCase { public function testMoveWithCalendarAlreadySharedToDestination(bool $force): void { $this->userManager->expects($this->exactly(2)) ->method('userExists') - ->withConsecutive( - ['user'], - ['user2'], - ) - ->willReturn(true); + ->willReturnMap([ + ['user', true], + ['user2', true], + ]); $this->calDav->expects($this->exactly(2)) ->method('getCalendarByUri') - ->withConsecutive( - ['principals/users/user', 'personal'], - ['principals/users/user2', 'personal'], - ) - ->willReturnOnConsecutiveCalls( - [ + ->willReturnMap([ + ['principals/users/user', 'personal', [ 'id' => 1234, 'uri' => 'personal', '{DAV:}displayname' => 'Personal' - ], - null, - ); + ]], + ['principals/users/user2', 'personal', null], + ]); $this->calDav->expects($this->once())->method('getShares') ->with(1234) diff --git a/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php b/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php index f2346c211ce..ec56aa64eb2 100644 --- a/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php +++ b/apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php @@ -1,16 +1,16 @@ <?php +declare(strict_types=1); /** * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors * 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; use OCP\IDBConnection; -use OCP\Migration\IOutput; use OCP\Server; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -37,18 +37,16 @@ class RemoveInvalidSharesTest extends TestCase { public function test(): void { $db = Server::get(IDBConnection::class); - /** @var Principal | \PHPUnit\Framework\MockObject\MockObject $principal */ $principal = $this->createMock(Principal::class); - /** @var IOutput | \PHPUnit\Framework\MockObject\MockObject $output */ - $output = $this->createMock(IOutput::class); - $repair = new RemoveInvalidShares($db, $principal); $this->invokePrivate($repair, 'run', [$this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)]); $query = $db->getQueryBuilder(); - $result = $query->select('*')->from('dav_shares') - ->where($query->expr()->eq('principaluri', $query->createNamedParameter('principal:unknown')))->execute(); + $query->select('*') + ->from('dav_shares') + ->where($query->expr()->eq('principaluri', $query->createNamedParameter('principal:unknown'))); + $result = $query->executeQuery(); $data = $result->fetchAll(); $result->closeCursor(); $this->assertEquals(0, count($data)); diff --git a/apps/dav/tests/unit/Comments/CommentsNodeTest.php b/apps/dav/tests/unit/Comments/CommentsNodeTest.php index c253c59df0f..40da2e523c7 100644 --- a/apps/dav/tests/unit/Comments/CommentsNodeTest.php +++ b/apps/dav/tests/unit/Comments/CommentsNodeTest.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,38 +15,26 @@ use OCP\Comments\MessageTooLongException; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\DAV\PropPatch; class CommentsNodeTest extends \Test\TestCase { - - /** @var ICommentsManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $commentsManager; - - protected $comment; - protected $node; - protected $userManager; - protected $logger; - protected $userSession; + protected ICommentsManager&MockObject $commentsManager; + protected IComment&MockObject $comment; + protected IUserManager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected CommentNode $node; protected function setUp(): void { parent::setUp(); - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->comment = $this->getMockBuilder(IComment::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->comment = $this->createMock(IComment::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->node = new CommentNode( $this->commentsManager, @@ -57,10 +46,7 @@ class CommentsNodeTest extends \Test\TestCase { } public function testDelete(): void { - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('alice'); @@ -92,10 +78,7 @@ class CommentsNodeTest extends \Test\TestCase { public function testDeleteForbidden(): void { $this->expectException(\Sabre\DAV\Exception\Forbidden::class); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('mallory'); @@ -144,10 +127,7 @@ class CommentsNodeTest extends \Test\TestCase { public function testUpdateComment(): void { $msg = 'Hello Earth'; - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('alice'); @@ -182,10 +162,7 @@ class CommentsNodeTest extends \Test\TestCase { $msg = null; - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('alice'); @@ -221,10 +198,7 @@ class CommentsNodeTest extends \Test\TestCase { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('Message exceeds allowed character limit of'); - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('alice'); @@ -261,10 +235,7 @@ class CommentsNodeTest extends \Test\TestCase { $msg = 'HaXX0r'; - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('getUID') ->willReturn('mallory'); @@ -296,10 +267,7 @@ class CommentsNodeTest extends \Test\TestCase { $msg = 'HaXX0r'; - $user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - + $user = $this->createMock(IUser::class); $user->expects($this->never()) ->method('getUID'); @@ -344,10 +312,7 @@ class CommentsNodeTest extends \Test\TestCase { } public function testPropPatch(): void { - $propPatch = $this->getMockBuilder(PropPatch::class) - ->disableOriginalConstructor() - ->getMock(); - + $propPatch = $this->createMock(PropPatch::class); $propPatch->expects($this->once()) ->method('handle') ->with('{http://owncloud.org/ns}message'); @@ -396,11 +361,10 @@ class CommentsNodeTest extends \Test\TestCase { $this->commentsManager->expects($this->exactly(2)) ->method('resolveDisplayName') - ->withConsecutive( - [$this->equalTo('user'), $this->equalTo('alice')], - [$this->equalTo('user'), $this->equalTo('bob')] - ) - ->willReturnOnConsecutiveCalls('Alice Al-Isson', 'Unknown user'); + ->willReturnMap([ + ['user', 'alice', 'Alice Al-Isson'], + ['user', 'bob', 'Unknown user'] + ]); $this->comment->expects($this->once()) ->method('getId') @@ -491,7 +455,7 @@ class CommentsNodeTest extends \Test\TestCase { $this->assertTrue(empty($expected)); } - public function readCommentProvider() { + public static function readCommentProvider(): array { $creationDT = new \DateTime('2016-01-19 18:48:00'); $diff = new \DateInterval('PT2H'); $readDT1 = clone $creationDT; @@ -507,9 +471,8 @@ class CommentsNodeTest extends \Test\TestCase { /** * @dataProvider readCommentProvider - * @param $expected */ - public function testGetPropertiesUnreadProperty($creationDT, $readDT, $expected): void { + public function testGetPropertiesUnreadProperty(\DateTime $creationDT, ?\DateTime $readDT, string $expected): void { $this->comment->expects($this->any()) ->method('getCreationDateTime') ->willReturn($creationDT); diff --git a/apps/dav/tests/unit/Comments/CommentsPluginTest.php b/apps/dav/tests/unit/Comments/CommentsPluginTest.php index 5ca0cedf04b..35638391e67 100644 --- a/apps/dav/tests/unit/Comments/CommentsPluginTest.php +++ b/apps/dav/tests/unit/Comments/CommentsPluginTest.php @@ -14,44 +14,30 @@ use OCP\Comments\IComment; use OCP\Comments\ICommentsManager; use OCP\IUser; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Sabre\DAV\INode; use Sabre\DAV\Tree; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; class CommentsPluginTest extends \Test\TestCase { - /** @var \Sabre\DAV\Server */ - private $server; - - /** @var Tree */ - private $tree; - - /** @var ICommentsManager */ - private $commentsManager; - - /** @var IUserSession */ - private $userSession; - - /** @var CommentsPluginImplementation */ - private $plugin; + private \Sabre\DAV\Server&MockObject $server; + private Tree&MockObject $tree; + private ICommentsManager&MockObject $commentsManager; + private IUserSession&MockObject $userSession; + private CommentsPluginImplementation $plugin; protected function setUp(): void { parent::setUp(); - $this->tree = $this->getMockBuilder(Tree::class) - ->disableOriginalConstructor() - ->getMock(); + $this->tree = $this->createMock(Tree::class); - $this->server = $this->getMockBuilder('\Sabre\DAV\Server') + $this->server = $this->getMockBuilder(\Sabre\DAV\Server::class) ->setConstructorArgs([$this->tree]) - ->setMethods(['getRequestUri']) + ->onlyMethods(['getRequestUri']) ->getMock(); - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->userSession = $this->createMock(IUserSession::class); $this->plugin = new CommentsPluginImplementation($this->commentsManager, $this->userSession); } @@ -151,7 +137,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testCreateCommentInvalidObject(): void { $this->expectException(\Sabre\DAV\Exception\NotFound::class); @@ -233,7 +219,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testCreateCommentInvalidActor(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); @@ -321,7 +307,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testCreateCommentUnsupportedMediaType(): void { $this->expectException(\Sabre\DAV\Exception\UnsupportedMediaType::class); @@ -409,7 +395,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testCreateCommentInvalidPayload(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); @@ -503,7 +489,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testCreateCommentMessageTooLong(): void { $this->expectException(\Sabre\DAV\Exception\BadRequest::class); $this->expectExceptionMessage('Message exceeds allowed character limit of'); @@ -597,7 +583,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->httpPost($request, $response); } - + public function testOnReportInvalidNode(): void { $this->expectException(\Sabre\DAV\Exception\ReportNotSupported::class); @@ -620,7 +606,7 @@ class CommentsPluginTest extends \Test\TestCase { $this->plugin->onReport(CommentsPluginImplementation::REPORT_NAME, [], '/' . $path); } - + public function testOnReportInvalidReportName(): void { $this->expectException(\Sabre\DAV\Exception\ReportNotSupported::class); diff --git a/apps/dav/tests/unit/Comments/EntityCollectionTest.php b/apps/dav/tests/unit/Comments/EntityCollectionTest.php index e5a68e5a726..fcf0748696c 100644 --- a/apps/dav/tests/unit/Comments/EntityCollectionTest.php +++ b/apps/dav/tests/unit/Comments/EntityCollectionTest.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,36 +15,23 @@ use OCP\Comments\ICommentsManager; use OCP\Comments\NotFoundException; use OCP\IUserManager; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class EntityCollectionTest extends \Test\TestCase { - - /** @var ICommentsManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $commentsManager; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - /** @var EntityCollection */ - protected $collection; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - protected $userSession; + protected ICommentsManager&MockObject $commentsManager; + protected IUserManager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected EntityCollection $collection; protected function setUp(): void { parent::setUp(); - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->collection = new EntityCollection( '19', @@ -70,7 +58,7 @@ class EntityCollectionTest extends \Test\TestCase { ); $node = $this->collection->getChild('55'); - $this->assertTrue($node instanceof CommentNode); + $this->assertInstanceOf(CommentNode::class, $node); } @@ -97,8 +85,8 @@ class EntityCollectionTest extends \Test\TestCase { $result = $this->collection->getChildren(); - $this->assertSame(count($result), 1); - $this->assertTrue($result[0] instanceof CommentNode); + $this->assertCount(1, $result); + $this->assertInstanceOf(CommentNode::class, $result[0]); } public function testFindChildren(): void { @@ -114,8 +102,8 @@ class EntityCollectionTest extends \Test\TestCase { $result = $this->collection->findChildren(5, 15, $dt); - $this->assertSame(count($result), 1); - $this->assertTrue($result[0] instanceof CommentNode); + $this->assertCount(1, $result); + $this->assertInstanceOf(CommentNode::class, $result[0]); } public function testChildExistsTrue(): void { diff --git a/apps/dav/tests/unit/Comments/EntityTypeCollectionTest.php b/apps/dav/tests/unit/Comments/EntityTypeCollectionTest.php index e5706099270..e5178a3e786 100644 --- a/apps/dav/tests/unit/Comments/EntityTypeCollectionTest.php +++ b/apps/dav/tests/unit/Comments/EntityTypeCollectionTest.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,40 +13,25 @@ use OCA\DAV\Comments\EntityTypeCollection; use OCP\Comments\ICommentsManager; use OCP\IUserManager; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class EntityTypeCollectionTest extends \Test\TestCase { - - /** @var ICommentsManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $commentsManager; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - /** @var EntityTypeCollection */ - protected $collection; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - protected $userSession; + protected ICommentsManager&MockObject $commentsManager; + protected IUserManager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected EntityTypeCollection $collection; protected $childMap = []; protected function setUp(): void { parent::setUp(); - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $instance = $this; + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->collection = new EntityTypeCollection( 'files', @@ -53,8 +39,8 @@ class EntityTypeCollectionTest extends \Test\TestCase { $this->userManager, $this->userSession, $this->logger, - function ($child) use ($instance) { - return !empty($instance->childMap[$child]); + function ($child) { + return !empty($this->childMap[$child]); } ); } @@ -72,7 +58,7 @@ class EntityTypeCollectionTest extends \Test\TestCase { $this->childMap[17] = true; $ec = $this->collection->getChild('17'); - $this->assertTrue($ec instanceof EntityCollectionImplemantation); + $this->assertInstanceOf(EntityCollectionImplemantation::class, $ec); } diff --git a/apps/dav/tests/unit/Comments/RootCollectionTest.php b/apps/dav/tests/unit/Comments/RootCollectionTest.php index 5d9e828f687..9a05d996c8c 100644 --- a/apps/dav/tests/unit/Comments/RootCollectionTest.php +++ b/apps/dav/tests/unit/Comments/RootCollectionTest.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,44 +17,27 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; class RootCollectionTest extends \Test\TestCase { - - /** @var ICommentsManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $commentsManager; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $userManager; - /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $logger; - /** @var RootCollection */ - protected $collection; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ - protected $userSession; - /** @var IEventDispatcher */ - protected $dispatcher; - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ - protected $user; + protected ICommentsManager&MockObject $commentsManager; + protected IUserManager&MockObject $userManager; + protected LoggerInterface&MockObject $logger; + protected IUserSession&MockObject $userSession; + protected IEventDispatcher $dispatcher; + protected IUser&MockObject $user; + protected RootCollection $collection; protected function setUp(): void { parent::setUp(); - $this->user = $this->getMockBuilder(IUser::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->commentsManager = $this->getMockBuilder(ICommentsManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor() - ->getMock(); - $this->userSession = $this->getMockBuilder(IUserSession::class) - ->disableOriginalConstructor() - ->getMock(); - $this->logger = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $this->user = $this->createMock(IUser::class); + + $this->commentsManager = $this->createMock(ICommentsManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->dispatcher = new EventDispatcher( new \Symfony\Component\EventDispatcher\EventDispatcher(), \OC::$server, @@ -69,7 +53,7 @@ class RootCollectionTest extends \Test\TestCase { ); } - protected function prepareForInitCollections() { + protected function prepareForInitCollections(): void { $this->user->expects($this->any()) ->method('getUID') ->willReturn('alice'); @@ -102,7 +86,7 @@ class RootCollectionTest extends \Test\TestCase { public function testGetChild(): void { $this->prepareForInitCollections(); $etc = $this->collection->getChild('files'); - $this->assertTrue($etc instanceof EntityTypeCollectionImplementation); + $this->assertInstanceOf(EntityTypeCollectionImplementation::class, $etc); } @@ -125,7 +109,7 @@ class RootCollectionTest extends \Test\TestCase { $children = $this->collection->getChildren(); $this->assertFalse(empty($children)); foreach ($children as $child) { - $this->assertTrue($child instanceof EntityTypeCollectionImplementation); + $this->assertInstanceOf(EntityTypeCollectionImplementation::class, $child); } } 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/AssemblyStreamTest.php b/apps/dav/tests/unit/Upload/AssemblyStreamTest.php index 854d02bfc10..e0bc3c589bc 100644 --- a/apps/dav/tests/unit/Upload/AssemblyStreamTest.php +++ b/apps/dav/tests/unit/Upload/AssemblyStreamTest.php @@ -15,7 +15,11 @@ class AssemblyStreamTest extends \Test\TestCase { /** * @dataProvider providesNodes() */ - public function testGetContents($expected, $nodes): void { + public function testGetContents(string $expected, array $nodeData): void { + $nodes = []; + foreach ($nodeData as $data) { + $nodes[] = $this->buildNode(...$data); + } $stream = AssemblyStream::wrap($nodes); $content = stream_get_contents($stream); @@ -25,7 +29,11 @@ class AssemblyStreamTest extends \Test\TestCase { /** * @dataProvider providesNodes() */ - public function testGetContentsFread($expected, $nodes, $chunkLength = 3): void { + public function testGetContentsFread(string $expected, array $nodeData, int $chunkLength = 3): void { + $nodes = []; + foreach ($nodeData as $data) { + $nodes[] = $this->buildNode(...$data); + } $stream = AssemblyStream::wrap($nodes); $content = ''; @@ -43,7 +51,12 @@ class AssemblyStreamTest extends \Test\TestCase { /** * @dataProvider providesNodes() */ - public function testSeek($expected, $nodes): void { + public function testSeek(string $expected, array $nodeData): void { + $nodes = []; + foreach ($nodeData as $data) { + $nodes[] = $this->buildNode(...$data); + } + $stream = AssemblyStream::wrap($nodes); $offset = floor(strlen($expected) * 0.6); @@ -55,75 +68,75 @@ class AssemblyStreamTest extends \Test\TestCase { $this->assertEquals(substr($expected, $offset), $content); } - public function providesNodes() { - $data8k = $this->makeData(8192); - $dataLess8k = $this->makeData(8191); + public static function providesNodes(): array { + $data8k = self::makeData(8192); + $dataLess8k = self::makeData(8191); $tonofnodes = []; $tonofdata = ''; for ($i = 0; $i < 101; $i++) { $thisdata = random_int(0, 100); // variable length and content $tonofdata .= $thisdata; - $tonofnodes[] = $this->buildNode((string)$i, (string)$thisdata); + $tonofnodes[] = [(string)$i, (string)$thisdata]; } return[ 'one node zero bytes' => [ '', [ - $this->buildNode('0', '') + ['0', ''], ]], 'one node only' => [ '1234567890', [ - $this->buildNode('0', '1234567890') + ['0', '1234567890'], ]], 'one node buffer boundary' => [ $data8k, [ - $this->buildNode('0', $data8k) + ['0', $data8k], ]], 'two nodes' => [ '1234567890', [ - $this->buildNode('1', '67890'), - $this->buildNode('0', '12345') + ['1', '67890'], + ['0', '12345'], ]], 'two nodes end on buffer boundary' => [ $data8k . $data8k, [ - $this->buildNode('1', $data8k), - $this->buildNode('0', $data8k) + ['1', $data8k], + ['0', $data8k], ]], 'two nodes with one on buffer boundary' => [ $data8k . $dataLess8k, [ - $this->buildNode('1', $dataLess8k), - $this->buildNode('0', $data8k) + ['1', $dataLess8k], + ['0', $data8k], ]], 'two nodes on buffer boundary plus one byte' => [ $data8k . 'X' . $data8k, [ - $this->buildNode('1', $data8k), - $this->buildNode('0', $data8k . 'X') + ['1', $data8k], + ['0', $data8k . 'X'], ]], 'two nodes on buffer boundary plus one byte at the end' => [ $data8k . $data8k . 'X', [ - $this->buildNode('1', $data8k . 'X'), - $this->buildNode('0', $data8k) + ['1', $data8k . 'X'], + ['0', $data8k], ]], 'a ton of nodes' => [ $tonofdata, $tonofnodes ], 'one read over multiple nodes' => [ '1234567890', [ - $this->buildNode('0', '1234'), - $this->buildNode('1', '5678'), - $this->buildNode('2', '90'), + ['0', '1234'], + ['1', '5678'], + ['2', '90'], ], 10], 'two reads over multiple nodes' => [ '1234567890', [ - $this->buildNode('0', '1234'), - $this->buildNode('1', '5678'), - $this->buildNode('2', '90'), + ['0', '1234'], + ['1', '5678'], + ['2', '90'], ], 5], ]; } - private function makeData($count) { + private static function makeData(int $count): string { $data = ''; $base = '1234567890'; $j = 0; @@ -137,10 +150,10 @@ class AssemblyStreamTest extends \Test\TestCase { return $data; } - private function buildNode($name, $data) { + private function buildNode(string $name, string $data) { $node = $this->getMockBuilder(File::class) - ->setMethods(['getName', 'get', 'getSize']) - ->getMockForAbstractClass(); + ->onlyMethods(['getName', 'get', 'getSize']) + ->getMock(); $node->expects($this->any()) ->method('getName') 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/l10n/fa.js b/apps/federatedfilesharing/l10n/fa.js index 08abe157524..a50cb263c88 100644 --- a/apps/federatedfilesharing/l10n/fa.js +++ b/apps/federatedfilesharing/l10n/fa.js @@ -8,6 +8,7 @@ OC.L10N.register( "Federated Share request sent, you will receive an invitation. Check your notifications." : "درخواست اشتراک فدرال ارسال شد، یک دعوت نامه دریافت خواهید کرد. اعلان های خود را بررسی کنید.", "Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "نمیتوان یک اشتراک فدرال ایجاد کرد، به نظر میرسد سروری که باید با آن فدرال شود خیلی قدیمی است (Nextcloud <= 9).", "It is not allowed to send federated group shares from this server." : "ارسال اشتراک های گروه فدرال از این سرور مجاز نیست.", + "Sharing %1$s failed, because this item is already shared with the account %2$s" : "اشتراکگذاری %1$s ناموفق بود، زیرا این مورد قبلاً با حساب %2$s به اشتراک گذاشته شده است", "Federated shares require read permissions" : "سهام فدرال به مجوز خواندن نیاز دارد", "File is already shared with %s" : "فایل قبلاً با به اشتراک گذاشته شده است%s", "Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "اشتراکگذاری %1$s انجام نشد، پیدا نشد%2$s، شاید سرور در حال حاضر غیرقابل دسترسی باشد یا از گواهی امضا شده استفاده میکند.", diff --git a/apps/federatedfilesharing/l10n/fa.json b/apps/federatedfilesharing/l10n/fa.json index f2cbe156d59..60e78b275c8 100644 --- a/apps/federatedfilesharing/l10n/fa.json +++ b/apps/federatedfilesharing/l10n/fa.json @@ -6,6 +6,7 @@ "Federated Share request sent, you will receive an invitation. Check your notifications." : "درخواست اشتراک فدرال ارسال شد، یک دعوت نامه دریافت خواهید کرد. اعلان های خود را بررسی کنید.", "Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "نمیتوان یک اشتراک فدرال ایجاد کرد، به نظر میرسد سروری که باید با آن فدرال شود خیلی قدیمی است (Nextcloud <= 9).", "It is not allowed to send federated group shares from this server." : "ارسال اشتراک های گروه فدرال از این سرور مجاز نیست.", + "Sharing %1$s failed, because this item is already shared with the account %2$s" : "اشتراکگذاری %1$s ناموفق بود، زیرا این مورد قبلاً با حساب %2$s به اشتراک گذاشته شده است", "Federated shares require read permissions" : "سهام فدرال به مجوز خواندن نیاز دارد", "File is already shared with %s" : "فایل قبلاً با به اشتراک گذاشته شده است%s", "Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "اشتراکگذاری %1$s انجام نشد، پیدا نشد%2$s، شاید سرور در حال حاضر غیرقابل دسترسی باشد یا از گواهی امضا شده استفاده میکند.", diff --git a/apps/federatedfilesharing/openapi.json b/apps/federatedfilesharing/openapi.json index 990cbf50bfa..411ff856b18 100644 --- a/apps/federatedfilesharing/openapi.json +++ b/apps/federatedfilesharing/openapi.json @@ -158,47 +158,56 @@ "remote": { "type": "string", "nullable": true, + "default": null, "description": "Address of the remote" }, "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" }, "name": { "type": "string", "nullable": true, + "default": null, "description": "Name of the shared resource" }, "owner": { "type": "string", "nullable": true, + "default": null, "description": "Display name of the receiver" }, "sharedBy": { "type": "string", "nullable": true, + "default": null, "description": "Display name of the sender" }, "shareWith": { "type": "string", "nullable": true, + "default": null, "description": "ID of the user that receives the share" }, "remoteId": { "type": "integer", "format": "int64", "nullable": true, + "default": null, "description": "ID of the remote" }, "sharedByFederatedId": { "type": "string", "nullable": true, + "default": null, "description": "Federated ID of the sender" }, "ownerFederatedId": { "type": "string", "nullable": true, + "default": null, "description": "Federated ID of the receiver" } } @@ -276,11 +285,13 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" }, "shareWith": { "type": "string", "nullable": true, + "default": null, "description": "ID of the user that receives the share" }, "remoteId": { @@ -417,12 +428,14 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" }, "permissions": { "type": "integer", "format": "int64", "nullable": true, + "default": null, "description": "New permissions" } } @@ -538,6 +551,7 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" } } @@ -635,6 +649,7 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" } } @@ -722,6 +737,7 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" } } @@ -809,6 +825,7 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" } } @@ -924,16 +941,19 @@ "token": { "type": "string", "nullable": true, + "default": null, "description": "Shared secret between servers" }, "remote": { "type": "string", "nullable": true, + "default": null, "description": "Address of the remote" }, "remote_id": { "type": "string", "nullable": true, + "default": null, "description": "ID of the remote" } } 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 9fa7c438bc6..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Osobní soubory", "Text file" : "Textový soubor", "New text file.txt" : "Nový textový soubor.txt", + "%1$s (renamed)" : "%1$s (přejmenované)", + "renamed file" : "přejmenovaný soubor", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Po povolení názvů souborů, kompatibilních s Windows, stávající soubory už nebude možné změnit, ale je možné je přejmenovat na platné nové názvy jejich vlastníkem.", "{count} files could not be converted" : "{count} souborů nebylo možné převést", "{count} files successfully converted" : "{count} souborů úspěšně převedeno" }, diff --git a/apps/files/l10n/cs.json b/apps/files/l10n/cs.json index 6887c3f59de..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", @@ -453,6 +453,9 @@ "Personal Files" : "Osobní soubory", "Text file" : "Textový soubor", "New text file.txt" : "Nový textový soubor.txt", + "%1$s (renamed)" : "%1$s (přejmenované)", + "renamed file" : "přejmenovaný soubor", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Po povolení názvů souborů, kompatibilních s Windows, stávající soubory už nebude možné změnit, ale je možné je přejmenovat na platné nové názvy jejich vlastníkem.", "{count} files could not be converted" : "{count} souborů nebylo možné převést", "{count} files successfully converted" : "{count} souborů úspěšně převedeno" },"pluralForm" :"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/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 d21936c8ec9..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Persönliche Dateien", "Text file" : "Textdatei", "New text file.txt" : "Neue Textdatei file.txt", + "%1$s (renamed)" : "%1$s (umbenannt)", + "renamed file" : "Umbenannte Datei", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Nach Aktivierung der Windows-kompatiblen Dateinamen können vorhandene Dateien nicht mehr geändert, aber von ihrem Besitzer in gültige neue Namen umbenannt werden.", "{count} files could not be converted" : "{count} Dateien konnten nicht konvertiert werden", "{count} files successfully converted" : "{count} Dateien konvertiert" }, diff --git a/apps/files/l10n/de.json b/apps/files/l10n/de.json index 15fae9b76ba..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", @@ -453,6 +453,9 @@ "Personal Files" : "Persönliche Dateien", "Text file" : "Textdatei", "New text file.txt" : "Neue Textdatei file.txt", + "%1$s (renamed)" : "%1$s (umbenannt)", + "renamed file" : "Umbenannte Datei", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Nach Aktivierung der Windows-kompatiblen Dateinamen können vorhandene Dateien nicht mehr geändert, aber von ihrem Besitzer in gültige neue Namen umbenannt werden.", "{count} files could not be converted" : "{count} Dateien konnten nicht konvertiert werden", "{count} files successfully converted" : "{count} Dateien konvertiert" },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/apps/files/l10n/de_DE.js b/apps/files/l10n/de_DE.js index f831a8be747..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Persönliche Dateien", "Text file" : "Textdatei", "New text file.txt" : "Neue Textdatei file.txt", + "%1$s (renamed)" : "%1$s (umbenannt)", + "renamed file" : "Umbenannte Datei", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Nach Aktivierung der Windows-kompatiblen Dateinamen können vorhandene Dateien nicht mehr geändert, aber von ihrem Besitzer in gültige neue Namen umbenannt werden.", "{count} files could not be converted" : "{count} Dateien konnten nicht konvertiert werden", "{count} files successfully converted" : "{count} Dateien konvertiert" }, diff --git a/apps/files/l10n/de_DE.json b/apps/files/l10n/de_DE.json index ae1dbdeca62..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", @@ -453,6 +453,9 @@ "Personal Files" : "Persönliche Dateien", "Text file" : "Textdatei", "New text file.txt" : "Neue Textdatei file.txt", + "%1$s (renamed)" : "%1$s (umbenannt)", + "renamed file" : "Umbenannte Datei", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Nach Aktivierung der Windows-kompatiblen Dateinamen können vorhandene Dateien nicht mehr geändert, aber von ihrem Besitzer in gültige neue Namen umbenannt werden.", "{count} files could not be converted" : "{count} Dateien konnten nicht konvertiert werden", "{count} files successfully converted" : "{count} Dateien konvertiert" },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/apps/files/l10n/en_GB.js b/apps/files/l10n/en_GB.js index 1499c95351b..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Personal Files", "Text file" : "Text file", "New text file.txt" : "New text file.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" }, diff --git a/apps/files/l10n/en_GB.json b/apps/files/l10n/en_GB.json index 093e3fbf15e..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", @@ -453,6 +453,9 @@ "Personal Files" : "Personal Files", "Text file" : "Text file", "New text file.txt" : "New text file.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);" diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js index 9f1470a2e7b..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", @@ -447,6 +447,9 @@ OC.L10N.register( "Personal Files" : "Archivos Personales", "Text file" : "Archivo de texto", "New text file.txt" : "Nuevo archivo.txt", + "%1$s (renamed)" : "%1$s (renombrado)", + "renamed file" : "archivo renombrado", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Luego de habilitar los nombres de archivo compatibles con windows, los archivos existentes no podrán ser modificados, pero, podrán ser renombrados a nuevos nombres válidos por su respectivo propietario.", "{count} files could not be converted" : "{count} archivos no han podido ser convertidos", "{count} files successfully converted" : "{count} archivos convertidos correctamente" }, diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json index 6f586c00097..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", @@ -445,6 +445,9 @@ "Personal Files" : "Archivos Personales", "Text file" : "Archivo de texto", "New text file.txt" : "Nuevo archivo.txt", + "%1$s (renamed)" : "%1$s (renombrado)", + "renamed file" : "archivo renombrado", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Luego de habilitar los nombres de archivo compatibles con windows, los archivos existentes no podrán ser modificados, pero, podrán ser renombrados a nuevos nombres válidos por su respectivo propietario.", "{count} files could not be converted" : "{count} archivos no han podido ser convertidos", "{count} files successfully converted" : "{count} archivos convertidos correctamente" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 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 f5ca9e71e54..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Isiklikud Failid", "Text file" : "Tekstifail", "New text file.txt" : "Uus tekstifail.txt", + "%1$s (renamed)" : "%1$s (nimi on muudetud)", + "renamed file" : "muudetud nimega fail", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Kui võtad kasutusele Windowsiga ühilduvad failinimed, siis olemasolevad mitteühilduvaid faile ei saa enam muuta, aga faili omanik saab failinime muuta ühilduvaks.", "{count} files could not be converted" : "{count} faili ei õnnestunud teisendada", "{count} files successfully converted" : "{count} faili teisendamine õnnestus" }, diff --git a/apps/files/l10n/et_EE.json b/apps/files/l10n/et_EE.json index 5b90843bdf3..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", @@ -453,6 +453,9 @@ "Personal Files" : "Isiklikud Failid", "Text file" : "Tekstifail", "New text file.txt" : "Uus tekstifail.txt", + "%1$s (renamed)" : "%1$s (nimi on muudetud)", + "renamed file" : "muudetud nimega fail", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Kui võtad kasutusele Windowsiga ühilduvad failinimed, siis olemasolevad mitteühilduvaid faile ei saa enam muuta, aga faili omanik saab failinime muuta ühilduvaks.", "{count} files could not be converted" : "{count} faili ei õnnestunud teisendada", "{count} files successfully converted" : "{count} faili teisendamine õnnestus" },"pluralForm" :"nplurals=2; plural=(n != 1);" 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..bf3bf2f5883 100644 --- a/apps/files/l10n/fi.js +++ b/apps/files/l10n/fi.js @@ -87,6 +87,11 @@ OC.L10N.register( "Renamed \"{oldName}\" to \"{newName}\"" : "Kohteen \"{oldName}\" uudeksi nimeksi asetettiin \"{newName}\"", "Rename file" : "Nimeä tiedosto uudelleen", "Folder" : "Kansio", + "Unknown file type" : "Tuntematon tiedostotyyppi", + "{ext} image" : "{ext} kuva", + "{ext} video" : "{ext} video", + "{ext} audio" : "{ext} ääni", + "{ext} text" : "{ext} teksti", "Pending" : "Odottaa", "Unknown date" : "Tuntematon päivämäärä", "Clear filter" : "Tyhjennä suodatin", @@ -95,6 +100,7 @@ OC.L10N.register( "Active filters" : "Aktiiviset suodattimet", "Remove filter" : "Poista suodatin", "Name" : "Nimi", + "File type" : "Tiedoston tyyppi", "Size" : "Koko", "\"{displayName}\" batch action executed successfully" : "\"{displayName}\" massatoiminto suoritettu", "Actions" : "Toiminnot", @@ -164,6 +170,7 @@ OC.L10N.register( "Sort favorites first" : "Järjestä suosikit ensiksi", "Sort folders before files" : "Järjestä kansiot ennen tiedostoja", "Show hidden files" : "Näytä piilotetut tiedostot", + "Show file type column" : "Näytä tiedostotyypin sarake", "Crop image previews" : "Rajaa kuvien esikatseluja", "Enable the grid view" : "Käytä ruudukkonäkymää", "Enable folder tree" : "Ota kansiopuu käyttöön", @@ -244,10 +251,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", @@ -290,6 +297,7 @@ OC.L10N.register( "Unexpected error: {error}" : "Odottamaton virhe: {error}", "_%n file_::_%n files_" : ["%n tiedosto","%n tiedostoa"], "_%n folder_::_%n folders_" : ["%n kansio","%n kansiota"], + "_%n hidden_::_%n hidden_" : ["%n piilotettu","%n piilotettua"], "Filename must not be empty." : "Tiedostonimi ei voi olla tyhjä.", "\"{char}\" is not allowed inside a filename." : "\"{char}\" ei ole sallittu tiedoston nimessä.", "\"{extension}\" is not an allowed filetype." : "\"{extension}\" ei ole sallitttu tiedostotyyppi.", @@ -402,6 +410,7 @@ OC.L10N.register( "Personal Files" : "Henkilökohtaiset tiedostot", "Text file" : "Tekstitiedosto", "New text file.txt" : "Uusi tekstitiedosto.txt", + "%1$s (renamed)" : "%1$s (nimetty uudelleen)", "{count} files could not be converted" : "{count} tiedostoa ei voitu muuntaa", "{count} files successfully converted" : "{count} tiedostoa muunnettu onnistuneesti" }, diff --git a/apps/files/l10n/fi.json b/apps/files/l10n/fi.json index fad7ebafc6e..b9c53ba232c 100644 --- a/apps/files/l10n/fi.json +++ b/apps/files/l10n/fi.json @@ -85,6 +85,11 @@ "Renamed \"{oldName}\" to \"{newName}\"" : "Kohteen \"{oldName}\" uudeksi nimeksi asetettiin \"{newName}\"", "Rename file" : "Nimeä tiedosto uudelleen", "Folder" : "Kansio", + "Unknown file type" : "Tuntematon tiedostotyyppi", + "{ext} image" : "{ext} kuva", + "{ext} video" : "{ext} video", + "{ext} audio" : "{ext} ääni", + "{ext} text" : "{ext} teksti", "Pending" : "Odottaa", "Unknown date" : "Tuntematon päivämäärä", "Clear filter" : "Tyhjennä suodatin", @@ -93,6 +98,7 @@ "Active filters" : "Aktiiviset suodattimet", "Remove filter" : "Poista suodatin", "Name" : "Nimi", + "File type" : "Tiedoston tyyppi", "Size" : "Koko", "\"{displayName}\" batch action executed successfully" : "\"{displayName}\" massatoiminto suoritettu", "Actions" : "Toiminnot", @@ -162,6 +168,7 @@ "Sort favorites first" : "Järjestä suosikit ensiksi", "Sort folders before files" : "Järjestä kansiot ennen tiedostoja", "Show hidden files" : "Näytä piilotetut tiedostot", + "Show file type column" : "Näytä tiedostotyypin sarake", "Crop image previews" : "Rajaa kuvien esikatseluja", "Enable the grid view" : "Käytä ruudukkonäkymää", "Enable folder tree" : "Ota kansiopuu käyttöön", @@ -242,10 +249,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", @@ -288,6 +295,7 @@ "Unexpected error: {error}" : "Odottamaton virhe: {error}", "_%n file_::_%n files_" : ["%n tiedosto","%n tiedostoa"], "_%n folder_::_%n folders_" : ["%n kansio","%n kansiota"], + "_%n hidden_::_%n hidden_" : ["%n piilotettu","%n piilotettua"], "Filename must not be empty." : "Tiedostonimi ei voi olla tyhjä.", "\"{char}\" is not allowed inside a filename." : "\"{char}\" ei ole sallittu tiedoston nimessä.", "\"{extension}\" is not an allowed filetype." : "\"{extension}\" ei ole sallitttu tiedostotyyppi.", @@ -400,6 +408,7 @@ "Personal Files" : "Henkilökohtaiset tiedostot", "Text file" : "Tekstitiedosto", "New text file.txt" : "Uusi tekstitiedosto.txt", + "%1$s (renamed)" : "%1$s (nimetty uudelleen)", "{count} files could not be converted" : "{count} tiedostoa ei voitu muuntaa", "{count} files successfully converted" : "{count} tiedostoa muunnettu onnistuneesti" },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js index 20142bbebf2..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Fichiers personnels", "Text file" : "Fichier texte", "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 af4f5f70116..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", @@ -453,6 +453,9 @@ "Personal Files" : "Fichiers personnels", "Text file" : "Fichier texte", "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 e08c16d1f7e..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", @@ -455,6 +455,8 @@ OC.L10N.register( "Personal Files" : "Comhaid Phearsanta", "Text file" : "Comhad téacs", "New text file.txt" : "Comhad téacs nua.txt", + "%1$s (renamed)" : "%1$s (athainmnithe)", + "renamed file" : "comhad athainmnithe", "{count} files could not be converted" : "{count} níorbh fhéidir comhaid a thiontú", "{count} files successfully converted" : "{count} comhaid a thiontú go rathúil" }, diff --git a/apps/files/l10n/ga.json b/apps/files/l10n/ga.json index acc3249e017..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", @@ -453,6 +453,8 @@ "Personal Files" : "Comhaid Phearsanta", "Text file" : "Comhad téacs", "New text file.txt" : "Comhad téacs nua.txt", + "%1$s (renamed)" : "%1$s (athainmnithe)", + "renamed file" : "comhad athainmnithe", "{count} files could not be converted" : "{count} níorbh fhéidir comhaid a thiontú", "{count} files successfully converted" : "{count} comhaid a thiontú go rathúil" },"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);" 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 e189cf4673a..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", @@ -455,6 +455,8 @@ OC.L10N.register( "Personal Files" : "File personali", "Text file" : "File di testo", "New text file.txt" : "Nuovo file di testo.txt", + "%1$s (renamed)" : "%1$s (rinominato)", + "renamed file" : "file rinominato", "{count} files could not be converted" : "{count} file non possono essere convertiti", "{count} files successfully converted" : "{count} file convertiti con successo" }, diff --git a/apps/files/l10n/it.json b/apps/files/l10n/it.json index e3787686d41..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", @@ -453,6 +453,8 @@ "Personal Files" : "File personali", "Text file" : "File di testo", "New text file.txt" : "Nuovo file di testo.txt", + "%1$s (renamed)" : "%1$s (rinominato)", + "renamed file" : "file rinominato", "{count} files could not be converted" : "{count} file non possono essere convertiti", "{count} files successfully converted" : "{count} file convertiti con successo" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" diff --git a/apps/files/l10n/ja.js b/apps/files/l10n/ja.js index 6b29c1c9780..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" : "フォルダー内で表示", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "個人ファイル", "Text file" : "テキストファイル", "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 d8d803191db..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" : "フォルダー内で表示", @@ -453,6 +453,9 @@ "Personal Files" : "個人ファイル", "Text file" : "テキストファイル", "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 2e652ce1683..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Pliki osobiste", "Text file" : "Plik tekstowy", "New text file.txt" : "Nowy plik tekstowy.txt", + "%1$s (renamed)" : "%1$s (zmieniona nazwa)", + "renamed file" : "zmieniona nazwa pliku", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Po włączeniu nazw plików zgodnych z systemem Windows, istniejących plików nie można już modyfikować, ale ich właściciel może zmienić ich nazwy na nowe, prawidłowe.", "{count} files could not be converted" : "Nie można przekonwertować {count} plików", "{count} files successfully converted" : "Zostały pomyślnie przekonwertowane{count} plików" }, diff --git a/apps/files/l10n/pl.json b/apps/files/l10n/pl.json index 24c20660260..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", @@ -453,6 +453,9 @@ "Personal Files" : "Pliki osobiste", "Text file" : "Plik tekstowy", "New text file.txt" : "Nowy plik tekstowy.txt", + "%1$s (renamed)" : "%1$s (zmieniona nazwa)", + "renamed file" : "zmieniona nazwa pliku", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Po włączeniu nazw plików zgodnych z systemem Windows, istniejących plików nie można już modyfikować, ale ich właściciel może zmienić ich nazwy na nowe, prawidłowe.", "{count} files could not be converted" : "Nie można przekonwertować {count} plików", "{count} files successfully converted" : "Zostały pomyślnie przekonwertowane{count} plików" },"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);" diff --git a/apps/files/l10n/pt_BR.js b/apps/files/l10n/pt_BR.js index 091fe73d2f6..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,14 +447,17 @@ 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", "New text file.txt" : "Novo arquivo de texto.txt", + "%1$s (renamed)" : "%1$s (renomeado)", + "renamed file" : "arquivo renomeado", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Depois de ativar os nomes de arquivos compatíveis com o Windows, os arquivos existentes não podem mais ser modificados, mas podem ser renomeados para novos nomes válidos pelo proprietário.", "{count} files could not be converted" : "{count} arquivos não puderam ser convertidos", "{count} files successfully converted" : "{count} arquivos convertidos com sucesso" }, diff --git a/apps/files/l10n/pt_BR.json b/apps/files/l10n/pt_BR.json index a1a8a55396b..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,14 +445,17 @@ "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", "New text file.txt" : "Novo arquivo de texto.txt", + "%1$s (renamed)" : "%1$s (renomeado)", + "renamed file" : "arquivo renomeado", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Depois de ativar os nomes de arquivos compatíveis com o Windows, os arquivos existentes não podem mais ser modificados, mas podem ser renomeados para novos nomes válidos pelo proprietário.", "{count} files could not be converted" : "{count} arquivos não puderam ser convertidos", "{count} files successfully converted" : "{count} arquivos convertidos com sucesso" },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 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 aac16577263..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" : "Види у фасцикли", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Лични фајлови", "Text file" : "Tекстуални фајл", "New text file.txt" : "Нов текстуални фајл.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/sr.json b/apps/files/l10n/sr.json index b2d6b3cb257..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" : "Види у фасцикли", @@ -453,6 +453,9 @@ "Personal Files" : "Лични фајлови", "Text file" : "Tекстуални фајл", "New text file.txt" : "Нов текстуални фајл.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=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/files/l10n/sv.js b/apps/files/l10n/sv.js index d4428ac84de..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", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Personliga filer", "Text file" : "Textfil", "New text file.txt" : "Ny textfil.txt", + "%1$s (renamed)" : "%1$s (omdöpt)", + "renamed file" : "omdöpt fil", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "När Windows-kompatibla filnamn har aktiverats kan befintliga filer inte längre ändras, men de kan byta namn till giltiga nya namn av sin ägare.", "{count} files could not be converted" : "{count} filer kunde inte konverteras", "{count} files successfully converted" : "{count} filer har konverterats" }, diff --git a/apps/files/l10n/sv.json b/apps/files/l10n/sv.json index e56bc427e48..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", @@ -453,6 +453,9 @@ "Personal Files" : "Personliga filer", "Text file" : "Textfil", "New text file.txt" : "Ny textfil.txt", + "%1$s (renamed)" : "%1$s (omdöpt)", + "renamed file" : "omdöpt fil", + "After enabling the windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "När Windows-kompatibla filnamn har aktiverats kan befintliga filer inte längre ändras, men de kan byta namn till giltiga nya namn av sin ägare.", "{count} files could not be converted" : "{count} filer kunde inte konverteras", "{count} files successfully converted" : "{count} filer har konverterats" },"pluralForm" :"nplurals=2; plural=(n != 1);" 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..e7e18117acb 100644 --- a/apps/files/l10n/uk.js +++ b/apps/files/l10n/uk.js @@ -70,6 +70,8 @@ OC.L10N.register( "Transferred from %1$s on %2$s" : "Перенесено від %1$s до %2$s", "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." : "Дозволити обмежувати імена файлів для забезпечення сумісності з різними клієнтами. Типово всі імена файлів, які відповідають моделі POSIX (напр., Linux, macOS), дозволені.", + "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Після увімкнення сумісности імен файлів з системою Windows наявні файли неможливо буде змінити, але власники зможуть перейменувати ці файли на нові з дійсними іменами.", + "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command." : "Також можлива автоматична міграція файлів після увімкнення цих налаштувань. Ознайомтеся з документацією відповідної команди occ.", "Enforce Windows compatibility" : "Увімкнути сумісність із Windows", "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." : "Це унеможливить використання імен файлів, які не сумісні з системами Windows, напр., використанння зарезервованих імен або спеціальних символів. Зауважте, що це не обмежить сумісність за регістром символів.", "File Management" : "Керування файлами", @@ -95,6 +97,11 @@ OC.L10N.register( "Renamed \"{oldName}\" to \"{newName}\"" : "Перейменовано \"{oldName}\" на \"{newName}\"", "Rename file" : "Перейменувати файл", "Folder" : "Каталог", + "Unknown file type" : "Невідомий тип файлу", + "{ext} image" : "{ext} зображення", + "{ext} video" : "{ext} відео", + "{ext} audio" : "{ext} аудіо", + "{ext} text" : "{ext} текст", "Pending" : "Очікування", "Unknown date" : "Невідома дата", "Clear filter" : "Очистити фільтр", @@ -105,6 +112,7 @@ OC.L10N.register( "Total rows summary" : "Загалом рядків", "Toggle selection for all files and folders" : "Перемкнути вибір для всіх файлів та каталогів", "Name" : "Ім'я", + "File type" : "Тип файлу", "Size" : "Розмір", "\"{displayName}\" failed on some elements" : "\"{displayName}\" не спрацював у деяких елементах", "\"{displayName}\" batch action executed successfully" : "Операцію \"{displayName}\" успішно виконано", @@ -183,6 +191,7 @@ OC.L10N.register( "Sort favorites first" : "Спочатку показувати із зірочкою", "Sort folders before files" : "Показувати каталоги перед файлами", "Show hidden files" : "Показувати приховані файли", + "Show file type column" : "Показувати стовпець з типом файлу", "Crop image previews" : "Попередній перегляд перед кадруванням", "Enable the grid view" : "Увімкнути подання сіткою", "Enable folder tree" : "Увімкнути дерево каталогів", @@ -279,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" : "Переглянути у каталозі", @@ -446,6 +455,9 @@ OC.L10N.register( "Personal Files" : "Мої документи", "Text file" : "Текстовий файл", "New text file.txt" : "Новий текстовий файл.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/uk.json b/apps/files/l10n/uk.json index e133f666763..8e5cc11949f 100644 --- a/apps/files/l10n/uk.json +++ b/apps/files/l10n/uk.json @@ -68,6 +68,8 @@ "Transferred from %1$s on %2$s" : "Перенесено від %1$s до %2$s", "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." : "Дозволити обмежувати імена файлів для забезпечення сумісності з різними клієнтами. Типово всі імена файлів, які відповідають моделі POSIX (напр., Linux, macOS), дозволені.", + "After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Після увімкнення сумісности імен файлів з системою Windows наявні файли неможливо буде змінити, але власники зможуть перейменувати ці файли на нові з дійсними іменами.", + "It is also possible to migrate files automatically after enabling this setting, please refer to the documentation about the occ command." : "Також можлива автоматична міграція файлів після увімкнення цих налаштувань. Ознайомтеся з документацією відповідної команди occ.", "Enforce Windows compatibility" : "Увімкнути сумісність із Windows", "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." : "Це унеможливить використання імен файлів, які не сумісні з системами Windows, напр., використанння зарезервованих імен або спеціальних символів. Зауважте, що це не обмежить сумісність за регістром символів.", "File Management" : "Керування файлами", @@ -93,6 +95,11 @@ "Renamed \"{oldName}\" to \"{newName}\"" : "Перейменовано \"{oldName}\" на \"{newName}\"", "Rename file" : "Перейменувати файл", "Folder" : "Каталог", + "Unknown file type" : "Невідомий тип файлу", + "{ext} image" : "{ext} зображення", + "{ext} video" : "{ext} відео", + "{ext} audio" : "{ext} аудіо", + "{ext} text" : "{ext} текст", "Pending" : "Очікування", "Unknown date" : "Невідома дата", "Clear filter" : "Очистити фільтр", @@ -103,6 +110,7 @@ "Total rows summary" : "Загалом рядків", "Toggle selection for all files and folders" : "Перемкнути вибір для всіх файлів та каталогів", "Name" : "Ім'я", + "File type" : "Тип файлу", "Size" : "Розмір", "\"{displayName}\" failed on some elements" : "\"{displayName}\" не спрацював у деяких елементах", "\"{displayName}\" batch action executed successfully" : "Операцію \"{displayName}\" успішно виконано", @@ -181,6 +189,7 @@ "Sort favorites first" : "Спочатку показувати із зірочкою", "Sort folders before files" : "Показувати каталоги перед файлами", "Show hidden files" : "Показувати приховані файли", + "Show file type column" : "Показувати стовпець з типом файлу", "Crop image previews" : "Попередній перегляд перед кадруванням", "Enable the grid view" : "Увімкнути подання сіткою", "Enable folder tree" : "Увімкнути дерево каталогів", @@ -277,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" : "Переглянути у каталозі", @@ -444,6 +453,9 @@ "Personal Files" : "Мої документи", "Text file" : "Текстовий файл", "New text file.txt" : "Новий текстовий файл.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=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/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 1bbbdb18e88..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" : "在文件夹中查看", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "个人文件", "Text file" : "文本文件", "New text file.txt" : "新建文本文件.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/zh_CN.json b/apps/files/l10n/zh_CN.json index dd225ef638a..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" : "在文件夹中查看", @@ -453,6 +453,9 @@ "Personal Files" : "个人文件", "Text file" : "文本文件", "New text file.txt" : "新建文本文件.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/zh_HK.js b/apps/files/l10n/zh_HK.js index 4c279ff809a..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" : "在資料夾中檢視", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "個人檔案", "Text file" : "文字檔", "New text file.txt" : "新文字檔.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/zh_HK.json b/apps/files/l10n/zh_HK.json index 39825088806..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" : "在資料夾中檢視", @@ -453,6 +453,9 @@ "Personal Files" : "個人檔案", "Text file" : "文字檔", "New text file.txt" : "新文字檔.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/zh_TW.js b/apps/files/l10n/zh_TW.js index 808a21a8f2a..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" : "在資料夾中檢視", @@ -455,6 +455,9 @@ OC.L10N.register( "Personal Files" : "個人檔案", "Text file" : "文字檔案", "New text file.txt" : "新文字檔案.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/zh_TW.json b/apps/files/l10n/zh_TW.json index 4037307ffa6..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" : "在資料夾中檢視", @@ -453,6 +453,9 @@ "Personal Files" : "個人檔案", "Text file" : "文字檔案", "New text file.txt" : "新文字檔案.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/lib/BackgroundJob/ScanFiles.php b/apps/files/lib/BackgroundJob/ScanFiles.php index 3a39382d0b4..f3f9093d648 100644 --- a/apps/files/lib/BackgroundJob/ScanFiles.php +++ b/apps/files/lib/BackgroundJob/ScanFiles.php @@ -69,7 +69,7 @@ class ScanFiles extends TimedJob { $query->select('m.user_id') ->from('filecache', 'f') ->leftJoin('f', 'mounts', 'm', $query->expr()->eq('m.storage_id', 'f.storage')) - ->where($query->expr()->lt('f.size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))) + ->where($query->expr()->eq('f.size', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->gt('f.parent', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->setMaxResults(10) ->groupBy('f.storage') @@ -90,7 +90,7 @@ class ScanFiles extends TimedJob { $query->select('m.user_id') ->from('filecache', 'f') ->leftJoin('f', 'mounts', 'm', $query->expr()->eq('m.storage_id', 'f.storage')) - ->where($query->expr()->lt('f.size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))) + ->where($query->expr()->eq('f.size', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->gt('f.parent', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->in('f.storage', $query->createNamedParameter($storages, IQueryBuilder::PARAM_INT_ARRAY))) ->setMaxResults(1) @@ -101,7 +101,7 @@ class ScanFiles extends TimedJob { $query->select('m.user_id') ->from('filecache', 'f') ->innerJoin('f', 'mounts', 'm', $query->expr()->eq('m.storage_id', 'f.storage')) - ->where($query->expr()->lt('f.size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))) + ->where($query->expr()->eq('f.size', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->gt('f.parent', $query->createNamedParameter(-1, IQueryBuilder::PARAM_INT))) ->setMaxResults(1) ->runAcrossAllShards(); 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/openapi.json b/apps/files/openapi.json index c227b12d922..c5d6053075c 100644 --- a/apps/files/openapi.json +++ b/apps/files/openapi.json @@ -847,12 +847,14 @@ "editorId": { "type": "string", "nullable": true, + "default": null, "description": "ID of the editor" }, "fileId": { "type": "integer", "format": "int64", "nullable": true, + "default": null, "description": "ID of the file" } } @@ -1032,6 +1034,7 @@ "templateId": { "type": "string", "nullable": true, + "default": null, "description": "ID of the template" } } @@ -2366,6 +2369,7 @@ "destination": { "type": "string", "nullable": true, + "default": null, "description": "The target path of the converted file. Written to a temporary file if left empty" } } 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/src/services/HotKeysService.spec.ts b/apps/files/src/services/HotKeysService.spec.ts index c732c728ce5..7bbba77b222 100644 --- a/apps/files/src/services/HotKeysService.spec.ts +++ b/apps/files/src/services/HotKeysService.spec.ts @@ -61,6 +61,7 @@ describe('HotKeysService testing', () => { activeStore.setActiveNode(file) window.OCA = { Files: { Sidebar: { open: () => {}, setActiveTab: () => {} } } } + // We only mock what needed, we do not need Files.Router.goTo or Files.Navigation window.OCP = { Files: { Router: { goToRoute: goToRouteMock, params: {}, query: {} } } } initialState = document.createElement('input') @@ -73,26 +74,26 @@ describe('HotKeysService testing', () => { }) it('Pressing d should open the sidebar once', () => { - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'd', code: 'KeyD' })) + dispatchEvent({ key: 'd', code: 'KeyD' }) // Modifier keys should not trigger the action - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'd', code: 'KeyD', ctrlKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'd', code: 'KeyD', altKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'd', code: 'KeyD', shiftKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'd', code: 'KeyD', metaKey: true })) + dispatchEvent({ key: 'd', code: 'KeyD', ctrlKey: true }) + dispatchEvent({ key: 'd', code: 'KeyD', altKey: true }) + dispatchEvent({ key: 'd', code: 'KeyD', shiftKey: true }) + dispatchEvent({ key: 'd', code: 'KeyD', metaKey: true }) expect(sidebarAction.enabled).toHaveReturnedWith(true) expect(sidebarAction.exec).toHaveBeenCalledOnce() }) it('Pressing F2 should rename the file', () => { - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', code: 'F2' })) + dispatchEvent({ key: 'F2', code: 'F2' }) // Modifier keys should not trigger the action - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', code: 'F2', ctrlKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', code: 'F2', altKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', code: 'F2', shiftKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', code: 'F2', metaKey: true })) + dispatchEvent({ key: 'F2', code: 'F2', ctrlKey: true }) + dispatchEvent({ key: 'F2', code: 'F2', altKey: true }) + dispatchEvent({ key: 'F2', code: 'F2', shiftKey: true }) + dispatchEvent({ key: 'F2', code: 'F2', metaKey: true }) expect(renameAction.enabled).toHaveReturnedWith(true) expect(renameAction.exec).toHaveBeenCalledOnce() @@ -100,29 +101,29 @@ describe('HotKeysService testing', () => { it('Pressing s should toggle favorite', () => { vi.spyOn(axios, 'post').mockImplementationOnce(() => Promise.resolve()) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 's', code: 'KeyS' })) + dispatchEvent({ key: 's', code: 'KeyS' }) // Modifier keys should not trigger the action - window.dispatchEvent(new KeyboardEvent('keydown', { key: 's', code: 'KeyS', ctrlKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 's', code: 'KeyS', altKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 's', code: 'KeyS', shiftKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 's', code: 'KeyS', metaKey: true })) + dispatchEvent({ key: 's', code: 'KeyS', ctrlKey: true }) + dispatchEvent({ key: 's', code: 'KeyS', altKey: true }) + dispatchEvent({ key: 's', code: 'KeyS', shiftKey: true }) + dispatchEvent({ key: 's', code: 'KeyS', metaKey: true }) expect(favoriteAction.enabled).toHaveReturnedWith(true) expect(favoriteAction.exec).toHaveBeenCalledOnce() }) it('Pressing Delete should delete the file', async () => { - // @ts-expect-error mocking private field + // @ts-expect-error unit testing vi.spyOn(deleteAction._action, 'exec').mockResolvedValue(() => true) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete' })) + dispatchEvent({ key: 'Delete', code: 'Delete' }) // Modifier keys should not trigger the action - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete', ctrlKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete', altKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete', shiftKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Delete', code: 'Delete', metaKey: true })) + dispatchEvent({ key: 'Delete', code: 'Delete', ctrlKey: true }) + dispatchEvent({ key: 'Delete', code: 'Delete', altKey: true }) + dispatchEvent({ key: 'Delete', code: 'Delete', shiftKey: true }) + dispatchEvent({ key: 'Delete', code: 'Delete', metaKey: true }) expect(deleteAction.enabled).toHaveReturnedWith(true) expect(deleteAction.exec).toHaveBeenCalledOnce() @@ -132,7 +133,7 @@ describe('HotKeysService testing', () => { expect(goToRouteMock).toHaveBeenCalledTimes(0) window.OCP.Files.Router.query = { dir: '/foo/bar' } - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', code: 'ArrowUp', altKey: true })) + dispatchEvent({ key: 'ArrowUp', code: 'ArrowUp', altKey: true }) expect(goToRouteMock).toHaveBeenCalledOnce() expect(goToRouteMock.mock.calls[0][2].dir).toBe('/foo') @@ -145,9 +146,7 @@ describe('HotKeysService testing', () => { userConfigStore.userConfig.grid_view = false expect(userConfigStore.userConfig.grid_view).toBe(false) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'v', code: 'KeyV' })) - await nextTick() - + dispatchEvent({ key: 'v', code: 'KeyV' }) expect(userConfigStore.userConfig.grid_view).toBe(true) }) @@ -164,9 +163,19 @@ describe('HotKeysService testing', () => { userConfigStore.userConfig.grid_view = false expect(userConfigStore.userConfig.grid_view).toBe(false) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 'v', code: 'KeyV', [modifier]: true })) + dispatchEvent(new KeyboardEvent('keydown', { key: 'v', code: 'KeyV', [modifier]: true })) + await nextTick() expect(userConfigStore.userConfig.grid_view).toBe(false) }) }) + +/** + * Helper to dispatch the correct event. + * + * @param init - KeyboardEvent options + */ +function dispatchEvent(init: KeyboardEventInit) { + document.body.dispatchEvent(new KeyboardEvent('keydown', { ...init, bubbles: true })) +} 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_external/l10n/fr.js b/apps/files_external/l10n/fr.js index bb6ed322fea..5c6d38b6396 100644 --- a/apps/files_external/l10n/fr.js +++ b/apps/files_external/l10n/fr.js @@ -7,6 +7,7 @@ OC.L10N.register( "Error configuring OAuth2" : "Erreur lors de la configuration de OAuth2", "Generate keys" : "Générer des clés", "Error generating key pair" : "Erreur lors de la génération des clés", + "You are not logged in" : "Vous n'êtes pas connecté", "Permission denied" : "Autorisation refusée", "Forbidden to manage local mounts" : "Interdiction de gérer les montages locaux.", "Storage with ID \"%d\" not found" : "Stockage avec l'ID \"%d\" non trouvé", diff --git a/apps/files_external/l10n/fr.json b/apps/files_external/l10n/fr.json index 23e6346641f..2cadc830a7d 100644 --- a/apps/files_external/l10n/fr.json +++ b/apps/files_external/l10n/fr.json @@ -5,6 +5,7 @@ "Error configuring OAuth2" : "Erreur lors de la configuration de OAuth2", "Generate keys" : "Générer des clés", "Error generating key pair" : "Erreur lors de la génération des clés", + "You are not logged in" : "Vous n'êtes pas connecté", "Permission denied" : "Autorisation refusée", "Forbidden to manage local mounts" : "Interdiction de gérer les montages locaux.", "Storage with ID \"%d\" not found" : "Stockage avec l'ID \"%d\" non trouvé", diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js index 4df5dddd8db..233814a6abc 100644 --- a/apps/files_external/l10n/pt_BR.js +++ b/apps/files_external/l10n/pt_BR.js @@ -33,7 +33,7 @@ OC.L10N.register( "Client ID" : "ID do Cliente", "Client secret" : "Segredo do cliente", "OpenStack v2" : "OpenStack v2", - "Login" : "Entrar", + "Login" : "Nome de login", "Password" : "Senha", "Tenant name" : "Nome do inquilino", "Identity endpoint URL" : "URL do destino da identidade", @@ -42,17 +42,17 @@ OC.L10N.register( "Rackspace" : "Espaço no rack", "API key" : "Chave API", "Global credentials" : "Credenciais globais", - "Log-in credentials, save in database" : "Credenciais de acesso, salvas no banco de dados", - "Login and password" : "Login e senha", - "Log-in credentials, save in session" : "Credenciais de login, guardadas em sessão", + "Log-in credentials, save in database" : "Credenciais de acesso, armazenar no banco de dados", + "Login and password" : "Nome de login e senha", + "Log-in credentials, save in session" : "Credenciais de login, armazenar na sessão", "Global credentials, manually entered" : "Credenciais globais, inseridas manualmente", - "Manually entered, store in database" : "Inserido manualmente, armazenado no banco de dados", + "Manually entered, store in database" : "Inseridos manualmente, armazenados no banco de dados", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "RSA private key" : "Chave privada RSA", "Private key" : "Chave privada", - "Kerberos default realm, defaults to \"WORKGROUP\"" : "reino padrão do Kerberos, padrão para \"WORKGROUP\"", - "Kerberos ticket Apache mode" : "Bilhete Kerberos Modo Apache", + "Kerberos default realm, defaults to \"WORKGROUP\"" : "Reino padrão do Kerberos, o padrão é \"WORKGROUP\"", + "Kerberos ticket Apache mode" : "Modo Apache de Ticket Kerberos", "Kerberos ticket" : "Ticket Kerberos", "Amazon S3" : "Amazon S3", "Bucket" : "Cesta", @@ -81,13 +81,13 @@ OC.L10N.register( "SMB/CIFS" : "SMB/CIFS", "Share" : "Compartilhar", "Show hidden files" : "Mostrar arquivos ocultos", - "Case sensitive file system" : "Sistema de arquivos sensível a maiúsculas", + "Case sensitive file system" : "Sistema de arquivos diferenciando maiúsculas/minúsculas", "Disabling it will allow to use a case insensitive file system, but comes with a performance penalty" : "Desativá-lo permitirá usar um sistema de arquivos que não diferencia maiúsculas de minúsculas, mas acarretará uma penalidade de desempenho", "Verify ACL access when listing files" : "Verifique o acesso da ACL ao listar arquivos", "Check the ACL's of each file or folder inside a directory to filter out items where the account has no read permissions, comes with a performance penalty" : "Verifique as ACLs de cada arquivo ou pasta dentro de um diretório para filtrar itens onde a conta não tem permissões de leitura, o que acarreta uma penalidade de desempenho", "Timeout" : "Tempo limite", - "SMB/CIFS using OC login" : "SMB/CIFS usandoo login OC", - "Login as share" : "Faça login como compartilhar", + "SMB/CIFS using OC login" : "SMB/CIFS usando login OC", + "Login as share" : "Faça login como compartilhamento", "OpenStack Object Storage" : "Armazenamento de Objetos OpenStack", "Service name" : "Nome do serviço", "Request timeout (seconds)" : "Tempo limite para requisição (segundos)", @@ -101,21 +101,21 @@ OC.L10N.register( "Confirm" : "Confirmar", "Storage credentials" : "Credenciais de armazenamento", "To access the storage, you need to provide the authentication credentials." : "Para acessar o armazenamento, você precisa fornecer as credenciais de autenticação.", - "Enter the storage login" : "Digite o login de armazenamento", + "Enter the storage login" : "Digite o nome de login de armazenamento", "Enter the storage password" : "Digite a senha de armazenamento", "Unable to update this external storage config. {statusMessage}" : "Não é possível atualizar esta configuração de armazenamento externo. {statusMessage}", "New configuration successfully saved" : "Nova configuração salva com sucesso", "Enter missing credentials" : "Digite as credenciais ausentes", - "Credentials successfully set" : "Credenciais configuradas com sucesso", - "Error while setting credentials: {error}" : "Erro ao configurar as credenciais: {error}", + "Credentials successfully set" : "Credenciais definidas com sucesso", + "Error while setting credentials: {error}" : "Erro ao definir as credenciais: {error}", "Checking storage …" : "Verificação do armazenamento …", "There was an error with this external storage." : "Ocorreu um erro com este armazenamento externo.", "We were unable to check the external storage {basename}" : "Não foi possível verificar o armazenamento externo {basename}", "Examine this faulty external storage configuration" : "Examine esta configuração de armazenamento externo com falha", - "Open in Files" : "Abrir em arquivos", + "Open in Files" : "Abrir em Arquivos", "There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Ocorreu um erro com este armazenamento externo. Deseja revisar esta configuração do ponto de montagem na página de configurações?", "External mount error" : "Erro de montagem externa", - "List of external storage." : "Lista de armazenamento externo.", + "List of external storage." : "Lista de armazenamentos externos.", "There is no external storage configured. You can configure them in your Personal settings." : "Não há armazenamento externo configurado. Você pode configurá-los em suas configurações pessoais.", "There is no external storage configured and you don't have the permission to configure them." : "Não há armazenamento externo configurado e você não tem permissão para configurá-los.", "No external storage" : "Sem armazenamento externo", @@ -135,10 +135,10 @@ OC.L10N.register( "Once every direct access" : "Uma vez a cada acesso direto", "Read only" : "Somente leitura", "Disconnect" : "Desconectar", - "Unknown backend: {backendName}" : "Backend desconhecido: {backendName}", + "Unknown backend: {backendName}" : "Back-end desconhecido: {backendName}", "Admin defined" : "Definido pelo administrador", "Automatic status checking is disabled due to the large number of configured storages, click to check status" : "A verificação automática de status está desabilitada devido ao grande número de armazenamentos configurados, clique para verificar o status", - "Are you sure you want to disconnect this external storage? It will make the storage unavailable in Nextcloud and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Tem certeza de que deseja desconectar este armazenamento externo? Isso tornará o armazenamento indisponível no Nextcloud e levará à exclusão desses arquivos e pastas em qualquer cliente de sincronização que esteja conectado no momento, mas não excluirá nenhum arquivo e pasta no próprio armazenamento externo.", + "Are you sure you want to disconnect this external storage? It will make the storage unavailable in Nextcloud and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Tem certeza de que deseja desconectar este armazenamento externo? Isso tornará o armazenamento indisponível no Nextcloud e levará à exclusão destes arquivos e pastas em qualquer cliente de sincronização que esteja conectado no momento, mas não excluirá nenhum arquivo e pasta do armazenamento externo em si.", "Delete storage?" : "Excluir armazenamento?", "Click to recheck the configuration" : "Clique para rechecar a configuração", "Saved" : "Salvo", diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json index 02fd258d356..6002404e464 100644 --- a/apps/files_external/l10n/pt_BR.json +++ b/apps/files_external/l10n/pt_BR.json @@ -31,7 +31,7 @@ "Client ID" : "ID do Cliente", "Client secret" : "Segredo do cliente", "OpenStack v2" : "OpenStack v2", - "Login" : "Entrar", + "Login" : "Nome de login", "Password" : "Senha", "Tenant name" : "Nome do inquilino", "Identity endpoint URL" : "URL do destino da identidade", @@ -40,17 +40,17 @@ "Rackspace" : "Espaço no rack", "API key" : "Chave API", "Global credentials" : "Credenciais globais", - "Log-in credentials, save in database" : "Credenciais de acesso, salvas no banco de dados", - "Login and password" : "Login e senha", - "Log-in credentials, save in session" : "Credenciais de login, guardadas em sessão", + "Log-in credentials, save in database" : "Credenciais de acesso, armazenar no banco de dados", + "Login and password" : "Nome de login e senha", + "Log-in credentials, save in session" : "Credenciais de login, armazenar na sessão", "Global credentials, manually entered" : "Credenciais globais, inseridas manualmente", - "Manually entered, store in database" : "Inserido manualmente, armazenado no banco de dados", + "Manually entered, store in database" : "Inseridos manualmente, armazenados no banco de dados", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "RSA private key" : "Chave privada RSA", "Private key" : "Chave privada", - "Kerberos default realm, defaults to \"WORKGROUP\"" : "reino padrão do Kerberos, padrão para \"WORKGROUP\"", - "Kerberos ticket Apache mode" : "Bilhete Kerberos Modo Apache", + "Kerberos default realm, defaults to \"WORKGROUP\"" : "Reino padrão do Kerberos, o padrão é \"WORKGROUP\"", + "Kerberos ticket Apache mode" : "Modo Apache de Ticket Kerberos", "Kerberos ticket" : "Ticket Kerberos", "Amazon S3" : "Amazon S3", "Bucket" : "Cesta", @@ -79,13 +79,13 @@ "SMB/CIFS" : "SMB/CIFS", "Share" : "Compartilhar", "Show hidden files" : "Mostrar arquivos ocultos", - "Case sensitive file system" : "Sistema de arquivos sensível a maiúsculas", + "Case sensitive file system" : "Sistema de arquivos diferenciando maiúsculas/minúsculas", "Disabling it will allow to use a case insensitive file system, but comes with a performance penalty" : "Desativá-lo permitirá usar um sistema de arquivos que não diferencia maiúsculas de minúsculas, mas acarretará uma penalidade de desempenho", "Verify ACL access when listing files" : "Verifique o acesso da ACL ao listar arquivos", "Check the ACL's of each file or folder inside a directory to filter out items where the account has no read permissions, comes with a performance penalty" : "Verifique as ACLs de cada arquivo ou pasta dentro de um diretório para filtrar itens onde a conta não tem permissões de leitura, o que acarreta uma penalidade de desempenho", "Timeout" : "Tempo limite", - "SMB/CIFS using OC login" : "SMB/CIFS usandoo login OC", - "Login as share" : "Faça login como compartilhar", + "SMB/CIFS using OC login" : "SMB/CIFS usando login OC", + "Login as share" : "Faça login como compartilhamento", "OpenStack Object Storage" : "Armazenamento de Objetos OpenStack", "Service name" : "Nome do serviço", "Request timeout (seconds)" : "Tempo limite para requisição (segundos)", @@ -99,21 +99,21 @@ "Confirm" : "Confirmar", "Storage credentials" : "Credenciais de armazenamento", "To access the storage, you need to provide the authentication credentials." : "Para acessar o armazenamento, você precisa fornecer as credenciais de autenticação.", - "Enter the storage login" : "Digite o login de armazenamento", + "Enter the storage login" : "Digite o nome de login de armazenamento", "Enter the storage password" : "Digite a senha de armazenamento", "Unable to update this external storage config. {statusMessage}" : "Não é possível atualizar esta configuração de armazenamento externo. {statusMessage}", "New configuration successfully saved" : "Nova configuração salva com sucesso", "Enter missing credentials" : "Digite as credenciais ausentes", - "Credentials successfully set" : "Credenciais configuradas com sucesso", - "Error while setting credentials: {error}" : "Erro ao configurar as credenciais: {error}", + "Credentials successfully set" : "Credenciais definidas com sucesso", + "Error while setting credentials: {error}" : "Erro ao definir as credenciais: {error}", "Checking storage …" : "Verificação do armazenamento …", "There was an error with this external storage." : "Ocorreu um erro com este armazenamento externo.", "We were unable to check the external storage {basename}" : "Não foi possível verificar o armazenamento externo {basename}", "Examine this faulty external storage configuration" : "Examine esta configuração de armazenamento externo com falha", - "Open in Files" : "Abrir em arquivos", + "Open in Files" : "Abrir em Arquivos", "There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Ocorreu um erro com este armazenamento externo. Deseja revisar esta configuração do ponto de montagem na página de configurações?", "External mount error" : "Erro de montagem externa", - "List of external storage." : "Lista de armazenamento externo.", + "List of external storage." : "Lista de armazenamentos externos.", "There is no external storage configured. You can configure them in your Personal settings." : "Não há armazenamento externo configurado. Você pode configurá-los em suas configurações pessoais.", "There is no external storage configured and you don't have the permission to configure them." : "Não há armazenamento externo configurado e você não tem permissão para configurá-los.", "No external storage" : "Sem armazenamento externo", @@ -133,10 +133,10 @@ "Once every direct access" : "Uma vez a cada acesso direto", "Read only" : "Somente leitura", "Disconnect" : "Desconectar", - "Unknown backend: {backendName}" : "Backend desconhecido: {backendName}", + "Unknown backend: {backendName}" : "Back-end desconhecido: {backendName}", "Admin defined" : "Definido pelo administrador", "Automatic status checking is disabled due to the large number of configured storages, click to check status" : "A verificação automática de status está desabilitada devido ao grande número de armazenamentos configurados, clique para verificar o status", - "Are you sure you want to disconnect this external storage? It will make the storage unavailable in Nextcloud and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Tem certeza de que deseja desconectar este armazenamento externo? Isso tornará o armazenamento indisponível no Nextcloud e levará à exclusão desses arquivos e pastas em qualquer cliente de sincronização que esteja conectado no momento, mas não excluirá nenhum arquivo e pasta no próprio armazenamento externo.", + "Are you sure you want to disconnect this external storage? It will make the storage unavailable in Nextcloud and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Tem certeza de que deseja desconectar este armazenamento externo? Isso tornará o armazenamento indisponível no Nextcloud e levará à exclusão destes arquivos e pastas em qualquer cliente de sincronização que esteja conectado no momento, mas não excluirá nenhum arquivo e pasta do armazenamento externo em si.", "Delete storage?" : "Excluir armazenamento?", "Click to recheck the configuration" : "Clique para rechecar a configuração", "Saved" : "Salvo", diff --git a/apps/files_sharing/css/404.css b/apps/files_sharing/css/404.css index 160a8f83fc3..7542c7cfae1 100644 --- a/apps/files_sharing/css/404.css +++ b/apps/files_sharing/css/404.css @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ #body-login .error-broken-link{ - text-align:left;color:#fff; + text-align:start;color:#fff; } #body-login .error-broken-link ul{ 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..3ab0c7c797b 100644 --- a/apps/files_sharing/l10n/et_EE.js +++ b/apps/files_sharing/l10n/et_EE.js @@ -80,11 +80,12 @@ OC.L10N.register( "Sharing %s failed because the back end does not support ScienceMesh shares" : "„%s“ jagamine ei õnnestunud, sest taustateenus ei toeta ScienceMeshi meedia jagamist", "Unknown share type" : "Tundmatu jagamise tüüp", "Not a directory" : "Ei ole kaust", - "Could not lock node" : "Sõlme ei õnnestunud lukustada", + "Could not lock node" : "Sõlme lukustamine ei õnnestunud", "Public upload is only possible for publicly shared folders" : "Avalik üleslaadminie on võimalik ainult avalikult jagatud kaustades", "Share must at least have READ or CREATE permissions" : "jaosmeedial peavad olema vähemalt logemis- ja loomisõigused", + "Share must have READ permission if UPDATE or DELETE permission is set" : "Kui jaosmeedial on muutmis ja kustutamisõigus, siis peab olema ka lugemisõigus", "Public upload disabled by the administrator" : "Avalik üleslaadimine on administraatori poolt keelatud", - "Could not lock path" : "Ei saanud rada lukustada", + "Could not lock path" : "Asukoha lukustamine ei õnnestunud", "no sharing rights on this item" : "selle objekti kontekstis pole jagamisõigusi", "You are not allowed to edit incoming shares" : "Sul pole lubatud vastuvõetud jaosmeediat muuta", "Wrong or no update parameter given" : "Antud vale või aegunud parameeter", @@ -230,7 +231,7 @@ OC.L10N.register( "Create a new share link" : "Loo uus jagamislink", "Quick share options, the current selected is \"{selectedOption}\"" : "Kiirjagamise valikud, hetkel on valitud „{selectedOption}“", "View only" : "Ainult vaatamine", - "Can edit" : "Võib redigeerida", + "Can edit" : "Võib muuta", "Custom permissions" : "Kohandatud õigused", "Resharing is not allowed" : "Edasijagamine pole lubatud", "Name or email …" : "Nimi või e-posti aadress…", @@ -253,6 +254,7 @@ OC.L10N.register( "File drop" : "Failiedastus", "Upload files to {foldername}." : "Laadi failid üles kausta {foldername}.", "By uploading files, you agree to the terms of service." : "Faile üleslaadides nõustud sa kasutustingimustega.", + "Successfully uploaded files" : "Failide üleslaadimine õnnestus", "View terms of service" : "Vaata kasutustingimusi", "Terms of service" : "Kasutustingimused", "Upload files to {folder}" : "Laadi failid üles kausta {folder}", @@ -356,7 +358,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..e746432509a 100644 --- a/apps/files_sharing/l10n/et_EE.json +++ b/apps/files_sharing/l10n/et_EE.json @@ -78,11 +78,12 @@ "Sharing %s failed because the back end does not support ScienceMesh shares" : "„%s“ jagamine ei õnnestunud, sest taustateenus ei toeta ScienceMeshi meedia jagamist", "Unknown share type" : "Tundmatu jagamise tüüp", "Not a directory" : "Ei ole kaust", - "Could not lock node" : "Sõlme ei õnnestunud lukustada", + "Could not lock node" : "Sõlme lukustamine ei õnnestunud", "Public upload is only possible for publicly shared folders" : "Avalik üleslaadminie on võimalik ainult avalikult jagatud kaustades", "Share must at least have READ or CREATE permissions" : "jaosmeedial peavad olema vähemalt logemis- ja loomisõigused", + "Share must have READ permission if UPDATE or DELETE permission is set" : "Kui jaosmeedial on muutmis ja kustutamisõigus, siis peab olema ka lugemisõigus", "Public upload disabled by the administrator" : "Avalik üleslaadimine on administraatori poolt keelatud", - "Could not lock path" : "Ei saanud rada lukustada", + "Could not lock path" : "Asukoha lukustamine ei õnnestunud", "no sharing rights on this item" : "selle objekti kontekstis pole jagamisõigusi", "You are not allowed to edit incoming shares" : "Sul pole lubatud vastuvõetud jaosmeediat muuta", "Wrong or no update parameter given" : "Antud vale või aegunud parameeter", @@ -228,7 +229,7 @@ "Create a new share link" : "Loo uus jagamislink", "Quick share options, the current selected is \"{selectedOption}\"" : "Kiirjagamise valikud, hetkel on valitud „{selectedOption}“", "View only" : "Ainult vaatamine", - "Can edit" : "Võib redigeerida", + "Can edit" : "Võib muuta", "Custom permissions" : "Kohandatud õigused", "Resharing is not allowed" : "Edasijagamine pole lubatud", "Name or email …" : "Nimi või e-posti aadress…", @@ -251,6 +252,7 @@ "File drop" : "Failiedastus", "Upload files to {foldername}." : "Laadi failid üles kausta {foldername}.", "By uploading files, you agree to the terms of service." : "Faile üleslaadides nõustud sa kasutustingimustega.", + "Successfully uploaded files" : "Failide üleslaadimine õnnestus", "View terms of service" : "Vaata kasutustingimusi", "Terms of service" : "Kasutustingimused", "Upload files to {folder}" : "Laadi failid üles kausta {folder}", @@ -354,7 +356,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/eu.js b/apps/files_sharing/l10n/eu.js index 5ff41b708cb..5c933b4fec9 100644 --- a/apps/files_sharing/l10n/eu.js +++ b/apps/files_sharing/l10n/eu.js @@ -90,6 +90,8 @@ OC.L10N.register( "You are not allowed to edit incoming shares" : "Ez duzu baimenik zuri partekaturikoak editatzeko", "Wrong or no update parameter given" : "Eguneraketa parametrorik ez da eman edo okerra da", "\"Sending the password by Nextcloud Talk\" for sharing a file or folder failed because Nextcloud Talk is not enabled." : "\"Nextcloud Talk-ek pasahitza bidaltzeak\" huts egin du ez dagoelako Nextcloud Talk gaituta fitxategi edo karpeta bat partekatzeko.", + "Custom share link tokens have been disabled by the administrator" : "Administratzaileak esteka pertsonalizatuen tokenak sortzeko aukera ezgaitu du", + "Tokens must contain at least 1 character and may only contain letters, numbers, or a hyphen" : "Tokenek gutxienez karaktere 1 izan behar dute, eta letrak, zenbakiak edo marratxo bat baino ezin dituzte eduki", "Invalid date. Format must be YYYY-MM-DD" : "Data baliogabea. UUU-HH-EE gisako formatua izan behar du", "No sharing rights on this item" : "Ez dago baimenik fitxategi hau partekatzeko", "Invalid share attributes provided: \"%s\"" : "Baliogabeko partekatze atributuak eman dira: \"%s\"", @@ -97,6 +99,7 @@ OC.L10N.register( "No mail notification configured for this share type" : "Partekatze mota honentzat ez dago email jakinarazpenik konfiguratuta", "Wrong password" : "Pasahitz okerra", "Error while sending mail notification" : "Errorea email jakinarazpena bidaltzean", + "Failed to generate a unique token" : "Ezin izan da token bakar bat sortu", "This share does not exist or is no longer available" : "Partekatze hau ez dago edo jada ez dago erabilgarri", "shared by %s" : "%s erabiltzaileak partekatua", "Download" : "Deskargatu", @@ -182,6 +185,8 @@ OC.L10N.register( "Set default folder for accepted shares" : "Ezarri onartutako partekatzeen karpeta lehenetsia", "Reset" : "Berrezarri", "Reset folder to system default" : "Berrezarri karpeta sistemaren balio lehenetsietara", + "Share expiration: " : "Partekatzearen iraungitze-data:", + "Share Expiration" : "Partekatzearen iraungitze-data", "group" : "taldea", "conversation" : "elkarrizketa", "remote" : "urrunekoa", @@ -245,11 +250,14 @@ OC.L10N.register( "Deck board" : "Deck mahaia", "ScienceMesh" : "ScienceMesh", "on {server}" : "{server} zerbitzarian", + "Enter external recipients" : "Sartu kanpoko hartzaileak", + "Search for internal recipients" : "Bilatu barruko hartzaileak", "Note from" : "Oharra bidali du", "Note:" : "Oharra:", "File drop" : "Fitxategiak jaregin", "Upload files to {foldername}." : "Igo fitxategiak {foldername}(e)ra.", "By uploading files, you agree to the terms of service." : "Fitxategiak igotzean, zerbitzu-baldintzak onartzen dituzu.", + "Successfully uploaded files" : "Fitxategiak ongi igo dira", "View terms of service" : "Ikusi zerbitzu-balditzak", "Terms of service" : "Erabilera baldintzak", "Upload files to {folder}" : "Igo fitxategiak {folder}(e)ra", @@ -272,12 +280,18 @@ OC.L10N.register( "Edit" : "Aldatu", "Share" : "Partekatu", "Delete" : "Ezabatu", + "Password field cannot be empty" : "Pasahitz-eremua ezin da hutsik egon", "Replace current password" : "Aldatu uneko pasahitza", + "Failed to generate a new token" : "Ezin izan da token berri bat sortu", "Allow upload and editing" : "Onartu igotzea eta editatzea", "Allow editing" : "Baimendu editatzea", "Upload only" : "Igoera soilik", "Advanced settings" : "Ezarpen aurreratuak", "Share label" : "Partekatu etiketa", + "Share link token" : "Partekatzeko esteka-tokena", + "Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Ezarri partekatze-estekaren token publikoa gogoratzeko erraza den zerbait, edo sortu token berria. Ez da gomendagarria informazio sentikorra duten partekatzeetako tokenak asma daitezkeenak erabiltzea.", + "Generating…" : "Sortzen...", + "Generate new token" : "Sortu token berria", "Set password" : "Pasahitza ezarri", "Password expires {passwordExpirationTime}" : "Pasahitza {passwordExpirationTime} iraungiko da", "Password expired" : "Pasahitza iraungi da", @@ -288,6 +302,7 @@ OC.L10N.register( "Allow download and sync" : "Baimendu deskargatu eta sinkronizatzea", "Note to recipient" : "Oharra hartzailearentzat", "Enter a note for the share recipient" : "Sartu ohar bat partekatzearen hartzailearentzat", + "Show files in grid view" : "Erakutsi fitxategiak sareta ikuspegian", "Delete share" : "Ezabatu partekatzea", "Others with access" : "Sarbidea duten beste erabiltzaileak", "No other accounts with access found" : "Ez da aurkitu sarbidea duen beste konturik", @@ -296,12 +311,22 @@ OC.L10N.register( "Unable to fetch inherited shares" : "Ezin izan dira heredatutako partekatzeak eskuratu", "Link shares" : "Lotu partekatzeak", "Shares" : "Partekatzeak", + "Use this method to share files with individuals or teams within your organization. If the recipient already has access to the share but cannot locate it, you can send them the internal share link for easy access." : "Erabili metodo hau zure erakundeko banako edo taldeekin fitxategiak partekatzeko. Hartzaileak dagoeneko baimena badu partekatutako elementurako baina ezin badu aurkitu, bidali iezaiozu barneko partekatze-esteka, sarbidea errazteko.", + "Use this method to share files with individuals or organizations outside your organization. Files and folders can be shared via public share links and email addresses. You can also share to other Nextcloud accounts hosted on different instances using their federated cloud ID." : "Erabili metodo hau zure erakundeaz kanpoko banako edo erakundeekin fitxategiak partekatzeko. Fitxategiak eta karpetak parteka ditzakezu esteka publikoen bidez edo helbide elektronikoen bidez. Bestelako Nextcloud kontuetara ere parteka ditzakezu, beste instantziatan daudenak, haien federatutako hodeiaren ID-a erabiliz.", + "Shares that are not part of the internal or external shares. This can be shares from apps or other sources." : "Barneko zein kanpoko partekatzeetan sartzen ez diren partekatzeak. Hauetakoren bat aplikazioetatik edo beste iturri batzuetatik etorritako partekatzeak izan daitezke.", + "Share with accounts, teams, federated cloud IDs" : "Partekatu kontuekin, taldeekin edo federatutako hodeien ID-ekin", + "Share with accounts and teams" : "Partekatu kontuekin eta taldeekin", + "Email, federated cloud ID" : "Posta elektroniko, federatutako hodeien ID", "Unable to load the shares list" : "Ezin izan da partekatzeen zerrenda kargatu", "Expires {relativetime}" : "Iraungitzea: {relativetime}", "this share just expired." : "partekatze hau oraintxe iraungi da.", "Shared with you by {owner}" : "{owner} erabiltzaileak zurekin partekatua", "Internal shares" : "Barneko partekatzeak", + "Internal shares explanation" : "Barneko partekatzeen azalpena ", "External shares" : "Kanpoko sareak", + "External shares explanation" : "Kanpoko partekatzeen azalpena", + "Additional shares" : "Partekatze gehigarriak", + "Additional shares explanation" : "Partekatze gehigarrien azalpena", "Link to a file" : "Esteka fitxategi batera", "_Accept share_::_Accept shares_" : ["Onartu partekatzea","Onartu partekatzeak"], "Open in Files" : "Ireki Fitxategiak aplikazioan", @@ -395,6 +420,8 @@ OC.L10N.register( "_1 email address already added_::_{count} email addresses already added_" : ["Helbide elektroniko 1 gehitu da dagoeneko","{count} helbide elektroniko gehitu dira dagoeneko"], "_1 email address added_::_{count} email addresses added_" : ["Helbide elektroniko 1 gehitu da","{count} helbide elektroniko gehitu dira"], "Search for share recipients" : "Bilatu partekatze-hartzaileak", - "No recommendations. Start typing." : "Gomendiorik ez. Hasi idazten." + "No recommendations. Start typing." : "Gomendiorik ez. Hasi idazten.", + "Share with accounts, teams, federated cloud id" : "Partekatu kontuekin, taldeekin edo federatutako hodeien ID-ekin", + "Email, federated cloud id" : "Posta elektroniko, federatutako hodeien ID" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/eu.json b/apps/files_sharing/l10n/eu.json index fd592005648..40eac16d694 100644 --- a/apps/files_sharing/l10n/eu.json +++ b/apps/files_sharing/l10n/eu.json @@ -88,6 +88,8 @@ "You are not allowed to edit incoming shares" : "Ez duzu baimenik zuri partekaturikoak editatzeko", "Wrong or no update parameter given" : "Eguneraketa parametrorik ez da eman edo okerra da", "\"Sending the password by Nextcloud Talk\" for sharing a file or folder failed because Nextcloud Talk is not enabled." : "\"Nextcloud Talk-ek pasahitza bidaltzeak\" huts egin du ez dagoelako Nextcloud Talk gaituta fitxategi edo karpeta bat partekatzeko.", + "Custom share link tokens have been disabled by the administrator" : "Administratzaileak esteka pertsonalizatuen tokenak sortzeko aukera ezgaitu du", + "Tokens must contain at least 1 character and may only contain letters, numbers, or a hyphen" : "Tokenek gutxienez karaktere 1 izan behar dute, eta letrak, zenbakiak edo marratxo bat baino ezin dituzte eduki", "Invalid date. Format must be YYYY-MM-DD" : "Data baliogabea. UUU-HH-EE gisako formatua izan behar du", "No sharing rights on this item" : "Ez dago baimenik fitxategi hau partekatzeko", "Invalid share attributes provided: \"%s\"" : "Baliogabeko partekatze atributuak eman dira: \"%s\"", @@ -95,6 +97,7 @@ "No mail notification configured for this share type" : "Partekatze mota honentzat ez dago email jakinarazpenik konfiguratuta", "Wrong password" : "Pasahitz okerra", "Error while sending mail notification" : "Errorea email jakinarazpena bidaltzean", + "Failed to generate a unique token" : "Ezin izan da token bakar bat sortu", "This share does not exist or is no longer available" : "Partekatze hau ez dago edo jada ez dago erabilgarri", "shared by %s" : "%s erabiltzaileak partekatua", "Download" : "Deskargatu", @@ -180,6 +183,8 @@ "Set default folder for accepted shares" : "Ezarri onartutako partekatzeen karpeta lehenetsia", "Reset" : "Berrezarri", "Reset folder to system default" : "Berrezarri karpeta sistemaren balio lehenetsietara", + "Share expiration: " : "Partekatzearen iraungitze-data:", + "Share Expiration" : "Partekatzearen iraungitze-data", "group" : "taldea", "conversation" : "elkarrizketa", "remote" : "urrunekoa", @@ -243,11 +248,14 @@ "Deck board" : "Deck mahaia", "ScienceMesh" : "ScienceMesh", "on {server}" : "{server} zerbitzarian", + "Enter external recipients" : "Sartu kanpoko hartzaileak", + "Search for internal recipients" : "Bilatu barruko hartzaileak", "Note from" : "Oharra bidali du", "Note:" : "Oharra:", "File drop" : "Fitxategiak jaregin", "Upload files to {foldername}." : "Igo fitxategiak {foldername}(e)ra.", "By uploading files, you agree to the terms of service." : "Fitxategiak igotzean, zerbitzu-baldintzak onartzen dituzu.", + "Successfully uploaded files" : "Fitxategiak ongi igo dira", "View terms of service" : "Ikusi zerbitzu-balditzak", "Terms of service" : "Erabilera baldintzak", "Upload files to {folder}" : "Igo fitxategiak {folder}(e)ra", @@ -270,12 +278,18 @@ "Edit" : "Aldatu", "Share" : "Partekatu", "Delete" : "Ezabatu", + "Password field cannot be empty" : "Pasahitz-eremua ezin da hutsik egon", "Replace current password" : "Aldatu uneko pasahitza", + "Failed to generate a new token" : "Ezin izan da token berri bat sortu", "Allow upload and editing" : "Onartu igotzea eta editatzea", "Allow editing" : "Baimendu editatzea", "Upload only" : "Igoera soilik", "Advanced settings" : "Ezarpen aurreratuak", "Share label" : "Partekatu etiketa", + "Share link token" : "Partekatzeko esteka-tokena", + "Set the public share link token to something easy to remember or generate a new token. It is not recommended to use a guessable token for shares which contain sensitive information." : "Ezarri partekatze-estekaren token publikoa gogoratzeko erraza den zerbait, edo sortu token berria. Ez da gomendagarria informazio sentikorra duten partekatzeetako tokenak asma daitezkeenak erabiltzea.", + "Generating…" : "Sortzen...", + "Generate new token" : "Sortu token berria", "Set password" : "Pasahitza ezarri", "Password expires {passwordExpirationTime}" : "Pasahitza {passwordExpirationTime} iraungiko da", "Password expired" : "Pasahitza iraungi da", @@ -286,6 +300,7 @@ "Allow download and sync" : "Baimendu deskargatu eta sinkronizatzea", "Note to recipient" : "Oharra hartzailearentzat", "Enter a note for the share recipient" : "Sartu ohar bat partekatzearen hartzailearentzat", + "Show files in grid view" : "Erakutsi fitxategiak sareta ikuspegian", "Delete share" : "Ezabatu partekatzea", "Others with access" : "Sarbidea duten beste erabiltzaileak", "No other accounts with access found" : "Ez da aurkitu sarbidea duen beste konturik", @@ -294,12 +309,22 @@ "Unable to fetch inherited shares" : "Ezin izan dira heredatutako partekatzeak eskuratu", "Link shares" : "Lotu partekatzeak", "Shares" : "Partekatzeak", + "Use this method to share files with individuals or teams within your organization. If the recipient already has access to the share but cannot locate it, you can send them the internal share link for easy access." : "Erabili metodo hau zure erakundeko banako edo taldeekin fitxategiak partekatzeko. Hartzaileak dagoeneko baimena badu partekatutako elementurako baina ezin badu aurkitu, bidali iezaiozu barneko partekatze-esteka, sarbidea errazteko.", + "Use this method to share files with individuals or organizations outside your organization. Files and folders can be shared via public share links and email addresses. You can also share to other Nextcloud accounts hosted on different instances using their federated cloud ID." : "Erabili metodo hau zure erakundeaz kanpoko banako edo erakundeekin fitxategiak partekatzeko. Fitxategiak eta karpetak parteka ditzakezu esteka publikoen bidez edo helbide elektronikoen bidez. Bestelako Nextcloud kontuetara ere parteka ditzakezu, beste instantziatan daudenak, haien federatutako hodeiaren ID-a erabiliz.", + "Shares that are not part of the internal or external shares. This can be shares from apps or other sources." : "Barneko zein kanpoko partekatzeetan sartzen ez diren partekatzeak. Hauetakoren bat aplikazioetatik edo beste iturri batzuetatik etorritako partekatzeak izan daitezke.", + "Share with accounts, teams, federated cloud IDs" : "Partekatu kontuekin, taldeekin edo federatutako hodeien ID-ekin", + "Share with accounts and teams" : "Partekatu kontuekin eta taldeekin", + "Email, federated cloud ID" : "Posta elektroniko, federatutako hodeien ID", "Unable to load the shares list" : "Ezin izan da partekatzeen zerrenda kargatu", "Expires {relativetime}" : "Iraungitzea: {relativetime}", "this share just expired." : "partekatze hau oraintxe iraungi da.", "Shared with you by {owner}" : "{owner} erabiltzaileak zurekin partekatua", "Internal shares" : "Barneko partekatzeak", + "Internal shares explanation" : "Barneko partekatzeen azalpena ", "External shares" : "Kanpoko sareak", + "External shares explanation" : "Kanpoko partekatzeen azalpena", + "Additional shares" : "Partekatze gehigarriak", + "Additional shares explanation" : "Partekatze gehigarrien azalpena", "Link to a file" : "Esteka fitxategi batera", "_Accept share_::_Accept shares_" : ["Onartu partekatzea","Onartu partekatzeak"], "Open in Files" : "Ireki Fitxategiak aplikazioan", @@ -393,6 +418,8 @@ "_1 email address already added_::_{count} email addresses already added_" : ["Helbide elektroniko 1 gehitu da dagoeneko","{count} helbide elektroniko gehitu dira dagoeneko"], "_1 email address added_::_{count} email addresses added_" : ["Helbide elektroniko 1 gehitu da","{count} helbide elektroniko gehitu dira"], "Search for share recipients" : "Bilatu partekatze-hartzaileak", - "No recommendations. Start typing." : "Gomendiorik ez. Hasi idazten." + "No recommendations. Start typing." : "Gomendiorik ez. Hasi idazten.", + "Share with accounts, teams, federated cloud id" : "Partekatu kontuekin, taldeekin edo federatutako hodeien ID-ekin", + "Email, federated cloud id" : "Posta elektroniko, federatutako hodeien ID" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_sharing/l10n/fa.js b/apps/files_sharing/l10n/fa.js index 21c1715227e..e2148a257d0 100644 --- a/apps/files_sharing/l10n/fa.js +++ b/apps/files_sharing/l10n/fa.js @@ -15,6 +15,7 @@ OC.L10N.register( "You removed yourself" : "شما خدتان را حذف کردید", "Share for {user} expired" : "اشتراک برای {user} منقضی شده است", "Share expired" : "اشتراک منقضی شد", + "{actor} shared {file} with you" : "{actor} {file} را با شما به اشتراک گذاشت", "A file or folder shared by mail or by public link was <strong>downloaded</strong>" : "یک پرونده یا پوشه به اشتراک گذاشته شده از طریق پست یا از طریق لینک عمومی بارگیری شد", "A file or folder was shared from <strong>another server</strong>" : "یک پرونده یا پوشه از سرور دیگر به اشتراک گذاشته شد", "Sharing" : "اشتراک گذاری", @@ -150,6 +151,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 +160,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..03df10efc91 100644 --- a/apps/files_sharing/l10n/fa.json +++ b/apps/files_sharing/l10n/fa.json @@ -13,6 +13,7 @@ "You removed yourself" : "شما خدتان را حذف کردید", "Share for {user} expired" : "اشتراک برای {user} منقضی شده است", "Share expired" : "اشتراک منقضی شد", + "{actor} shared {file} with you" : "{actor} {file} را با شما به اشتراک گذاشت", "A file or folder shared by mail or by public link was <strong>downloaded</strong>" : "یک پرونده یا پوشه به اشتراک گذاشته شده از طریق پست یا از طریق لینک عمومی بارگیری شد", "A file or folder was shared from <strong>another server</strong>" : "یک پرونده یا پوشه از سرور دیگر به اشتراک گذاشته شد", "Sharing" : "اشتراک گذاری", @@ -148,6 +149,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 +158,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_sharing/lib/DefaultPublicShareTemplateProvider.php b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php index 910d00a5972..645250ab2b5 100644 --- a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php +++ b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php @@ -91,6 +91,9 @@ class DefaultPublicShareTemplateProvider implements IPublicShareTemplateProvider 'disclaimer', $this->appConfig->getValueString('core', 'shareapi_public_link_disclaimertext'), ); + // file drops do not request the root folder so we need to provide label and note if available + $this->initialState->provideInitialState('label', $share->getLabel()); + $this->initialState->provideInitialState('note', $share->getNote()); } // Set up initial state $this->initialState->provideInitialState('isPublic', true); diff --git a/apps/files_sharing/openapi.json b/apps/files_sharing/openapi.json index 68420dde80e..89c82843939 100644 --- a/apps/files_sharing/openapi.json +++ b/apps/files_sharing/openapi.json @@ -1490,6 +1490,13 @@ 1 ] } + }, + { + "name": "X-NC-Preview", + "in": "header", + "schema": { + "type": "string" + } } ], "responses": { @@ -1574,11 +1581,13 @@ "password": { "type": "string", "nullable": true, + "default": null, "description": "Password of the share" }, "dir": { "type": "string", "nullable": true, + "default": null, "description": "Subdirectory to get info about" }, "depth": { @@ -1782,12 +1791,14 @@ "path": { "type": "string", "nullable": true, + "default": null, "description": "Path of the share" }, "permissions": { "type": "integer", "format": "int64", "nullable": true, + "default": null, "description": "Permissions for the share" }, "shareType": { @@ -1799,11 +1810,13 @@ "shareWith": { "type": "string", "nullable": true, + "default": null, "description": "The entity this should be shared with" }, "publicUpload": { "type": "string", "nullable": true, + "default": null, "enum": [ "true", "false" @@ -1818,11 +1831,13 @@ "sendPasswordByTalk": { "type": "string", "nullable": true, + "default": null, "description": "Send the password for the share over Talk" }, "expireDate": { "type": "string", "nullable": true, + "default": null, "description": "The expiry date of the share in the user's timezone at 00:00. If $expireDate is not supplied or set to `null`, the system default will be used." }, "note": { @@ -1838,11 +1853,13 @@ "attributes": { "type": "string", "nullable": true, + "default": null, "description": "Additional attributes for the share" }, "sendMail": { "type": "string", "nullable": true, + "default": null, "enum": [ "false", "true" @@ -2297,56 +2314,67 @@ "type": "integer", "format": "int64", "nullable": true, + "default": null, "description": "New permissions" }, "password": { "type": "string", "nullable": true, + "default": null, "description": "New password" }, "sendPasswordByTalk": { "type": "string", "nullable": true, + "default": null, "description": "New condition if the password should be send over Talk" }, "publicUpload": { "type": "string", "nullable": true, + "default": null, "description": "New condition if public uploading is allowed" }, "expireDate": { "type": "string", "nullable": true, + "default": null, "description": "New expiry date" }, "note": { "type": "string", "nullable": true, + "default": null, "description": "New note" }, "label": { "type": "string", "nullable": true, + "default": null, "description": "New label" }, "hideDownload": { "type": "string", "nullable": true, + "default": null, "description": "New condition if the download should be hidden" }, "attributes": { "type": "string", "nullable": true, + "default": null, "description": "New additional attributes" }, "sendMail": { "type": "string", "nullable": true, + "default": null, "description": "if the share should be send by mail. Considering the share already exists, no mail will be send after the share is updated. You will have to use the sendMail action to send the mail." }, "token": { "type": "string", "nullable": true, + "default": null, "description": "New token" } } @@ -3099,7 +3127,8 @@ "description": "Limit to specific item types", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { @@ -3128,6 +3157,7 @@ "description": "Limit to specific share types", "schema": { "nullable": true, + "default": null, "oneOf": [ { "type": "integer", @@ -3267,6 +3297,7 @@ "description": "Limit to specific share types", "schema": { "nullable": true, + "default": null, "oneOf": [ { "type": "integer", diff --git a/apps/files_sharing/src/files_views/publicFileDrop.ts b/apps/files_sharing/src/files_views/publicFileDrop.ts index 0d782d48fc7..65756e83c74 100644 --- a/apps/files_sharing/src/files_views/publicFileDrop.ts +++ b/apps/files_sharing/src/files_views/publicFileDrop.ts @@ -4,7 +4,8 @@ */ import type { VueConstructor } from 'vue' -import { Folder, Permission, View, davRemoteURL, davRootPath, getNavigation } from '@nextcloud/files' +import { Folder, Permission, View, getNavigation } from '@nextcloud/files' +import { defaultRemoteURL, defaultRootPath } from '@nextcloud/files/dav' import { loadState } from '@nextcloud/initial-state' import { translate as t } from '@nextcloud/l10n' import svgCloudUpload from '@mdi/svg/svg/cloud-upload.svg?raw' @@ -45,8 +46,8 @@ export default () => { // Fake a writeonly folder as root folder: new Folder({ id: 0, - source: `${davRemoteURL}${davRootPath}`, - root: davRootPath, + source: `${defaultRemoteURL}${defaultRootPath}`, + root: defaultRootPath, owner: null, permissions: Permission.CREATE, }), diff --git a/apps/files_sharing/src/views/FilesViewFileDropEmptyContent.vue b/apps/files_sharing/src/views/FilesViewFileDropEmptyContent.vue index 5571e5e9f5d..33fec9af028 100644 --- a/apps/files_sharing/src/views/FilesViewFileDropEmptyContent.vue +++ b/apps/files_sharing/src/views/FilesViewFileDropEmptyContent.vue @@ -5,13 +5,29 @@ <template> <NcEmptyContent class="file-drop-empty-content" data-cy-files-sharing-file-drop - :name="t('files_sharing', 'File drop')"> + :name="name"> <template #icon> <NcIconSvgWrapper :svg="svgCloudUpload" /> </template> <template #description> - {{ t('files_sharing', 'Upload files to {foldername}.', { foldername }) }} - {{ disclaimer === '' ? '' : t('files_sharing', 'By uploading files, you agree to the terms of service.') }} + <p> + {{ shareNote || t('files_sharing', 'Upload files to {foldername}.', { foldername }) }} + </p> + <p v-if="disclaimer"> + {{ t('files_sharing', 'By uploading files, you agree to the terms of service.') }} + </p> + <NcNoteCard v-if="getSortedUploads().length" + class="file-drop-empty-content__note-card" + type="success"> + <h2 id="file-drop-empty-content__heading"> + {{ t('files_sharing', 'Successfully uploaded files') }} + </h2> + <ul aria-labelledby="file-drop-empty-content__heading" class="file-drop-empty-content__list"> + <li v-for="file in getSortedUploads()" :key="file"> + {{ file }} + </li> + </ul> + </NcNoteCard> </template> <template #action> <template v-if="disclaimer"> @@ -34,16 +50,24 @@ </NcEmptyContent> </template> +<script lang="ts"> +/* eslint-disable import/first */ + +// We need this on module level rather than on the instance as view will be refreshed by the files app after uploading +const uploads = new Set<string>() +</script> + <script setup lang="ts"> import { loadState } from '@nextcloud/initial-state' import { translate as t } from '@nextcloud/l10n' -import { getUploader, UploadPicker } from '@nextcloud/upload' +import { getUploader, UploadPicker, UploadStatus } from '@nextcloud/upload' import { ref } from 'vue' import NcButton from '@nextcloud/vue/components/NcButton' import NcDialog from '@nextcloud/vue/components/NcDialog' import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent' import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper' +import NcNoteCard from '@nextcloud/vue/components/NcNoteCard' import svgCloudUpload from '@mdi/svg/svg/cloud-upload.svg?raw' defineProps<{ @@ -51,17 +75,62 @@ defineProps<{ }>() const disclaimer = loadState<string>('files_sharing', 'disclaimer', '') +const shareLabel = loadState<string>('files_sharing', 'label', '') +const shareNote = loadState<string>('files_sharing', 'note', '') + +const name = shareLabel || t('files_sharing', 'File drop') + const showDialog = ref(false) const uploadDestination = getUploader().destination -</script> -<style scoped> -:deep(.terms-of-service-dialog) { - min-height: min(100px, 20vh); +getUploader() + .addNotifier((upload) => { + if (upload.status === UploadStatus.FINISHED && upload.file.name) { + // if a upload is finished and is not a meta upload (name is set) + // then we add the upload to the list of finished uploads to be shown to the user + uploads.add(upload.file.name) + } + }) + +/** + * Get the previous uploads as sorted list + */ +function getSortedUploads() { + return [...uploads].sort((a, b) => a.localeCompare(b)) } -/* TODO fix in library */ -.file-drop-empty-content :deep(.empty-content__action) { - display: flex; - gap: var(--default-grid-baseline); +</script> + +<style scoped lang="scss"> +.file-drop-empty-content { + margin: auto; + max-width: max(50vw, 300px); + + .file-drop-empty-content__note-card { + width: fit-content; + margin-inline: auto; + } + + #file-drop-empty-content__heading { + margin-block: 0 10px; + font-weight: bold; + font-size: 20px; + } + + .file-drop-empty-content__list { + list-style: inside; + max-height: min(350px, 33vh); + overflow-y: scroll; + padding-inline-end: calc(2 * var(--default-grid-baseline)); + } + + :deep(.terms-of-service-dialog) { + min-height: min(100px, 20vh); + } + + /* TODO fix in library */ + :deep(.empty-content__action) { + display: flex; + gap: var(--default-grid-baseline); + } } </style> diff --git a/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php b/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php index 888b2cdd596..769516cda85 100644 --- a/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php +++ b/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php @@ -11,6 +11,7 @@ use OCP\Federation\ICloudId; use OCP\Federation\ICloudIdManager; use OCP\IDBConnection; use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Test\TestCase; @@ -24,20 +25,9 @@ use Test\TestCase; */ class CleanupRemoteStoragesTest extends TestCase { - /** - * @var CleanupRemoteStorages - */ - private $command; - - /** - * @var IDBConnection - */ - private $connection; - - /** - * @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject - */ - private $cloudIdManager; + protected IDBConnection $connection; + protected CleanupRemoteStorages $command; + private ICloudIdManager&MockObject $cloudIdManager; private $storages = [ ['id' => 'shared::7b4a322b22f9d0047c38d77d471ce3cf', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e1', 'remote' => 'https://hostname.tld/owncloud1', 'user' => 'user1'], @@ -77,7 +67,7 @@ class CleanupRemoteStoragesTest extends TestCase { foreach ($this->storages as &$storage) { if (isset($storage['id'])) { $storageQuery->setParameter('id', $storage['id']); - $storageQuery->execute(); + $storageQuery->executeStatement(); $storage['numeric_id'] = $storageQuery->getLastInsertId(); } @@ -121,13 +111,13 @@ class CleanupRemoteStoragesTest extends TestCase { foreach ($this->storages as $storage) { if (isset($storage['id'])) { $storageQuery->setParameter('id', $storage['id']); - $storageQuery->execute(); + $storageQuery->executeStatement(); } if (isset($storage['share_token'])) { $shareExternalQuery->setParameter('share_token', $storage['share_token']); $shareExternalQuery->setParameter('remote', $storage['remote']); - $shareExternalQuery->execute(); + $shareExternalQuery->executeStatement(); } } @@ -174,14 +164,13 @@ class CleanupRemoteStoragesTest extends TestCase { ->getMock(); // parent folder, `files`, ´test` and `welcome.txt` => 4 elements - + $outputCalls = []; $output ->expects($this->any()) ->method('writeln') - ->withConsecutive( - ['5 remote storage(s) need(s) to be checked'], - ['5 remote share(s) exist'], - ); + ->willReturnCallback(function (string $text) use (&$outputCalls) { + $outputCalls[] = $text; + }); $this->cloudIdManager ->expects($this->any()) @@ -206,5 +195,10 @@ class CleanupRemoteStoragesTest extends TestCase { $this->assertFalse($this->doesStorageExist($this->storages[3]['numeric_id'])); $this->assertTrue($this->doesStorageExist($this->storages[4]['numeric_id'])); $this->assertFalse($this->doesStorageExist($this->storages[5]['numeric_id'])); + + $this->assertEquals([ + '5 remote storage(s) need(s) to be checked', + '5 remote share(s) exist', + ], array_slice($outputCalls, 0, 2)); } } diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 02c133ee5d1..203e09e217e 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -1675,8 +1675,11 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['canAccessShare']) + // This is not possible anymore with PHPUnit 10+ + // as `setMethods` was removed and now real reflection is used, thus the class needs to exist. + // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') + $helper = $this->getMockBuilder(\stdClass::class) + ->addMethods(['canAccessShare']) ->getMock(); $helper->method('canAccessShare') ->with($share, $this->currentUser) @@ -2492,8 +2495,11 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['createShare']) + // This is not possible anymore with PHPUnit 10+ + // as `setMethods` was removed and now real reflection is used, thus the class needs to exist. + // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') + $helper = $this->getMockBuilder(\stdClass::class) + ->addMethods(['createShare']) ->getMock(); $helper->method('createShare') ->with( @@ -2598,7 +2604,10 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') + // This is not possible anymore with PHPUnit 10+ + // as `setMethods` was removed and now real reflection is used, thus the class needs to exist. + // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') + $helper = $this->getMockBuilder(\stdClass::class) ->addMethods(['createShare']) ->getMock(); $helper->method('createShare') @@ -5093,8 +5102,11 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['formatShare', 'canAccessShare']) + // This is not possible anymore with PHPUnit 10+ + // as `setMethods` was removed and now real reflection is used, thus the class needs to exist. + // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') + $helper = $this->getMockBuilder(\stdClass::class) + ->addMethods(['formatShare', 'canAccessShare']) ->getMock(); $helper->method('formatShare') ->with($share) diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index 524336787cb..a6bef1bed56 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -399,6 +399,8 @@ class ShareControllerTest extends \Test\TestCase { ->setPassword('password') ->setShareOwner('ownerUID') ->setSharedBy('initiatorUID') + ->setNote('The note') + ->setLabel('A label') ->setNode($file) ->setTarget("/$filename") ->setToken('token'); @@ -478,6 +480,8 @@ class ShareControllerTest extends \Test\TestCase { 'disclaimer' => 'My disclaimer text', 'owner' => 'ownerUID', 'ownerDisplayName' => 'ownerDisplay', + 'note' => 'The note', + 'label' => 'A label', ]; $response = $this->shareController->showShare(); @@ -487,9 +491,9 @@ class ShareControllerTest extends \Test\TestCase { $csp = new ContentSecurityPolicy(); $csp->addAllowedFrameDomain('\'self\''); $expectedResponse = new PublicTemplateResponse('files', 'index'); - $expectedResponse->setParams(['pageTitle' => $filename]); + $expectedResponse->setParams(['pageTitle' => 'A label']); $expectedResponse->setContentSecurityPolicy($csp); - $expectedResponse->setHeaderTitle($filename); + $expectedResponse->setHeaderTitle('A label'); $expectedResponse->setHeaderDetails('shared by ownerDisplay'); $expectedResponse->setHeaderActions([ new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', 'shareUrl'), diff --git a/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php index f2df74fd01b..571647829f2 100644 --- a/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php @@ -15,15 +15,13 @@ use OCP\IRequest; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class ShareInfoControllerTest extends TestCase { - /** @var ShareInfoController */ - private $controller; - - /** @var ShareManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; + protected ShareInfoController $controller; + protected ShareManager&MockObject $shareManager; protected function setUp(): void { @@ -31,14 +29,11 @@ class ShareInfoControllerTest extends TestCase { $this->shareManager = $this->createMock(ShareManager::class); - $this->controller = $this->getMockBuilder(ShareInfoController::class) - ->setConstructorArgs([ - 'files_sharing', - $this->createMock(IRequest::class), - $this->shareManager - ]) - ->setMethods(['addROWrapper']) - ->getMock(); + $this->controller = new ShareInfoController( + 'files_sharing', + $this->createMock(IRequest::class), + $this->shareManager + ); } public function testNoShare(): void { diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index 611392c286e..5314d1ec00f 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -33,6 +33,7 @@ use OCP\IUserSession; use OCP\OCS\IDiscoveryService; use OCP\Server; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\Traits\UserTrait; @@ -46,42 +47,19 @@ use Test\Traits\UserTrait; class ManagerTest extends TestCase { use UserTrait; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $contactsManager; - - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject * */ - private $manager; - - /** @var \OC\Files\Mount\Manager */ - private $mountManager; - - /** @var IClientService|\PHPUnit\Framework\MockObject\MockObject */ - private $clientService; - - /** @var ICloudFederationProviderManager|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationProviderManager; - - /** @var ICloudFederationFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationFactory; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IGroupManager */ - private $groupManager; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IUserManager */ - private $userManager; - - /** @var LoggerInterface */ - private $logger; - - private $uid; - - /** - * @var IUser - */ - private $user; - private $testMountProvider; - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ - private $eventDispatcher; + protected string $uid; + protected IUser $user; + protected MountProvider $testMountProvider; + protected IEventDispatcher&MockObject $eventDispatcher; + protected LoggerInterface&MockObject $logger; + protected \OC\Files\Mount\Manager $mountManager; + protected IManager&MockObject $contactsManager; + protected Manager&MockObject $manager; + protected IClientService&MockObject $clientService; + protected ICloudFederationProviderManager&MockObject $cloudFederationProviderManager; + protected ICloudFederationFactory&MockObject $cloudFederationFactory; + protected IGroupManager&MockObject $groupManager; + protected IUserManager&MockObject $userManager; protected function setUp(): void { parent::setUp(); @@ -169,7 +147,7 @@ class ManagerTest extends TestCase { $this->eventDispatcher, $this->logger, ] - )->setMethods(['tryOCMEndPoint'])->getMock(); + )->onlyMethods(['tryOCMEndPoint'])->getMock(); } private function setupMounts() { @@ -222,14 +200,12 @@ class ManagerTest extends TestCase { if ($isGroup) { $this->manager->expects($this->never())->method('tryOCMEndPoint'); } else { - $this->manager->method('tryOCMEndPoint') - ->withConsecutive( - ['http://localhost', 'token1', '2342', 'accept'], - ['http://localhost', 'token3', '2342', 'decline'], - )->willReturnOnConsecutiveCalls( - false, - false, - ); + $this->manager->expects(self::atLeast(2)) + ->method('tryOCMEndPoint') + ->willReturnMap([ + ['http://localhost', 'token1', '2342', 'accept', false], + ['http://localhost', 'token3', '2342', 'decline', false], + ]); } // Add a share for "user" diff --git a/apps/files_sharing/tests/MountProviderTest.php b/apps/files_sharing/tests/MountProviderTest.php index 285af51f022..4a1eb673a06 100644 --- a/apps/files_sharing/tests/MountProviderTest.php +++ b/apps/files_sharing/tests/MountProviderTest.php @@ -20,29 +20,21 @@ use OCP\IUserManager; use OCP\Share\IAttributes as IShareAttributes; use OCP\Share\IManager; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; /** * @group DB */ class MountProviderTest extends \Test\TestCase { - /** @var MountProvider */ - private $provider; - /** @var IConfig|MockObject */ - private $config; + protected MountProvider $provider; - /** @var IUser|MockObject */ - private $user; - - /** @var IStorageFactory|MockObject */ - private $loader; - - /** @var IManager|MockObject */ - private $shareManager; - - /** @var LoggerInterface|MockObject */ - private $logger; + protected IUser&MockObject $user; + protected IConfig&MockObject $config; + protected IManager&MockObject $shareManager; + protected IStorageFactory&MockObject $loader; + protected LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); @@ -144,38 +136,34 @@ class MountProviderTest extends \Test\TestCase { ]; // tests regarding circles and sciencemesh are made in the apps themselves. $circleShares = []; - $sciencemeshShares = []; + $scienceMeshShares = []; $this->user->expects($this->any()) ->method('getUID') ->willReturn('user1'); $this->shareManager->expects($this->exactly(6)) ->method('getSharedWith') - ->withConsecutive( - ['user1', IShare::TYPE_USER], - ['user1', IShare::TYPE_GROUP, null, -1], - ['user1', IShare::TYPE_CIRCLE, null, -1], - ['user1', IShare::TYPE_ROOM, null, -1], - ['user1', IShare::TYPE_DECK, null, -1], - ['user1', IShare::TYPE_SCIENCEMESH, null, -1], - )->willReturnOnConsecutiveCalls( - $userShares, - $groupShares, - $circleShares, - $roomShares, - $deckShares, - $sciencemeshShares - ); + ->willReturnMap([ + ['user1', IShare::TYPE_USER, null, -1, 0, $userShares], + ['user1', IShare::TYPE_GROUP, null, -1, 0, $groupShares], + ['user1', IShare::TYPE_CIRCLE, null, -1, 0, $circleShares], + ['user1', IShare::TYPE_ROOM, null, -1, 0, $roomShares], + ['user1', IShare::TYPE_DECK, null, -1, 0, $deckShares], + ['user1', IShare::TYPE_SCIENCEMESH, null, -1, 0, $scienceMeshShares], + ]); + $this->shareManager->expects($this->any()) ->method('newShare') ->willReturnCallback(function () use ($rootFolder, $userManager) { return new Share($rootFolder, $userManager); }); + $mounts = $this->provider->getMountsForUser($this->user, $this->loader); $this->assertCount(4, $mounts); $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[0]); $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[1]); $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[2]); $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[3]); + /** @var OCA\Files_Sharing\SharedMount[] $mounts */ $mountedShare1 = $mounts[0]->getShare(); $this->assertEquals('2', $mountedShare1->getId()); $this->assertEquals('user2', $mountedShare1->getShareOwner()); @@ -204,7 +192,7 @@ class MountProviderTest extends \Test\TestCase { $this->assertEquals(31, $mountedShare4->getPermissions()); } - public function mergeSharesDataProvider() { + public static function mergeSharesDataProvider(): array { // note: the user in the specs here is the shareOwner not recipient // the recipient is always "user1" return [ @@ -368,24 +356,18 @@ class MountProviderTest extends \Test\TestCase { $circleShares = []; $roomShares = []; $deckShares = []; - $sciencemeshShares = []; + $scienceMeshShares = []; $this->shareManager->expects($this->exactly(6)) ->method('getSharedWith') - ->withConsecutive( - ['user1', IShare::TYPE_USER], - ['user1', IShare::TYPE_GROUP, null, -1], - ['user1', IShare::TYPE_CIRCLE, null, -1], - ['user1', IShare::TYPE_ROOM, null, -1], - ['user1', IShare::TYPE_DECK, null, -1], - ['user1', IShare::TYPE_SCIENCEMESH, null, -1], - )->willReturnOnConsecutiveCalls( - $userShares, - $groupShares, - $circleShares, - $roomShares, - $deckShares, - $sciencemeshShares - ); + ->willReturnMap([ + ['user1', IShare::TYPE_USER, null, -1, 0, $userShares], + ['user1', IShare::TYPE_GROUP, null, -1, 0, $groupShares], + ['user1', IShare::TYPE_CIRCLE, null, -1, 0, $circleShares], + ['user1', IShare::TYPE_ROOM, null, -1, 0, $roomShares], + ['user1', IShare::TYPE_DECK, null, -1, 0, $deckShares], + ['user1', IShare::TYPE_SCIENCEMESH, null, -1, 0, $scienceMeshShares], + ]); + $this->shareManager->expects($this->any()) ->method('newShare') ->willReturnCallback(function () use ($rootFolder, $userManager) { @@ -407,6 +389,7 @@ class MountProviderTest extends \Test\TestCase { $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mount); // supershare + /** @var OCA\Files_Sharing\SharedMount $mount */ $share = $mount->getShare(); $this->assertEquals($expectedShare[0], $share->getId()); 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/fi.js b/apps/files_trashbin/l10n/fi.js index 20ad0ecdcfb..2ce9a4f2c18 100644 --- a/apps/files_trashbin/l10n/fi.js +++ b/apps/files_trashbin/l10n/fi.js @@ -4,6 +4,7 @@ OC.L10N.register( "restored" : "palautettu", "Deleted files" : "Poistetut tiedostot", "Restore" : "Palauta", + "Not enough free space to restore the file/folder" : "Tiedoston/kansion palauttamiseksi ei ole riittävästi vapaata tilaa", "Empty deleted files" : "Tyhjennä poistetut tiedostot", "Confirm permanent deletion" : "Vahvista lopullinen poistaminen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Haluatko varmasti poistaa pysyvästi kaikki roskakorissa olevat tiedostot ja kansiot? Tätä ei voi perua.", diff --git a/apps/files_trashbin/l10n/fi.json b/apps/files_trashbin/l10n/fi.json index cea7d0c42e1..9d2b9fd3a37 100644 --- a/apps/files_trashbin/l10n/fi.json +++ b/apps/files_trashbin/l10n/fi.json @@ -2,6 +2,7 @@ "restored" : "palautettu", "Deleted files" : "Poistetut tiedostot", "Restore" : "Palauta", + "Not enough free space to restore the file/folder" : "Tiedoston/kansion palauttamiseksi ei ole riittävästi vapaata tilaa", "Empty deleted files" : "Tyhjennä poistetut tiedostot", "Confirm permanent deletion" : "Vahvista lopullinen poistaminen", "Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone." : "Haluatko varmasti poistaa pysyvästi kaikki roskakorissa olevat tiedostot ja kansiot? Tätä ei voi perua.", 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/lib/Sabre/TrashbinPlugin.php b/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php index 2a2e3a141dc..e9213882804 100644 --- a/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php +++ b/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php @@ -8,9 +8,12 @@ declare(strict_types=1); */ namespace OCA\Files_Trashbin\Sabre; +use OC\Files\FileInfo; +use OC\Files\View; use OCA\DAV\Connector\Sabre\FilesPlugin; use OCA\Files_Trashbin\Trash\ITrashItem; use OCP\IPreview; +use Psr\Log\LoggerInterface; use Sabre\DAV\INode; use Sabre\DAV\PropFind; use Sabre\DAV\Server; @@ -32,6 +35,7 @@ class TrashbinPlugin extends ServerPlugin { public function __construct( private IPreview $previewManager, + private View $view, ) { } @@ -40,6 +44,7 @@ class TrashbinPlugin extends ServerPlugin { $this->server->on('propFind', [$this, 'propFind']); $this->server->on('afterMethod:GET', [$this,'httpGet']); + $this->server->on('beforeMove', [$this, 'beforeMove']); } @@ -129,4 +134,47 @@ class TrashbinPlugin extends ServerPlugin { $response->addHeader('Content-Disposition', 'attachment; filename="' . $node->getFilename() . '"'); } } + + /** + * Check if a user has available space before attempting to + * restore from trashbin unless they have unlimited quota. + * + * @param string $sourcePath + * @param string $destinationPath + * @return bool + */ + public function beforeMove(string $sourcePath, string $destinationPath): bool { + try { + $node = $this->server->tree->getNodeForPath($sourcePath); + $destinationNodeParent = $this->server->tree->getNodeForPath(dirname($destinationPath)); + } catch (\Sabre\DAV\Exception $e) { + \OCP\Server::get(LoggerInterface::class) + ->error($e->getMessage(), ['app' => 'files_trashbin', 'exception' => $e]); + return true; + } + + // Check if a file is being restored before proceeding + if (!$node instanceof ITrash || !$destinationNodeParent instanceof RestoreFolder) { + return true; + } + + $fileInfo = $node->getFileInfo(); + if (!$fileInfo instanceof ITrashItem) { + return true; + } + $restoreFolder = dirname($fileInfo->getOriginalLocation()); + $freeSpace = $this->view->free_space($restoreFolder); + if ($freeSpace === FileInfo::SPACE_NOT_COMPUTED || + $freeSpace === FileInfo::SPACE_UNKNOWN || + $freeSpace === FileInfo::SPACE_UNLIMITED) { + return true; + } + $filesize = $fileInfo->getSize(); + if ($freeSpace < $filesize) { + $this->server->httpResponse->setStatus(507); + return false; + } + + return true; + } } diff --git a/apps/files_trashbin/src/files_actions/restoreAction.ts b/apps/files_trashbin/src/files_actions/restoreAction.ts index 9af0a13a2b0..3aeeceea7b3 100644 --- a/apps/files_trashbin/src/files_actions/restoreAction.ts +++ b/apps/files_trashbin/src/files_actions/restoreAction.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ import { getCurrentUser } from '@nextcloud/auth' +import { showError } from '@nextcloud/dialogs' import { emit } from '@nextcloud/event-bus' import { Permission, Node, View, FileAction } from '@nextcloud/files' import { t } from '@nextcloud/l10n' @@ -52,6 +53,9 @@ export const restoreAction = new FileAction({ emit('files:node:deleted', node) return true } catch (error) { + if (error.response?.status === 507) { + showError(t('files_trashbin', 'Not enough free space to restore the file/folder')) + } logger.error('Failed to restore node', { error, node }) return false } 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 new file mode 100644 index 00000000000..6c566afc738 --- /dev/null +++ b/apps/files_trashbin/tests/Sabre/TrashbinPluginTest.php @@ -0,0 +1,72 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Files_Trashbin\Tests\Sabre; + +use OC\Files\FileInfo; +use OC\Files\View; +use OCA\Files_Trashbin\Sabre\ITrash; +use OCA\Files_Trashbin\Sabre\RestoreFolder; +use OCA\Files_Trashbin\Sabre\TrashbinPlugin; +use OCA\Files_Trashbin\Trash\ITrashItem; +use OCP\IPreview; +use Sabre\DAV\Server; +use Sabre\DAV\Tree; +use Test\TestCase; + +class TrashbinPluginTest extends TestCase { + private Server $server; + + protected function setUp(): void { + parent::setUp(); + + $tree = $this->createMock(Tree::class); + $this->server = new Server($tree); + } + + /** + * @dataProvider quotaProvider + */ + public function testQuota(int $quota, int $fileSize, bool $expectedResult): void { + $fileInfo = $this->createMock(ITrashItem::class); + $fileInfo->method('getSize') + ->willReturn($fileSize); + + $trashNode = $this->createMock(ITrash::class); + $trashNode->method('getFileInfo') + ->willReturn($fileInfo); + + $restoreNode = $this->createMock(RestoreFolder::class); + + $this->server->tree->method('getNodeForPath') + ->willReturn($trashNode, $restoreNode); + + $previewManager = $this->createMock(IPreview::class); + + $view = $this->createMock(View::class); + $view->method('free_space') + ->willReturn($quota); + + $plugin = new TrashbinPlugin($previewManager, $view); + $plugin->initialize($this->server); + + $sourcePath = 'trashbin/test/trash/file1'; + $destinationPath = 'trashbin/test/restore/file1'; + $this->assertEquals($expectedResult, $plugin->beforeMove($sourcePath, $destinationPath)); + } + + public static function quotaProvider(): array { + return [ + [ 1024, 512, true ], + [ 512, 513, false ], + [ FileInfo::SPACE_NOT_COMPUTED, 1024, true ], + [ FileInfo::SPACE_UNKNOWN, 1024, true ], + [ FileInfo::SPACE_UNLIMITED, 1024, true ] + ]; + } +} 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/provisioning_api/openapi-administration.json b/apps/provisioning_api/openapi-administration.json index 3c54be68194..84b1a12d2dd 100644 --- a/apps/provisioning_api/openapi-administration.json +++ b/apps/provisioning_api/openapi-administration.json @@ -381,7 +381,8 @@ "description": "Filter for enabled or disabled apps", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { @@ -1003,7 +1004,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { diff --git a/apps/provisioning_api/openapi-full.json b/apps/provisioning_api/openapi-full.json index 9079404c35c..734c588be6b 100644 --- a/apps/provisioning_api/openapi-full.json +++ b/apps/provisioning_api/openapi-full.json @@ -428,7 +428,8 @@ "description": "Filter for enabled or disabled apps", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { @@ -885,7 +886,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -1230,7 +1232,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -2189,7 +2192,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -2438,7 +2442,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -2554,7 +2559,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -2695,6 +2701,7 @@ "manager": { "type": "string", "nullable": true, + "default": null, "description": "Manager of the user" } } @@ -2816,7 +2823,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -2932,7 +2940,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { diff --git a/apps/provisioning_api/openapi.json b/apps/provisioning_api/openapi.json index 59f31a2c25d..d2fd2378488 100644 --- a/apps/provisioning_api/openapi.json +++ b/apps/provisioning_api/openapi.json @@ -437,7 +437,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -538,7 +539,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -787,7 +789,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -986,7 +989,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -1127,6 +1131,7 @@ "manager": { "type": "string", "nullable": true, + "default": null, "description": "Manager of the user" } } @@ -1248,7 +1253,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -1364,7 +1370,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { 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 23f07351faa..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" : "تعذر تحديث تهيئة التشفير من جانب الخادم", @@ -583,12 +584,9 @@ 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 remove group \"{group}\"" : "تعذّر حذف المجموعة \"{group}\"", "Please confirm the group removal" : "رجاءً، قم بتأكيد حذف المجموعة", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "أنت على وشك إزالة المجموعة \"{group}\". لن يتم حذف الحسابات.", "Submit" : "إرسال ", "Rename group" : "تغيير تسمية مجموعة", - "Remove group" : "حذف مجموعة", "Current password" : "كلمة المرور الحالية", "New password" : "كلمة المرور الجديدة", "Change password" : "تغيير كلمة المرور", diff --git a/apps/settings/l10n/ar.json b/apps/settings/l10n/ar.json index 24b097daa9e..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" : "تعذر تحديث تهيئة التشفير من جانب الخادم", @@ -581,12 +582,9 @@ "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 remove group \"{group}\"" : "تعذّر حذف المجموعة \"{group}\"", "Please confirm the group removal" : "رجاءً، قم بتأكيد حذف المجموعة", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "أنت على وشك إزالة المجموعة \"{group}\". لن يتم حذف الحسابات.", "Submit" : "إرسال ", "Rename group" : "تغيير تسمية مجموعة", - "Remove group" : "حذف مجموعة", "Current password" : "كلمة المرور الحالية", "New password" : "كلمة المرور الجديدة", "Change password" : "تغيير كلمة المرور", diff --git a/apps/settings/l10n/ast.js b/apps/settings/l10n/ast.js index 69ff6506628..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", @@ -324,11 +325,9 @@ OC.L10N.register( "No encryption module loaded, please enable an encryption module in the app menu." : "Nun se cargó nengún módulu de cifráu, activa unu nel menú d'aplicaciones.", "Enable encryption" : "Activar el cifráu", "Please read carefully before activating server-side encryption:" : "Llei con procuru enantes d'activar el cifráu nel sirvidor:", - "Failed to remove group \"{group}\"" : "Nun se pue quitar el grupu «{group}»", "Please confirm the group removal" : "Confirma'l desaniciu del grupu", "Submit" : "Unviar", "Rename group" : "Renomar el grupu", - "Remove group" : "Quitar el grupu", "Current password" : "Contraseña actual", "New password" : "Contraseña nueva", "Change password" : "Camudar la contraseña", diff --git a/apps/settings/l10n/ast.json b/apps/settings/l10n/ast.json index ac5e96fd046..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", @@ -322,11 +323,9 @@ "No encryption module loaded, please enable an encryption module in the app menu." : "Nun se cargó nengún módulu de cifráu, activa unu nel menú d'aplicaciones.", "Enable encryption" : "Activar el cifráu", "Please read carefully before activating server-side encryption:" : "Llei con procuru enantes d'activar el cifráu nel sirvidor:", - "Failed to remove group \"{group}\"" : "Nun se pue quitar el grupu «{group}»", "Please confirm the group removal" : "Confirma'l desaniciu del grupu", "Submit" : "Unviar", "Rename group" : "Renomar el grupu", - "Remove group" : "Quitar el grupu", "Current password" : "Contraseña actual", "New password" : "Contraseña nueva", "Change password" : "Camudar la contraseña", diff --git a/apps/settings/l10n/bg.js b/apps/settings/l10n/bg.js index 696fc33984a..43bd5f090f4 100644 --- a/apps/settings/l10n/bg.js +++ b/apps/settings/l10n/bg.js @@ -256,7 +256,6 @@ OC.L10N.register( "This is the final warning: Do you really want to enable encryption?" : "Това е последно предупреждение: Наистина ли искате да активирате криптирането?", "Submit" : "Изпращане", "Rename group" : "Преименуване на група", - "Remove group" : "Премахване на групата", "Current password" : "Текуща парола", "New password" : "Нова парола", "Change password" : "Промени паролата", diff --git a/apps/settings/l10n/bg.json b/apps/settings/l10n/bg.json index 80e8a66a7e0..666f4c93972 100644 --- a/apps/settings/l10n/bg.json +++ b/apps/settings/l10n/bg.json @@ -254,7 +254,6 @@ "This is the final warning: Do you really want to enable encryption?" : "Това е последно предупреждение: Наистина ли искате да активирате криптирането?", "Submit" : "Изпращане", "Rename group" : "Преименуване на група", - "Remove group" : "Премахване на групата", "Current password" : "Текуща парола", "New password" : "Нова парола", "Change password" : "Промени паролата", diff --git a/apps/settings/l10n/br.js b/apps/settings/l10n/br.js index ea3a5d8a334..8c0dcdcc6a1 100644 --- a/apps/settings/l10n/br.js +++ b/apps/settings/l10n/br.js @@ -197,7 +197,6 @@ 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." : "Mat eo kaout ur vackup reoliek eus o roadennoù, ha e bezit sur ober ur vackup eus an alrv'hwez sifrañ gant o roadennoù sifret.", "This is the final warning: Do you really want to enable encryption?" : "Kemenadenn diwall divezhañ : Sur oc'h aotreañ ar sifrañ ?", "Submit" : "Kinnig", - "Remove group" : "Lemel strollad", "Current password" : "Ger-tremen hiziv", "New password" : "Ger-tremen nevez", "Change password" : "Cheñch ger-tremen", diff --git a/apps/settings/l10n/br.json b/apps/settings/l10n/br.json index 388ad7ebee4..ec6a68e42fc 100644 --- a/apps/settings/l10n/br.json +++ b/apps/settings/l10n/br.json @@ -195,7 +195,6 @@ "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." : "Mat eo kaout ur vackup reoliek eus o roadennoù, ha e bezit sur ober ur vackup eus an alrv'hwez sifrañ gant o roadennoù sifret.", "This is the final warning: Do you really want to enable encryption?" : "Kemenadenn diwall divezhañ : Sur oc'h aotreañ ar sifrañ ?", "Submit" : "Kinnig", - "Remove group" : "Lemel strollad", "Current password" : "Ger-tremen hiziv", "New password" : "Ger-tremen nevez", "Change password" : "Cheñch ger-tremen", diff --git a/apps/settings/l10n/ca.js b/apps/settings/l10n/ca.js index 34fec6323fc..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", @@ -578,12 +579,9 @@ 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 és bó crear còpies de seguretat de les vostres dades amb regularitat, en el cas de xifratge assegureu-vos de desar les claus de xifratge juntament amb les vostres dades a la còpia de seguretat.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulteu la documentació d'administració sobre com xifrar també manualment els fitxers existents.", "This is the final warning: Do you really want to enable encryption?" : "Avís final: Realment voleu activar xifratge?", - "Failed to remove group \"{group}\"" : "No s'ha pogut suprimir el grup \"{group}\"", "Please confirm the group removal" : "Confirmeu l'eliminació del grup", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Esteu a punt d'eliminar el grup \"{group}\". Els comptes NO es suprimiràn.", "Submit" : "Envia", "Rename group" : "Canvia el nom del grup", - "Remove group" : "Suprimir el grup", "Current password" : "Contrasenya actual", "New password" : "Contrasenya nova", "Change password" : "Canvia la contrasenya", diff --git a/apps/settings/l10n/ca.json b/apps/settings/l10n/ca.json index fa46f702b59..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", @@ -576,12 +577,9 @@ "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 és bó crear còpies de seguretat de les vostres dades amb regularitat, en el cas de xifratge assegureu-vos de desar les claus de xifratge juntament amb les vostres dades a la còpia de seguretat.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulteu la documentació d'administració sobre com xifrar també manualment els fitxers existents.", "This is the final warning: Do you really want to enable encryption?" : "Avís final: Realment voleu activar xifratge?", - "Failed to remove group \"{group}\"" : "No s'ha pogut suprimir el grup \"{group}\"", "Please confirm the group removal" : "Confirmeu l'eliminació del grup", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Esteu a punt d'eliminar el grup \"{group}\". Els comptes NO es suprimiràn.", "Submit" : "Envia", "Rename group" : "Canvia el nom del grup", - "Remove group" : "Suprimir el grup", "Current password" : "Contrasenya actual", "New password" : "Contrasenya nova", "Change password" : "Canvia la contrasenya", diff --git a/apps/settings/l10n/cs.js b/apps/settings/l10n/cs.js index a994be35518..a39adab6030 100644 --- a/apps/settings/l10n/cs.js +++ b/apps/settings/l10n/cs.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Architektura", "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.", @@ -561,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", @@ -583,12 +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 remove group \"{group}\"" : "Nepodařilo se odebrat skupinu „{group}“", + "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 remove the group \"{group}\". The accounts will NOT be deleted." : "Chystáte se smazat skupinu „{group}“. Účty NEbudou smazány.", + "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", - "Remove group" : "Odebrat 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 30f1aa72f22..7f9ab60d49f 100644 --- a/apps/settings/l10n/cs.json +++ b/apps/settings/l10n/cs.json @@ -313,6 +313,10 @@ "Architecture" : "Architektura", "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.", @@ -559,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", @@ -581,12 +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 remove group \"{group}\"" : "Nepodařilo se odebrat skupinu „{group}“", + "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 remove the group \"{group}\". The accounts will NOT be deleted." : "Chystáte se smazat skupinu „{group}“. Účty NEbudou smazány.", + "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", - "Remove group" : "Odebrat 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 fbedba31feb..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", @@ -583,12 +584,9 @@ 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." : "Det er altid godt at lave regelmæssige sikkerhedskopier af dine data, i tilfælde af kryptering skal du sørge for at tage backup af krypteringsnøglerne sammen med dine data.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Se administratordokumentationen om, hvordan man manuelt også krypterer eksisterende filer.", "This is the final warning: Do you really want to enable encryption?" : "Dette er den sidste advarsel: Sikker på at du vil slå kryptering til?", - "Failed to remove group \"{group}\"" : "Kunne ikke slette gruppen \"{group}\"", "Please confirm the group removal" : "Bekræft venligst sletning af gruppen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du er ved at fjerne gruppen \"{group}\". Konti indeholdt i gruppen vil IKKE blive slettet.", "Submit" : "Tilføj", "Rename group" : "Omdøb gruppe", - "Remove group" : "Fjern gruppe", "Current password" : "Nuværende adgangskode", "New password" : "Ny adgangskode", "Change password" : "Skift kodeord", diff --git a/apps/settings/l10n/da.json b/apps/settings/l10n/da.json index bf06d9740e2..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", @@ -581,12 +582,9 @@ "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." : "Det er altid godt at lave regelmæssige sikkerhedskopier af dine data, i tilfælde af kryptering skal du sørge for at tage backup af krypteringsnøglerne sammen med dine data.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Se administratordokumentationen om, hvordan man manuelt også krypterer eksisterende filer.", "This is the final warning: Do you really want to enable encryption?" : "Dette er den sidste advarsel: Sikker på at du vil slå kryptering til?", - "Failed to remove group \"{group}\"" : "Kunne ikke slette gruppen \"{group}\"", "Please confirm the group removal" : "Bekræft venligst sletning af gruppen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du er ved at fjerne gruppen \"{group}\". Konti indeholdt i gruppen vil IKKE blive slettet.", "Submit" : "Tilføj", "Rename group" : "Omdøb gruppe", - "Remove group" : "Fjern gruppe", "Current password" : "Nuværende adgangskode", "New password" : "Ny adgangskode", "Change password" : "Skift kodeord", diff --git a/apps/settings/l10n/de.js b/apps/settings/l10n/de.js index 3aaa96dc03f..91e260f30d2 100644 --- a/apps/settings/l10n/de.js +++ b/apps/settings/l10n/de.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Architektur", "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!" : "Anscheinend wird eine 32-Bit-PHP-Version verwendet. Nextcloud benötigt 64-Bit, um gut zu laufen. Bitte Betriebssystem und PHP auf 64-Bit aktualisieren!", + "Task Processing pickup speed" : "Abholgeschwindigkeit für Aufgabenverarbeitung", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Keine geplanten Aufgaben in der letzten %n Stunde.","Keine geplanten Aufgaben in den letzten %n Stunden."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Die Geschwindigkeit der Aufgabenübernahme war in der letzten %n Stunde in Ordnung.","Die Geschwindigkeit der Aufgabenübernahme war in den letzten %n Stunden in Ordnung."], + "_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._" : ["Die Aufgabenabholgeschwindigkeit war in der letzten %n Stunde langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwäge die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet.","Die Aufgabenabholgeschwindigkeit war in den letzten %n Stunden langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet."], "Temporary space available" : "Temporärer Platz verfügbar", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fehler beim Überprüfen des temporären PHP-Pfads - er wurde nicht ordnungsgemäß auf ein Verzeichnis festgelegt. Zurückgegebener Wert: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Die PHP-Funktion \"disk_free_space\" ist deaktiviert, was die Überprüfung auf ausreichend Speicherplatz in den temporären Verzeichnissen verhindert.", @@ -561,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.", @@ -583,12 +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." : "Es ist immer gut, regelmäßig Datensicherungen zu erstellen. Sofern die Verschlüsselung genutzt wird, sollte auch eine Sicherung der Verschlüsselungsschlüssel zusammen mit den Daten durchgeführt werden.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informationen zum manuellen Verschlüsseln vorhandener Dateien finden sich in der Administrationsdokumentation.", "This is the final warning: Do you really want to enable encryption?" : "Dies ist die letzte Warnung: Soll die Verschlüsselung wirklich aktiviert werden?", - "Failed to remove group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht entfernt werden.", + "Failed to delete group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht gelöscht werden", "Please confirm the group removal" : "Bitte die Löschung der Gruppe bestätigen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du bist im Begriff, die Gruppe \"{group}\" zu entfernen. Die Konten werden NICHT gelöscht.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Du bist im Begriff, die Gruppe \"{group}\" zu löschen. Die Konten werden NICHT gelöscht.", "Submit" : "Übermitteln", "Rename group" : "Gruppe umbenennen", - "Remove group" : "Gruppe entfernen", + "Delete group" : "Gruppe löschen", "Current password" : "Aktuelles Passwort", "New password" : "Neues Passwort", "Change password" : "Passwort ändern", diff --git a/apps/settings/l10n/de.json b/apps/settings/l10n/de.json index 75a892b4f8d..b16e4a100ca 100644 --- a/apps/settings/l10n/de.json +++ b/apps/settings/l10n/de.json @@ -313,6 +313,10 @@ "Architecture" : "Architektur", "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!" : "Anscheinend wird eine 32-Bit-PHP-Version verwendet. Nextcloud benötigt 64-Bit, um gut zu laufen. Bitte Betriebssystem und PHP auf 64-Bit aktualisieren!", + "Task Processing pickup speed" : "Abholgeschwindigkeit für Aufgabenverarbeitung", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Keine geplanten Aufgaben in der letzten %n Stunde.","Keine geplanten Aufgaben in den letzten %n Stunden."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Die Geschwindigkeit der Aufgabenübernahme war in der letzten %n Stunde in Ordnung.","Die Geschwindigkeit der Aufgabenübernahme war in den letzten %n Stunden in Ordnung."], + "_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._" : ["Die Aufgabenabholgeschwindigkeit war in der letzten %n Stunde langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwäge die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet.","Die Aufgabenabholgeschwindigkeit war in den letzten %n Stunden langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet."], "Temporary space available" : "Temporärer Platz verfügbar", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fehler beim Überprüfen des temporären PHP-Pfads - er wurde nicht ordnungsgemäß auf ein Verzeichnis festgelegt. Zurückgegebener Wert: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Die PHP-Funktion \"disk_free_space\" ist deaktiviert, was die Überprüfung auf ausreichend Speicherplatz in den temporären Verzeichnissen verhindert.", @@ -559,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.", @@ -581,12 +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." : "Es ist immer gut, regelmäßig Datensicherungen zu erstellen. Sofern die Verschlüsselung genutzt wird, sollte auch eine Sicherung der Verschlüsselungsschlüssel zusammen mit den Daten durchgeführt werden.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informationen zum manuellen Verschlüsseln vorhandener Dateien finden sich in der Administrationsdokumentation.", "This is the final warning: Do you really want to enable encryption?" : "Dies ist die letzte Warnung: Soll die Verschlüsselung wirklich aktiviert werden?", - "Failed to remove group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht entfernt werden.", + "Failed to delete group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht gelöscht werden", "Please confirm the group removal" : "Bitte die Löschung der Gruppe bestätigen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du bist im Begriff, die Gruppe \"{group}\" zu entfernen. Die Konten werden NICHT gelöscht.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Du bist im Begriff, die Gruppe \"{group}\" zu löschen. Die Konten werden NICHT gelöscht.", "Submit" : "Übermitteln", "Rename group" : "Gruppe umbenennen", - "Remove group" : "Gruppe entfernen", + "Delete group" : "Gruppe löschen", "Current password" : "Aktuelles Passwort", "New password" : "Neues Passwort", "Change password" : "Passwort ändern", diff --git a/apps/settings/l10n/de_DE.js b/apps/settings/l10n/de_DE.js index 34bd495da1d..70a2c10b712 100644 --- a/apps/settings/l10n/de_DE.js +++ b/apps/settings/l10n/de_DE.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Architektur", "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!" : "Anscheinend verwenden Sie eine 32-Bit-PHP-Version. Nextcloud benötigt 64-Bit, um gut zu laufen. Bitte aktualisieren Sie Ihr Betriebssystem und PHP auf 64-Bit!", + "Task Processing pickup speed" : "Abholgeschwindigkeit für Aufgabenverarbeitung", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Keine geplanten Aufgaben in der letzten %n Stunde.","Keine geplanten Aufgaben in den letzten %n Stunden."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Die Geschwindigkeit der Aufgabenübernahme war in der letzten %n Stunde in Ordnung.","Die Geschwindigkeit der Aufgabenübernahme war in den letzten %n Stunden in Ordnung."], + "_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._" : ["Die Aufgabenabholgeschwindigkeit war in der letzten %n Stunde langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet.","Die Aufgabenabholgeschwindigkeit war in den letzten %n Stunden langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet."], "Temporary space available" : "Temporärer Platz verfügbar", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fehler beim Überprüfen des temporären PHP-Pfads - er wurde nicht ordnungsgemäß auf ein Verzeichnis festgelegt. Zurückgegebener Wert: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Die PHP-Funktion \"disk_free_space\" ist deaktiviert, was die Überprüfung auf ausreichend Speicherplatz in den temporären Verzeichnissen verhindert.", @@ -561,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", @@ -583,12 +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." : "Es ist immer gut, regelmäßig Sicherungskopien von ihren Daten zu machen. Falls Sie die Verschlüsselung nutzen, sollten Sie auch eine Sicherung der Verschlüsselungsschlüssel zusammen mit Ihren Daten machen.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informationen zum manuellen Verschlüsseln vorhandener Dateien finden Sie in der Administrationsdokumentation.", "This is the final warning: Do you really want to enable encryption?" : "Dies ist die letzte Warnung: Möchten Sie die Verschlüsselung wirklich aktivieren?", - "Failed to remove group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht entfernt werden.", + "Failed to delete group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht gelöscht werden", "Please confirm the group removal" : "Bitte die Löschung der Gruppe bestätigen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Sie sind im Begriff, die Gruppe \"{group}\" zu entfernen. Die Konten werden NICHT gelöscht.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Sie sind im Begriff, die Gruppe \"{group}\" zu löschen. Die Konten werden NICHT gelöscht.", "Submit" : "Übermitteln", "Rename group" : "Gruppe umbenennen", - "Remove group" : "Gruppe entfernen", + "Delete group" : "Gruppe löschen", "Current password" : "Aktuelles Passwort", "New password" : "Neues Passwort", "Change password" : "Passwort ändern", diff --git a/apps/settings/l10n/de_DE.json b/apps/settings/l10n/de_DE.json index 1557cdc2153..3f18effb1af 100644 --- a/apps/settings/l10n/de_DE.json +++ b/apps/settings/l10n/de_DE.json @@ -313,6 +313,10 @@ "Architecture" : "Architektur", "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!" : "Anscheinend verwenden Sie eine 32-Bit-PHP-Version. Nextcloud benötigt 64-Bit, um gut zu laufen. Bitte aktualisieren Sie Ihr Betriebssystem und PHP auf 64-Bit!", + "Task Processing pickup speed" : "Abholgeschwindigkeit für Aufgabenverarbeitung", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Keine geplanten Aufgaben in der letzten %n Stunde.","Keine geplanten Aufgaben in den letzten %n Stunden."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Die Geschwindigkeit der Aufgabenübernahme war in der letzten %n Stunde in Ordnung.","Die Geschwindigkeit der Aufgabenübernahme war in den letzten %n Stunden in Ordnung."], + "_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._" : ["Die Aufgabenabholgeschwindigkeit war in der letzten %n Stunde langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet.","Die Aufgabenabholgeschwindigkeit war in den letzten %n Stunden langsam. Viele Aufgaben benötigten länger als 4 Minuten, um abgeholt zu werden. Erwägen Sie die Einrichtung eines Workers, der Aufgaben im Hintergrund verarbeitet."], "Temporary space available" : "Temporärer Platz verfügbar", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fehler beim Überprüfen des temporären PHP-Pfads - er wurde nicht ordnungsgemäß auf ein Verzeichnis festgelegt. Zurückgegebener Wert: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Die PHP-Funktion \"disk_free_space\" ist deaktiviert, was die Überprüfung auf ausreichend Speicherplatz in den temporären Verzeichnissen verhindert.", @@ -559,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", @@ -581,12 +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." : "Es ist immer gut, regelmäßig Sicherungskopien von ihren Daten zu machen. Falls Sie die Verschlüsselung nutzen, sollten Sie auch eine Sicherung der Verschlüsselungsschlüssel zusammen mit Ihren Daten machen.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informationen zum manuellen Verschlüsseln vorhandener Dateien finden Sie in der Administrationsdokumentation.", "This is the final warning: Do you really want to enable encryption?" : "Dies ist die letzte Warnung: Möchten Sie die Verschlüsselung wirklich aktivieren?", - "Failed to remove group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht entfernt werden.", + "Failed to delete group \"{group}\"" : "Die Gruppe \"{group}\" konnte nicht gelöscht werden", "Please confirm the group removal" : "Bitte die Löschung der Gruppe bestätigen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Sie sind im Begriff, die Gruppe \"{group}\" zu entfernen. Die Konten werden NICHT gelöscht.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Sie sind im Begriff, die Gruppe \"{group}\" zu löschen. Die Konten werden NICHT gelöscht.", "Submit" : "Übermitteln", "Rename group" : "Gruppe umbenennen", - "Remove group" : "Gruppe entfernen", + "Delete group" : "Gruppe löschen", "Current password" : "Aktuelles Passwort", "New password" : "Neues Passwort", "Change password" : "Passwort ändern", diff --git a/apps/settings/l10n/el.js b/apps/settings/l10n/el.js index a550312f55c..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" : "Δεν είναι δυνατή η ενημέρωση της διαμόρφωσης κρυπτογράφησης από τον διακομιστή", @@ -577,12 +578,9 @@ 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 remove group \"{group}\"" : "Αποτυχία κατά την αφαίρεση της ομάδας \"{group}\"", "Please confirm the group removal" : "Παρακαλώ επιβεβαιώστε την αφαίρεση της ομάδας", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Πρόκειται να αφαιρέσετε την ομάδα \"{group}\". Οι λογαριασμοί ΔΕΝ θα διαγραφούν.", "Submit" : "Υποβολή", "Rename group" : "Μετονομασία ομάδας", - "Remove group" : "Αφαίρεση ομάδας", "Current password" : "Τρέχον συνθηματικό", "New password" : "Νέο συνθηματικό", "Change password" : "Αλλαγή συνθηματικού", diff --git a/apps/settings/l10n/el.json b/apps/settings/l10n/el.json index 5f15c424659..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" : "Δεν είναι δυνατή η ενημέρωση της διαμόρφωσης κρυπτογράφησης από τον διακομιστή", @@ -575,12 +576,9 @@ "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 remove group \"{group}\"" : "Αποτυχία κατά την αφαίρεση της ομάδας \"{group}\"", "Please confirm the group removal" : "Παρακαλώ επιβεβαιώστε την αφαίρεση της ομάδας", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Πρόκειται να αφαιρέσετε την ομάδα \"{group}\". Οι λογαριασμοί ΔΕΝ θα διαγραφούν.", "Submit" : "Υποβολή", "Rename group" : "Μετονομασία ομάδας", - "Remove group" : "Αφαίρεση ομάδας", "Current password" : "Τρέχον συνθηματικό", "New password" : "Νέο συνθηματικό", "Change password" : "Αλλαγή συνθηματικού", diff --git a/apps/settings/l10n/en_GB.js b/apps/settings/l10n/en_GB.js index 24bcb65f04c..6d127073390 100644 --- a/apps/settings/l10n/en_GB.js +++ b/apps/settings/l10n/en_GB.js @@ -315,6 +315,10 @@ OC.L10N.register( "Architecture" : "Architecture", "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!" : "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!", + "Task Processing pickup speed" : "Task Processing pickup speed", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["No scheduled tasks in the last %n hour.","No scheduled tasks in the last %n hours."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["The task pickup speed has been ok in the last %n hour.","The task pickup speed has been ok in the last %n hours."], + "_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._" : ["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."], "Temporary space available" : "Temporary space available", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "The PHP function \"disk_free_space\" is disabled, preventing the system from checking for sufficient space in the temporary directories.", @@ -561,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", @@ -583,12 +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." : "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." : "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?" : "This is the final warning: Do you really want to enable encryption?", - "Failed to remove group \"{group}\"" : "Failed to remove group \"{group}\"", + "Failed to delete group \"{group}\"" : "Failed to delete group \"{group}\"", "Please confirm the group removal" : "Please confirm the group removal", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "You are about to remove the group \"{group}\". The accounts will NOT be deleted.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "You are about to delete the group \"{group}\". The accounts will NOT be deleted.", "Submit" : "Submit", "Rename group" : "Rename group", - "Remove group" : "Remove group", + "Delete group" : "Delete group", "Current password" : "Current password", "New password" : "New password", "Change password" : "Change password", diff --git a/apps/settings/l10n/en_GB.json b/apps/settings/l10n/en_GB.json index e5b031cc8e8..43c5bd06674 100644 --- a/apps/settings/l10n/en_GB.json +++ b/apps/settings/l10n/en_GB.json @@ -313,6 +313,10 @@ "Architecture" : "Architecture", "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!" : "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!", + "Task Processing pickup speed" : "Task Processing pickup speed", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["No scheduled tasks in the last %n hour.","No scheduled tasks in the last %n hours."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["The task pickup speed has been ok in the last %n hour.","The task pickup speed has been ok in the last %n hours."], + "_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._" : ["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."], "Temporary space available" : "Temporary space available", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "The PHP function \"disk_free_space\" is disabled, preventing the system from checking for sufficient space in the temporary directories.", @@ -559,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", @@ -581,12 +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." : "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." : "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?" : "This is the final warning: Do you really want to enable encryption?", - "Failed to remove group \"{group}\"" : "Failed to remove group \"{group}\"", + "Failed to delete group \"{group}\"" : "Failed to delete group \"{group}\"", "Please confirm the group removal" : "Please confirm the group removal", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "You are about to remove the group \"{group}\". The accounts will NOT be deleted.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "You are about to delete the group \"{group}\". The accounts will NOT be deleted.", "Submit" : "Submit", "Rename group" : "Rename group", - "Remove group" : "Remove group", + "Delete group" : "Delete group", "Current password" : "Current password", "New password" : "New password", "Change password" : "Change password", diff --git a/apps/settings/l10n/eo.js b/apps/settings/l10n/eo.js index c5a78ad2e22..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", @@ -196,7 +197,6 @@ 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." : "Ĉiam estas bone krei savkopiojn de viaj datumoj. Se tiuj ĉi lastaj estas ĉifritaj, certigu, ke vi savkopias ankaŭ la ĉifroŝlosilon kune kun la datumoj.", "This is the final warning: Do you really want to enable encryption?" : "Jen la fina averto: ĉu vi certe volas ŝalti ĉifradon?", "Submit" : "Sendi", - "Remove group" : "Forigi grupon", "Current password" : "Nuna pasvorto", "New password" : "Nova pasvorto", "Change password" : "Ŝanĝi la pasvorton", diff --git a/apps/settings/l10n/eo.json b/apps/settings/l10n/eo.json index a408497b551..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", @@ -194,7 +195,6 @@ "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." : "Ĉiam estas bone krei savkopiojn de viaj datumoj. Se tiuj ĉi lastaj estas ĉifritaj, certigu, ke vi savkopias ankaŭ la ĉifroŝlosilon kune kun la datumoj.", "This is the final warning: Do you really want to enable encryption?" : "Jen la fina averto: ĉu vi certe volas ŝalti ĉifradon?", "Submit" : "Sendi", - "Remove group" : "Forigi grupon", "Current password" : "Nuna pasvorto", "New password" : "Nova pasvorto", "Change password" : "Ŝanĝi la pasvorton", diff --git a/apps/settings/l10n/es.js b/apps/settings/l10n/es.js index b3b04572006..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", @@ -583,12 +584,9 @@ 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." : "Siempre es bueno crear copias de seguridad de sus datos, en el caso del cifrado, asegúrese de tener una copia de seguridad de las claves de cifrado junto con sus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulta la documentación del administrador para saber cómo cifrar manualmente también los archivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente quiere activar el cifrado?", - "Failed to remove group \"{group}\"" : "Fallo al eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor, confirme la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a punto de eliminar el grupo \"{group}\". Las cuentas NO serán eliminadas.", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", diff --git a/apps/settings/l10n/es.json b/apps/settings/l10n/es.json index 917624f223d..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", @@ -581,12 +582,9 @@ "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." : "Siempre es bueno crear copias de seguridad de sus datos, en el caso del cifrado, asegúrese de tener una copia de seguridad de las claves de cifrado junto con sus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulta la documentación del administrador para saber cómo cifrar manualmente también los archivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente quiere activar el cifrado?", - "Failed to remove group \"{group}\"" : "Fallo al eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor, confirme la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a punto de eliminar el grupo \"{group}\". Las cuentas NO serán eliminadas.", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", 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 10729f0573c..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", @@ -343,12 +344,9 @@ 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." : "Siempre es una buena idea crear copias de seguridad de tus datos, en el caso del cifrado asegurate de tener una copia de seguridad de las claves de cifrado junto con tus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consultá la documentación del administrador para saber cómo cifrar manualmente también los archivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente querés activar el cifrado?", - "Failed to remove group \"{group}\"" : "No se pudo eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor confirmá la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Vas a eliminar el grupo {group}. Los usuarios NO serán eliminados.", "Submit" : "Enviar", "Rename group" : "Cambiar nombre del grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", diff --git a/apps/settings/l10n/es_AR.json b/apps/settings/l10n/es_AR.json index fd1669c3db1..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", @@ -341,12 +342,9 @@ "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." : "Siempre es una buena idea crear copias de seguridad de tus datos, en el caso del cifrado asegurate de tener una copia de seguridad de las claves de cifrado junto con tus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consultá la documentación del administrador para saber cómo cifrar manualmente también los archivos existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente querés activar el cifrado?", - "Failed to remove group \"{group}\"" : "No se pudo eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor confirmá la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Vas a eliminar el grupo {group}. Los usuarios NO serán eliminados.", "Submit" : "Enviar", "Rename group" : "Cambiar nombre del grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", 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 f4204534e6f..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. ", @@ -258,7 +259,6 @@ OC.L10N.register( "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final: ¿Realmente deseas habilitar la encripción?", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", diff --git a/apps/settings/l10n/es_EC.json b/apps/settings/l10n/es_EC.json index f14b77247dc..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. ", @@ -256,7 +257,6 @@ "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final: ¿Realmente deseas habilitar la encripción?", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", 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 245db3a5c9c..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", @@ -468,12 +469,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Por favor considera que la encripción siempre aumenta el tamaño de los archivos. ", "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." : "Siempre es una buena idea generar respaldos de tus datos, en caso de tener encripción asegúrate de respaldar las llaves de encripción junto con tus datos. ", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final: ¿Realmente deseas habilitar la encripción?", - "Failed to remove group \"{group}\"" : "No se pudo eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor, confirme la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a punto de eliminar el grupo \"{group}\". Los usuarios NO serán eliminados.", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", diff --git a/apps/settings/l10n/es_MX.json b/apps/settings/l10n/es_MX.json index 550319965b6..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", @@ -466,12 +467,9 @@ "Be aware that encryption always increases the file size." : "Por favor considera que la encripción siempre aumenta el tamaño de los archivos. ", "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." : "Siempre es una buena idea generar respaldos de tus datos, en caso de tener encripción asegúrate de respaldar las llaves de encripción junto con tus datos. ", "This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final: ¿Realmente deseas habilitar la encripción?", - "Failed to remove group \"{group}\"" : "No se pudo eliminar el grupo \"{group}\"", "Please confirm the group removal" : "Por favor, confirme la eliminación del grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a punto de eliminar el grupo \"{group}\". Los usuarios NO serán eliminados.", "Submit" : "Enviar", "Rename group" : "Renombrar grupo", - "Remove group" : "Eliminar grupo", "Current password" : "Contraseña actual", "New password" : "Nueva contraseña", "Change password" : "Cambiar contraseña", 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 4b06afedea8..e7fe29f42dd 100644 --- a/apps/settings/l10n/et_EE.js +++ b/apps/settings/l10n/et_EE.js @@ -136,9 +136,11 @@ OC.L10N.register( "No altered files" : "Muudetud faile pole", "Database missing primary keys" : "Andmebaasis on puudu primaarvõtmed", "Missing primary key on table \"%s\"." : "Puuduv primaarvõti tabelis „%s“.", + "Default phone region" : "Telefonide vaikimisi piirkond", "Email test" : "E-kirjade saatmise test", "Mail delivery is disabled by instance config \"%s\"." : "Selles serveris piirab e-kirjade edasisaatmist seadistus „%s“.", - "Email test was successfully sent" : "Test e-kirja saatmine õnnestus", + "Email test was successfully sent" : "Testkirja saatmine õnnestus", + "Your \"trusted_proxies\" setting is not correctly set, it should be an array." : "Serveri „trusted_proxies“ seadistus pole korrektne - seal peab leiduma massiiv, aga hetkel on midagi muud.", "Old server-side-encryption" : "Vana serveripoolne krüptimine", "Disabled" : "Keelatud", "The old server-side-encryption format is enabled. We recommend disabling this." : "Vana serveripoolse krüptimise vorming on kasutusel. Mes soovitame, et lülitad selle välja.", @@ -146,6 +148,7 @@ OC.L10N.register( "The %1$s configuration option must be a valid integer value." : "Seadistusvalik „%1$s“ peab olema korrektne täisarv.", "The logging level is set to debug level. Use debug level only when you have a problem to diagnose, and then reset your log level to a less-verbose level as it outputs a lot of information, and can affect your server performance." : "Logimistase on hetkel seatud veaotsinguks. Kasuta seda vaid siis, kui tõesti tegeled veaotsinguga ning peale seda muuda logimine jälle tavaliseks. Veaotsinguks vajalik logimine on väga väljundirikas ning võib mõjutada serveri jõudlust.", "Logging level configured correctly." : "Logimistase on korrektselt seadistatud", + "PHP configuration option \"default_charset\" should be UTF-8" : "PHP seadistuse „default_charset“ väärtus peab olema UTF-8", "Supported" : "Toetatud", "PHP getenv" : "PHP getenv", "PHP does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP ei tundu olevat süsteemsete keskkonnamuutujate pärimiseks korrektselt seadistatud. Test getenv(\"PATH\") abil tagastab tühja vastuse.", @@ -164,6 +167,8 @@ OC.L10N.register( "PHP version" : "PHP versioon", "You are currently running PHP %1$s. PHP %2$s is deprecated since Nextcloud %3$s. Nextcloud %4$s may require at least PHP %5$s. Please upgrade to one of the officially supported PHP versions provided by the PHP Group as soon as possible." : "Sa kasutad hetkel PHP versiooni %1$s. PHP %2$s on aga alates Nexctcloudi versioonist %3$s kasutuselt eemaldatud. Nexctcloud %4$s eeldab, et PHP versioon on vähemalt %5$s. Palun uuenda oma server PHP Groupi poolt väljaantud ametliku PHP versioonini niipea, kui võimalik.", "You are currently running PHP %s." : "Sul on hetkel kasutusel PHP versioon %s.", + "PHP \"output_buffering\" option" : "PHP eelistus „output_buffering“", + "PHP configuration option \"output_buffering\" must be disabled" : "PHP seadistus „output_buffering“ peab olema lülitatud välja", "Push service" : "Tõuketeenus", "Valid enterprise license" : "Suurfirmade litsents", "Free push service" : "Tasuta tõuketeenus", @@ -176,9 +181,14 @@ OC.L10N.register( "MariaDB version \"%1$s\" detected. MariaDB >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin MariaDB versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks MariaDB versioone >=%2$s and <= %3$s.", "MySQL version \"%1$s\" detected. MySQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin MySQLi versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks MySQLi versioone >=%2$s and <= %3$s.", "PostgreSQL version \"%1$s\" detected. PostgreSQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin PostgreSQLi versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks PostgreSQLi >=%2$s and <= %3$s.", + "Unknown database platform" : "Tuvastamatu andmebaasiplatvorm", "Architecture" : "Arhitektuur", "64-bit" : "64-bitine", "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!" : "Tundub, et kasutad PHP 32-bitist versiooni. Tõhusaks toimimiseks eeldab Nextcloud 64-bitist keskkonda. Palun uuenda oma serveri operatsioonisüsteem ja PHP 64-bitiseks versiooniks!", + "Task Processing pickup speed" : "Ülesannete töötlemise kiirus", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Viimase %n tunni jooksul pole olnud ühtegi ajastatud ülesannet.","Viimase %n tunni jooksul pole olnud ühtegi ajastatud ülesannet."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud mõistlik.","Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud mõistlik."], + "_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._" : ["Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud aeglane. Paljude ülesannete töölepanekuks kulus enam, kui 4 minutit. Palun kaalu võimalust, et ülesannete töötlemiseks seadistad taustal töötava protsessihalduri.","Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud aeglane. Paljude ülesannete töölepanekuks kulus enam, kui 4 minutit. Palun kaalu võimalust, et ülesannete töötlemiseks seadistad taustal töötava protsessihalduri."], "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funktsioon „disk_free_space“ pole kasutusel. Selle puudumine takistab ajutiste kaustade jaoks vajaliku andmeruumi kontrollimist.", "Profile information" : "Kasutajaprofiili teave", "Nextcloud settings" : "Nextcloudi seadistused", @@ -186,8 +196,12 @@ OC.L10N.register( "Enable" : "Lülita sisse", "Machine translation" : "Masintõlge", "Image generation" : "Pildiloome", + "Here you can decide which group can access certain sections of the administration settings." : "Siinkohal saad sa otsustada mis gruppidel on ligipääs valitud haldusseadistustele.", "Unable to modify setting" : "Seadistuse muutmine ei õnnestu", "None" : "Pole", + "Changed disclaimer text" : "Vastutusest lahtiütluse tekst on muutunud", + "Deleted disclaimer text" : "Vastutusest lahtiütluse tekst on kustutatud", + "Could not set disclaimer text" : "Vastutusest lahtiütluse teksti seadistamine ei õnnestunud", "Allow apps to use the Share API" : "Luba rakendustel kasutada Share API-t", "Allow resharing" : "Luba edasijagamine", "Allow sharing with groups" : "Luba gruppidega jagamine", @@ -197,6 +211,7 @@ OC.L10N.register( "Always ask for a password" : "Alati küsi parooli", "Enforce password protection" : "Jõusta paroolikaitse", "Exclude groups from password requirements" : "Välista grupid salasõnareeglitest", + "Exclude groups from creating link shares" : "Välista grupid jagamislinkide loomisest", "Limit sharing based on groups" : "Piira jagamist gruppide alusel", "Allow sharing for everyone (default)" : "Luba jagamine kõikidele (vaikimisi)", "Exclude some groups from sharing" : "Välista mõned grupid jagamisest", @@ -205,7 +220,14 @@ OC.L10N.register( "Enforce expiration date" : "Sunnitud aegumise kuupäev", "Default expiration time of new shares in days" : "Uue jaosmeedia vaikimisi aegumine päevades", "Expire shares after x days" : "Jaosmeedia aegub x päeva möödudes", + "Enforce expiration date for remote shares" : "Määra lingi kaugserverid asuva jaosmeedia vaikimisi aegumiskuupäev ", + "Default expiration time of remote shares in days" : "Kaugserveris asuva jaosmeedia vaikimisi aegumine päevades", + "Expire remote shares after x days" : "Jaosmeedia aegub x päeva möödudes", + "Set default expiration date for shares via link or mail" : "Määra lingi või e-kirjaga jagatava jaosmeedia vaikimisi aegumiskuupäev", + "Default expiration time of shares in days" : "Jaosmeedia vaikimisi aegumine päevades", "Privacy settings for sharing" : "Jagamise privaatsusseadistused", + "Show disclaimer text on the public link upload page (only shown when the file list is hidden)" : "Kuva avaliku lingiga üleslaadimise lehel lahtiütluste tekst (vaid siis, kui failide loend on peidetud)", + "Disclaimer text" : "Vastutusest lahtiütluse tekst", "This text will be shown on the public link upload page when the file list is hidden." : "Seda teksti näidatakse avaliku lingiga üleslaadimise lehel kui failide loend on peidetud.", "Two-Factor Authentication" : "Kaheastmeline autentimine", "Two-factor authentication can be enforced for all accounts and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system." : "Kaheastmelist autentimist on võimalik teha kohustuslikuks kas kõikidele kasutajakontodele või konkreetsete gruppide kaupa. Kui kaheastmelise autentimise kohustuslikkus on määratud, kuid on kasutajal seadistamata, siis ta ei saa siia serverisse sisse logida.", @@ -251,8 +273,10 @@ OC.L10N.register( "Next slide" : "Järgmine slaid", "Choose slide to display" : "Vali kuvatav slaid", "{index} of {total}" : "{index} / {total}", + "Deploy Daemon" : "Kasutuselevõtmise taustateenus", "Type" : "Tüüp", "Display Name" : "Kuvatav nimi", + "Advanced deploy options" : "Kasutuselevõtmise lisavalikud", "Edit ExApp deploy options before installation" : "Muuda ExApp konteineri seadistuse enne paigaldamist", "Configured ExApp deploy options. Can be set only during installation" : "ExApp'i konteineri seadistuse valikud. Neid saab määrata vaid paigalduse ajal", "Learn more" : "Lisateave", @@ -260,9 +284,12 @@ OC.L10N.register( "ExApp container environment variables" : "ExApp konteineri keskonnamuutujad", "No environment variables defined" : "Ühtegi keskonnamuutujat pole defineeritud", "Mounts" : "Haakepunktid", + "Must exist on the Deploy daemon host prior to installing the ExApp" : "Enne ExAppi paigaldamist peab ta olema leitav kasutuselevõtmise taustateenuses", + "Container path" : "Konteineri asukoht", "Read-only" : "Ainult lugemiseks", "Remove mount" : "Eemalda haakepunkt", "New mount" : "Uus haakepunkt", + "Enter path to host folder" : "Sisesta peremeeskausta asukoht", "Enter path to container folder" : "Sisesta konteinerikausta asukoht", "Toggle read-only mode" : "Lülita „ainult lugemiseks“ režiim sisse/välja", "Confirm adding new mount" : "Kinnita uue haakepunkti lisamine", @@ -282,6 +309,8 @@ OC.L10N.register( "Limit app usage to groups" : "Piira rakenduse kasutamist gruppidega", "No results" : "Vasteid ei leitud", "Update to {version}" : "Uuenda versioonile {version}", + "Deploy options" : "Kasutuselevõtmise valikud", + "Default Deploy daemon is not accessible" : "Kasutuselevõtmise taustateenus pole leitav", "Delete data on remove" : "Eemaldamisel kustuta andmed", "This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Sellel rakendusel pole määratud minimaalset Nextcloudi versiooni. See põhjustab tulevikus veateateid.", "This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Sellel rakendusel pole määratud maksimaalset Nextcloudi versiooni. See põhjustab tulevikus veateateid.", @@ -336,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", @@ -356,12 +386,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." : "Alati on hea mõte, kui varundad oma andmeid. Kui aga kasutusel on krüptimine, siis palun kontrolli, et lisaks andmetele on varundatud ka krüptovõtmed.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Süsteemihalduse juhendist leiad teavet kuidas saad käsitsi krüptida juba olemasolevaid faile.", "This is the final warning: Do you really want to enable encryption?" : "See on viimane hoiatus: Kas oled kindel, et soovid krüptimise sisse lülitada?", - "Failed to remove group \"{group}\"" : "„{group}“ grupi eemaldamine ei õnnestunud", + "Failed to delete group \"{group}\"" : "„{group}“ grupi eemaldamine ei õnnestunud", "Please confirm the group removal" : "Palun kinnita grupi eemaldamine", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Sa oled eemaldamas gruppi „{group}“. Selles grupis olevad kasutajad aga JÄÄVAD kustutamata.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Sa oled eemaldamas gruppi „{group}“. Selles grupis olevad kasutajad aga JÄÄVAD kustutamata.", "Submit" : "Saada", "Rename group" : "Muuda grupi nime", - "Remove group" : "Eemalda grupp", + "Delete group" : "Kustuta grupp", "Current password" : "Praegune salasõna", "New password" : "Uus salasõna", "Change password" : "Muuda salasõna", @@ -519,7 +549,10 @@ OC.L10N.register( "Defaults" : "Vaikeväärtused", "Default quota" : "Vaikimisi mahupiir", "Select default quota" : "Vali vaikimisi andmemahu piir", + "Server error while trying to complete WebAuthn device registration" : "Serveriviga WebAuthn seadme registreerimise lõpetamisel", "Passwordless authentication requires a secure connection." : "Salasõnata autentimine eeldab turvalise võrguühenduse kasutamist.", + "Add WebAuthn device" : "Lisa WebAuthni kasutav seade", + "Please authorize your WebAuthn device." : "Palun anna luba oma WebAuthn seadme kasutamiseks", "Adding your device …" : "Lisan sinu seadet…", "Unnamed device" : "Nimetu seade", "Passwordless Authentication" : "Salasõnata autentimine", @@ -569,12 +602,16 @@ OC.L10N.register( "Show to logged in accounts only" : "Näita vaid sisseloginud kasutajatele", "Hide" : "Peida", "Manually installed apps cannot be updated" : "Käsitsi paigaldatud rakendusi ei saa uuendada", + "{progress}% Deploying …" : "Võtan kasutusele {progress}%…", + "Deploy and Enable" : "Võta kasutusele ja lülita sisse", "Disable" : "Lülita välja", "Allow untested app" : "Luba testimata rakenduse kasutamine", + "The app will be downloaded from the App Store" : "See rakendus laaditakse alla App Store'ist", "Unknown" : "Teadmata", "Never" : "Mitte kunagi", "Could not register device: Network error" : "Seadme registreerimine polnud võimalik: võrguühenduse viga", "An error occurred during the request. Unable to proceed." : "Päringu ajal tekkis viga. Jätkamine pole võimalik.", + "Error: This app cannot be enabled because it makes the server unstable" : "Viga: Kuna ta muudaks selle serveri mittetöökindlaks, siis seda rakendust ei saa sisse lülitada", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Rakendus on lubatud, aga see vajab uuendamist. Sind suunatakse 5 sekundi pärast uuendamise lehele.", "Do you really want to wipe your data from this device?" : "Oled sa kindel, et soovid siit seadmest oma andmed kaugkustutada?", "Confirm wipe" : "Kinnita kaugkustutamine", @@ -603,6 +640,7 @@ OC.L10N.register( "Test and verify email settings" : "Testi ja kontrolli e-posti seadistusi", "Security & setup warnings" : "Turva- ja paigalduse hoiatused", "All checks passed." : "Kõik kontrollid on läbitud.", + "Reasons to use Nextcloud in your organization" : "Põhjused, miks peaksid Nextcloudi kasutama oma organisatsioonis", "Follow us on X" : "Järgne meile X-is", "Follow us on Mastodon" : "Järgne meile Mastodonis", "Check out our blog" : "Loe meie ajaveebi", @@ -612,6 +650,7 @@ OC.L10N.register( "The PHP memory limit is below the recommended value of %s." : "PHP mälukasutuse ülempiir on väiksem, kui soovitatav %s.", "for WebAuthn passwordless login" : "WebAuthn salasõnata sisselogimise jaoks", "for WebAuthn passwordless login, and SFTP storage" : "WebAuthn salasõnata sisselogimise ja SFTP andmeruumi jaoks", + "Set default expiration date for shares" : "Määra jaosmeedia vaikimisi aegumiskuupäev", "Your biography" : "Sinu elulugu", "You are using <strong>{usage}</strong>" : "Sa kasutad: <strong>{usage}</strong>", "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Sa kasutad: <strong>{usage}</strong> / <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)", diff --git a/apps/settings/l10n/et_EE.json b/apps/settings/l10n/et_EE.json index 02f14eb1312..a27534910f2 100644 --- a/apps/settings/l10n/et_EE.json +++ b/apps/settings/l10n/et_EE.json @@ -134,9 +134,11 @@ "No altered files" : "Muudetud faile pole", "Database missing primary keys" : "Andmebaasis on puudu primaarvõtmed", "Missing primary key on table \"%s\"." : "Puuduv primaarvõti tabelis „%s“.", + "Default phone region" : "Telefonide vaikimisi piirkond", "Email test" : "E-kirjade saatmise test", "Mail delivery is disabled by instance config \"%s\"." : "Selles serveris piirab e-kirjade edasisaatmist seadistus „%s“.", - "Email test was successfully sent" : "Test e-kirja saatmine õnnestus", + "Email test was successfully sent" : "Testkirja saatmine õnnestus", + "Your \"trusted_proxies\" setting is not correctly set, it should be an array." : "Serveri „trusted_proxies“ seadistus pole korrektne - seal peab leiduma massiiv, aga hetkel on midagi muud.", "Old server-side-encryption" : "Vana serveripoolne krüptimine", "Disabled" : "Keelatud", "The old server-side-encryption format is enabled. We recommend disabling this." : "Vana serveripoolse krüptimise vorming on kasutusel. Mes soovitame, et lülitad selle välja.", @@ -144,6 +146,7 @@ "The %1$s configuration option must be a valid integer value." : "Seadistusvalik „%1$s“ peab olema korrektne täisarv.", "The logging level is set to debug level. Use debug level only when you have a problem to diagnose, and then reset your log level to a less-verbose level as it outputs a lot of information, and can affect your server performance." : "Logimistase on hetkel seatud veaotsinguks. Kasuta seda vaid siis, kui tõesti tegeled veaotsinguga ning peale seda muuda logimine jälle tavaliseks. Veaotsinguks vajalik logimine on väga väljundirikas ning võib mõjutada serveri jõudlust.", "Logging level configured correctly." : "Logimistase on korrektselt seadistatud", + "PHP configuration option \"default_charset\" should be UTF-8" : "PHP seadistuse „default_charset“ väärtus peab olema UTF-8", "Supported" : "Toetatud", "PHP getenv" : "PHP getenv", "PHP does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP ei tundu olevat süsteemsete keskkonnamuutujate pärimiseks korrektselt seadistatud. Test getenv(\"PATH\") abil tagastab tühja vastuse.", @@ -162,6 +165,8 @@ "PHP version" : "PHP versioon", "You are currently running PHP %1$s. PHP %2$s is deprecated since Nextcloud %3$s. Nextcloud %4$s may require at least PHP %5$s. Please upgrade to one of the officially supported PHP versions provided by the PHP Group as soon as possible." : "Sa kasutad hetkel PHP versiooni %1$s. PHP %2$s on aga alates Nexctcloudi versioonist %3$s kasutuselt eemaldatud. Nexctcloud %4$s eeldab, et PHP versioon on vähemalt %5$s. Palun uuenda oma server PHP Groupi poolt väljaantud ametliku PHP versioonini niipea, kui võimalik.", "You are currently running PHP %s." : "Sul on hetkel kasutusel PHP versioon %s.", + "PHP \"output_buffering\" option" : "PHP eelistus „output_buffering“", + "PHP configuration option \"output_buffering\" must be disabled" : "PHP seadistus „output_buffering“ peab olema lülitatud välja", "Push service" : "Tõuketeenus", "Valid enterprise license" : "Suurfirmade litsents", "Free push service" : "Tasuta tõuketeenus", @@ -174,9 +179,14 @@ "MariaDB version \"%1$s\" detected. MariaDB >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin MariaDB versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks MariaDB versioone >=%2$s and <= %3$s.", "MySQL version \"%1$s\" detected. MySQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin MySQLi versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks MySQLi versioone >=%2$s and <= %3$s.", "PostgreSQL version \"%1$s\" detected. PostgreSQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud." : "Tuvastasin PostgreSQLi versiooni „%1$s“. Parima jõudluse, stabiilsuse ja funktsionaalsuse mõttes soovitame selle Nextcloudi versiooni jaoks PostgreSQLi >=%2$s and <= %3$s.", + "Unknown database platform" : "Tuvastamatu andmebaasiplatvorm", "Architecture" : "Arhitektuur", "64-bit" : "64-bitine", "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!" : "Tundub, et kasutad PHP 32-bitist versiooni. Tõhusaks toimimiseks eeldab Nextcloud 64-bitist keskkonda. Palun uuenda oma serveri operatsioonisüsteem ja PHP 64-bitiseks versiooniks!", + "Task Processing pickup speed" : "Ülesannete töötlemise kiirus", + "_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Viimase %n tunni jooksul pole olnud ühtegi ajastatud ülesannet.","Viimase %n tunni jooksul pole olnud ühtegi ajastatud ülesannet."], + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud mõistlik.","Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud mõistlik."], + "_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._" : ["Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud aeglane. Paljude ülesannete töölepanekuks kulus enam, kui 4 minutit. Palun kaalu võimalust, et ülesannete töötlemiseks seadistad taustal töötava protsessihalduri.","Ülesannete töötlemise kiirus on viimase %n tunni jooksul olnud aeglane. Paljude ülesannete töölepanekuks kulus enam, kui 4 minutit. Palun kaalu võimalust, et ülesannete töötlemiseks seadistad taustal töötava protsessihalduri."], "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funktsioon „disk_free_space“ pole kasutusel. Selle puudumine takistab ajutiste kaustade jaoks vajaliku andmeruumi kontrollimist.", "Profile information" : "Kasutajaprofiili teave", "Nextcloud settings" : "Nextcloudi seadistused", @@ -184,8 +194,12 @@ "Enable" : "Lülita sisse", "Machine translation" : "Masintõlge", "Image generation" : "Pildiloome", + "Here you can decide which group can access certain sections of the administration settings." : "Siinkohal saad sa otsustada mis gruppidel on ligipääs valitud haldusseadistustele.", "Unable to modify setting" : "Seadistuse muutmine ei õnnestu", "None" : "Pole", + "Changed disclaimer text" : "Vastutusest lahtiütluse tekst on muutunud", + "Deleted disclaimer text" : "Vastutusest lahtiütluse tekst on kustutatud", + "Could not set disclaimer text" : "Vastutusest lahtiütluse teksti seadistamine ei õnnestunud", "Allow apps to use the Share API" : "Luba rakendustel kasutada Share API-t", "Allow resharing" : "Luba edasijagamine", "Allow sharing with groups" : "Luba gruppidega jagamine", @@ -195,6 +209,7 @@ "Always ask for a password" : "Alati küsi parooli", "Enforce password protection" : "Jõusta paroolikaitse", "Exclude groups from password requirements" : "Välista grupid salasõnareeglitest", + "Exclude groups from creating link shares" : "Välista grupid jagamislinkide loomisest", "Limit sharing based on groups" : "Piira jagamist gruppide alusel", "Allow sharing for everyone (default)" : "Luba jagamine kõikidele (vaikimisi)", "Exclude some groups from sharing" : "Välista mõned grupid jagamisest", @@ -203,7 +218,14 @@ "Enforce expiration date" : "Sunnitud aegumise kuupäev", "Default expiration time of new shares in days" : "Uue jaosmeedia vaikimisi aegumine päevades", "Expire shares after x days" : "Jaosmeedia aegub x päeva möödudes", + "Enforce expiration date for remote shares" : "Määra lingi kaugserverid asuva jaosmeedia vaikimisi aegumiskuupäev ", + "Default expiration time of remote shares in days" : "Kaugserveris asuva jaosmeedia vaikimisi aegumine päevades", + "Expire remote shares after x days" : "Jaosmeedia aegub x päeva möödudes", + "Set default expiration date for shares via link or mail" : "Määra lingi või e-kirjaga jagatava jaosmeedia vaikimisi aegumiskuupäev", + "Default expiration time of shares in days" : "Jaosmeedia vaikimisi aegumine päevades", "Privacy settings for sharing" : "Jagamise privaatsusseadistused", + "Show disclaimer text on the public link upload page (only shown when the file list is hidden)" : "Kuva avaliku lingiga üleslaadimise lehel lahtiütluste tekst (vaid siis, kui failide loend on peidetud)", + "Disclaimer text" : "Vastutusest lahtiütluse tekst", "This text will be shown on the public link upload page when the file list is hidden." : "Seda teksti näidatakse avaliku lingiga üleslaadimise lehel kui failide loend on peidetud.", "Two-Factor Authentication" : "Kaheastmeline autentimine", "Two-factor authentication can be enforced for all accounts and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system." : "Kaheastmelist autentimist on võimalik teha kohustuslikuks kas kõikidele kasutajakontodele või konkreetsete gruppide kaupa. Kui kaheastmelise autentimise kohustuslikkus on määratud, kuid on kasutajal seadistamata, siis ta ei saa siia serverisse sisse logida.", @@ -249,8 +271,10 @@ "Next slide" : "Järgmine slaid", "Choose slide to display" : "Vali kuvatav slaid", "{index} of {total}" : "{index} / {total}", + "Deploy Daemon" : "Kasutuselevõtmise taustateenus", "Type" : "Tüüp", "Display Name" : "Kuvatav nimi", + "Advanced deploy options" : "Kasutuselevõtmise lisavalikud", "Edit ExApp deploy options before installation" : "Muuda ExApp konteineri seadistuse enne paigaldamist", "Configured ExApp deploy options. Can be set only during installation" : "ExApp'i konteineri seadistuse valikud. Neid saab määrata vaid paigalduse ajal", "Learn more" : "Lisateave", @@ -258,9 +282,12 @@ "ExApp container environment variables" : "ExApp konteineri keskonnamuutujad", "No environment variables defined" : "Ühtegi keskonnamuutujat pole defineeritud", "Mounts" : "Haakepunktid", + "Must exist on the Deploy daemon host prior to installing the ExApp" : "Enne ExAppi paigaldamist peab ta olema leitav kasutuselevõtmise taustateenuses", + "Container path" : "Konteineri asukoht", "Read-only" : "Ainult lugemiseks", "Remove mount" : "Eemalda haakepunkt", "New mount" : "Uus haakepunkt", + "Enter path to host folder" : "Sisesta peremeeskausta asukoht", "Enter path to container folder" : "Sisesta konteinerikausta asukoht", "Toggle read-only mode" : "Lülita „ainult lugemiseks“ režiim sisse/välja", "Confirm adding new mount" : "Kinnita uue haakepunkti lisamine", @@ -280,6 +307,8 @@ "Limit app usage to groups" : "Piira rakenduse kasutamist gruppidega", "No results" : "Vasteid ei leitud", "Update to {version}" : "Uuenda versioonile {version}", + "Deploy options" : "Kasutuselevõtmise valikud", + "Default Deploy daemon is not accessible" : "Kasutuselevõtmise taustateenus pole leitav", "Delete data on remove" : "Eemaldamisel kustuta andmed", "This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Sellel rakendusel pole määratud minimaalset Nextcloudi versiooni. See põhjustab tulevikus veateateid.", "This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Sellel rakendusel pole määratud maksimaalset Nextcloudi versiooni. See põhjustab tulevikus veateateid.", @@ -334,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", @@ -354,12 +384,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." : "Alati on hea mõte, kui varundad oma andmeid. Kui aga kasutusel on krüptimine, siis palun kontrolli, et lisaks andmetele on varundatud ka krüptovõtmed.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Süsteemihalduse juhendist leiad teavet kuidas saad käsitsi krüptida juba olemasolevaid faile.", "This is the final warning: Do you really want to enable encryption?" : "See on viimane hoiatus: Kas oled kindel, et soovid krüptimise sisse lülitada?", - "Failed to remove group \"{group}\"" : "„{group}“ grupi eemaldamine ei õnnestunud", + "Failed to delete group \"{group}\"" : "„{group}“ grupi eemaldamine ei õnnestunud", "Please confirm the group removal" : "Palun kinnita grupi eemaldamine", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Sa oled eemaldamas gruppi „{group}“. Selles grupis olevad kasutajad aga JÄÄVAD kustutamata.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Sa oled eemaldamas gruppi „{group}“. Selles grupis olevad kasutajad aga JÄÄVAD kustutamata.", "Submit" : "Saada", "Rename group" : "Muuda grupi nime", - "Remove group" : "Eemalda grupp", + "Delete group" : "Kustuta grupp", "Current password" : "Praegune salasõna", "New password" : "Uus salasõna", "Change password" : "Muuda salasõna", @@ -517,7 +547,10 @@ "Defaults" : "Vaikeväärtused", "Default quota" : "Vaikimisi mahupiir", "Select default quota" : "Vali vaikimisi andmemahu piir", + "Server error while trying to complete WebAuthn device registration" : "Serveriviga WebAuthn seadme registreerimise lõpetamisel", "Passwordless authentication requires a secure connection." : "Salasõnata autentimine eeldab turvalise võrguühenduse kasutamist.", + "Add WebAuthn device" : "Lisa WebAuthni kasutav seade", + "Please authorize your WebAuthn device." : "Palun anna luba oma WebAuthn seadme kasutamiseks", "Adding your device …" : "Lisan sinu seadet…", "Unnamed device" : "Nimetu seade", "Passwordless Authentication" : "Salasõnata autentimine", @@ -567,12 +600,16 @@ "Show to logged in accounts only" : "Näita vaid sisseloginud kasutajatele", "Hide" : "Peida", "Manually installed apps cannot be updated" : "Käsitsi paigaldatud rakendusi ei saa uuendada", + "{progress}% Deploying …" : "Võtan kasutusele {progress}%…", + "Deploy and Enable" : "Võta kasutusele ja lülita sisse", "Disable" : "Lülita välja", "Allow untested app" : "Luba testimata rakenduse kasutamine", + "The app will be downloaded from the App Store" : "See rakendus laaditakse alla App Store'ist", "Unknown" : "Teadmata", "Never" : "Mitte kunagi", "Could not register device: Network error" : "Seadme registreerimine polnud võimalik: võrguühenduse viga", "An error occurred during the request. Unable to proceed." : "Päringu ajal tekkis viga. Jätkamine pole võimalik.", + "Error: This app cannot be enabled because it makes the server unstable" : "Viga: Kuna ta muudaks selle serveri mittetöökindlaks, siis seda rakendust ei saa sisse lülitada", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Rakendus on lubatud, aga see vajab uuendamist. Sind suunatakse 5 sekundi pärast uuendamise lehele.", "Do you really want to wipe your data from this device?" : "Oled sa kindel, et soovid siit seadmest oma andmed kaugkustutada?", "Confirm wipe" : "Kinnita kaugkustutamine", @@ -601,6 +638,7 @@ "Test and verify email settings" : "Testi ja kontrolli e-posti seadistusi", "Security & setup warnings" : "Turva- ja paigalduse hoiatused", "All checks passed." : "Kõik kontrollid on läbitud.", + "Reasons to use Nextcloud in your organization" : "Põhjused, miks peaksid Nextcloudi kasutama oma organisatsioonis", "Follow us on X" : "Järgne meile X-is", "Follow us on Mastodon" : "Järgne meile Mastodonis", "Check out our blog" : "Loe meie ajaveebi", @@ -610,6 +648,7 @@ "The PHP memory limit is below the recommended value of %s." : "PHP mälukasutuse ülempiir on väiksem, kui soovitatav %s.", "for WebAuthn passwordless login" : "WebAuthn salasõnata sisselogimise jaoks", "for WebAuthn passwordless login, and SFTP storage" : "WebAuthn salasõnata sisselogimise ja SFTP andmeruumi jaoks", + "Set default expiration date for shares" : "Määra jaosmeedia vaikimisi aegumiskuupäev", "Your biography" : "Sinu elulugu", "You are using <strong>{usage}</strong>" : "Sa kasutad: <strong>{usage}</strong>", "You are using <strong>{usage}</strong> of <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)" : "Sa kasutad: <strong>{usage}</strong> / <strong>{totalSpace}</strong> (<strong>{usageRelative}%</strong>)", diff --git a/apps/settings/l10n/eu.js b/apps/settings/l10n/eu.js index 542ae9457ac..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", @@ -538,12 +539,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Kontuan izan zifratzeak beti fitxategiaren tamaina handitzen duela.", "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." : "Zure datuen babeskopiak sortu beharko zenituzke aldizka, eta zifratuta badaude, ziurtatu zifratze-gakoen babeskopia ere egiten dela datuekin batera.", "This is the final warning: Do you really want to enable encryption?" : "Azken abisua da: Benetan gaitu nahi duzu zifratzea?", - "Failed to remove group \"{group}\"" : "Ezin izan da \"{group}\" taldea kendu", "Please confirm the group removal" : "Mesedez, baieztatu taldearen ezabaketa", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "\"{group}\" taldea ezabatzera zoaz. Kontuak EZ dira ezabatuko.", "Submit" : "Bidali", "Rename group" : "Berrizendatu taldea", - "Remove group" : "Ezabatu taldea", "Current password" : "Uneko pasahitza", "New password" : "Pasahitz berria", "Change password" : "Aldatu pasahitza", diff --git a/apps/settings/l10n/eu.json b/apps/settings/l10n/eu.json index 3521d4772ec..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", @@ -536,12 +537,9 @@ "Be aware that encryption always increases the file size." : "Kontuan izan zifratzeak beti fitxategiaren tamaina handitzen duela.", "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." : "Zure datuen babeskopiak sortu beharko zenituzke aldizka, eta zifratuta badaude, ziurtatu zifratze-gakoen babeskopia ere egiten dela datuekin batera.", "This is the final warning: Do you really want to enable encryption?" : "Azken abisua da: Benetan gaitu nahi duzu zifratzea?", - "Failed to remove group \"{group}\"" : "Ezin izan da \"{group}\" taldea kendu", "Please confirm the group removal" : "Mesedez, baieztatu taldearen ezabaketa", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "\"{group}\" taldea ezabatzera zoaz. Kontuak EZ dira ezabatuko.", "Submit" : "Bidali", "Rename group" : "Berrizendatu taldea", - "Remove group" : "Ezabatu taldea", "Current password" : "Uneko pasahitza", "New password" : "Pasahitz berria", "Change password" : "Aldatu pasahitza", diff --git a/apps/settings/l10n/fa.js b/apps/settings/l10n/fa.js index 9e29dec7c96..a58a88386d8 100644 --- a/apps/settings/l10n/fa.js +++ b/apps/settings/l10n/fa.js @@ -266,7 +266,6 @@ OC.L10N.register( "This is the final warning: Do you really want to enable encryption?" : "این آخرین اخطار است: آیا میخواهید رمزگذاری را فعال کنید ؟", "Submit" : "ارسال", "Rename group" : "Rename group", - "Remove group" : "برداشتن گروه", "Current password" : "گذرواژه کنونی", "New password" : "گذرواژه جدید", "Change password" : "تغییر گذر واژه", @@ -403,6 +402,7 @@ OC.L10N.register( "Headline" : "عنوان", "Organisation" : "سازمان", "Phone number" : "شماره تلفن", + "Pronouns" : "ضمایر", "Role" : "نقش", "Website" : "وب سایت", "Profile visibility" : "امکان دیده شدن پروفایل", @@ -472,6 +472,7 @@ OC.L10N.register( "This community release of Nextcloud is unsupported and instant notifications are unavailable." : "This community release of Nextcloud is unsupported and instant notifications are unavailable.", "Use a second factor besides your password to increase security for your account." : "برای افزایش امنیت حساب کاربری خود ، از یک عامل دوم علاوه بر رمز عبور خود استفاده کنید.", "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." : "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.", + "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "برای اجرای این بررسی، باید مطمئن شوید که وبسرور شما میتواند به خودش متصل شود. بنابراین باید بتواند حداقل یکی از `trusted_domains` یا `overwrite.cli.url` خود را حل و به آن متصل شود. این خطا ممکن است نتیجه عدم تطابق DNS سمت سرور یا قانون فایروال خروجی باشد.", "Set default expiration date for shares" : "تاریخ انقضا پیش فرض را برای اشتراک گذاری تعیین کنید", "Your biography" : "بیوگرافی شما", "You are using <strong>{usage}</strong>" : "فضای مورد استفاده: <strong>{usage}</strong>", diff --git a/apps/settings/l10n/fa.json b/apps/settings/l10n/fa.json index 555c33bb260..89a923794ff 100644 --- a/apps/settings/l10n/fa.json +++ b/apps/settings/l10n/fa.json @@ -264,7 +264,6 @@ "This is the final warning: Do you really want to enable encryption?" : "این آخرین اخطار است: آیا میخواهید رمزگذاری را فعال کنید ؟", "Submit" : "ارسال", "Rename group" : "Rename group", - "Remove group" : "برداشتن گروه", "Current password" : "گذرواژه کنونی", "New password" : "گذرواژه جدید", "Change password" : "تغییر گذر واژه", @@ -401,6 +400,7 @@ "Headline" : "عنوان", "Organisation" : "سازمان", "Phone number" : "شماره تلفن", + "Pronouns" : "ضمایر", "Role" : "نقش", "Website" : "وب سایت", "Profile visibility" : "امکان دیده شدن پروفایل", @@ -470,6 +470,7 @@ "This community release of Nextcloud is unsupported and instant notifications are unavailable." : "This community release of Nextcloud is unsupported and instant notifications are unavailable.", "Use a second factor besides your password to increase security for your account." : "برای افزایش امنیت حساب کاربری خود ، از یک عامل دوم علاوه بر رمز عبور خود استفاده کنید.", "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." : "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.", + "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "برای اجرای این بررسی، باید مطمئن شوید که وبسرور شما میتواند به خودش متصل شود. بنابراین باید بتواند حداقل یکی از `trusted_domains` یا `overwrite.cli.url` خود را حل و به آن متصل شود. این خطا ممکن است نتیجه عدم تطابق DNS سمت سرور یا قانون فایروال خروجی باشد.", "Set default expiration date for shares" : "تاریخ انقضا پیش فرض را برای اشتراک گذاری تعیین کنید", "Your biography" : "بیوگرافی شما", "You are using <strong>{usage}</strong>" : "فضای مورد استفاده: <strong>{usage}</strong>", diff --git a/apps/settings/l10n/fi.js b/apps/settings/l10n/fi.js index 6d197318ee6..34e3ac3ba9c 100644 --- a/apps/settings/l10n/fi.js +++ b/apps/settings/l10n/fi.js @@ -122,6 +122,7 @@ OC.L10N.register( "Internet connectivity" : "Internet-yhdistettävyys", "Disabled" : "Pois käytöstä", "The old server-side-encryption format is enabled. We recommend disabling this." : "Vanha palvelinpuolen salausmenetelmä on käytössä. Suosittelemme sen ottamista pois käytöstä.", + "Logging level" : "Lokitustaso", "Maintenance window start" : "Huoltoikkunan alku", "Memcache" : "Memcache", "You are not using MySQL" : "Et käytä MySQL:ää", @@ -209,11 +210,13 @@ OC.L10N.register( "No apps found for your version" : "Sovelluksia ei löytynyt versiollesi", "_%n app has an update available_::_%n apps have an update available_" : ["%n sovelluksella on päivitys saatavilla","%n sovelluksella on päivitys saatavilla"], "_Update_::_Update all_" : ["Päivitä","Päivitä kaikki"], + "Failed to load groups" : "Ryhmien lataaminen epäonnistui", "Failed to create group" : "Ryhmän luonti epäonnistui", "Creating group…" : "Luodaan ryhmä…", "Create group" : "Luo ryhmä", "Group name" : "Ryhmän nimi", "Please enter a valid group name" : "Kirjoita kelvollinen ryhmän nimi", + "Search groups…" : "Etsi ryhmiä…", "Loading groups…" : "Ladataan ryhmiä…", "Nothing to show" : "Ei mitään näytettävää", "Loading" : "Ladataan", @@ -227,6 +230,7 @@ OC.L10N.register( "Type" : "Tyyppi", "Display Name" : "Näyttönimi", "Learn more" : "Opi lisää", + "Environment variables" : "Ympäristömuuttujat", "Confirm" : "Vahvista", "Cancel" : "Peru", "Description" : "Kuvaus", @@ -258,6 +262,8 @@ OC.L10N.register( "{productName} Talk for iOS" : "{productName} Talk iOS:lle", "{productName} Talk for Android" : "{productName} Talk Androidille", "This session" : "Tämä istunto", + "{client} - {version} ({system})" : "{client} - {version} ({system})", + "{client} - {version}" : "{client} - {version}", "Device name" : "Laitteen nimi", "Save new name" : "Tallenna uusi nimi", "Marked for remote wipe" : "Merkitty etätyhjennettäväksi", @@ -286,9 +292,11 @@ OC.L10N.register( "Use system cron service to call the cron.php file every 5 minutes." : "Käytä järjestelmän cron-palvelua cron.php-skriptin suorittamiseen 5 minuutin välein", "Last job execution ran {time}. Something seems wrong." : "Viimeisimmän työn suoritus {time}. Jokin vaikuttaa olevan pielessä.", "Last job ran {relativeTime}." : "Viimeisin työ ajettiin {relativeTime}.", + "AJAX" : "AJAX", "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", @@ -301,12 +309,11 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Ota huomioon, että salaus kasvattaa aina tiedostojen kokoa.", "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." : "Säännöllisten varmuuskopioiden ottaminen on erittäin tärkeää. Jos olet ottanut salauksen käyttöön, huolehdi salausavainten varmuuskopioinnista.", "This is the final warning: Do you really want to enable encryption?" : "Tämä on viimeinen varoitus: haluatko varmasti ottaa salauksen käyttöön?", - "Failed to remove group \"{group}\"" : "Ryhmän \"{group}\" poistaminen epäonnistui", + "Failed to delete group \"{group}\"" : "Ryhmän \"{group}\" poistaminen epäonnistui", "Please confirm the group removal" : "Vahvista ryhmän poistaminen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Olet aikeissa poistaa ryhmän \"{group}\". Tilejä EI poisteta.", "Submit" : "Lähetä", "Rename group" : "Nimeä ryhmä uudelleen", - "Remove group" : "Poista ryhmä", + "Delete group" : "Poista ryhmä", "Current password" : "Nykyinen salasana", "New password" : "Uusi salasana", "Change password" : "Vaihda salasana", @@ -402,7 +409,9 @@ OC.L10N.register( "Account deletion" : "Tilin poistaminen", "Delete {userid}'s account" : "Poista käyttäjän {userid} tili", "Display name was successfully changed" : "Näyttönimi vaihdettiin onnistuneesti", + "Password can't be empty" : "Salasana ei voi olla tyhjä", "Password was successfully changed" : "Salasana vaihdettiin onnistuneesti", + "Email can't be empty" : "Sähköposti ei voi olla tyhjä", "Email was successfully changed" : "Sähköpostiosoite vaihdettiin onnistuneesti", "Welcome mail sent!" : "Tervetuloviesti lähetetty!", "Loading account …" : "Ladataan tiliä…", @@ -441,6 +450,8 @@ OC.L10N.register( "Loading categories" : "Ladataan luokkia", "Developer documentation ↗" : "Kehittäjien dokumentaatio ↗", "Version {version}, {license}-licensed" : "Versio {version}, lisenssi {license}", + "Version {version}" : "Versio {version}", + "All accounts" : "Kaikki tilit", "Admins" : "Ylläpitäjät", "Account group: {group}" : "Tiliryhmä: {group}", "Account management" : "Tilihallinta", @@ -461,6 +472,7 @@ OC.L10N.register( "Website" : "Verkkosivusto", "Profile visibility" : "Profiilin näkyvyys", "Locale" : "Aluekohtainen asetus", + "First day of week" : "Viikon ensimmäinen päivä", "Your apps" : "Sovelluksesi", "Active apps" : "Aktiiviset sovellukset", "Disabled apps" : "Käytöstä poistetut sovellukset", diff --git a/apps/settings/l10n/fi.json b/apps/settings/l10n/fi.json index 87103ca03b9..d78cfde1069 100644 --- a/apps/settings/l10n/fi.json +++ b/apps/settings/l10n/fi.json @@ -120,6 +120,7 @@ "Internet connectivity" : "Internet-yhdistettävyys", "Disabled" : "Pois käytöstä", "The old server-side-encryption format is enabled. We recommend disabling this." : "Vanha palvelinpuolen salausmenetelmä on käytössä. Suosittelemme sen ottamista pois käytöstä.", + "Logging level" : "Lokitustaso", "Maintenance window start" : "Huoltoikkunan alku", "Memcache" : "Memcache", "You are not using MySQL" : "Et käytä MySQL:ää", @@ -207,11 +208,13 @@ "No apps found for your version" : "Sovelluksia ei löytynyt versiollesi", "_%n app has an update available_::_%n apps have an update available_" : ["%n sovelluksella on päivitys saatavilla","%n sovelluksella on päivitys saatavilla"], "_Update_::_Update all_" : ["Päivitä","Päivitä kaikki"], + "Failed to load groups" : "Ryhmien lataaminen epäonnistui", "Failed to create group" : "Ryhmän luonti epäonnistui", "Creating group…" : "Luodaan ryhmä…", "Create group" : "Luo ryhmä", "Group name" : "Ryhmän nimi", "Please enter a valid group name" : "Kirjoita kelvollinen ryhmän nimi", + "Search groups…" : "Etsi ryhmiä…", "Loading groups…" : "Ladataan ryhmiä…", "Nothing to show" : "Ei mitään näytettävää", "Loading" : "Ladataan", @@ -225,6 +228,7 @@ "Type" : "Tyyppi", "Display Name" : "Näyttönimi", "Learn more" : "Opi lisää", + "Environment variables" : "Ympäristömuuttujat", "Confirm" : "Vahvista", "Cancel" : "Peru", "Description" : "Kuvaus", @@ -256,6 +260,8 @@ "{productName} Talk for iOS" : "{productName} Talk iOS:lle", "{productName} Talk for Android" : "{productName} Talk Androidille", "This session" : "Tämä istunto", + "{client} - {version} ({system})" : "{client} - {version} ({system})", + "{client} - {version}" : "{client} - {version}", "Device name" : "Laitteen nimi", "Save new name" : "Tallenna uusi nimi", "Marked for remote wipe" : "Merkitty etätyhjennettäväksi", @@ -284,9 +290,11 @@ "Use system cron service to call the cron.php file every 5 minutes." : "Käytä järjestelmän cron-palvelua cron.php-skriptin suorittamiseen 5 minuutin välein", "Last job execution ran {time}. Something seems wrong." : "Viimeisimmän työn suoritus {time}. Jokin vaikuttaa olevan pielessä.", "Last job ran {relativeTime}." : "Viimeisin työ ajettiin {relativeTime}.", + "AJAX" : "AJAX", "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", @@ -299,12 +307,11 @@ "Be aware that encryption always increases the file size." : "Ota huomioon, että salaus kasvattaa aina tiedostojen kokoa.", "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." : "Säännöllisten varmuuskopioiden ottaminen on erittäin tärkeää. Jos olet ottanut salauksen käyttöön, huolehdi salausavainten varmuuskopioinnista.", "This is the final warning: Do you really want to enable encryption?" : "Tämä on viimeinen varoitus: haluatko varmasti ottaa salauksen käyttöön?", - "Failed to remove group \"{group}\"" : "Ryhmän \"{group}\" poistaminen epäonnistui", + "Failed to delete group \"{group}\"" : "Ryhmän \"{group}\" poistaminen epäonnistui", "Please confirm the group removal" : "Vahvista ryhmän poistaminen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Olet aikeissa poistaa ryhmän \"{group}\". Tilejä EI poisteta.", "Submit" : "Lähetä", "Rename group" : "Nimeä ryhmä uudelleen", - "Remove group" : "Poista ryhmä", + "Delete group" : "Poista ryhmä", "Current password" : "Nykyinen salasana", "New password" : "Uusi salasana", "Change password" : "Vaihda salasana", @@ -400,7 +407,9 @@ "Account deletion" : "Tilin poistaminen", "Delete {userid}'s account" : "Poista käyttäjän {userid} tili", "Display name was successfully changed" : "Näyttönimi vaihdettiin onnistuneesti", + "Password can't be empty" : "Salasana ei voi olla tyhjä", "Password was successfully changed" : "Salasana vaihdettiin onnistuneesti", + "Email can't be empty" : "Sähköposti ei voi olla tyhjä", "Email was successfully changed" : "Sähköpostiosoite vaihdettiin onnistuneesti", "Welcome mail sent!" : "Tervetuloviesti lähetetty!", "Loading account …" : "Ladataan tiliä…", @@ -439,6 +448,8 @@ "Loading categories" : "Ladataan luokkia", "Developer documentation ↗" : "Kehittäjien dokumentaatio ↗", "Version {version}, {license}-licensed" : "Versio {version}, lisenssi {license}", + "Version {version}" : "Versio {version}", + "All accounts" : "Kaikki tilit", "Admins" : "Ylläpitäjät", "Account group: {group}" : "Tiliryhmä: {group}", "Account management" : "Tilihallinta", @@ -459,6 +470,7 @@ "Website" : "Verkkosivusto", "Profile visibility" : "Profiilin näkyvyys", "Locale" : "Aluekohtainen asetus", + "First day of week" : "Viikon ensimmäinen päivä", "Your apps" : "Sovelluksesi", "Active apps" : "Aktiiviset sovellukset", "Disabled apps" : "Käytöstä poistetut sovellukset", diff --git a/apps/settings/l10n/fr.js b/apps/settings/l10n/fr.js index 392f0f17d92..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,12 +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 remove group \"{group}\"" : "Erreur à la suppression de « {group} »", + "Failed to delete group \"{group}\"" : "Échec de la suppression du groupe \"{group}\"", "Please confirm the group removal" : "Merci de confirmer la suppression du groupe", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Vous êtes sur le point de supprimer le groupe « {group} ». Les comptes qui en font partie ne seront PAS supprimés.", "Submit" : "Soumettre", "Rename group" : "Renommer le groupe", - "Remove group" : "Retirer 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 095170f3d13..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,12 +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 remove group \"{group}\"" : "Erreur à la suppression de « {group} »", + "Failed to delete group \"{group}\"" : "Échec de la suppression du groupe \"{group}\"", "Please confirm the group removal" : "Merci de confirmer la suppression du groupe", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Vous êtes sur le point de supprimer le groupe « {group} ». Les comptes qui en font partie ne seront PAS supprimés.", "Submit" : "Soumettre", "Rename group" : "Renommer le groupe", - "Remove group" : "Retirer 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/ga.js b/apps/settings/l10n/ga.js index d32d8cec1c6..6459d2a0218 100644 --- a/apps/settings/l10n/ga.js +++ b/apps/settings/l10n/ga.js @@ -315,6 +315,9 @@ OC.L10N.register( "Architecture" : "Ailtireacht", "64-bit" : "64-giotán", "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!" : "Is cosúil go bhfuil leagan PHP 32-giotán á rith agat. Tá 64-giotán ag teastáil ó Nextcloud chun go n-éireoidh go maith. Uasghrádaigh do OS agus PHP go 64-giotán le do thoil!", + "Task Processing pickup speed" : "Luas bailithe Próiseála Tascanna", + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas."], + "_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._" : ["Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra."], "Temporary space available" : "Spás sealadach ar fáil", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Earráid agus an cosán PHP sealadach á sheiceáil - níor socraíodh go heolaire é i gceart. Luach aischurtha: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Tá an fheidhm PHP \"disk_free_space\" díchumasaithe, rud a chuireann cosc ar an seiceáil le haghaidh spás leordhóthanach sna heolairí sealadacha.", @@ -583,12 +586,9 @@ 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." : "Is maith i gcónaí cúltacaí rialta de do shonraí a chruthú, i gcás criptithe déan cinnte cúltaca a dhéanamh de na heochracha criptithe chomh maith le do shonraí.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Déan tagairt don doiciméadú riaracháin maidir le conas comhaid atá ann cheana a chriptiú de láimh freisin.", "This is the final warning: Do you really want to enable encryption?" : "Seo é an rabhadh deiridh: Ar mhaith leat criptiúchán a chumasú?", - "Failed to remove group \"{group}\"" : "Theip ar an ngrúpa \"{group}\" a bhaint", "Please confirm the group removal" : "Deimhnigh baint an ghrúpa", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Tá tú ar tí an grúpa \"{group}\" a bhaint. NÍ scriosfar na cuntais.", "Submit" : "Cuir isteach", "Rename group" : "Athainmnigh an grúpa", - "Remove group" : "Bain an grúpa", "Current password" : "Pasfhocal reatha", "New password" : "Focal Faire Nua", "Change password" : "Athraigh do phasfhocal", diff --git a/apps/settings/l10n/ga.json b/apps/settings/l10n/ga.json index b6eb9381282..da9d8291ba6 100644 --- a/apps/settings/l10n/ga.json +++ b/apps/settings/l10n/ga.json @@ -313,6 +313,9 @@ "Architecture" : "Ailtireacht", "64-bit" : "64-giotán", "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!" : "Is cosúil go bhfuil leagan PHP 32-giotán á rith agat. Tá 64-giotán ag teastáil ó Nextcloud chun go n-éireoidh go maith. Uasghrádaigh do OS agus PHP go 64-giotán le do thoil!", + "Task Processing pickup speed" : "Luas bailithe Próiseála Tascanna", + "_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas.","Tá luas bailithe na dtascanna ceart go leor le %n uair an chloig anuas."], + "_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._" : ["Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra.","Tá luas bailithe na dtascanna mall le %n uair an chloig anuas. Thóg sé níos mó ná 4 nóiméad go leor tascanna a bhailiú. Smaoinigh ar oibrí a shocrú chun tascanna a phróiseáil sa chúlra."], "Temporary space available" : "Spás sealadach ar fáil", "Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Earráid agus an cosán PHP sealadach á sheiceáil - níor socraíodh go heolaire é i gceart. Luach aischurtha: %s", "The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "Tá an fheidhm PHP \"disk_free_space\" díchumasaithe, rud a chuireann cosc ar an seiceáil le haghaidh spás leordhóthanach sna heolairí sealadacha.", @@ -581,12 +584,9 @@ "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." : "Is maith i gcónaí cúltacaí rialta de do shonraí a chruthú, i gcás criptithe déan cinnte cúltaca a dhéanamh de na heochracha criptithe chomh maith le do shonraí.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Déan tagairt don doiciméadú riaracháin maidir le conas comhaid atá ann cheana a chriptiú de láimh freisin.", "This is the final warning: Do you really want to enable encryption?" : "Seo é an rabhadh deiridh: Ar mhaith leat criptiúchán a chumasú?", - "Failed to remove group \"{group}\"" : "Theip ar an ngrúpa \"{group}\" a bhaint", "Please confirm the group removal" : "Deimhnigh baint an ghrúpa", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Tá tú ar tí an grúpa \"{group}\" a bhaint. NÍ scriosfar na cuntais.", "Submit" : "Cuir isteach", "Rename group" : "Athainmnigh an grúpa", - "Remove group" : "Bain an grúpa", "Current password" : "Pasfhocal reatha", "New password" : "Focal Faire Nua", "Change password" : "Athraigh do phasfhocal", diff --git a/apps/settings/l10n/gl.js b/apps/settings/l10n/gl.js index 13738a6d883..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", @@ -578,12 +579,9 @@ 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 é bo crear copias de seguranza dos seus datos, no caso do cifrado, asegúrese de ter unha copia de seguranza das chaves de cifrado xunto cos seus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulte a documentación de administración sobre para saber tamén como cifrar manualmente os ficheiros existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta é a última advertencia: Confirma que quere activar o cifrado?", - "Failed to remove group \"{group}\"" : "Produciuse un fallo ao retirar o grupo «{group}»", "Please confirm the group removal" : "Confirme a retirada do grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a piques de retirar o grupo «{group}». As contas NON van ser eliminadas.", "Submit" : "Enviar", "Rename group" : "Cambiar o nome do grupo", - "Remove group" : "Retirar o grupo", "Current password" : "Contrasinal actual", "New password" : "Novo contrasinal", "Change password" : "Cambiar o contrasinal", diff --git a/apps/settings/l10n/gl.json b/apps/settings/l10n/gl.json index 65690552052..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", @@ -576,12 +577,9 @@ "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 é bo crear copias de seguranza dos seus datos, no caso do cifrado, asegúrese de ter unha copia de seguranza das chaves de cifrado xunto cos seus datos.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Consulte a documentación de administración sobre para saber tamén como cifrar manualmente os ficheiros existentes.", "This is the final warning: Do you really want to enable encryption?" : "Esta é a última advertencia: Confirma que quere activar o cifrado?", - "Failed to remove group \"{group}\"" : "Produciuse un fallo ao retirar o grupo «{group}»", "Please confirm the group removal" : "Confirme a retirada do grupo", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Está a piques de retirar o grupo «{group}». As contas NON van ser eliminadas.", "Submit" : "Enviar", "Rename group" : "Cambiar o nome do grupo", - "Remove group" : "Retirar o grupo", "Current password" : "Contrasinal actual", "New password" : "Novo contrasinal", "Change password" : "Cambiar o contrasinal", diff --git a/apps/settings/l10n/he.js b/apps/settings/l10n/he.js index cab93cff966..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" : "הפעלת הצפנה בצד שרת", @@ -212,7 +213,6 @@ 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." : "תמיד טוב ליצור גיבוי קבוע למידע , במקרה של הצפנה יש לוודא שגם מפתחות ההצפנה מגובים עם המידע שלך.", "This is the final warning: Do you really want to enable encryption?" : "זו הזהרה אחרונה: האם באמת ברצונך להפעיל הצפנה?", "Submit" : "שליחה", - "Remove group" : "הסרת קבוצה", "Current password" : "סיסמא נוכחית", "New password" : "סיסמא חדשה", "Change password" : "שינוי סיסמא", diff --git a/apps/settings/l10n/he.json b/apps/settings/l10n/he.json index 57b3b3517d8..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" : "הפעלת הצפנה בצד שרת", @@ -210,7 +211,6 @@ "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." : "תמיד טוב ליצור גיבוי קבוע למידע , במקרה של הצפנה יש לוודא שגם מפתחות ההצפנה מגובים עם המידע שלך.", "This is the final warning: Do you really want to enable encryption?" : "זו הזהרה אחרונה: האם באמת ברצונך להפעיל הצפנה?", "Submit" : "שליחה", - "Remove group" : "הסרת קבוצה", "Current password" : "סיסמא נוכחית", "New password" : "סיסמא חדשה", "Change password" : "שינוי סיסמא", diff --git a/apps/settings/l10n/hr.js b/apps/settings/l10n/hr.js index 1ff23c276df..de5cf954a77 100644 --- a/apps/settings/l10n/hr.js +++ b/apps/settings/l10n/hr.js @@ -228,7 +228,6 @@ 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." : "Uvijek je dobra ideja redovito izrađivati sigurnosne kopije podataka; ako upotrebljavate šifriranje, obavezno sigurnosno kopirajte ključeve za šifriranje zajedno sa svojim podacima.", "This is the final warning: Do you really want to enable encryption?" : "Ovo je posljednje upozorenje: želite li zaista omogućiti šifriranje?", "Submit" : "Šalji", - "Remove group" : "Ukloni grupu", "Current password" : "Trenutna zaporka", "New password" : "Nova zaporka", "Change password" : "Promijeni zaporku", diff --git a/apps/settings/l10n/hr.json b/apps/settings/l10n/hr.json index 991eea4471d..c4930239dc8 100644 --- a/apps/settings/l10n/hr.json +++ b/apps/settings/l10n/hr.json @@ -226,7 +226,6 @@ "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." : "Uvijek je dobra ideja redovito izrađivati sigurnosne kopije podataka; ako upotrebljavate šifriranje, obavezno sigurnosno kopirajte ključeve za šifriranje zajedno sa svojim podacima.", "This is the final warning: Do you really want to enable encryption?" : "Ovo je posljednje upozorenje: želite li zaista omogućiti šifriranje?", "Submit" : "Šalji", - "Remove group" : "Ukloni grupu", "Current password" : "Trenutna zaporka", "New password" : "Nova zaporka", "Change password" : "Promijeni zaporku", diff --git a/apps/settings/l10n/hu.js b/apps/settings/l10n/hu.js index cd6075991c8..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.", @@ -399,11 +400,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Ügyeljen arra, hogy a titkosítás mindig megnöveli a fájlok méretét.", "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." : "Mindig jó ötlet rendszeres biztonsági mentést készíteni az adatokról. Titkosítás esetén győződjön meg arról, hogy a titkosítási kulcsokról is készít biztonsági mentést.", "This is the final warning: Do you really want to enable encryption?" : "Ez az utolsó figyelmeztetés: Biztos, hogy engedélyezi a titkosítást?", - "Failed to remove group \"{group}\"" : "Nem sikerült a(z) „{group}” csoport törlése", "Please confirm the group removal" : "Erősítse meg a csoport eltávolítását", "Submit" : "Beküldés", "Rename group" : "Csoport átnevezése", - "Remove group" : "Csoport eltávolítása", "Current password" : "Jelenlegi jelszó", "New password" : "Új jelszó", "Change password" : "Jelszó megváltoztatása", diff --git a/apps/settings/l10n/hu.json b/apps/settings/l10n/hu.json index e49a52fea27..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.", @@ -397,11 +398,9 @@ "Be aware that encryption always increases the file size." : "Ügyeljen arra, hogy a titkosítás mindig megnöveli a fájlok méretét.", "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." : "Mindig jó ötlet rendszeres biztonsági mentést készíteni az adatokról. Titkosítás esetén győződjön meg arról, hogy a titkosítási kulcsokról is készít biztonsági mentést.", "This is the final warning: Do you really want to enable encryption?" : "Ez az utolsó figyelmeztetés: Biztos, hogy engedélyezi a titkosítást?", - "Failed to remove group \"{group}\"" : "Nem sikerült a(z) „{group}” csoport törlése", "Please confirm the group removal" : "Erősítse meg a csoport eltávolítását", "Submit" : "Beküldés", "Rename group" : "Csoport átnevezése", - "Remove group" : "Csoport eltávolítása", "Current password" : "Jelenlegi jelszó", "New password" : "Új jelszó", "Change password" : "Jelszó megváltoztatása", diff --git a/apps/settings/l10n/id.js b/apps/settings/l10n/id.js index 2ad64343c52..33d57471e83 100644 --- a/apps/settings/l10n/id.js +++ b/apps/settings/l10n/id.js @@ -214,7 +214,6 @@ 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." : "Alangkah baiknya untuk membuat cadangan data secara rutin, dalam kasus enkripsi, pastikan untuk mencadangkan kunci enkripsi bersama dengan data Anda.", "This is the final warning: Do you really want to enable encryption?" : "Ini adalah peringatan terakhir: Apakah Anda yakin ingin mengaktifkan enkripsi?", "Rename group" : "Ganti nama grup", - "Remove group" : "Hapus grup", "Current password" : "Kata sandi saat ini", "New password" : "Kata sandi baru", "Change password" : "Ubah kata sandi", diff --git a/apps/settings/l10n/id.json b/apps/settings/l10n/id.json index a510d35b913..da357f5a569 100644 --- a/apps/settings/l10n/id.json +++ b/apps/settings/l10n/id.json @@ -212,7 +212,6 @@ "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." : "Alangkah baiknya untuk membuat cadangan data secara rutin, dalam kasus enkripsi, pastikan untuk mencadangkan kunci enkripsi bersama dengan data Anda.", "This is the final warning: Do you really want to enable encryption?" : "Ini adalah peringatan terakhir: Apakah Anda yakin ingin mengaktifkan enkripsi?", "Rename group" : "Ganti nama grup", - "Remove group" : "Hapus grup", "Current password" : "Kata sandi saat ini", "New password" : "Kata sandi baru", "Change password" : "Ubah kata sandi", diff --git a/apps/settings/l10n/is.js b/apps/settings/l10n/is.js index e8350dc7362..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", @@ -414,12 +415,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Hafðu í huga að dulritun eykur alltaf skráastærð.", "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." : "Það er góður siður að taka regluleg öryggisafrit af gögnunum þínum; ef um dulrituð gögn er að ræða, gakktu úr skugga um að einnig sé tekið öryggisafrit af dulritunarlyklum ásamt gögnunum.", "This is the final warning: Do you really want to enable encryption?" : "Þetta er lokaaðvörun: Viltu örugglega virkja dulritun?", - "Failed to remove group \"{group}\"" : "Mistókst að fjarlægja hópinn \"{group}\"", "Please confirm the group removal" : "Staðfestu fjarlægingu hópsins", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Þú er í þann mund að fara að fjarlægja hópinn \"{group}\". Notendaaðgöngunum verður EKKI eytt.", "Submit" : "Senda inn", "Rename group" : "Endurnefna hóp", - "Remove group" : "Fjarlægja hóp", "Current password" : "Núverandi lykilorð", "New password" : "Nýtt lykilorð", "Change password" : "Breyta lykilorði", diff --git a/apps/settings/l10n/is.json b/apps/settings/l10n/is.json index 821abd30bca..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", @@ -412,12 +413,9 @@ "Be aware that encryption always increases the file size." : "Hafðu í huga að dulritun eykur alltaf skráastærð.", "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." : "Það er góður siður að taka regluleg öryggisafrit af gögnunum þínum; ef um dulrituð gögn er að ræða, gakktu úr skugga um að einnig sé tekið öryggisafrit af dulritunarlyklum ásamt gögnunum.", "This is the final warning: Do you really want to enable encryption?" : "Þetta er lokaaðvörun: Viltu örugglega virkja dulritun?", - "Failed to remove group \"{group}\"" : "Mistókst að fjarlægja hópinn \"{group}\"", "Please confirm the group removal" : "Staðfestu fjarlægingu hópsins", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Þú er í þann mund að fara að fjarlægja hópinn \"{group}\". Notendaaðgöngunum verður EKKI eytt.", "Submit" : "Senda inn", "Rename group" : "Endurnefna hóp", - "Remove group" : "Fjarlægja hóp", "Current password" : "Núverandi lykilorð", "New password" : "Nýtt lykilorð", "Change password" : "Breyta lykilorði", diff --git a/apps/settings/l10n/it.js b/apps/settings/l10n/it.js index 6e01e49e907..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.", @@ -461,11 +462,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Considera che la cifratura incrementa sempre la dimensione dei file.", "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." : "Ti consigliamo di creare copie di sicurezza dei tuoi dati con regolarità, in caso di utilizzo della cifratura, assicurati di creare una copia delle chiavi di cifratura insieme ai tuoi dati.", "This is the final warning: Do you really want to enable encryption?" : "Questo è l'ultimo avviso: vuoi davvero abilitare la cifratura?", - "Failed to remove group \"{group}\"" : "Rimozione del gruppo \"{group}\" fallita", "Please confirm the group removal" : "Conferma la rimozione del gruppo", "Submit" : "Invia", "Rename group" : "Rinomina gruppo", - "Remove group" : "Rimuovi gruppo", "Current password" : "Password attuale", "New password" : "Nuova password", "Change password" : "Modifica password", diff --git a/apps/settings/l10n/it.json b/apps/settings/l10n/it.json index b9396695e79..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.", @@ -459,11 +460,9 @@ "Be aware that encryption always increases the file size." : "Considera che la cifratura incrementa sempre la dimensione dei file.", "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." : "Ti consigliamo di creare copie di sicurezza dei tuoi dati con regolarità, in caso di utilizzo della cifratura, assicurati di creare una copia delle chiavi di cifratura insieme ai tuoi dati.", "This is the final warning: Do you really want to enable encryption?" : "Questo è l'ultimo avviso: vuoi davvero abilitare la cifratura?", - "Failed to remove group \"{group}\"" : "Rimozione del gruppo \"{group}\" fallita", "Please confirm the group removal" : "Conferma la rimozione del gruppo", "Submit" : "Invia", "Rename group" : "Rinomina gruppo", - "Remove group" : "Rimuovi gruppo", "Current password" : "Password attuale", "New password" : "Nuova password", "Change password" : "Modifica password", diff --git a/apps/settings/l10n/ja.js b/apps/settings/l10n/ja.js index f66ce707717..87cfe42f3ea 100644 --- a/apps/settings/l10n/ja.js +++ b/apps/settings/l10n/ja.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ビット版が必要です。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\"が無効になっており、一時的なディレクトリに十分な空き容量があるかどうかをチェックできません。", @@ -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,12 +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 remove group \"{group}\"" : "グループ \"{group}\" の削除に失敗しました", + "Failed to delete group \"{group}\"" : "グループ \"{group}\"の削除に失敗しました", "Please confirm the group removal" : "グループの削除を確認してください", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", "Submit" : "送信", "Rename group" : "グループの名称変更", - "Remove group" : "グループを削除", + "Delete group" : "グループを削除", "Current password" : "現在のパスワード", "New password" : "新しいパスワード", "Change password" : "パスワードを変更", diff --git a/apps/settings/l10n/ja.json b/apps/settings/l10n/ja.json index 89e9a12ea87..a1ecd71d95e 100644 --- a/apps/settings/l10n/ja.json +++ b/apps/settings/l10n/ja.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ビット版が必要です。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\"が無効になっており、一時的なディレクトリに十分な空き容量があるかどうかをチェックできません。", @@ -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,12 +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 remove group \"{group}\"" : "グループ \"{group}\" の削除に失敗しました", + "Failed to delete group \"{group}\"" : "グループ \"{group}\"の削除に失敗しました", "Please confirm the group removal" : "グループの削除を確認してください", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "グループ \"{group}\" を削除しようとしています。アカウントは削除されません。", "Submit" : "送信", "Rename group" : "グループの名称変更", - "Remove group" : "グループを削除", + "Delete group" : "グループを削除", "Current password" : "現在のパスワード", "New password" : "新しいパスワード", "Change password" : "パスワードを変更", diff --git a/apps/settings/l10n/ka.js b/apps/settings/l10n/ka.js index c0be4c87b04..0c66cd9d6fd 100644 --- a/apps/settings/l10n/ka.js +++ b/apps/settings/l10n/ka.js @@ -350,11 +350,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Be aware that encryption always increases the file size.", "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." : "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.", "This is the final warning: Do you really want to enable encryption?" : "This is the final warning: Do you really want to enable encryption?", - "Failed to remove group \"{group}\"" : "Failed to remove group \"{group}\"", "Please confirm the group removal" : "Please confirm the group removal", "Submit" : "Submit", "Rename group" : "Rename group", - "Remove group" : "Remove group", "Current password" : "Current password", "New password" : "New password", "Change password" : "Change password", diff --git a/apps/settings/l10n/ka.json b/apps/settings/l10n/ka.json index b21e1679a3c..dafb5323388 100644 --- a/apps/settings/l10n/ka.json +++ b/apps/settings/l10n/ka.json @@ -348,11 +348,9 @@ "Be aware that encryption always increases the file size." : "Be aware that encryption always increases the file size.", "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." : "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.", "This is the final warning: Do you really want to enable encryption?" : "This is the final warning: Do you really want to enable encryption?", - "Failed to remove group \"{group}\"" : "Failed to remove group \"{group}\"", "Please confirm the group removal" : "Please confirm the group removal", "Submit" : "Submit", "Rename group" : "Rename group", - "Remove group" : "Remove group", "Current password" : "Current password", "New password" : "New password", "Change 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 0d43d833d85..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" : "서버 측 암호화", @@ -482,12 +483,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "암호화된 파일의 크기는 항상 커집니다.", "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." : "데이터를 주기적으로 백업하는 것을 추천하며, 암호화를 사용하고 있다면 데이터와 더불어 암호화 키도 백업하십시오.", "This is the final warning: Do you really want to enable encryption?" : "마지막 경고입니다. 암호화를 활성화하시겠습니까?", - "Failed to remove group \"{group}\"" : "그룹 \"{group}\"을(를) 삭제할 수 없음", "Please confirm the group removal" : "그룹 지우기를 확인해 주십시오", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "그룹 \"{group}\"을(를) 지우려고 합니다. 그룹의 계정은 삭제되지 않습니다.", "Submit" : "제출", "Rename group" : "그룹 이름 바꾸기", - "Remove group" : "그룹 지우기", "Current password" : "현재 암호", "New password" : "새 암호", "Change password" : "암호 변경", diff --git a/apps/settings/l10n/ko.json b/apps/settings/l10n/ko.json index 7afb74e8f0e..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" : "서버 측 암호화", @@ -480,12 +481,9 @@ "Be aware that encryption always increases the file size." : "암호화된 파일의 크기는 항상 커집니다.", "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." : "데이터를 주기적으로 백업하는 것을 추천하며, 암호화를 사용하고 있다면 데이터와 더불어 암호화 키도 백업하십시오.", "This is the final warning: Do you really want to enable encryption?" : "마지막 경고입니다. 암호화를 활성화하시겠습니까?", - "Failed to remove group \"{group}\"" : "그룹 \"{group}\"을(를) 삭제할 수 없음", "Please confirm the group removal" : "그룹 지우기를 확인해 주십시오", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "그룹 \"{group}\"을(를) 지우려고 합니다. 그룹의 계정은 삭제되지 않습니다.", "Submit" : "제출", "Rename group" : "그룹 이름 바꾸기", - "Remove group" : "그룹 지우기", "Current password" : "현재 암호", "New password" : "새 암호", "Change password" : "암호 변경", diff --git a/apps/settings/l10n/lt_LT.js b/apps/settings/l10n/lt_LT.js index 585fdfb4690..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.", @@ -270,12 +271,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Turėkite omenyje, kad šifravimas visada padidina failų dydį.", "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." : "Visada yra gerai daryti reguliarias atsargines duomenų kopijas. Esant šifravimui, nepamirškite kartu su savo duomenų atsargine kopija, pasidaryti ir šifravimo raktų atsarginę kopiją.", "This is the final warning: Do you really want to enable encryption?" : "Tai yra paskutinis įspėjimas: Ar tikrai norite įjungti šifravimą?", - "Failed to remove group \"{group}\"" : "Nepavyko pašalinti grupės „{group}“", "Please confirm the group removal" : "Patvirtinkite grupės pašalinimą", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Jūs ketinate pašalinti grupę „{group}“. Paskyros NEBUS ištrintos.", "Submit" : "Pateikti", "Rename group" : "Pervadinti grupę", - "Remove group" : "Šalinti grupę", "Current password" : "Dabartinis slaptažodis", "New password" : "Naujas slaptažodis", "Change password" : "Pakeisti slaptažodį", diff --git a/apps/settings/l10n/lt_LT.json b/apps/settings/l10n/lt_LT.json index 54d5227731b..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.", @@ -268,12 +269,9 @@ "Be aware that encryption always increases the file size." : "Turėkite omenyje, kad šifravimas visada padidina failų dydį.", "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." : "Visada yra gerai daryti reguliarias atsargines duomenų kopijas. Esant šifravimui, nepamirškite kartu su savo duomenų atsargine kopija, pasidaryti ir šifravimo raktų atsarginę kopiją.", "This is the final warning: Do you really want to enable encryption?" : "Tai yra paskutinis įspėjimas: Ar tikrai norite įjungti šifravimą?", - "Failed to remove group \"{group}\"" : "Nepavyko pašalinti grupės „{group}“", "Please confirm the group removal" : "Patvirtinkite grupės pašalinimą", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Jūs ketinate pašalinti grupę „{group}“. Paskyros NEBUS ištrintos.", "Submit" : "Pateikti", "Rename group" : "Pervadinti grupę", - "Remove group" : "Šalinti grupę", "Current password" : "Dabartinis slaptažodis", "New password" : "Naujas slaptažodis", "Change password" : "Pakeisti slaptažodį", diff --git a/apps/settings/l10n/lv.js b/apps/settings/l10n/lv.js index d69e5dc6a95..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,17 +136,17 @@ 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", - "Remove group" : "Noņemt grupu", "Current password" : "Pašreizējā parole", "New password" : "Jaunā parole", "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", @@ -154,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", @@ -183,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 …", @@ -225,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 bbee8b63232..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,17 +134,17 @@ "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", - "Remove group" : "Noņemt grupu", "Current password" : "Pašreizējā parole", "New password" : "Jaunā parole", "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", @@ -152,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", @@ -181,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 …", @@ -223,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/mk.js b/apps/settings/l10n/mk.js index aa309864574..bb21a77250c 100644 --- a/apps/settings/l10n/mk.js +++ b/apps/settings/l10n/mk.js @@ -257,7 +257,6 @@ OC.L10N.register( "This is the final warning: Do you really want to enable encryption?" : "Ова е последно предупредување: Дали навистина сакате да овозможите енкрипција?", "Submit" : "Испрати", "Rename group" : "Преименувај група", - "Remove group" : "Отстрани група", "Current password" : "Моментална лозинка", "New password" : "Нова лозинка", "Change password" : "Промени лозинка", diff --git a/apps/settings/l10n/mk.json b/apps/settings/l10n/mk.json index cce2ea14925..8dc960d2b30 100644 --- a/apps/settings/l10n/mk.json +++ b/apps/settings/l10n/mk.json @@ -255,7 +255,6 @@ "This is the final warning: Do you really want to enable encryption?" : "Ова е последно предупредување: Дали навистина сакате да овозможите енкрипција?", "Submit" : "Испрати", "Rename group" : "Преименувај група", - "Remove group" : "Отстрани група", "Current password" : "Моментална лозинка", "New password" : "Нова лозинка", "Change password" : "Промени лозинка", diff --git a/apps/settings/l10n/nb.js b/apps/settings/l10n/nb.js index 1e37be5684a..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", @@ -525,12 +526,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Vær oppmerksom på at kryptering alltid øker filstørrelsen.", "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." : "Det er alltid bra å ta regelmessig sikkerhetskopi av dataene dine. Pass på å ta kopi av krypteringsnøklene sammen med dataene når kryptering er i bruk.", "This is the final warning: Do you really want to enable encryption?" : "Dette er siste advarsel: Vil du virkelig aktivere kryptering?", - "Failed to remove group \"{group}\"" : "Fjerning av gruppe \"{group}\" feilet", "Please confirm the group removal" : "Vennligst bekreft fjerning av gruppe", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du er i ferd med å fjerne gruppen \"{group}\". Kontoene vil IKKE bli slettet.", "Submit" : "Send inn", "Rename group" : "Gi nytt navn til gruppen", - "Remove group" : "Fjern gruppe", "Current password" : "Nåværende passord", "New password" : "Nytt passord", "Change password" : "Endre passord", diff --git a/apps/settings/l10n/nb.json b/apps/settings/l10n/nb.json index 25a29fda890..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", @@ -523,12 +524,9 @@ "Be aware that encryption always increases the file size." : "Vær oppmerksom på at kryptering alltid øker filstørrelsen.", "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." : "Det er alltid bra å ta regelmessig sikkerhetskopi av dataene dine. Pass på å ta kopi av krypteringsnøklene sammen med dataene når kryptering er i bruk.", "This is the final warning: Do you really want to enable encryption?" : "Dette er siste advarsel: Vil du virkelig aktivere kryptering?", - "Failed to remove group \"{group}\"" : "Fjerning av gruppe \"{group}\" feilet", "Please confirm the group removal" : "Vennligst bekreft fjerning av gruppe", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du er i ferd med å fjerne gruppen \"{group}\". Kontoene vil IKKE bli slettet.", "Submit" : "Send inn", "Rename group" : "Gi nytt navn til gruppen", - "Remove group" : "Fjern gruppe", "Current password" : "Nåværende passord", "New password" : "Nytt passord", "Change password" : "Endre passord", diff --git a/apps/settings/l10n/nl.js b/apps/settings/l10n/nl.js index ffbce1032ee..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", @@ -366,7 +367,6 @@ OC.L10N.register( "This is the final warning: Do you really want to enable encryption?" : "Dit is de laatste waarschuwing: Wil je versleuteling echt inschakelen?", "Submit" : "Verwerken", "Rename group" : "Hernoem groep", - "Remove group" : "Groep verwijderen", "Current password" : "Huidig wachtwoord", "New password" : "Nieuw wachtwoord", "Change password" : "Wijzig wachtwoord", diff --git a/apps/settings/l10n/nl.json b/apps/settings/l10n/nl.json index ce6766ae8ac..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", @@ -364,7 +365,6 @@ "This is the final warning: Do you really want to enable encryption?" : "Dit is de laatste waarschuwing: Wil je versleuteling echt inschakelen?", "Submit" : "Verwerken", "Rename group" : "Hernoem groep", - "Remove group" : "Groep verwijderen", "Current password" : "Huidig wachtwoord", "New password" : "Nieuw wachtwoord", "Change password" : "Wijzig wachtwoord", diff --git a/apps/settings/l10n/oc.js b/apps/settings/l10n/oc.js index 7bdf7ba6f5a..083d8703887 100644 --- a/apps/settings/l10n/oc.js +++ b/apps/settings/l10n/oc.js @@ -131,7 +131,6 @@ OC.L10N.register( "Enable encryption" : "Activar lo chiframent", "Submit" : "Transmetre", "Rename group" : "Renomenar lo grop", - "Remove group" : "Suprimir lo grop", "Current password" : "Senhal actual", "New password" : "Senhal novèl", "Change password" : "Cambiar de senhal", diff --git a/apps/settings/l10n/oc.json b/apps/settings/l10n/oc.json index 75b66caf91d..665d476d0a1 100644 --- a/apps/settings/l10n/oc.json +++ b/apps/settings/l10n/oc.json @@ -129,7 +129,6 @@ "Enable encryption" : "Activar lo chiframent", "Submit" : "Transmetre", "Rename group" : "Renomenar lo grop", - "Remove group" : "Suprimir lo grop", "Current password" : "Senhal actual", "New password" : "Senhal novèl", "Change password" : "Cambiar de senhal", diff --git a/apps/settings/l10n/pl.js b/apps/settings/l10n/pl.js index 16b3873aa06..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", @@ -471,11 +472,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Należy pamiętać, że szyfrowanie zawsze zwiększa rozmiar pliku.", "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." : "Zawsze dobrze jest regularnie wykonywać kopie zapasowe swoich danych. W przypadku szyfrowania upewnij się, aby kopie zapasowe kluczy szyfrowania były wraz z danymi.", "This is the final warning: Do you really want to enable encryption?" : "To ostatnie ostrzeżenie: Czy na pewno chcesz włączyć szyfrowanie?", - "Failed to remove group \"{group}\"" : "Nie udało się usunąć grupy \"{group}\"", "Please confirm the group removal" : "Potwierdź usunięcie grupy", "Submit" : "Wyślij", "Rename group" : "Zmień nazwę grupy", - "Remove group" : "Usuń grupę", "Current password" : "Bieżące hasło", "New password" : "Nowe hasło", "Change password" : "Zmień hasło", diff --git a/apps/settings/l10n/pl.json b/apps/settings/l10n/pl.json index b3e6d2134ed..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", @@ -469,11 +470,9 @@ "Be aware that encryption always increases the file size." : "Należy pamiętać, że szyfrowanie zawsze zwiększa rozmiar pliku.", "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." : "Zawsze dobrze jest regularnie wykonywać kopie zapasowe swoich danych. W przypadku szyfrowania upewnij się, aby kopie zapasowe kluczy szyfrowania były wraz z danymi.", "This is the final warning: Do you really want to enable encryption?" : "To ostatnie ostrzeżenie: Czy na pewno chcesz włączyć szyfrowanie?", - "Failed to remove group \"{group}\"" : "Nie udało się usunąć grupy \"{group}\"", "Please confirm the group removal" : "Potwierdź usunięcie grupy", "Submit" : "Wyślij", "Rename group" : "Zmień nazwę grupy", - "Remove group" : "Usuń grupę", "Current password" : "Bieżące hasło", "New password" : "Nowe hasło", "Change password" : "Zmień hasło", diff --git a/apps/settings/l10n/pt_BR.js b/apps/settings/l10n/pt_BR.js index a240ecf264d..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,12 +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 remove group \"{group}\"" : "Falha ao remover o grupo \"{group}\"", + "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 remove the group \"{group}\". The accounts will NOT be deleted." : "Você está prestes a remover o grupo \"{group}\". As contas NÃO serão excluídas.", + "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", - "Remove group" : "Excluir grupo", + "Delete group" : "Excluir grupo", "Current password" : "Senha atual", "New password" : "Nova senha", "Change password" : "Alterar senha", @@ -695,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 bfbc22ef691..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,12 +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 remove group \"{group}\"" : "Falha ao remover o grupo \"{group}\"", + "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 remove the group \"{group}\". The accounts will NOT be deleted." : "Você está prestes a remover o grupo \"{group}\". As contas NÃO serão excluídas.", + "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", - "Remove group" : "Excluir grupo", + "Delete group" : "Excluir grupo", "Current password" : "Senha atual", "New password" : "Nova senha", "Change password" : "Alterar senha", @@ -693,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 c96f5303673..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:", @@ -190,7 +191,6 @@ OC.L10N.register( "Encryption alone does not guarantee security of the system. Please see documentation for more information about how the encryption app works, and the supported use cases." : "Criptarea, ca unică variantă, nu garantează securitatea sistemului. Consultați documentația pentru mai multe informații despre cum funcționează aplicația de criptare și variantele de utilizare acceptate.", "This is the final warning: Do you really want to enable encryption?" : "Aceasta este avertizarea finală: Chiar vrei să activezi criptarea?", "Submit" : "Trimite", - "Remove group" : "Înlătură grupul", "Current password" : "Parola curentă", "New password" : "Noua parolă", "Change password" : "Schimbă parola", diff --git a/apps/settings/l10n/ro.json b/apps/settings/l10n/ro.json index 41bb1a3bb34..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:", @@ -188,7 +189,6 @@ "Encryption alone does not guarantee security of the system. Please see documentation for more information about how the encryption app works, and the supported use cases." : "Criptarea, ca unică variantă, nu garantează securitatea sistemului. Consultați documentația pentru mai multe informații despre cum funcționează aplicația de criptare și variantele de utilizare acceptate.", "This is the final warning: Do you really want to enable encryption?" : "Aceasta este avertizarea finală: Chiar vrei să activezi criptarea?", "Submit" : "Trimite", - "Remove group" : "Înlătură grupul", "Current password" : "Parola curentă", "New password" : "Noua parolă", "Change password" : "Schimbă parola", diff --git a/apps/settings/l10n/ru.js b/apps/settings/l10n/ru.js index edfef1dca16..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" : "Не удалось обновить параметры шифрования на стороне сервера", @@ -583,12 +584,9 @@ 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 remove group \"{group}\"" : "Не удалось удалить группу \"{group}\"", "Please confirm the group removal" : "Подтвердите удаление группы", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Группа «{group}» будет удалена. Это действие НЕ ПРИВОДИТ к удалению учётных записей, входящих в эту группу.", "Submit" : "Отправить ответ", "Rename group" : "Переименовать группу", - "Remove group" : "Удалить группу", "Current password" : "Текущий пароль", "New password" : "Новый пароль", "Change password" : "Сменить пароль", diff --git a/apps/settings/l10n/ru.json b/apps/settings/l10n/ru.json index 4dc2e4ee2e4..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" : "Не удалось обновить параметры шифрования на стороне сервера", @@ -581,12 +582,9 @@ "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 remove group \"{group}\"" : "Не удалось удалить группу \"{group}\"", "Please confirm the group removal" : "Подтвердите удаление группы", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Группа «{group}» будет удалена. Это действие НЕ ПРИВОДИТ к удалению учётных записей, входящих в эту группу.", "Submit" : "Отправить ответ", "Rename group" : "Переименовать группу", - "Remove group" : "Удалить группу", "Current password" : "Текущий пароль", "New password" : "Новый пароль", "Change password" : "Сменить пароль", diff --git a/apps/settings/l10n/sc.js b/apps/settings/l10n/sc.js index 20d56f8c4d2..d7a8345f3ae 100644 --- a/apps/settings/l10n/sc.js +++ b/apps/settings/l10n/sc.js @@ -225,7 +225,6 @@ 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." : "Benit semper a bene a creare còpias de seguresa regulares de is datos tuos, in casu de tzifradura assegura•ti de creare còpia de is craes de tzfradura paris cun is datos tuos.", "This is the final warning: Do you really want to enable encryption?" : "Custu est s'ùrtimu avisu : a beru boles ativare sa tzifradura?", "Submit" : "Imbia", - "Remove group" : "Boga·nche grupu", "Current password" : "Crae currente", "New password" : "Crae noa", "Change password" : "Càmbia crae", diff --git a/apps/settings/l10n/sc.json b/apps/settings/l10n/sc.json index 79d6a185d70..f1ec7c6b3ab 100644 --- a/apps/settings/l10n/sc.json +++ b/apps/settings/l10n/sc.json @@ -223,7 +223,6 @@ "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." : "Benit semper a bene a creare còpias de seguresa regulares de is datos tuos, in casu de tzifradura assegura•ti de creare còpia de is craes de tzfradura paris cun is datos tuos.", "This is the final warning: Do you really want to enable encryption?" : "Custu est s'ùrtimu avisu : a beru boles ativare sa tzifradura?", "Submit" : "Imbia", - "Remove group" : "Boga·nche grupu", "Current password" : "Crae currente", "New password" : "Crae noa", "Change password" : "Càmbia crae", diff --git a/apps/settings/l10n/sk.js b/apps/settings/l10n/sk.js index f68183a58f9..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", @@ -582,12 +583,9 @@ 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 dobré vytvárať pravidelné zálohy vašich dát, uistite sa, že v prípade šifrovania spolu s vašimi dátami zálohujete aj šifrovacie kľúče.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informácie o tom, ako ručne zašifrovať aj existujúce súbory, nájdete v dokumentácii pre administrátora.", "This is the final warning: Do you really want to enable encryption?" : "Toto je posledné varovanie: Vážne si prajete povoliť šifrovanie?", - "Failed to remove group \"{group}\"" : "Nepodarilo sa odstrániť skupinu \"{group}\"", "Please confirm the group removal" : "Prosím potvrďte vymazanie skupiny.", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Chystáte sa odstrániť skupinu \"{group}\". Používatelia NEBUDÚ vymazaní.", "Submit" : "Odoslať", "Rename group" : "Premenovať skupinu", - "Remove group" : "Odstrániť skupinu", "Current password" : "Aktuálne heslo", "New password" : "Nové heslo", "Change password" : "Zmeniť heslo", diff --git a/apps/settings/l10n/sk.json b/apps/settings/l10n/sk.json index 46d49eca927..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", @@ -580,12 +581,9 @@ "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 dobré vytvárať pravidelné zálohy vašich dát, uistite sa, že v prípade šifrovania spolu s vašimi dátami zálohujete aj šifrovacie kľúče.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Informácie o tom, ako ručne zašifrovať aj existujúce súbory, nájdete v dokumentácii pre administrátora.", "This is the final warning: Do you really want to enable encryption?" : "Toto je posledné varovanie: Vážne si prajete povoliť šifrovanie?", - "Failed to remove group \"{group}\"" : "Nepodarilo sa odstrániť skupinu \"{group}\"", "Please confirm the group removal" : "Prosím potvrďte vymazanie skupiny.", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Chystáte sa odstrániť skupinu \"{group}\". Používatelia NEBUDÚ vymazaní.", "Submit" : "Odoslať", "Rename group" : "Premenovať skupinu", - "Remove group" : "Odstrániť skupinu", "Current password" : "Aktuálne heslo", "New password" : "Nové heslo", "Change password" : "Zmeniť heslo", diff --git a/apps/settings/l10n/sl.js b/apps/settings/l10n/sl.js index d0cea080fff..5dd4503fa4f 100644 --- a/apps/settings/l10n/sl.js +++ b/apps/settings/l10n/sl.js @@ -420,12 +420,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : " Upoštevajte, da šifriranje poveča velikost datoteke.", "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." : "Priporočljivo je redno ustvarjati varnostne kopije podatkov, v primeru šifriranja pa varnostno kopirati tudi šifrirne ključe.", "This is the final warning: Do you really want to enable encryption?" : "To je zadnje opozorilo. Ali res želite omogočiti šifriranje?", - "Failed to remove group \"{group}\"" : "Odstranjevanje skupine »{group}« je spodlotelo", "Please confirm the group removal" : "Potrditi je treba skupinsko odstranjevanje", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Odstranili boste skupino »{group}«. Računi ne bodo izbrisani.", "Submit" : "Pošlji", "Rename group" : "Preimenuj skupino", - "Remove group" : "Odstrani skupino", "Current password" : "Trenutno geslo", "New password" : "Novo geslo", "Change password" : "Spremeni geslo", diff --git a/apps/settings/l10n/sl.json b/apps/settings/l10n/sl.json index 38dda68891f..1b8237ec98d 100644 --- a/apps/settings/l10n/sl.json +++ b/apps/settings/l10n/sl.json @@ -418,12 +418,9 @@ "Be aware that encryption always increases the file size." : " Upoštevajte, da šifriranje poveča velikost datoteke.", "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." : "Priporočljivo je redno ustvarjati varnostne kopije podatkov, v primeru šifriranja pa varnostno kopirati tudi šifrirne ključe.", "This is the final warning: Do you really want to enable encryption?" : "To je zadnje opozorilo. Ali res želite omogočiti šifriranje?", - "Failed to remove group \"{group}\"" : "Odstranjevanje skupine »{group}« je spodlotelo", "Please confirm the group removal" : "Potrditi je treba skupinsko odstranjevanje", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Odstranili boste skupino »{group}«. Računi ne bodo izbrisani.", "Submit" : "Pošlji", "Rename group" : "Preimenuj skupino", - "Remove group" : "Odstrani skupino", "Current password" : "Trenutno geslo", "New password" : "Novo geslo", "Change password" : "Spremeni geslo", diff --git a/apps/settings/l10n/sq.js b/apps/settings/l10n/sq.js index 37b0f878782..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", @@ -147,7 +148,6 @@ 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." : "Është gjithmonë ide e mirë të krijohen kopjeruajtje të rregullta të të dhënave tuaja, në rast fshehtëzimi sigurohuni që bëni kopjeruajtje të kyçeve të fshehtëzimit, tok me të dhënat tuaja.", "This is the final warning: Do you really want to enable encryption?" : "Ky është sinjalizimi përfundimtar: Doni vërtet të aktivizohet fshehtëzimi?", "Submit" : "Dërgo", - "Remove group" : "Hiq grupin", "Current password" : "Fjalëkalimi i tanishëm", "New password" : "Fjalëkalimi i ri", "Change password" : "Ndrysho fjalëkalimin", diff --git a/apps/settings/l10n/sq.json b/apps/settings/l10n/sq.json index d66ea79e142..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", @@ -145,7 +146,6 @@ "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." : "Është gjithmonë ide e mirë të krijohen kopjeruajtje të rregullta të të dhënave tuaja, në rast fshehtëzimi sigurohuni që bëni kopjeruajtje të kyçeve të fshehtëzimit, tok me të dhënat tuaja.", "This is the final warning: Do you really want to enable encryption?" : "Ky është sinjalizimi përfundimtar: Doni vërtet të aktivizohet fshehtëzimi?", "Submit" : "Dërgo", - "Remove group" : "Hiq grupin", "Current password" : "Fjalëkalimi i tanishëm", "New password" : "Fjalëkalimi i ri", "Change password" : "Ndrysho fjalëkalimin", diff --git a/apps/settings/l10n/sr.js b/apps/settings/l10n/sr.js index 4688fe65639..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,12 +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 remove group \"{group}\"" : "Није успело уклањање групе „{group}”", + "Failed to delete group \"{group}\"" : "Није успело брисање групе „{group}”", "Please confirm the group removal" : "Молимо вас да потврдите уклањање групе", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете уклонити групу „{group}”. Налози се НЕЋЕ обрисати.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете обрисати групу „{group}”. Налози се НЕЋЕ обрисати.", "Submit" : "Пошаљи", "Rename group" : "Промени име групе", - "Remove group" : "Уклони групу", + "Delete group" : "Брисање групе", "Current password" : "Тренутна лозинка", "New password" : "Нова лозинка", "Change password" : "Измени лозинку", diff --git a/apps/settings/l10n/sr.json b/apps/settings/l10n/sr.json index 1362a80aa90..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,12 +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 remove group \"{group}\"" : "Није успело уклањање групе „{group}”", + "Failed to delete group \"{group}\"" : "Није успело брисање групе „{group}”", "Please confirm the group removal" : "Молимо вас да потврдите уклањање групе", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете уклонити групу „{group}”. Налози се НЕЋЕ обрисати.", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "Управо ћете обрисати групу „{group}”. Налози се НЕЋЕ обрисати.", "Submit" : "Пошаљи", "Rename group" : "Промени име групе", - "Remove group" : "Уклони групу", + "Delete group" : "Брисање групе", "Current password" : "Тренутна лозинка", "New password" : "Нова лозинка", "Change password" : "Измени лозинку", diff --git a/apps/settings/l10n/sv.js b/apps/settings/l10n/sv.js index 3990547b1b4..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", @@ -419,12 +420,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "OBS! Observera att kryptering alltid ökar filstorleken", "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." : "Det är alltid en god ide att skapa regelbundna säkerhetskopior av din data, om kryptering används var säker på att även krypteringsnycklarna säkerhetskopieras tillsammans med din data.", "This is the final warning: Do you really want to enable encryption?" : "Detta är en slutgiltig varning: Vill du verkligen aktivera kryptering?", - "Failed to remove group \"{group}\"" : "Det gick inte att ta bort gruppen \"{group}\"", "Please confirm the group removal" : "Bekräfta borttagning av gruppen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du håller på att ta bort gruppen \"{group}\". Kontona kommer INTE att raderas.", "Submit" : "Skicka", "Rename group" : "Byt namn på grupp", - "Remove group" : "Ta bort grupp", "Current password" : "Nuvarande lösenord", "New password" : "Nytt lösenord", "Change password" : "Ändra lösenord", diff --git a/apps/settings/l10n/sv.json b/apps/settings/l10n/sv.json index 3ff1d9e5411..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", @@ -417,12 +418,9 @@ "Be aware that encryption always increases the file size." : "OBS! Observera att kryptering alltid ökar filstorleken", "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." : "Det är alltid en god ide att skapa regelbundna säkerhetskopior av din data, om kryptering används var säker på att även krypteringsnycklarna säkerhetskopieras tillsammans med din data.", "This is the final warning: Do you really want to enable encryption?" : "Detta är en slutgiltig varning: Vill du verkligen aktivera kryptering?", - "Failed to remove group \"{group}\"" : "Det gick inte att ta bort gruppen \"{group}\"", "Please confirm the group removal" : "Bekräfta borttagning av gruppen", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "Du håller på att ta bort gruppen \"{group}\". Kontona kommer INTE att raderas.", "Submit" : "Skicka", "Rename group" : "Byt namn på grupp", - "Remove group" : "Ta bort grupp", "Current password" : "Nuvarande lösenord", "New password" : "Nytt lösenord", "Change password" : "Ändra lösenord", diff --git a/apps/settings/l10n/th.js b/apps/settings/l10n/th.js index 5ca7e9484f7..b923d57537c 100644 --- a/apps/settings/l10n/th.js +++ b/apps/settings/l10n/th.js @@ -159,7 +159,6 @@ 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." : "การสำรองข้อมูลของคุณเป็นประจำเป็นเรื่องที่ดีเสมอ ในกรณีของการเข้ารหัส อย่าลืมสำรองคีย์เข้ารหัสพร้อมข้อมูลของคุณด้วย", "This is the final warning: Do you really want to enable encryption?" : "นี่คือการเตือนครั้งสุดท้าย: คุณต้องการเปิดใช้การเข้ารหัสจริง ๆ หรือไม่?", "Submit" : "ส่ง", - "Remove group" : "ลบกลุ่ม", "Current password" : "รหัสผ่านปัจจุบัน", "New password" : "รหัสผ่านใหม่", "Change password" : "เปลี่ยนรหัสผ่าน", diff --git a/apps/settings/l10n/th.json b/apps/settings/l10n/th.json index 9a141bb20c5..f20c0a8bcfc 100644 --- a/apps/settings/l10n/th.json +++ b/apps/settings/l10n/th.json @@ -157,7 +157,6 @@ "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." : "การสำรองข้อมูลของคุณเป็นประจำเป็นเรื่องที่ดีเสมอ ในกรณีของการเข้ารหัส อย่าลืมสำรองคีย์เข้ารหัสพร้อมข้อมูลของคุณด้วย", "This is the final warning: Do you really want to enable encryption?" : "นี่คือการเตือนครั้งสุดท้าย: คุณต้องการเปิดใช้การเข้ารหัสจริง ๆ หรือไม่?", "Submit" : "ส่ง", - "Remove group" : "ลบกลุ่ม", "Current password" : "รหัสผ่านปัจจุบัน", "New password" : "รหัสผ่านใหม่", "Change password" : "เปลี่ยนรหัสผ่าน", diff --git a/apps/settings/l10n/tr.js b/apps/settings/l10n/tr.js index 25bf05b19bb..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", @@ -583,12 +584,9 @@ 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." : "Verilerinizi düzenli yedekleyin ve şifreleme kullanıyorsanız şifreleme anahtarlarınızın da verilerinizle birlikte yedeklendiğinden emin olun.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Var olan dosyaların el ile nasıl şifreleneceğini öğrenmek için yönetici belgelerine bakın.", "This is the final warning: Do you really want to enable encryption?" : "Son uyarı: Şifrelemeyi kullanıma almak istiyor musunuz?", - "Failed to remove group \"{group}\"" : "\"{group}\" grubu silinemedi", "Please confirm the group removal" : "Grubu silme işlemini onaylayın", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "\"{group}\" grubunu silmek üzeresiniz. Hesaplar SİLİNMEYECEK.", "Submit" : "Gönder", "Rename group" : "Grubu yeniden adlandır", - "Remove group" : "Grubu sil", "Current password" : "Geçerli parola", "New password" : "Yeni parola", "Change password" : "Parola değiştir", diff --git a/apps/settings/l10n/tr.json b/apps/settings/l10n/tr.json index bddc44c3ccd..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", @@ -581,12 +582,9 @@ "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." : "Verilerinizi düzenli yedekleyin ve şifreleme kullanıyorsanız şifreleme anahtarlarınızın da verilerinizle birlikte yedeklendiğinden emin olun.", "Refer to the admin documentation on how to manually also encrypt existing files." : "Var olan dosyaların el ile nasıl şifreleneceğini öğrenmek için yönetici belgelerine bakın.", "This is the final warning: Do you really want to enable encryption?" : "Son uyarı: Şifrelemeyi kullanıma almak istiyor musunuz?", - "Failed to remove group \"{group}\"" : "\"{group}\" grubu silinemedi", "Please confirm the group removal" : "Grubu silme işlemini onaylayın", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "\"{group}\" grubunu silmek üzeresiniz. Hesaplar SİLİNMEYECEK.", "Submit" : "Gönder", "Rename group" : "Grubu yeniden adlandır", - "Remove group" : "Grubu sil", "Current password" : "Geçerli parola", "New password" : "Yeni parola", "Change password" : "Parola değiştir", diff --git a/apps/settings/l10n/ug.js b/apps/settings/l10n/ug.js index ab123b29b7d..e5150d0e730 100644 --- a/apps/settings/l10n/ug.js +++ b/apps/settings/l10n/ug.js @@ -518,12 +518,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "شۇنىڭغا دىققەت قىلىڭكى ، شىفىرلاش ھەمىشە ھۆججەتنىڭ چوڭ-كىچىكلىكىنى ئاشۇرىدۇ.", "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." : "شىفىرلانغان ئەھۋال ئاستىدا شىفىرلاش كۇنۇپكىسىنى سانلىق مەلۇماتلىرىڭىز بىلەن بىللە زاپاسلاشنى جەزملەشتۈرۈڭ.", "This is the final warning: Do you really want to enable encryption?" : "بۇ ئاخىرقى ئاگاھلاندۇرۇش: مەخپىيلەشتۈرۈشنى قوزغىتىشنى خالامسىز؟", - "Failed to remove group \"{group}\"" : "«{group}» گۇرۇپپىسىنى ئۆچۈرەلمىدى", "Please confirm the group removal" : "گۇرۇپپا ئۆچۈرۈلگەنلىكىنى جەزملەشتۈرۈڭ", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "سىز «{group}» گۇرۇپپىسىنى ئۆچۈرمەكچى بولۇۋاتىسىز. ھېساباتلار ئۆچۈرۈلمەيدۇ.", "Submit" : "يوللاڭ", "Rename group" : "گۇرۇپپىنىڭ نامىنى ئۆزگەرتىش", - "Remove group" : "گۇرۇپپىنى ئۆچۈرۈڭ", "Current password" : "نۆۋەتتىكى ئىم", "New password" : "يېڭى ئىم", "Change password" : "ئىم ئۆزگەرت", diff --git a/apps/settings/l10n/ug.json b/apps/settings/l10n/ug.json index 9e48ca73084..f773c4b3d6e 100644 --- a/apps/settings/l10n/ug.json +++ b/apps/settings/l10n/ug.json @@ -516,12 +516,9 @@ "Be aware that encryption always increases the file size." : "شۇنىڭغا دىققەت قىلىڭكى ، شىفىرلاش ھەمىشە ھۆججەتنىڭ چوڭ-كىچىكلىكىنى ئاشۇرىدۇ.", "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." : "شىفىرلانغان ئەھۋال ئاستىدا شىفىرلاش كۇنۇپكىسىنى سانلىق مەلۇماتلىرىڭىز بىلەن بىللە زاپاسلاشنى جەزملەشتۈرۈڭ.", "This is the final warning: Do you really want to enable encryption?" : "بۇ ئاخىرقى ئاگاھلاندۇرۇش: مەخپىيلەشتۈرۈشنى قوزغىتىشنى خالامسىز؟", - "Failed to remove group \"{group}\"" : "«{group}» گۇرۇپپىسىنى ئۆچۈرەلمىدى", "Please confirm the group removal" : "گۇرۇپپا ئۆچۈرۈلگەنلىكىنى جەزملەشتۈرۈڭ", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "سىز «{group}» گۇرۇپپىسىنى ئۆچۈرمەكچى بولۇۋاتىسىز. ھېساباتلار ئۆچۈرۈلمەيدۇ.", "Submit" : "يوللاڭ", "Rename group" : "گۇرۇپپىنىڭ نامىنى ئۆزگەرتىش", - "Remove group" : "گۇرۇپپىنى ئۆچۈرۈڭ", "Current password" : "نۆۋەتتىكى ئىم", "New password" : "يېڭى ئىم", "Change password" : "ئىم ئۆزگەرت", diff --git a/apps/settings/l10n/uk.js b/apps/settings/l10n/uk.js index f0680a777c2..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" : "Шифрування на сервері", @@ -473,11 +474,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Майте на увазі, що шифрування завжди збільшує розмір файлів.", "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." : "Завжди корисно регулярно створювати резервні копії ваших даних, у разі шифрування обов’язково зробіть резервну копію ключів шифрування разом із вашими даними.", "This is the final warning: Do you really want to enable encryption?" : "Це останнє попередження: Ви справді хочете ввімкнути шифрування?", - "Failed to remove group \"{group}\"" : "Не вдалося вилучити групу \"{group}\"", "Please confirm the group removal" : "Підтвердіть вилучення групи", "Submit" : "Продовжити", "Rename group" : "Перейменувати групу", - "Remove group" : "Вилучити групу", "Current password" : "Поточний пароль", "New password" : "Новий пароль", "Change password" : "Змінити пароль", diff --git a/apps/settings/l10n/uk.json b/apps/settings/l10n/uk.json index e5052a92171..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" : "Шифрування на сервері", @@ -471,11 +472,9 @@ "Be aware that encryption always increases the file size." : "Майте на увазі, що шифрування завжди збільшує розмір файлів.", "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." : "Завжди корисно регулярно створювати резервні копії ваших даних, у разі шифрування обов’язково зробіть резервну копію ключів шифрування разом із вашими даними.", "This is the final warning: Do you really want to enable encryption?" : "Це останнє попередження: Ви справді хочете ввімкнути шифрування?", - "Failed to remove group \"{group}\"" : "Не вдалося вилучити групу \"{group}\"", "Please confirm the group removal" : "Підтвердіть вилучення групи", "Submit" : "Продовжити", "Rename group" : "Перейменувати групу", - "Remove group" : "Вилучити групу", "Current password" : "Поточний пароль", "New password" : "Новий пароль", "Change password" : "Змінити пароль", diff --git a/apps/settings/l10n/vi.js b/apps/settings/l10n/vi.js index 4ad76354817..62c7d6a527d 100644 --- a/apps/settings/l10n/vi.js +++ b/apps/settings/l10n/vi.js @@ -268,11 +268,9 @@ OC.L10N.register( "Be aware that encryption always increases the file size." : "Xin lưu ý rằng mã hóa luôn làm tăng kích thước tệp.", "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." : "Việc tạo bản sao lưu thường xuyên cho dữ liệu của bạn luôn là điều tốt, trong trường hợp mã hóa, hãy đảm bảo sao lưu các khóa mã hóa cùng với dữ liệu của bạn.", "This is the final warning: Do you really want to enable encryption?" : "Cảnh báo lần cuối: Bạn có thực sự muốn kích hoạt tính năng mã hoá?", - "Failed to remove group \"{group}\"" : "Không xóa được nhóm \"{group}\"", "Please confirm the group removal" : "Vui lòng xác nhận việc xóa nhóm", "Submit" : "Gửi đi", "Rename group" : "Đổi tên nhóm", - "Remove group" : "Xóa nhóm", "Current password" : "Mật khẩu cũ", "New password" : "Mật khẩu mới", "Change password" : "Đổi mật khẩu", diff --git a/apps/settings/l10n/vi.json b/apps/settings/l10n/vi.json index 1d316d3369d..450ea619420 100644 --- a/apps/settings/l10n/vi.json +++ b/apps/settings/l10n/vi.json @@ -266,11 +266,9 @@ "Be aware that encryption always increases the file size." : "Xin lưu ý rằng mã hóa luôn làm tăng kích thước tệp.", "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." : "Việc tạo bản sao lưu thường xuyên cho dữ liệu của bạn luôn là điều tốt, trong trường hợp mã hóa, hãy đảm bảo sao lưu các khóa mã hóa cùng với dữ liệu của bạn.", "This is the final warning: Do you really want to enable encryption?" : "Cảnh báo lần cuối: Bạn có thực sự muốn kích hoạt tính năng mã hoá?", - "Failed to remove group \"{group}\"" : "Không xóa được nhóm \"{group}\"", "Please confirm the group removal" : "Vui lòng xác nhận việc xóa nhóm", "Submit" : "Gửi đi", "Rename group" : "Đổi tên nhóm", - "Remove group" : "Xóa nhóm", "Current password" : "Mật khẩu cũ", "New password" : "Mật khẩu mới", "Change password" : "Đổi mật khẩu", diff --git a/apps/settings/l10n/zh_CN.js b/apps/settings/l10n/zh_CN.js index 49c78044548..4d1cb4663a5 100644 --- a/apps/settings/l10n/zh_CN.js +++ b/apps/settings/l10n/zh_CN.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版本以便良好运行。请升级您的系统和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\" 被禁用,这会阻止检查临时目录中是否有足够的空间。", @@ -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,12 +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 remove group \"{group}\"" : "删除群组 “{group}” 失败", + "Failed to delete group \"{group}\"" : "无法删除群组“{group}”", "Please confirm the group removal" : "请确认移除该群组", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您即将删除组 \"{group}\" 。 这些帐户不会被删除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您即将删除群组“{group}”。账号将不会被删除。", "Submit" : "提交", "Rename group" : "重命名分组", - "Remove group" : "删除分组", + "Delete group" : "删除群组", "Current password" : "当前密码", "New password" : "新密码", "Change password" : "修改密码", diff --git a/apps/settings/l10n/zh_CN.json b/apps/settings/l10n/zh_CN.json index 2180ac68a8b..34ea100b230 100644 --- a/apps/settings/l10n/zh_CN.json +++ b/apps/settings/l10n/zh_CN.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版本以便良好运行。请升级您的系统和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\" 被禁用,这会阻止检查临时目录中是否有足够的空间。", @@ -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,12 +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 remove group \"{group}\"" : "删除群组 “{group}” 失败", + "Failed to delete group \"{group}\"" : "无法删除群组“{group}”", "Please confirm the group removal" : "请确认移除该群组", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您即将删除组 \"{group}\" 。 这些帐户不会被删除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您即将删除群组“{group}”。账号将不会被删除。", "Submit" : "提交", "Rename group" : "重命名分组", - "Remove group" : "删除分组", + "Delete group" : "删除群组", "Current password" : "当前密码", "New password" : "新密码", "Change password" : "修改密码", diff --git a/apps/settings/l10n/zh_HK.js b/apps/settings/l10n/zh_HK.js index b6c78f5a94c..ab2f321716b 100644 --- a/apps/settings/l10n/zh_HK.js +++ b/apps/settings/l10n/zh_HK.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分鐘才被提取。考慮設置一個工作人員在背景中處理任務。"], "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,12 +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 remove group \"{group}\"" : "移除群組「{group}」失敗", + "Failed to delete group \"{group}\"" : "無法刪除群組「{group}」", "Please confirm the group removal" : "請確認移除群組", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您將要移除群組「{group}」。帳戶將不會被刪除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳戶將不會被刪除。", "Submit" : "遞交", "Rename group" : "重新命名群組", - "Remove group" : "移除群組", + "Delete group" : "刪除群組", "Current password" : "目前密碼", "New password" : "新密碼", "Change password" : "更改密碼", diff --git a/apps/settings/l10n/zh_HK.json b/apps/settings/l10n/zh_HK.json index bb9025948ea..6f4a48888ef 100644 --- a/apps/settings/l10n/zh_HK.json +++ b/apps/settings/l10n/zh_HK.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分鐘才被提取。考慮設置一個工作人員在背景中處理任務。"], "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,12 +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 remove group \"{group}\"" : "移除群組「{group}」失敗", + "Failed to delete group \"{group}\"" : "無法刪除群組「{group}」", "Please confirm the group removal" : "請確認移除群組", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您將要移除群組「{group}」。帳戶將不會被刪除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳戶將不會被刪除。", "Submit" : "遞交", "Rename group" : "重新命名群組", - "Remove group" : "移除群組", + "Delete group" : "刪除群組", "Current password" : "目前密碼", "New password" : "新密碼", "Change password" : "更改密碼", diff --git a/apps/settings/l10n/zh_TW.js b/apps/settings/l10n/zh_TW.js index 170f5b602d7..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,12 +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 remove group \"{group}\"" : "移除群組「{group}」失敗", + "Failed to delete group \"{group}\"" : "刪除群組「{group}」失敗", "Please confirm the group removal" : "請確認移除群組", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您將要移除群組「{group}」。帳號將不會被刪除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳號將不會被刪除。", "Submit" : "提交", "Rename group" : "重新命名群組", - "Remove 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 88fd907b300..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,12 +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 remove group \"{group}\"" : "移除群組「{group}」失敗", + "Failed to delete group \"{group}\"" : "刪除群組「{group}」失敗", "Please confirm the group removal" : "請確認移除群組", - "You are about to remove the group \"{group}\". The accounts will NOT be deleted." : "您將要移除群組「{group}」。帳號將不會被刪除。", + "You are about to delete the group \"{group}\". The accounts will NOT be deleted." : "您將要刪除群組「{group}」。帳號將不會被刪除。", "Submit" : "提交", "Rename group" : "重新命名群組", - "Remove 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/lib/SetupChecks/TaskProcessingPickupSpeed.php b/apps/settings/lib/SetupChecks/TaskProcessingPickupSpeed.php index 8e6448f91d4..83168ac0f3e 100644 --- a/apps/settings/lib/SetupChecks/TaskProcessingPickupSpeed.php +++ b/apps/settings/lib/SetupChecks/TaskProcessingPickupSpeed.php @@ -38,7 +38,7 @@ class TaskProcessingPickupSpeed implements ISetupCheck { $tasks = $this->taskProcessingManager->getTasks(userId: '', scheduleAfter: $this->timeFactory->now()->getTimestamp() - 60 * 60 * self::TIME_SPAN); // userId: '' means no filter, whereas null would mean guest $taskCount = count($tasks); if ($taskCount === 0) { - return SetupResult::success($this->l10n->t('No scheduled tasks in the last {hours} hours.', ['hours' => self::TIME_SPAN])); + return SetupResult::success($this->l10n->n('No scheduled tasks in the last %n hour.', 'No scheduled tasks in the last %n hours.', self::TIME_SPAN)); } $slowCount = 0; foreach ($tasks as $task) { @@ -55,9 +55,9 @@ class TaskProcessingPickupSpeed implements ISetupCheck { } if ($slowCount / $taskCount < self::MAX_SLOW_PERCENTAGE) { - return SetupResult::success($this->l10n->t('Task pickup speed is ok in the last {hours} hours.', ['hours' => self::TIME_SPAN])); + return SetupResult::success($this->l10n->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.', self::TIME_SPAN)); } else { - return SetupResult::warning($this->l10n->t('Task pickup speed is slow in the last {hours} hours. Many tasks took longer than 4 min to get picked up. Consider setting up a worker to process tasks in the background.', ['hours' => self::TIME_SPAN]), 'https://docs.nextcloud.com/server/latest/admin_manual/ai/overview.html#improve-ai-task-pickup-speed'); + return SetupResult::warning($this->l10n->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.', self::TIME_SPAN), 'https://docs.nextcloud.com/server/latest/admin_manual/ai/overview.html#improve-ai-task-pickup-speed'); } } } 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/components/GroupListItem.vue b/apps/settings/src/components/GroupListItem.vue index 65d46136ec1..76088fa74db 100644 --- a/apps/settings/src/components/GroupListItem.vue +++ b/apps/settings/src/components/GroupListItem.vue @@ -13,7 +13,7 @@ </h2> <NcNoteCard type="warning" show-alert> - {{ t('settings', 'You are about to remove the group "{group}". The accounts will NOT be deleted.', { group: name }) }} + {{ t('settings', 'You are about to delete the group "{group}". The accounts will NOT be deleted.', { group: name }) }} </NcNoteCard> <div class="modal__button-row"> <NcButton type="secondary" @@ -62,7 +62,7 @@ <template #icon> <Delete :size="20" /> </template> - {{ t('settings', 'Remove group') }} + {{ t('settings', 'Delete group') }} </NcActionButton> </template> </NcAppNavigationItem> @@ -179,7 +179,7 @@ export default { await this.$store.dispatch('removeGroup', this.id) this.showRemoveGroupModal = false } catch (error) { - showError(t('settings', 'Failed to remove group "{group}"', { group: this.name })) + showError(t('settings', 'Failed to delete group "{group}"', { group: this.name })) } }, }, diff --git a/apps/settings/src/components/PersonalInfo/shared/AccountPropertySection.vue b/apps/settings/src/components/PersonalInfo/shared/AccountPropertySection.vue index 8cdde6b7d9a..d039641ec72 100644 --- a/apps/settings/src/components/PersonalInfo/shared/AccountPropertySection.vue +++ b/apps/settings/src/components/PersonalInfo/shared/AccountPropertySection.vue @@ -155,6 +155,7 @@ export default { methods: { async updateProperty(value) { try { + this.hasError = false const responseData = await savePrimaryAccountProperty( this.name, value, @@ -180,10 +181,8 @@ export default { this.isSuccess = true setTimeout(() => { this.isSuccess = false }, 2000) } else { - this.$emit('update:value', this.initialValue) handleError(error, errorMessage) this.hasError = true - setTimeout(() => { this.hasError = false }, 2000) } }, }, 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/sharebymail/l10n/fa.js b/apps/sharebymail/l10n/fa.js index aabadad2fb0..e9328c5b102 100644 --- a/apps/sharebymail/l10n/fa.js +++ b/apps/sharebymail/l10n/fa.js @@ -14,12 +14,18 @@ OC.L10N.register( "Password to access {file} was sent to {email}" : "رمز عبور برای دسترسی به {file} به {email} ارسال شد", "Password to access {file} was sent to you" : "رمز ورود برای دسترسی به {file} برای شما ارسال شد", "Share by mail" : "اشتراک از طریق پست", + "Sharing %1$s failed, because this item is already shared with the account %2$s" : "اشتراکگذاری %1$s ناموفق بود، زیرا این مورد قبلاً با حساب %2$s به اشتراک گذاشته شده است", "We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "ما نمی توانیم رمز عبور ایجاد شده به صورت خودکار را برای شما ارسال کنیم. لطفاً یک آدرس ایمیل معتبر در تنظیمات شخصی خود تنظیم کنید و دوباره امتحان کنید.", "Failed to send share by email. Got an invalid email address" : "اشتراک از طریق ایمیل ارسال نشد. یک آدرس ایمیل نامعتبر دریافت کردم", "Failed to send share by email" : "ارسال اشتراک از طریق ایمیل انجام نشد", + "%1$s shared %2$s with you" : "%1$s %2$s را با شما به اشتراک گذاشت", + "Open %s" : "باز کردن %s", "%1$s via %2$s" : "%1$s از طریق %2$s", "It is protected with the following password:" : "با رمز عبور زیر محافظت می شود:", "This password will expire at %s" : "این رمز عبور در تاریخ منقضی می شود %s", + "%1$s shared %2$s with you and wants to add:" : "%1$s %2$s را با شما به اشتراک گذاشت و میخواهد اضافه کند:", + "%1$s shared %2$s with you and wants to add" : "%1$s %2$s را با شما به اشتراک گذاشت و میخواهد اضافه کند", + "%s added a note to a file shared with you" : "%s یک یادداشت به فایلی که با شما به اشتراک گذاشته شده است اضافه کرد", "This is the password:" : "این رمز عبور است:", "You can choose a different password at any time in the share dialog." : "می توانید در هر زمان و در گفتگوی اشتراک ، رمزعبور دیگری را انتخاب کنید.", "Could not find share" : "اشتراک یافت نشد", diff --git a/apps/sharebymail/l10n/fa.json b/apps/sharebymail/l10n/fa.json index e585745bdb2..4459f308770 100644 --- a/apps/sharebymail/l10n/fa.json +++ b/apps/sharebymail/l10n/fa.json @@ -12,12 +12,18 @@ "Password to access {file} was sent to {email}" : "رمز عبور برای دسترسی به {file} به {email} ارسال شد", "Password to access {file} was sent to you" : "رمز ورود برای دسترسی به {file} برای شما ارسال شد", "Share by mail" : "اشتراک از طریق پست", + "Sharing %1$s failed, because this item is already shared with the account %2$s" : "اشتراکگذاری %1$s ناموفق بود، زیرا این مورد قبلاً با حساب %2$s به اشتراک گذاشته شده است", "We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "ما نمی توانیم رمز عبور ایجاد شده به صورت خودکار را برای شما ارسال کنیم. لطفاً یک آدرس ایمیل معتبر در تنظیمات شخصی خود تنظیم کنید و دوباره امتحان کنید.", "Failed to send share by email. Got an invalid email address" : "اشتراک از طریق ایمیل ارسال نشد. یک آدرس ایمیل نامعتبر دریافت کردم", "Failed to send share by email" : "ارسال اشتراک از طریق ایمیل انجام نشد", + "%1$s shared %2$s with you" : "%1$s %2$s را با شما به اشتراک گذاشت", + "Open %s" : "باز کردن %s", "%1$s via %2$s" : "%1$s از طریق %2$s", "It is protected with the following password:" : "با رمز عبور زیر محافظت می شود:", "This password will expire at %s" : "این رمز عبور در تاریخ منقضی می شود %s", + "%1$s shared %2$s with you and wants to add:" : "%1$s %2$s را با شما به اشتراک گذاشت و میخواهد اضافه کند:", + "%1$s shared %2$s with you and wants to add" : "%1$s %2$s را با شما به اشتراک گذاشت و میخواهد اضافه کند", + "%s added a note to a file shared with you" : "%s یک یادداشت به فایلی که با شما به اشتراک گذاشته شده است اضافه کرد", "This is the password:" : "این رمز عبور است:", "You can choose a different password at any time in the share dialog." : "می توانید در هر زمان و در گفتگوی اشتراک ، رمزعبور دیگری را انتخاب کنید.", "Could not find share" : "اشتراک یافت نشد", 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/systemtags/src/components/SystemTagsCreationControl.vue b/apps/systemtags/src/components/SystemTagsCreationControl.vue index 1b69983839f..2133387ec06 100644 --- a/apps/systemtags/src/components/SystemTagsCreationControl.vue +++ b/apps/systemtags/src/components/SystemTagsCreationControl.vue @@ -6,17 +6,17 @@ <template> <div id="system-tags-creation-control"> <h4 class="inlineblock"> - {{ t('settings', 'System tag management') }} + {{ t('systemtags', 'System tag management') }} </h4> <p class="settings-hint"> - {{ t('settings', 'If enabled, only administrators can create and edit tags. Accounts can still assign and remove them from files.') }} + {{ t('systemtags', 'If enabled, only administrators can create and edit tags. Accounts can still assign and remove them from files.') }} </p> <NcCheckboxRadioSwitch type="switch" :checked.sync="systemTagsCreationRestrictedToAdmin" @update:checked="updateSystemTagsDefault"> - {{ t('settings', 'Restrict tag creation and editing to administrators') }} + {{ t('systemtags', 'Restrict tag creation and editing to administrators') }} </NcCheckboxRadioSwitch> </div> </template> @@ -47,7 +47,7 @@ export default { data() { return { // By default, system tags creation is not restricted to admins - systemTagsCreationRestrictedToAdmin: loadState('settings', 'restrictSystemTagsCreationToAdmin', false), + systemTagsCreationRestrictedToAdmin: loadState('systemtags', 'restrictSystemTagsCreationToAdmin', false), } }, methods: { @@ -61,7 +61,7 @@ export default { }) } catch (e) { this.handleResponse({ - errorMessage: t('settings', 'Unable to update setting'), + errorMessage: t('systemtags', 'Unable to update setting'), error: e, }) } @@ -71,8 +71,8 @@ export default { if (status === 'ok') { this.systemTagsCreationRestrictedToAdmin = isRestricted showSuccess(isRestricted - ? t('settings', 'System tag creation is now restricted to administrators') - : t('settings', 'System tag creation is now allowed for everybody'), + ? t('systemtags', 'System tag creation is now restricted to administrators') + : t('systemtags', 'System tag creation is now allowed for everybody'), ) return } diff --git a/apps/systemtags/src/services/HotKeysService.spec.ts b/apps/systemtags/src/services/HotKeysService.spec.ts index 2e329444f54..92d9f56f56d 100644 --- a/apps/systemtags/src/services/HotKeysService.spec.ts +++ b/apps/systemtags/src/services/HotKeysService.spec.ts @@ -42,15 +42,24 @@ describe('HotKeysService testing', () => { }) it('Pressing t should open the tag management dialog', () => { - window.dispatchEvent(new KeyboardEvent('keydown', { key: 't', code: 'KeyT' })) + dispatchEvent({ key: 't', code: 'KeyT' }) // Modifier keys should not trigger the action - window.dispatchEvent(new KeyboardEvent('keydown', { key: 't', code: 'KeyT', ctrlKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 't', code: 'KeyT', altKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 't', code: 'KeyT', shiftKey: true })) - window.dispatchEvent(new KeyboardEvent('keydown', { key: 't', code: 'KeyT', metaKey: true })) + dispatchEvent({ key: 't', code: 'KeyT', ctrlKey: true }) + dispatchEvent({ key: 't', code: 'KeyT', altKey: true }) + dispatchEvent({ key: 't', code: 'KeyT', shiftKey: true }) + dispatchEvent({ key: 't', code: 'KeyT', metaKey: true }) expect(bulkSystemTagsAction.enabled).toHaveReturnedWith(true) expect(bulkSystemTagsAction.exec).toHaveBeenCalledOnce() }) }) + +/** + * Helper to dispatch the correct event. + * + * @param init - KeyboardEvent options + */ +function dispatchEvent(init: KeyboardEventInit) { + document.body.dispatchEvent(new KeyboardEvent('keydown', { ...init, bubbles: true })) +} 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/theming/openapi.json b/apps/theming/openapi.json index 2518f4acb73..26f5e7b8120 100644 --- a/apps/theming/openapi.json +++ b/apps/theming/openapi.json @@ -701,6 +701,7 @@ "color": { "type": "string", "nullable": true, + "default": null, "description": "Color for the background" } } 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/updatenotification/openapi.json b/apps/updatenotification/openapi.json index 969dfc7cfaa..f635b0839ef 100644 --- a/apps/updatenotification/openapi.json +++ b/apps/updatenotification/openapi.json @@ -248,7 +248,8 @@ "description": "The version to search the changelog entry for (defaults to the latest installed)", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { diff --git a/apps/user_ldap/css/renewPassword.css b/apps/user_ldap/css/renewPassword.css index 0fe8c4d183e..8acd97254fa 100644 --- a/apps/user_ldap/css/renewPassword.css +++ b/apps/user_ldap/css/renewPassword.css @@ -33,7 +33,6 @@ letter-spacing:normal; line-break:auto; line-height:1.6; - text-align:left; text-align:start; text-decoration:none; text-shadow:none; diff --git a/apps/user_ldap/css/settings.css b/apps/user_ldap/css/settings.css index 3aa9b2a168e..a1048031fa2 100644 --- a/apps/user_ldap/css/settings.css +++ b/apps/user_ldap/css/settings.css @@ -202,10 +202,12 @@ select[multiple=multiple] + button { width: 16px; vertical-align: text-bottom; } + .ldap_config_state_indicator_sign.success { background: #37ce02; border-radius: 8px; } + .ldap_config_state_indicator_sign.error { background: #ce3702; } diff --git a/apps/user_ldap/l10n/et_EE.js b/apps/user_ldap/l10n/et_EE.js index 92cb8c11e68..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", @@ -60,7 +70,7 @@ OC.L10N.register( "Only from these groups:" : "Ainult neist gruppidest:", "Search groups" : "Otsi gruppe", "Available groups" : "Saadaolevad grupid", - "Selected groups" : "Validut grupid", + "Selected groups" : "Valitud grupid", "Edit LDAP Query" : "Muuda LDAP päringut", "LDAP Filter:" : "LDAP filter:", "The filter specifies which LDAP groups shall have access to the %s instance." : "Filter määrab millised LDAP grupid saavad ligipääsu sellele %s instantsile.", @@ -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 47aba4f4b3d..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", @@ -58,7 +68,7 @@ "Only from these groups:" : "Ainult neist gruppidest:", "Search groups" : "Otsi gruppe", "Available groups" : "Saadaolevad grupid", - "Selected groups" : "Validut grupid", + "Selected groups" : "Valitud grupid", "Edit LDAP Query" : "Muuda LDAP päringut", "LDAP Filter:" : "LDAP filter:", "The filter specifies which LDAP groups shall have access to the %s instance." : "Filter määrab millised LDAP grupid saavad ligipääsu sellele %s instantsile.", @@ -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; + } } diff --git a/apps/user_status/openapi.json b/apps/user_status/openapi.json index a0d30693e37..65d9af59fef 100644 --- a/apps/user_status/openapi.json +++ b/apps/user_status/openapi.json @@ -427,7 +427,8 @@ "schema": { "type": "integer", "format": "int64", - "nullable": true + "nullable": true, + "default": null } }, { @@ -438,6 +439,7 @@ "type": "integer", "format": "int64", "nullable": true, + "default": null, "minimum": 0 } }, diff --git a/apps/webhook_listeners/l10n/et_EE.js b/apps/webhook_listeners/l10n/et_EE.js new file mode 100644 index 00000000000..39fc925dfc4 --- /dev/null +++ b/apps/webhook_listeners/l10n/et_EE.js @@ -0,0 +1,7 @@ +OC.L10N.register( + "webhook_listeners", + { + "Webhooks" : "Veebihaagid", + "Nextcloud webhook support" : "Veebihaakide (webhook) tugi Nextcloudi jaoks" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/apps/webhook_listeners/l10n/et_EE.json b/apps/webhook_listeners/l10n/et_EE.json new file mode 100644 index 00000000000..62ac64b0765 --- /dev/null +++ b/apps/webhook_listeners/l10n/et_EE.json @@ -0,0 +1,5 @@ +{ "translations": { + "Webhooks" : "Veebihaagid", + "Nextcloud webhook support" : "Veebihaakide (webhook) tugi Nextcloudi jaoks" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +}
\ No newline at end of file diff --git a/apps/webhook_listeners/openapi.json b/apps/webhook_listeners/openapi.json index 9e7acc5c6f8..84610d204bb 100644 --- a/apps/webhook_listeners/openapi.json +++ b/apps/webhook_listeners/openapi.json @@ -121,7 +121,8 @@ "description": "The callback URI to filter by", "schema": { "type": "string", - "nullable": true + "nullable": true, + "default": null } }, { @@ -255,6 +256,13 @@ }, "parameters": [ { + "name": "EX-APP-ID", + "in": "header", + "schema": { + "type": "string" + } + }, + { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", @@ -548,6 +556,13 @@ } }, { + "name": "EX-APP-ID", + "in": "header", + "schema": { + "type": "string" + } + }, + { "name": "OCS-APIRequest", "in": "header", "description": "Required to be true for the API request to pass", |