Skip to content

Commit c3a141b

Browse files
committed
tests, sessionID checking
1 parent e136b36 commit c3a141b

File tree

4 files changed

+133
-24
lines changed

4 files changed

+133
-24
lines changed

leetcode/configuration.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,40 @@ def execute(self, args):
3131
if getattr(args, 'config_key') and getattr(args, 'config_value'):
3232
self.dump_key(args.config_key, args.config_value)
3333
print('Configuration updated successfully.')
34-
35-
def check_session():
36-
with open(CONFIG_PATH, 'r') as yaml_file:
34+
35+
def check_session_response(session_id: str) -> bool:
36+
QUERY = """ query
37+
{
38+
user {
39+
username
40+
isCurrentUserPremium
41+
}
42+
}
43+
"""
44+
response = requests.post(url="https://leetcode.com/graphql",
45+
json={'query': QUERY},
46+
cookies={'LEETCODE_SESSION': session_id})
47+
if response.json()['data']['user']:
48+
return True
49+
else:
50+
return False
51+
52+
def update_session_id(session_id: str, path = CONFIG_PATH):
53+
with open(path, 'r') as yaml_file:
54+
data = yaml.safe_load(yaml_file)
55+
56+
data['user_data']['session_id'] = session_id
57+
with open(path, 'w') as yaml_file:
58+
yaml.dump(data, yaml_file, default_flow_style=False)
59+
60+
def check_session_validity(path = CONFIG_PATH) -> bool:
61+
with open(path, 'r') as yaml_file:
3762
data = yaml.safe_load(yaml_file)
3863

3964
SESSION_ID = data['user_data']['session_id']
40-
if SESSION_ID == '': # or the id is not valid!
41-
SESSION_ID = input("Please provide the SESSION_ID: ")
42-
data['user_data']['session_id'] = SESSION_ID
43-
with open(CONFIG_PATH, 'w') as yaml_file:
44-
yaml.dump(data, yaml_file, default_flow_style=False)
65+
while not check_session_response(SESSION_ID):
66+
SESSION_ID = input("Please provide the proper SESSION_ID: ")
67+
update_session_id(SESSION_ID)
4568
return True
4669

