tangled
alpha
login
or
join now
urschrei.eurosky.social
/
pyzotero
0
fork
atom
Pyzotero: a Python client for the Zotero API
pyzotero.readthedocs.io
zotero
0
fork
atom
overview
issues
pulls
pipelines
Appease Ruff
urschrei.eurosky.social
1 year ago
d5b1224d
54f2acca
+139
-103
1 changed file
expand all
collapse all
unified
split
tests
test_zotero.py
+139
-103
tests/test_zotero.py
···
863
863
def testFileUpload(self):
864
864
"""Tests file upload process with attachments"""
865
865
zot = z.Zotero("myuserID", "user", "myuserkey")
866
866
-
866
866
+
867
867
# Create a temporary file for testing
868
868
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
869
869
with open(temp_file_path, "w") as f:
870
870
f.write("Test file content for upload")
871
871
-
871
871
+
872
872
# Mock Step 0: Create preliminary item registration
873
873
-
prelim_response = {
874
874
-
"success": {
875
875
-
"0": "ITEMKEY123"
876
876
-
}
877
877
-
}
873
873
+
prelim_response = {"success": {"0": "ITEMKEY123"}}
878
874
HTTPretty.register_uri(
879
875
HTTPretty.POST,
880
876
"https://api.zotero.org/users/myuserID/items",
···
882
878
body=json.dumps(prelim_response),
883
879
status=200,
884
880
)
885
885
-
881
881
+
886
882
# Create the upload payload
887
887
-
payload = [{"filename": "test_upload_file.txt", "title": "Test File", "linkMode": "imported_file"}]
888
888
-
883
883
+
payload = [
884
884
+
{
885
885
+
"filename": "test_upload_file.txt",
886
886
+
"title": "Test File",
887
887
+
"linkMode": "imported_file",
888
888
+
}
889
889
+
]
890
890
+
889
891
# Create mock auth data to be returned by _get_auth
890
892
mock_auth_data = {
891
893
"url": "https://uploads.zotero.org/",
892
894
"params": {
893
895
"key": "abcdef1234567890",
894
896
"prefix": "prefix",
895
895
-
"suffix": "suffix"
897
897
+
"suffix": "suffix",
896
898
},
897
897
-
"uploadKey": "upload_key_123"
899
899
+
"uploadKey": "upload_key_123",
898
900
}
899
899
-
901
901
+
900
902
# Patch the necessary methods to avoid HTTP calls and file system checks
901
901
-
with patch.object(z.Zupload, '_verify', return_value=None), \
902
902
-
patch.object(z.Zupload, '_get_auth', return_value=mock_auth_data), \
903
903
-
patch.object(z.Zupload, '_upload_file', return_value=None):
903
903
+
with (
904
904
+
patch.object(z.Zupload, "_verify", return_value=None),
905
905
+
patch.object(z.Zupload, "_get_auth", return_value=mock_auth_data),
906
906
+
patch.object(z.Zupload, "_upload_file", return_value=None),
907
907
+
):
904
908
# Create the upload object and initiate upload
905
905
-
upload = z.Zupload(zot, payload, basedir=os.path.join(self.cwd, "api_responses"))
909
909
+
upload = z.Zupload(
910
910
+
zot, payload, basedir=os.path.join(self.cwd, "api_responses")
911
911
+
)
906
912
result = upload.upload()
907
907
-
913
913
+
908
914
# Verify the result structure
909
915
self.assertIn("success", result)
910
916
self.assertIn("failure", result)
911
917
self.assertIn("unchanged", result)
912
918
self.assertEqual(len(result["success"]), 1)
913
919
self.assertEqual(result["success"][0]["key"], "ITEMKEY123")
914
914
-
920
920
+
915
921
# Clean up
916
922
os.remove(temp_file_path)
917
917
-
923
923
+
918
924
@httpretty.activate
919
925
def testFileUploadExists(self):
920
926
"""Tests file upload process when the file already exists on the server"""
921
927
zot = z.Zotero("myuserID", "user", "myuserkey")
922
922
-
928
928
+
923
929
# Create a temporary file for testing
924
930
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
925
931
with open(temp_file_path, "w") as f:
926
932
f.write("Test file content for upload")
927
927
-
933
933
+
928
934
# Mock Step 0: Create preliminary item registration
929
929
-
prelim_response = {
930
930
-
"success": {
931
931
-
"0": "ITEMKEY123"
932
932
-
}
933
933
-
}
935
935
+
prelim_response = {"success": {"0": "ITEMKEY123"}}
934
936
HTTPretty.register_uri(
935
937
HTTPretty.POST,
936
938
"https://api.zotero.org/users/myuserID/items",
···
938
940
body=json.dumps(prelim_response),
939
941
status=200,
940
942
)
941
941
-
943
943
+
942
944
# Create the upload payload
943
943
-
payload = [{"filename": "test_upload_file.txt", "title": "Test File", "linkMode": "imported_file"}]
944
944
-
945
945
+
payload = [
946
946
+
{
947
947
+
"filename": "test_upload_file.txt",
948
948
+
"title": "Test File",
949
949
+
"linkMode": "imported_file",
950
950
+
}
951
951
+
]
952
952
+
945
953
# Create mock auth data to be returned by _get_auth with exists=True
946
946
-
mock_auth_data = {
947
947
-
"exists": True
948
948
-
}
949
949
-
954
954
+
mock_auth_data = {"exists": True}
955
955
+
950
956
# Patch the necessary methods to avoid HTTP calls and file system checks
951
951
-
with patch.object(z.Zupload, '_verify', return_value=None), \
952
952
-
patch.object(z.Zupload, '_get_auth', return_value=mock_auth_data):
957
957
+
with (
958
958
+
patch.object(z.Zupload, "_verify", return_value=None),
959
959
+
patch.object(z.Zupload, "_get_auth", return_value=mock_auth_data),
960
960
+
):
953
961
# Create the upload object and initiate upload
954
954
-
upload = z.Zupload(zot, payload, basedir=os.path.join(self.cwd, "api_responses"))
962
962
+
upload = z.Zupload(
963
963
+
zot, payload, basedir=os.path.join(self.cwd, "api_responses")
964
964
+
)
955
965
result = upload.upload()
956
956
-
966
966
+
957
967
# Verify the result structure
958
968
self.assertIn("success", result)
959
969
self.assertIn("failure", result)
960
970
self.assertIn("unchanged", result)
961
971
self.assertEqual(len(result["unchanged"]), 1)
962
972
self.assertEqual(result["unchanged"][0]["key"], "ITEMKEY123")
963
963
-
973
973
+
964
974
# Clean up
965
975
os.remove(temp_file_path)
966
966
-
976
976
+
967
977
@httpretty.activate
968
978
def testFileUploadWithParentItem(self):
969
979
"""Tests file upload process with a parent item ID"""
970
980
zot = z.Zotero("myuserID", "user", "myuserkey")
971
971
-
981
981
+
972
982
# Create a temporary file for testing
973
983
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
974
984
with open(temp_file_path, "w") as f:
975
985
f.write("Test file content for upload")
976
976
-
986
986
+
977
987
# Mock Step 0: Create preliminary item registration
978
978
-
prelim_response = {
979
979
-
"success": {
980
980
-
"0": "ITEMKEY123"
981
981
-
}
982
982
-
}
988
988
+
prelim_response = {"success": {"0": "ITEMKEY123"}}
983
989
HTTPretty.register_uri(
984
990
HTTPretty.POST,
985
991
"https://api.zotero.org/users/myuserID/items",
···
987
993
body=json.dumps(prelim_response),
988
994
status=200,
989
995
)
990
990
-
996
996
+
991
997
# Create the upload payload
992
992
-
payload = [{"filename": "test_upload_file.txt", "title": "Test File", "linkMode": "imported_file"}]
993
993
-
998
998
+
payload = [
999
999
+
{
1000
1000
+
"filename": "test_upload_file.txt",
1001
1001
+
"title": "Test File",
1002
1002
+
"linkMode": "imported_file",
1003
1003
+
}
1004
1004
+
]
1005
1005
+
994
1006
# Test with parent ID
995
1007
parent_id = "PARENTITEM123"
996
996
-
1008
1008
+
997
1009
# Create mock auth data to be returned by _get_auth
998
1010
mock_auth_data = {
999
1011
"url": "https://uploads.zotero.org/",
1000
1012
"params": {
1001
1013
"key": "abcdef1234567890",
1002
1014
"prefix": "prefix",
1003
1003
-
"suffix": "suffix"
1015
1015
+
"suffix": "suffix",
1004
1016
},
1005
1005
-
"uploadKey": "upload_key_123"
1017
1017
+
"uploadKey": "upload_key_123",
1006
1018
}
1007
1007
-
1019
1019
+
1008
1020
# Mock Step 1: Get upload authorization
1009
1021
HTTPretty.register_uri(
1010
1022
HTTPretty.POST,
···
1013
1025
body=json.dumps(mock_auth_data),
1014
1026
status=200,
1015
1027
)
1016
1016
-
1028
1028
+
1017
1029
# Patch the necessary methods to avoid file system checks and skip the actual upload
1018
1018
-
with patch.object(z.Zupload, '_verify', return_value=None), \
1019
1019
-
patch.object(z.Zupload, '_upload_file', return_value=None):
1030
1030
+
with (
1031
1031
+
patch.object(z.Zupload, "_verify", return_value=None),
1032
1032
+
patch.object(z.Zupload, "_upload_file", return_value=None),
1033
1033
+
):
1020
1034
# Create the upload object with a parent ID and initiate upload
1021
1021
-
upload = z.Zupload(zot, payload, parentid=parent_id, basedir=os.path.join(self.cwd, "api_responses"))
1035
1035
+
upload = z.Zupload(
1036
1036
+
zot,
1037
1037
+
payload,
1038
1038
+
parentid=parent_id,
1039
1039
+
basedir=os.path.join(self.cwd, "api_responses"),
1040
1040
+
)
1022
1041
result = upload.upload()
1023
1023
-
1042
1042
+
1024
1043
# Verify the result structure
1025
1044
self.assertIn("success", result)
1026
1045
self.assertEqual(len(result["success"]), 1)
1027
1027
-
1046
1046
+
1028
1047
# Check that the parentItem was added to the payload
1029
1048
# Get the latest request to the items endpoint
1030
1049
requests = httpretty.latest_requests()
···
1033
1052
if req.url.endswith("/items"):
1034
1053
item_request = req
1035
1054
break
1036
1036
-
1055
1055
+
1037
1056
self.assertIsNotNone(item_request, "No request found to the items endpoint")
1038
1038
-
request_body = json.loads(item_request.body.decode('utf-8'))
1057
1057
+
request_body = json.loads(item_request.body.decode("utf-8"))
1039
1058
self.assertEqual(request_body[0]["parentItem"], parent_id)
1040
1040
-
1059
1059
+
1041
1060
# Clean up
1042
1061
os.remove(temp_file_path)
1043
1043
-
1062
1062
+
1044
1063
@httpretty.activate
1045
1064
def testFileUploadFailure(self):
1046
1065
"""Tests file upload process when auth step fails"""
1047
1066
zot = z.Zotero("myuserID", "user", "myuserkey")
1048
1048
-
1067
1067
+
1049
1068
# Create a temporary file for testing
1050
1069
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
1051
1070
with open(temp_file_path, "w") as f:
1052
1071
f.write("Test file content for upload")
1053
1053
-
1072
1072
+
1054
1073
# Mock Step 0: Create preliminary item registration
1055
1055
-
prelim_response = {
1056
1056
-
"success": {
1057
1057
-
"0": "ITEMKEY123"
1058
1058
-
}
1059
1059
-
}
1074
1074
+
prelim_response = {"success": {"0": "ITEMKEY123"}}
1060
1075
HTTPretty.register_uri(
1061
1076
HTTPretty.POST,
1062
1077
"https://api.zotero.org/users/myuserID/items",
···
1064
1079
body=json.dumps(prelim_response),
1065
1080
status=200,
1066
1081
)
1067
1067
-
1082
1082
+
1068
1083
# Mock Step 1: Authorization fails with 403
1069
1084
HTTPretty.register_uri(
1070
1085
HTTPretty.POST,
1071
1086
"https://api.zotero.org/users/myuserID/items/ITEMKEY123/file",
1072
1087
status=403,
1073
1088
)
1074
1074
-
1089
1089
+
1075
1090
# Create the upload payload
1076
1076
-
payload = [{"filename": "test_upload_file.txt", "title": "Test File", "linkMode": "imported_file"}]
1077
1077
-
1091
1091
+
payload = [
1092
1092
+
{
1093
1093
+
"filename": "test_upload_file.txt",
1094
1094
+
"title": "Test File",
1095
1095
+
"linkMode": "imported_file",
1096
1096
+
}
1097
1097
+
]
1098
1098
+
1078
1099
# Patch just the _verify method to avoid file system checks, but allow the real HTTP calls
1079
1079
-
with patch.object(z.Zupload, '_verify', return_value=None):
1100
1100
+
with patch.object(z.Zupload, "_verify", return_value=None):
1080
1101
# Create the upload object and test for exception
1081
1081
-
upload = z.Zupload(zot, payload, basedir=os.path.join(self.cwd, "api_responses"))
1082
1082
-
1102
1102
+
upload = z.Zupload(
1103
1103
+
zot, payload, basedir=os.path.join(self.cwd, "api_responses")
1104
1104
+
)
1105
1105
+
1083
1106
# This should raise an error due to 403 status
1084
1107
with self.assertRaises(z.ze.UserNotAuthorisedError):
1085
1108
upload.upload()
1086
1086
-
1109
1109
+
1087
1110
# Clean up
1088
1111
os.remove(temp_file_path)
1089
1089
-
1112
1112
+
1090
1113
@httpretty.activate
1091
1114
def testFileUploadWithPreexistingKeys(self):
1092
1115
"""Tests file upload process when the payload already contains keys"""
1093
1116
zot = z.Zotero("myuserID", "user", "myuserkey")
1094
1094
-
1117
1117
+
1095
1118
# Create a temporary file for testing
1096
1119
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
1097
1120
with open(temp_file_path, "w") as f:
1098
1121
f.write("Test file content for upload")
1099
1099
-
1122
1122
+
1100
1123
# Create the upload payload with preexisting key
1101
1101
-
payload = [{"key": "PREEXISTING123", "filename": "test_upload_file.txt", "title": "Test File", "linkMode": "imported_file"}]
1102
1102
-
1124
1124
+
payload = [
1125
1125
+
{
1126
1126
+
"key": "PREEXISTING123",
1127
1127
+
"filename": "test_upload_file.txt",
1128
1128
+
"title": "Test File",
1129
1129
+
"linkMode": "imported_file",
1130
1130
+
}
1131
1131
+
]
1132
1132
+
1103
1133
# Create mock auth data to be returned by _get_auth
1104
1134
mock_auth_data = {
1105
1135
"url": "https://uploads.zotero.org/",
1106
1136
"params": {
1107
1137
"key": "abcdef1234567890",
1108
1138
"prefix": "prefix",
1109
1109
-
"suffix": "suffix"
1139
1139
+
"suffix": "suffix",
1110
1140
},
1111
1111
-
"uploadKey": "upload_key_123"
1141
1141
+
"uploadKey": "upload_key_123",
1112
1142
}
1113
1113
-
1143
1143
+
1114
1144
# Patch the necessary methods to avoid HTTP calls and file system checks
1115
1115
-
with patch.object(z.Zupload, '_verify', return_value=None), \
1116
1116
-
patch.object(z.Zupload, '_get_auth', return_value=mock_auth_data), \
1117
1117
-
patch.object(z.Zupload, '_upload_file', return_value=None):
1145
1145
+
with (
1146
1146
+
patch.object(z.Zupload, "_verify", return_value=None),
1147
1147
+
patch.object(z.Zupload, "_get_auth", return_value=mock_auth_data),
1148
1148
+
patch.object(z.Zupload, "_upload_file", return_value=None),
1149
1149
+
):
1118
1150
# Create the upload object and initiate upload
1119
1119
-
upload = z.Zupload(zot, payload, basedir=os.path.join(self.cwd, "api_responses"))
1151
1151
+
upload = z.Zupload(
1152
1152
+
zot, payload, basedir=os.path.join(self.cwd, "api_responses")
1153
1153
+
)
1120
1154
result = upload.upload()
1121
1121
-
1155
1155
+
1122
1156
# Verify the result structure
1123
1157
self.assertIn("success", result)
1124
1158
self.assertEqual(len(result["success"]), 1)
1125
1159
self.assertEqual(result["success"][0]["key"], "PREEXISTING123")
1126
1126
-
1160
1160
+
1127
1161
# No need to check for endpoint calls since we're patching the methods
1128
1128
-
1162
1162
+
1129
1163
# Clean up
1130
1164
os.remove(temp_file_path)
1131
1131
-
1165
1165
+
1132
1166
@httpretty.activate
1133
1167
def testFileUploadInvalidPayload(self):
1134
1168
"""Tests file upload process with invalid payload mixing items with and without keys"""
1135
1169
zot = z.Zotero("myuserID", "user", "myuserkey")
1136
1136
-
1170
1170
+
1137
1171
# Create a temporary file for testing
1138
1172
temp_file_path = os.path.join(self.cwd, "api_responses", "test_upload_file.txt")
1139
1173
with open(temp_file_path, "w") as f:
1140
1174
f.write("Test file content for upload")
1141
1141
-
1175
1175
+
1142
1176
# Create the invalid upload payload (mixing items with and without keys)
1143
1177
payload = [
1144
1178
{"key": "PREEXISTING123", "filename": "test_upload_file.txt"},
1145
1145
-
{"filename": "test_upload_file.txt"} # No key
1179
1179
+
{"filename": "test_upload_file.txt"}, # No key
1146
1180
]
1147
1147
-
1181
1181
+
1148
1182
# Patch the _verify method to avoid file system checks
1149
1149
-
with patch.object(z.Zupload, '_verify', return_value=None):
1183
1183
+
with patch.object(z.Zupload, "_verify", return_value=None):
1150
1184
# Create the upload object and test for exception
1151
1151
-
upload = z.Zupload(zot, payload, basedir=os.path.join(self.cwd, "api_responses"))
1152
1152
-
1185
1185
+
upload = z.Zupload(
1186
1186
+
zot, payload, basedir=os.path.join(self.cwd, "api_responses")
1187
1187
+
)
1188
1188
+
1153
1189
# This should raise an UnsupportedParamsError
1154
1190
with self.assertRaises(z.ze.UnsupportedParamsError):
1155
1191
upload.upload()
1156
1156
-
1192
1192
+
1157
1193
# Clean up
1158
1194
os.remove(temp_file_path)
1159
1195