Skip to content

Commit 7eb7492

Browse files
Update tests
* Simplify testing by making 'source_config.json' and 'source_metadata.csv' serve as test data * Add fixture 'mocked_s3_bucket_bitstreams' to show full S3 file path for bitstreams * Add fixture for metadata csv with 'bitstreams' column (test/fixtures/updated-source_metadata.csv) * Update fixture 'web_mock' to clarify mocked requests: * Update test_cli.py to use updated CLI command args * Deprecate 'mocked_s3' fixture
1 parent 12767a5 commit 7eb7492

7 files changed

+228
-205
lines changed

tests/conftest.py

+130-82
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import csv
22
import json
3+
import yaml
34

45
import boto3
56
import pytest
67
import requests_mock
8+
import smart_open
9+
710
from click.testing import CliRunner
811
from moto import mock_aws
912

@@ -19,6 +22,33 @@ def _test_environment(monkeypatch):
1922
monkeypatch.setenv("AWS_SESSION_TOKEN", "testing")
2023

2124

25+
@pytest.fixture
26+
def source_config():
27+
with smart_open.open("tests/fixtures/source_config.json", "r") as file:
28+
return yaml.safe_load(file)
29+
30+
31+
@pytest.fixture
32+
def source_metadata_csv():
33+
with open("tests/fixtures/source_metadata.csv") as file:
34+
reader = csv.DictReader(file)
35+
yield reader
36+
37+
38+
@pytest.fixture()
39+
def dspace_client():
40+
dspace_client = dspace.DSpaceClient("mock://example.com/")
41+
dspace_client.header = {}
42+
dspace_client.cookies = {}
43+
dspace_client.user_full_name = ""
44+
return dspace_client
45+
46+
47+
@pytest.fixture()
48+
def s3_client():
49+
return boto3.client("s3", region_name="us-east-1")
50+
51+
2252
@pytest.fixture
2353
def mocked_s3_bucket():
2454
bucket_name = "mocked-bucket"
@@ -57,60 +87,19 @@ def mocked_s3_bucket():
5787
yield
5888

5989

60-
@pytest.fixture()
61-
def mocked_s3():
62-
with mock_aws():
63-
s3_instance = boto3.client("s3", region_name="us-east-1")
64-
s3_instance.create_bucket(Bucket="test-bucket")
65-
s3_instance.put_object(
66-
Body="",
67-
Bucket="test-bucket",
68-
Key="test_01.pdf",
69-
)
70-
s3_instance.put_object(
71-
Body="",
72-
Bucket="test-bucket",
73-
Key="test_02.pdf",
74-
)
75-
s3_instance.put_object(
76-
Body="",
77-
Bucket="test-bucket",
78-
Key="best_01.pdf",
79-
)
80-
s3_instance.put_object(
81-
Body="",
82-
Bucket="test-bucket",
83-
Key="test_01.jpg",
84-
)
85-
yield s3_instance
86-
87-
88-
@pytest.fixture()
89-
def s3_client():
90-
return boto3.client("s3", region_name="us-east-1")
91-
92-
93-
@pytest.fixture()
94-
def dspace_client():
95-
dspace_client = dspace.DSpaceClient("mock://example.com/")
96-
dspace_client.header = {}
97-
dspace_client.cookies = {}
98-
dspace_client.user_full_name = ""
99-
return dspace_client
100-
101-
102-
@pytest.fixture()
103-
def aspace_delimited_csv():
104-
with open("tests/fixtures/aspace_metadata_delimited.csv") as f:
105-
reader = csv.DictReader(f)
106-
yield reader
107-
108-
109-
@pytest.fixture()
110-
def aspace_mapping():
111-
with open("config/aspace_mapping.json") as f:
112-
mapping = json.load(f)
113-
yield mapping
90+
@pytest.fixture
91+
def mocked_s3_bucket_bitstreams():
92+
return {
93+
"001": ["s3://mocked-bucket/one-to-one/aaaa_001_01.pdf"],
94+
"002": ["s3://mocked-bucket/one-to-one/aaaa_002_01.pdf"],
95+
"003": [
96+
"s3://mocked-bucket/many-to-one/bbbb_003_01.jpg",
97+
"s3://mocked-bucket/many-to-one/bbbb_003_01.pdf",
98+
"s3://mocked-bucket/many-to-one/bbbb_003_02.pdf",
99+
],
100+
"004": ["s3://mocked-bucket/many-to-one/bbbb_004_01.pdf"],
101+
"005": ["s3://mocked-bucket/nested/prefix/objects/include_005_01.pdf"],
102+
}
114103