4770
""" The main configuration class for the connection to GraphQL API.
@@ -68,7 +91,6 @@ def __init__(self, session_id: str = ''):
6891
'Referer': self.host}
6992
self._cookies: dict = {'csrftoken': self._csrf_cookie,
7093
'LEETCODE_SESSION': self.session_id}
71-
7294
if not Configuration.session_checked:
7395
self.check_session_validity()
7496

leetcode/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import argparse
22
from models import *
3-
from leetcode.configuration import check_session, UserConfig
3+
from leetcode.configuration import check_session_validity, UserConfig
44

5+
# TODO: add --version
56
# TODO: add a command to open the question in editor
67
# TODO: submit the solution from the terminal
78
# TODO: add a command to show the solution in the terminal
@@ -63,5 +64,5 @@ def main():
6364

6465

6566
if __name__ == '__main__':
66-
if check_session():
67+
if check_session_validity():
6768
main()

tests/test_check_session.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import pytest
2+
from leetcode.configuration import check_session_response, check_session_validity, update_session_id
3+
import os
4+
import tempfile
5+
import yaml
6+
import requests_mock
7+
8+
@pytest.fixture
9+
def temp_config_file():
10+
temp_dir = tempfile.mkdtemp()
11+
temp_file_path = os.path.join(temp_dir, 'temp_config.yaml')
12+
13+
yaml_data = {
14+
'user_data': {
15+
'csrv_token': 'example_token',
16+
'session_id': 'example_session_id',
17+
'username': 'coderbeep'
18+
}
19+
}
20+
21+
with open(temp_file_path, 'w') as temp_file:
22+
yaml.dump(yaml_data, temp_file, default_flow_style=False)
23+
print(temp_file_path)
24+
return temp_file_path # Provide the temporary file path to the tests
25+
26+
@pytest.fixture
27+
def mock_requests():
28+
with requests_mock.Mocker() as m:
29+
yield m
30+
31+
def test_valid_session(mock_requests):
32+
mock_requests.post('https://leetcode.com/graphql', json={'data': {'user': {'username': None, 'isCurrentUserPremium': False}}})
33+
34+
session_id = 'valid_session_id'
35+
result = check_session_response(session_id)
36+
assert result is True
37+
38+
def test_invalid_session(mock_requests):
39+
mock_requests.post('https://leetcode.com/graphql', json={'data': {'user': None}})
40+
41+
session_id = 'invalid_session_id'
42+
result = check_session_response(session_id)
43+
assert result is False
44+
45+
def test_update_session_id(temp_config_file):
46+
update_session_id('new_session_id', temp_config_file)
47+
with open(temp_config_file, 'r') as yaml_file:
48+
data = yaml.safe_load(yaml_file)
49+
assert data['user_data']['session_id'] == 'new_session_id'
50+
51+
def test_check_session_validity(temp_config_file, monkeypatch):
52+
monkeypatch.setattr('leetcode.configuration.check_session_response', lambda x: True)
53+
monkeypatch.setattr('builtins.input', lambda x: 'new_session_id')
54+
55+
monkeypatch.setattr('leetcode.configuration.update_session_id', lambda x: None)
56+
assert check_session_validity(temp_config_file) is True
57+
58+
def test_check_session_validity_with_invalid_session_id(temp_config_file, monkeypatch):
59+
# Mocking the check_session_response function to always return False
60+
counter = 0
61+
def mock_check_session_response(session_id):
62+
nonlocal counter
63+
if counter < 3:
64+
counter += 1
65+
return False
66+
else:
67+
return True
68+
monkeypatch.setattr('leetcode.configuration.check_session_response', mock_check_session_response)
69+
70+
# Mocking the input function to return a specific value
71+
monkeypatch.setattr('builtins.input', lambda x: 'new_session_id')
72+
73+
# Mocking the update_session_id function to just pass
74+
monkeypatch.setattr('leetcode.configuration.update_session_id', lambda x: None)
75+
76+
# Import and call the check_session_validity function
77+
assert check_session_validity(temp_config_file)
78+
# cases:
79+
# 1. session_id is empty
80+
# 2. session_id is valid
81+
# 3. session_id is invalid

tests/test_user_config.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import tempfile
1+
import argparse
22
import os
3-
import yaml
3+
import tempfile
4+
45
import pytest
5-
import argparse
6-
from leetcode.configuration import UserConfig # Replace 'your_module' with the actual module where UserConfig is defined
6+
import yaml
7+
8+
from leetcode.configuration import \
9+
UserConfig
710

8-
# Define a fixture to create a temporary configuration file
11+
12+
# fixture for temporary config file
913
@pytest.fixture
1014
def temp_config_file():
1115
temp_dir = tempfile.mkdtemp()
@@ -24,35 +28,34 @@ def temp_config_file():
2428

2529
return temp_file_path # Provide the temporary file path to the tests
2630

31+
# fixture for UserConfig object with temporary config file
2732
@pytest.fixture
28-
def user_config_with_temp_file(temp_config_file):
33+
def user_config_with_temp_file(temp_config_file: str):
2934
return UserConfig(config_path=temp_config_file)
3035

3136
# Test UserConfig initialization
32-
def test_userconfig_init(temp_config_file):
37+
def test_userconfig_init(temp_config_file: str):
3338
user_config = UserConfig(config_path=temp_config_file)
3439
assert user_config.path == temp_config_file
3540
assert user_config.data is not None
3641

3742
# Test UserConfig get method
38-
def test_userconfig_get(temp_config_file):
43+
def test_userconfig_get(temp_config_file: str):
3944
user_config = UserConfig(config_path=temp_config_file)
4045
assert user_config.get('csrv_token') == 'example_token'
4146

4247
# Test UserConfig dump_key method
43-
def test_userconfig_dump_key(temp_config_file):
48+
def test_userconfig_dump_key(temp_config_file: str):
4449
user_config = UserConfig(config_path=temp_config_file)
4550

46-
# Dump a key-value pair and check if it's updated in the config file
4751
user_config.dump_key('new_key', 'new_value')
4852

49-
# Read the config file to check if the value is updated
5053
with open(temp_config_file, 'r') as yaml_file:
5154
data = yaml.safe_load(yaml_file)
5255
assert data['user_data']['new_key'] == 'new_value'
5356

5457
# Test UserConfig execute method with valid args
55-
def test_userconfig_execute_valid_args(user_config_with_temp_file, capsys):
58+
def test_userconfig_execute_valid_args(user_config_with_temp_file: UserConfig, capsys: pytest.CaptureFixture[str]):
5659
args = argparse.Namespace(config_key='csrv_token', config_value='new_token')
5760
user_config_with_temp_file.execute(args)
5861

@@ -62,10 +65,12 @@ def test_userconfig_execute_valid_args(user_config_with_temp_file, capsys):
6265
assert "Configuration updated successfully." in captured.out
6366

6467
# Test UserConfig execute method with invalid config_key
65-
def test_userconfig_execute_invalid_key(user_config_with_temp_file, capsys):
68+
def test_userconfig_execute_invalid_key(user_config_with_temp_file: UserConfig, capsys: pytest.CaptureFixture[str]):
6669
args = argparse.Namespace(config_key='invalid_key', config_value='new_value')
6770
user_config_with_temp_file.execute(args)
6871

6972
# Check if an error message is printed for an invalid key
7073
captured = capsys.readouterr()
7174
assert "Invalid key: invalid_key" in captured.out
75+
76+
# argparse module handles the case when either of the arguments is missing

0 commit comments

Comments
 (0)