Skip to content

Commit 6d713f2

Browse files
committed
Add tests for client methods
1 parent f259276 commit 6d713f2

File tree

7 files changed

+285
-11
lines changed

7 files changed

+285
-11
lines changed

tests/async/conftest.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
from dotenv import load_dotenv
55

6-
from codingame import Client
6+
from codingame import Client, ClashOfCode
77
from codingame.client.async_ import AsyncClient
88

99
load_dotenv()
@@ -30,3 +30,18 @@ async def create_logged_in_client(
3030
remember_me_cookie=os.environ.get("TEST_LOGIN_REMEMBER_ME_COOKIE"),
3131
)
3232
yield client
33+
34+
35+
@pytest.fixture(name="private_clash")
36+
async def create_private_clash(
37+
request: pytest.FixtureRequest, auth_client: AsyncClient
38+
) -> ClashOfCode:
39+
if "mock_http" in request.fixturenames:
40+
mock_http = request.getfixturevalue("mock_http")
41+
mock_http(auth_client._state.http, "create_private_clash_of_code")
42+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
43+
44+
clash_of_code = await auth_client.create_private_clash_of_code(
45+
["Python3"], ["SHORTEST", "FASTEST"]
46+
)
47+
yield clash_of_code

tests/async/test_client.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,103 @@ async def test_client_get_pending_clash_of_code(client: AsyncClient, mock_http):
158158
assert isinstance(clash_of_code, ClashOfCode) or clash_of_code is None
159159

160160

161+
async def test_client_create_private_clash_of_code(
162+
auth_client: AsyncClient, mock_http
163+
):
164+
mock_http(auth_client._state.http, "create_private_clash_of_code")
165+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
166+
clash_of_code = await auth_client.create_private_clash_of_code(
167+
["Python3"], ["SHORTEST", "FASTEST"]
168+
)
169+
assert isinstance(clash_of_code, ClashOfCode)
170+
assert clash_of_code.modes in (
171+
["SHORTEST", "FASTEST"],
172+
["FASTEST", "SHORTEST"],
173+
)
174+
assert clash_of_code.programming_languages == ["Python3"]
175+
assert auth_client.codingamer.id in [p.id for p in clash_of_code.players]
176+
177+
178+
async def test_client_create_private_clash_of_code_logged_in_error(
179+
client: AsyncClient,
180+
):
181+
with pytest.raises(exceptions.LoginRequired):
182+
await client.create_private_clash_of_code(
183+
["Python3"], ["SHORTEST", "FASTEST"]
184+
)
185+
186+
187+
async def test_client_create_private_clash_of_code_value_error(
188+
auth_client: AsyncClient, mock_httperror
189+
):
190+
with pytest.raises(ValueError):
191+
await auth_client.create_private_clash_of_code(
192+
["Python3"], ["BAD MODE", "FASTEST"]
193+
)
194+
195+
mock_httperror(
196+
auth_client._state.http,
197+
"create_private_clash_of_code",
198+
{"id": 501, "message": "You need to be logged to perform this action."},
199+
)
200+
with pytest.raises(exceptions.LoginRequired):
201+
await auth_client.create_private_clash_of_code(
202+
["Python3"], ["SHORTEST", "FASTEST"]
203+
)
204+
205+
206+
async def test_client_join_private_clash_of_code(
207+
auth_client: AsyncClient, private_clash: ClashOfCode, mock_http
208+
):
209+
mock_http(auth_client._state.http, "join_clash_of_code_by_handle")
210+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
211+
clash_of_code = await auth_client.join_private_clash_of_code(private_clash)
212+
assert isinstance(clash_of_code, ClashOfCode)
213+
assert private_clash.public_handle == clash_of_code.public_handle
214+
assert auth_client.codingamer.id in [p.id for p in clash_of_code.players]
215+
216+
217+
async def test_client_join_private_clash_of_code_logged_in_error(
218+
client: AsyncClient,
219+
):
220+
with pytest.raises(exceptions.LoginRequired):
221+
await client.join_private_clash_of_code("0" * 7 + "a" * 32)
222+
223+
224+
async def test_client_join_private_clash_of_code_value_error(
225+
auth_client: AsyncClient, is_mocking: bool, mock_httperror
226+
):
227+
with pytest.raises(ValueError):
228+
await auth_client.join_private_clash_of_code("not a public handle")
229+
230+
mock_httperror(
231+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 502}
232+
)
233+
with pytest.raises(exceptions.ClashOfCodeNotFound):
234+
await auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
235+
236+
if not is_mocking:
237+
return
238+
239+
mock_httperror(
240+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 504}
241+
)
242+
with pytest.raises(exceptions.ClashOfCodeStarted):
243+
await auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
244+
245+
mock_httperror(
246+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 505}
247+
)
248+
with pytest.raises(exceptions.ClashOfCodeFinished):
249+
await auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
250+
251+
mock_httperror(
252+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 506}
253+
)
254+
with pytest.raises(exceptions.ClashOfCodeFull):
255+
await auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
256+
257+
161258
async def test_client_get_language_ids(client: AsyncClient, mock_http):
162259
mock_http(client._state.http, "get_language_ids")
163260
language_ids = await client.get_language_ids()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"nbPlayersMin": 2,
3+
"nbPlayersMax": 100,
4+
"publicHandle": "33784308137d34af00a8678be1e14142e6b8856",
5+
"clashDurationTypeId": "SHORT",
6+
"startTime": "Nov 19, 2023, 3:07:55 PM",
7+
"startTimestamp": 1700406475677,
8+
"finished": false,
9+
"started": false,
10+
"publicClash": false,
11+
"players": [
12+
{
13+
"codingamerId": 1234567,
14+
"codingamerNickname": "Player 1",
15+
"duration": 0,
16+
"status": "OWNER"
17+
}
18+
],
19+
"type": "PRIVATE"
20+
}

