@@ -26,3 +26,245 @@ async fn test_event() -> Result<()> {
2626
2727 Ok ( ( ) )
2828}
29+
30+ #[ tokio:: test]
31+ async fn test_event_screen_size ( ) -> Result < ( ) > {
32+ let app = common:: app ( ) ;
33+ let ( tx, rx) = common:: events ( ) ;
34+ let client = common:: TestClient :: new ( app. clone ( ) , tx) ;
35+ app. entities . create ( & Entity { display_name : "Entity 1" . to_string ( ) , id : "entity-1" . to_string ( ) } , & [ ] ) ?;
36+
37+ let ua = vec ! [ ( "user-agent" . to_string( ) , "Mozilla/5.0 (test)" . to_string( ) ) ] ;
38+
39+ // Mobile: 375px
40+ let res = client
41+ . post_with_headers (
42+ "/api/event" ,
43+ json ! ( {
44+ "entity_id" : "entity-1" , "name" : "pageview" ,
45+ "url" : "https://example.com/" , "screen_width" : 375
46+ } ) ,
47+ ua. clone ( ) ,
48+ )
49+ . await ;
50+ res. assert_status_success ( ) ;
51+ let event = rx. recv ( ) . unwrap ( ) ;
52+ assert_eq ! ( event. screen_size. as_deref( ) , Some ( "mobile" ) ) ;
53+
54+ // Tablet: 810px
55+ let res = client
56+ . post_with_headers (
57+ "/api/event" ,
58+ json ! ( {
59+ "entity_id" : "entity-1" , "name" : "pageview" ,
60+ "url" : "https://example.com/" , "screen_width" : 810
61+ } ) ,
62+ ua. clone ( ) ,
63+ )
64+ . await ;
65+ res. assert_status_success ( ) ;
66+ let event = rx. recv ( ) . unwrap ( ) ;
67+ assert_eq ! ( event. screen_size. as_deref( ) , Some ( "tablet" ) ) ;
68+
69+ // Desktop: 1920px
70+ let res = client
71+ . post_with_headers (
72+ "/api/event" ,
73+ json ! ( {
74+ "entity_id" : "entity-1" , "name" : "pageview" ,
75+ "url" : "https://example.com/" , "screen_width" : 1920
76+ } ) ,
77+ ua. clone ( ) ,
78+ )
79+ . await ;
80+ res. assert_status_success ( ) ;
81+ let event = rx. recv ( ) . unwrap ( ) ;
82+ assert_eq ! ( event. screen_size. as_deref( ) , Some ( "desktop" ) ) ;
83+
84+ // Ultrawide: 3840px
85+ let res = client
86+ . post_with_headers (
87+ "/api/event" ,
88+ json ! ( {
89+ "entity_id" : "entity-1" , "name" : "pageview" ,
90+ "url" : "https://example.com/" , "screen_width" : 3840
91+ } ) ,
92+ ua. clone ( ) ,
93+ )
94+ . await ;
95+ res. assert_status_success ( ) ;
96+ let event = rx. recv ( ) . unwrap ( ) ;
97+ assert_eq ! ( event. screen_size. as_deref( ) , Some ( "ultrawide" ) ) ;
98+
99+ // Wuithout screen_width
100+ let res = client
101+ . post_with_headers (
102+ "/api/event" ,
103+ json ! ( {
104+ "entity_id" : "entity-1" , "name" : "pageview" ,
105+ "url" : "https://example.com/"
106+ } ) ,
107+ ua. clone ( ) ,
108+ )
109+ . await ;
110+ res. assert_status_success ( ) ;
111+ let event = rx. recv ( ) . unwrap ( ) ;
112+ assert_eq ! ( event. screen_size, None ) ;
113+
114+ Ok ( ( ) )
115+ }
116+
117+ #[ tokio:: test]
118+ async fn test_screen_size_dimension_api ( ) -> Result < ( ) > {
119+ use chrono:: Utc ;
120+ use liwan:: app:: models:: Event ;
121+
122+ let app = common:: app ( ) ;
123+ let ( tx, _rx) = common:: events ( ) ;
124+ let client = common:: TestClient :: new ( app. clone ( ) , tx) ;
125+
126+ app. seed_database ( 0 ) ?;
127+
128+ let events_to_insert = vec ! [
129+ Event {
130+ entity_id: "entity-1" . to_string( ) ,
131+ visitor_id: "visitor-1" . to_string( ) ,
132+ event: "pageview" . to_string( ) ,
133+ created_at: Utc :: now( ) ,
134+ fqdn: Some ( "example.com" . to_string( ) ) ,
135+ path: Some ( "/" . to_string( ) ) ,
136+ referrer: None ,
137+ platform: None ,
138+ browser: None ,
139+ mobile: Some ( false ) ,
140+ country: None ,
141+ city: None ,
142+ utm_source: None ,
143+ utm_medium: None ,
144+ utm_campaign: None ,
145+ utm_content: None ,
146+ utm_term: None ,
147+ screen_size: Some ( "mobile" . to_string( ) ) ,
148+ } ,
149+ Event {
150+ entity_id: "entity-1" . to_string( ) ,
151+ visitor_id: "visitor-2" . to_string( ) ,
152+ event: "pageview" . to_string( ) ,
153+ created_at: Utc :: now( ) ,
154+ fqdn: Some ( "example.com" . to_string( ) ) ,
155+ path: Some ( "/" . to_string( ) ) ,
156+ referrer: None ,
157+ platform: None ,
158+ browser: None ,
159+ mobile: Some ( true ) ,
160+ country: None ,
161+ city: None ,
162+ utm_source: None ,
163+ utm_medium: None ,
164+ utm_campaign: None ,
165+ utm_content: None ,
166+ utm_term: None ,
167+ screen_size: Some ( "mobile" . to_string( ) ) ,
168+ } ,
169+ Event {
170+ entity_id: "entity-1" . to_string( ) ,
171+ visitor_id: "visitor-2" . to_string( ) ,
172+ event: "pageview" . to_string( ) ,
173+ created_at: Utc :: now( ) ,
174+ fqdn: Some ( "example.com" . to_string( ) ) ,
175+ path: Some ( "/" . to_string( ) ) ,
176+ referrer: None ,
177+ platform: None ,
178+ browser: None ,
179+ mobile: None ,
180+ country: None ,
181+ city: None ,
182+ utm_source: None ,
183+ utm_medium: None ,
184+ utm_campaign: None ,
185+ utm_content: None ,
186+ utm_term: None ,
187+ screen_size: Some ( "tablet" . to_string( ) ) ,
188+ } ,
189+ Event {
190+ entity_id: "entity-1" . to_string( ) ,
191+ visitor_id: "visitor-3" . to_string( ) ,
192+ event: "pageview" . to_string( ) ,
193+ created_at: Utc :: now( ) ,
194+ fqdn: Some ( "example.com" . to_string( ) ) ,
195+ path: Some ( "/" . to_string( ) ) ,
196+ referrer: None ,
197+ platform: None ,
198+ browser: None ,
199+ mobile: None ,
200+ country: None ,
201+ city: None ,
202+ utm_source: None ,
203+ utm_medium: None ,
204+ utm_campaign: None ,
205+ utm_content: None ,
206+ utm_term: None ,
207+ screen_size: Some ( "desktop" . to_string( ) ) ,
208+ } ,
209+ Event {
210+ entity_id: "entity-1" . to_string( ) ,
211+ visitor_id: "visitor-4" . to_string( ) ,
212+ event: "pageview" . to_string( ) ,
213+ created_at: Utc :: now( ) ,
214+ fqdn: Some ( "example.com" . to_string( ) ) ,
215+ path: Some ( "/" . to_string( ) ) ,
216+ referrer: None ,
217+ platform: None ,
218+ browser: None ,
219+ mobile: None ,
220+ country: None ,
221+ city: None ,
222+ utm_source: None ,
223+ utm_medium: None ,
224+ utm_campaign: None ,
225+ utm_content: None ,
226+ utm_term: None ,
227+ screen_size: Some ( "ultrawide" . to_string( ) ) ,
228+ } ,
229+ ] ;
230+ app. events . append ( events_to_insert. into_iter ( ) ) ?;
231+
232+ let start = ( Utc :: now ( ) - chrono:: Duration :: hours ( 1 ) ) . to_rfc3339 ( ) ;
233+ let end = Utc :: now ( ) . to_rfc3339 ( ) ;
234+
235+ let res = client
236+ . post (
237+ "/api/dashboard/project/public-project/dimension" ,
238+ json ! ( {
239+ "dimension" : "screen_size" ,
240+ "filters" : [ ] ,
241+ "metric" : "views" ,
242+ "range" : { "start" : start, "end" : end }
243+ } ) ,
244+ )
245+ . await ;
246+ res. assert_status_success ( ) ;
247+
248+ let body: serde_json:: Value = res. json ( ) ;
249+ let rows = body[ "data" ] . as_array ( ) . expect ( "data should be an array" ) ;
250+
251+ let find = |bucket : & str | rows. iter ( ) . find ( |r| r[ "dimensionValue" ] . as_str ( ) == Some ( bucket) ) ;
252+
253+ let mobile_row = find ( "mobile" ) . expect ( "mobile bucket should be present" ) ;
254+ assert_eq ! ( mobile_row[ "displayName" ] . as_str( ) , Some ( "Mobile" ) ) ;
255+ assert_eq ! ( mobile_row[ "value" ] . as_f64( ) , Some ( 2.0 ) ) ;
256+
257+ let tablet_row = find ( "tablet" ) . expect ( "tablet bucket should be present" ) ;
258+ assert_eq ! ( tablet_row[ "displayName" ] . as_str( ) , Some ( "Tablet" ) ) ;
259+ assert_eq ! ( tablet_row[ "value" ] . as_f64( ) , Some ( 1.0 ) ) ;
260+
261+ let desktop_row = find ( "desktop" ) . expect ( "desktop bucket should be present" ) ;
262+ assert_eq ! ( desktop_row[ "displayName" ] . as_str( ) , Some ( "Desktop" ) ) ;
263+ assert_eq ! ( desktop_row[ "value" ] . as_f64( ) , Some ( 1.0 ) ) ;
264+
265+ let ultrawide_row = find ( "ultrawide" ) . expect ( "ultrawide bucket should be present" ) ;
266+ assert_eq ! ( ultrawide_row[ "displayName" ] . as_str( ) , Some ( "Ultrawide" ) ) ;
267+ assert_eq ! ( ultrawide_row[ "value" ] . as_f64( ) , Some ( 1.0 ) ) ;
268+
269+ Ok ( ( ) )
270+ }
0 commit comments