Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jkmarx/data set owner transfer #2794

Merged
merged 16 commits into from Jun 6, 2018
Merged

Conversation

jkmarx
Copy link
Member

@jkmarx jkmarx commented May 30, 2018

@codecov
Copy link

codecov bot commented May 30, 2018

Codecov Report

Merging #2794 into develop will decrease coverage by 2.5%.
The diff coverage is 93.54%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2794      +/-   ##
===========================================
- Coverage    59.84%   57.34%   -2.51%     
===========================================
  Files          415      417       +2     
  Lines        28396    26257    -2139     
  Branches      1253     1256       +3     
===========================================
- Hits         16993    15056    -1937     
+ Misses       11403    11201     -202
Impacted Files Coverage Δ
refinery/core/models.py 75.14% <100%> (-5.21%) ⬇️
refinery/core/test_views.py 100% <100%> (ø) ⬆️
refinery/core/views.py 40.37% <100%> (+1.97%) ⬆️
...js/dashboard/directives/data-set-transfer-modal.js 100% <100%> (ø)
...ce/js/dashboard/controllers/data-sets-card-ctrl.js 67.02% <57.14%> (-0.8%) ⬇️
...hboard/controllers/data-set-transfer-modal-ctrl.js 57.5% <57.5%> (ø)
refinery/tool_manager/views.py 85.71% <0%> (-1.13%) ⬇️
refinery/tool_manager/models.py 96.97% <0%> (-0.61%) ⬇️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5a6230c...cb5bc40. Read the comment docs.

@@ -54,8 +54,8 @@ def setUp(self):
)

# Create Datasets
self.dataset = create_dataset_with_necessary_models(user=self.user)
self.dataset2 = create_dataset_with_necessary_models(user=self.user)
self.data_set = create_dataset_with_necessary_models(user=self.user)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept making typos so went ahead and updated the file to data_set vs dataset

@jkmarx jkmarx requested a review from scottx611x May 30, 2018 18:53
@jkmarx jkmarx self-assigned this May 30, 2018
@jkmarx jkmarx added this to the Release 1.6.5 milestone May 30, 2018
perm_groups = self.update_group_perms(new_owner)
self.send_tranfer_notification_email(current_owner,
new_owner, perm_groups)
self.data_set.transfer_ownership(current_owner, new_owner)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make sense to call transfer_ownership before sending the email notification. That way we could wrap it in a try/except and handle any errors and only send the email if we've deemed the ownership transfer successful.

I'm also curious as to what would happen if anything went wrong after update_group_perms has been called. We should think about how to rollback the unsharing done here: https://github.com/refinery-platform/refinery-platform/pull/2794/files#diff-f20c3884fa8cbcaa080cb9b22e276ad9R915 if send_tranfer_notification_email or transfer_ownership calls fails

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the order is wrong. Must have jumbled it up when refactoring.

)

def send_tranfer_notification_email(self, old_owner, new_owner,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tranfer -> transfer

to=[new_owner.email, old_owner.email]
)
email.send()
return email
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to return the email here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's useful for testing.

group.extendedgroup.uuid
)
})
if group.id in new_owner_group_ids:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this just be an else?

)
groups_with_access = []
groups_without_access = []
for group in all_groups_with_ds_access:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do something like:

group_data = {
    'name': group.extendedgroup.name,
    'profile': 'http://{}/groups/{}'.format(self.current_site, group.extendedgroup.uuid)
}

at the beginning of this for, and just append group_data to groups_without_access & groups_with_access below instead of duplicating the dict?

self.assertFalse(is_filtered)

def test_send_tranfer_notification_email_corrent_users(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tranfer -> transfer
corrent -> current

self.data_set.share(ExtendedGroup.objects.public_group())
group_union = ExtendedGroup.objects.create(name="Group Union",
is_public=True)
group_non_union = ExtendedGroup.objects.create(name="Group Non-Union",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe in Refinery there is only to be one public group. Maybe this isn't testing an exact scenario we'd encounter

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure what you mean. The data set is shared with three groups (one being public) and the new owner only belongs to public and the union group. This test checks to see the data set is unshared with the non-union group.

self.password)
self.data_set.share(ExtendedGroup.objects.public_group())
group_union = ExtendedGroup.objects.create(name="Group Union",
is_public=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above public group concern

new_owner_email = 'new_owner@fake.com'
new_owner = User.objects.create_user('NewOwner1', new_owner_email,
self.password)
group_union_public = ExtendedGroup.objects.public_group()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group_union_public -> public_group ?

jkmarx and others added 7 commits May 31, 2018 18:31
* Add tranfer modal.

* Error handling for invalid email.

* Add group notice text.

* Disable button after successful transfer.

* Add data set title to modal.

* Add unit tests.

* Add unit test for view method.

* Update email text.

* Additional modal text.

* Fix css.

* Relocate data set name to minimize clutter on form.

* Fix all transfer typos.

* Remove console.

* Uneccessary string.

@mock.patch('core.views.DataSetsViewSet.update_group_perms',
side_effect=RuntimeError)
def test_dataset_patch_fails_and_rollback_owner(self, mock_update):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scottx611x These are the additional tests

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did confirm the unsharing

except Exception:
return Response(uuid, status=status.HTTP_404_NOT_FOUND)

try:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scottx611x Error handling and rollback

perm_groups = self.update_group_perms(new_owner)
except Exception as e:
return Response(
e, status=status.HTTP_500_INTERNAL_SERVER_ERROR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking again, this would be more appropriate as an error in the 400's. Its weird to explicitly send back a 500

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really a bad request is it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe HTTP_412_PRECONDITION_FAILED ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good reference for HTTP response status codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

@jkmarx
Copy link
Member Author

jkmarx commented Jun 6, 2018

@scottx611x After reading @hackdna posts, I think the 412 is appropriate. Were there any other changes?

@scottx611x
Copy link
Member

@jkmarx Its been a while since I looked at the whole PR. I'll take a peek and let you know

@jkmarx jkmarx merged commit a488e68 into develop Jun 6, 2018
@jkmarx jkmarx deleted the jkmarx/data-set-owner-transfer branch June 6, 2018 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants