-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Check rate limits for each request to GitHub (#208)
* Modify GitHubApi to throw an IllegalStateException if the rate limit is exceeded (X-RateLimit-Remaining is 0). I chose to fail-fast here instead of assuming callers will always check the result. This is fine in this small application. * Move the rate limit check logic out of the GitHubResponse "from" factory method and into its own method, sendRequestAndCheckRateLimit. This keeps the "from" method simple and free of cross-cutting concerns. * Add several methods to GitHubResponse to get the reset time, the time until reset from a given date, and methods to check if the rate limit is exceeded. * Add rateLimitResource to GitHubResponse, so that it can be included in log and exception messages, which will be most useful if the rate limit is exceeded. * Add GitHubResponseTest as dedicated test of GitHubResponse Misc: * Remove unused (except in tests) takeRequestWith1MilliTimeout from MockWebServerExtensions.kt * Add firstValueOrThrow to HttpHeadersExtensions.kt * Add top-level and extension functions in DateTimeExtensions.kt Closes #173
- Loading branch information
1 parent
6cce24c
commit f78baab
Showing
8 changed files
with
332 additions
and
85 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
src/main/kotlin/org/kiwiproject/changelog/extension/DateTimeExtensions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.kiwiproject.changelog.extension | ||
|
||
import java.time.Instant | ||
import java.time.ZoneOffset | ||
import java.time.ZonedDateTime | ||
import java.time.temporal.ChronoUnit | ||
|
||
fun nowUtcTruncatedToSeconds(): ZonedDateTime = | ||
nowUtc().truncatedToSeconds() | ||
|
||
fun nowUtc(): ZonedDateTime = | ||
ZonedDateTime.now(ZoneOffset.UTC) | ||
|
||
fun ZonedDateTime.truncatedToSeconds(): ZonedDateTime = | ||
truncatedTo(ChronoUnit.SECONDS) | ||
|
||
fun utcZonedDateTimeFromEpochSeconds(epochSeconds: Long): ZonedDateTime = | ||
Instant.ofEpochSecond(epochSeconds).atZone(ZoneOffset.UTC) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
src/test/kotlin/org/kiwiproject/changelog/extension/DateTimeExtensionsTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package org.kiwiproject.changelog.extension | ||
|
||
import org.assertj.core.api.Assertions.assertThat | ||
import org.assertj.core.api.Assertions.within | ||
import org.junit.jupiter.api.DisplayName | ||
import org.junit.jupiter.api.RepeatedTest | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.assertAll | ||
import java.time.Instant | ||
import java.time.ZoneId | ||
import java.time.ZoneOffset | ||
import java.time.ZonedDateTime | ||
import java.time.temporal.ChronoUnit | ||
import kotlin.random.Random | ||
|
||
@DisplayName("DateTimeExtensions") | ||
class DateTimeExtensionsTest { | ||
|
||
@Test | ||
fun shouldGetCurrentTimeAtUTCTruncatedToSeconds() { | ||
val now = nowUtcTruncatedToSeconds() | ||
|
||
assertAll( | ||
{ assertThat(now.offset).isEqualTo(ZoneOffset.UTC) }, | ||
{ assertThat(now.nano).isZero() } | ||
) | ||
} | ||
|
||
@Test | ||
fun shouldGetCurrentTimeAtUTC() { | ||
val now = nowUtc() | ||
|
||
assertAll( | ||
{ assertThat(now.offset).isEqualTo(ZoneOffset.UTC) }, | ||
{ assertThat(now).isCloseTo(ZonedDateTime.now(ZoneOffset.UTC), within(100, ChronoUnit.MILLIS)) } | ||
) | ||
} | ||
|
||
@RepeatedTest(10) | ||
fun shouldTruncateZonedDateTimeToSeconds() { | ||
val randomMinutes = Random.nextLong(1, 100) | ||
val offset = Random.nextInt(10) | ||
val now = ZonedDateTime.now(ZoneOffset.ofHours(offset)).plusMinutes(randomMinutes) | ||
val nowWithSecondPrecision = now.truncatedToSeconds() | ||
|
||
assertAll( | ||
{ assertThat(nowWithSecondPrecision.offset).isEqualTo(now.offset) }, | ||
{ assertThat(nowWithSecondPrecision.nano).isZero() } | ||
) | ||
} | ||
|
||
@RepeatedTest(10) | ||
fun shouldCreateZonedDateTimeAtUTCFromEpochSeconds() { | ||
val originalZonedDateTime = ZonedDateTime | ||
.now(ZoneOffset.ofHours(Random.nextInt(10))) | ||
.plusMinutes(Random.nextLong(0, 60)) | ||
val epochSeconds = originalZonedDateTime.toEpochSecond() | ||
|
||
val utcZonedDateTime = utcZonedDateTimeFromEpochSeconds(epochSeconds) | ||
|
||
assertThat(utcZonedDateTime) | ||
.isEqualTo(Instant.ofEpochSecond(epochSeconds).atZone(ZoneId.of("UTC"))) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.