def test_to_json_and_back(self, bot):
        test_watcher_file = "./test_subscription_watcher.json"
        if os.path.exists(test_watcher_file):
            os.remove(test_watcher_file)
        old_filename = SubscriptionWatcher.FILENAME
        SubscriptionWatcher.FILENAME = test_watcher_file
        api = MockExportAPI()
        latest_submissions = [
            SubmissionBuilder(submission_id="123243").build_short_submission(),
            SubmissionBuilder(submission_id="123242").build_short_submission(),
            SubmissionBuilder(submission_id="123240").build_short_submission()
        ]
        subscription1 = Subscription("query", 1234)
        subscription2 = Subscription("example", 5678)
        watcher = SubscriptionWatcher(api, bot)
        watcher._update_latest_ids(latest_submissions)
        watcher.subscriptions.add(subscription1)
        watcher.subscriptions.add(subscription2)
        watcher.blocklists[3452] = {"test", "example"}
        watcher.blocklists[1453] = {"ych"}

        try:
            watcher.save_to_json()
            new_watcher = SubscriptionWatcher.load_from_json(api, bot)

            assert len(new_watcher.latest_ids) == 3
            assert "123243" in new_watcher.latest_ids
            assert "123242" in new_watcher.latest_ids
            assert "123240" in new_watcher.latest_ids
            assert list(watcher.latest_ids) == list(new_watcher.latest_ids)
            assert len(new_watcher.subscriptions) == 2
            list_subs = list(new_watcher.subscriptions)
            if list_subs[0].query == "query":
                assert list_subs[0].destination == 1234
                assert list_subs[1].query == "example"
                assert list_subs[1].destination == 5678
            else:
                assert list_subs[0].query == "example"
                assert list_subs[0].destination == 5678
                assert list_subs[1].query == "query"
                assert list_subs[1].destination == 1234
            assert len(new_watcher.blocklists) == 2
            assert 3452 in new_watcher.blocklists
            assert len(new_watcher.blocklists[3452]) == 2
            assert isinstance(new_watcher.blocklists[3452], set)
            assert "test" in new_watcher.blocklists[3452]
            assert "example" in new_watcher.blocklists[3452]
            assert 1453 in new_watcher.blocklists
            assert len(new_watcher.blocklists[1453]) == 1
            assert isinstance(new_watcher.blocklists[1453], set)
            assert "ych" in new_watcher.blocklists[1453]
        finally:
            SubscriptionWatcher.FILENAME = old_filename
            os.remove(test_watcher_file)
    def test_save_to_json(self, bot):
        test_watcher_file = "./test_subscription_watcher.json"
        if os.path.exists(test_watcher_file):
            os.remove(test_watcher_file)
        api = MockExportAPI()
        latest_submissions = [
            SubmissionBuilder(submission_id="123243").build_short_submission(),
            SubmissionBuilder(submission_id="123242").build_short_submission(),
            SubmissionBuilder(submission_id="123240").build_short_submission()
        ]
        subscription1 = Subscription("query", 1234)
        subscription2 = Subscription("example", 5678)
        watcher = SubscriptionWatcher(api, bot)
        watcher._update_latest_ids(latest_submissions)
        watcher.subscriptions.add(subscription1)
        watcher.subscriptions.add(subscription2)
        watcher.blocklists[3452] = {"test", "example"}
        watcher.blocklists[1453] = {"ych"}
        watcher.FILENAME = test_watcher_file

        try:
            watcher.save_to_json()

            assert os.path.exists(test_watcher_file)
            with open(test_watcher_file, "r") as f:
                data = json.load(f)
            assert data is not None
            assert len(data['latest_ids']) == 3
            assert "123240" in data['latest_ids']
            assert "123242" in data['latest_ids']
            assert "123243" in data['latest_ids']
            assert len(data['subscriptions']) == 2
            if data['subscriptions'][0]['query'] == "query":
                assert data['subscriptions'][0]['destination'] == 1234
                assert data['subscriptions'][1]['query'] == "example"
                assert data['subscriptions'][1]['destination'] == 5678
            else:
                assert data['subscriptions'][0]['query'] == "example"
                assert data['subscriptions'][0]['destination'] == 5678
                assert data['subscriptions'][1]['query'] == "query"
                assert data['subscriptions'][1]['destination'] == 1234
            assert len(data["blacklists"]) == 2
            assert "3452" in data["blacklists"]
            assert len(data["blacklists"]["3452"]) == 2
            assert isinstance(data["blacklists"]["3452"], list)
            assert "test" in data["blacklists"]["3452"]
            assert "example" in data["blacklists"]["3452"]
            assert "1453" in data["blacklists"]
            assert len(data["blacklists"]["1453"]) == 1
            assert isinstance(data["blacklists"]["1453"], list)
            assert data["blacklists"]["1453"] == ["ych"]
        finally:
            os.remove(test_watcher_file)
    def test_update_latest_ids(self, bot):
        api = MockExportAPI()
        watcher = SubscriptionWatcher(api, bot)
        id_list = ["1234", "1233", "1230", "1229"]
        submissions = [MockSubmission(x) for x in id_list]
        mock_save_json = MockMethod()
        watcher.save_to_json = mock_save_json.call

        watcher._update_latest_ids(submissions)

        assert list(watcher.latest_ids) == id_list
        assert mock_save_json.called
    def test_run__calls_update_latest_ids(self, bot):
        submission1 = MockSubmission("12322")
        submission2 = MockSubmission("12324")
        api = MockExportAPI().with_submissions([submission1, submission2])
        watcher = SubscriptionWatcher(api, bot)
        mock_new_results = MockMethod([submission1, submission2])
        watcher._get_new_results = mock_new_results.call
        mock_update_latest = MockMethod()
        watcher._update_latest_ids = mock_update_latest.call
        # Shorten the wait
        watcher.BACK_OFF = 1

        thread = Thread(target=lambda: self.watcher_killer(watcher))
        thread.start()
        # Run watcher
        watcher.run()
        thread.join()

        assert mock_update_latest.called
        assert mock_update_latest.args[0] == [submission2]