"""Resource Tests"""
import copy
import json
import os
from datetime import datetime, timezone
from os import remove
from os.path import basename, join

import pytest
from hdx.utilities.dictandlist import merge_two_dictionaries
from hdx.utilities.downloader import DownloadError

from hdx.api.configuration import Configuration
from hdx.data.hdxobject import HDXError
from hdx.data.resource import Resource

from . import MockResponse, dataset_resultdict
from .test_resource_view import resource_view_list, resource_view_mocklist

resultdict = {
    "cache_last_updated": None,
    "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
    "webstore_last_updated": None,
    "datastore_active": None,
    "id": "de6549d8-268b-4dfe-adaf-a4ae5c8510d5",
    "size": None,
    "hash": "",
    "description": "My Resource",
    "format": "csv",
    "last_modified": None,
    "url_type": "api",
    "mimetype": None,
    "cache_url": None,
    "name": "MyResource1",
    "created": "2016-06-07T08:57:27.367939",
    "url": "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-api/master/tests/fixtures/test_data.csv",
    "webstore_url": None,
    "mimetype_inner": None,
    "position": 0,
    "revision_id": "43765383-1fce-471f-8166-d6c8660cc8a9",
    "resource_type": "api",
}

searchdict = {
    "count": 4,
    "results": [
        {
            "size": None,
            "description": "ACLED-All-Africa-File_20160101-to-20160903.xlsx",
            "revision_id": "796b639e-f217-4d0e-bedd-4e3b35da4461",
            "cache_last_updated": None,
            "created": "2016-06-22T12:41:02.857171",
            "name": "ACLED-All-Africa-File_20160101-to-date.xlsx",
            "last_modified": None,
            "url_type": "api",
            "format": "XLSX",
            "cache_url": None,
            "url": "http://www.acleddata.com/wp-content/uploads/2016/09/ACLED.slxs",
            "state": "active",
            "position": 0,
            "revision_last_updated": "2016-06-28T14:17:27.150541",
            "webstore_last_updated": None,
            "mimetype": None,
            "package_id": "45f53bde-544c-4a4a-9c6f-d609481b8719",
            "resource_type": "api",
            "id": "d6d1c367-1980-4dc7-ab20-c23f02d3b9e7",
            "mimetype_inner": None,
            "hash": "",
            "webstore_url": None,
        },
        {
            "size": None,
            "description": "",
            "revision_id": "5259be68-e72f-4c02-be8e-61d7cd594a9b",
            "cache_last_updated": None,
            "created": "2016-03-23T14:17:02.272572",
            "name": "ACLED-Version-6-All-Africa-1997-2015_csv_dyadic.zip",
            "last_modified": None,
            "url_type": "api",
            "format": "ZIP",
            "cache_url": None,
            "url": "http://www.acleddata.com/wp-content/uploads/2016/01/ACLED.zip",
            "state": "active",
            "position": 0,
            "webstore_last_updated": None,
            "mimetype": None,
            "package_id": "71d852e4-e41e-4320-a770-9fc2bb87fb64",
            "resource_type": "api",
            "id": "866b3b60-5b2a-4ca3-9b76-665870cc6d71",
            "mimetype_inner": None,
            "webstore_url": None,
            "hash": "",
            "originalHash": "97196323",
        },
        {
            "size": None,
            "description": "ACLED-All-Africa-File_20160101-to-20160903_csv.zip",
            "revision_id": "796b639e-f217-4d0e-bedd-4e3b35da4461",
            "cache_last_updated": None,
            "created": "2016-06-22T12:41:02.857194",
            "name": "ACLED-All-Africa-File_20160101-to-date_csv.zip",
            "last_modified": None,
            "url_type": "api",
            "format": "zipped csv",
            "cache_url": None,
            "url": "http://www.acleddata.com/wp-content/uploads/2016/09/ACLED.zip",
            "state": "active",
            "position": 1,
            "revision_last_updated": "2016-06-28T14:17:27.150541",
            "webstore_last_updated": None,
            "mimetype": None,
            "package_id": "45f53bde-544c-4a4a-9c6f-d609481b8719",
            "resource_type": "api",
            "id": "74b74ae1-df0c-4716-829f-4f939a046811",
            "mimetype_inner": None,
            "hash": "",
            "webstore_url": None,
        },
        {
            "size": None,
            "description": "",
            "revision_id": "5259be68-e72f-4c02-be8e-61d7cd594a9b",
            "cache_last_updated": None,
            "created": "2016-03-23T14:17:08.594232",
            "name": "ACLED-Version-6-All-Africa-1997-2015_dyadic-file.xlsx",
            "last_modified": None,
            "url_type": "api",
            "format": "XLSX",
            "cache_url": None,
            "url": "http://www.acleddata.com/wp-content/uploads/2016/01/ACLEDxlsx",
            "state": "active",
            "position": 1,
            "webstore_last_updated": None,
            "mimetype": None,
            "package_id": "71d852e4-e41e-4320-a770-9fc2bb87fb64",
            "resource_type": "api",
            "id": "e1e16f5c-2380-4a28-87b1-f5d644f248e5",
            "mimetype_inner": None,
            "webstore_url": None,
            "hash": "",
            "originalHash": "97196323",
        },
    ],
}


