Skip to content

Commit 1c81289

Browse files
committed
Finalize set_password tests
1 parent 4f6637a commit 1c81289

File tree

1 file changed

+124
-25
lines changed

1 file changed

+124
-25
lines changed

tests/test_admin.py

Lines changed: 124 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,152 @@
11
"""
2-
Collection of test cases to test connection module.
2+
Collection of test cases to test admin module.
33
"""
44

55
import datajoint as dj
6-
from datajoint import DataJointError
7-
import numpy as np
8-
from . import CONN_INFO_ROOT, connection_root, connection_test
9-
10-
from . import PREFIX
6+
import os
117
import pymysql
128
import pytest
139

10+
from . import CONN_INFO_ROOT
11+
12+
13+
@pytest.fixture()
14+
def user_alice() -> dict:
15+
# set up - reset config, log in as root, and create a new user alice
16+
# reset dj.config manually because its state may be changed by these tests
17+
if os.path.exists(dj.settings.LOCALCONFIG):
18+
os.remove(dj.settings.LOCALCONFIG)
19+
dj.config["database.password"] = os.getenv("DJ_PASS")
20+
root_conn = dj.conn(**CONN_INFO_ROOT, reset=True)
21+
new_credentials = dict(
22+
host=CONN_INFO_ROOT["host"],
23+
user="alice",
24+
password="oldpass",
25+
)
26+
root_conn.query(f"DROP USER IF EXISTS '{new_credentials['user']}'@'%%';")
27+
root_conn.query(
28+
f"CREATE USER '{new_credentials['user']}'@'%%' "
29+
f"IDENTIFIED BY '{new_credentials['password']}';"
30+
)
31+
32+
# test the connection
33+
dj.Connection(**new_credentials)
1434

15-
def test_set_password_prompt_match(monkeypatch):
35+
# return alice's credentials
36+
yield new_credentials
37+
38+
# tear down - delete the user and the local config file
39+
root_conn.query(f"DROP USER '{new_credentials['user']}'@'%%';")
40+
if os.path.exists(dj.settings.LOCALCONFIG):
41+
os.remove(dj.settings.LOCALCONFIG)
42+
43+
44+
def test_set_password_prompt_match(monkeypatch, user_alice: dict):
1645
"""
1746
Should be able to change the password using user prompt
1847
"""
19-
c = dj.conn(**CONN_INFO_ROOT)
20-
c.query("CREATE USER 'alice'@'%' IDENTIFIED BY 'pass';")
21-
# prompt responses: new password / confirm password / update local setting?
22-
responses = ["newpass", "newpass", "yes"]
23-
monkeypatch.setattr('getpass.getpass', lambda _: next(responses))
24-
monkeypatch.setattr('input', lambda _: next(responses))
48+
# reset the connection to use alice's credentials
49+
dj.conn(**user_alice, reset=True)
50+
51+
# prompts: new password / confirm password
52+
password_resp = iter(["newpass", "newpass"])
53+
# NOTE: because getpass.getpass is imported in datajoint.admin and used as
54+
# getpass in that module, we need to patch datajoint.admin.getpass
55+
# instead of getpass.getpass
56+
monkeypatch.setattr("datajoint.admin.getpass", lambda _: next(password_resp))
2557

58+
# respond no to prompt to update local config
59+
monkeypatch.setattr("builtins.input", lambda _: "no")
60+
61+
# reset password of user of current connection (alice)
2662
dj.set_password()
2763

64+
# should not be able to connect with old credentials
2865
with pytest.raises(pymysql.err.OperationalError):
29-
# should not be able to log in with old credentials
30-
dj.conn(host=CONN_INFO_ROOT["host"], user="alice", password="pass")
66+
dj.Connection(**user_alice)
3167

32-
# should be able to log in with new credentials
33-
dj.conn(host=CONN_INFO_ROOT["host"], user="alice", password="newpass")
68+
# should be able to connect with new credentials
69+
dj.Connection(host=user_alice["host"], user=user_alice["user"], password="newpass")
3470

35-
assert dj.config["database.password"] == "newpass"
71+
# check that local config is not updated
72+
assert dj.config["database.password"] == os.getenv("DJ_PASS")
73+
assert not os.path.exists(dj.settings.LOCALCONFIG)
3674

37-
def test_set_password_prompt_mismatch(monkeypatch):
75+
76+
def test_set_password_prompt_mismatch(monkeypatch, user_alice: dict):
3877
"""
3978
Should not be able to change the password when passwords do not match
4079
"""
41-
pass
80+
# reset the connection to use alice's credentials
81+
dj.conn(**user_alice, reset=True)
82+
83+
# prompts: new password / confirm password
84+
password_resp = iter(["newpass", "wrong"])
85+
# NOTE: because getpass.getpass is imported in datajoint.admin and used as
86+
# getpass in that module, we need to patch datajoint.admin.getpass
87+
# instead of getpass.getpass
88+
monkeypatch.setattr("datajoint.admin.getpass", lambda _: next(password_resp))
89+
90+
# reset password of user of current connection (alice)
91+
# should be nop
92+
dj.set_password()
93+
94+
# should be able to connect with old credentials
95+
dj.Connection(**user_alice)
96+
4297

43-
def test_set_password_arg(monkeypatch):
98+
def test_set_password_args(user_alice: dict):
4499
"""
45100
Should be able to change the password with an argument
46101
"""
47-
pass
102+
# reset the connection to use alice's credentials
103+
dj.conn(**user_alice, reset=True)
48104

49-
def test_set_password_no_update_config(monkeypatch):
105+
# reset password of user of current connection (alice)
106+
dj.set_password(new_password="newpass", update_config=False)
107+
108+
# should be able to connect with new credentials
109+
dj.Connection(host=user_alice["host"], user=user_alice["user"], password="newpass")
110+
111+
112+
def test_set_password_update_config(monkeypatch, user_alice: dict):
50113
"""
51-
Should be able to change the password without updating local config
114+
Should be able to change the password and update local config
52115
"""
53-
pass
116+
# reset the connection to use alice's credentials
117+
dj.conn(**user_alice, reset=True)
118+
119+
# respond yes to prompt to update local config
120+
monkeypatch.setattr("builtins.input", lambda _: "yes")
121+
122+
# reset password of user of current connection (alice)
123+
dj.set_password(new_password="newpass")
124+
125+
# should be able to connect with new credentials
126+
dj.Connection(host=user_alice["host"], user=user_alice["user"], password="newpass")
127+
128+
# check that local config is updated
129+
# NOTE: the global config state is changed unless dj modules are reloaded
130+
# NOTE: this test is a bit unrealistic because the config user does not match
131+
# the user whose password is being updated, so the config credentials
132+
# will be invalid after update...
133+
assert dj.config["database.password"] == "newpass"
134+
assert os.path.exists(dj.settings.LOCALCONFIG)
135+
136+
137+
def test_set_password_conn(user_alice: dict):
138+
"""
139+
Should be able to change the password using a given connection
140+
"""
141+
# create a connection with alice's credentials
142+
conn_alice = dj.Connection(**user_alice)
143+
144+
# reset password of user of alice's connection (alice) and do not update config
145+
dj.set_password(new_password="newpass", connection=conn_alice, update_config=False)
146+
147+
# should be able to connect with new credentials
148+
dj.Connection(host=user_alice["host"], user=user_alice["user"], password="newpass")
149+
150+
# check that local config is not updated
151+
assert dj.config["database.password"] == os.getenv("DJ_PASS")
152+
assert not os.path.exists(dj.settings.LOCALCONFIG)

0 commit comments

Comments
 (0)