Skip to content

Commit 7b71c4a

Browse files
committed
fixed bug in create_folder()
1 parent 4e986a6 commit 7b71c4a

File tree

3 files changed

+88
-9
lines changed

3 files changed

+88
-9
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Unreleased
22
----------
3-
-
3+
**Bugfixes**
4+
- Fixed an issue where `folders.create_folder()` would attempt to use root folder as parent if desired parent
5+
folder wasn't found. Now correctly handles parent folders and raises an error if folder not found.
46

57
v1.6.3 (2021-09-23)
68
-------------------

src/sasctl/_services/folders.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,43 @@ class Folders(Service):
2525
@classmethod
2626
@sasctl_command('folders', 'create')
2727
def create_folder(cls, name, parent=None, description=None):
28-
"""
28+
"""Create a new folder.
2929
3030
Parameters
3131
----------
3232
name : str
3333
The name of the new folder
3434
parent : str or dict, optional
35-
The parent folder for this folder, if any. Can be a folder name,
36-
id, or dict response from `get_folder`
35+
The parent folder for this folder, if any. Can be a folder name, id, or dict response from `get_folder`.
36+
If not specified, new folder will be created under root folder.
3737
description : str, optional
3838
A description of the folder
3939
4040
Returns
4141
-------
42+
RestObj
43+
Details of newly-created folder
4244
4345
"""
4446
if parent is not None:
45-
parent = cls.get_folder(parent)
47+
parent_obj = cls.get_folder(parent)
4648

47-
if parent is None:
48-
raise ValueError('`parent` folder does not exist')
49+
parent_uri = cls.get_link(parent_obj, 'self')
50+
if parent_uri is None:
51+
raise ValueError("`parent` folder '%s' does not exist." % parent)
52+
parent_uri = parent_uri['uri']
53+
else:
54+
parent_uri = None
4955

5056
body = {
5157
'name': name,
5258
'description': description,
53-
'folderType': 'folder',
54-
'parentFolderUri': '/folders/folders/'+parent.id if parent else None,
59+
'folderType': 'folder'
5560
}
5661

5762
return cls.post(
5863
'/folders',
5964
json=body,
65+
params={'parentFolderUri': parent_uri},
6066
headers={'Content-Type': 'application/vnd.sas.content.folder+json'},
6167
)

tests/unit/test_folders.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
#
4+
# Copyright © 2022, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
from unittest import mock
8+
9+
import pytest
10+
from sasctl.services import folders
11+
12+
13+
def test_create_folder_basic():
14+
"""Create a folder with minimal parameters."""
15+
FOLDER_NAME = 'Spam'
16+
17+
with mock.patch('sasctl._services.folders.Folders.post') as post:
18+
folders.create_folder(FOLDER_NAME)
19+
20+
assert post.called
21+
json = post.call_args[1]['json']
22+
params = post.call_args[1]['params']
23+
assert json['name'] == FOLDER_NAME
24+
assert json['description'] is None
25+
assert params['parentFolderUri'] is None
26+
27+
28+
def test_create_folder_with_desc():
29+
"""Ensure description parameter is passed."""
30+
FOLDER_NAME = 'Spam'
31+
FOLDER_DESC = 'Created by sasctl testing.'
32+
33+
with mock.patch('sasctl._services.folders.Folders.post') as post:
34+
folders.create_folder(FOLDER_NAME, description=FOLDER_DESC)
35+
36+
assert post.called
37+
json = post.call_args[1]['json']
38+
params = post.call_args[1]['params']
39+
assert json['name'] == FOLDER_NAME
40+
assert json['description'] == FOLDER_DESC
41+
assert params['parentFolderUri'] is None
42+
43+
44+
def test_create_folder_with_parent():
45+
"""Ensure parent folder parameter is handled correctly."""
46+
from sasctl.core import RestObj
47+
48+
FOLDER_NAME = 'Spam'
49+
50+
# Mock response when retrieving parent folder.
51+
PARENT_FOLDER = RestObj({'name': '', 'id': '123', 'links': [
52+
{'rel': 'self', 'uri': '/folders/somewhere/spam-eggs-spam-spam'}
53+
]})
54+
55+
with mock.patch('sasctl._services.folders.Folders.get_folder', return_value=PARENT_FOLDER):
56+
with mock.patch('sasctl._services.folders.Folders.post') as post:
57+
folders.create_folder(FOLDER_NAME, parent='Doesnt Matter')
58+
59+
# Should have tried to create folder with correct name and parent URI
60+
assert post.called
61+
json = post.call_args[1]['json']
62+
params = post.call_args[1]['params']
63+
assert json['name'] == FOLDER_NAME
64+
assert json['description'] is None
65+
assert params['parentFolderUri'] == PARENT_FOLDER['links'][0]['uri']
66+
67+
# If parent folder can't be found, error should be raised
68+
with mock.patch('sasctl._services.folders.Folders.get_folder', return_value=None):
69+
with mock.patch('sasctl._services.folders.Folders.post'):
70+
with pytest.raises(ValueError):
71+
folders.create_folder(FOLDER_NAME, parent='Doesnt Matter')

0 commit comments

Comments
 (0)