@@ -8,6 +8,11 @@ defmodule TamaEx.MemoryTest do
88 alias TamaEx.Memory.Entity.Params , as: EntityParams
99 alias TamaEx.Neural.Class
1010
11+ setup do
12+ bypass = Bypass . open ( )
13+ { :ok , bypass: bypass }
14+ end
15+
1116 # Test helper for creating a mock class
1217 defp mock_class ( id \\ "class_123" ) do
1318 % Class {
@@ -17,7 +22,247 @@ defmodule TamaEx.MemoryTest do
1722 }
1823 end
1924
20- describe "create_entity/3" do
25+ describe "create_entity/3 - bypass integration" do
26+ test "successfully creates entity with bypass" , % { bypass: bypass } do
27+ base_url = "http://localhost:#{ bypass . port } "
28+ client = mock_client ( "memory" , base_url )
29+ class = mock_class ( "test_class_123" )
30+
31+ attrs = % {
32+ "identifier" => "test-entity-bypass" ,
33+ "record" => % { "name" => "Test Entity" , "value" => 42 } ,
34+ "validate_record" => true
35+ }
36+
37+ expected_response = % {
38+ "data" => % {
39+ "id" => "entity_created_456" ,
40+ "class_id" => "test_class_123" ,
41+ "current_state" => "active" ,
42+ "identifier" => "test-entity-bypass"
43+ }
44+ }
45+
46+ Bypass . expect ( bypass , "POST" , "/memory/classes/test_class_123/entities" , fn conn ->
47+ { :ok , body , conn } = Plug.Conn . read_body ( conn )
48+ request_data = Jason . decode! ( body )
49+
50+ # Verify the request structure
51+ assert request_data [ "entity" ] [ "identifier" ] == "test-entity-bypass"
52+ assert request_data [ "entity" ] [ "record" ] [ "name" ] == "Test Entity"
53+ assert request_data [ "entity" ] [ "record" ] [ "value" ] == 42
54+ assert request_data [ "entity" ] [ "validate_record" ] == true
55+
56+ conn
57+ |> Plug.Conn . put_resp_content_type ( "application/json" )
58+ |> Plug.Conn . resp ( 201 , Jason . encode! ( expected_response ) )
59+ end )
60+
61+ # Make the actual API call
62+ assert { :ok , % Entity { } = entity } = Memory . create_entity ( client , class , attrs )
63+
64+ # Verify the parsed entity
65+ assert entity . id == "entity_created_456"
66+ assert entity . class_id == "test_class_123"
67+ assert entity . current_state == "active"
68+ assert entity . identifier == "test-entity-bypass"
69+ end
70+
71+ test "handles API error responses with bypass" , % { bypass: bypass } do
72+ base_url = "http://localhost:#{ bypass . port } "
73+ client = mock_client ( "memory" , base_url )
74+ class = mock_class ( "error_class_123" )
75+
76+ attrs = % {
77+ "identifier" => "error-entity" ,
78+ "record" => % { "invalid" => "data" }
79+ }
80+
81+ error_response = % {
82+ "error" => % {
83+ "message" => "Validation failed" ,
84+ "details" => % {
85+ "record" => [ "is invalid" ]
86+ }
87+ }
88+ }
89+
90+ Bypass . expect ( bypass , "POST" , "/memory/classes/error_class_123/entities" , fn conn ->
91+ { :ok , body , conn } = Plug.Conn . read_body ( conn )
92+ request_data = Jason . decode! ( body )
93+
94+ assert request_data [ "entity" ] [ "identifier" ] == "error-entity"
95+ assert request_data [ "entity" ] [ "record" ] [ "invalid" ] == "data"
96+
97+ conn
98+ |> Plug.Conn . put_resp_content_type ( "application/json" )
99+ |> Plug.Conn . resp ( 422 , Jason . encode! ( error_response ) )
100+ end )
101+
102+ # Make the actual API call and expect an error
103+ assert { :error , _error } = Memory . create_entity ( client , class , attrs )
104+ end
105+
106+ test "handles server errors with bypass" , % { bypass: bypass } do
107+ base_url = "http://localhost:#{ bypass . port } "
108+ client = mock_client ( "memory" , base_url )
109+ class = mock_class ( "server_error_class_123" )
110+
111+ attrs = % {
112+ "identifier" => "server-error-entity" ,
113+ "record" => % { "data" => "test" }
114+ }
115+
116+ # Simulate server error
117+ Bypass . expect ( bypass , "POST" , "/memory/classes/server_error_class_123/entities" , fn conn ->
118+ conn
119+ |> Plug.Conn . put_resp_content_type ( "application/json" )
120+ |> Plug.Conn . resp ( 500 , Jason . encode! ( % { "error" => "Internal server error" } ) )
121+ end )
122+
123+ # Make the actual API call and expect an error
124+ assert { :error , _error } = Memory . create_entity ( client , class , attrs )
125+ end
126+
127+ test "handles different class IDs in URL construction" , % { bypass: bypass } do
128+ base_url = "http://localhost:#{ bypass . port } "
129+ client = mock_client ( "memory" , base_url )
130+
131+ test_cases = [
132+ { "simple" , "simple" } ,
133+ { "class_with_underscores" , "class_with_underscores" } ,
134+ { "class-with-dashes" , "class-with-dashes" } ,
135+ { "Class123" , "Class123" }
136+ ]
137+
138+ Enum . each ( test_cases , fn { class_id , expected_url_part } ->
139+ class = mock_class ( class_id )
140+ attrs = % { "identifier" => "test-#{ class_id } " , "record" => % { } }
141+
142+ expected_response = % {
143+ "data" => % {
144+ "id" => "entity_#{ class_id } " ,
145+ "class_id" => class_id ,
146+ "current_state" => "active" ,
147+ "identifier" => "test-#{ class_id } "
148+ }
149+ }
150+
151+ Bypass . expect_once (
152+ bypass ,
153+ "POST" ,
154+ "/memory/classes/#{ expected_url_part } /entities" ,
155+ fn conn ->
156+ conn
157+ |> Plug.Conn . put_resp_content_type ( "application/json" )
158+ |> Plug.Conn . resp ( 201 , Jason . encode! ( expected_response ) )
159+ end
160+ )
161+
162+ assert { :ok , % Entity { } = entity } = Memory . create_entity ( client , class , attrs )
163+ assert entity . class_id == class_id
164+ assert entity . identifier == "test-#{ class_id } "
165+ end )
166+ end
167+
168+ test "validates request headers and content type" , % { bypass: bypass } do
169+ base_url = "http://localhost:#{ bypass . port } "
170+ client = mock_client ( "memory" , base_url )
171+ class = mock_class ( "headers_test_123" )
172+
173+ attrs = % {
174+ "identifier" => "headers-test" ,
175+ "record" => % { "test" => "data" }
176+ }
177+
178+ Bypass . expect ( bypass , "POST" , "/memory/classes/headers_test_123/entities" , fn conn ->
179+ # Verify headers
180+ assert Plug.Conn . get_req_header ( conn , "authorization" ) == [ "Bearer mock_token" ]
181+ assert Plug.Conn . get_req_header ( conn , "content-type" ) == [ "application/json" ]
182+
183+ expected_response = % {
184+ "data" => % {
185+ "id" => "headers_entity_123" ,
186+ "class_id" => "headers_test_123" ,
187+ "current_state" => "active" ,
188+ "identifier" => "headers-test"
189+ }
190+ }
191+
192+ conn
193+ |> Plug.Conn . put_resp_content_type ( "application/json" )
194+ |> Plug.Conn . resp ( 201 , Jason . encode! ( expected_response ) )
195+ end )
196+
197+ assert { :ok , % Entity { } } = Memory . create_entity ( client , class , attrs )
198+ end
199+
200+ test "handles complex record structures with bypass" , % { bypass: bypass } do
201+ base_url = "http://localhost:#{ bypass . port } "
202+ client = mock_client ( "memory" , base_url )
203+ class = mock_class ( "complex_class_123" )
204+
205+ complex_record = % {
206+ "user" => % {
207+ "name" => "John Doe" ,
208+ "age" => 30 ,
209+ "preferences" => % {
210+ "theme" => "dark" ,
211+ "notifications" => true
212+ }
213+ } ,
214+ "metadata" => % {
215+ "created_at" => "2023-01-01T00:00:00Z" ,
216+ "tags" => [ "important" , "test" ]
217+ }
218+ }
219+
220+ attrs = % {
221+ "identifier" => "complex-entity" ,
222+ "record" => complex_record ,
223+ "validate_record" => false
224+ }
225+
226+ expected_response = % {
227+ "data" => % {
228+ "id" => "complex_entity_789" ,
229+ "class_id" => "complex_class_123" ,
230+ "current_state" => "active" ,
231+ "identifier" => "complex-entity"
232+ }
233+ }
234+
235+ Bypass . expect ( bypass , "POST" , "/memory/classes/complex_class_123/entities" , fn conn ->
236+ { :ok , body , conn } = Plug.Conn . read_body ( conn )
237+ request_data = Jason . decode! ( body )
238+
239+ # Verify the complex record structure is preserved
240+ assert request_data [ "entity" ] [ "identifier" ] == "complex-entity"
241+ assert request_data [ "entity" ] [ "record" ] [ "user" ] [ "name" ] == "John Doe"
242+ assert request_data [ "entity" ] [ "record" ] [ "user" ] [ "age" ] == 30
243+ assert request_data [ "entity" ] [ "record" ] [ "user" ] [ "preferences" ] [ "theme" ] == "dark"
244+ assert request_data [ "entity" ] [ "record" ] [ "user" ] [ "preferences" ] [ "notifications" ] == true
245+
246+ assert request_data [ "entity" ] [ "record" ] [ "metadata" ] [ "created_at" ] ==
247+ "2023-01-01T00:00:00Z"
248+
249+ assert request_data [ "entity" ] [ "record" ] [ "metadata" ] [ "tags" ] == [ "important" , "test" ]
250+ assert request_data [ "entity" ] [ "validate_record" ] == false
251+
252+ conn
253+ |> Plug.Conn . put_resp_content_type ( "application/json" )
254+ |> Plug.Conn . resp ( 201 , Jason . encode! ( expected_response ) )
255+ end )
256+
257+ assert { :ok , % Entity { } = entity } = Memory . create_entity ( client , class , attrs )
258+ assert entity . id == "complex_entity_789"
259+ assert entity . class_id == "complex_class_123"
260+ assert entity . current_state == "active"
261+ assert entity . identifier == "complex-entity"
262+ end
263+ end
264+
265+ describe "create_entity/3 - unit tests" do
21266 test "creates entity with valid parameters" do
22267 _client = mock_client ( "ingest" )
23268 _class = mock_class ( )
0 commit comments