from collections import namedtuple
from unittest.mock import MagicMock

from django.test import TestCase

from jarbas.core.models import Reimbursement
from jarbas.dashboard.admin import (
    ReceiptUrlWidget,
    ReimbursementModelAdmin,
    SubquotaWidget,
    SubuotaListfilter,
    SuspiciousWidget,
)


Request = namedtuple('Request', ('method',))
ReimbursementMock = namedtuple('Reimbursement', ('cnpj_cpf'))


class TestDashboardSite(TestCase):

    def setUp(self):
        self.requests = map(Request, ('GET', 'POST', 'PUT', 'PATCH', 'DELETE'))
        self.ma = ReimbursementModelAdmin(Reimbursement, 'dashboard')

    def test_has_add_permission(self):
        permissions = map(self.ma.has_add_permission, self.requests)
        self.assertNotIn(True, tuple(permissions))

    def test_has_change_permission(self):
        permissions = map(self.ma.has_change_permission, self.requests)
        expected = (True, False, False, False, False)
        self.assertEqual(expected, tuple(permissions))

    def test_has_delete_permission(self):
        permissions = map(self.ma.has_delete_permission, self.requests)
        self.assertNotIn(True, tuple(permissions))

    def test_format_document_with_cnpj(self):
        obj = ReimbursementMock('12345678901234')
        self.assertEqual('12.345.678/9012-34', self.ma._format_document(obj))

    def test_format_document_with_cpf(self):
        obj = ReimbursementMock('12345678901')
        self.assertEqual('123.456.789-01', self.ma._format_document(obj))

    def test_format_document_with_unknown(self):
        obj = ReimbursementMock('2345678')
        self.assertEqual('2345678', self.ma._format_document(obj))


class TestSubuotaListfilter(TestCase):

    def setUp(self):
        self.qs = MagicMock()
        self.list_filter = MagicMock()

    def test_queryset_without_subquota(self):
        self.list_filter.value.return_value = None
        SubuotaListfilter.queryset(self.list_filter, MagicMock(), self.qs)
        self.qs.filter.assert_not_called()

    def test_queryset_with_subquota(self):
        self.list_filter.value.return_value = 42
        SubuotaListfilter.queryset(self.list_filter, MagicMock(), self.qs)
        self.qs.filter.assert_called_once_with(subquota_id=42)


class TestCustomWidgets(TestCase):

    def test_subquota_widget(self):
        widget = SubquotaWidget()
        rendered = widget.render('Name', 'Flight ticket issue')
        self.assertIn('Emissão bilhete aéreo', rendered)

    def test_suspicious_widget_with_one_suspicion(self):
        widget = SuspiciousWidget()
        json_value = '{"invalid_cnpj_cpf": true}'
        rendered = widget.render('Name', json_value)
        self.assertIn('CPF ou CNPJ inválidos', rendered)
        self.assertNotIn('<br>', rendered)

    def test_suspicious_widget_with_two_suspicions(self):
        widget = SuspiciousWidget()
        json_value = '{"invalid_cnpj_cpf": true, "election_expenses": true}'
        rendered = widget.render('Name', json_value)
        self.assertIn('CPF ou CNPJ inválidos', rendered)
        self.assertIn('<br>', rendered)
        self.assertIn('Gasto com campanha eleitoral', rendered)

    def test_suspicious_widget_with_new_suspicion(self):
        widget = SuspiciousWidget()
        json_value = '{"whatever": true, "invalid_cnpj_cpf": true}'
        rendered = widget.render('Name', json_value)
        self.assertIn('CPF ou CNPJ inválidos', rendered)
        self.assertIn('<br>', rendered)
        self.assertIn('whatever', rendered)

    def test_suspicious_widget_without_suspicion(self):
        widget = SuspiciousWidget()
        json_value = 'null'
        rendered = widget.render('Name', json_value)
        self.assertEqual('', rendered)

    def test_receipt_url_widget(self):
        widget = ReceiptUrlWidget()
        url = 'https://jarbas.serenatadeamor.org'
        rendered = widget.render('Name', url)
        self.assertIn('href="{}"'.format(url), rendered)
        self.assertIn('>{}</a>'.format(url), rendered)

    def test_receipt_url_widget_without_url(self):
        widget = ReceiptUrlWidget()
        rendered = widget.render('Name', '')
        self.assertEqual('', rendered)

@@ -63,16 +63,23 @@
 agicMock
+, patch
 %0A%0Afrom d
@@ -262,32 +262,33 @@
 get,%0A    Sub
+q
 uotaList
 filter,%0A    
@@ -271,25 +271,25 @@
 SubquotaList
-f
+F
 ilter,%0A    S
@@ -1692,24 +1692,25 @@
  TestSub
+q
 uotaList
 filter(T
@@ -1697,25 +1697,25 @@
 SubquotaList
-f
+F
 ilter(TestCa
@@ -1753,18 +1753,16 @@
     
-self.q
+arg
 s = 
+%5B
 Magi
@@ -1772,48 +1772,187 @@
 ck()
-%0A        self.list_filter = MagicMock()%0A
+%5D * 4  # SubquotaListFilter expectss 4 arguments%0A        self.list_filter = SubquotaListFilter(*args)%0A        self.qs = MagicMock()%0A%0A    @patch.object(SubquotaListFilter, 'value')
 %0A   
@@ -1983,32 +1983,39 @@
 ut_subquota(self
+, value
 ):%0A        self.
@@ -2009,33 +2009,16 @@
         
-self.list_filter.
 value.re
@@ -2039,35 +2039,34 @@
 one%0A        
-SubuotaL
+self.l
 ist
+_
 filter.query
@@ -2069,34 +2069,16 @@
 ueryset(
-self.list_filter, 
 MagicMoc
@@ -2131,24 +2131,71 @@
 t_called()%0A%0A
+    @patch.object(SubquotaListFilter, 'value')%0A
     def test
@@ -2218,24 +2218,31 @@
 ubquota(self
+, value
 ):%0A        s
@@ -2240,33 +2240,16 @@
         
-self.list_filter.
 value.re
@@ -2261,18 +2261,18 @@
 value = 
-42
+10
 %0A       
@@ -2276,19 +2276,18 @@
     
-SubuotaL
+self.l
 ist
+_
 filt
@@ -2302,26 +2302,8 @@
 set(
-self.list_filter, 
 Magi
@@ -2312,32 +2312,98 @@
 ock(), self.qs)%0A
+        expected = dict(subquota_description='Telecommunication')%0A
         self.qs.
@@ -2437,22 +2437,18 @@
 ith(
-subquota_id=42
+**expected
 )%0A%0A%0A

Refactor tests for subquota list filter queryset method