def mockshow(url, datadict):
    if "show" not in url:
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "TEST ERROR: Not show", "__type": "TEST ERROR: Not Show Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}',
        )
    result = json.dumps(resultdict)
    if datadict["id"] == "74b74ae1-df0c-4716-829f-4f939a046811":
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}'
            % result,
        )
    if datadict["id"] == "74b74ae1-df0c-4716-829f-4f939a046812":
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}',
        )
    if datadict["id"] == "74b74ae1-df0c-4716-829f-4f939a046813":
        return MockResponse(
            200,
            '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}',
        )
    if datadict["id"] == "74b74ae1-df0c-4716-829f-4f939a046814":
        resdictcopy = copy.deepcopy(resultdict)
        resdictcopy["url"] = "lalalala"
        result = json.dumps(resdictcopy)
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}'
            % result,
        )
    if datadict["id"] == "74b74ae1-df0c-4716-829f-4f939a046815":
        resdictcopy = copy.deepcopy(resultdict)
        resdictcopy["id"] = "datastore_unknown_resource"
        result = json.dumps(resdictcopy)
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}'
            % result,
        )
    return MockResponse(
        404,
        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_show"}',
    )


def mockpatch(url, datadict):
    if "patch" not in url:
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "TEST ERROR: Not patch", "__type": "TEST ERROR: Not Patch Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_patch"}',
        )
    result = json.dumps(resultdict)
    return MockResponse(
        200,
        '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_patch"}'
        % result,
    )


def mockdataset(url, datadict):
    if "show" not in url:
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "TEST ERROR: Not show", "__type": "TEST ERROR: Not Show Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=package_show"}',
        )
    result = json.dumps(dataset_resultdict)
    return MockResponse(
        200,
        '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=package_show"}'
        % result,
    )


def mocksearch(url, datadict):
    if "search" not in url:
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "TEST ERROR: Not search", "__type": "TEST ERROR: Not Search Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_search"}',
        )
    result = json.dumps(searchdict)
    if datadict["query"] == "name:ACLED":
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_search"}'
            % result,
        )
    if datadict["query"] == "fail":
        return MockResponse(
            404,
            '{"success": false, "error": {"message": "Validation Error", "__type": "Validation Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_search"}',
        )
    if datadict["query"] == "name:ajyhgr":
        return MockResponse(
            200,
            '{"success": true, "result": {"count": 0, "results": []}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_search"}',
        )
    return MockResponse(
        404,
        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_search"}',
    )


