@@ -2,10 +2,285 @@ defmodule AnalyticsTest do
22 use ExUnit.Case , async: true
33
44 alias OpenApiTypesense.Analytics
5+ alias OpenApiTypesense.AnalyticsRuleSchema
56 alias OpenApiTypesense.AnalyticsRulesRetrieveSchema
7+ alias OpenApiTypesense.ApiResponse
8+ alias OpenApiTypesense.Collections
9+ alias OpenApiTypesense.CollectionResponse
10+ alias OpenApiTypesense.AnalyticsEventCreateResponse
11+
12+ setup_all do
13+ recipe_name = "recipes"
14+
15+ recipe_schema =
16+ % {
17+ name: recipe_name ,
18+ fields: [
19+ % { "name" => "recipe_name" , "type" => "string" } ,
20+ % { "name" => "#{ recipe_name } _id" , "type" => "int32" } ,
21+ % { "name" => "description" , "type" => "string" }
22+ ] ,
23+ default_sorting_field: "#{ recipe_name } _id"
24+ }
25+ |> Jason . encode_to_iodata! ( )
26+
27+ product_name = "products"
28+
29+ product_schema =
30+ % {
31+ name: product_name ,
32+ fields: [
33+ % { "name" => "product_name" , "type" => "string" } ,
34+ % { "name" => "#{ product_name } _id" , "type" => "int32" } ,
35+ % { "name" => "description" , "type" => "string" } ,
36+ % { "name" => "title" , "type" => "string" } ,
37+ % { "name" => "popularity" , "type" => "int32" , "optional" => true }
38+ ] ,
39+ default_sorting_field: "#{ product_name } _id"
40+ }
41+ |> Jason . encode_to_iodata! ( )
42+
43+ product_queries_name = "product_queries"
44+
45+ product_queries_schema =
46+ % {
47+ "name" => product_queries_name ,
48+ "fields" => [
49+ % { "name" => "q" , "type" => "string" } ,
50+ % { "name" => "count" , "type" => "int32" } ,
51+ % { "name" => "downloads" , "type" => "int32" , "optional" => true }
52+ ]
53+ }
54+ |> Jason . encode_to_iodata! ( )
55+
56+ nohits_queries_name = "no_hits_queries"
57+
58+ nohits_queries_schema =
59+ % {
60+ "name" => nohits_queries_name ,
61+ "fields" => [
62+ % { "name" => "q" , "type" => "string" } ,
63+ % { "name" => "count" , "type" => "int32" }
64+ ]
65+ }
66+ |> Jason . encode_to_iodata! ( )
67+
68+ recipe_nohits_queries_name = "recipe_no_hits_queries"
69+
70+ recipe_nohits_queries_schema =
71+ % {
72+ "name" => recipe_nohits_queries_name ,
73+ "fields" => [
74+ % { "name" => "q" , "type" => "string" } ,
75+ % { "name" => "count" , "type" => "int32" }
76+ ]
77+ }
78+ |> Jason . encode_to_iodata! ( )
79+
80+ [
81+ recipe_schema ,
82+ product_schema ,
83+ product_queries_schema ,
84+ nohits_queries_schema ,
85+ recipe_nohits_queries_schema
86+ ]
87+ |> Enum . map ( fn schema ->
88+ Collections . create_collection ( schema )
89+ end )
90+
91+ on_exit ( fn ->
92+ { :ok , % CollectionResponse { name: ^ recipe_name } } =
93+ Collections . delete_collection ( recipe_name )
94+
95+ { :ok , % CollectionResponse { name: ^ product_name } } =
96+ Collections . delete_collection ( product_name )
97+
98+ { :ok , % CollectionResponse { name: ^ product_queries_name } } =
99+ Collections . delete_collection ( product_queries_name )
100+
101+ { :ok , % CollectionResponse { name: ^ nohits_queries_name } } =
102+ Collections . delete_collection ( nohits_queries_name )
103+
104+ { :ok , % CollectionResponse { name: ^ recipe_nohits_queries_name } } =
105+ Collections . delete_collection ( recipe_nohits_queries_name )
106+
107+ { :ok , % AnalyticsRulesRetrieveSchema { rules: rules } } = Analytics . retrieve_analytics_rules ( )
108+ Enum . map ( rules , & Analytics . delete_analytics_rule ( & 1 . name ) )
109+ end )
110+
111+ :ok
112+ end
113+
114+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
115+ test "error: create analytics rule with non-existent collection" do
116+ name = "products_missing_query"
117+ collection_name = "non_existent_collection"
118+
119+ body =
120+ % {
121+ "name" => name ,
122+ "type" => "counter" ,
123+ "params" => % {
124+ "source" => % {
125+ "collections" => [ "products" ] ,
126+ "events" => [
127+ % { "type" => "click" , "weight" => 1 , "name" => "products_downloads_event" }
128+ ]
129+ } ,
130+ "destination" => % {
131+ "collection" => collection_name ,
132+ "counter_field" => "downloads"
133+ }
134+ }
135+ }
136+ |> Jason . encode_to_iodata! ( )
137+
138+ message = "Collection `#{ collection_name } ` not found."
139+ assert { :error , % ApiResponse { message: ^ message } } = Analytics . create_analytics_rule ( body )
140+ end
141+
142+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
143+ test "success: upsert analytics rule" do
144+ name = "another_product_no_hits"
145+
146+ body =
147+ % {
148+ "type" => "nohits_queries" ,
149+ "params" => % {
150+ "source" => % {
151+ "collections" => [ "recipes" ]
152+ } ,
153+ "destination" => % {
154+ "collection" => "recipe_no_hits_queries"
155+ } ,
156+ "limit" => 1_000
157+ }
158+ }
159+ |> Jason . encode_to_iodata! ( )
160+
161+ assert { :ok , % AnalyticsRuleSchema { name: ^ name } } = Analytics . upsert_analytics_rule ( name , body )
162+ end
163+
164+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
165+ test "error: create analytics rule with wrong field" do
166+ name = "products_test_query"
167+ field_name = "wrong_field"
168+
169+ body =
170+ % {
171+ "name" => name ,
172+ "type" => "counter" ,
173+ "params" => % {
174+ "source" => % {
175+ "collections" => [ "products" ] ,
176+ "events" => [
177+ % { "type" => "click" , "weight" => 1 , "name" => "products_downloads_event" }
178+ ]
179+ } ,
180+ "destination" => % {
181+ "collection" => "product_queries" ,
182+ "counter_field" => field_name
183+ }
184+ }
185+ }
186+ |> Jason . encode_to_iodata! ( )
187+
188+ assert { :error , % ApiResponse { message: _ } } = Analytics . create_analytics_rule ( body )
189+ end
6190
7191 @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
8192 test "success: list analytics rules" do
9- assert { :ok , % AnalyticsRulesRetrieveSchema { } } = Analytics . retrieve_analytics_rules ( )
193+ assert { :ok , % AnalyticsRulesRetrieveSchema { rules: rules } } =
194+ Analytics . retrieve_analytics_rules ( )
195+
196+ assert length ( rules ) >= 0
197+ end
198+
199+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
200+ test "success: create analytics rule" do
201+ name = "product_queries_aggregation"
202+
203+ body =
204+ % {
205+ "name" => name ,
206+ "type" => "popular_queries" ,
207+ "params" => % {
208+ "source" => % {
209+ "collections" => [ "products" ]
210+ } ,
211+ "destination" => % {
212+ "collection" => "product_queries"
213+ } ,
214+ "limit" => 1_000
215+ }
216+ }
217+ |> Jason . encode_to_iodata! ( )
218+
219+ assert { :ok , % AnalyticsRuleSchema { name: ^ name } } = Analytics . create_analytics_rule ( body )
220+ end
221+
222+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
223+ test "success: retrieve analytics rule" do
224+ name = "product_no_hits"
225+
226+ body =
227+ % {
228+ "name" => name ,
229+ "type" => "nohits_queries" ,
230+ "params" => % {
231+ "source" => % {
232+ "collections" => [ "products" ]
233+ } ,
234+ "destination" => % {
235+ "collection" => "no_hits_queries"
236+ } ,
237+ "limit" => 1_000
238+ }
239+ }
240+ |> Jason . encode_to_iodata! ( )
241+
242+ assert { :ok , % AnalyticsRuleSchema { name: ^ name } } = Analytics . create_analytics_rule ( body )
243+ assert { :ok , % AnalyticsRuleSchema { name: ^ name } } = Analytics . retrieve_analytics_rule ( name )
244+ end
245+
246+ @ tag [ "27.1": true , "26.0": true , "0.25.2": true ]
247+ test "success: create analytics event" do
248+ name = "product_downloads"
249+
250+ body =
251+ % {
252+ "name" => name ,
253+ "type" => "counter" ,
254+ "params" => % {
255+ "source" => % {
256+ "collections" => [ "products" ] ,
257+ "events" => [
258+ % { "type" => "click" , "weight" => 1 , "name" => "products_downloads_event" }
259+ ]
260+ } ,
261+ "destination" => % {
262+ "collection" => "product_queries" ,
263+ "counter_field" => "downloads"
264+ }
265+ }
266+ }
267+ |> Jason . encode_to_iodata! ( )
268+
269+ assert { :ok , % AnalyticsRuleSchema { name: ^ name } } = Analytics . create_analytics_rule ( body )
270+
271+ name = "products_downloads_event"
272+
273+ body =
274+ % {
275+ "name" => name ,
276+ "type" => "click" ,
277+ "data" => % {
278+ "doc_id" => "2468" ,
279+ "user_id" => "9903"
280+ }
281+ }
282+ |> Jason . encode_to_iodata! ( )
283+
284+ assert { :ok , % AnalyticsEventCreateResponse { ok: true } } = Analytics . create_analytics_event ( body )
10285 end
11286end
0 commit comments