"""Deleting a question hides it; restoring it puts back the same question. The point of the whole arrangement is the id. Ids come from a sequence and are never reissued, and fourteen tables point at this one — attempts, quiz membership, exam membership, media, notes, favourites, feedback. Erasing the row takes all of that with it, so a "restore" that re-inserted the text would be a different question wearing the same words. """ import unittest import test_quiz_builder as fixtures from app.models.question import Question class QuestionTrashTests(unittest.TestCase): def setUp(self): self.bank = fixtures.BuilderTests() self.bank.setUp() self.client = self.bank.client self.bank.user = self.bank.mod def tearDown(self): self.bank.tearDown() def row(self, question_id): self.bank.db.expire_all() return self.bank.db.get(Question, question_id) def test_delete_hides_the_question_but_keeps_the_row(self): self.assertEqual(self.client.delete("/questions/1").status_code, 204) kept = self.row(1) self.assertIsNotNone(kept, "the row must survive or nothing can point at it") self.assertIsNotNone(kept.deleted_at) def test_a_deleted_question_leaves_the_bank_and_the_builder(self): before = self.client.get("/questions/bank").json() before_ids = [q["id"] for q in before["questions"]] self.assertIn(1, before_ids) self.client.delete("/questions/1") after = self.client.get("/questions/bank").json() self.assertNotIn(1, [q["id"] for q in after["questions"]]) # Excluded in the shared predicate, so the builder's count moves too # rather than each caller having to remember. self.assertEqual(self.client.get("/questions/builder/count", params={"state": "all"}).json()["count"], len(before_ids) - 1) def test_the_trash_lists_it_and_restore_brings_back_the_same_id(self): self.client.delete("/questions/1") trash = self.client.get("/questions/trash").json() self.assertEqual([row["id"] for row in trash], [1]) self.assertEqual(self.client.patch("/questions/1/restore").status_code, 200) self.assertIsNone(self.row(1).deleted_at) self.assertIn(1, [q["id"] for q in self.client.get("/questions/bank").json()["questions"]]) self.assertEqual(self.client.get("/questions/trash").json(), []) def test_restoring_something_that_is_not_deleted_is_refused(self): self.assertEqual(self.client.patch("/questions/1/restore").status_code, 400) def test_erasing_requires_the_trash_first(self): # Straight to permanent would make the trash a formality. self.assertEqual(self.client.delete("/questions/1/permanent").status_code, 400) self.client.delete("/questions/1") self.assertEqual(self.client.delete("/questions/1/permanent").status_code, 204) self.assertIsNone(self.row(1)) if __name__ == "__main__": unittest.main()