tests/mock/responses/get_clash_of_code_from_handle.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"nbPlayersMax": 100,
44
"publicHandle": "1234567fedcba9876543210fedcba9876543210",
55
"clashDurationTypeId": "SHORT",
6-
"mode": "REVERSE",
6+
"mode": "FASTEST",
77
"creationTime": "Jan 1, 2021 12:34:56 PM",
88
"startTime": "Jan 1, 2021 12:36:56 PM",
99
"endTime": "Jan 1, 2021 12:51:56 PM",
@@ -36,7 +36,7 @@
3636
"duration": 234567,
3737
"status": "STANDARD",
3838
"testSessionStatus": "COMPLETED",
39-
"languageId": "C++",
39+
"languageId": "Python3",
4040
"rank": 2,
4141
"position": 3,
4242
"solutionShared": true,
@@ -52,18 +52,16 @@
5252
"duration": 345678,
5353
"status": "OWNER",
5454
"testSessionStatus": "COMPLETED",
55-
"languageId": "Javascript",
55+
"languageId": "Python3",
5656
"rank": 3,
5757
"position": 1,
5858
"solutionShared": false,
5959
"testSessionHandle": "34567890dcba9876543210fedcba9876543210fe",
6060
"submissionId": 34567890
6161
}
6262
],
63-
"programmingLanguages": [
64-
"Python3", "C", "C++", "Java", "Javascript"
65-
],
63+
"programmingLanguages": ["Python3"],
6664
"modes": [
67-
"REVERSE", "SHORTEST"
65+
"FASTEST", "SHORTEST"
6866
]
6967
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"nbPlayersMin": 2,
3+
"nbPlayersMax": 100,
4+
"publicHandle": "1234567fedcba9876543210fedcba9876543210",
5+
"clashDurationTypeId": "SHORT",
6+
"creationTime": "Nov 19, 2023, 4:06:44 PM",
7+
"startTime": "Nov 19, 2023, 4:11:44 PM",
8+
"startTimestamp": 1700410304746,
9+
"msBeforeStart": 236827,
10+
"finished": false,
11+
"started": false,
12+
"publicClash": false,
13+
"players": [
14+
{
15+
"codingamerId": 7654321,
16+
"codingamerNickname": "Player 1",
17+
"codingamerHandle": "0123456789abcdef0123456789abcdef1234567",
18+
"duration": 0,
19+
"status": "OWNER",
20+
"rank": 1,
21+
"position": 1
22+
},
23+
{
24+
"codingamerId": 1234567,
25+
"codingamerNickname": "Player 2",
26+
"duration": 0,
27+
"status": "STANDARD"
28+
}
29+
],
30+
"type": "PRIVATE"
31+
}

tests/sync/conftest.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@
33
import pytest
44
from dotenv import load_dotenv
55

6-
from codingame import Client
6+
from codingame import Client, ClashOfCode
7+
from codingame.client.sync import SyncClient
78

89
load_dotenv()
910

1011

1112
@pytest.fixture(name="client", scope="function")
12-
def create_client() -> Client:
13+
def create_client() -> SyncClient:
1314
with Client() as client:
1415
yield client
1516

1617

