Skip to content

Commit

Permalink
Extend unit test to check that new manual matches are indeed saved in…
Browse files Browse the repository at this point in the history
… JSON file.
  • Loading branch information
notoraptor committed Jul 26, 2023
1 parent 0e2d731 commit 0940717
Showing 1 changed file with 85 additions and 2 deletions.
87 changes: 85 additions & 2 deletions tests/functional/cli/acquire/test_acquire_users.py
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
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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

Expand All @@ -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).
Expand All @@ -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(
[
Expand All @@ -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")
Expand Down

0 comments on commit 0940717

Please sign in to comment.