roksta 0.3.3__cp312-cp312-macosx_10_13_universal2.whl → 0.3.5__cp312-cp312-macosx_10_13_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of roksta might be problematic. Click here for more details.

Files changed (60) hide show
  1. roksta/ai/llm.cpython-312-darwin.so +0 -0
  2. roksta/ai/tools/__init__.cpython-312-darwin.so +0 -0
  3. roksta/ai/tools/tool_defs.cpython-312-darwin.so +0 -0
  4. roksta/ai/tools/web_fetch.cpython-312-darwin.so +0 -0
  5. roksta/analytics.cpython-312-darwin.so +0 -0
  6. roksta/build_project.cpython-312-darwin.so +0 -0
  7. roksta/clarify_goal.cpython-312-darwin.so +0 -0
  8. roksta/command_handlers/handle_dev_rate_command.cpython-312-darwin.so +0 -0
  9. roksta/env.cpython-312-darwin.so +0 -0
  10. roksta/firebase_auth_web.cpython-312-darwin.so +0 -0
  11. roksta/fix_tests.cpython-312-darwin.so +0 -0
  12. roksta/goal_workflow.cpython-312-darwin.so +0 -0
  13. roksta/new_features.cpython-312-darwin.so +0 -0
  14. roksta/propose_solution.cpython-312-darwin.so +0 -0
  15. roksta/select_files.cpython-312-darwin.so +0 -0
  16. roksta/utils.cpython-312-darwin.so +0 -0
  17. roksta/write_code.cpython-312-darwin.so +0 -0
  18. {roksta-0.3.3.dist-info → roksta-0.3.5.dist-info}/METADATA +2 -1
  19. {roksta-0.3.3.dist-info → roksta-0.3.5.dist-info}/RECORD +22 -59
  20. {roksta-0.3.3.dist-info → roksta-0.3.5.dist-info}/top_level.txt +0 -1
  21. tests/__init__.py +0 -2
  22. tests/conftest.py +0 -211
  23. tests/functions/__init__.py +0 -2
  24. tests/functions/api_v1_00/__init__.py +0 -2
  25. tests/functions/api_v1_00/test__analytics.py +0 -416
  26. tests/functions/api_v1_00/test__gemini_proxy.py +0 -352
  27. tests/functions/api_v1_00/test__generic_proxy.py +0 -428
  28. tests/functions/api_v1_00/test__get_payment_details.py +0 -356
  29. tests/functions/api_v1_00/test__openai_proxy.py +0 -449
  30. tests/functions/api_v1_00/test__redeem_credit_code.py +0 -167
  31. tests/functions/api_v1_00/test__sync_emails.py +0 -325
  32. tests/functions/api_v1_00/test__take_payment.py +0 -491
  33. tests/functions/api_v1_00/test__use_activation_code.py +0 -438
  34. tests/functions/api_v1_01/__init__.py +0 -2
  35. tests/functions/api_v1_01/test__analytics.py +0 -416
  36. tests/functions/api_v1_01/test__gemini_proxy.py +0 -352
  37. tests/functions/api_v1_01/test__generic_proxy.py +0 -428
  38. tests/functions/api_v1_01/test__get_payment_details.py +0 -356
  39. tests/functions/api_v1_01/test__openai_proxy.py +0 -449
  40. tests/functions/api_v1_01/test__redeem_credit_code.py +0 -167
  41. tests/functions/api_v1_01/test__sync_emails.py +0 -325
  42. tests/functions/api_v1_01/test__take_payment.py +0 -491
  43. tests/functions/api_v1_01/test__use_activation_code.py +0 -438
  44. tests/functions/api_v1_02/__init__.py +0 -2
  45. tests/functions/api_v1_02/test__analytics.py +0 -416
  46. tests/functions/api_v1_02/test__gemini_proxy.py +0 -352
  47. tests/functions/api_v1_02/test__generic_proxy.py +0 -428
  48. tests/functions/api_v1_02/test__get_payment_details.py +0 -356
  49. tests/functions/api_v1_02/test__openai_proxy.py +0 -449
  50. tests/functions/api_v1_02/test__redeem_credit_code.py +0 -167
  51. tests/functions/api_v1_02/test__sync_emails.py +0 -325
  52. tests/functions/api_v1_02/test__take_payment.py +0 -491
  53. tests/functions/api_v1_02/test__use_activation_code.py +0 -438
  54. tests/functions/api_v1_02/test_proxy_keyword_replacement.py +0 -557
  55. tests/functions/api_v1_02/test_replace_keywords.py +0 -74
  56. tests/functions/test_auth.py +0 -24
  57. tests/functions/test_main.py +0 -73
  58. tests/functions/test_utils.py +0 -484
  59. {roksta-0.3.3.dist-info → roksta-0.3.5.dist-info}/WHEEL +0 -0
  60. {roksta-0.3.3.dist-info → roksta-0.3.5.dist-info}/entry_points.txt +0 -0
