Detailed changes
@@ -1220,6 +1220,13 @@ impl Database {
self.check_user_is_channel_admin(&new_parent, admin_id, &*tx)
.await?;
+ if new_parent
+ .ancestors_including_self()
+ .any(|id| id == channel.id)
+ {
+ Err(anyhow!("cannot move a channel into one of its descendants"))?;
+ }
+
new_parent_path = new_parent.path();
new_parent_channel = Some(new_parent);
} else {
@@ -450,6 +450,20 @@ async fn test_db_channel_moving_bugs(db: &Arc<Database>) {
(livestreaming_id, &[projects_id]),
],
);
+
+ // Can't move a channel into its ancestor
+ db.move_channel(projects_id, Some(livestreaming_id), user_id)
+ .await
+ .unwrap_err();
+ let result = db.get_channels_for_user(user_id).await.unwrap();
+ assert_channel_tree(
+ result.channels,
+ &[
+ (zed_id, &[]),
+ (projects_id, &[]),
+ (livestreaming_id, &[projects_id]),
+ ],
+ );
}
test_both_dbs!(
@@ -1220,6 +1220,13 @@ impl Database {
self.check_user_is_channel_admin(&new_parent, admin_id, &*tx)
.await?;
+ if new_parent
+ .ancestors_including_self()
+ .any(|id| id == channel.id)
+ {
+ Err(anyhow!("cannot move a channel into one of its descendants"))?;
+ }
+
new_parent_path = new_parent.path();
new_parent_channel = Some(new_parent);
} else {
@@ -420,8 +420,6 @@ async fn test_db_channel_moving_bugs(db: &Arc<Database>) {
.await
.unwrap();
- // Dag is: zed - projects - livestreaming
-
// Move to same parent should be a no-op
assert!(db
.move_channel(projects_id, Some(zed_id), user_id)
@@ -450,6 +448,20 @@ async fn test_db_channel_moving_bugs(db: &Arc<Database>) {
(livestreaming_id, &[projects_id]),
],
);
+
+ // Can't move a channel into its ancestor
+ db.move_channel(projects_id, Some(livestreaming_id), user_id)
+ .await
+ .unwrap_err();
+ let result = db.get_channels_for_user(user_id).await.unwrap();
+ assert_channel_tree(
+ result.channels,
+ &[
+ (zed_id, &[]),
+ (projects_id, &[]),
+ (livestreaming_id, &[projects_id]),
+ ],
+ );
}
test_both_dbs!(