def mockresourceview(url, decodedata):
    if "delete" in url:
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_delete"}'
            % decodedata,
        )
    datadict = json.loads(decodedata)
    if "show" in url:
        if id not in datadict:
            return MockResponse(
                404,
                '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_show"}',
            )
        if datadict["title"] == "Data Explorer":
            result = json.dumps(resource_view_list[0])
            return MockResponse(
                200,
                '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_show"}'
                % result,
            )
        if datadict["title"] == "Quick Charts":
            result = json.dumps(resource_view_list[1])
            return MockResponse(
                200,
                '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_show"}'
                % result,
            )
    if "list" in url:
        return resource_view_mocklist(url, datadict)

    if "create" in url or "update" in url:
        if datadict["title"] == "Data Explorer":
            result = json.dumps(resource_view_list[0])
            return MockResponse(
                200,
                '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_create"}'
                % result,
            )
        if datadict["title"] == "Quick Charts":
            result = json.dumps(resource_view_list[1])
            return MockResponse(
                200,
                '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_show"}'
                % result,
            )
    if "reorder" in url:
        result = json.dumps(
            {
                "id": "25982d1c-f45a-45e1-b14e-87d367413045",
                "order": [
                    "c06b5a0d-1d41-4a74-a196-41c251c76023",
                    "d80301b5-4abd-49bd-bf94-fa4af7b6e7a4",
                ],
            }
        )
        return MockResponse(
            200,
            '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_reorder"}'
            % result,
        )

    return MockResponse(
        404,
        '{"success": false, "error": {"message": "TEST ERROR: Not show", "__type": "TEST ERROR: Not Show Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_view_show"}',
    )


