from django.test import TestCase
from django.test import Client
from django.db.models import signals

from base.models import Version

from models import UploadedCrash
from signals import process_uploaded_crash

import os
import tempfile
import json

def get_test_file_path(file_name):
    dir = os.path.dirname(__file__)
    return os.path.join(dir, "testdata/%s" % (file_name))

def remove_dir(top):
    for root, dirs, files in os.walk(top, topdown=False):
        for name in files:
            os.remove(os.path.join(root, name))
        for name in dirs:
            os.rmdir(os.path.join(root, name))

def find_crash_id(response):
    crash_id_split = response.content.split('=')
    return crash_id_split[1]

def find_crash(response):
    id = find_crash_id(response)
    upload_crash = UploadedCrash.objects.get(crash_id=id)
    return upload_crash

class TestCrashUpload(TestCase):

    def setUp(self):
        self.version = Version.objects.create(major_version = 1,
                minor_version = 2, micro_version = 3, patch_version = 4)
        self.tmp_dir = tempfile.mkdtemp()
        signals.post_save.disconnect(process_uploaded_crash, sender=UploadedCrash)

    def tearDown(self):
        remove_dir(self.tmp_dir)

    def test_uploadCorrectCrash(self):
        c = Client()
        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):
            with open(get_test_file_path("test")) as f:
                response = c.post('/submit/', {'upload_file_minidump':f, 'Version': '1.2.3.4'})
        self.assertEqual(response.status_code, 200)

    def test_uploadInvalidVersion(self):
        c = Client()
        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):
            with open(get_test_file_path("test")) as f:
                response = c.post('/submit/', {'upload_file_minidump':f, 'Version': '2.3.4.5'})
        self.assertEqual(response.status_code, 500)

    def test_uploadInvalidFile(self):
        c = Client()
        response = c.post('/submit/', {'Version': self.version})
        self.assertEqual(response.status_code, 400)

    def test_uploadMetadata(self):
        c = Client()
        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):
            with open(get_test_file_path("test")) as f:
                response = c.post('/submit/', {'upload_file_minidump':f, 'Version': '1.2.3.4'})
        self.assertEqual(response.status_code, 200)

    def test_uploadDeprecatedAttribs(self):
        c = Client()
        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):
            with open(get_test_file_path("test")) as f:
                response = c.post('/submit/', {'upload_file_minidump':f, 'Version': '1.2.3.4', 'AdapterDeviceId': 'Device1', 'AdapterVendorId': 'Vendor1'})
        self.assertEqual(response.status_code, 200)

    def test_uploadJsonAttribs(self):
        c = Client()
        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):
            with open(get_test_file_path("test")) as f:
                response = c.post('/submit/', {'upload_file_minidump':f, 'Version': '1.2.3.4', 'AdditionalData': '{ "key1" : "val1", "key2" : "val2"}'})
        self.assertEqual(response.status_code, 200)
        upload_crash = find_crash(response)
        self.assertIsNotNone(upload_crash)
        json_data = json.loads(upload_crash.additional_data)
        self.assertDictEqual(json_data, { 'key1': 'val1', 'key2': 'val2'})

@@ -1229,16 +1229,97 @@
 p_dir)%0A%0A
+    def _extrac_crash_id(self, response):%0A        return response.split('=')%5B1%5D%0A%0A
     def 
@@ -3439,12 +3439,656 @@
 ': 'val2'%7D)%0A
+%0A    def test_delete_report(self):%0A        c = Client()%0A        with self.settings(TEMP_UPLOAD_DIR=self.tmp_dir):%0A            with open(get_test_file_path(%22test%22)) as f:%0A                response = c.post('/submit/', %7B'upload_file_minidump': f, 'Version': '1.2.3.4', 'AdditionalData': '%7B %22key1%22: %22val1%22, %22key2%22: %22val2%22 %7D'%7D)%0A            crash_id = self._extrac_crash_id(response.content)%0A            upload_crash = find_crash(response)%0A            path = upload_crash.crash_path%0A            self.assertTrue(os.path.exists(path))%0A            UploadedCrash.objects.get(crash_id=crash_id).delete()%0A            self.assertFalse(os.path.exists(path))%0A

add test for new signal