From 94c7fdf93965c5126f1041408d238e6e32ad8e6e Mon Sep 17 00:00:00 2001 From: Paul Rybitskyi Date: Tue, 9 Mar 2021 01:14:21 +0200 Subject: [PATCH] Setup GitHub actions (#102) --- .github/ci-gradle.properties | 23 ++++ .github/workflows/build.yml | 111 +++++++++++++++ .../workflows/gradle-wrapper-validation.yml | 19 +++ checksum.sh | 23 ++++ .../ArticlePublicationDateFormatter.kt | 21 ++- .../core/formatters/RelativeDateFormatter.kt | 11 +- .../gamedge/core/providers/TimeProvider.kt | 40 ++++++ .../gamedge/core/utils/TimeUtils.kt | 25 ++++ ...ArticlePublicationDateFormatterImplTest.kt | 42 +++--- .../core/RelativeDateFormatterImplTest.kt | 126 ++++++++---------- .../gamedge/igdb/api/GamesServiceTest.kt | 7 + 11 files changed, 333 insertions(+), 115 deletions(-) create mode 100644 .github/ci-gradle.properties create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/gradle-wrapper-validation.yml create mode 100755 checksum.sh create mode 100644 core/src/main/java/com/paulrybitskyi/gamedge/core/providers/TimeProvider.kt create mode 100644 core/src/main/java/com/paulrybitskyi/gamedge/core/utils/TimeUtils.kt diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties new file mode 100644 index 000000000..1eb73a35c --- /dev/null +++ b/.github/ci-gradle.properties @@ -0,0 +1,23 @@ +# +# Copyright 2021 Paul Rybitskyi, paul.rybitskyi.work@gmail.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.gradle.daemon=false +org.gradle.parallel=true +org.gradle.jvmargs=-Xmx5120m +org.gradle.workers.max=2 + +# https://stackoverflow.com/questions/50138863/why-does-my-kotlin-gradle-build-die-with-exit-code-137 +kotlin.compiler.execution.strategy=in-process \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..19ea9ac69 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + unit-test: + runs-on: [ubuntu-latest] + if: ${{ !contains(github.event.head_commit.message, '[ci skip]') }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Generate a Cache Key + run: ./checksum.sh checksum.txt + + - name: Copy CI Gradle Properties + run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties + + - name: Cache Gradle Folders + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches/ + ~/.gradle/wrapper/ + key: cache-gradle-${{ runner.os }}-${{ hashFiles('checksum.txt') }} + restore-keys: | + cache-gradle-${{ runner.os }}- + cache-gradle- + + - name: Run all unit tests + run: ./gradlew test + + instrumentation-test: + runs-on: [macos-latest] + if: ${{ !contains(github.event.head_commit.message, '[ci skip]') }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Generate a Cache Key + run: ./checksum.sh checksum.txt + + - name: Copy CI Gradle Properties + run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties + + - name: Cache Gradle Folders + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches/ + ~/.gradle/wrapper/ + key: cache-gradle-${{ runner.os }}-${{ hashFiles('checksum.txt') }} + restore-keys: | + cache-gradle-${{ runner.os }}- + cache-gradle- + + - name: Run all instrumentation tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 30 + target: google_apis # https://github.com/ReactiveCircus/android-emulator-runner/issues/106 + script: ./gradlew connectedAndroidTest + + assemble: + runs-on: [ubuntu-latest] + if: ${{ !contains(github.event.head_commit.message, '[ci skip]') }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Generate a Cache Key + run: ./checksum.sh checksum.txt + + - name: Copy CI Gradle Properties + run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties + + - name: Cache Gradle Folders + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches/ + ~/.gradle/wrapper/ + key: cache-gradle-${{ runner.os }}-${{ hashFiles('checksum.txt') }} + restore-keys: | + cache-gradle-${{ runner.os }}- + cache-gradle- + + - name: Build Debug APK + run: ./gradlew assembleDebug \ No newline at end of file diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml new file mode 100644 index 000000000..df90952ea --- /dev/null +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -0,0 +1,19 @@ +name: Validate Gradle Wrapper + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + validation: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[ci skip]') }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v2 + + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v1 \ No newline at end of file diff --git a/checksum.sh b/checksum.sh new file mode 100755 index 000000000..e624cd4ca --- /dev/null +++ b/checksum.sh @@ -0,0 +1,23 @@ +#!/bin/bash +RESULT_FILE=$1 + +if [ -f $RESULT_FILE ]; then + rm $RESULT_FILE +fi +touch $RESULT_FILE + +checksum_file() { + echo $(openssl md5 $1 | awk '{print $2}') +} + +FILES=() +while read -r -d ''; do + FILES+=("$REPLY") +done < <(find . -type f \( -name "build.gradle*" -o -name "Dependencies.kt" -o -name "gradle-wrapper.properties" \) -print0) + +# Loop through files and append MD5 to result file +for FILE in ${FILES[@]}; do + echo $(checksum_file $FILE) >> $RESULT_FILE +done +# Now sort the file so that it is +sort $RESULT_FILE -o $RESULT_FILE \ No newline at end of file diff --git a/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/ArticlePublicationDateFormatter.kt b/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/ArticlePublicationDateFormatter.kt index 946333dfd..2096bc655 100644 --- a/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/ArticlePublicationDateFormatter.kt +++ b/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/ArticlePublicationDateFormatter.kt @@ -18,7 +18,7 @@ package com.paulrybitskyi.gamedge.core.formatters import com.paulrybitskyi.gamedge.core.providers.TimeFormat import com.paulrybitskyi.gamedge.core.providers.TimeFormatProvider -import com.paulrybitskyi.gamedge.core.providers.TimestampProvider +import com.paulrybitskyi.gamedge.core.providers.TimeProvider import com.paulrybitskyi.hiltbinder.BindType import java.time.Instant import java.time.LocalDateTime @@ -38,7 +38,7 @@ interface ArticlePublicationDateFormatter { @BindType internal class ArticlePublicationDateFormatterImpl @Inject constructor( private val relativeDateFormatter: RelativeDateFormatter, - private val timestampProvider: TimestampProvider, + private val timeProvider: TimeProvider, private val timeFormatProvider: TimeFormatProvider ) : ArticlePublicationDateFormatter { @@ -55,7 +55,10 @@ internal class ArticlePublicationDateFormatterImpl @Inject constructor( override fun formatPublicationDate(timestamp: Long): String { - val dateTime = toLocalDateTime(timestamp) + val dateTime = LocalDateTime.ofInstant( + Instant.ofEpochMilli(timestamp), + ZoneId.systemDefault() + ) return if(shouldFormatAsRelativeDate(dateTime)) { relativeDateFormatter.formatRelativeDate(dateTime) @@ -65,16 +68,8 @@ internal class ArticlePublicationDateFormatterImpl @Inject constructor( } - private fun toLocalDateTime(timestamp: Long): LocalDateTime { - return LocalDateTime.ofInstant( - Instant.ofEpochMilli(timestamp), - ZoneId.systemDefault() - ) - } - - private fun shouldFormatAsRelativeDate(dateTime: LocalDateTime): Boolean { - val currentDateTime = toLocalDateTime(timestampProvider.getUnixTimestamp()) + val currentDateTime = timeProvider.getCurrentDateTime() val dayDiffCount = ChronoUnit.DAYS.between(dateTime, currentDateTime) return (dayDiffCount == 0L) @@ -90,7 +85,7 @@ internal class ArticlePublicationDateFormatterImpl @Inject constructor( private fun getAbsoluteDatePattern(dateTime: LocalDateTime): String { - val currentDateTime = LocalDateTime.now() + val currentDateTime = timeProvider.getCurrentDateTime() val yearDiffCount = ChronoUnit.YEARS.between(dateTime, currentDateTime).toInt() val hasYearDiff = (yearDiffCount > 0) diff --git a/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/RelativeDateFormatter.kt b/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/RelativeDateFormatter.kt index a56918fb4..d74f4f5e6 100644 --- a/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/RelativeDateFormatter.kt +++ b/core/src/main/java/com/paulrybitskyi/gamedge/core/formatters/RelativeDateFormatter.kt @@ -18,11 +18,9 @@ package com.paulrybitskyi.gamedge.core.formatters import com.paulrybitskyi.gamedge.core.R import com.paulrybitskyi.gamedge.core.providers.StringProvider -import com.paulrybitskyi.gamedge.core.providers.TimestampProvider +import com.paulrybitskyi.gamedge.core.providers.TimeProvider import com.paulrybitskyi.hiltbinder.BindType -import java.time.Instant import java.time.LocalDateTime -import java.time.ZoneId import java.time.temporal.ChronoUnit import javax.inject.Inject @@ -36,16 +34,13 @@ interface RelativeDateFormatter { @BindType internal class RelativeDateFormatterImpl @Inject constructor( - private val timestampProvider: TimestampProvider, + private val timeProvider: TimeProvider, private val stringProvider: StringProvider ) : RelativeDateFormatter { override fun formatRelativeDate(dateTime: LocalDateTime): String { - val currentDateTime = LocalDateTime.ofInstant( - Instant.ofEpochMilli(timestampProvider.getUnixTimestamp()), - ZoneId.systemDefault() - ) + val currentDateTime = timeProvider.getCurrentDateTime() val isDateTimeInFuture = currentDateTime.isBefore(dateTime) return if(isDateTimeInFuture) { diff --git a/core/src/main/java/com/paulrybitskyi/gamedge/core/providers/TimeProvider.kt b/core/src/main/java/com/paulrybitskyi/gamedge/core/providers/TimeProvider.kt new file mode 100644 index 000000000..e8595f12d --- /dev/null +++ b/core/src/main/java/com/paulrybitskyi/gamedge/core/providers/TimeProvider.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Paul Rybitskyi, paul.rybitskyi.work@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.paulrybitskyi.gamedge.core.providers + +import com.paulrybitskyi.hiltbinder.BindType +import java.time.LocalDateTime +import javax.inject.Inject + + +interface TimeProvider { + + fun getCurrentDateTime(): LocalDateTime + +} + + +@BindType +internal class TimeProviderImpl @Inject constructor() : TimeProvider { + + + override fun getCurrentDateTime(): LocalDateTime { + return LocalDateTime.now() + } + + +} \ No newline at end of file diff --git a/core/src/main/java/com/paulrybitskyi/gamedge/core/utils/TimeUtils.kt b/core/src/main/java/com/paulrybitskyi/gamedge/core/utils/TimeUtils.kt new file mode 100644 index 000000000..1538c1212 --- /dev/null +++ b/core/src/main/java/com/paulrybitskyi/gamedge/core/utils/TimeUtils.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Paul Rybitskyi, paul.rybitskyi.work@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.paulrybitskyi.gamedge.core.utils + +import java.time.LocalDateTime +import java.time.ZoneId + + +fun LocalDateTime.toMillis(zoneId: ZoneId = ZoneId.systemDefault()): Long { + return atZone(zoneId).toInstant().toEpochMilli() +} \ No newline at end of file diff --git a/core/src/test/java/com/paulrybitskyi/gamedge/core/ArticlePublicationDateFormatterImplTest.kt b/core/src/test/java/com/paulrybitskyi/gamedge/core/ArticlePublicationDateFormatterImplTest.kt index 4b6e831e0..6fa625154 100644 --- a/core/src/test/java/com/paulrybitskyi/gamedge/core/ArticlePublicationDateFormatterImplTest.kt +++ b/core/src/test/java/com/paulrybitskyi/gamedge/core/ArticlePublicationDateFormatterImplTest.kt @@ -18,17 +18,19 @@ package com.paulrybitskyi.gamedge.core import com.paulrybitskyi.gamedge.core.formatters.ArticlePublicationDateFormatterImpl import com.paulrybitskyi.gamedge.core.formatters.RelativeDateFormatter -import com.paulrybitskyi.gamedge.core.formatters.RelativeDateFormatterImpl import com.paulrybitskyi.gamedge.core.providers.TimeFormat import com.paulrybitskyi.gamedge.core.providers.TimeFormatProvider -import com.paulrybitskyi.gamedge.core.providers.TimestampProvider +import com.paulrybitskyi.gamedge.core.providers.TimeProvider +import com.paulrybitskyi.gamedge.core.utils.toMillis import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK import org.assertj.core.api.Assertions.* import org.junit.Before import org.junit.Test -import java.util.concurrent.TimeUnit +import java.time.LocalDateTime +import java.time.Month +import java.time.ZoneId private const val RELATIVE_DATE = "relative_date" @@ -38,7 +40,7 @@ internal class ArticlePublicationDateFormatterImplTest { @MockK private lateinit var relativeDateFormatter: RelativeDateFormatter - @MockK private lateinit var timestampProvider: TimestampProvider + @MockK private lateinit var timeProvider: TimeProvider @MockK private lateinit var timeFormatProvider: TimeFormatProvider private lateinit var SUT: ArticlePublicationDateFormatterImpl @@ -50,7 +52,7 @@ internal class ArticlePublicationDateFormatterImplTest { SUT = ArticlePublicationDateFormatterImpl( relativeDateFormatter = relativeDateFormatter, - timestampProvider = timestampProvider, + timeProvider = timeProvider, timeFormatProvider = timeFormatProvider ) @@ -60,9 +62,10 @@ internal class ArticlePublicationDateFormatterImplTest { @Test fun `Formats pub date in relative format`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM + val timestamp = currentTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime assertThat(SUT.formatPublicationDate(timestamp)).isEqualTo(RELATIVE_DATE) } @@ -70,10 +73,10 @@ internal class ArticlePublicationDateFormatterImplTest { @Test fun `Formats pub date in absolute 24 hours format without year`() { - val originalTimestamp = 1614813308317L // March 4th, 2021 at 1:15 AM - val timestamp = (originalTimestamp - TimeUnit.DAYS.toMillis(2)) + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM + val timestamp = currentTime.minusDays(2).toMillis() - every { timestampProvider.getUnixTimestamp(any()) } returns originalTimestamp + every { timeProvider.getCurrentDateTime() } returns currentTime every { timeFormatProvider.getTimeFormat() } returns TimeFormat.TWENTY_FOUR_HOURS assertThat(SUT.formatPublicationDate(timestamp)).isEqualTo("Mar 2, 1:15") @@ -82,10 +85,10 @@ internal class ArticlePublicationDateFormatterImplTest { @Test fun `Formats pub date in absolute 24 hours format with year`() { - val originalTimestamp = 1614813308317L // March 4th, 2021 at 1:15 AM - val timestamp = (originalTimestamp - TimeUnit.DAYS.toMillis(365)) + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM + val timestamp = currentTime.minusYears(1).toMillis() - every { timestampProvider.getUnixTimestamp(any()) } returns originalTimestamp + every { timeProvider.getCurrentDateTime() } returns currentTime every { timeFormatProvider.getTimeFormat() } returns TimeFormat.TWENTY_FOUR_HOURS assertThat(SUT.formatPublicationDate(timestamp)).isEqualTo("Mar 4, 2020, 1:15") @@ -94,10 +97,10 @@ internal class ArticlePublicationDateFormatterImplTest { @Test fun `Formats pub date in absolute 12 hours format without year`() { - val originalTimestamp = 1614813308317L // March 4th, 2021 at 1:15 AM - val timestamp = (originalTimestamp - TimeUnit.DAYS.toMillis(2)) + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM + val timestamp = currentTime.minusDays(2).toMillis() - every { timestampProvider.getUnixTimestamp(any()) } returns originalTimestamp + every { timeProvider.getCurrentDateTime() } returns currentTime every { timeFormatProvider.getTimeFormat() } returns TimeFormat.TWELVE_HOURS assertThat(SUT.formatPublicationDate(timestamp)).isEqualTo("Mar 2, 1:15 AM") @@ -106,15 +109,14 @@ internal class ArticlePublicationDateFormatterImplTest { @Test fun `Formats pub date in absolute 12 hours format with year`() { - val originalTimestamp = 1614813308317L // March 4th, 2021 at 1:15 AM - val timestamp = (originalTimestamp - TimeUnit.DAYS.toMillis(365)) + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM + val timestamp = currentTime.minusYears(1).toMillis() - every { timestampProvider.getUnixTimestamp(any()) } returns originalTimestamp + every { timeProvider.getCurrentDateTime() } returns currentTime every { timeFormatProvider.getTimeFormat() } returns TimeFormat.TWELVE_HOURS assertThat(SUT.formatPublicationDate(timestamp)).isEqualTo("Mar 4, 2020, 1:15 AM") } - } \ No newline at end of file diff --git a/core/src/test/java/com/paulrybitskyi/gamedge/core/RelativeDateFormatterImplTest.kt b/core/src/test/java/com/paulrybitskyi/gamedge/core/RelativeDateFormatterImplTest.kt index 210df134c..b1acc6f39 100644 --- a/core/src/test/java/com/paulrybitskyi/gamedge/core/RelativeDateFormatterImplTest.kt +++ b/core/src/test/java/com/paulrybitskyi/gamedge/core/RelativeDateFormatterImplTest.kt @@ -18,22 +18,20 @@ package com.paulrybitskyi.gamedge.core import com.paulrybitskyi.gamedge.core.formatters.RelativeDateFormatterImpl import com.paulrybitskyi.gamedge.core.providers.StringProvider -import com.paulrybitskyi.gamedge.core.providers.TimestampProvider +import com.paulrybitskyi.gamedge.core.providers.TimeProvider import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK import org.assertj.core.api.Assertions.* import org.junit.Before import org.junit.Test -import java.time.Instant import java.time.LocalDateTime -import java.time.ZoneId -import java.util.concurrent.TimeUnit +import java.time.Month internal class RelativeDateFormatterImplTest { - @MockK private lateinit var timestampProvider: TimestampProvider + @MockK private lateinit var timeProvider: TimeProvider private lateinit var stringProvider: FakeStringProvider private lateinit var SUT: RelativeDateFormatterImpl @@ -45,7 +43,7 @@ internal class RelativeDateFormatterImplTest { stringProvider = FakeStringProvider() SUT = RelativeDateFormatterImpl( - timestampProvider = timestampProvider, + timeProvider = timeProvider, stringProvider = stringProvider ) } @@ -53,165 +51,145 @@ internal class RelativeDateFormatterImplTest { @Test fun `Formats future date with year difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val yearDiff = 2L - val futureTimestamp = (timestamp + TimeUnit.DAYS.toMillis(365 * yearDiff)) + val futureTime = currentTime.plusYears(yearDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $yearDiff years") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $yearDiff years") } @Test fun `Formats future date with month difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val monthDiff = 3L - val futureTimestamp = (timestamp + TimeUnit.DAYS.toMillis(31 * monthDiff)) + val futureTime = currentTime.plusMonths(monthDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $monthDiff months") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $monthDiff months") } @Test fun `Formats future date with day difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val dayDiff = 15L - val futureTimestamp = (timestamp + TimeUnit.DAYS.toMillis(dayDiff)) + val futureTime = currentTime.plusDays(dayDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $dayDiff days") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $dayDiff days") } @Test fun `Formats future date with hour difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val hourDiff = 5L - val futureTimestamp = (timestamp + TimeUnit.HOURS.toMillis(hourDiff)) + val futureTime = currentTime.plusHours(hourDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $hourDiff hours") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $hourDiff hours") } @Test fun `Formats future date with minute difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val minuteDiff = 5L - val futureTimestamp = (timestamp + TimeUnit.MINUTES.toMillis(minuteDiff)) + val futureTime = currentTime.plusMinutes(minuteDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $minuteDiff minutes") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $minuteDiff minutes") } @Test fun `Formats future date with second difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val secondDiff = 5L - val futureTimestamp = (timestamp + TimeUnit.SECONDS.toMillis(secondDiff)) + val futureTime = currentTime.plusSeconds(secondDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("in $secondDiff seconds") + assertThat(SUT.formatRelativeDate(futureTime)).isEqualTo("in $secondDiff seconds") } @Test fun `Formats past date with year difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val yearDiff = 1L - val futureTimestamp = (timestamp - TimeUnit.DAYS.toMillis(365 * yearDiff)) + val pastTime = currentTime.minusYears(yearDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$yearDiff years ago") + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$yearDiff years ago") } @Test fun `Formats past date with month difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val monthDiff = 3L - val futureTimestamp = (timestamp - TimeUnit.DAYS.toMillis(31 * monthDiff)) + val pastTime = currentTime.minusMonths(monthDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$monthDiff months ago") + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$monthDiff months ago") } @Test fun `Formats past date with day difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val dayDiff = 15L - val futureTimestamp = (timestamp - TimeUnit.DAYS.toMillis(dayDiff)) + val pastTime = currentTime.minusDays(dayDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$dayDiff days ago") + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$dayDiff days ago") } @Test fun `Formats past date with hour difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val hourDiff = 5L - val futureTimestamp = (timestamp - TimeUnit.HOURS.toMillis(hourDiff)) + val pastTime = currentTime.minusHours(hourDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$hourDiff hours ago") + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$hourDiff hours ago") } @Test fun `Formats past date with minute difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val minuteDiff = 5L - val futureTimestamp = (timestamp - TimeUnit.MINUTES.toMillis(minuteDiff)) + val pastTime = currentTime.minusMinutes(minuteDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$minuteDiff minutes ago") + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$minuteDiff minutes ago") } @Test fun `Formats past date with second difference correctly`() { - val timestamp = 1614813308317L // March 4th, 2021 at 1:15 AM + val currentTime = LocalDateTime.of(2021, Month.MARCH, 4, 1, 15) // March 4th, 2021 at 1:15 AM val secondDiff = 5L - val futureTimestamp = (timestamp - TimeUnit.SECONDS.toMillis(secondDiff)) + val pastTime = currentTime.minusSeconds(secondDiff) - every { timestampProvider.getUnixTimestamp(any()) } returns timestamp + every { timeProvider.getCurrentDateTime() } returns currentTime - assertThat(SUT.formatRelativeDate(futureTimestamp.toLocalDateTime())) - .isEqualTo("$secondDiff seconds ago") - } - - - private fun Long.toLocalDateTime(): LocalDateTime { - return LocalDateTime.ofInstant( - Instant.ofEpochMilli(this), - ZoneId.systemDefault() - ) + assertThat(SUT.formatRelativeDate(pastTime)).isEqualTo("$secondDiff seconds ago") } diff --git a/igdb-api/src/androidTest/java/com/paulrybitskyi/gamedge/igdb/api/GamesServiceTest.kt b/igdb-api/src/androidTest/java/com/paulrybitskyi/gamedge/igdb/api/GamesServiceTest.kt index 313ef3db2..fd645e5f5 100644 --- a/igdb-api/src/androidTest/java/com/paulrybitskyi/gamedge/igdb/api/GamesServiceTest.kt +++ b/igdb-api/src/androidTest/java/com/paulrybitskyi/gamedge/igdb/api/GamesServiceTest.kt @@ -19,7 +19,9 @@ package com.paulrybitskyi.gamedge.igdb.api import com.github.michaelbull.result.get import com.github.michaelbull.result.getError import com.paulrybitskyi.gamedge.commons.api.Error +import com.paulrybitskyi.gamedge.commons.testing.DATA_OAUTH_CREDENTIALS import com.paulrybitskyi.gamedge.commons.testing.utils.startSafe +import com.paulrybitskyi.gamedge.data.auth.datastores.local.AuthLocalDataStore import com.paulrybitskyi.gamedge.igdb.api.games.ApiCategory import com.paulrybitskyi.gamedge.igdb.api.games.ApiGame import com.paulrybitskyi.gamedge.igdb.api.games.GamesService @@ -44,6 +46,7 @@ internal class GamesServiceTest { var hiltRule = HiltAndroidRule(this) @Inject lateinit var mockWebServer: MockWebServer + @Inject lateinit var authLocalDataStore: AuthLocalDataStore @Inject lateinit var gamesService: GamesService @@ -51,6 +54,10 @@ internal class GamesServiceTest { fun setup() { hiltRule.inject() mockWebServer.startSafe() + + runBlocking { + authLocalDataStore.saveOauthCredentials(DATA_OAUTH_CREDENTIALS) + } }