diff --git a/Corona-Warn-App/src/main/AndroidManifest.xml b/Corona-Warn-App/src/main/AndroidManifest.xml index e058ffe9572563a9836bc3a95bbd28d58ef59c67..f7f4cc3eef5107e5ab6ff333ecde6950b9bc5615 100644 --- a/Corona-Warn-App/src/main/AndroidManifest.xml +++ b/Corona-Warn-App/src/main/AndroidManifest.xml @@ -81,6 +81,7 @@ android:exported="false" android:screenOrientation="portrait" android:launchMode="singleTop" + android:label="@string/empty_string_to_avoid_toolbar_announcement" android:theme="@style/AppTheme.ContactDiary" android:windowSoftInputMode="adjustResize" /> diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt index 82b5775e5401e38f438399d8944f5e08b2417021..8f7cd9cc526fe839e26f3ecf37bb20e58fb897c0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/day/ContactDiaryDayViewModel.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.lifecycle.asLiveData import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject +import de.rki.coronawarnapp.R import de.rki.coronawarnapp.contactdiary.ui.day.tabs.ContactDiaryDayTab import de.rki.coronawarnapp.contactdiary.util.getLocale import de.rki.coronawarnapp.contactdiary.util.toFormattedDay @@ -27,7 +28,8 @@ class ContactDiaryDayViewModel @AssistedInject constructor( val uiState = displayedDay.map { day -> UIState( dayText = { day.toFormattedDay(it.getLocale()) }, - dayTextContentDescription = { day.toFormattedDayForAccessibility(it.getLocale()) }) + dayTextContentDescription = { day.toFormattedDayForAccessibility(it.getLocale()) + + it.getString(R.string.accessibility_day_view_header) }) }.asLiveData() fun onCreateButtonClicked(activeTab: ContactDiaryDayTab) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculation.kt index a78f20525bdfb4c195b4115250264cbb3c27e248..e018b011f886fe150059fd3f236a7b0b41083c30 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculation.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculation.kt @@ -1,15 +1,17 @@ package de.rki.coronawarnapp.ui.calendar -import dagger.Reusable +import android.content.Context +import de.rki.coronawarnapp.contactdiary.util.getLocale import org.joda.time.DateTime import org.joda.time.DateTimeZone import org.joda.time.Instant import org.joda.time.LocalDate import java.util.Locale -import javax.inject.Inject -@Reusable -class CalendarCalculation @Inject constructor() { +class CalendarCalculation constructor(private val context: Context) { + + private val locale: Locale + get() = context.getLocale() /** * Get month text view text @@ -42,19 +44,19 @@ class CalendarCalculation @Inject constructor() { fun getMonthText(firstDate: LocalDate, lastDate: LocalDate): String { val monthText = StringBuilder() // Append first date month as it would always be displayed - monthText.append(firstDate.monthOfYear().getAsText(Locale.getDefault())) + monthText.append(firstDate.monthOfYear().getAsText(locale)) if (firstDate.monthOfYear() != lastDate.monthOfYear()) { // Different month if (firstDate.year() == lastDate.year()) { // Same year (Case 1) monthText.append(" - ") - .append(lastDate.monthOfYear().getAsText(Locale.getDefault())) + .append(lastDate.monthOfYear().getAsText(locale)) } else { // Different year (Case 2) monthText.append(" ") .append(firstDate.year().get()) .append(" - ") - .append(lastDate.monthOfYear().getAsText(Locale.getDefault())) + .append(lastDate.monthOfYear().getAsText(locale)) } // Append last date year monthText.append(" ") diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarView.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarView.kt index f953c70c0c86c625a6dde1d62cd312ad5b2374b2..38174e548220c19df0580e863b950cc3bdfb430d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarView.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/calendar/CalendarView.kt @@ -122,7 +122,7 @@ class CalendarView @JvmOverloads constructor( } // Calculate dates to display - days.addAll(CalendarCalculation().getDates()) + days.addAll(CalendarCalculation(context).getDates()) // Set calendar adapter as adapter for recycler view adapter = CalendarAdapter(onItemClickListener) @@ -190,6 +190,6 @@ class CalendarView @JvmOverloads constructor( val firstDate = days.first().date val lastDate = days.last().date - monthTextView.text = CalendarCalculation().getMonthText(firstDate, lastDate) + monthTextView.text = CalendarCalculation(context).getMonthText(firstDate, lastDate) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/backgroundpriority/SettingsBackgroundPriorityFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/backgroundpriority/SettingsBackgroundPriorityFragment.kt index 8cd7d7b1a7da2e1aab0f5d309621bef34567021d..4edfee1a4a158af5c9032ac4a3fc90680691df13 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/backgroundpriority/SettingsBackgroundPriorityFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/backgroundpriority/SettingsBackgroundPriorityFragment.kt @@ -38,7 +38,7 @@ class SettingsBackgroundPriorityFragment : Fragment(R.layout.fragment_settings_b override fun onResume() { super.onResume() - binding.settingsBackgroundPriorityContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) + binding.settingsBackgroundPriorityContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED) } private fun setButtonOnClickListener() { diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml index 215a15ab12efdac8ebf93df66bf8cf01de2c6f60..b00a8bde2e668726e502cf044d516c850689968b 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_day_fragment.xml @@ -15,6 +15,7 @@ android:layout_height="wrap_content" android:background="@drawable/contact_diary_background" android:elevation="@dimen/elevation_weak" + android:focusable="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml b/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml index d3b162defdbd627c69d4d58f82c440a16d621255..cb4c410114df6878889a7a376f6a81b06d299e19 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml @@ -12,7 +12,6 @@ android:id="@+id/settings_background_priority_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:contentDescription="@string/settings_background_priority_title" android:focusable="true"> <include @@ -20,6 +19,8 @@ layout="@layout/include_header" android:layout_width="0dp" android:layout_height="wrap_content" + android:contentDescription="@string/settings_background_priority_title" + android:focusable="true" app:icon="@{@drawable/ic_back}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml index 91c98f4974dcc33fef59ff0ca27b4045bffde0ac..819bdd358ae9416838d697c52dcf772621a1d2c5 100644 --- a/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/contact_diary_strings.xml @@ -111,22 +111,24 @@ <string name="contact_diary_delete_person_title">"Wollen Sie wirklich diese Person entfernen?"</string> <!-- XTXT: location (description for screen readers) --> - <string name="accessibility_location">Ort %s</string> + <string name="accessibility_location">"Ort %s"</string> <!-- XTXT: person (description for screen readers) --> - <string name="accessibility_person">Person %s</string> + <string name="accessibility_person">"Person %s"</string> <!-- XTXT: location is not selected (description for screen readers) --> - <string name="accessibility_location_unselected">Ort %s ist nicht ausgewählt</string> + <string name="accessibility_location_unselected">"Ort %s ist nicht ausgewählt"</string> <!-- XTXT: person is not selected (description for screen readers) --> - <string name="accessibility_person_unselected">Person %s ist nicht ausgewählt</string> + <string name="accessibility_person_unselected">"Person %s ist nicht ausgewählt"</string> <!-- XTXT: location is selected (description for screen readers) --> - <string name="accessibility_location_selected">Ort %s ist ausgewählt</string> + <string name="accessibility_location_selected">"Ort %s ist ausgewählt"</string> <!-- XTXT: person is selected (description for screen readers) --> - <string name="accessibility_person_selected">Person %s ist ausgewählt</string> + <string name="accessibility_person_selected">"Person %s ist ausgewählt"</string> + <!-- XTXT: Day View headline (description for screen readers) --> + <string name="accessibility_day_view_header">"Tagesansicht"</string> <!-- XTXT: Select (description for screen readers) --> - <string name="accessibility_action_select">Auswählen</string> + <string name="accessibility_action_select">"Auswählen"</string> <!-- XTXT: Deselect (description for screen readers) --> - <string name="accessibility_action_deselect">Auswahl aufheben</string> + <string name="accessibility_action_deselect">"Auswahl aufheben"</string> <!-- XTXT: Edit (description for screen readers) --> - <string name="accessibility_edit">Bearbeiten</string> + <string name="accessibility_edit">"Bearbeiten"</string> </resources> diff --git a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml index 76e54bbec47b6ec1f27e1d42f47059cf7ac2ce99..6671b37dd501cb58321163fd7089d9461e146e3a 100644 --- a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml @@ -129,6 +129,8 @@ <string name="accessibility_location_selected">"Place %s is selected"</string> <!-- XTXT: person is selected (description for screen readers) --> <string name="accessibility_person_selected">"Person %s is selected"</string> + <!-- XTXT: Day View headline (description for screen readers) --> + <string name="accessibility_day_view_header"></string> <!-- XTXT: Select (description for screen readers) --> <string name="accessibility_action_select">"Select"</string> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index 9ecd4f74af9d556d91ea5ce0a790d66f3d0ba1d2..e5f241e1362bb60fa455eb3758d205dc6ed5736c 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -1507,4 +1507,8 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Cancel"</string> + <!-- XTXT: Empty label for an activity --> + <string name="empty_string_to_avoid_toolbar_announcement" translatable="false">""</string> + + </resources> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculationTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculationTest.kt index ad8e47590f0c812119283aa3f66442855d432736..a77e3a903406084c1f9ed18f8157cedc1b1108a1 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculationTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/calendar/CalendarCalculationTest.kt @@ -1,21 +1,53 @@ package de.rki.coronawarnapp.ui.calendar +import android.content.Context +import android.content.res.Configuration +import android.content.res.Resources import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.impl.annotations.MockK import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat -import org.junit.Test +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import testhelpers.BaseTest +import java.util.Locale -class CalendarCalculationTest { +class CalendarCalculationTest : BaseTest() { + + @MockK lateinit var context: Context + @MockK lateinit var resources: Resources + @MockK lateinit var configuration: Configuration private var pattern = "dd.MM.yyyy" private val formatter = DateTimeFormat.forPattern(pattern) + @BeforeEach + fun setUp() { + MockKAnnotations.init(this) + + every { context.resources } returns resources + every { resources.configuration } returns Configuration().apply { + locale = Locale.ENGLISH + } + } + + @AfterEach + fun teardown() { + clearAllMocks() + } + + fun createInstance() = CalendarCalculation(context) + @Test fun calculateSameYearSameMonth() { - var input = "27.08.2020" + val input = "27.08.2020" val dateTime = DateTime.parse(input, DateTimeFormat.forPattern(pattern)) - val dates = CalendarCalculation().getDates(dateTime) + val dates = createInstance().getDates(dateTime) // First day - 3 of August dates.first().date.dayOfMonth shouldBe 3 @@ -25,7 +57,7 @@ class CalendarCalculationTest { dates.last().date.dayOfMonth shouldBe 30 dates.last().date.monthOfYear shouldBe 8 - CalendarCalculation().getMonthText( + createInstance().getMonthText( dates.first().date, dates.last().date ) shouldBe "August 2020" @@ -33,10 +65,10 @@ class CalendarCalculationTest { @Test fun calculateSameYearDifferentMonth() { - var input = "15.09.2020" + val input = "15.09.2020" val dateTime = DateTime.parse(input, DateTimeFormat.forPattern(pattern)) - val dates = CalendarCalculation().getDates(dateTime) + val dates = createInstance().getDates(dateTime) // First day - 24 of August dates.first().date.dayOfMonth shouldBe 24 @@ -46,7 +78,7 @@ class CalendarCalculationTest { dates.last().date.dayOfMonth shouldBe 20 dates.last().date.monthOfYear shouldBe 9 - CalendarCalculation().getMonthText( + createInstance().getMonthText( dates.first().date, dates.last().date ) shouldBe "August - September 2020" @@ -54,10 +86,10 @@ class CalendarCalculationTest { @Test fun calculateDifferentYearDifferentMonth() { - var input = "12.01.2021" + val input = "12.01.2021" val dateTime = DateTime.parse(input, DateTimeFormat.forPattern(pattern)) - val dates = CalendarCalculation().getDates(dateTime) + val dates = createInstance().getDates(dateTime) // First day - 21 of December 2020 dates.first().date.dayOfMonth shouldBe 21 @@ -69,7 +101,7 @@ class CalendarCalculationTest { dates.last().date.monthOfYear shouldBe 1 dates.last().date.year shouldBe 2021 - CalendarCalculation().getMonthText( + createInstance().getMonthText( dates.first().date, dates.last().date ) shouldBe "December 2020 - January 2021" @@ -78,7 +110,7 @@ class CalendarCalculationTest { @Test fun calculateEdgeCases() { // new year - CalendarCalculation().getDates(DateTime.parse("27.12.2021", formatter)).apply { + createInstance().getDates(DateTime.parse("27.12.2021", formatter)).apply { // First day - 6 of December 2021 first().date.dayOfMonth shouldBe 6 first().date.monthOfYear shouldBe 12 @@ -89,14 +121,14 @@ class CalendarCalculationTest { last().date.monthOfYear shouldBe 1 last().date.year shouldBe 2022 - CalendarCalculation().getMonthText( + createInstance().getMonthText( first().date, last().date ) shouldBe "December 2021 - January 2022" } // leap year - CalendarCalculation().getDates(DateTime.parse("29.02.2024", formatter)).apply { + createInstance().getDates(DateTime.parse("29.02.2024", formatter)).apply { // First day - 5 of February 2024 first().date.dayOfMonth shouldBe 5 first().date.monthOfYear shouldBe 2 @@ -107,7 +139,7 @@ class CalendarCalculationTest { last().date.monthOfYear shouldBe 3 last().date.year shouldBe 2024 - CalendarCalculation().getMonthText( + createInstance().getMonthText( first().date, last().date ) shouldBe "February - March 2024"