Count only subscribers' read marks and pins when freeing disk space (#156)
The reaper counted read marks and pins in entry_state from anyone and compared them with the feed's subscribers. Unsubscribing leaves your rows behind, and the flags endpoint writes them for feeds you do not subscribe to as well. So an episode read by someone who had left and by one subscriber of two counted as heard by everyone, and went first under the quota though the other had not played it; and a pin of a person who had left kept a file, and its item, for good, which can leave the quota impossible to meet. Both queries, the reaper's candidates and prune_entries, now count only the marks of people who subscribe to the item's feed. The old prune test's pin had no subscriber behind it; it has one now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -189,11 +189,36 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn the_marks_of_someone_who_left_count_for_nothing() {
|
||||
// ray and sam subscribe; left read one episode and pinned the others before unsubscribing.
|
||||
let db = Db::memory().await.unwrap();
|
||||
db.exec_for_test(
|
||||
"INSERT INTO users (id, name, is_admin) VALUES (1,'ray',true),(2,'sam',false),(3,'left',false);
|
||||
INSERT INTO subscriptions (user_id, feed_id) VALUES (1,'f'),(2,'f');
|
||||
INSERT INTO entries (feed_id, guid, first_seen) VALUES
|
||||
('f', 'heard', 0), ('f', 'pinned', 0), ('f', 'old', 0);
|
||||
INSERT INTO entry_state (user_id, feed_id, guid, read, flagged) VALUES
|
||||
(3, 'f', 'heard', true, false),
|
||||
(1, 'f', 'heard', true, false),
|
||||
(3, 'f', 'pinned', false, true),
|
||||
(3, 'f', 'old', false, true);
|
||||
INSERT INTO enclosures (id, feed_id, guid, url, path, bytes_done, state, downloaded_at) VALUES
|
||||
(1, 'f', 'heard', 'u1', '/tmp/heard', 10, 'done', 10),
|
||||
(2, 'f', 'pinned', 'u2', '/tmp/pinned', 10, 'done', 20);",
|
||||
).await
|
||||
.unwrap();
|
||||
let got: Vec<(i64, bool)> = db.reap_candidates().await.unwrap().iter().map(|c| (c.id, c.read)).collect();
|
||||
assert_eq!(got, vec![(1, false), (2, false)], "sam has not heard it, and nobody here pinned it (#156)");
|
||||
assert_eq!(db.prune_entries(500).await.unwrap(), 1, "the old item goes, a leaver's pin or not");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn prune_keeps_entries_that_still_have_a_file() {
|
||||
let db = Db::memory().await.unwrap();
|
||||
db.exec_for_test(
|
||||
"INSERT INTO users (id, name, is_admin) VALUES (1,'ray',true);
|
||||
INSERT INTO subscriptions (user_id, feed_id) VALUES (1,'f');
|
||||
INSERT INTO entry_state (user_id, feed_id, guid, flagged) VALUES (1,'f','flagged',true);
|
||||
INSERT INTO entries (feed_id, guid, first_seen) VALUES
|
||||
('f', 'has-file', 100),
|
||||
|
||||
Reference in New Issue
Block a user