115104

116105
@pytest.fixture()
@@ -127,34 +116,93 @@ def runner():
127116

128117
@pytest.fixture(autouse=True)
129118
def web_mock():
130-
with requests_mock.Mocker() as m:
119+
with requests_mock.Mocker() as mocked_request:
120+
# DSpace authentication
131121
cookies = {"JSESSIONID": "11111111"}
132-
m.post("mock://example.com/login", cookies=cookies)
122+
mocked_request.post("mock://example.com/login", cookies=cookies)
133123
user_json = {"fullname": "User Name"}
134-
m.get("mock://example.com/status", json=user_json)
135-
rec_json = {"metadata": {"title": "Sample title"}, "type": "item"}
136-
m.get("mock://example.com/items/123?expand=all", json=rec_json)
137-
results_json1 = {"items": [{"link": "1234"}]}
138-
results_json2 = {"items": []}
139-
m.get(
140-
"mock://example.com/filtered-items?",
141-
[{"json": results_json1}, {"json": results_json2}],
124+
mocked_request.get("mock://example.com/status", json=user_json)
125+
126+
# get - retrieve item
127+
item_get_url = "mock://example.com/items/123?expand=all"
128+
item_get_response = {"metadata": {"title": "Sample title"}, "type": "item"}
129+
mocked_request.get(item_get_url, json=item_get_response)
130+
131+
# get - retrieve uuid from handle
132+
uuid_get_url = "mock://example.com/handle/111.1111"
133+
uuid_get_response = {"uuid": "a1b2"}
134+
mocked_request.get(uuid_get_url, json=uuid_get_response)
135+
136+
# get - retrieve uuid from handle (for test_cli.test_additems )
137+
uuid_get_url_2 = "mock://example.com/handle/333.3333"
138+
uuid_get_response_2 = {"uuid": "k1l2"}
139+
mocked_request.get(uuid_get_url_2, json=uuid_get_response_2)
140+
141+
# get - retrieve filtered set of items
142+
filtered_items_get_url = "mock://example.com/filtered-items?"
143+
filtered_items_get_response = [
144+
{"json": {"items": [{"link": "1234"}]}},
145+
{"json": {"items": []}},
146+
]
147+
mocked_request.get(filtered_items_get_url, filtered_items_get_response)
148+
149+
# post - add collection to community
150+
collection_post_url = "mock://example.com/communities/a1b2/collections"
151+
collection_post_response = {"uuid": "c3d4"}
152+
mocked_request.post(collection_post_url, json=collection_post_response)
153+
154+
# post - add item to collection
155+
item_post_url = "mock://example.com/collections/c3d4/items"
156+
item_post_response = {"uuid": "e5f6", "handle": "222.2222"}
157+
mocked_request.post(item_post_url, json=item_post_response)
158+
159+
# post - add item to collection (for test_cli.test_additems)
160+
item_post_url_2 = "mock://example.com/collections/k1l2/items"
161+
item_post_response_2 = {"uuid": "e5f6", "handle": "222.2222"}
162+
mocked_request.post(item_post_url_2, json=item_post_response_2)
163+
164+
# post - add bitstream to item
165+
bitstream_post_url = (
166+
"mock://example.com/items/e5f6/bitstreams?name=aaaa_001_01.pdf"
167+
)
168+
bitstream_post_response = {"uuid": "g7h8"}
169+
mocked_request.post(bitstream_post_url, json=bitstream_post_response)
170+
171+
bitstream_post_url_2 = (
172+
"mock://example.com/items/e5f6/bitstreams?name=aaaa_002_01.pdf"
173+
)
174+
bitstream_post_response_2 = {"uuid": "i9j0"}
175+
mocked_request.post(bitstream_post_url_2, json=bitstream_post_response_2)
176+
177+
bitstream_post_url_3 = (
178+
"mock://example.com/items/e5f6/bitstreams?name=bbbb_003_01.jpg"
179+
)
180+
bitstream_post_response_3 = {"uuid": "item_003_01_a"}
181+
mocked_request.post(bitstream_post_url_3, json=bitstream_post_response_3)
182+
183+
bitstream_post_url_4 = (
184+
"mock://example.com/items/e5f6/bitstreams?name=bbbb_003_01.pdf"
185+
)
186+
bitstream_post_response_4 = {"uuid": "item_003_01_b"}
187+
mocked_request.post(bitstream_post_url_4, json=bitstream_post_response_4)
188+
189+
bitstream_post_url_5 = (
190+
"mock://example.com/items/e5f6/bitstreams?name=bbbb_003_02.pdf"
191+
)
192+
bitstream_post_response_5 = {"uuid": "item_003_02_a"}
193+
mocked_request.post(bitstream_post_url_5, json=bitstream_post_response_5)
194+
195+
bitstream_post_url_6 = (
196+
"mock://example.com/items/e5f6/bitstreams?name=bbbb_004_01.pdf"
197+
)
198+
bitstream_post_response_6 = {"uuid": "item_004_01_a"}
199+
mocked_request.post(bitstream_post_url_6, json=bitstream_post_response_6)
200+
201+
bitstream_post_url_7 = (
202+
"mock://example.com/items/e5f6/bitstreams?name=include_005_01.pdf"
142203
)
143-
rec_json = {"uuid": "a1b2"}
144-
m.get("mock://example.com/handle/111.1111", json=rec_json)
145-
coll_json = {"uuid": "c3d4"}
146-
m.post("mock://example.com/communities/a1b2/collections", json=coll_json)
147-
item_json = {"uuid": "e5f6", "handle": "222.2222"}
148-
m.post("mock://example.com/collections/c3d4/items", json=item_json)
149-
b_json_1 = {"uuid": "g7h8"}
150-
url_1 = "mock://example.com/items/e5f6/bitstreams?name=test_01.pdf"
151-
m.post(url_1, json=b_json_1)
152-
b_json_2 = {"uuid": "i9j0"}
153-
url_2 = "mock://example.com/items/e5f6/bitstreams?name=test_02.pdf"
154-
m.post(url_2, json=b_json_2)
155-
m.get("mock://remoteserver.com/files/test_01.pdf", content=b"Sample")
156-
coll_json = {"uuid": "k1l2"}
157-
m.get("mock://example.com/handle/333.3333", json=coll_json)
158-
item_json_2 = {"uuid": "e5f6", "handle": "222.2222"}
159-
m.post("mock://example.com/collections/k1l2/items", json=item_json_2)
160-
yield m
204+
bitstream_post_response_7 = {"uuid": "item_005_01_a"}
205+
mocked_request.post(bitstream_post_url_7, json=bitstream_post_response_7)
206+
# mocked_request.get("mock://remoteserver.com/files/test_01.pdf", content=b"Sample")
207+
208+
yield mocked_request

tests/fixtures/source_config.json

+4-26
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
{
22
"settings": {
3-
"bitstream_folders": [
4-
"objects"
5-
],
6-
"id_regex": ".*-(.*?-.*)\\..*$"
3+
"bitstream_folders": [],
4+
"id_regex": "_(.*)_"
75
},
86
"mapping": {
9-
"file_identifier": {
10-
"csv_field_name": "file_identifier",
7+
"item_identifier": {
8+
"csv_field_name": "item_identifier",
119
"language": null,
1210
"delimiter": ""
1311
},
@@ -16,30 +14,10 @@
1614
"language": "en_US",
1715
"delimiter": ""
1816
},
19-
"source_system_identifier": {
20-
"csv_field_name": "uri",
21-
"language": null,
22-
"delimiter": ""
23-
},
2417
"dc.contributor.author": {
2518
"csv_field_name": "author",
2619
"language": null,
2720
"delimiter": "|"
28-
},
29-
"dc.description": {
30-
"csv_field_name": "description",
31-
"language": "en_US",
32-
"delimiter": ""
33-
},
34-
"dc.rights": {
35-
"csv_field_name": "rights_statement",
36-
"language": "en_US",
37-
"delimiter": ""
38-
},
39-
"dc.rights.uri": {
40-
"csv_field_name": "rights_uri",
41-
"language": null,
42-
"delimiter": ""
4321
}
4422
}
4523
}

tests/fixtures/source_metadata.csv

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
item_identifier,title,author
2+
001,Title 1,May Smith
3+
002,Title 2,May Smith
4+
003,Title 3,June Smith
5+
004,Title 4,June Smith
6+
005,Title 5,July Smith
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
item_identifier,title,author,bitstreams
2+
001,Title 1,May Smith,['s3://mocked-bucket/one-to-one/aaaa_001_01.pdf']
3+
002,Title 2,May Smith,['s3://mocked-bucket/one-to-one/aaaa_002_01.pdf']
4+
003,Title 3,June Smith,"['s3://mocked-bucket/many-to-one/bbbb_003_01.jpg', 's3://mocked-bucket/many-to-one/bbbb_003_01.pdf', 's3://mocked-bucket/many-to-one/bbbb_003_02.pdf']"
5+
004,Title 4,June Smith,['s3://mocked-bucket/many-to-one/bbbb_004_01.pdf']
6+
005,Title 5,July Smith,['s3://mocked-bucket/nested/prefix/objects/include_005_01.pdf']

tests/test_cli.py

+9-16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55

66
@mock_aws
7-
def test_additems(runner, mocked_s3):
7+
def test_additems(runner, mocked_s3_bucket, caplog):
88
"""Test adding items to a collection."""
99
result = runner.invoke(
1010
main,
@@ -19,18 +19,15 @@ def test_additems(runner, mocked_s3):
1919
"1234",
2020
"additems",
2121
"--metadata-csv",
22-
"tests/fixtures/aspace_metadata_delimited.csv",
23-
"--field-map",
24-
"config/aspace_mapping.json",
22+
"tests/fixtures/updated-source_metadata.csv",
2523
"--content-directory",
26-
"s3://test-bucket",
27-
"--file-type",
28-
"pdf",
24+
"s3://mocked-bucket",
2925
"--collection-handle",
3026
"333.3333",
3127
],
3228
)
3329
assert result.exit_code == 0
30+
3431
result = runner.invoke(
3532
main,
3633
[
@@ -49,13 +46,9 @@ def test_additems(runner, mocked_s3):
4946
"Test Collection",
5047
"additems",
5148
"--metadata-csv",
52-
"tests/fixtures/aspace_metadata_delimited.csv",
53-
"--field-map",
54-
"config/aspace_mapping.json",
49+
"tests/fixtures/updated-source_metadata.csv",
5550
"--content-directory",
56-
"s3://test-bucket",
57-
"--file-type",
58-
"pdf",
51+
"s3://mocked-bucket",
5952
],
6053
)
6154
assert result.exit_code == 0
@@ -85,7 +78,7 @@ def test_newcollection(runner):
8578

8679

8780
@mock_aws
88-
def test_reconcile(runner, mocked_s3, output_dir):
81+
def test_reconcile(runner, mocked_s3_bucket, output_dir):
8982
"""Test reconcile command."""
9083
result = runner.invoke(
9184
main,
@@ -100,11 +93,11 @@ def test_reconcile(runner, mocked_s3, output_dir):
10093
"1234",
10194
"reconcile",
10295
"--metadata-csv",
103-
"tests/fixtures/aspace_metadata_delimited.csv",
96+
"tests/fixtures/source_metadata.csv",
10497
"--output-directory",
10598
output_dir,
10699
"--content-directory",
107-
"s3://test-bucket",
100+
"s3://mocked-bucket",
108101
],
109102
)
110103
assert result.exit_code == 0

0 commit comments

Comments
 (0)