Skip to content

Commit 8b06f31

Browse files
author
Charles Larivier
committed
feat: add User
1 parent 533a7d1 commit 8b06f31

File tree

3 files changed

+176
-45
lines changed

3 files changed

+176
-45
lines changed

metabase/resources/user.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from __future__ import annotations
2+
3+
from datetime import datetime
4+
from typing import Any, Dict, List
5+
6+
from metabase.resource import ListResource, CreateResource, GetResource, UpdateResource, DeleteResource
7+
from metabase.missing import MISSING
8+
9+
10+
class User(ListResource, CreateResource, GetResource, UpdateResource, DeleteResource):
11+
ENDPOINT = "/api/user"
12+
13+
id: int
14+
email: str
15+
first_name: str
16+
last_name: str
17+
common_name: str
18+
locale: str
19+
20+
is_superuser: bool
21+
is_active: bool
22+
is_qbnewb: bool
23+
ldap_auth: bool
24+
google_auth: bool
25+
26+
login_attributes: Dict[str, Any]
27+
group_ids: List[int]
28+
29+
last_login: datetime
30+
date_joined: datetime
31+
updated_at: datetime
32+
33+
@classmethod
34+
def list(cls) -> List[User]:
35+
response = cls.connection().get(cls.ENDPOINT)
36+
records = [cls(**user) for user in response.json().get("data", [])]
37+
return records
38+
39+
@classmethod
40+
def create(
41+
cls,
42+
first_name: str,
43+
last_name: str,
44+
email: str,
45+
password: str,
46+
group_ids: List[int] = None,
47+
login_attributes: Dict[str, Any] = None,
48+
**kwargs
49+
) -> User:
50+
return super(User, cls).create(
51+
first_name=first_name,
52+
last_name=last_name,
53+
email=email,
54+
password=password,
55+
group_ids=group_ids,
56+
login_attributes=login_attributes,
57+
**kwargs
58+
)
59+
60+
def update(
61+
self,
62+
first_name: str = MISSING,
63+
last_name: str = MISSING,
64+
email: str = MISSING,
65+
password: str = MISSING,
66+
group_ids: List[int] = MISSING,
67+
is_superuser: bool = MISSING,
68+
locale: str = MISSING,
69+
**kwargs
70+
) -> None:
71+
return super(User, self).update(
72+
first_name=first_name,
73+
last_name=last_name,
74+
email=email,
75+
password=password,
76+
group_ids=group_ids,
77+
locale=locale,
78+
**kwargs
79+
)
80+
81+
def send_invite(self):
82+
self.connection().put(self.ENDPOINT + f"/{getattr(self, self.PRIMARY_KEY)}" + "/send_invite")
83+
84+
def reactivate(self):
85+
self.connection().put(self.ENDPOINT + f"/{getattr(self, self.PRIMARY_KEY)}" + "/reactivate")

metabase/user.py

Lines changed: 0 additions & 45 deletions
This file was deleted.

tests/resources/test_user.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from random import randint
2+
3+
from exceptions import NotFoundError
4+
from metabase.resources.user import User
5+
6+
from tests.helpers import IntegrationTestCase
7+
8+
9+
class UserTests(IntegrationTestCase):
10+
def tearDown(self) -> None:
11+
users = User.list()
12+
for user in users:
13+
if user.id != 1:
14+
user.delete()
15+
16+
def test_get(self):
17+
"""
18+
Ensure User.get() returns a User instance for a given ID, or
19+
raises a NotFoundError when it does not exist.
20+
"""
21+
# fixture
22+
user = User.create(
23+
first_name="Test",
24+
last_name="Test",
25+
email=f"{randint(2, 10000)}@example.com",
26+
password="example123"
27+
)
28+
self.assertIsInstance(user, User)
29+
30+
u = User.get(user.id)
31+
self.assertIsInstance(u, User)
32+
self.assertEqual(user.id, u.id)
33+
34+
with self.assertRaises(NotFoundError):
35+
_ = User.get(12345)
36+
37+
def test_create(self):
38+
"""Ensure User.create() creates a User in Metabase and returns a User instance."""
39+
email = f"{randint(2, 10000)}@example.com"
40+
user = User.create(
41+
first_name="Test",
42+
last_name="Test",
43+
email=email,
44+
password="example123"
45+
)
46+
47+
self.assertIsInstance(user, User)
48+
self.assertEqual("Test", user.first_name)
49+
self.assertEqual("Test", user.last_name)
50+
self.assertEqual(email, user.email)
51+
52+
def test_update(self):
53+
"""Ensure User.update() updates an existing User in Metabase."""
54+
# fixture
55+
user = User.create(
56+
first_name="Test",
57+
last_name="Test",
58+
email=f"{randint(2, 10000)}@example.com",
59+
password="example123"
60+
)
61+
62+
self.assertIsInstance(user, User)
63+
self.assertEqual("Test", user.first_name)
64+
65+
user.update(
66+
first_name="Test1"
67+
)
68+
# assert local instance is mutated
69+
self.assertEqual("Test1", user.first_name)
70+
71+
# assert metabase object is mutated
72+
u = User.get(user.id)
73+
self.assertEqual("Test1", u.first_name)
74+
75+
def test_delete(self):
76+
"""Ensure User.delete() updates archived=True."""
77+
# fixture
78+
user = User.create(
79+
first_name="Test",
80+
last_name="Test",
81+
email=f"{randint(2, 10000)}@example.com",
82+
password="example123"
83+
)
84+
self.assertIsInstance(user, User)
85+
86+
user.delete()
87+
88+
# assert metabase object is mutated
89+
with self.assertRaises(NotFoundError):
90+
_ = User.get(user.id)
91+

0 commit comments

Comments
 (0)