@@ -1,356 +0,0 @@
1
- import os
2
- import sys
3
- import json
4
- import types
5
- import importlib
6
- from unittest.mock import patch
7
-
8
-
9
- # Ensure the functions/ directory is importable as a top-level module location
10
- PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
11
- FUNCTIONS_DIR = os.path.join(PROJECT_ROOT, 'functions')
12
- if FUNCTIONS_DIR not in sys.path:
13
- sys.path.insert(0, FUNCTIONS_DIR)
14
-
15
- # Prepare lightweight fake modules to satisfy imports inside _get_payment_details
16
- # We'll temporarily inject these into sys.modules while importing the module
17
-
18
- _orig_sys_modules = {}
19
- _names_to_fake = [
20
- 'firebase_functions',
21
- 'utils',
22
- 'firebase_admin',
23
- 'firebase_admin.auth',
24
- 'firebase_admin.firestore',
25
- 'stripe',
26
- 'ulid',
27
- ]
28
- for name in _names_to_fake:
29
- _orig_sys_modules[name] = sys.modules.get(name)
30
-
31
- # Fake firebase_functions.https_fn.Response to capture returned data
32
- firebase_functions = types.ModuleType('firebase_functions')
33
-
34
- class FakeResponse:
35
- def __init__(self, response=None, mimetype=None, status=200, **kwargs):
36
- # Mirror a small subset of the interface tests expect
37
- self.status_code = status
38
- if isinstance(response, (dict, list)):
39
- self._body_text = json.dumps(response)
40
- else:
41
- self._body_text = '' if response is None else response
42
- # Accept either a mimetype arg (used in source) or explicit headers
43
- self.headers = kwargs.get('headers', {})
44
-
45
- def get_data(self, as_text=False):
46
- if as_text:
47
- return self._body_text
48
- return self._body_text.encode('utf-8')
49
-
50
- firebase_functions.https_fn = types.SimpleNamespace(Request=object, Response=FakeResponse)
51
- sys.modules['firebase_functions'] = firebase_functions
52
-
53
- # Fake utils module
54
- utils_mod = types.ModuleType('utils')
55
-
56
- # Default implementations; tests will patch attributes on the imported module when needed
57
- def _fake_get_secret_key(name: str):
58
- return 'DUMMY_STRIPE_KEY'
59
-
60
- def _fake_verify_firebase_token(req):
61
- # Default: successful verification
62
- return {'uid': 'user_1'}
63
-
64
- # create_json_response: tests expect the payload to be merged at top-level when payload is a dict,
65
- # or under the 'message' key when payload is a string. Return the firebase_functions.https_fn.Response
66
- # compatible FakeResponse defined above.
67
- def _fake_create_json_response(success: bool, payload, status_code: int):
68
- body = {"success": success}
69
- if isinstance(payload, dict):
70
- body.update(payload)
71
- else:
72
- body["message"] = payload
73
- return firebase_functions.https_fn.Response(response=body, status=status_code, mimetype="application/json")
74
-
75
- utils_mod.get_secret_key = _fake_get_secret_key
76
- utils_mod.verify_firebase_token = _fake_verify_firebase_token
77
- utils_mod.create_json_response = _fake_create_json_response
78
- sys.modules['utils'] = utils_mod
79
-
80
- # Fake firebase_admin with auth and firestore
81
- firebase_admin_mod = types.ModuleType('firebase_admin')
82
-
83
- # auth fake
84
- auth_mod = types.ModuleType('firebase_admin.auth')
85
-
86
- def _fake_get_user(uid):
87
- # Return an object with an email attribute
88
- return types.SimpleNamespace(email='user@example.com')
89
-
90
- auth_mod.get_user = _fake_get_user
91
- firebase_admin_mod.auth = auth_mod
92
- sys.modules['firebase_admin.auth'] = auth_mod
93
-
94
- # firestore fake: minimal in-memory store for collections -> documents
95
- fake_db_data = {}
96
-
97
- class DocumentSnapshot:
98
- def __init__(self, exists, data):
99
- self.exists = exists
100
- self._data = data
101
-
102
- def to_dict(self):
103
- return self._data
104
-
105
- def get(self, key):
106
- if not self._data:
107
- return None
108
- return self._data.get(key)
109
-
110
- class DocumentRef:
111
- def __init__(self, collection_name, doc_id):
112
- self.collection = collection_name
113
- self.doc_id = doc_id
114
-
115
- def get(self, transaction=None):
116
- coll = fake_db_data.get(self.collection, {})
117
- if self.doc_id in coll:
118
- return DocumentSnapshot(True, coll[self.doc_id])
119
- return DocumentSnapshot(False, None)
120
-
121
- def update(self, update_dict):
122
- coll = fake_db_data.setdefault(self.collection, {})
123
- doc = coll.setdefault(self.doc_id, {})
124
- doc.update(update_dict)
125
-
126
- def set(self, data):
127
- coll = fake_db_data.setdefault(self.collection, {})
128
- coll[self.doc_id] = data
129
-
130
- class CollectionRef:
131
- def __init__(self, name):
132
- self.name = name
133
-
134
- def document(self, doc_id):
135
- return DocumentRef(self.name, doc_id)
136
-
137
- class FakeFirestoreClient:
138
- def __init__(self):
139
- pass
140
-
141
- def collection(self, name):
142
- return CollectionRef(name)
143
-
144
- # Provide a minimal firestore module with client() and transactional decorator
145
- fake_firestore_mod = types.ModuleType('firebase_admin.firestore')
146
- fake_firestore_mod.client = lambda: FakeFirestoreClient()
147
- # transactional decorator: just return the function unchanged in this fake
148
- fake_firestore_mod.transactional = lambda f: f
149
-
150
- firebase_admin_mod.firestore = fake_firestore_mod
151
- sys.modules['firebase_admin'] = firebase_admin_mod
152
- sys.modules['firebase_admin.firestore'] = fake_firestore_mod
153
-
154
- # Fake stripe module
155
- stripe_mod = types.ModuleType('stripe')
156
-
157
- class StripeError(Exception):
158
- pass
159
-
160
- stripe_mod.error = types.SimpleNamespace(StripeError=StripeError)
161
- stripe_mod.api_key = None
162
-
163
- class _Customer:
164
- @staticmethod
165
- def create(email=None, metadata=None):
166
- # Simulate creating a Stripe customer
167
- return types.SimpleNamespace(id='cus_new')
168
-
169
- stripe_mod.Customer = _Customer
170
-
171
- class _Session:
172
- @staticmethod
173
- def create(**kwargs):
174
- # Return a dummy checkout session
175
- return types.SimpleNamespace(id='sess_123', url='https://checkout.example/sess_123')
176
-
177
- stripe_mod.checkout = types.SimpleNamespace(Session=_Session)
178
- sys.modules['stripe'] = stripe_mod
179
-
180
- # Fake ulid
181
- ulid_mod = types.ModuleType('ulid')
182
- ulid_mod.new = lambda: 'ULID123'
183
- sys.modules['ulid'] = ulid_mod
184
-
185
- # Import the module under test after preparing fake imports
186
- # Load the module directly from the functions/ tree so the test's fake sys.modules entries are respected
187
- repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
188
- functions_root = os.path.join(repo_root, 'functions')
189
- module_path = os.path.join(functions_root, 'api_v1_00', '_get_payment_details.py')
190
- spec = importlib.util.spec_from_file_location('api_v1_00._get_payment_details', module_path)
191
- _get_payment_details = importlib.util.module_from_spec(spec)
192
- spec.loader.exec_module(_get_payment_details)
193
-
194
- # Restore original sys.modules mappings to avoid side-effects for other tests
195
- for name, orig in _orig_sys_modules.items():
196
- if orig is None:
197
- try:
198
- del sys.modules[name]
199
- except KeyError:
200
- pass
201
- else:
202
- sys.modules[name] = orig
203
-
204
- # Import env constants for auth header usage in tests
205
- import env as functions_env # noqa: E402
206
- AUTH_HEADER_NAME = functions_env.AUTH_HEADER_NAME
207
- VALID_ENCRYPTED_KEY = functions_env.ENCRYPTED_AUTH_KEY.decode('utf-8')
208
-
209
-
210
- # Helper request stub used in tests
211
- class DummyRequest:
212
- def __init__(self, headers=None, method='POST', json_data=None, raise_on_get_json=False):
213
- self.headers = headers or {}
214
- self.method = method
215
- self._json_data = json_data
216
- self._raise = raise_on_get_json
217
-
218
- def get_json(self, silent=True):
219
- if self._raise:
220
- raise Exception('Malformed JSON')
221
- return self._json_data
222
-
223
-
224
- def _parse_response(resp):
225
- data = resp.get_data(as_text=True)
226
- return json.loads(data)
227
-
228
-
229
- # -----------------------------
230
- # Tests
231
- # -----------------------------
232
-
233
-
234
- def test_verify_firebase_token_failure_returns_403():
235
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST')
236
- with patch.object(_get_payment_details, 'verify_firebase_token', side_effect=Exception('invalid token')):
237
- resp = _get_payment_details._get_payment_details(req)
238
-
239
- assert resp.status_code == 403
240
- payload = _parse_response(resp)
241
- assert payload['success'] is False
242
- assert 'Authentication failed' in payload.get('message', '')
243
-
244
-
245
- def test_missing_json_payload_returns_400():
246
- fake_db_data.clear()
247
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data=None)
248
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
249
- patch.object(_get_payment_details, 'get_secret_key', return_value='DUMMY_STRIPE_KEY'):
250
- resp = _get_payment_details._get_payment_details(req)
251
-
252
- assert resp.status_code == 400
253
- payload = _parse_response(resp)
254
- assert payload['success'] is False
255
- assert 'Invalid or missing JSON payload' in payload.get('message', '')
256
-
257
-
258
- def test_billing_info_missing_returns_404():
259
- fake_db_data.clear()
260
- # provide a non-empty payload so code proceeds to check Firestore
261
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
262
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
263
- patch.object(_get_payment_details, 'get_secret_key', return_value='DUMMY_STRIPE_KEY'):
264
- resp = _get_payment_details._get_payment_details(req)
265
-
266
- assert resp.status_code == 404
267
- payload = _parse_response(resp)
268
- assert payload['success'] is False
269
- assert 'Billing information is missing' in payload.get('message', '')
270
-
271
-
272
- def test_setup_session_with_existing_customer_returns_session_url():
273
- # Pre-populate billing doc with an existing stripe_customer_id
274
- fake_db_data.clear()
275
- fake_db_data.setdefault('billing', {})['user_1'] = {'stripe_customer_id': 'cus_existing'}
276
-
277
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
278
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
279
- patch.object(_get_payment_details, 'get_secret_key', return_value='DUMMY_STRIPE_KEY'):
280
- resp = _get_payment_details._get_payment_details(req)
281
-
282
- assert resp.status_code == 200
283
- payload = _parse_response(resp)
284
- assert payload['success'] is True
285
- assert payload['session_url'] == 'https://checkout.example/sess_123'
286
-
287
-
288
- def test_create_customer_and_setup_session_when_no_stripe_customer():
289
- fake_db_data.clear()
290
- fake_db_data.setdefault('billing', {})['user_1'] = {} # no stripe id
291
-
292
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
293
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
294
- patch.object(_get_payment_details, 'get_secret_key', return_value='DUMMY_STRIPE_KEY'):
295
- resp = _get_payment_details._get_payment_details(req)
296
-
297
- assert resp.status_code == 200
298
- payload = _parse_response(resp)
299
- assert payload['success'] is True
300
- assert payload['session_url'] == 'https://checkout.example/sess_123'
301
- # billing doc should have been updated with new stripe_customer_id
302
- assert fake_db_data['billing']['user_1'].get('stripe_customer_id') == 'cus_new'
303
-
304
-
305
- def test_get_secret_key_failure_returns_500():
306
- fake_db_data.clear()
307
- fake_db_data.setdefault('billing', {})['user_1'] = {'stripe_customer_id': 'cus_existing'}
308
-
309
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
310
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
311
- patch.object(_get_payment_details, 'get_secret_key', side_effect=Exception('boom')):
312
- resp = _get_payment_details._get_payment_details(req)
313
-
314
- assert resp.status_code == 500
315
- payload = _parse_response(resp)
316
- assert payload['success'] is False
317
- assert 'Failed to retrieve Stripe configuration' in payload.get('message', '')
318
-
319
-
320
- def test_invalid_negative_amount_returns_400():
321
- # Ensure billing doc exists so code reaches amount parsing
322
- fake_db_data.clear()
323
- fake_db_data.setdefault('billing', {})['user_1'] = {'stripe_customer_id': 'cus_existing'}
324
-
325
- req = DummyRequest(headers={AUTH_HEADER_NAME: VALID_ENCRYPTED_KEY, 'Authorization': 'Bearer TOK'}, method='POST', json_data={'amount': '-5'})
326
- with patch.object(_get_payment_details, 'verify_firebase_token', return_value={'uid': 'user_1'}), \
327
- patch.object(_get_payment_details, 'get_secret_key', return_value='DUMMY_STRIPE_KEY'):
328
- resp = _get_payment_details._get_payment_details(req)
329
-
330
- assert resp.status_code == 400
331
- payload = _parse_response(resp)
332
- assert payload['success'] is False
333
- assert 'Invalid amount value provided' in payload.get('message', '')
334
-
335
-
336
- def test_missing_auth_header_returns_401():
337
- fake_db_data.clear()
338
- req = DummyRequest(headers={'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
339
- # No X-Roksta-Auth-Key header provided
340
- resp = _get_payment_details._get_payment_details(req)
341
-
342
- assert resp.status_code == 401
343
- payload = _parse_response(resp)
344
- assert payload['success'] is False
345
- assert 'Missing authentication key' in payload.get('message', '')
346
-
347
-
348
- def test_invalid_auth_header_returns_403():
349
- fake_db_data.clear()
350
- req = DummyRequest(headers={AUTH_HEADER_NAME: 'bad-key', 'Authorization': 'Bearer TOK'}, method='POST', json_data={'dummy': True})
351
- resp = _get_payment_details._get_payment_details(req)
352
-
353
- assert resp.status_code == 403
354
- payload = _parse_response(resp)
355
- assert payload['success'] is False
356
- assert 'Invalid authentication key' in payload.get('message', '')