-
Notifications
You must be signed in to change notification settings - Fork 68
Get invitations #1962
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
Merged
Merged
Get invitations #1962
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
import pytest | ||
from faker import Faker | ||
from labelbox.schema.media_type import MediaType | ||
from labelbox import ProjectRole | ||
import time | ||
|
||
faker = Faker() | ||
|
||
|
||
@pytest.fixture | ||
def dummy_email(): | ||
"""Generate a random dummy email for testing""" | ||
return f"none+{faker.uuid4()}@labelbox.com" | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def test_project(client): | ||
"""Create a temporary project for testing""" | ||
project = client.create_project( | ||
name=f"test-project-{faker.uuid4()}", media_type=MediaType.Image | ||
) | ||
yield project | ||
|
||
# Occurs after the test is finished based on scope | ||
project.delete() | ||
|
||
|
||
@pytest.fixture | ||
def org_invite(client, dummy_email): | ||
"""Create an organization-level invite""" | ||
role = client.get_roles()["LABELER"] | ||
organization = client.get_organization() | ||
invite = organization.invite_user(dummy_email, role) | ||
|
||
yield invite | ||
|
||
if invite.uid: | ||
invite.cancel() | ||
|
||
|
||
@pytest.fixture | ||
def project_invite(client, test_project, dummy_email): | ||
"""Create a project-level invite""" | ||
roles = client.get_roles() | ||
project_role = ProjectRole(project=test_project, role=roles["LABELER"]) | ||
organization = client.get_organization() | ||
|
||
invite = organization.invite_user( | ||
dummy_email, roles["NONE"], project_roles=[project_role] | ||
) | ||
|
||
yield invite | ||
|
||
# Cleanup: Use invite.cancel() instead of organization.cancel_invite() | ||
if invite.uid: | ||
invite.cancel() | ||
|
||
|
||
def test_get_organization_invites(client, org_invite): | ||
"""Test retrieving all organization invites""" | ||
# Add a small delay to ensure invite is created | ||
time.sleep(1) | ||
|
||
organization = client.get_organization() | ||
invites = organization.get_invites() | ||
invite_list = [invite for invite in invites] | ||
assert len(invite_list) > 0 | ||
|
||
# Verify our test invite is in the list | ||
invite_emails = [invite.email for invite in invite_list] | ||
assert org_invite.email in invite_emails | ||
|
||
|
||
def test_get_project_invites(client, test_project, project_invite): | ||
"""Test retrieving project-specific invites""" | ||
# Add a small delay to ensure invite is created | ||
time.sleep(1) | ||
|
||
organization = client.get_organization() | ||
project_invites = organization.get_project_invites(test_project.uid) | ||
invite_list = [invite for invite in project_invites] | ||
assert len(invite_list) > 0 | ||
|
||
# Verify our test invite is in the list | ||
invite_emails = [invite.email for invite in invite_list] | ||
assert project_invite.email in invite_emails | ||
|
||
# Verify project role assignment | ||
found_invite = next( | ||
invite for invite in invite_list if invite.email == project_invite.email | ||
) | ||
assert len(found_invite.project_roles) == 1 | ||
assert found_invite.project_roles[0].project.uid == test_project.uid | ||
|
||
|
||
def test_cancel_invite(client, dummy_email): | ||
"""Test canceling an invite""" | ||
# Create a new invite | ||
role = client.get_roles()["LABELER"] | ||
organization = client.get_organization() | ||
organization.invite_user(dummy_email, role) | ||
|
||
# Add a small delay to ensure invite is created | ||
time.sleep(1) | ||
|
||
# Find the actual invite by email | ||
invites = organization.get_invites() | ||
found_invite = next( | ||
(invite for invite in invites if invite.email == dummy_email), None | ||
) | ||
assert found_invite is not None, f"Invite for {dummy_email} not found" | ||
|
||
# Cancel the invite using the found invite object | ||
result = found_invite.cancel() | ||
assert result is True | ||
|
||
# Verify the invite is no longer in the organization's invites | ||
invites = organization.get_invites() | ||
invite_emails = [i.email for i in invites] | ||
assert dummy_email not in invite_emails | ||
|
||
|
||
def test_cancel_project_invite(client, test_project, dummy_email): | ||
"""Test canceling a project invite""" | ||
# Create a project invite | ||
roles = client.get_roles() | ||
project_role = ProjectRole(project=test_project, role=roles["LABELER"]) | ||
organization = client.get_organization() | ||
|
||
organization.invite_user( | ||
dummy_email, roles["NONE"], project_roles=[project_role] | ||
) | ||
|
||
# Add a small delay to ensure invite is created | ||
time.sleep(1) | ||
|
||
# Find the actual invite by email | ||
invites = organization.get_invites() | ||
found_invite = next( | ||
(invite for invite in invites if invite.email == dummy_email), None | ||
) | ||
assert found_invite is not None, f"Invite for {dummy_email} not found" | ||
|
||
# Cancel the invite using the found invite object | ||
result = found_invite.cancel() | ||
assert result is True | ||
|
||
# Verify the invite is no longer in the project's invites | ||
project_invites = organization.get_project_invites(test_project.uid) | ||
invite_emails = [i.email for i in project_invites] | ||
assert dummy_email not in invite_emails | ||
|
||
|
||
def test_project_invite_after_project_deletion(client, dummy_email): | ||
"""Test that project invites are properly filtered when a project is deleted""" | ||
# Create two test projects | ||
project1 = client.create_project( | ||
name=f"test-project1-{faker.uuid4()}", media_type=MediaType.Image | ||
) | ||
project2 = client.create_project( | ||
name=f"test-project2-{faker.uuid4()}", media_type=MediaType.Image | ||
) | ||
|
||
# Create project roles | ||
roles = client.get_roles() | ||
project_role1 = ProjectRole(project=project1, role=roles["LABELER"]) | ||
project_role2 = ProjectRole(project=project2, role=roles["LABELER"]) | ||
|
||
# Invite user to both projects | ||
organization = client.get_organization() | ||
organization.invite_user( | ||
dummy_email, roles["NONE"], project_roles=[project_role1, project_role2] | ||
) | ||
|
||
# Add a small delay to ensure invite is created | ||
time.sleep(1) | ||
|
||
# Delete one project | ||
project1.delete() | ||
|
||
# Find the invite and verify project roles | ||
invites = organization.get_invites() | ||
found_invite = next( | ||
(invite for invite in invites if invite.email == dummy_email), None | ||
) | ||
assert found_invite is not None, f"Invite for {dummy_email} not found" | ||
|
||
# Verify only one project role remains | ||
assert ( | ||
len(found_invite.project_roles) == 1 | ||
), "Expected only one project role" | ||
assert found_invite.project_roles[0].project.uid == project2.uid | ||
|
||
# Cleanup | ||
project2.delete() | ||
if found_invite.uid: | ||
found_invite.cancel() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might make it finicky is their any way we could make this behave more sync? Worse case a retry loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simple one something like time.sleep 5 seconds check if not there retry again up to 3 times
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only mention because ive fix test with this sort of logic. Its annoying when they become finicky
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. I've removed the pause completely.