-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extend unit test to check that new manual matches are indeed saved in…
… JSON file.
- Loading branch information
1 parent
0e2d731
commit 0940717
Showing
1 changed file
with
85 additions
and
2 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,4 +1,6 @@ | ||
import io | ||
import json | ||
from io import StringIO | ||
from unittest.mock import MagicMock, mock_open, patch | ||
|
||
import pytest | ||
|
@@ -54,6 +56,67 @@ def fake_raw_ldap_data(nbr_users=10): | |
) | ||
|
||
|
||
class MyStringIO(StringIO): | ||
""" | ||
Special StringIO class which always save | ||
its content in a `text` field, especially | ||
on `close()`, so that content can be read | ||
even after object is closed. | ||
""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.text = self.getvalue() | ||
|
||
def close(self): | ||
self.text = self.getvalue() | ||
return super().close() | ||
|
||
|
||
class FileSimulator: | ||
""" | ||
Helper class to mock `open` builtin function. | ||
""" | ||
|
||
def __init__(self, contents): | ||
"""Initialize. | ||
contents must be a dictionary matching filename to (str) content, | ||
used to provide filename content when opening file. | ||
""" | ||
self.contents = contents | ||
self.files = {} | ||
|
||
def get(self, filename): | ||
"""Return filename content if loaded, empty string otherwise.""" | ||
if filename in self.files: | ||
return self.files[filename].text | ||
return "" | ||
|
||
def __call__(self, filename, *args, **kwargs): | ||
""" | ||
Mock for `open` function. | ||
File is managed as a MyStringIO object. | ||
""" | ||
|
||
# Return an empty file if mode is "w", whatever the filename. | ||
if kwargs.get("mode") == "w" or (args and args[0] == "w"): | ||
file = MyStringIO() | ||
# Otherwise, return a file with content if filename is known. | ||
elif filename in self.contents: | ||
file = MyStringIO(self.contents[filename]) | ||
# Otherwise, return an empty file. | ||
else: | ||
file = MyStringIO() | ||
|
||
# Store open file for further content reading. | ||
self.files[filename] = file | ||
|
||
# And return open file. | ||
return file | ||
|
||
|
||
@pytest.mark.usefixtures("empty_read_write_db") | ||
def test_acquire_users(cli_main, monkeypatch, mock_file): | ||
"""Test command line `sarc acquire users`. | ||
|
@@ -101,7 +164,7 @@ def mock_query_ldap( | |
|
||
|
||
@pytest.mark.usefixtures("empty_read_write_db") | ||
def test_acquire_users_prompt(cli_main, monkeypatch, mock_file): | ||
def test_acquire_users_prompt(cli_main, monkeypatch, file_contents): | ||
"""Test command line `sarc acquire users --prompt`.""" | ||
nbr_users = 10 | ||
|
||
|
@@ -113,6 +176,18 @@ def mock_query_ldap( | |
|
||
monkeypatch.setattr(sarc.ldap.read_mila_ldap, "query_ldap", mock_query_ldap) | ||
|
||
# Load config | ||
cfg = config() | ||
# Load mock for `open` builtin function | ||
file_simulator = FileSimulator(file_contents) | ||
# Preload manual matching file for to check initial content | ||
file_simulator(cfg.account_matching.make_matches_config) | ||
# Check initial content. Should contain only 1 default manual match. | ||
before = json.loads(file_simulator.get(cfg.account_matching.make_matches_config)) | ||
assert before["D_override_matches_mila_to_cc_account_username"] == { | ||
"[email protected]": "js_the_first" | ||
} | ||
|
||
# Feed input for prompt. | ||
# First input firstly receives `a` (invalid, should re-prompt) | ||
# then <enter> (valid, ignore). | ||
|
@@ -121,7 +196,7 @@ def mock_query_ldap( | |
# be matched with john smith the 6rd as drac_member. | ||
monkeypatch.setattr("sys.stdin", io.StringIO("a\n\n\n\n3\n\n\n\n\n\n\n\n\n\n\n")) | ||
|
||
with patch("builtins.open", side_effect=mock_file): | ||
with patch("builtins.open", side_effect=file_simulator): | ||
assert ( | ||
cli_main( | ||
[ | ||
|
@@ -133,6 +208,14 @@ def mock_query_ldap( | |
== 0 | ||
) | ||
|
||
# Check manual matching file after execution. Should contain | ||
# 2 manual matches with the new one set from prompt. | ||
after = json.loads(file_simulator.get(cfg.account_matching.make_matches_config)) | ||
assert after["D_override_matches_mila_to_cc_account_username"] == { | ||
"[email protected]": "js_the_first", | ||
"[email protected]": "stranger.person", | ||
} | ||
|
||
# Validate the results of all of this by inspecting the database. | ||
for i in range(3): | ||
js_user = get_user(mila_email_username=f"john.smith{i:03d}@mila.quebec") | ||
|