das-cli 1.2.5__tar.gz → 1.2.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {das_cli-1.2.5/das_cli.egg-info → das_cli-1.2.14}/PKG-INFO +1 -1
- {das_cli-1.2.5 → das_cli-1.2.14}/das/cli.py +42 -31
- {das_cli-1.2.5 → das_cli-1.2.14}/das/common/entry_fields_constants.py +2 -1
- {das_cli-1.2.5 → das_cli-1.2.14}/das/common/file_utils.py +3 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/managers/entries_manager.py +68 -29
- {das_cli-1.2.5 → das_cli-1.2.14/das_cli.egg-info}/PKG-INFO +1 -1
- {das_cli-1.2.5 → das_cli-1.2.14}/pyproject.toml +1 -1
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/entries_manager_test.py +60 -7
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/file_utils_test.py +6 -6
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/search_manager_test.py +1 -1
- {das_cli-1.2.5 → das_cli-1.2.14}/LICENSE +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/MANIFEST.in +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/README.md +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/__init__.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/ai/plugins/dasai.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/ai/plugins/entries/entries_plugin.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/app.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/authentication/auth.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/authentication/secure_input.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/common/api.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/common/config.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/common/enums.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/managers/__init__.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/managers/digital_objects_manager.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/managers/download_manager.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/managers/search_manager.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/attributes.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/cache.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/digital_objects.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/downloads.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/entries.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/entry_fields.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/hangfire.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/search.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das/services/users.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das_cli.egg-info/SOURCES.txt +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das_cli.egg-info/dependency_links.txt +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das_cli.egg-info/entry_points.txt +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das_cli.egg-info/requires.txt +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/das_cli.egg-info/top_level.txt +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/setup.cfg +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/__init__.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/attributes_test.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/download_manager_test.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/entries_service_test.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/entries_test.py +0 -0
- {das_cli-1.2.5 → das_cli-1.2.14}/tests/run_tests.py +0 -0
|
@@ -290,38 +290,39 @@ def entry():
|
|
|
290
290
|
pass
|
|
291
291
|
|
|
292
292
|
@entry.command("update")
|
|
293
|
-
@click.option('--
|
|
294
|
-
@click.option('--code', help='Entry code to update (only used
|
|
293
|
+
@click.option('--id', default=None, help='Entry ID to update (only used with --data for single entry)')
|
|
294
|
+
@click.option('--code', default=None, help='Entry code to update (only used with --data for single entry)')
|
|
295
295
|
@click.argument('file_path', required=False)
|
|
296
296
|
@click.option('--data', help='Data string in format { "key1": "value1", "key2": "value2", ... } or a list of such objects')
|
|
297
297
|
@pass_das_context
|
|
298
|
-
def update_entry(das_ctx,
|
|
299
|
-
"""Update entries from file or data string
|
|
298
|
+
def update_entry(das_ctx, id, code, file_path, data):
|
|
299
|
+
"""Update entries from file or data string by ID or code.
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
For single updates, provide either --id or --code (or Id/Code in the data).
|
|
302
|
+
For bulk updates, each entry must contain a Code or Id field.
|
|
302
303
|
Files can contain multiple entries (rows in CSV/XLS or list of objects in JSON).
|
|
303
304
|
|
|
304
305
|
Examples:
|
|
305
306
|
|
|
306
307
|
\b
|
|
307
|
-
# Update
|
|
308
|
-
das entry update --
|
|
308
|
+
# Update by code from data string
|
|
309
|
+
das entry update --code ENT001 --data "{ 'Grant Public Access': 'Yes' }"
|
|
309
310
|
|
|
310
311
|
\b
|
|
311
|
-
# Update
|
|
312
|
-
das entry update --
|
|
312
|
+
# Update by ID from data string
|
|
313
|
+
das entry update --id 9b826efc-36f3-471c-ad18-9c1e00abe4fa --data "{ 'Name': 'Updated' }"
|
|
313
314
|
|
|
314
315
|
\b
|
|
315
|
-
# Update entries from
|
|
316
|
-
das entry update
|
|
316
|
+
# Update entries from JSON file (each object needs Code or Id)
|
|
317
|
+
das entry update c:\\data\\entries.json
|
|
317
318
|
|
|
318
319
|
\b
|
|
319
|
-
# Update
|
|
320
|
-
das entry update
|
|
320
|
+
# Update entries from CSV file
|
|
321
|
+
das entry update c:\\data\\entries.csv
|
|
321
322
|
|
|
322
323
|
\b
|
|
323
324
|
# Update multiple entries from data string
|
|
324
|
-
das entry update --
|
|
325
|
+
das entry update --data "[{ 'Code': 'ENT001', ... }, { 'Code': 'ENT002', ... }]"
|
|
325
326
|
"""
|
|
326
327
|
try:
|
|
327
328
|
# Ensure client and entry_manager are initialized
|
|
@@ -341,13 +342,14 @@ def update_entry(das_ctx, attribute, code=None, file_path=None, data=None):
|
|
|
341
342
|
is_bulk_update = True
|
|
342
343
|
click.echo(f"Found {len(entry_data)} entries to update")
|
|
343
344
|
else:
|
|
344
|
-
# If we got a single object but no code was provided, check if it has
|
|
345
|
-
if not code:
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if not
|
|
349
|
-
raise click.UsageError("No code provided and entry data doesn't contain
|
|
350
|
-
|
|
345
|
+
# If we got a single object but no id/code was provided, check if it has Id or Code in data
|
|
346
|
+
if not id and not code:
|
|
347
|
+
data_id = next((entry_data.get(key) for key in entry_data if key.lower() == 'id'), None)
|
|
348
|
+
data_code = next((entry_data.get(key) for key in entry_data if key.lower() == 'code'), None)
|
|
349
|
+
if not data_id and not data_code:
|
|
350
|
+
raise click.UsageError("No --id or --code provided and entry data doesn't contain an Id or Code field")
|
|
351
|
+
id = id or data_id
|
|
352
|
+
code = code or data_code
|
|
351
353
|
|
|
352
354
|
elif data:
|
|
353
355
|
click.echo("Parsing data string")
|
|
@@ -357,19 +359,25 @@ def update_entry(das_ctx, attribute, code=None, file_path=None, data=None):
|
|
|
357
359
|
if isinstance(entry_data, list):
|
|
358
360
|
is_bulk_update = True
|
|
359
361
|
click.echo(f"Found {len(entry_data)} entries to update")
|
|
360
|
-
elif not code:
|
|
361
|
-
# If we got a single object but no code was provided, check if it has
|
|
362
|
-
|
|
363
|
-
if
|
|
364
|
-
|
|
365
|
-
|
|
362
|
+
elif not id and not code:
|
|
363
|
+
# If we got a single object but no id/code was provided, check if it has Id or Code in data
|
|
364
|
+
data_id = next((entry_data.get(key) for key in entry_data if key.lower() == 'id'), None)
|
|
365
|
+
data_code = next((entry_data.get(key) for key in entry_data if key.lower() == 'code'), None)
|
|
366
|
+
if not data_id and not data_code:
|
|
367
|
+
raise click.UsageError("No --id or --code provided and data doesn't contain an Id or Code field")
|
|
368
|
+
id = id or data_id
|
|
369
|
+
code = code or data_code
|
|
366
370
|
|
|
367
371
|
if not entry_data:
|
|
368
372
|
raise click.UsageError("No valid entry data found")
|
|
369
373
|
|
|
374
|
+
# For single entry update, require id or code
|
|
375
|
+
if not is_bulk_update and not id and not code:
|
|
376
|
+
raise click.UsageError("Please provide either --id or --code, or include Id or Code in the data")
|
|
377
|
+
|
|
370
378
|
# Update the entries
|
|
371
379
|
if is_bulk_update:
|
|
372
|
-
results = das_ctx.entry_manager.update(
|
|
380
|
+
results = das_ctx.entry_manager.update(entries=entry_data)
|
|
373
381
|
|
|
374
382
|
# Display results
|
|
375
383
|
success_count = sum(1 for result in results if result.get('status') == 'success')
|
|
@@ -385,13 +393,16 @@ def update_entry(das_ctx, attribute, code=None, file_path=None, data=None):
|
|
|
385
393
|
click.echo("\nFailed updates:")
|
|
386
394
|
for result in results:
|
|
387
395
|
if result.get('status') == 'error':
|
|
388
|
-
|
|
396
|
+
ident = result.get('code') or result.get('id') or 'Unknown'
|
|
397
|
+
click.echo(f" {ident}: {result.get('error', 'Unknown error')}")
|
|
389
398
|
else:
|
|
390
399
|
# Single entry update
|
|
391
|
-
results = das_ctx.entry_manager.update(
|
|
400
|
+
results = das_ctx.entry_manager.update(id=id, code=code, entry=entry_data)
|
|
392
401
|
|
|
393
402
|
if results and results[0].get('status') == 'success':
|
|
394
|
-
|
|
403
|
+
identifier = id or code
|
|
404
|
+
id_label = "ID" if id else "code"
|
|
405
|
+
click.secho(f"✓ Entry '{identifier}' ({id_label}) updated successfully!", fg="green")
|
|
395
406
|
click.echo(f"Entry ID: {results[0].get('id')}")
|
|
396
407
|
else:
|
|
397
408
|
error_msg = results[0].get('error', 'No response from server') if results else 'No response from server'
|
|
@@ -67,6 +67,9 @@ def load_csv_file(file_path: str) -> List[Dict[str, Any]]:
|
|
|
67
67
|
|
|
68
68
|
if not headers:
|
|
69
69
|
raise ValueError("CSV file is empty or has no headers")
|
|
70
|
+
|
|
71
|
+
# Strip leading/trailing whitespace from column headers
|
|
72
|
+
headers = [h.strip() for h in headers]
|
|
70
73
|
|
|
71
74
|
result = []
|
|
72
75
|
for row in reader:
|
|
@@ -4,7 +4,7 @@ from das.managers.search_manager import SearchManager
|
|
|
4
4
|
from das.services.attributes import AttributesService
|
|
5
5
|
from das.services.entry_fields import EntryFieldsService
|
|
6
6
|
from das.services.entries import EntriesService
|
|
7
|
-
from das.common.entry_fields_constants import DIGITAL_OBJECT_INPUT, SELECT_COMBO_INPUT
|
|
7
|
+
from das.common.entry_fields_constants import DIGITAL_OBJECT_INPUT, SELECT_COMBO_INPUT, GROUP_BOX_INPUT
|
|
8
8
|
from das.services.search import SearchService
|
|
9
9
|
from das.services.users import UsersService
|
|
10
10
|
|
|
@@ -161,18 +161,26 @@ class EntryManager:
|
|
|
161
161
|
|
|
162
162
|
new_entry = {}
|
|
163
163
|
|
|
164
|
+
# all keys must be strings and lowercase
|
|
165
|
+
entry = {str(k).lower(): v for k, v in entry.items()}
|
|
166
|
+
|
|
164
167
|
for field in fields:
|
|
165
|
-
field_name = field.get("displayName")
|
|
168
|
+
field_name = field.get("displayName").lower()
|
|
166
169
|
column_name = field.get("column").lower()
|
|
167
170
|
|
|
168
|
-
if
|
|
169
|
-
new_entry
|
|
171
|
+
if field.get('inputType') == GROUP_BOX_INPUT:
|
|
172
|
+
new_entry = self.__set_group_box_field_value(new_entry, field, entry)
|
|
170
173
|
else:
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
if field_name in entry:
|
|
175
|
+
new_entry[column_name] = self.__get_value(field, entry[field_name])
|
|
176
|
+
elif column_name in entry:
|
|
177
|
+
new_entry[column_name] = self.__get_value(field, entry[column_name])
|
|
178
|
+
else:
|
|
179
|
+
new_entry[column_name] = None
|
|
180
|
+
|
|
173
181
|
return self.entry_service.create(attribute_id=attribute_id, entry=new_entry)
|
|
174
182
|
|
|
175
|
-
def update(self,
|
|
183
|
+
def update(self, id: str = None, code: str = None, entry: dict = None, entries: list = None) -> list:
|
|
176
184
|
"""
|
|
177
185
|
Update one or more existing entries.
|
|
178
186
|
|
|
@@ -180,7 +188,7 @@ class EntryManager:
|
|
|
180
188
|
If 'entries' is provided, updates multiple entries based on the code in each entry.
|
|
181
189
|
|
|
182
190
|
Args:
|
|
183
|
-
|
|
191
|
+
id (str, optional): The entry ID for single entry update
|
|
184
192
|
code (str, optional): The entry code for single entry update
|
|
185
193
|
entry (dict, optional): The entry data for single entry update
|
|
186
194
|
entries (list, optional): List of entry data for multiple updates
|
|
@@ -206,42 +214,48 @@ class EntryManager:
|
|
|
206
214
|
|
|
207
215
|
# Each entry must have a Code field
|
|
208
216
|
entry_code = next((entry_data.get(key) for key in entry_data if key.lower() == 'code'), None)
|
|
217
|
+
entry_id = next((entry_data.get(key) for key in entry_data if key.lower() == 'id'), None)
|
|
209
218
|
if not entry_code:
|
|
210
|
-
|
|
219
|
+
entry_data['code'] = code
|
|
220
|
+
if not entry_id:
|
|
221
|
+
entry_data['id'] = id
|
|
211
222
|
|
|
212
223
|
try:
|
|
213
|
-
result = self._update_single_entry(
|
|
224
|
+
result = self._update_single_entry(id=id, code=code, entry=entry_data)
|
|
214
225
|
results.append({"code": entry_code, "id": result, "status": "success"})
|
|
215
226
|
except Exception as e:
|
|
216
227
|
results.append({"code": entry_code, "error": str(e), "status": "error"})
|
|
217
228
|
|
|
218
229
|
return results
|
|
219
230
|
|
|
220
|
-
elif code and entry:
|
|
231
|
+
elif (code or id) and entry:
|
|
221
232
|
# Single entry update
|
|
222
|
-
result = self._update_single_entry(
|
|
233
|
+
result = self._update_single_entry(id=id, code=code, entry=entry)
|
|
223
234
|
return [{"code": code, "id": result, "status": "success"}]
|
|
224
235
|
|
|
225
236
|
else:
|
|
226
|
-
raise ValueError("Either 'code' and 'entry' or 'entries' must be provided")
|
|
237
|
+
raise ValueError("Either 'id', 'code' and 'entry' or 'entries' must be provided")
|
|
227
238
|
|
|
228
|
-
def _update_single_entry(self,
|
|
239
|
+
def _update_single_entry(self, id: str = None, code: str = None, entry: dict = None) -> str:
|
|
229
240
|
"""Internal method to update a single entry."""
|
|
230
|
-
if not code:
|
|
231
|
-
raise ValueError("Entry code is required")
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
241
|
+
if not id and not code:
|
|
242
|
+
raise ValueError("Entry ID or code is required")
|
|
243
|
+
if id:
|
|
244
|
+
if not entry:
|
|
245
|
+
raise ValueError("Entry data is required")
|
|
246
|
+
existing_entry_response = self.entry_service.get(id=id)
|
|
247
|
+
elif code:
|
|
248
|
+
existing_entry_response = self.entry_service.get(code=code)
|
|
249
|
+
else:
|
|
250
|
+
raise ValueError("Entry ID or code is required")
|
|
237
251
|
|
|
238
252
|
if not existing_entry_response or not isinstance(existing_entry_response, dict):
|
|
239
253
|
raise ValueError(f"Invalid existing entry response: {existing_entry_response}")
|
|
240
254
|
|
|
241
255
|
attribute_id = existing_entry_response.get("attributeId")
|
|
242
256
|
|
|
243
|
-
#
|
|
244
|
-
entry = {k.lower(): v for k, v in entry.items()}
|
|
257
|
+
# all keys must be strings and lowercase
|
|
258
|
+
entry = {str(k).lower(): v for k, v in entry.items()}
|
|
245
259
|
|
|
246
260
|
if not attribute_id:
|
|
247
261
|
raise ValueError("Attribute ID is missing in the existing entry")
|
|
@@ -259,24 +273,49 @@ class EntryManager:
|
|
|
259
273
|
updated_entry = existing_entry_response.get('entry', {})
|
|
260
274
|
|
|
261
275
|
for field in fields:
|
|
262
|
-
|
|
276
|
+
|
|
277
|
+
field_name = field.get("displayName").lower()
|
|
263
278
|
column_name = field.get("column").lower()
|
|
264
279
|
|
|
265
|
-
if
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
updated_entry[column_name] = self.__get_value(field, entry[column_name])
|
|
280
|
+
if field.get('inputType') == GROUP_BOX_INPUT:
|
|
281
|
+
# remove the column from the entry
|
|
282
|
+
updated_entry = self.__set_group_box_field_value(updated_entry, field, entry)
|
|
269
283
|
else:
|
|
270
|
-
|
|
284
|
+
if field_name in entry:
|
|
285
|
+
updated_entry[column_name] = self.__get_value(field, entry[field_name])
|
|
286
|
+
elif column_name in entry:
|
|
287
|
+
updated_entry[column_name] = self.__get_value(field, entry[column_name])
|
|
288
|
+
else:
|
|
289
|
+
updated_entry[column_name] = None
|
|
271
290
|
|
|
272
291
|
return self.entry_service.update(attribute_id=attribute_id, entry=updated_entry)
|
|
273
292
|
|
|
293
|
+
def __set_group_box_field_value(self, current_entry: dict, field, entry: dict) -> dict:
|
|
294
|
+
"""Helper method to set group box field value."""
|
|
295
|
+
custom_data = field.get('customData', None)
|
|
296
|
+
if custom_data is not None:
|
|
297
|
+
custom_data = json.loads(custom_data)
|
|
298
|
+
if custom_data.get('fields') is not None:
|
|
299
|
+
for field in custom_data.get('fields'):
|
|
300
|
+
field_name = field.get("displayName").lower()
|
|
301
|
+
column_name = field.get("column").lower()
|
|
302
|
+
if field_name in entry:
|
|
303
|
+
current_entry[column_name] = self.__get_value(field, entry[field_name])
|
|
304
|
+
elif column_name in entry:
|
|
305
|
+
current_entry[column_name] = self.__get_value(field, entry[column_name])
|
|
306
|
+
else:
|
|
307
|
+
current_entry[column_name] = None
|
|
308
|
+
|
|
309
|
+
return current_entry
|
|
274
310
|
|
|
275
311
|
def __get_value(self, field, source: str):
|
|
276
312
|
"""Helper method to get field value based on its type."""
|
|
277
313
|
if field.get('inputType') == SELECT_COMBO_INPUT: # SELECT_COMBO_INPUT
|
|
278
314
|
select_value = self.__get_select_combobox_field_value(field, source)
|
|
279
315
|
return select_value
|
|
316
|
+
elif field.get('inputType') == GROUP_BOX_INPUT:
|
|
317
|
+
# group_box_value = self.__get_group_box_field_value(entry_raw, field)
|
|
318
|
+
return None
|
|
280
319
|
else:
|
|
281
320
|
return source
|
|
282
321
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import code
|
|
1
2
|
from dotenv import load_dotenv
|
|
2
3
|
import unittest
|
|
3
4
|
import os
|
|
@@ -95,10 +96,24 @@ class TestEntriesManager(unittest.TestCase):
|
|
|
95
96
|
"27": "ca9ab414-31e1-4aa7-98b9-b69744ffee92"
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
updated_entry_id = self.entry_manager.update(
|
|
99
|
+
updated_entry_id = self.entry_manager.update(id="9b826efc-36f3-471c-ad18-9c1e00abe4fa", entry=updated_entry_data)
|
|
99
100
|
self.assertIsNotNone(updated_entry_id)
|
|
100
101
|
self.assertRegex(updated_entry_id[0]['id'], r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
|
|
101
102
|
|
|
103
|
+
def test_update_entry_by_code(self):
|
|
104
|
+
"""Test updating an entry"""
|
|
105
|
+
|
|
106
|
+
updated_entry_data = {
|
|
107
|
+
"Availability": "pc.b.c",
|
|
108
|
+
"Number" : 2,
|
|
109
|
+
"diameterincm": 15,
|
|
110
|
+
"27": "#2319-03_03HM"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
updated_entry_id = self.entry_manager.update(code="zb.b.0", entry=updated_entry_data)
|
|
114
|
+
self.assertIsNotNone(updated_entry_id)
|
|
115
|
+
self.assertRegex(updated_entry_id[0]['id'], r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
|
|
116
|
+
|
|
102
117
|
|
|
103
118
|
def test_create_entry_with_json_file(self):
|
|
104
119
|
"""Test creating an entry from a JSON file"""
|
|
@@ -108,12 +123,50 @@ class TestEntriesManager(unittest.TestCase):
|
|
|
108
123
|
|
|
109
124
|
def test_create_entry_with_csv_file(self):
|
|
110
125
|
"""Test creating an entry from a CSV file"""
|
|
111
|
-
file_path = os.path.join(os.path.dirname(__file__), 'test_data', '
|
|
126
|
+
file_path = os.path.join(os.path.dirname(__file__), 'test_data', 'sample_entry.csv')
|
|
112
127
|
self.entry_manager.create_from_file(attribute="Cores", file_path=file_path)
|
|
113
128
|
# If no exception is raised, the test is considered passed for this example
|
|
114
129
|
|
|
115
|
-
def test_create_entry_with_excel_file(self):
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
# def test_create_entry_with_excel_file(self):
|
|
131
|
+
# """Test creating an entry from an Excel file"""
|
|
132
|
+
# file_path = os.path.join(os.path.dirname(__file__), 'test_data', 'entry_data.xlsx')
|
|
133
|
+
# self.entry_manager.create_from_file(attribute="Cores", file_path=file_path)
|
|
134
|
+
# # If no exception is raised, the test is considered passed for this example
|
|
135
|
+
|
|
136
|
+
def test_update_entry_with_column_names(self):
|
|
137
|
+
"""Test updating an entry with column names"""
|
|
138
|
+
updated_entry_data = {
|
|
139
|
+
'displayname': 'Eveline Garritsen-van Arnhem',
|
|
140
|
+
'personid': 100015,
|
|
141
|
+
'name': 'Eveline',
|
|
142
|
+
'surname': 'Garritsen-van Arnhem',
|
|
143
|
+
'phonenumber': '+31222369559',
|
|
144
|
+
'emailaddress': 'eveline.garritsen@nioz.nl',
|
|
145
|
+
'jobtitle': 'Research Assistant',
|
|
146
|
+
'DutchJobTitle': 'Onderzoekmedewerker',
|
|
147
|
+
'contractenddate': '2034-12-01',
|
|
148
|
+
'showuntildate': '2034-12-01',
|
|
149
|
+
'educationaltitle': 'ing.',
|
|
150
|
+
'educationaldegree': None,
|
|
151
|
+
'location': 'T',
|
|
152
|
+
'taborder': 3,
|
|
153
|
+
'IsDefaultProfileOnWebsite': False,
|
|
154
|
+
'isPrivate': True,
|
|
155
|
+
'128': [{'id': 'd080b26e-2db0-4d68-acae-44c3a7399c51', 'attributeid': 128}]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
updated_entry_id = self.entry_manager.update(id="994a9fa5-5ccb-11f0-aafa-a84a63c8db73", entry=updated_entry_data)
|
|
159
|
+
self.assertIsNotNone(updated_entry_id[0]['id'])
|
|
160
|
+
self.assertRegex(updated_entry_id[0]['id'], r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
|
|
161
|
+
|
|
162
|
+
def test_create_entry_with_column_names(self):
|
|
163
|
+
"""Test creating an entry with column names"""
|
|
164
|
+
created_entry_data = {
|
|
165
|
+
'displayname': 'Maximilian Garritsen-van Arnhem',
|
|
166
|
+
'personid': 100099,
|
|
167
|
+
'name': 'Maximilian',
|
|
168
|
+
'surname': 'Garritsen-van Arnhem',
|
|
169
|
+
}
|
|
170
|
+
created_entry_id = self.entry_manager.create(attribute="Person", entry=created_entry_data)
|
|
171
|
+
self.assertIsNotNone(created_entry_id[0]['id'])
|
|
172
|
+
self.assertRegex(created_entry_id[0]['id'], r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
|
|
@@ -51,9 +51,9 @@ class TestFileUtils(unittest.TestCase):
|
|
|
51
51
|
|
|
52
52
|
# Test loading the file
|
|
53
53
|
result = load_csv_file(str(csv_path))
|
|
54
|
-
self.assertEqual(result["Name"], "Test Entry")
|
|
55
|
-
self.assertEqual(result["Description"], "Test Description")
|
|
56
|
-
self.assertEqual(result["Grant Public Access"], "Yes")
|
|
54
|
+
self.assertEqual(result[0]["Name"], "Test Entry")
|
|
55
|
+
self.assertEqual(result[0]["Description"], "Test Description")
|
|
56
|
+
self.assertEqual(result[0]["Grant Public Access"], "Yes")
|
|
57
57
|
|
|
58
58
|
def test_load_excel_file(self):
|
|
59
59
|
"""Test loading Excel file."""
|
|
@@ -74,9 +74,9 @@ class TestFileUtils(unittest.TestCase):
|
|
|
74
74
|
|
|
75
75
|
# Test loading the file
|
|
76
76
|
result = load_excel_file(str(excel_path))
|
|
77
|
-
self.assertEqual(result["Name"], "Test Entry")
|
|
78
|
-
self.assertEqual(result["Description"], "Test Description")
|
|
79
|
-
self.assertEqual(result["Grant Public Access"], "Yes")
|
|
77
|
+
self.assertEqual(result[0]["Name"], "Test Entry")
|
|
78
|
+
self.assertEqual(result[0]["Description"], "Test Description")
|
|
79
|
+
self.assertEqual(result[0]["Grant Public Access"], "Yes")
|
|
80
80
|
except ImportError:
|
|
81
81
|
self.skipTest("pandas not installed, skipping Excel test")
|
|
82
82
|
|
|
@@ -11,7 +11,7 @@ load_dotenv()
|
|
|
11
11
|
|
|
12
12
|
class TestSearchManager(unittest.TestCase):
|
|
13
13
|
def setUp(self):
|
|
14
|
-
self.das_client = Das(base_url="
|
|
14
|
+
self.das_client = Das(base_url=os.getenv("API_URL"))
|
|
15
15
|
self.das_client.authenticate(username=os.getenv("USER_NAME"), password=os.getenv("USER_PASSWORD"))
|
|
16
16
|
|
|
17
17
|
def test_search_manager(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|