hyperpocket 0.0.3__py3-none-any.whl → 0.1.9__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. hyperpocket/auth/README.md +3 -3
  2. hyperpocket/auth/__init__.py +0 -8
  3. hyperpocket/auth/gumloop/context.py +13 -0
  4. hyperpocket/auth/gumloop/token_context.py +15 -0
  5. hyperpocket/auth/gumloop/token_handler.py +66 -0
  6. hyperpocket/auth/gumloop/token_schema.py +8 -0
  7. hyperpocket/auth/linear/token_context.py +1 -1
  8. hyperpocket/auth/notion/README.md +28 -0
  9. hyperpocket/auth/notion/context.py +15 -0
  10. hyperpocket/auth/notion/token_context.py +14 -0
  11. hyperpocket/auth/notion/token_handler.py +65 -0
  12. hyperpocket/auth/notion/token_schema.py +10 -0
  13. hyperpocket/auth/provider.py +8 -5
  14. hyperpocket/auth/reddit/context.py +15 -0
  15. hyperpocket/auth/reddit/oauth2_context.py +32 -0
  16. hyperpocket/auth/reddit/oauth2_handler.py +151 -0
  17. hyperpocket/auth/reddit/oauth2_schema.py +18 -0
  18. hyperpocket/auth/slack/token_context.py +1 -1
  19. hyperpocket/builtin.py +63 -0
  20. hyperpocket/cli/__main__.py +12 -0
  21. hyperpocket/cli/auth.py +83 -0
  22. hyperpocket/cli/codegen/auth/__init__.py +13 -0
  23. hyperpocket/cli/codegen/auth/auth_context_template.py +16 -0
  24. hyperpocket/cli/codegen/auth/auth_token_context_template.py +16 -0
  25. hyperpocket/cli/codegen/auth/auth_token_handler_template.py +69 -0
  26. hyperpocket/cli/codegen/auth/auth_token_schema_template.py +12 -0
  27. hyperpocket/cli/codegen/auth/server_auth_template.py +18 -0
  28. hyperpocket/cli/eject.py +19 -0
  29. hyperpocket/cli/sync.py +5 -5
  30. hyperpocket/config/settings.py +14 -12
  31. hyperpocket/futures/futurestore.py +0 -1
  32. hyperpocket/pocket_auth.py +25 -5
  33. hyperpocket/pocket_core.py +264 -0
  34. hyperpocket/pocket_main.py +127 -174
  35. hyperpocket/prompts.py +6 -8
  36. hyperpocket/repository/__init__.py +2 -2
  37. hyperpocket/repository/lock.py +71 -1
  38. hyperpocket/repository/lockfile.py +19 -13
  39. hyperpocket/repository/repository.py +26 -1
  40. hyperpocket/server/auth/__init__.py +0 -6
  41. hyperpocket/server/auth/gumloop.py +16 -0
  42. hyperpocket/server/auth/notion.py +19 -0
  43. hyperpocket/server/auth/reddit.py +16 -0
  44. hyperpocket/server/server.py +56 -20
  45. hyperpocket/server/tool/dto/script.py +15 -2
  46. hyperpocket/server/tool/wasm.py +20 -8
  47. hyperpocket/session/README.md +2 -2
  48. hyperpocket/session/in_memory.py +18 -5
  49. hyperpocket/session/interface.py +14 -0
  50. hyperpocket/session/redis.py +29 -5
  51. hyperpocket/tool/README.md +16 -12
  52. hyperpocket/tool/__init__.py +4 -3
  53. hyperpocket/tool/function/README.md +39 -10
  54. hyperpocket/tool/function/__init__.py +2 -0
  55. hyperpocket/tool/function/annotation.py +2 -1
  56. hyperpocket/tool/function/tool.py +108 -29
  57. hyperpocket/tool/tool.py +100 -28
  58. hyperpocket/tool/wasm/README.md +27 -5
  59. hyperpocket/tool/wasm/browser.py +2 -7
  60. hyperpocket/tool/wasm/script.py +40 -1
  61. hyperpocket/tool/wasm/templates/python.py +32 -14
  62. hyperpocket/tool/wasm/tool.py +21 -18
  63. hyperpocket/tool_like.py +5 -0
  64. hyperpocket/util/__init__.py +1 -1
  65. hyperpocket/util/extract_func_param_desc_from_docstring.py +4 -4
  66. hyperpocket/util/function_to_model.py +5 -2
  67. hyperpocket/util/json_schema_to_model.py +47 -26
  68. {hyperpocket-0.0.3.dist-info → hyperpocket-0.1.9.dist-info}/METADATA +107 -88
  69. hyperpocket-0.1.9.dist-info/RECORD +137 -0
  70. {hyperpocket-0.0.3.dist-info → hyperpocket-0.1.9.dist-info}/WHEEL +1 -1
  71. hyperpocket-0.1.9.dist-info/entry_points.txt +2 -0
  72. hyperpocket/auth/README.KR.md +0 -309
  73. hyperpocket/auth/slack/tests/test_oauth2_handler.py +0 -32
  74. hyperpocket/auth/slack/tests/test_token_handler.py +0 -23
  75. hyperpocket/auth/tests/test_google_oauth2_handler.py +0 -147
  76. hyperpocket/auth/tests/test_slack_oauth2_handler.py +0 -147
  77. hyperpocket/auth/tests/test_slack_token_handler.py +0 -66
  78. hyperpocket/external/__init__.py +0 -7
  79. hyperpocket/external/github_client.py +0 -19
  80. hyperpocket/session/README.KR.md +0 -62
  81. hyperpocket/session/tests/test_in_memory.py +0 -145
  82. hyperpocket/session/tests/test_redis.py +0 -151
  83. hyperpocket/tests/test_pocket.py +0 -116
  84. hyperpocket/tests/test_pocket_auth.py +0 -982
  85. hyperpocket/tool/README.KR.md +0 -68
  86. hyperpocket/tool/builtins/__init__.py +0 -0
  87. hyperpocket/tool/builtins/example/__init__.py +0 -0
  88. hyperpocket/tool/builtins/example/add_tool.py +0 -18
  89. hyperpocket/tool/function/README.KR.md +0 -159
  90. hyperpocket/tool/tests/test_function_tool.py +0 -266
  91. hyperpocket/tool/wasm/README.KR.md +0 -144
  92. hyperpocket-0.0.3.dist-info/RECORD +0 -130
  93. hyperpocket-0.0.3.dist-info/entry_points.txt +0 -3
  94. /hyperpocket/auth/{slack/tests → gumloop}/__init__.py +0 -0
  95. /hyperpocket/auth/{tests → notion}/__init__.py +0 -0
  96. /hyperpocket/{session/tests → auth/reddit}/__init__.py +0 -0
  97. /hyperpocket/{tests → cli/codegen}/__init__.py +0 -0