1718
@pytest.fixture(name="auth_client")
18-
def create_logged_in_client(request: pytest.FixtureRequest) -> Client:
19+
def create_logged_in_client(request: pytest.FixtureRequest) -> SyncClient:
1920
with Client() as client:
2021
if "mock_http" in request.fixturenames:
2122
mock_http = request.getfixturevalue("mock_http")
@@ -27,3 +28,18 @@ def create_logged_in_client(request: pytest.FixtureRequest) -> Client:
2728
remember_me_cookie=os.environ.get("TEST_LOGIN_REMEMBER_ME_COOKIE"),
2829
)
2930
yield client
31+
32+
33+
@pytest.fixture(name="private_clash")
34+
def create_private_clash(
35+
request: pytest.FixtureRequest, auth_client: SyncClient
36+
) -> ClashOfCode:
37+
if "mock_http" in request.fixturenames:
38+
mock_http = request.getfixturevalue("mock_http")
39+
mock_http(auth_client._state.http, "create_private_clash_of_code")
40+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
41+
42+
clash_of_code = auth_client.create_private_clash_of_code(
43+
["Python3"], ["SHORTEST", "FASTEST"]
44+
)
45+
yield clash_of_code

tests/sync/test_client.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,103 @@ def test_client_get_pending_clash_of_code(client: SyncClient, mock_http):
147147
assert isinstance(clash_of_code, ClashOfCode) or clash_of_code is None
148148

149149

150+
def test_client_create_private_clash_of_code(
151+
auth_client: SyncClient, mock_http
152+
):
153+
mock_http(auth_client._state.http, "create_private_clash_of_code")
154+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
155+
clash_of_code = auth_client.create_private_clash_of_code(
156+
["Python3"], ["SHORTEST", "FASTEST"]
157+
)
158+
assert isinstance(clash_of_code, ClashOfCode)
159+
assert clash_of_code.modes in (
160+
["SHORTEST", "FASTEST"],
161+
["FASTEST", "SHORTEST"],
162+
)
163+
assert clash_of_code.programming_languages == ["Python3"]
164+
assert auth_client.codingamer.id in [p.id for p in clash_of_code.players]
165+
166+
167+
def test_client_create_private_clash_of_code_logged_in_error(
168+
client: SyncClient,
169+
):
170+
with pytest.raises(exceptions.LoginRequired):
171+
client.create_private_clash_of_code(
172+
["Python3"], ["SHORTEST", "FASTEST"]
173+
)
174+
175+
176+
def test_client_create_private_clash_of_code_value_error(
177+
auth_client: SyncClient, mock_httperror
178+
):
179+
with pytest.raises(ValueError):
180+
auth_client.create_private_clash_of_code(
181+
["Python3"], ["BAD MODE", "FASTEST"]
182+
)
183+
184+
mock_httperror(
185+
auth_client._state.http,
186+
"create_private_clash_of_code",
187+
{"id": 501, "message": "You need to be logged to perform this action."},
188+
)
189+
with pytest.raises(exceptions.LoginRequired):
190+
auth_client.create_private_clash_of_code(
191+
["Python3"], ["SHORTEST", "FASTEST"]
192+
)
193+
194+
195+
def test_client_join_private_clash_of_code(
196+
auth_client: SyncClient, private_clash: ClashOfCode, mock_http
197+
):
198+
mock_http(auth_client._state.http, "join_clash_of_code_by_handle")
199+
mock_http(auth_client._state.http, "get_clash_of_code_from_handle")
200+
clash_of_code = auth_client.join_private_clash_of_code(private_clash)
201+
assert isinstance(clash_of_code, ClashOfCode)
202+
assert private_clash.public_handle == clash_of_code.public_handle
203+
assert auth_client.codingamer.id in [p.id for p in clash_of_code.players]
204+
205+
206+
def test_client_join_private_clash_of_code_logged_in_error(
207+
client: SyncClient,
208+
):
209+
with pytest.raises(exceptions.LoginRequired):
210+
client.join_private_clash_of_code("0" * 7 + "a" * 32)
211+
212+
213+
def test_client_join_private_clash_of_code_value_error(
214+
auth_client: SyncClient, is_mocking: bool, mock_httperror
215+
):
216+
with pytest.raises(ValueError):
217+
auth_client.join_private_clash_of_code("not a public handle")
218+
219+
mock_httperror(
220+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 502}
221+
)
222+
with pytest.raises(exceptions.ClashOfCodeNotFound):
223+
auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
224+
225+
if not is_mocking:
226+
return
227+
228+
mock_httperror(
229+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 504}
230+
)
231+
with pytest.raises(exceptions.ClashOfCodeStarted):
232+
auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
233+
234+
mock_httperror(
235+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 505}
236+
)
237+
with pytest.raises(exceptions.ClashOfCodeFinished):
238+
auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
239+
240+
mock_httperror(
241+
auth_client._state.http, "join_clash_of_code_by_handle", {"id": 506}
242+
)
243+
with pytest.raises(exceptions.ClashOfCodeFull):
244+
auth_client.join_private_clash_of_code("0" * 7 + "a" * 32)
245+
246+
150247
def test_client_get_language_ids(client: SyncClient, mock_http):
151248
mock_http(client._state.http, "get_language_ids")
152249
language_ids = client.get_language_ids()

0 commit comments

Comments
 (0)