1pub mod collections {
6 use flix_model::id::CollectionId;
7
8 use sea_orm::entity::prelude::*;
9
10 use crate::entity;
11
12 #[sea_orm::model]
14 #[derive(Debug, Clone, DeriveEntityModel)]
15 #[sea_orm(table_name = "flix_info_collections")]
16 pub struct Model {
17 #[sea_orm(primary_key, auto_increment = false)]
19 pub id: CollectionId,
20 pub title: String,
22 pub overview: String,
24
25 #[sea_orm(indexed)]
27 pub sort_title: String,
28 #[sea_orm(indexed, unique)]
30 pub fs_slug: String,
31 #[sea_orm(indexed, unique)]
33 pub web_slug: String,
34
35 #[sea_orm(has_one)]
37 pub content: HasOne<entity::content::collections::Entity>,
38 }
39
40 #[expect(clippy::missing_trait_methods, reason = "accept default methods")]
41 impl ActiveModelBehavior for ActiveModel {}
42}
43
44pub mod movies {
46 use flix_model::id::MovieId;
47
48 use chrono::NaiveDate;
49 use sea_orm::entity::prelude::*;
50
51 use crate::entity;
52
53 #[sea_orm::model]
55 #[derive(Debug, Clone, DeriveEntityModel)]
56 #[sea_orm(table_name = "flix_info_movies")]
57 pub struct Model {
58 #[sea_orm(primary_key, auto_increment = false)]
60 pub id: MovieId,
61 pub title: String,
63 pub tagline: String,
65 pub overview: String,
67 #[sea_orm(indexed)]
69 pub date: NaiveDate,
70
71 #[sea_orm(indexed)]
73 pub sort_title: String,
74 #[sea_orm(indexed, unique)]
76 pub fs_slug: String,
77 #[sea_orm(indexed, unique)]
79 pub web_slug: String,
80
81 #[sea_orm(has_one)]
83 pub content: HasOne<entity::content::movies::Entity>,
84 }
85
86 #[expect(clippy::missing_trait_methods, reason = "accept default methods")]
87 impl ActiveModelBehavior for ActiveModel {}
88}
89
90pub mod shows {
92 use flix_model::id::ShowId;
93
94 use chrono::NaiveDate;
95 use sea_orm::entity::prelude::*;
96
97 use crate::entity;
98
99 #[sea_orm::model]
101 #[derive(Debug, Clone, DeriveEntityModel)]
102 #[sea_orm(table_name = "flix_info_shows")]
103 pub struct Model {
104 #[sea_orm(primary_key, auto_increment = false)]
106 pub id: ShowId,
107 pub title: String,
109 pub tagline: String,
111 pub overview: String,
113 #[sea_orm(indexed)]
115 pub date: NaiveDate,
116
117 #[sea_orm(indexed)]
119 pub sort_title: String,
120 #[sea_orm(indexed, unique)]
122 pub fs_slug: String,
123 #[sea_orm(indexed, unique)]
125 pub web_slug: String,
126
127 #[sea_orm(has_many)]
129 pub seasons: HasMany<super::seasons::Entity>,
130 #[sea_orm(has_many)]
132 pub episodes: HasMany<super::episodes::Entity>,
133
134 #[sea_orm(has_one)]
136 pub content: HasOne<entity::content::shows::Entity>,
137 }
138
139 #[expect(clippy::missing_trait_methods, reason = "accept default methods")]
140 impl ActiveModelBehavior for ActiveModel {}
141}
142
143pub mod seasons {
145 use flix_model::id::ShowId;
146 use flix_model::numbers::SeasonNumber;
147
148 use chrono::NaiveDate;
149 use sea_orm::entity::prelude::*;
150
151 use crate::entity;
152
153 #[sea_orm::model]
155 #[derive(Debug, Clone, DeriveEntityModel)]
156 #[sea_orm(table_name = "flix_info_seasons")]
157 pub struct Model {
158 #[sea_orm(primary_key, auto_increment = false)]
160 pub show_id: ShowId,
161 #[sea_orm(primary_key, auto_increment = false)]
163 pub season_number: SeasonNumber,
164 pub title: String,
166 pub overview: String,
168 #[sea_orm(indexed)]
170 pub date: NaiveDate,
171
172 #[sea_orm(
174 belongs_to,
175 from = "show_id",
176 to = "id",
177 on_update = "Cascade",
178 on_delete = "Cascade"
179 )]
180 pub show: HasOne<super::shows::Entity>,
181 #[sea_orm(has_many)]
183 pub episodes: HasMany<super::episodes::Entity>,
184
185 #[sea_orm(has_one)]
187 pub content: HasOne<entity::content::seasons::Entity>,
188 }
189
190 #[expect(clippy::missing_trait_methods, reason = "accept default methods")]
191 impl ActiveModelBehavior for ActiveModel {}
192}
193
194pub mod episodes {
196 use flix_model::id::ShowId;
197 use flix_model::numbers::{EpisodeNumber, SeasonNumber};
198
199 use chrono::NaiveDate;
200 use sea_orm::entity::prelude::*;
201
202 use crate::entity;
203
204 #[sea_orm::model]
206 #[derive(Debug, Clone, DeriveEntityModel)]
207 #[sea_orm(table_name = "flix_info_episodes")]
208 pub struct Model {
209 #[sea_orm(primary_key, auto_increment = false)]
211 pub show_id: ShowId,
212 #[sea_orm(primary_key, auto_increment = false)]
214 pub season_number: SeasonNumber,
215 #[sea_orm(primary_key, auto_increment = false)]
217 pub episode_number: EpisodeNumber,
218 pub title: String,
220 pub overview: String,
222 #[sea_orm(indexed)]
224 pub date: NaiveDate,
225
226 #[sea_orm(
228 belongs_to,
229 from = "show_id",
230 to = "id",
231 on_update = "Cascade",
232 on_delete = "Cascade"
233 )]
234 pub show: HasOne<super::shows::Entity>,
235 #[sea_orm(
237 belongs_to,
238 from = "(show_id, season_number)",
239 to = "(show_id, season_number)",
240 on_update = "Cascade",
241 on_delete = "Cascade"
242 )]
243 pub season: HasOne<super::seasons::Entity>,
244
245 #[sea_orm(has_one)]
247 pub content: HasOne<entity::content::episodes::Entity>,
248 }
249
250 #[expect(clippy::missing_trait_methods, reason = "accept default methods")]
251 impl ActiveModelBehavior for ActiveModel {}
252}
253
254#[cfg(test)]
256pub mod test {
257 macro_rules! make_info_collection {
258 ($db:expr, $id:expr) => {
259 drop(
260 $crate::entity::info::collections::ActiveModel {
261 id: Set(::flix_model::id::CollectionId::from_raw($id)),
262 title: Set(::alloc::string::String::new()),
263 overview: Set(::alloc::string::String::new()),
264 sort_title: Set(::alloc::string::String::new()),
265 fs_slug: Set(format!("C FS {}", $id)),
266 web_slug: Set(format!("C Web {}", $id)),
267 }
268 .insert($db)
269 .await
270 .expect("insert"),
271 );
272 };
273 }
274 pub(crate) use make_info_collection;
275
276 macro_rules! make_info_movie {
277 ($db:expr, $id:expr) => {
278 drop(
279 $crate::entity::info::movies::ActiveModel {
280 id: Set(::flix_model::id::MovieId::from_raw($id)),
281 title: Set(::alloc::string::String::new()),
282 tagline: Set(::alloc::string::String::new()),
283 overview: Set(::alloc::string::String::new()),
284 date: Set(::chrono::NaiveDate::from_yo_opt(1, 1).expect("from_yo_opt")),
285 sort_title: Set(::alloc::string::String::new()),
286 fs_slug: Set(format!("M FS {}", $id)),
287 web_slug: Set(format!("M Web {}", $id)),
288 }
289 .insert($db)
290 .await
291 .expect("insert"),
292 );
293 };
294 }
295 pub(crate) use make_info_movie;
296
297 macro_rules! make_info_show {
298 ($db:expr, $id:expr) => {
299 drop(
300 $crate::entity::info::shows::ActiveModel {
301 id: Set(::flix_model::id::ShowId::from_raw($id)),
302 title: Set(::alloc::string::String::new()),
303 tagline: Set(::alloc::string::String::new()),
304 overview: Set(::alloc::string::String::new()),
305 date: Set(::chrono::NaiveDate::from_yo_opt(1, 1).expect("from_yo_opt")),
306 sort_title: Set(::alloc::string::String::new()),
307 fs_slug: Set(format!("S FS {}", $id)),
308 web_slug: Set(format!("S Web {}", $id)),
309 }
310 .insert($db)
311 .await
312 .expect("insert"),
313 );
314 };
315 }
316 pub(crate) use make_info_show;
317
318 macro_rules! make_info_season {
319 ($db:expr, $show:expr, $season:expr) => {
320 drop(
321 $crate::entity::info::seasons::ActiveModel {
322 show_id: Set(::flix_model::id::ShowId::from_raw($show)),
323 season_number: Set(::flix_model::numbers::SeasonNumber::new($season)),
324 title: Set(::alloc::string::String::new()),
325 overview: Set(::alloc::string::String::new()),
326 date: Set(::chrono::NaiveDate::from_yo_opt(1, 1).expect("from_yo_opt")),
327 }
328 .insert($db)
329 .await
330 .expect("insert"),
331 );
332 };
333 }
334 pub(crate) use make_info_season;
335
336 macro_rules! make_info_episode {
337 ($db:expr, $show:expr, $season:expr, $episode:expr) => {
338 drop(
339 $crate::entity::info::episodes::ActiveModel {
340 show_id: Set(::flix_model::id::ShowId::from_raw($show)),
341 season_number: Set(::flix_model::numbers::SeasonNumber::new($season)),
342 episode_number: Set(::flix_model::numbers::EpisodeNumber::new($episode)),
343 title: Set(::alloc::string::String::new()),
344 overview: Set(::alloc::string::String::new()),
345 date: Set(::chrono::NaiveDate::from_yo_opt(1, 1).expect("from_yo_opt")),
346 }
347 .insert($db)
348 .await
349 .expect("insert"),
350 );
351 };
352 }
353 pub(crate) use make_info_episode;
354}
355
356#[cfg(test)]
357mod tests {
358 use flix_model::id::{CollectionId, MovieId, ShowId};
359
360 use chrono::NaiveDate;
361 use sea_orm::ActiveValue::{NotSet, Set};
362 use sea_orm::entity::prelude::*;
363 use sea_orm::sqlx::error::ErrorKind;
364
365 use crate::tests::new_initialized_memory_db;
366
367 use super::super::tests::get_error_kind;
368 use super::super::tests::notsettable;
369 use super::test::{
370 make_info_collection, make_info_episode, make_info_movie, make_info_season, make_info_show,
371 };
372
373 #[cfg(not(miri))]
374 #[tokio::test]
375 #[expect(clippy::missing_panics_doc, reason = "unit test")]
376 #[expect(clippy::default_numeric_fallback, reason = "unit test")]
377 async fn use_test_macros() {
378 let db = new_initialized_memory_db().await;
379
380 make_info_collection!(&db, 1);
381 make_info_movie!(&db, 1);
382 make_info_show!(&db, 1);
383 make_info_season!(&db, 1, 1);
384 make_info_episode!(&db, 1, 1, 1);
385 }
386
387 #[cfg(not(miri))]
388 #[tokio::test]
389 #[expect(clippy::missing_panics_doc, reason = "unit test")]
390 async fn round_trip_collections() {
391 let db = new_initialized_memory_db().await;
392
393 macro_rules! assert_collection {
394 ($db:expr, $id:literal, Success $(; $($skip:ident),+)?) => {
395 let model = assert_collection!(@insert, $db, $id $(; $($skip),+)?)
396 .expect("insert");
397
398 assert_eq!(model.id, CollectionId::from_raw($id));
399 assert_eq!(model.title, concat!("C Title ", $id));
400 assert_eq!(model.overview, concat!("C Overview ", $id));
401 };
402 ($db:expr, $id:literal, $error:ident $(; $($skip:ident),+)?) => {
403 let model = assert_collection!(@insert, $db, $id $(; $($skip),+)?)
404 .expect_err("insert");
405
406 assert_eq!(get_error_kind(model).expect("get_error_kind"), ErrorKind::$error);
407 };
408 (@insert, $db:expr, $id:literal $(; $($skip:ident),+)?) => {
409 super::collections::ActiveModel {
410 id: notsettable!(id, CollectionId::from_raw($id) $(, $($skip),+)?),
411 title: notsettable!(title, concat!("C Title ", $id).to_string() $(, $($skip),+)?),
412 overview: notsettable!(overview, concat!("C Overview ", $id).to_string() $(, $($skip),+)?),
413 sort_title: notsettable!(sort_title, concat!("C Sort Title ", $id).to_string() $(, $($skip),+)?),
414 fs_slug: notsettable!(fs_slug, concat!("C FS Slug ", $id).to_string() $(, $($skip),+)?),
415 web_slug: notsettable!(web_slug, concat!("C Web Slug ", $id).to_string() $(, $($skip),+)?),
416 }.insert($db).await
417 };
418 }
419
420 assert_collection!(&db, 1, Success);
421 assert_collection!(&db, 1, UniqueViolation);
422 assert_collection!(&db, 2, Success);
423
424 assert_collection!(&db, 3, Success; id);
425 assert_collection!(&db, 4, NotNullViolation; title);
426 assert_collection!(&db, 5, NotNullViolation; overview);
427 assert_collection!(&db, 6, NotNullViolation; sort_title);
428 assert_collection!(&db, 7, NotNullViolation; fs_slug);
429 assert_collection!(&db, 8, NotNullViolation; web_slug);
430 }
431
432 #[cfg(not(miri))]
433 #[tokio::test]
434 #[expect(clippy::missing_panics_doc, reason = "unit test")]
435 async fn round_trip_movies() {
436 let db = new_initialized_memory_db().await;
437
438 macro_rules! assert_movie {
439 ($db:expr, $id:literal, Success $(; $($skip:ident),+)?) => {
440 let model = assert_movie!(@insert, $db, $id $(; $($skip),+)?)
441 .expect("insert");
442
443 assert_eq!(model.id, MovieId::from_raw($id));
444 assert_eq!(model.title, concat!("M Title ", $id));
445 assert_eq!(model.tagline, concat!("M Tagline ", $id));
446 assert_eq!(model.overview, concat!("M Overview ", $id));
447 assert_eq!(model.date, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt"));
448 };
449 ($db:expr, $id:literal, $error:ident $(; $($skip:ident),+)?) => {
450 let model = assert_movie!(@insert, $db, $id $(; $($skip),+)?)
451 .expect_err("insert");
452
453 assert_eq!(get_error_kind(model).expect("get_error_kind"), ErrorKind::$error);
454 };
455 (@insert, $db:expr, $id:literal $(; $($skip:ident),+)?) => {
456 super::movies::ActiveModel {
457 id: notsettable!(id, MovieId::from_raw($id) $(, $($skip),+)?),
458 title: notsettable!(title, concat!("M Title ", $id).to_string() $(, $($skip),+)?),
459 tagline: notsettable!(tagline, concat!("M Tagline ", $id).to_string() $(, $($skip),+)?),
460 overview: notsettable!(overview, concat!("M Overview ", $id).to_string() $(, $($skip),+)?),
461 date: notsettable!(date, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt") $(, $($skip),+)?),
462 sort_title: notsettable!(sort_title, concat!("M Sort Title ", $id).to_string() $(, $($skip),+)?),
463 fs_slug: notsettable!(fs_slug, concat!("M FS Slug ", $id).to_string() $(, $($skip),+)?),
464 web_slug: notsettable!(web_slug, concat!("M Web Slug ", $id).to_string() $(, $($skip),+)?),
465 }.insert($db).await
466 };
467 }
468
469 assert_movie!(&db, 1, Success);
470 assert_movie!(&db, 1, UniqueViolation);
471 assert_movie!(&db, 2, Success);
472
473 assert_movie!(&db, 3, Success; id);
474 assert_movie!(&db, 4, NotNullViolation; title);
475 assert_movie!(&db, 5, NotNullViolation; tagline);
476 assert_movie!(&db, 6, NotNullViolation; overview);
477 assert_movie!(&db, 7, NotNullViolation; date);
478 assert_movie!(&db, 8, NotNullViolation; sort_title);
479 assert_movie!(&db, 9, NotNullViolation; fs_slug);
480 assert_movie!(&db, 10, NotNullViolation; web_slug);
481 }
482
483 #[cfg(not(miri))]
484 #[tokio::test]
485 #[expect(clippy::missing_panics_doc, reason = "unit test")]
486 async fn round_trip_shows() {
487 let db = new_initialized_memory_db().await;
488
489 macro_rules! assert_show {
490 ($db:expr, $id:literal, Success $(; $($skip:ident),+)?) => {
491 let model = assert_show!(@insert, $db, $id $(; $($skip),+)?)
492 .expect("insert");
493
494 assert_eq!(model.id, ShowId::from_raw($id));
495 assert_eq!(model.title, concat!("S Title ", $id));
496 assert_eq!(model.tagline, concat!("S Tagline ", $id));
497 assert_eq!(model.overview, concat!("S Overview ", $id));
498 assert_eq!(model.date, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt"));
499 };
500 ($db:expr, $id:literal, $error:ident $(; $($skip:ident),+)?) => {
501 let model = assert_show!(@insert, $db, $id $(; $($skip),+)?)
502 .expect_err("insert");
503
504 assert_eq!(
505 get_error_kind(model).expect("get_error_kind"),
506 ErrorKind::$error
507 );
508 };
509 (@insert, $db:expr, $id:literal $(; $($skip:ident),+)?) => {
510 super::shows::ActiveModel {
511 id: notsettable!(id, ShowId::from_raw($id) $(, $($skip),+)?),
512 title: notsettable!(title, concat!("S Title ", $id).to_string() $(, $($skip),+)?),
513 tagline: notsettable!(tagline, concat!("S Tagline ", $id).to_string() $(, $($skip),+)?),
514 overview: notsettable!(overview, concat!("S Overview ", $id).to_string() $(, $($skip),+)?),
515 date: notsettable!(date, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt") $(, $($skip),+)?),
516 sort_title: notsettable!(sort_title, concat!("S Sort Title ", $id).to_string() $(, $($skip),+)?),
517 fs_slug: notsettable!(fs_slug, concat!("S FS Slug ", $id).to_string() $(, $($skip),+)?),
518 web_slug: notsettable!(web_slug, concat!("S Web Slug ", $id).to_string() $(, $($skip),+)?),
519 }.insert($db).await
520 };
521 }
522
523 assert_show!(&db, 1, Success);
524 assert_show!(&db, 1, UniqueViolation);
525 assert_show!(&db, 2, Success);
526
527 assert_show!(&db, 3, Success; id);
528 assert_show!(&db, 4, NotNullViolation; title);
529 assert_show!(&db, 5, NotNullViolation; tagline);
530 assert_show!(&db, 6, NotNullViolation; overview);
531 assert_show!(&db, 7, NotNullViolation; date);
532 assert_show!(&db, 8, NotNullViolation; sort_title);
533 assert_show!(&db, 9, NotNullViolation; fs_slug);
534 assert_show!(&db, 10, NotNullViolation; web_slug);
535 }
536
537 #[cfg(not(miri))]
538 #[tokio::test]
539 #[expect(clippy::missing_panics_doc, reason = "unit test")]
540 #[expect(clippy::default_numeric_fallback, reason = "unit test")]
541 async fn round_trip_seasons() {
542 let db = new_initialized_memory_db().await;
543
544 macro_rules! assert_season {
545 ($db:expr, $show:literal, $season:literal, Success $(; $($skip:ident),+)?) => {
546 let model = assert_season!(@insert, $db, $show, $season $(; $($skip),+)?)
547 .expect("insert");
548
549 assert_eq!(model.show_id, ShowId::from_raw($show));
550 assert_eq!(model.season_number, ::flix_model::numbers::SeasonNumber::new($season));
551 assert_eq!(model.title, concat!("SS Title ", $show, ",", $season));
552 assert_eq!(model.overview, concat!("SS Overview ", $show, ",", $season));
553 assert_eq!(model.date, NaiveDate::from_yo_opt($show + $season, 1).expect("from_yo_opt"));
554 };
555 ($db:expr, $show:literal, $season:literal, $error:ident $(; $($skip:ident),+)?) => {
556 let model = assert_season!(@insert, $db, $show, $season $(; $($skip),+)?)
557 .expect_err("insert");
558
559 assert_eq!(
560 get_error_kind(model).expect("get_error_kind"),
561 ErrorKind::$error
562 );
563 };
564 (@insert, $db:expr, $show:literal, $season:literal $(; $($skip:ident),+)?) => {
565 super::seasons::ActiveModel {
566 show_id: notsettable!(show_id, ShowId::from_raw($show) $(, $($skip),+)?),
567 season_number: notsettable!(season_number, ::flix_model::numbers::SeasonNumber::new($season) $(, $($skip),+)?),
568 title: notsettable!(title, concat!("SS Title ", $show, ",", $season).to_string() $(, $($skip),+)?),
569 overview: notsettable!(overview, concat!("SS Overview ", $show, ",", $season).to_string() $(, $($skip),+)?),
570 date: notsettable!(date, NaiveDate::from_yo_opt($show + $season, 1).expect("from_yo_opt") $(, $($skip),+)?),
571 }.insert($db).await
572 };
573 }
574
575 assert_season!(&db, 1, 1, ForeignKeyViolation);
576 make_info_show!(&db, 1);
577 make_info_show!(&db, 2);
578
579 assert_season!(&db, 1, 1, Success);
580 assert_season!(&db, 1, 1, UniqueViolation);
581 assert_season!(&db, 2, 1, Success);
582 assert_season!(&db, 1, 2, Success);
583
584 assert_season!(&db, 1, 3, NotNullViolation; show_id);
585 assert_season!(&db, 1, 4, NotNullViolation; season_number);
586 assert_season!(&db, 1, 5, NotNullViolation; title);
587 assert_season!(&db, 1, 6, NotNullViolation; overview);
588 assert_season!(&db, 1, 7, NotNullViolation; date);
589 }
590
591 #[cfg(not(miri))]
592 #[tokio::test]
593 #[expect(clippy::missing_panics_doc, reason = "unit test")]
594 #[expect(clippy::default_numeric_fallback, reason = "unit test")]
595 async fn round_trip_episodes() {
596 let db = new_initialized_memory_db().await;
597
598 macro_rules! assert_episode {
599 ($db:expr, $show:literal, $season:literal, $episode:literal, Success $(; $($skip:ident),+)?) => {
600 let model = assert_episode!(@insert, $db, $show, $season, $episode $(; $($skip),+)?)
601 .expect("insert");
602
603 assert_eq!(model.show_id, ShowId::from_raw($show));
604 assert_eq!(model.season_number, ::flix_model::numbers::SeasonNumber::new($season));
605 assert_eq!(model.episode_number, ::flix_model::numbers::EpisodeNumber::new($episode));
606 assert_eq!(model.title, concat!("SSE Title ", $show, ",", $season, ",", $episode));
607 assert_eq!(model.overview, concat!("SSE Overview ", $show, ",", $season, ",", $episode));
608 assert_eq!(model.date, NaiveDate::from_yo_opt($show + $season, 1).expect("from_yo_opt"));
609 };
610 ($db:expr, $show:literal, $season:literal, $episode:literal, $error:ident $(; $($skip:ident),+)?) => {
611 let model = assert_episode!(@insert, $db, $show, $season, $episode $(; $($skip),+)?)
612 .expect_err("insert");
613
614 assert_eq!(
615 get_error_kind(model).expect("get_error_kind"),
616 ErrorKind::$error
617 );
618 };
619 (@insert, $db:expr, $show:literal, $season:literal, $episode:literal $(; $($skip:ident),+)?) => {
620 super::episodes::ActiveModel {
621 show_id: notsettable!(show_id, ShowId::from_raw($show) $(, $($skip),+)?),
622 season_number: notsettable!(season_number, ::flix_model::numbers::SeasonNumber::new($season) $(, $($skip),+)?),
623 episode_number: notsettable!(episode_number, ::flix_model::numbers::EpisodeNumber::new($episode) $(, $($skip),+)?),
624 title: notsettable!(title, concat!("SSE Title ", $show, ",", $season, ",", $episode).to_string() $(, $($skip),+)?),
625 overview: notsettable!(overview, concat!("SSE Overview ", $show, ",", $season, ",", $episode).to_string() $(, $($skip),+)?),
626 date: notsettable!(date, NaiveDate::from_yo_opt($show + $season, 1).expect("from_yo_opt") $(, $($skip),+)?),
627 }.insert($db).await
628 };
629 }
630
631 assert_episode!(&db, 1, 1, 1, ForeignKeyViolation);
632 make_info_show!(&db, 1);
633 make_info_show!(&db, 2);
634 assert_episode!(&db, 1, 1, 1, ForeignKeyViolation);
635 make_info_season!(&db, 1, 1);
636 make_info_season!(&db, 1, 2);
637 make_info_season!(&db, 2, 1);
638
639 assert_episode!(&db, 1, 1, 1, Success);
640 assert_episode!(&db, 1, 1, 1, UniqueViolation);
641 assert_episode!(&db, 2, 1, 1, Success);
642 assert_episode!(&db, 1, 2, 1, Success);
643 assert_episode!(&db, 1, 1, 2, Success);
644
645 assert_episode!(&db, 1, 1, 3, NotNullViolation; show_id);
646 assert_episode!(&db, 1, 1, 4, NotNullViolation; season_number);
647 assert_episode!(&db, 1, 1, 4, NotNullViolation; episode_number);
648 assert_episode!(&db, 1, 1, 5, NotNullViolation; title);
649 assert_episode!(&db, 1, 1, 6, NotNullViolation; overview);
650 assert_episode!(&db, 1, 1, 7, NotNullViolation; date);
651 }
652}