@@ -1,147 +0,0 @@
1
- import uuid
2
- from datetime import timezone, datetime
3
- from unittest.async_case import IsolatedAsyncioTestCase
4
- from unittest.mock import patch
5
- from urllib.parse import urlparse, parse_qs
6
-
7
- import httpx
8
-
9
- from hyperpocket.auth import SlackOAuth2AuthContext
10
- from hyperpocket.auth.slack.oauth2_handler import SlackOAuth2AuthHandler
11
- from hyperpocket.auth.slack.oauth2_schema import SlackOAuth2Request, SlackOAuth2Response
12
- from hyperpocket.config import config
13
- from hyperpocket.config.auth import SlackAuthConfig
14
- from hyperpocket.futures import FutureStore
15
-
16
-
17
- class TestSlackOAuth2AuthHandler(IsolatedAsyncioTestCase):
18
-
19
- async def asyncSetUp(self):
20
- config.auth.slack = SlackAuthConfig(
21
- client_id="test-client-id",
22
- client_secret="test-client-secret",
23
- )
24
-
25
- self.handler = SlackOAuth2AuthHandler()
26
- self.auth_req = SlackOAuth2Request(
27
- auth_scopes=["channels:history", "im:history", "mpim:history", "groups:history", "reactions:read"],
28
- client_id="test-client-id",
29
- client_secret="test-client-secret",
30
- )
31
-
32
- async def test_make_auth_url(self):
33
- future_uid = str(uuid.uuid4())
34
-
35
- auth_url = self.handler._make_auth_url(
36
- req=self.auth_req,
37
- redirect_uri="http://test-redirect-uri.com",
38
- state=future_uid
39
- )
40
- parsed = urlparse(auth_url)
41
- query_params = parse_qs(parsed.query)
42
- base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
43
-
44
- # then
45
- self.assertEqual(base_url, SlackOAuth2AuthHandler._SLACK_OAUTH_URL)
46
- self.assertEqual(query_params["state"][0], future_uid)
47
- self.assertEqual(query_params["redirect_uri"][0], "http://test-redirect-uri.com")
48
- self.assertEqual(query_params["client_id"][0], "test-client-id")
49
- self.assertEqual(query_params["user_scope"][0],
50
- "channels:history,im:history,mpim:history,groups:history,reactions:read")
51
-
52
- async def test_prepare(self):
53
- future_uid = str(uuid.uuid4())
54
-
55
- # when
56
- prepare: str = self.handler.prepare(
57
- auth_req=self.auth_req,
58
- thread_id="test-prepare-thread-id",
59
- profile="test-prepare-profile",
60
- future_uid=future_uid,
61
- )
62
- auth_url = prepare.removeprefix("User needs to authenticate using the following URL:").strip()
63
- future_data = FutureStore.get_future( uid=future_uid)
64
-
65
- # then
66
- self.assertTrue(auth_url.startswith(SlackOAuth2AuthHandler._SLACK_OAUTH_URL))
67
- self.assertIsNotNone(future_data)
68
- self.assertEqual(future_data.data["thread_id"], "test-prepare-thread-id")
69
- self.assertEqual(future_data.data["profile"], "test-prepare-profile")
70
- self.assertFalse(future_data.future.done())
71
-
72
- async def test_authenticate(self):
73
- # given
74
- future_uid = str(uuid.uuid4())
75
- mock_response = httpx.Response(
76
- status_code=200,
77
- json={
78
- "ok": True,
79
- "authed_user": {
80
- "id": "test-user",
81
- "access_token": "test-token"
82
- }
83
-
84
- }
85
- )
86
-
87
- # when
88
- self.handler.prepare(
89
- auth_req=self.auth_req,
90
- thread_id="test-thread-id",
91
- profile="test-profile",
92
- future_uid=future_uid
93
- )
94
- future_data = FutureStore.get_future( uid=future_uid)
95
- future_data.future.set_result("test-code")
96
-
97
- with patch("httpx.AsyncClient.post", return_value=mock_response):
98
- response: SlackOAuth2AuthContext = await self.handler.authenticate(
99
- auth_req=self.auth_req,
100
- future_uid=future_uid
101
- )
102
-
103
- self.assertIsInstance(response, SlackOAuth2AuthContext)
104
- self.assertEqual(response.access_token, "test-token")
105
-
106
- async def test_refresh(self):
107
- # given
108
- # https://api.slack.com/authentication/rotation
109
- mock_response = httpx.Response(
110
- status_code=200,
111
- json={
112
- "ok": True,
113
- "access_token": "new-access-token",
114
- "refresh_token": "new-refresh-token",
115
- "expires_in": 3600,
116
- }
117
- )
118
-
119
- response = SlackOAuth2Response(
120
- **{
121
- "ok": True,
122
- "authed_user": {
123
- "id": "test",
124
- "access_token": "access-token",
125
- "refresh_token": "refresh-token",
126
- "expires_in": 3600,
127
- }
128
- }
129
- )
130
- context = SlackOAuth2AuthContext.from_slack_oauth2_response(response)
131
-
132
- # when
133
- with patch("httpx.AsyncClient.post", return_value=mock_response):
134
- new_context: SlackOAuth2AuthContext = await self.handler.refresh(
135
- auth_req=self.auth_req,
136
- context=context
137
- )
138
-
139
- time_diff = (new_context.expires_at - datetime.now(tz=timezone.utc))
140
-
141
- # then
142
- self.assertIsInstance(new_context, SlackOAuth2AuthContext)
143
- self.assertEqual(context.access_token, "access-token")
144
- self.assertEqual(context.refresh_token, "refresh-token")
145
- self.assertEqual(new_context.access_token, "new-access-token")
146
- self.assertEqual(new_context.refresh_token, "new-refresh-token")
147
- self.assertTrue(time_diff.total_seconds() > 3500)
@@ -1,66 +0,0 @@
1
- from unittest.async_case import IsolatedAsyncioTestCase
2
- from urllib.parse import urlparse, parse_qs
3
-
4
- from hyperpocket.auth import SlackTokenAuthContext
5
- from hyperpocket.auth.slack.token_handler import SlackTokenAuthHandler
6
- from hyperpocket.auth.slack.token_schema import SlackTokenRequest
7
- from hyperpocket.futures import FutureStore
8
-
9
-
10
- class TestSlackTokenAuthHandler(IsolatedAsyncioTestCase):
11
-
12
- async def asyncSetUp(self):
13
- self.handler: SlackTokenAuthHandler = SlackTokenAuthHandler()
14
- self.auth_req = SlackTokenRequest()
15
-
16
- async def test_make_auth_url(self):
17
- auth_url = self.handler._make_auth_url(
18
- req=self.auth_req,
19
- redirect_uri="http://test-redirect-uri.com",
20
- state="test-future-id"
21
- )
22
- parsed = urlparse(auth_url)
23
- query_params = parse_qs(parsed.query)
24
- base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
25
-
26
- # then
27
- self.assertEqual(base_url, self.handler._TOKEN_URL)
28
- self.assertEqual(query_params["state"][0], "test-future-id")
29
- self.assertEqual(query_params["redirect_uri"][0], "http://test-redirect-uri.com")
30
-
31
- async def test_prepare(self):
32
- # when
33
- prepare: str = self.handler.prepare(
34
- auth_req=self.auth_req,
35
- thread_id="test-prepare-thread-id",
36
- profile="test-prepare-profile",
37
- future_uid="test-prepare-future-uid",
38
- )
39
- auth_url = prepare.removeprefix("User needs to authenticate using the following URL:").strip()
40
- future_data = FutureStore.get_future( uid="test-prepare-future-uid")
41
-
42
- # then
43
- self.assertTrue(auth_url.startswith(self.handler._TOKEN_URL))
44
- self.assertIsNotNone(future_data)
45
- self.assertEqual(future_data.data["thread_id"], "test-prepare-thread-id")
46
- self.assertEqual(future_data.data["profile"], "test-prepare-profile")
47
- self.assertFalse(future_data.future.done())
48
-
49
- async def test_authenticate(self):
50
- self.handler.prepare(
51
- auth_req=self.auth_req,
52
- thread_id="test-thread-id",
53
- profile="test-profile",
54
- future_uid="test-future-uid"
55
- )
56
- future_data = FutureStore.get_future( uid="test-future-uid")
57
- future_data.future.set_result("test-token")
58
-
59
- response: SlackTokenAuthContext = await self.handler.authenticate(
60
- auth_req=self.auth_req,
61
- future_uid="test-future-uid"
62
- )
63
-
64
- self.assertIsInstance(response, SlackTokenAuthContext)
65
- self.assertEqual(response.access_token, "test-token")
66
- self.assertIsNone(response.expires_at)
@@ -1,7 +0,0 @@
1
- from hyperpocket.external.github_client import github_instance
2
-
3
- github = github_instance()
4
-
5
- __all__ = [
6
- "github",
7
- ]
@@ -1,19 +0,0 @@
1
- from github import Auth, Github, GithubIntegration
2
-
3
- from hyperpocket.config import config
4
-
5
- _github = None
6
-
7
-
8
- def github_instance() -> Github:
9
- global _github
10
- if _github is None:
11
- if config.git.github.github_token:
12
- _github = Github(auth=Auth.Token(config.git.github.github_token))
13
- elif config.git.github.app_id:
14
- auth = Auth.AppAuth(config.git.github.app_id, config.git.github.app_private_key)
15
- gi = GithubIntegration(auth=auth)
16
- _github = gi.get_github_for_installation(config.git.github.app_installation_id)
17
- else:
18
- _github = Github()
19
- return _github
@@ -1,62 +0,0 @@
1
- # Session Storage
2
-
3
- 유저의 authentication(auth) session을 저장하기 위한 storage
4
-
5
- ## Current supported session storage
6
-
7
- - [x] InMemory
8
- - [x] Redis
9
- - [ ] Postgres
10
- - [ ] Mysql
11
- - [ ] Mongodb
12
-
13
- ## SessionKey
14
-
15
- 세션 키는 유저의 인증 정보를 식별하기 위한 유니크 키이다.
16
-
17
- 일반적으로 세션 키는 다음 세 가지 요소로 식별될 수 있다.
18
-
19
- - auth provider
20
- - profile
21
- - thread_id
22
-
23
- 하나의 auth provider에서는 하나의 session만 가질 수 있다.
24
-
25
- - 예를 들어 slack token으로 이미 인증한 사용자가 oauth로 인증하려 하면 이전 세션은 사라지게 된다.
26
-
27
- - profile은 pocket에서 지원하는 개념으로 하나의 thread_id에 여러 profile이 존재할 수 있다.
28
-
29
- - profile을 이용해 한 사용자는 여러 persona를 갖고 작업을 수행하도록 할 수 있다.
30
- - e.g., A group의 슬랙 메세지를 읽어 B group으로 요약해서 전달
31
-
32
- ## BaseSessionValue
33
-
34
- ```python
35
- class BaseSessionValue(BaseModel):
36
- auth_provider_name: str
37
- auth_context: Optional[AuthContext] = None
38
- scoped: bool
39
- auth_scopes: Optional[Set[str]] = None
40
- auth_resolve_uid: Optional[str] = None
41
- ```
42
-
43
- 기본적으로 Session에는 다음 정보들을 갖고 있다.
44
-
45
- - auth_provider_name : 현재 세션을 인증한 auth provider name
46
- - auth_context : 실제 세션 내용이 들어있는 auth context
47
- - scoped : 현재 세션이 scoped session인지 여부
48
- - auth_scopes : 현재 세션의 auth scopes. scoped session의 경우에만 존재
49
- - auth_resolve_uid : 유저가 auth 인증을 완료했는지를 비동기적으로 확인하기 위한 uid
50
-
51
- ## SessionStorageInterface
52
-
53
- TBU
54
-
55
- ## How To Implement
56
-
57
- 1. `pocket/config/session.py` 내에 새로운 SessionType Enum 추가
58
- 2. `pocket/config/session.py` 내에 새로운 SessionConfig 추가
59
- 3. SessionStorageInterface 구현
60
- - session storage가 초기화될 때 위에서 정의한 SessionConfig를 입력으로 받아야 한다.
61
-
62
-
@@ -1,145 +0,0 @@
1
- import unittest
2
-
3
- from hyperpocket.auth import AuthProvider, SlackTokenAuthContext
4
- from hyperpocket.config.session import SessionConfigInMemory
5
- from hyperpocket.session.in_memory import InMemorySessionStorage, InMemorySessionValue
6
-
7
-
8
- class TestInMemorySessionStorage(unittest.TestCase):
9
- storage: InMemorySessionStorage
10
- context: SlackTokenAuthContext
11
-
12
- def setUp(self):
13
- self.storage = InMemorySessionStorage(SessionConfigInMemory())
14
- self.auth_context = SlackTokenAuthContext(
15
- access_token="test",
16
- description="test-description",
17
- expires_at=None,
18
- detail=None,
19
- )
20
-
21
- def tearDown(self):
22
- del self.storage
23
- del self.auth_context
24
-
25
- def test_make_session_key(self):
26
- key = self.storage._make_session_key(
27
- auth_provider=AuthProvider.SLACK,
28
- thread_id="default_thread_id",
29
- profile="default_profile"
30
- )
31
-
32
- self.assertEqual(key, "SLACK__default_thread_id__default_profile")
33
-
34
- def test_make_session(self):
35
- session = self.storage._make_session(
36
- auth_provider_name=AuthProvider.SLACK.name,
37
- auth_scopes=["scope1", "scope2"],
38
- auth_context=self.auth_context,
39
- auth_resolve_uid="test-resolve-uid",
40
- is_auth_scope_universal=True
41
- )
42
-
43
- # then
44
- self.assertIsInstance(session, InMemorySessionValue)
45
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
46
- self.assertEqual(session.auth_context.access_token, "test")
47
- self.assertEqual(session.auth_context.description, "test-description")
48
-
49
- def test_set(self):
50
- session = self.storage.set(
51
- auth_provider=AuthProvider.SLACK,
52
- thread_id="default_thread_id",
53
- profile="default_profile",
54
- auth_scopes=["scope1", "scope2"],
55
- auth_resolve_uid="test-resolve-uid",
56
- auth_context=self.auth_context,
57
- is_auth_scope_universal=True
58
- )
59
-
60
- self.assertIsInstance(session, InMemorySessionValue)
61
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
62
- self.assertEqual(session.auth_context.access_token, self.auth_context.access_token)
63
- self.assertEqual(session.auth_context.description, self.auth_context.description)
64
-
65
- def test_get_existing_data(self):
66
- # given
67
- self.storage.set(
68
- auth_provider=AuthProvider.SLACK,
69
- thread_id="default_thread_id",
70
- profile="default_profile",
71
- auth_scopes=["scope1", "scope2"],
72
- auth_resolve_uid="test-resolve-uid",
73
- auth_context=self.auth_context,
74
- is_auth_scope_universal=True
75
- )
76
-
77
- # when
78
- session = self.storage.get(
79
- auth_provider=AuthProvider.SLACK,
80
- thread_id="default_thread_id",
81
- profile="default_profile",
82
- )
83
-
84
- # then
85
- self.assertIsInstance(session, InMemorySessionValue)
86
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
87
- self.assertEqual(session.auth_context.access_token, "test")
88
- self.assertEqual(session.auth_context.description, "test-description")
89
-
90
- def test_get_not_existing_data(self):
91
- # when
92
- session = self.storage.get(
93
- auth_provider=AuthProvider.SLACK,
94
- thread_id="default_thread_id",
95
- profile="default_profile",
96
- )
97
-
98
- # then
99
- self.assertIsNone(session)
100
-
101
- def test_delete_existing_data(self):
102
- # given
103
- self.storage.set(
104
- auth_provider=AuthProvider.SLACK,
105
- thread_id="default_thread_id",
106
- profile="default_profile",
107
- auth_scopes=["scope1", "scope2"],
108
- auth_resolve_uid="test-resolve-uid",
109
- auth_context=self.auth_context,
110
- is_auth_scope_universal=True
111
- )
112
-
113
- # when
114
- before_session = self.storage.get(
115
- auth_provider=AuthProvider.SLACK,
116
- thread_id="default_thread_id",
117
- profile="default_profile",
118
- )
119
-
120
- deleted = self.storage.delete(
121
- auth_provider=AuthProvider.SLACK,
122
- thread_id="default_thread_id",
123
- profile="default_profile",
124
- )
125
-
126
- after_session = self.storage.get(
127
- auth_provider=AuthProvider.SLACK,
128
- thread_id="default_thread_id",
129
- profile="default_profile",
130
- )
131
-
132
- # then
133
- self.assertTrue(deleted)
134
- self.assertIsNotNone(before_session)
135
- self.assertIsNone(after_session)
136
-
137
- def test_delete_not_existing_data(self):
138
- deleted = self.storage.delete(
139
- auth_provider=AuthProvider.SLACK,
140
- thread_id="default_thread_id",
141
- profile="default_profile",
142
- )
143
-
144
- # then
145
- self.assertFalse(deleted)
@@ -1,151 +0,0 @@
1
- import unittest
2
-
3
- from hyperpocket.auth import AuthProvider, SlackTokenAuthContext
4
- from hyperpocket.config.session import SessionConfigRedis
5
- from hyperpocket.session.in_memory import InMemorySessionValue
6
- from hyperpocket.session.redis import RedisSessionStorage, RedisSessionValue
7
-
8
-
9
- class TestRedisSessionStorage(unittest.TestCase):
10
- storage: RedisSessionStorage
11
- context: SlackTokenAuthContext
12
-
13
- def setUp(self):
14
- self.storage = RedisSessionStorage(SessionConfigRedis(
15
- host="localhost",
16
- port=6379,
17
- db="9"
18
- ))
19
- self.storage.client.flushdb()
20
-
21
- self.auth_context = SlackTokenAuthContext(
22
- access_token="test",
23
- description="test-description",
24
- expires_at=None,
25
- detail=None,
26
- )
27
-
28
- def tearDown(self):
29
- self.storage.client.flushdb()
30
-
31
- def test_make_session_key(self):
32
- key = self.storage._make_session_key(
33
- auth_provider=AuthProvider.SLACK,
34
- thread_id="default_thread_id",
35
- profile="default_profile"
36
- )
37
-
38
- self.assertEqual(key, "SLACK__default_thread_id__default_profile")
39
-
40
- def test_make_session(self):
41
- session = self.storage._make_session(
42
- auth_provider_name=AuthProvider.SLACK.name,
43
- auth_scopes=["scope1", "scope2"],
44
- auth_context=self.auth_context,
45
- auth_resolve_uid="test-resolve-uid",
46
- is_auth_scope_universal=True
47
- )
48
-
49
- # then
50
- self.assertIsInstance(session, RedisSessionValue)
51
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
52
- self.assertEqual(session.auth_context.access_token, "test")
53
- self.assertEqual(session.auth_context.description, "test-description")
54
-
55
- def test_set(self):
56
- session = self.storage.set(
57
- auth_provider=AuthProvider.SLACK,
58
- thread_id="default_thread_id",
59
- profile="default_profile",
60
- auth_scopes=["scope1", "scope2"],
61
- auth_resolve_uid="test-resolve-uid",
62
- auth_context=self.auth_context,
63
- is_auth_scope_universal=True
64
- )
65
-
66
- self.assertIsInstance(session, InMemorySessionValue)
67
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
68
- self.assertEqual(session.auth_context.access_token, self.auth_context.access_token)
69
- self.assertEqual(session.auth_context.description, self.auth_context.description)
70
-
71
- def test_get_existing_data(self):
72
- # given
73
- self.storage.set(
74
- auth_provider=AuthProvider.SLACK,
75
- thread_id="default_thread_id",
76
- profile="default_profile",
77
- auth_scopes=["scope1", "scope2"],
78
- auth_resolve_uid="test-resolve-uid",
79
- auth_context=self.auth_context,
80
- is_auth_scope_universal=True
81
- )
82
-
83
- # when
84
- session = self.storage.get(
85
- auth_provider=AuthProvider.SLACK,
86
- thread_id="default_thread_id",
87
- profile="default_profile",
88
- )
89
-
90
- # then
91
- self.assertIsInstance(session, InMemorySessionValue)
92
- self.assertEqual(session.auth_provider_name, AuthProvider.SLACK.name)
93
- self.assertEqual(session.auth_context.access_token, "test")
94
- self.assertEqual(session.auth_context.description, "test-description")
95
-
96
- def test_get_not_existing_data(self):
97
- # when
98
- session = self.storage.get(
99
- auth_provider=AuthProvider.SLACK,
100
- thread_id="default_thread_id",
101
- profile="default_profile",
102
- )
103
-
104
- # then
105
- self.assertIsNone(session)
106
-
107
- def test_delete_existing_data(self):
108
- # given
109
- self.storage.set(
110
- auth_provider=AuthProvider.SLACK,
111
- thread_id="default_thread_id",
112
- profile="default_profile",
113
- auth_scopes=["scope1", "scope2"],
114
- auth_resolve_uid="test-resolve-uid",
115
- auth_context=self.auth_context,
116
- is_auth_scope_universal=True
117
- )
118
-
119
- # when
120
- before_session = self.storage.get(
121
- auth_provider=AuthProvider.SLACK,
122
- thread_id="default_thread_id",
123
- profile="default_profile",
124
- )
125
-
126
- deleted = self.storage.delete(
127
- auth_provider=AuthProvider.SLACK,
128
- thread_id="default_thread_id",
129
- profile="default_profile",
130
- )
131
-
132
- after_session = self.storage.get(
133
- auth_provider=AuthProvider.SLACK,
134
- thread_id="default_thread_id",
135
- profile="default_profile",
136
- )
137
-
138
- # then
139
- self.assertTrue(deleted)
140
- self.assertIsNotNone(before_session)
141
- self.assertIsNone(after_session)
142
-
143
- def test_delete_not_existing_data(self):
144
- deleted = self.storage.delete(
145
- auth_provider=AuthProvider.SLACK,
146
- thread_id="default_thread_id",
147
- profile="default_profile",
148
- )
149
-
150
- # then
151
- self.assertFalse(deleted)