Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ android {
lintOptions {
baseline file("lint-baseline.xml")
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
}

dependencies {
Expand Down Expand Up @@ -61,5 +66,8 @@ dependencies {

// Testing dependencies
testImplementation Testing.junit4
testImplementation AndroidX.test.ext.junit
testImplementation "androidx.test:runner:_"
testImplementation Testing.robolectric
testImplementation project(path: ':common-test')
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class RealTimeDiffFormatter @Inject constructor(private val context: Context) :
val timeDifferenceDate = (endDate.time - startDate.time).run { TimeUnit.DAYS.convert(this, TimeUnit.MILLISECONDS) }

return when (timeDifferenceDate) {
0L, 1L -> TimePassed.fromMilliseconds(timeDifferenceMillis).shortFormat()
0L, 1L -> TimePassed.fromMilliseconds(timeDifferenceMillis).shortFormat(context.resources)
else -> context.getString(R.string.common_DaysAgo, timeDifferenceDate)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.duckduckgo.app.global.formatters.time.model

import android.content.res.Resources
import com.duckduckgo.app.global.R
import com.duckduckgo.app.global.formatters.time.DatabaseDateFormatter
import org.threeten.bp.LocalDateTime

Expand Down Expand Up @@ -45,47 +47,41 @@ data class TimePassed(
val seconds: Long
) {

fun shortFormat(): String {
val sb = StringBuilder()

fun shortFormat(resources: Resources): String {
if (hours > 0) {
sb.append(hours)
sb.append("h ago")
return sb.toString()
return resources.getString(R.string.common_HoursAgo, hours)
}

if (minutes > 2) {
sb.append(minutes)
sb.append("m ago")
return sb.toString()
return resources.getString(R.string.common_MinutesAgo, minutes)
}

sb.append("just now")
return sb.toString()
return resources.getString(R.string.common_JustNow)
}

fun format(
alwaysShowHours: Boolean = true,
alwaysShowMinutes: Boolean = true,
alwaysShowSeconds: Boolean = true
alwaysShowSeconds: Boolean = true,
resources: Resources
): String {
val sb = StringBuilder()

if (hours > 0 || alwaysShowHours) {
sb.append(hours)
sb.append(" hr")
sb.append(" ${resources.getString(R.string.common_hour_abbreviation)}")
}

if (minutes > 0 || alwaysShowMinutes) {
sb.append(" ")
sb.append(minutes)
sb.append(" min")
sb.append(" ${resources.getString(R.string.common_min_abbreviation)}")
}

if (alwaysShowSeconds) {
sb.append(" ")
sb.append(seconds)
sb.append(" sec")
sb.append(" ${resources.getString(R.string.common_seconds_abbreviation)}")
}

return sb.toString()
Expand Down
6 changes: 6 additions & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@
<string name="common_DaysAgo">%d days ago</string>
<string name="common_PastWeek">Past Week</string>
<string name="common_PastMonth">Past Month</string>
<string name="common_MinutesAgo">%dm ago</string>
<string name="common_HoursAgo">%dh ago</string>
<string name="common_JustNow">Just Now</string>
<string name="common_hour_abbreviation">hr</string>
<string name="common_min_abbreviation">min</string>
<string name="common_seconds_abbreviation">sec</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -16,86 +16,93 @@

package com.duckduckgo.app.global.formatters.time.model

import android.content.Context
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class TimePassedTest {

private val resources = getApplicationContext<Context>().resources

@Test
fun whenOnlyHoursPassedThenFormatsProperTime() {
val timePassed = TimePassed(1, 0, 0)
assertEquals("1 hr 0 min 0 sec", timePassed.format())
assertEquals("1 hr 0 min 0 sec", timePassed.format(resources = resources))
}

@Test
fun whenOnlyMinutesPassedThenFormatsProperTime() {
val timePassed = TimePassed(0, 10, 0)
assertEquals("0 hr 10 min 0 sec", timePassed.format())
assertEquals("0 hr 10 min 0 sec", timePassed.format(resources = resources))
}

@Test
fun whenOnlySecondsPassedThenFormatsProperTime() {
val timePassed = TimePassed(0, 0, 25)
assertEquals("0 hr 0 min 25 sec", timePassed.format())
assertEquals("0 hr 0 min 25 sec", timePassed.format(resources = resources))
}

@Test
fun whenHoursAndMinutesPassedThenFormatsProperTime() {
val timePassed = TimePassed(1, 10, 0)
assertEquals("1 hr 10 min 0 sec", timePassed.format())
assertEquals("1 hr 10 min 0 sec", timePassed.format(resources = resources))
}

@Test
fun whenHoursAndSecondsPassedThenFormatsProperTime() {
val timePassed = TimePassed(1, 0, 30)
assertEquals("1 hr 0 min 30 sec", timePassed.format())
assertEquals("1 hr 0 min 30 sec", timePassed.format(resources = resources))
}

@Test
fun whenMinutesAndSecondsPassedThenFormatsProperTime() {
val timePassed = TimePassed(0, 10, 10)
assertEquals("0 hr 10 min 10 sec", timePassed.format())
assertEquals("0 hr 10 min 10 sec", timePassed.format(resources = resources))
}

@Test
fun whenOnlyHoursPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(1, 0, 0)
assertEquals("1h ago", timePassed.shortFormat())
assertEquals("1h ago", timePassed.shortFormat(resources))
}

@Test
fun whenOnlyMinutesPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(0, 10, 0)
assertEquals("10m ago", timePassed.shortFormat())
assertEquals("10m ago", timePassed.shortFormat(resources))
}

@Test
fun whenOnlySecondsPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(0, 0, 45)
assertEquals("just now", timePassed.shortFormat())
assertEquals("Just Now", timePassed.shortFormat(resources))
}

@Test
fun whenOnlyFewSecondsPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(0, 0, 25)
assertEquals("just now", timePassed.shortFormat())
assertEquals("Just Now", timePassed.shortFormat(resources))
}

@Test
fun whenHoursAndMinutesPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(1, 10, 0)
assertEquals("1h ago", timePassed.shortFormat())
assertEquals("1h ago", timePassed.shortFormat(resources))
}

@Test
fun whenHoursAndSecondsPassedThenShortFormatsProperTime() {
val timePassed = TimePassed(1, 0, 30)
assertEquals("1h ago", timePassed.shortFormat())
assertEquals("1h ago", timePassed.shortFormat(resources))
}

@Test
fun whenMinutesAndSecondsPassedShortThenFormatsProperTime() {
val timePassed = TimePassed(0, 10, 10)
assertEquals("10m ago", timePassed.shortFormat())
assertEquals("10m ago", timePassed.shortFormat(resources))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class DeviceShieldActivityFeedViewModelTest {
TrackerCompanyBadge.Company(dummyTrackers[1].company, dummyTrackers[1].companyDisplayName),
),
timestamp = TEST_TIMESTAMP,
displayTimestamp = "just now",
displayTimestamp = "Just Now",
trackersTotalCount = 2
),
TrackerFeedItem.TrackerFeedData(
Expand All @@ -108,7 +108,7 @@ class DeviceShieldActivityFeedViewModelTest {
TrackerCompanyBadge.Company(dummyTrackers[2].company, dummyTrackers[2].companyDisplayName),
),
timestamp = TEST_TIMESTAMP,
displayTimestamp = "just now",
displayTimestamp = "Just Now",
trackersTotalCount = 1
),
),
Expand Down
7 changes: 4 additions & 3 deletions vpn/src/main/java/dummy/ui/VpnControllerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class VpnControllerActivity : DuckDuckGoActivity(), CoroutineScope by MainScope(
getString(R.string.vpnNotRunYet)
} else {
return getString(
R.string.vpnTimeRunning, TimePassed.fromMilliseconds(timeRunningMillis).format()
R.string.vpnTimeRunning, TimePassed.fromMilliseconds(timeRunningMillis).format(resources = resources)
)
}
}
Expand All @@ -257,7 +257,7 @@ class VpnControllerActivity : DuckDuckGoActivity(), CoroutineScope by MainScope(
val timestamp = LocalDateTime.parse(lastTracker.timestamp)
val timeDifference = timestamp.until(OffsetDateTime.now(), ChronoUnit.MILLIS)
val timeRunning = TimePassed.fromMilliseconds(timeDifference)
return "Latest tracker blocked ${timeRunning.format()} ago\n${lastTracker.domain}\n(owned by ${lastTracker.company})"
return "Latest tracker blocked ${timeRunning.format(resources = resources)} ago\n${lastTracker.domain}\n(owned by ${lastTracker.company})"
}

private fun generateLastWebTrackerBlocked(lastTracker: WebTrackerBlocked?): String {
Expand All @@ -266,7 +266,8 @@ class VpnControllerActivity : DuckDuckGoActivity(), CoroutineScope by MainScope(
val timestamp = LocalDateTime.parse(lastTracker.timestamp)
val timeDifference = timestamp.until(OffsetDateTime.now(), ChronoUnit.MILLIS)
val timeRunning = TimePassed.fromMilliseconds(timeDifference)
return "Latest tracker blocked ${timeRunning.format()} ago\n${lastTracker.trackerUrl}\n(owned by ${lastTracker.trackerCompany})"
return "Latest tracker blocked ${timeRunning.format(resources = resources)} ago\n" +
"${lastTracker.trackerUrl}\n(owned by ${lastTracker.trackerCompany})"
}

private fun generateTrackerCompaniesBlocked(
Expand Down
2 changes: 1 addition & 1 deletion vpn/src/main/java/dummy/ui/VpnDiagnosticsActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ class VpnDiagnosticsActivity : DuckDuckGoActivity(), CoroutineScope by MainScope
} else {
return getString(
R.string.vpnTimeRunning,
TimePassed.fromMilliseconds(timeRunningMillis).format(),
TimePassed.fromMilliseconds(timeRunningMillis).format(resources = resources),
)
}
}
Expand Down