1use datastore;
2use datastore::UserGroup;
3use persistencer;
4use rustix_event_shop;
5use persistencer::LMDBPersistencer;
6use persistencer::Persistencer;
7use serde_json;
8use serde_yaml;
9use std;
10use std::fs::File;
11use std::io::prelude::*;
12use datastore::Datastore;
13
14#[derive(Debug)]
15pub struct RustixBackend {
16 pub datastore: datastore::Datastore,
17 pub persistencer: persistencer::FilePersister,
18}
19pub trait WriteBackend {
30
31 fn apply(&mut self, event: &rustix_event_shop::BLEvents) -> bool;
32
33 fn snapshot(&mut self) -> Option<u64>;
34
35 fn load_snapshot(&mut self) -> Option<u64>;
36
37 fn create_bill(&mut self, timestamp_from: i64, timestamp_to: i64, user_ids: UserGroup, comment: String) -> bool;
38 fn create_item(&mut self, itemname: String, price_cents: u32, category: Option<String>)
39 -> bool;
40 fn create_user(&mut self, username: String) -> bool;
41 fn update_item(&mut self, item_id: u32, itemname: String, price_cents: u32, category: Option<String>)
42 -> bool;
43 fn update_user(&mut self, user_id: u32, username: String, is_billed: bool, is_highlighted: bool, external_user_id: Option<String>, is_sepa: bool) -> bool;
44
45 fn delete_user(&mut self, user_id: u32) -> bool;
46 fn delete_item(&mut self, item_id: u32) -> bool;
47
48 fn purchase(&mut self, user_id: u32, item_id: u32, millis_timestamp: i64) -> bool;
49
50 fn special_purchase(&mut self, user_id: u32, special_name: String, millis_timestamp: i64) -> bool;
51
52 fn cart_purchase(&mut self, user_id: u32, specials: Vec<String>, item_ids: Vec<u32>, millis_timestamp: i64) -> bool;
53
54 fn ffa_purchase(&mut self, ffa_id: u64, item_id: u32, millis_timestamp: i64) -> bool;
55
56 fn create_ffa(&mut self, allowed_categories : Vec<String>,
57 allowed_drinks : Vec<u32>,
58 allowed_number_total : u16,
59 text_message : String,
60 created_timestamp : i64,
61 donor : u32) -> bool;
62
63 fn create_free_budget(&mut self, cents_worth_total : u64,
64 text_message : String,
65 created_timestamp : i64,
66 donor : u32,
67 recipient : u32) -> bool;
68
69 fn create_free_count(&mut self, allowed_categories : Vec<String>,
70 allowed_drinks : Vec<u32>,
71 allowed_number_total : u16,
72 text_message : String,
73 created_timestamp : i64,
74 donor : u32,
75 recipient : u32) -> bool;
76
77 fn undo_purchase(&mut self, unique_id: u64) -> bool;
78
79 fn reload(&mut self) -> Result<u64, persistencer::RustixError>;
80}
81
82
83impl WriteBackend for RustixBackend {
84 fn create_bill(&mut self, timestamp_from: i64, timestamp_to: i64, user_ids: UserGroup, comment: String) -> bool {
85 return self.persistencer.test_store_apply(
86 &rustix_event_shop::BLEvents::CreateBill {
87 timestamp_from: timestamp_from,
88 timestamp_to: timestamp_to,
89 user_ids: user_ids,
90 comment: comment,
91 },
92 &mut self.datastore,
93 );
94 }
95
96 fn create_item(
97 &mut self,
98 itemname: String,
99 price_cents: u32,
100 category: Option<String>,
101 ) -> bool {
102 return self.persistencer.test_store_apply(
103 &rustix_event_shop::BLEvents::CreateItem {
104 itemname: itemname,
105 price_cents: price_cents,
106 category: category,
107 },
108 &mut self.datastore,
109 );
110 }
111
112 fn create_user(&mut self, username: String) -> bool {
113 return self.persistencer.test_store_apply(
114 &rustix_event_shop::BLEvents::CreateUser { username: username },
115 &mut self.datastore,
116 );
117 }
118
119 fn delete_user(&mut self, user_id: u32) -> bool {
120 return self.persistencer.test_store_apply(
121 &rustix_event_shop::BLEvents::DeleteUser { user_id: user_id },
122 &mut self.datastore,
123 );
124 }
125
126 fn delete_item(&mut self, item_id: u32) -> bool {
127 return self.persistencer.test_store_apply(
128 &rustix_event_shop::BLEvents::DeleteItem { item_id: item_id },
129 &mut self.datastore,
130 );
131 }
132
133 fn purchase(&mut self, user_id: u32, item_id: u32, millis_timestamp: i64) -> bool {
134 return self.persistencer.test_store_apply(
135 &rustix_event_shop::BLEvents::MakeSimplePurchase {
136 user_id: user_id,
137 item_id: item_id,
138 timestamp: millis_timestamp,
139 },
140 &mut self.datastore,
141 );
142 }
143
144
145 fn reload(&mut self) -> Result<u64, persistencer::RustixError> {
146 let counter = self.load_snapshot();
147 return self.persistencer.reload_from_filepath(&mut self.datastore);
148 }
149 fn undo_purchase(&mut self, unique_id: u64) -> bool {
150 return self.persistencer.test_store_apply(
151 &rustix_event_shop::BLEvents::UndoPurchase {
152 unique_id: unique_id,
153 },
154 &mut self.datastore,
155 );
156 }
157 fn special_purchase(&mut self, user_id: u32, special_name: String, millis_timestamp: i64) -> bool {
158 return self.persistencer.test_store_apply(
159 &rustix_event_shop::BLEvents::MakeSpecialPurchase {
160 user_id: user_id,
161 special_name: special_name,
162 timestamp: millis_timestamp,
163 },
164 &mut self.datastore,
165 );
166 }
167
168 fn ffa_purchase(&mut self, ffa_id: u64, item_id: u32, millis_timestamp: i64) -> bool {
169 return self.persistencer.test_store_apply(
170 &rustix_event_shop::BLEvents::MakeFreeForAllPurchase {
171 ffa_id: ffa_id,
172 item_id: item_id,
173 timestamp: millis_timestamp,
174 },
175 &mut self.datastore,
176 );
177 }
178
179 fn create_ffa(&mut self, allowed_categories: Vec<String>, allowed_drinks: Vec<u32>, allowed_number_total: u16, text_message: String, created_timestamp: i64, donor: u32) -> bool {
180 return self.persistencer.test_store_apply(
181 &rustix_event_shop::BLEvents::CreateFreeForAll {
182 allowed_categories: allowed_categories,
183 allowed_drinks: allowed_drinks,
184 allowed_number_total: allowed_number_total,
185 text_message: text_message,
186 created_timestamp: created_timestamp,
187 donor: donor,
188 },
189 &mut self.datastore,
190 );
191 }
192
193 fn create_free_budget(&mut self, cents_worth_total: u64, text_message: String, created_timestamp: i64, donor: u32, recipient: u32) -> bool {
194
195 return self.persistencer.test_store_apply(
196 &rustix_event_shop::BLEvents::CreateFreeBudget {
197 cents_worth_total: cents_worth_total,
198 text_message: text_message,
199 created_timestamp: created_timestamp,
200 donor: donor,
201 recipient: recipient,
202 },
203 &mut self.datastore,
204 );
205 }
206
207 fn create_free_count(&mut self, allowed_categories: Vec<String>, allowed_drinks: Vec<u32>, allowed_number_total: u16, text_message: String, created_timestamp: i64, donor: u32, recipient: u32) -> bool {
208
209 return self.persistencer.test_store_apply(
210 &rustix_event_shop::BLEvents::CreateFreeCount {
211 allowed_categories: allowed_categories,
212 allowed_drinks: allowed_drinks,
213 allowed_number_total: allowed_number_total,
214 text_message: text_message,
215 created_timestamp: created_timestamp,
216 donor: donor,
217 recipient: recipient,
218 },
219 &mut self.datastore,
220 );
221 }
222 fn cart_purchase(&mut self, user_id: u32, specials: Vec<String>, item_ids: Vec<u32>, millis_timestamp: i64) -> bool {
223 return self.persistencer.test_store_apply(
224 &rustix_event_shop::BLEvents::MakeShoppingCartPurchase {
225 user_id: user_id,
226 specials: specials,
227 item_ids: item_ids,
228 timestamp: millis_timestamp,
229 },
230 &mut self.datastore,
231 );
232 }
233 fn update_item(&mut self, item_id: u32, itemname: String, price_cents: u32, category: Option<String>) -> bool {
234 return self.persistencer.test_store_apply(
235 &rustix_event_shop::BLEvents::UpdateItem {
236 item_id: item_id,
237 itemname: itemname,
238 price_cents: price_cents,
239 category: category,
240 },
241 &mut self.datastore,
242 );
243 }
244
245 fn update_user(&mut self, user_id: u32, username: String, is_billed: bool, is_highlighted: bool, external_user_id: Option<String>, is_sepa: bool) -> bool {
246 return self.persistencer.test_store_apply(
247 &rustix_event_shop::BLEvents::UpdateUser {
248 user_id: user_id,
249 username: username,
250 is_billed: is_billed,
251 is_highlighted: is_highlighted,
252 external_user_id: external_user_id,
253 is_sepa: is_sepa,
254 },
255 &mut self.datastore,
256 );
257 }
258 fn apply(&mut self, event: &rustix_event_shop::BLEvents) -> bool {
259 return self.persistencer.test_store_apply(event, &mut self.datastore);
260 }
261
262 fn snapshot(&mut self) -> Option<u64> {
263 if !self.persistencer.config.use_persistence {
265 println!("snapshot() called, but not using persistence");
266 return None;
267 }
268
269 let filepath = self.persistencer.config.persistence_file_path.to_owned() + "/snapshot.yaml";
271 println!("snapshot() called, with file = {}", &filepath);
272
273 match serde_yaml::to_string(&self.datastore) {
277 Ok(json) => {
278
279 println!("snapshot() called, writing json");
280 let mut file_res = std::fs::File::create(filepath);
282 match file_res {
283 Ok(mut file) => {
284 let res = file.write_all(&json.into_bytes());
285 match res {
286 Ok(e) => {
287 println!("Success on snapshot()");
289 return Some(self.datastore.version);
290 },
291 Err(e) => {
292 println!("Eror writing file on snapshot(): {:?}", e);
293 return None
294 },
295 }
296 },
297 Err(e) => {
298 println!("Error opening file on snapshot(): {:?}", e);
299 return None
300 },
301 }
302 },
303 Err(e) => {
305 println!("Error creating json on snapshot(): {:?}", e);
306 return None
307 },
308 }
309 }
310 fn load_snapshot(&mut self) -> Option<u64> {
311 if !self.persistencer.config.use_persistence {
313 return None;
314 }
315
316 let filepath = self.persistencer.config.persistence_file_path.to_owned() + "/snapshot.yaml";
318
319 let mut file_raw= File::open(filepath);
320 if file_raw.is_err() {
321 return None;
322 }
323 let mut file = file_raw.unwrap();
324 let mut contents: String = String::new();
325 if file.read_to_string(&mut contents).is_err() {
326 return None
327 }
328
329 let ds_raw = serde_yaml::from_str(&contents);
331 if ds_raw.is_err() {
332 return None;
333 }
334 let ds: Datastore = ds_raw.unwrap();
335
336 let version: u64 = ds.version;
338 self.datastore = ds;
339
340 return Some(version);
342 }
343}
344
345
346#[cfg(test)]
350mod tests {
351 use rustix_event_shop;
352 use rustix_event_shop::BLEvents;
353 use serde_json;
354 use rustix_backend::RustixBackend;
355 use std;
356 use datastore;
357 use persistencer;
358 use config;
359 use std::collections::HashSet;
360 use datastore::UserGroup::AllUsers;
361 use suffix_rs::KDTree;
362 use datastore::*;
363 use datastore::PurchaseFunctions;
364 use datastore::DatastoreQueries;
365 use rustix_backend::WriteBackend;
366 use rustix_event_shop::BLEvents::SetPriceForSpecial;
367
368 fn build_test_backend() -> RustixBackend {
369 let config = config::StaticConfig::default();
370 return RustixBackend {
371 datastore: datastore::Datastore::default(),
372 persistencer: persistencer::FilePersister::new(config).unwrap(),
373 };
374 }
375
376 #[test]
377 fn simple_create_user_on_backend() {
378 let mut backend = build_test_backend();
379 backend.create_user("klaus".to_string());
380 println!("{:?}", backend);
381 assert_eq!(backend.datastore.users.len(), 1);
382 assert_eq!(backend.datastore.user_id_counter, 1);
383 assert_eq!(
384 backend.datastore.users.get(&0).unwrap().username,
385 "klaus".to_string()
386 );
387 }
388
389 #[test]
390 fn simple_create_item_on_backend() {
391 let mut backend = build_test_backend();
392 backend.create_item("beer".to_string(), 95, Some("Alcohol".to_string()));
393 backend.create_item("soda".to_string(), 75, None);
394 assert_eq!(backend.datastore.items.len(), 2);
395 assert_eq!(backend.datastore.item_id_counter, 2);
396 assert_eq!(
397 backend.datastore.items.get(&0).unwrap().name,
398 "beer".to_string()
399 );
400 assert_eq!(
401 backend.datastore.items.get(&1).unwrap().name,
402 "soda".to_string()
403 );
404 assert_eq!(
405 backend
406 .datastore
407 .items
408 .get(&0)
409 .unwrap()
410 .category
411 .clone()
412 .unwrap(),
413 "Alcohol".to_string()
414 );
415 assert_eq!(backend.datastore.items.get(&1).unwrap().cost_cents, 75);
416 assert_eq!(backend.datastore.categories.len(), 1);
417 }
418
419 #[test]
420 fn simple_delete_item() {
421 let mut backend = build_test_backend();
422 backend.create_item("beer".to_string(), 95, Some("Alcohol".to_string()));
423 backend.create_item("soda".to_string(), 75, None);
424 assert_eq!(backend.datastore.items.len(), 2);
425 assert_eq!(backend.datastore.item_id_counter, 2);
426 assert_eq!(
427 backend.datastore.items.get(&0).unwrap().name,
428 "beer".to_string()
429 );
430 assert_eq!(
431 backend.datastore.items.get(&1).unwrap().name,
432 "soda".to_string()
433 );
434 assert_eq!(
435 backend
436 .datastore
437 .items
438 .get(&0)
439 .unwrap()
440 .category
441 .clone()
442 .unwrap(),
443 "Alcohol".to_string()
444 );
445 assert_eq!(backend.datastore.items.get(&1).unwrap().cost_cents, 75);
446 assert_eq!(backend.datastore.categories.len(), 1);
447 backend.delete_item(1);
448 assert_eq!(backend.datastore.items.len(), 2);
449 assert_eq!(backend.datastore.item_id_counter, 2);
450 assert_eq!(
451 backend.datastore.items.get(&0).unwrap().name,
452 "beer".to_string()
453 );
454 assert_eq!(
455 backend
456 .datastore
457 .items
458 .get(&0)
459 .unwrap()
460 .category
461 .clone()
462 .unwrap(),
463 "Alcohol".to_string()
464 );
465 assert_eq!(backend.datastore.categories.len(), 1);
466 }
467
468
469 #[test]
470 fn simple_delete_user() {
471 let mut backend = build_test_backend();
472 backend.create_user("klaus".to_string());
473 assert_eq!(backend.datastore.users.len(), 1);
474 assert_eq!(backend.datastore.user_id_counter, 1);
475 assert_eq!(
476 backend.datastore.users.get(&0).unwrap().username,
477 "klaus".to_string()
478 );
479 backend.delete_user(0);
480 assert_eq!(backend.datastore.users.len(), 1);
481 assert_eq!(backend.datastore.user_id_counter, 1);
482 }
483
484
485 #[test]
486 fn simple_purchase() {
487 let mut backend = build_test_backend();
488 backend.persistencer.config.users_in_top_users = 1usize;
489
490 backend.create_user("klaus".to_string());
492 backend.create_user("dieter".to_string());
493
494 backend.create_item("beer".to_string(), 135u32, Some("Alcoholics".to_string()));
496
497 println!(
500 "Beginning simple purchase test with datastore={:?}",
501 backend.datastore
502 );
503 assert_eq!(backend.purchase(0, 0, 12345678i64), false);
504 assert_eq!(backend.datastore.purchases.len(), 1);
505 assert_eq!(backend.datastore.top_users.len(), 1);
506 assert_eq!(backend.datastore.top_users.get(&0).unwrap(), &0u32);
507
508 assert_eq!(backend.purchase(1, 0, 12345888i64), false);
511 assert_eq!(backend.datastore.purchases.len(), 2);
512 assert_eq!(backend.datastore.top_users.len(), 1);
513 assert_eq!(backend.datastore.top_users.get(&0).unwrap(), &0u32);
514
515 backend.purchase(1, 0, 12347878i64);
517
518 assert_eq!(backend.datastore.purchases.len(), 3);
520 assert_eq!(backend.datastore.top_users.len(), 1);
521
522 println!(
523 "Ending simple purchase test with datastore={:?}",
524 backend.datastore
525 );
526 assert_eq!(backend.datastore.top_users.get(&1).unwrap(), &1u32);
527 assert_eq!(
528 backend
529 .datastore
530 .top_drinks_per_user
531 .get(&0)
532 .unwrap()
533 .get(&0u32)
534 .unwrap(),
535 &0u32
536 );
537 assert_eq!(
538 backend
539 .datastore
540 .top_drinks_per_user
541 .get(&1)
542 .unwrap()
543 .get(&0u32)
544 .unwrap(),
545 &0u32
546 );
547
548
549 println!("Datastore before search: {:?}", backend.datastore);
550
551 assert_eq!(backend.datastore.get_purchase(1).unwrap().get_item_id(), &0u32);
553 assert_eq!(backend.datastore.get_purchase(1).unwrap().get_user_id(), &0u32);
554 assert_eq!(backend.datastore.get_purchase(1).unwrap().get_unique_id(), 1u64);
555 assert_eq!(backend.datastore.get_purchase(2).unwrap().get_item_id(), &0u32);
556 assert_eq!(backend.datastore.get_purchase(2).unwrap().get_user_id(), &1u32);
557 assert_eq!(backend.datastore.get_purchase(2).unwrap().get_unique_id(), 2u64);
558 assert_eq!(backend.datastore.get_purchase(3).unwrap().get_item_id(), &0u32);
559 assert_eq!(backend.datastore.get_purchase(3).unwrap().get_user_id(), &1u32);
560 assert_eq!(backend.datastore.get_purchase(3).unwrap().get_unique_id(), 3u64);
561
562 assert_eq!(backend.datastore.get_purchase(0).is_none(), true);
563
564 assert_eq!(backend.datastore.get_purchase(4).is_none(), true);
565
566
567 let two_user = backend.datastore.users_searchhit_ids("");
569 let one_user = backend.datastore.users_searchhit_ids("klau");
570 let zero_user = backend.datastore.users_searchhit_ids("lisa");
571
572 assert_eq!(two_user.len(), 2);
573 assert_eq!(one_user.len(), 1);
574 assert_eq!(zero_user.len(), 0);
575
576 let all_item = backend.datastore.items_searchhit_ids("");
578 let one_item = backend.datastore.items_searchhit_ids("beer");
579 let zero_item = backend.datastore.items_searchhit_ids("cola");
580
581 assert_eq!(one_item.len(), 1);
582 assert_eq!(all_item.len(), 1);
583 assert_eq!(zero_item.len(), 0);
584
585 let top_two_user = backend.datastore.top_user_ids(2);
587 let top_three_user = backend.datastore.top_user_ids(3);
588 let top_one_user = backend.datastore.top_user_ids(1);
589 let top_zero_user = backend.datastore.top_user_ids(0);
590
591 assert_eq!(top_two_user.len(), 2);
592 assert_eq!(top_three_user.len(), 2);
593 assert_eq!(top_one_user.len(), 1);
594 assert_eq!(top_zero_user.len(), 0);
595
596
597 let top_items = backend.datastore.top_item_ids(0, 2);
600 let no_top_items = backend.datastore.top_item_ids(0, 0);
601
602 assert_eq!(top_items.len(), 1);
603 assert_eq!(no_top_items.len(), 0);
604
605 let lowest_time_point = 1000i64;
607 let low_mid_time_point = 12345680i64;
608 let mid_time_point = 12345880i64;
609 let high_mid_time_poin = 12345890i64;
610 let highest_time_point = 12447878i64;
611
612 let all_personal_purchases = backend.datastore.personal_log_filtered(1, lowest_time_point, highest_time_point);
613 let one_personal_purchases = backend.datastore.personal_log_filtered(1, low_mid_time_point, high_mid_time_poin);
614 let zero_personal_purchases = backend.datastore.personal_log_filtered(1, low_mid_time_point, mid_time_point);
615
616 assert_eq!(all_personal_purchases.len(), 2);
617 assert_eq!(one_personal_purchases.len(), 1);
618 assert_eq!(zero_personal_purchases.len(), 0);
619
620
621 let all_global_purchases = backend.datastore.global_log_filtered(lowest_time_point, highest_time_point);
623 let one_global_purchases = backend.datastore.global_log_filtered(low_mid_time_point, high_mid_time_poin);
624 let zero_global_purchases = backend.datastore.global_log_filtered(low_mid_time_point, mid_time_point);
625
626
627 assert_eq!(all_global_purchases.len(), 3);
628 assert_eq!(one_global_purchases.len(), 1);
629 assert_eq!(zero_global_purchases.len(), 0);
630
631 }
632
633 #[test]
634 fn simple_create_bill() {
635 let mut backend = build_test_backend();
636 backend.create_user("user a".to_string());
638 backend.create_user("user b".to_string());
639 backend.create_user("donated_to_user".to_string());
640 backend.create_item("item 1".to_string(), 45, None);
641 backend.create_item("item 2".to_string(), 55, Some("category a".to_string()));
642 backend.create_item("item 3".to_string(), 75, Some("category b".to_string()));
643
644
645 {
646 let a = backend.datastore.users_suffix_tree.search("user");
647 let b = backend.datastore.users_suffix_tree.search("user a");
648 let c = backend.datastore.users_suffix_tree.search("");
649
650 assert_eq!(a.len(), 3);
651 assert_eq!(b.len(), 1);
652 assert_eq!(c.len(), 3);
653 }
654
655
656 backend.purchase(0, 0, 10);
657 backend.purchase(0, 1, 20);
658 backend.purchase(0, 0, 30);
659
660 backend.create_free_budget(1000, "some budget message".to_string(), 31, 0, 2);
661 backend.create_free_count(vec!["category a".to_string()], vec![0], 2, "some count message".to_string(), 32, 0, 2);
662
663 backend.purchase(2, 0, 33);
664 backend.purchase(2, 1, 34);
665
666
667
668 backend.create_ffa(Vec::new(), vec![0, 1], 2, "my ffa message".to_string(), 35, 0);
669 let ffa_id : u64 = backend.datastore.open_ffa[0].get_id();
670
671
672 backend.purchase(2, 0, 36);
673 backend.purchase(2, 0, 37);
674 backend.purchase(2, 1, 38);
675 backend.purchase(2, 0, 39);
676
677
678 backend.special_purchase(0, "some special".to_string(), 40);
679
680 assert_eq!(backend.ffa_purchase(ffa_id, 0, 50), true);
681 assert_eq!(backend.ffa_purchase(ffa_id, 0, 60), true);
682
683
684 assert_eq!(backend.ffa_purchase(ffa_id, 1, 70), false);
685
686 let user_key = (0, (&backend).datastore.users.get(&0).unwrap().username.to_string());
687 let user_1_key = (1, (&backend).datastore.users.get(&1).unwrap().username.to_string());
688 let item_0_key = (0, (&backend).datastore.items.get(&0).unwrap().name.to_string());
689 let item_1_key = (1, (&backend).datastore.items.get(&1).unwrap().name.to_string());
690 println!("Testoutput = {:?}\nwith user key = {:?}\nand item key = {:?}", backend.datastore, &user_key, &item_0_key);
691 assert!(backend
692 .datastore
693 .balance_cost_per_user
694 .get(&user_key)
695 .is_some());
696 assert_eq!(
697 backend
698 .datastore
699 .balance_cost_per_user
700 .get(&user_key)
701 .unwrap()
702 .get(&item_0_key)
703 .unwrap(),
704 &180u32
705 );
706
707 assert_eq!(
708 backend
709 .datastore
710 .balance_cost_per_user
711 .get(&user_key)
712 .unwrap()
713 .get(&item_1_key)
714 .unwrap(),
715 &55u32
716 );
717
718
719 assert_eq!(
720 backend.datastore.balance_cost_per_user.get(&user_1_key).is_none(),
721 true
722 );
723
724
725 backend.create_bill(0, 100, AllUsers, "remark of bill".to_string());
727
728
729 assert_eq!(
730 backend.datastore.bills[0].bill_state.is_finalized(),
731 false
732 );
733 assert_eq!(
734 backend.datastore.purchases.len(),
735 12
736 );
737
738 backend.update_user(0, "user a".to_string(), true, false, Some("user_id_external_a".to_string()), true);
739 backend.update_user(1, "user b".to_string(), false, false, None, false);
740 backend.update_user(2, "updated_donated_to_user".to_string(), true, false, Some("user_2_external_id".to_string()), true);
741
742
743 assert_eq!(
744 backend.datastore.open_freebies.get(&2).unwrap().len(),
745 2
746 );
747
748 assert_eq!(backend.apply(&BLEvents::FinalizeBill{timestamp_from: 0, timestamp_to: 100}) , false);
749
750 assert_eq!(backend.apply(&SetPriceForSpecial {
751 unique_id: 10,
752 price: 15,
753 }), true);
754
755 assert_eq!(backend.apply(&BLEvents::FinalizeBill{timestamp_from: 0, timestamp_to: 100}) , true);
756
757
758 assert_eq!(
759 backend.datastore.bills[0].bill_state.is_finalized(),
760 true
761 );
762 assert_eq!(
763 backend.datastore.purchases.len(),
764 0
765 );
766 assert_eq!(
767 backend.datastore.bills[0].finalized_data.all_items.len(),
768 2
769 );
770 assert_eq!(
771 backend.datastore.bills[0].finalized_data.all_users.len(),
772 2
773 );
774 assert_eq!(
775 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().personally_consumed.len(),
776 2
777 );
778 assert_eq!(
779 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().ffa_giveouts.len(),
780 1
781 );
782 assert_eq!(
783 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.len(),
784 1
785 );
786 assert_eq!(
787 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.get(&2).unwrap().budget_given,
788 190
789 );
790 assert_eq!(
791 backend.datastore.bills[0].finalized_data.user_consumption.get(&2).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.get(&0).unwrap().budget_gotten,
792 190
793 );
794 assert_eq!(
795 backend.datastore.bills[0].finalized_data.user_consumption.get(&2).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.get(&0).unwrap().budget_given,
796 0
797 );
798 assert_eq!(
799 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.get(&2).unwrap().budget_gotten,
800 0
801 );
802 assert_eq!(
803 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().giveouts_to_user_id.get(&2).unwrap().count_giveouts_used.len(),
804 2
805 );
806 assert_eq!(
807 backend.datastore.bills[0].finalized_data.user_consumption.get(&0).unwrap().per_day.get(&0).unwrap().specials_consumed.len(),
808 1
809 );
810
811
812 assert_eq!(
813 backend.datastore.open_freebies.get(&2).unwrap().len(),
814 1
815 );
816
817
818
819 backend.purchase(0, 0, 110);
898 backend.purchase(1, 2, 120);
899 backend.purchase(1, 0, 130);
900
901}
962
963
964
965
966
967 #[test]
968 fn simple_ffa_purchase() {
969 let mut backend = build_test_backend();
970 let ts1 = 1i64;
971 let ts2 = 2i64;
972
973 backend.create_user("klaus".to_string());
974 backend.create_item("item 1".to_string(), 45, None);
975 backend.create_ffa(Vec::new(), vec![0], 1, "some textmessage".to_string(), ts1, 0);
976
977 println!("open_ffa = {:?}\nused_up = {:?}", backend.datastore.open_ffa, backend.datastore.used_up_freebies);
978 assert_eq!(backend.datastore.open_ffa.len(), 1);
980 assert_eq!(backend.datastore.open_freebies.len(), 0);
981 assert_eq!(backend.datastore.used_up_freebies.len(), 0);
982 assert_eq!(backend.datastore.open_ffa[0].get_id(), 1);
983 backend.ffa_purchase(1, 0, ts2);
984
985 assert_eq!(backend.datastore.purchases.len(), 1);
986 assert_eq!(backend.datastore.purchase_count, 1);
987
988 println!("open_ffa = {:?}\nused_up = {:?}", backend.datastore.open_ffa, backend.datastore.used_up_freebies);
989 assert_eq!(backend.datastore.open_ffa.len(), 0);
991 assert_eq!(backend.datastore.open_freebies.len(), 0);
992 assert_eq!(backend.datastore.used_up_freebies.len(), 1);
993
994
995 }
996
997
998}