import unittest

import requests_mock

from parsons import Shopify, Table
from test.utils import assert_matching_tables

SUBDOMAIN = "myorg"
PASSWORD = "abc123"
API_KEY = "abc123"
API_VERSION = "2020-10"


class TestShopify(unittest.TestCase):
    mock_count_all = {"count": 2}
    mock_count_date = mock_count_since = {"count": 1}
    mock_graphql = {"data": {"orders": {"edges": [{"node": {"id": 1}}]}}}
    mock_orders_all = {
        "orders": [
            {
                "created_at": "2020-10-19T12:00:00-04:00",
                "financial_status": "paid",
                "id": 1,
            },
            {
                "created_at": "2020-10-20T12:00:00-04:00",
                "financial_status": "refunded",
                "id": 2,
            },
        ]
    }
    mock_orders_completed = {
        "orders": [
            {
                "created_at": "2020-10-19T12:00:00-04:00",
                "financial_status": "paid",
                "id": 1,
            }
        ]
    }
    mock_orders_date = mock_orders_since = {
        "orders": [
            {
                "created_at": "2020-10-20T12:00:00-04:00",
                "financial_status": "refunded",
                "id": 2,
            }
        ]
    }
    mock_result_all = Table(
        [
            ("created_at", "financial_status", "id"),
            ("2020-10-19T12:00:00-04:00", "paid", 1),
            ("2020-10-20T12:00:00-04:00", "refunded", 2),
        ]
    )
    mock_result_completed = Table(
        [
            ("created_at", "financial_status", "id"),
            ("2020-10-19T12:00:00-04:00", "paid", 1),
        ]
    )
    mock_result_date = mock_result_since = Table(
        [
            ("created_at", "financial_status", "id"),
            ("2020-10-20T12:00:00-04:00", "refunded", 2),
        ]
    )

    def setUp(self):
        self.shopify = Shopify(SUBDOMAIN, PASSWORD, API_KEY, API_VERSION)

    @requests_mock.Mocker()
    def test_get_count(self, m):
        m.get(
            self.shopify.get_query_url(None, None, "orders", True),
            json=self.mock_count_all,
        )
        m.get(
            self.shopify.get_query_url("2020-10-20", None, "orders", True),
            json=self.mock_count_date,
        )
        m.get(
            self.shopify.get_query_url(None, 2, "orders", True),
            json=self.mock_count_since,
        )
        self.assertEqual(self.shopify.get_count(None, None, "orders"), 2)
        self.assertEqual(self.shopify.get_count("2020-10-20", None, "orders"), 1)
        self.assertEqual(self.shopify.get_count(None, 2, "orders"), 1)

    @requests_mock.Mocker()
    def test_get_orders(self, m):
        m.get(
            self.shopify.get_query_url(None, None, "orders", False),
            json=self.mock_orders_all,
        )
        m.get(
            self.shopify.get_query_url("2020-10-20", None, "orders", False),
            json=self.mock_orders_date,
        )
        m.get(
            self.shopify.get_query_url(None, 2, "orders", False),
            json=self.mock_orders_since,
        )
        m.get(
            self.shopify.get_query_url(None, None, "orders", False) + "&financial_status=paid",
            json=self.mock_orders_completed,
        )
        assert_matching_tables(self.shopify.get_orders(None, None, False), self.mock_result_all)
        assert_matching_tables(
            self.shopify.get_orders("2020-10-20", None, False), self.mock_result_date
        )
        assert_matching_tables(self.shopify.get_orders(None, 2, False), self.mock_result_since)
        assert_matching_tables(
            self.shopify.get_orders(None, None, True), self.mock_result_completed
        )

    @requests_mock.Mocker()
    def test_get_query_url(self, m):
        self.assertEqual(
            self.shopify.get_query_url(None, None, "orders", True),
            f"https://{SUBDOMAIN}.myshopify.com/admin/api/{API_VERSION}/orders/"
            "count.json?limit=250&status=any",
        )
        self.assertEqual(
            self.shopify.get_query_url("2020-10-20", None, "orders", True),
            f"https://{SUBDOMAIN}.myshopify.com/admin/api/{API_VERSION}/orders/"
            "count.json?limit=250&status=any&created_at_min=2020-10-20T00:00:00&"
            "created_at_max=2020-10-21T00:00:00",
        )
        self.assertEqual(
            self.shopify.get_query_url(None, 2, "orders", True),
            f"https://{SUBDOMAIN}.myshopify.com/admin/api/{API_VERSION}/orders/"
            "count.json?limit=250&status=any&since_id=2",
        )
        self.assertEqual(
            self.shopify.get_query_url(None, None, "orders", False),
            f"https://{SUBDOMAIN}.myshopify.com/admin/api/{API_VERSION}/orders.json?"
            "limit=250&status=any",
        )

    @requests_mock.Mocker()
    def test_graphql(self, m):
        m.post(
            "https://{0}.myshopify.com/admin/api/{1}/graphql.json".format(SUBDOMAIN, API_VERSION),
            json=self.mock_graphql,
        )
        self.assertEqual(
            self.shopify.graphql(
                """
            {{
                orders(query: "financial_status:=paid", first: 100) {{
                    edges {{
                        node {{
                            id
                        }}
                    }}
                }}
            }}
        """
            ),
            self.mock_graphql["data"],
        )
