mockstack 0.9.0__tar.gz → 0.9.1__tar.gz

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.
Files changed (87) hide show
  1. {mockstack-0.9.0 → mockstack-0.9.1}/PKG-INFO +1 -1
  2. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/intent.py +7 -1
  3. mockstack-0.9.1/mockstack/tests/test_intent.py +162 -0
  4. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/PKG-INFO +1 -1
  5. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/SOURCES.txt +1 -0
  6. {mockstack-0.9.0 → mockstack-0.9.1}/.dockerignore +0 -0
  7. {mockstack-0.9.0 → mockstack-0.9.1}/.env.example +0 -0
  8. {mockstack-0.9.0 → mockstack-0.9.1}/.github/workflows/ci.yml +0 -0
  9. {mockstack-0.9.0 → mockstack-0.9.1}/.github/workflows/publish-docs.yml +0 -0
  10. {mockstack-0.9.0 → mockstack-0.9.1}/.github/workflows/publish-to-dockerhub.yml +0 -0
  11. {mockstack-0.9.0 → mockstack-0.9.1}/.github/workflows/publish-to-pypi.yml +0 -0
  12. {mockstack-0.9.0 → mockstack-0.9.1}/.gitignore +0 -0
  13. {mockstack-0.9.0 → mockstack-0.9.1}/.pre-commit-config.yaml +0 -0
  14. {mockstack-0.9.0 → mockstack-0.9.1}/CODE_OF_CONDUCT.md +0 -0
  15. {mockstack-0.9.0 → mockstack-0.9.1}/Dockerfile +0 -0
  16. {mockstack-0.9.0 → mockstack-0.9.1}/LICENSE +0 -0
  17. {mockstack-0.9.0 → mockstack-0.9.1}/README.md +0 -0
  18. {mockstack-0.9.0 → mockstack-0.9.1}/SECURITY.md +0 -0
  19. {mockstack-0.9.0 → mockstack-0.9.1}/docker-entrypoint.sh +0 -0
  20. {mockstack-0.9.0 → mockstack-0.9.1}/docs/assets/favicon.ico +0 -0
  21. {mockstack-0.9.0 → mockstack-0.9.1}/docs/assets/logo.png +0 -0
  22. {mockstack-0.9.0 → mockstack-0.9.1}/docs/assets/mockstack.png +0 -0
  23. {mockstack-0.9.0 → mockstack-0.9.1}/docs/configuration.md +0 -0
  24. {mockstack-0.9.0 → mockstack-0.9.1}/docs/ollama.md +0 -0
  25. {mockstack-0.9.0 → mockstack-0.9.1}/docs/strategies/base.md +0 -0
  26. {mockstack-0.9.0 → mockstack-0.9.1}/docs/strategies/filefixtures.md +0 -0
  27. {mockstack-0.9.0 → mockstack-0.9.1}/docs/strategies/proxyrules.md +0 -0
  28. {mockstack-0.9.0 → mockstack-0.9.1}/examples/filefixtures-with-templates/.env.example +0 -0
  29. {mockstack-0.9.0 → mockstack-0.9.1}/examples/filefixtures-with-templates/README.md +0 -0
  30. {mockstack-0.9.0 → mockstack-0.9.1}/examples/filefixtures-with-templates/templates/servicename-api-v1-items.j2 +0 -0
  31. {mockstack-0.9.0 → mockstack-0.9.1}/examples/filefixtures-with-templates/templates/servicename2-api-v2-user.533ec889-7c68-45c8-b21e-4a7e455d1234.j2 +0 -0
  32. {mockstack-0.9.0 → mockstack-0.9.1}/examples/llm/README.md +0 -0
  33. {mockstack-0.9.0 → mockstack-0.9.1}/examples/llm/mockstack-langchain-example.ipynb +0 -0
  34. {mockstack-0.9.0 → mockstack-0.9.1}/examples/llm/templates/ollama-openai-v1-chat-completions.j2 +0 -0
  35. {mockstack-0.9.0 → mockstack-0.9.1}/examples/llm/templates/openai-v1-chat-completions.j2 +0 -0
  36. {mockstack-0.9.0 → mockstack-0.9.1}/examples/llm/templates/openai-v1-deployments-gpt-4o-chat-completions.j2 +0 -0
  37. {mockstack-0.9.0 → mockstack-0.9.1}/examples/proxyrules-with-rules-file/.env.example +0 -0
  38. {mockstack-0.9.0 → mockstack-0.9.1}/examples/proxyrules-with-rules-file/README.md +0 -0
  39. {mockstack-0.9.0 → mockstack-0.9.1}/examples/proxyrules-with-rules-file/rules.yml +0 -0
  40. {mockstack-0.9.0 → mockstack-0.9.1}/mkdocs.yml +0 -0
  41. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/__init__.py +0 -0
  42. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/config.py +0 -0
  43. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/constants.py +0 -0
  44. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/display.py +0 -0
  45. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/exceptions.py +0 -0
  46. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/identifiers.py +0 -0
  47. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/lifespan.py +0 -0
  48. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/llm/__init__.py +0 -0
  49. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/llm/ollama.py +0 -0
  50. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/main.py +0 -0
  51. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/middleware.py +0 -0
  52. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/routers/__init__.py +0 -0
  53. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/routers/catchall.py +0 -0
  54. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/routers/homepage.py +0 -0
  55. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/__init__.py +0 -0
  56. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/base.py +0 -0
  57. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/create_mixin.py +0 -0
  58. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/factory.py +0 -0
  59. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/filefixtures.py +0 -0
  60. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/strategies/proxyrules.py +0 -0
  61. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/telemetry.py +0 -0
  62. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/templating.py +0 -0
  63. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/__init__.py +0 -0
  64. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/conftest.py +0 -0
  65. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/fixtures/proxyrules.yml +0 -0
  66. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/fixtures/templates/__init__.py +0 -0
  67. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/fixtures/templates/example-template.j2 +0 -0
  68. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/llm/__init__.py +0 -0
  69. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/llm/test_ollama.py +0 -0
  70. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/routers/__init__.py +0 -0
  71. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/routers/test_catchall.py +0 -0
  72. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/routers/test_homepage.py +0 -0
  73. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/strategies/test_create_mixin.py +0 -0
  74. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/strategies/test_filefixtures.py +0 -0
  75. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/strategies/test_proxyrules.py +0 -0
  76. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/test_display.py +0 -0
  77. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/test_identifiers.py +0 -0
  78. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/test_middleware.py +0 -0
  79. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/test_telemetry.py +0 -0
  80. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack/tests/test_templating.py +0 -0
  81. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/dependency_links.txt +0 -0
  82. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/entry_points.txt +0 -0
  83. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/requires.txt +0 -0
  84. {mockstack-0.9.0 → mockstack-0.9.1}/mockstack.egg-info/top_level.txt +0 -0
  85. {mockstack-0.9.0 → mockstack-0.9.1}/pyproject.toml +0 -0
  86. {mockstack-0.9.0 → mockstack-0.9.1}/setup.cfg +0 -0
  87. {mockstack-0.9.0 → mockstack-0.9.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mockstack
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: An API mocking workhorse
5
5
  Author-email: Adam Ever-Hadani <mockstack.contact@gmail.com>
6
6
  License-Expression: MIT
@@ -62,7 +62,13 @@ def looks_like_a_create(request: Request) -> bool:
62
62
  """
63
63
  return any(
64
64
  (
65
- request.method == "POST",
65
+ request.method == "POST"
66
+ and not any(
67
+ (
68
+ looks_like_a_search(request),
69
+ looks_like_a_command(request),
70
+ )
71
+ ),
66
72
  request.url.path.endswith("/create"),
67
73
  ),
68
74
  )
@@ -0,0 +1,162 @@
1
+ """Unit tests for the intent module."""
2
+
3
+ import pytest
4
+ from fastapi import Request
5
+ from starlette.datastructures import Headers
6
+
7
+ from mockstack.intent import (
8
+ wants_json,
9
+ looks_like_a_search,
10
+ looks_like_a_command,
11
+ looks_like_a_create,
12
+ )
13
+
14
+
15
+ @pytest.fixture
16
+ def mock_request():
17
+ """Create a mock FastAPI request object."""
18
+
19
+ def _create_request(
20
+ method="GET",
21
+ path="/",
22
+ headers=None,
23
+ ):
24
+ return Request(
25
+ {
26
+ "type": "http",
27
+ "method": method,
28
+ "path": path,
29
+ "headers": Headers(headers or {}).raw,
30
+ }
31
+ )
32
+
33
+ return _create_request
34
+
35
+
36
+ @pytest.fixture
37
+ def json_content_types():
38
+ """Return a list of valid JSON content types."""
39
+ return [
40
+ "application/json",
41
+ "text/json",
42
+ ]
43
+
44
+
45
+ @pytest.fixture
46
+ def non_json_content_types():
47
+ """Return a list of non-JSON content types."""
48
+ return [
49
+ "text/plain",
50
+ "application/xml",
51
+ "text/html",
52
+ ]
53
+
54
+
55
+ @pytest.fixture
56
+ def search_paths():
57
+ """Return a list of paths that should be identified as search requests."""
58
+ return [
59
+ "/api/_search",
60
+ "/api/search",
61
+ "/api/_query",
62
+ ]
63
+
64
+
65
+ @pytest.fixture
66
+ def command_paths():
67
+ """Return a list of paths that should be identified as command requests."""
68
+ return [
69
+ "/api/_command",
70
+ "/api/command",
71
+ "/api/_request",
72
+ "/api/request",
73
+ "/api/_run",
74
+ "/api/run",
75
+ "/api/_execute",
76
+ "/api/execute",
77
+ ]
78
+
79
+
80
+ @pytest.fixture
81
+ def create_paths():
82
+ """Return a list of paths that should be identified as create requests."""
83
+ return [
84
+ "/api/create",
85
+ "/api/data", # POST without search/command
86
+ ]
87
+
88
+
89
+ def test_wants_json_with_content_type(
90
+ mock_request, json_content_types, non_json_content_types
91
+ ):
92
+ """Test wants_json with different content types."""
93
+ # Test valid JSON content types
94
+ for content_type in json_content_types:
95
+ request = mock_request(headers={"Content-Type": content_type})
96
+ assert wants_json(request) is True
97
+
98
+ # Test non-JSON content types
99
+ for content_type in non_json_content_types:
100
+ request = mock_request(headers={"Content-Type": content_type})
101
+ assert wants_json(request) is False
102
+
103
+ # Test missing content type
104
+ request = mock_request()
105
+ assert wants_json(request) is False
106
+
107
+
108
+ def test_wants_json_with_path(mock_request):
109
+ """Test wants_json with .json path."""
110
+ # Test .json suffix
111
+ request = mock_request(path="/api/data.json")
112
+ assert wants_json(request) is True
113
+
114
+ # Test non-.json path
115
+ request = mock_request(path="/api/data")
116
+ assert wants_json(request) is False
117
+
118
+
119
+ def test_looks_like_a_search(mock_request, search_paths):
120
+ """Test looks_like_a_search with different paths."""
121
+ # Test search paths
122
+ for path in search_paths:
123
+ request = mock_request(path=path)
124
+ assert looks_like_a_search(request) is True
125
+
126
+ # Test non-search path
127
+ request = mock_request(path="/api/data")
128
+ assert looks_like_a_search(request) is False
129
+
130
+
131
+ def test_looks_like_a_command(mock_request, command_paths):
132
+ """Test looks_like_a_command with different paths."""
133
+ # Test command paths
134
+ for path in command_paths:
135
+ request = mock_request(path=path)
136
+ assert looks_like_a_command(request) is True
137
+
138
+ # Test non-command path
139
+ request = mock_request(path="/api/data")
140
+ assert looks_like_a_command(request) is False
141
+
142
+
143
+ def test_looks_like_a_create(mock_request, create_paths, search_paths, command_paths):
144
+ """Test looks_like_a_create with different scenarios."""
145
+ # Test create paths with POST method
146
+ for path in create_paths:
147
+ request = mock_request(method="POST", path=path)
148
+ assert looks_like_a_create(request) is True
149
+
150
+ # Test POST with search paths (should be False)
151
+ for path in search_paths:
152
+ request = mock_request(method="POST", path=path)
153
+ assert looks_like_a_create(request) is False
154
+
155
+ # Test POST with command paths (should be False)
156
+ for path in command_paths:
157
+ request = mock_request(method="POST", path=path)
158
+ assert looks_like_a_create(request) is False
159
+
160
+ # Test non-POST method
161
+ request = mock_request(method="GET", path="/api/data")
162
+ assert looks_like_a_create(request) is False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mockstack
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: An API mocking workhorse
5
5
  Author-email: Adam Ever-Hadani <mockstack.contact@gmail.com>
6
6
  License-Expression: MIT
@@ -68,6 +68,7 @@ mockstack/tests/__init__.py
68
68
  mockstack/tests/conftest.py
69
69
  mockstack/tests/test_display.py
70
70
  mockstack/tests/test_identifiers.py
71
+ mockstack/tests/test_intent.py
71
72
  mockstack/tests/test_middleware.py
72
73
  mockstack/tests/test_telemetry.py
73
74
  mockstack/tests/test_templating.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes