def test_to_json_and_back(mock_client):
    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, mock_client)
    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, mock_client)

        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_str == "query":
            assert list_subs[0].destination == 1234
            assert list_subs[1].query_str == "example"
            assert list_subs[1].destination == 5678
        else:
            assert list_subs[0].query_str == "example"
            assert list_subs[0].destination == 5678
            assert list_subs[1].query_str == "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(mock_client):
    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, mock_client)
    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["destinations"]) == 4
        assert len(data["destinations"]["1234"]["subscriptions"]) == 1
        assert data["destinations"]["1234"]["subscriptions"][0][
            "query"] == "query"
        assert len(data["destinations"]["1234"]["blocks"]) == 0

        assert len(data["destinations"]["5678"]["subscriptions"]) == 1
        assert data["destinations"]["5678"]["subscriptions"][0][
            "query"] == "example"
        assert len(data["destinations"]["5678"]["blocks"]) == 0

        assert len(data["destinations"]["3452"]["subscriptions"]) == 0
        assert len(data["destinations"]["3452"]["blocks"]) == 2
        assert set([
            block["query"] for block in data["destinations"]["3452"]["blocks"]
        ]) == {"test", "example"}

        assert len(data["destinations"]["1453"]["subscriptions"]) == 0
        assert len(data["destinations"]["1453"]["blocks"]) == 1
        assert data["destinations"]["1453"]["blocks"][0]["query"] == "ych"
    finally:
        os.remove(test_watcher_file)
def test_update_latest_ids(mock_client):
    api = MockExportAPI()
    watcher = SubscriptionWatcher(api, mock_client)
    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
async def test_run__calls_update_latest_ids(mock_client):
    submission1 = MockSubmission("12322")
    submission2 = MockSubmission("12324")
    api = MockExportAPI().with_submissions([submission1, submission2])
    watcher = SubscriptionWatcher(api, mock_client)
    mock_new_results = MockMethod([submission1, submission2])
    watcher._get_new_results = mock_new_results.async_call
    mock_update_latest = MockMethod()
    watcher._update_latest_ids = mock_update_latest.call
    # Shorten the wait
    watcher.BACK_OFF = 1

    task = asyncio.get_event_loop().create_task(watcher_killer(watcher))
    # Run watcher
    await watcher.run()
    await task

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