class TestResource:
    resource_data = {
        "name": "MyResource1",
        "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
        "format": "xlsx",
        "url": "http://test/spreadsheet.xlsx",
        "description": "My Resource",
        "api_type": "api",
        "resource_type": "api",
    }

    datastore = None

    @pytest.fixture(scope="class")
    def static_yaml(self):
        return join("tests", "fixtures", "config", "hdx_resource_static.yml")

    @pytest.fixture(scope="class")
    def static_json(self):
        return join("tests", "fixtures", "config", "hdx_resource_static.json")

    @pytest.fixture(scope="class")
    def topline_yaml(self):
        return join(
            "tests", "fixtures", "config", "hdx_datasource_topline.yml"
        )

    @pytest.fixture(scope="class")
    def topline_json(self):
        return join(
            "tests", "fixtures", "config", "hdx_datasource_topline.json"
        )

    @pytest.fixture(scope="function")
    def read(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                datadict = json.loads(data.decode("utf-8"))
                return mockshow(url, datadict)

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_create(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                if isinstance(data, dict):
                    datadict = {
                        k.decode("utf8"): v.decode("utf8")
                        for k, v in data.items()
                    }
                else:
                    datadict = json.loads(data.decode("utf-8"))
                if "show" in url:
                    return mockshow(url, datadict)
                if "resource_id" in datadict:
                    if (
                        datadict["resource_id"]
                        == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
                    ):
                        return MockResponse(
                            200,
                            '{"success": true, "result": {"fields": [{"type": "text", "id": "code"}, {"type": "text", "id": "title"}, {"type": "float", "id": "value"}, {"type": "timestamp", "id": "latest_date"}, {"type": "text", "id": "source"}, {"type": "text", "id": "source_link"}, {"type": "text", "id": "notes"}, {"type": "text", "id": "explore"}, {"type": "text", "id": "units"}], "method": "insert", "primary_key": "code", "resource_id": "bfa6b55f-10b6-4ba2-8470-33bb9a5194a5"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_create"}',
                        )
                if "create" not in url:
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "TEST ERROR: Not create", "__type": "TEST ERROR: Not Create Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_create"}',
                    )
                if datadict["name"] == "MyResource1":
                    resultdictcopy = copy.deepcopy(resultdict)
                    if files:
                        resultdictcopy["url_type"] = "upload"
                        resultdictcopy["resource_type"] = "file.upload"
                        filename = os.path.basename(files["upload"].name)
                        resultdictcopy[
                            "url"
                        ] = f"http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/{filename}"
                    resultdictcopy["state"] = datadict["state"]

                    result = json.dumps(resultdictcopy)
                    return MockResponse(
                        200,
                        '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_create"}'
                        % result,
                    )
                if datadict["name"] == "MyResource2":
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_create"}',
                    )
                if datadict["name"] == "MyResource3":
                    return MockResponse(
                        200,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_create"}',
                    )
                return MockResponse(
                    404,
                    '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_create"}',
                )

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_update(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                if isinstance(data, dict):
                    datadict = {
                        k.decode("utf8"): v.decode("utf8")
                        for k, v in data.items()
                    }
                else:
                    datadict = json.loads(data.decode("utf-8"))
                if "show" in url:
                    return mockshow(url, datadict)
                if "resource_id" in datadict:
                    if (
                        datadict["resource_id"]
                        == "74b74ae1-df0c-4716-829f-4f939a046811"
                    ):
                        return MockResponse(
                            200,
                            '{"success": true, "result": {"fields": [{"type": "text", "id": "code"}, {"type": "text", "id": "title"}, {"type": "float", "id": "value"}, {"type": "timestamp", "id": "latest_date"}, {"type": "text", "id": "source"}, {"type": "text", "id": "source_link"}, {"type": "text", "id": "notes"}, {"type": "text", "id": "explore"}, {"type": "text", "id": "units"}], "method": "insert", "primary_key": "code", "resource_id": "bfa6b55f-10b6-4ba2-8470-33bb9a5194a5"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_create"}',
                        )
                if "update" not in url:
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "TEST ERROR: Not update", "__type": "TEST ERROR: Not Update Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_update"}',
                    )
                if datadict["name"] == "MyResource1":
                    resultdictcopy = copy.deepcopy(resultdict)
                    merge_two_dictionaries(resultdictcopy, datadict)
                    if files:
                        resultdictcopy["url_type"] = "upload"
                        resultdictcopy["resource_type"] = "file.upload"
                        filename = os.path.basename(files["upload"].name)
                        resultdictcopy[
                            "url"
                        ] = f"http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/{filename}"
                    result = json.dumps(resultdictcopy)
                    return MockResponse(
                        200,
                        '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_update"}'
                        % result,
                    )
                if datadict["name"] == "MyResource2":
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_update"}',
                    )
                if datadict["name"] == "MyResource3":
                    return MockResponse(
                        200,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_update"}',
                    )

                return MockResponse(
                    404,
                    '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_update"}',
                )

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_delete(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                decodedata = data.decode("utf-8")
                datadict = json.loads(decodedata)
                if "show" in url:
                    return mockshow(url, datadict)
                if "delete" not in url:
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "TEST ERROR: Not delete", "__type": "TEST ERROR: Not Delete Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_delete"}',
                    )
                if datadict["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5":
                    return MockResponse(
                        200,
                        '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_delete"}'
                        % decodedata,
                    )

                return MockResponse(
                    404,
                    '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_delete"}',
                )

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_datastore(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                decodedata = data.decode("utf-8")
                datadict = json.loads(decodedata)
                if "show" in url:
                    return mockshow(url, datadict)
                if (
                    "create" not in url
                    and "insert" not in url
                    and "upsert" not in url
                    and "delete" not in url
                    and "search" not in url
                ):
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "TEST ERROR: Not create or delete", "__type": "TEST ERROR: Not Create or Delete Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_action"}',
                    )
                if (
                    "delete" in url
                    and datadict["resource_id"] == "datastore_unknown_resource"
                ):
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_delete"}',
                    )
                if (
                    "delete" in url
                    and datadict["resource_id"]
                    == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
                ):
                    TestResource.datastore = "delete"
                    return MockResponse(
                        200,
                        '{"success": true, "result": {"resource_id": "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_delete"}',
                    )
                if (
                    "create" in url
                    and datadict["resource_id"] == "datastore_unknown_resource"
                ):
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_create"}',
                    )
                if (
                    "search" in url
                    and datadict["resource_id"] == "datastore_unknown_resource"
                ):
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_create"}',
                    )
                if (
                    "search" in url
                    and datadict["resource_id"] == "_table_metadata"
                ):
                    return MockResponse(
                        200,
                        '{"success": true, "result": {"include_total": true, "resource_id": "_table_metadata", "fields": [{"type": "int", "id": "_id"}, {"type": "name", "id": "name"}, {"type": "oid", "id": "oid"}, {"type": "name", "id": "alias_of"}], "records_format": "objects", "records": [{"_id":"f9cd60f3d7f2f6d0","name":"f9228459-d808-4b51-948f-68a5850abfde","oid":"919290","alias_of":null},{"_id":"7ae63490de9b7d7b","name":"af618a0b-09b8-42c8-836f-2be597e1ea34","oid":"135294","alias_of":null},{"_id":"1dc37f4e89988644","name":"748b40dd-7bd3-40a3-941b-e76f0bfbe0eb","oid":"117144","alias_of":null},{"_id":"2a554a61bd366206","name":"91c78d24-eab3-40b5-ba91-6b29bcda7178","oid":"116963","alias_of":null},{"_id":"fd787575143afe90","name":"9320cfce-4620-489a-bcbe-25c73867d4fc","oid":"107430","alias_of":null},{"_id":"a70093abd230f647","name":"b9d2eb36-e65c-417a-bc28-f4dadb149302","oid":"107409","alias_of":null},{"_id":"95fbdd2d06c07aea","name":"ca6a0891-8395-4d58-9168-6c44e17e0193","oid":"107385","alias_of":null}], "limit": 10000, "_links": {"start": "/api/action/datastore_search?limit=10000&resource_id=_table_metadata", "next": "/api/action/datastore_search?offset=10000&limit=10000&resource_id=_table_metadata"}, "total": 7}}',
                    )
                if (
                    "create" in url
                    or "insert" in url
                    or "upsert" in url
                    or "search" in url
                ) and datadict[
                    "resource_id"
                ] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5":
                    TestResource.datastore = "create"
                    return MockResponse(
                        200,
                        '{"success": true, "result": {"fields": [{"type": "text", "id": "code"}, {"type": "text", "id": "title"}, {"type": "float", "id": "value"}, {"type": "timestamp", "id": "latest_date"}, {"type": "text", "id": "source"}, {"type": "text", "id": "source_link"}, {"type": "text", "id": "notes"}, {"type": "text", "id": "explore"}, {"type": "text", "id": "units"}], "method": "insert", "primary_key": "code", "resource_id": "bfa6b55f-10b6-4ba2-8470-33bb9a5194a5"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=datastore_create"}',
                    )
                return MockResponse(
                    404,
                    '{"success": false, "error": {"message": "Not found", "__type": "Not Found Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=resource_delete"}',
                )

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_patch(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                datadict = json.loads(data.decode("utf-8"))
                if "show" in url:
                    return mockshow(url, datadict)
                return mockpatch(url, datadict)

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_dataset(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                datadict = json.loads(data.decode("utf-8"))
                return mockdataset(url, datadict)

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def search(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                datadict = json.loads(data.decode("utf-8"))
                return mocksearch(url, datadict)

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_resourceview(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                decodedata = data.decode("utf-8")
                return mockresourceview(url, decodedata)

        Configuration.read().remoteckan().session = MockSession()

    @pytest.fixture(scope="function")
    def post_broken(self):
        class MockSession:
            @staticmethod
            def post(url, data, headers, files, allow_redirects, auth=None):
                if isinstance(data, dict):
                    datadict = {
                        k.decode("utf8"): v.decode("utf8")
                        for k, v in data.items()
                    }
                else:
                    datadict = json.loads(data.decode("utf-8"))
                if "show" in url:
                    return mockshow(url, datadict)
                if "broken" not in url:
                    return MockResponse(
                        404,
                        '{"success": false, "error": {"message": "TEST ERROR: Not mark broken", "__type": "TEST ERROR: Not Create Error"}, "help": "http://test-data.humdata.org/api/3/action/help_show?name=hdx_mark_broken_link_in_resource"}',
                    )
                resultdictcopy = copy.deepcopy(resultdict)
                resultdictcopy["broken_link"] = True
                result = json.dumps(resultdictcopy)
                return MockResponse(
                    200,
                    '{"success": true, "result": %s, "help": "http://test-data.humdata.org/api/3/action/help_show?name=hdx_mark_broken_link_in_resource"}'
                    % result,
                )

        Configuration.read().remoteckan().session = MockSession()

    def test_read_from_hdx(self, configuration, read):
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
        assert resource["name"] == "MyResource1"
        assert resource["package_id"] == "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d"
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046812"
        )
        assert resource is None
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046813"
        )
        assert resource is None
        with pytest.raises(HDXError):
            Resource.read_from_hdx("ABC")

    def test_check_url_filetoupload(self, configuration):
        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        resource.check_url_filetoupload()
        resource.set_file_to_upload("abc")
        resource.check_url_filetoupload()
        resource["url"] = "lala"
        with pytest.raises(HDXError):
            resource.check_url_filetoupload()
        resource = Resource(resource_data)
        resource["format"] = "NOTEXIST"
        with pytest.raises(HDXError):
            resource.check_url_filetoupload()
        with pytest.raises(HDXError):
            resource.set_file_type("NOTEXIST")
        del resource["format"]
        with pytest.raises(HDXError):
            resource.check_url_filetoupload()

    def test_get_set_date_of_resource(self):
        resource = Resource(
            {"daterange_for_data": "[2020-01-07T00:00:00 TO *]"}
        )
        result = resource.get_date_of_resource(today=datetime(2020, 11, 17))
        assert result == {
            "startdate": datetime(2020, 1, 7, 0, 0, tzinfo=timezone.utc),
            "enddate": datetime(2020, 11, 17, 23, 59, 59, tzinfo=timezone.utc),
            "startdate_str": "2020-01-07T00:00:00+00:00",
            "enddate_str": "2020-11-17T23:59:59+00:00",
            "ongoing": True,
        }
        resource.set_date_of_resource("2020-02-09", "2020-10-20")
        result = resource.get_date_of_resource("%d/%m/%Y")
        assert result == {
            "startdate": datetime(2020, 2, 9, 0, 0, tzinfo=timezone.utc),
            "enddate": datetime(2020, 10, 20, 23, 59, 59, tzinfo=timezone.utc),
            "startdate_str": "09/02/2020",
            "enddate_str": "20/10/2020",
            "ongoing": False,
        }

    def test_check_required_fields(self, configuration):
        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        resource.check_url_filetoupload()
        resource.check_required_fields()

    def test_create_in_hdx(self, configuration, post_create):
        resource = Resource()
        with pytest.raises(HDXError):
            resource.create_in_hdx()
        resource["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
        resource["name"] = "LALA"
        with pytest.raises(HDXError):
            resource.create_in_hdx()

        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        resource.create_in_hdx()
        assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
        assert resource["url_type"] == "api"
        assert resource["resource_type"] == "api"
        assert (
            resource["url"]
            == "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-api/master/tests/fixtures/test_data.csv"
        )

        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        filetoupload = join("tests", "fixtures", "test_data.csv")
        resource.set_file_to_upload(filetoupload)
        assert resource.get_file_to_upload() == filetoupload
        resource.create_in_hdx()
        assert resource["url_type"] == "upload"
        assert resource["resource_type"] == "file.upload"
        assert (
            resource["url"]
            == "http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/test_data.csv"
        )
        assert resource["state"] == "active"
        resource.set_file_to_upload(filetoupload)
        resource.create_in_hdx()
        assert (
            resource["url"]
            == "http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/test_data.csv"
        )
        resource_data["name"] = "MyResource2"
        resource = Resource(resource_data)
        with pytest.raises(HDXError):
            resource.create_in_hdx()

        resource_data["name"] = "MyResource3"
        resource = Resource(resource_data)
        with pytest.raises(HDXError):
            resource.create_in_hdx()

    def test_update_in_hdx(self, configuration, post_update):
        resource = Resource()
        resource["id"] = "NOTEXIST"
        with pytest.raises(HDXError):
            resource.update_in_hdx()
        resource["name"] = "LALA"
        with pytest.raises(HDXError):
            resource.update_in_hdx()

        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
        assert resource.get_file_type() == "csv"

        resource.set_file_type("XLSX")
        resource["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
        resource["name"] = "MyResource1"
        resource.update_in_hdx()
        assert resource["id"] == "74b74ae1-df0c-4716-829f-4f939a046811"
        assert resource["format"] == "xlsx"
        resource.set_file_type(".xsl")
        assert resource.get_file_type() == "xls"
        resource.set_file_type("XLSX")
        assert resource.get_file_type() == "xlsx"
        assert resource["url_type"] == "api"
        assert resource["resource_type"] == "api"
        assert (
            resource["url"]
            == "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-api/master/tests/fixtures/test_data.csv"
        )
        assert resource["state"] == "active"

        filetoupload = join("tests", "fixtures", "test_data.csv")
        resource.set_file_to_upload(
            filetoupload, guess_format_from_suffix=True
        )
        assert resource["format"] == "csv"
        resource.update_in_hdx()
        assert resource["url_type"] == "upload"
        assert resource["resource_type"] == "file.upload"
        assert (
            resource["url"]
            == "http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/test_data.csv"
        )
        assert resource["state"] == "active"

        resource["id"] = "NOTEXIST"
        with pytest.raises(HDXError):
            resource.update_in_hdx()

        del resource["id"]
        with pytest.raises(HDXError):
            resource.update_in_hdx()

        resource.data = dict()
        with pytest.raises(HDXError):
            resource.update_in_hdx()

        resource_data = copy.deepcopy(TestResource.resource_data)
        resource_data["name"] = "MyResource1"
        resource_data["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
        resource = Resource(resource_data)
        resource.create_in_hdx()
        assert resource["id"] == "74b74ae1-df0c-4716-829f-4f939a046811"
        assert resource.get_file_type() == "xlsx"
        assert resource["state"] == "active"
        resource["format"] = "Geoservice"
        resource.update_in_hdx()
        assert resource.get_file_type() == "geoservice"
        resource["format"] = "NOTEXIST"
        with pytest.raises(HDXError):
            resource.update_in_hdx()

    def test_delete_from_hdx(self, configuration, post_delete):
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        resource.delete_from_hdx()
        del resource["id"]
        with pytest.raises(HDXError):
            resource.delete_from_hdx()

    def test_update_yaml(self, configuration, static_yaml):
        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        assert resource["name"] == "MyResource1"
        assert resource.get_file_type() == "xlsx"
        resource.update_from_yaml(static_yaml)
        assert resource["name"] == "MyResource1"
        assert resource.get_file_type() == "csv"

    def test_update_json(self, configuration, static_json):
        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        assert resource["name"] == "MyResource1"
        assert resource.get_file_type() == "xlsx"
        resource.update_from_json(static_json)
        assert resource["name"] == "MyResource1"
        assert resource.get_file_type() == "zipped csv"

    def test_patch(self, configuration, post_patch):
        resource = Resource()
        resource["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
        resource.update_in_hdx(
            operation="patch", batch_mode="KEEP_OLD", skip_validation=True
        )
        assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"

    def test_get_dataset(self, configuration, post_dataset):
        resource_data = copy.deepcopy(TestResource.resource_data)
        resource = Resource(resource_data)
        dataset = resource.get_dataset()
        assert dataset["id"] == "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d"
        del resource["package_id"]
        with pytest.raises(HDXError):
            resource.get_dataset()

    def test_search_in_hdx(self, configuration, search):
        resources = Resource.search_in_hdx("name:ACLED")
        assert len(resources) == 4
        resources = Resource.search_in_hdx("name:ajyhgr")
        assert len(resources) == 0
        with pytest.raises(HDXError):
            Resource.search_in_hdx("fail")

    def test_download(self, configuration, read):
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        resource2 = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046814"
        )
        url, path = resource.download()
        remove(path)
        assert (
            url
            == "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-api/master/tests/fixtures/test_data.csv"
        )
        assert basename(path) == "MyResource1.csv"
        resource["url"] = ""
        with pytest.raises(HDXError):
            resource.download()
        with pytest.raises(DownloadError):
            resource2.download()

    def test_datastore(
        self, configuration, post_datastore, topline_yaml, topline_json
    ):
        resource_ids = Resource.get_all_resource_ids_in_datastore()
        assert resource_ids == [
            "f9228459-d808-4b51-948f-68a5850abfde",
            "af618a0b-09b8-42c8-836f-2be597e1ea34",
            "748b40dd-7bd3-40a3-941b-e76f0bfbe0eb",
            "91c78d24-eab3-40b5-ba91-6b29bcda7178",
            "9320cfce-4620-489a-bcbe-25c73867d4fc",
            "b9d2eb36-e65c-417a-bc28-f4dadb149302",
            "ca6a0891-8395-4d58-9168-6c44e17e0193",
        ]
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        resource2 = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046815"
        )
        TestResource.datastore = None
        assert resource.has_datastore() is True
        assert TestResource.datastore == "create"
        TestResource.datastore = None
        assert resource2.has_datastore() is False

    def test_resource_views(self, configuration, post_resourceview):
        resource = Resource({"id": "25982d1c-f45a-45e1-b14e-87d367413045"})
        with pytest.raises(HDXError):
            resource.add_update_resource_view("123")
        resource_view = copy.deepcopy(resource_view_list[0])
        del resource_view["id"]
        del resource_view["package_id"]
        resource.add_update_resource_view(resource_view)
        resource_view = copy.deepcopy(resource_view_list[1])
        del resource_view["id"]
        del resource_view["package_id"]
        with pytest.raises(HDXError):
            resource.add_update_resource_views("123")
        resource.add_update_resource_views([resource_view])
        resource_views = resource.get_resource_views()
        assert (
            resource_views[0]["id"] == "d80301b5-4abd-49bd-bf94-fa4af7b6e7a4"
        )
        assert (
            resource_views[1]["id"] == "c06b5a0d-1d41-4a74-a196-41c251c76023"
        )
        with pytest.raises(HDXError):
            resource.delete_resource_view("123")
        resource.delete_resource_view("d80301b5-4abd-49bd-bf94-fa4af7b6e7a4")
        resource.delete_resource_view(resource_view)
        resource_view["title"] = "XXX"
        with pytest.raises(HDXError):
            resource.delete_resource_view(resource_view)
        with pytest.raises(HDXError):
            resource.reorder_resource_views("123")
        resource.reorder_resource_views(
            [
                "c06b5a0d-1d41-4a74-a196-41c251c76023",
                "d80301b5-4abd-49bd-bf94-fa4af7b6e7a4",
            ]
        )
        resource.reorder_resource_views(resource_view_list)
        resource_view = copy.deepcopy(resource_view_list[0])
        resource_view["id"] = "123"
        with pytest.raises(HDXError):
            resource.reorder_resource_views(
                [resource_view_list[1], resource_view]
            )

    def test_mark_broken(self, configuration, post_broken):
        resource = Resource.read_from_hdx(
            "74b74ae1-df0c-4716-829f-4f939a046811"
        )
        assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
        assert resource["name"] == "MyResource1"
        assert resource["package_id"] == "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d"
        resource.mark_broken()
        assert resource.is_broken() is True
