@@ -5,18 +5,27 @@ import me.proxer.library.ProxerException
55import me.proxer.library.ProxerException.ServerErrorType
66import me.proxer.library.ProxerTest
77import me.proxer.library.enums.Language
8+ import me.proxer.library.fromResource
89import me.proxer.library.runRequest
10+ import okhttp3.Cache
11+ import okhttp3.mockwebserver.MockResponse
12+ import org.amshove.kluent.AnyException
913import org.amshove.kluent.invoking
1014import org.amshove.kluent.shouldBe
15+ import org.amshove.kluent.shouldNotBeNull
16+ import org.amshove.kluent.shouldNotThrow
1117import org.amshove.kluent.shouldThrow
1218import org.junit.jupiter.api.Disabled
19+ import org.junit.jupiter.api.RepeatedTest
1320import org.junit.jupiter.api.Test
21+ import java.util.concurrent.CountDownLatch
22+ import java.util.concurrent.TimeUnit
1423
1524class RateLimitInterceptorTest : ProxerTest () {
1625
1726 private val rateLimitApi = ProxerApi .Builder (" mock-key" )
1827 .enableRateLimitProtection()
19- .client(client)
28+ .client(client.newBuilder().cache( Cache (createTempDir(), 1_024L * 1_024L )).build() )
2029 .build()
2130
2231 @Test
@@ -45,6 +54,85 @@ class RateLimitInterceptorTest : ProxerTest() {
4554 result.exception.serverErrorType shouldBe ServerErrorType .RATE_LIMIT
4655 }
4756
57+ @Test
58+ fun testCachedResponse () {
59+ val response = MockResponse ()
60+ .setBody(fromResource(" chapter.json" ))
61+ .setHeader(" Cache-Control" , " public, max-age=31536000" )
62+
63+ // Limit 10.
64+ repeat(8 ) {
65+ server.enqueue(response)
66+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
67+ }
68+
69+ invoking {
70+ server.enqueue(response)
71+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
72+ } shouldNotThrow AnyException
73+ }
74+
75+ @Test
76+ @RepeatedTest(50 )
77+ fun testParallelRequests () {
78+ // Limit 10.
79+ repeat(7 ) {
80+ server.runRequest(" chapter.json" ) {
81+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
82+ }
83+ }
84+
85+ server.enqueue(MockResponse ().setBody(fromResource(" chapter.json" )))
86+ server.enqueue(MockResponse ().setBody(fromResource(" chapter.json" )))
87+
88+ val lock = CountDownLatch (2 )
89+ var error: ProxerException ? = null
90+
91+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().enqueue(
92+ { lock.countDown() },
93+ {
94+ error = it
95+ lock.countDown()
96+ }
97+ )
98+
99+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().enqueue(
100+ { lock.countDown() },
101+ {
102+ error = it
103+ lock.countDown()
104+ }
105+ )
106+
107+ lock.await(3_000L , TimeUnit .MILLISECONDS )
108+
109+ error.shouldNotBeNull()
110+ error!! .serverErrorType shouldBe ServerErrorType .RATE_LIMIT
111+ }
112+
113+ @Test
114+ @Disabled // Does not work because of real urls being passed in and mock urls in cache.
115+ fun testLimitButCached () {
116+ // Limit 10.
117+ repeat(7 ) {
118+ server.runRequest(" chapter.json" ) {
119+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
120+ }
121+ }
122+
123+ val response = MockResponse ()
124+ .setBody(fromResource(" chapter.json" ))
125+ .setHeader(" Cache-Control" , " public, max-age=31536000" )
126+
127+ server.enqueue(response)
128+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
129+
130+ invoking {
131+ server.enqueue(response)
132+ rateLimitApi.manga.chapter(" 123" , 123 , Language .ENGLISH ).build().execute()
133+ } shouldNotThrow AnyException
134+ }
135+
48136 @Test
49137 @Disabled
50138 fun testResetStateAfterTimeLimit () {
0 commit comments