<commit_before>
import os.path
import json
import tempfile
import unittest
from io import BytesIO
from uuid import uuid4
from zipfile import ZipFile

from django.test import TestCase, TransactionTestCase
from django.core.files.base import File
from django.urls import reverse
from sweettooth.extensions import models, views

from sweettooth.testutils import BasicUserTestCase

testdata_dir = os.path.join(os.path.dirname(__file__), 'testdata')

def get_test_zipfile(testname):
    original = open(os.path.join(testdata_dir, testname, testname + ".zip"), 'rb')
    new_temp = tempfile.NamedTemporaryFile(suffix=testname + ".zip.temp")
    new_temp.write(original.read())
    new_temp.seek(0)
    original.close()

    return new_temp

class UUIDPolicyTest(TestCase):
    def test_uuid_policy(self):
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))

        for i in range(10):
            self.assertTrue(models.validate_uuid(str(uuid4())))

        self.assertFalse(models.validate_uuid("<Wonderful>"))

        self.assertFalse(models.validate_uuid("<EMAIL>"))
        self.assertFalse(models.validate_uuid("<EMAIL>"))

        self.assertTrue(models.validate_uuid("<EMAIL>"))

class ExtensionPropertiesTest(BasicUserTestCase, TestCase):
    def test_description_parsing(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "Simple test metadata"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "Simple test metadata")

        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "First line\nSecond line"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "First line")

        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": ""}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "")

    def test_shell_versions_json(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "shell-version": ["3.2", "3.2.1"]}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion.objects.create(extension=extension,
                                                         status=models.STATUS_UNREVIEWED)
        version.parse_metadata_json(metadata)

        self.assertEqual(version.shell_versions_json, '["3.2", "3.2.1"]')

class ParseZipfileTest(BasicUserTestCase, TestCase):
    def test_simple_metadata(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "Simple test metadata",
                    "url": "http://test-metadata.gnome.org"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        self.assertEqual(extension.name, "Test Metadata")
        self.assertEqual(extension.description, "Simple test metadata")
        self.assertEqual(extension.url, "http://test-metadata.gnome.org")

    def test_simple_zipdata_data(self):
        with get_test_zipfile('SimpleExtension') as f:
            metadata = models.parse_zipfile_metadata(f)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        self.assertEqual(extension.uuid, "<EMAIL>")
        self.assertEqual(extension.name, "Test Extension")
        self.assertEqual(extension.description, "Simple test metadata")
        self.assertEqual(extension.url, "http://test-metadata.gnome.org")

    def test_extra_metadata(self):
        with get_test_zipfile('ExtraMetadata') as f:
            metadata = models.parse_zipfile_metadata(f)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        extra = json.loads(version.extra_json_fields)
        self.assertEqual(extension.uuid, "<EMAIL>")
        self.assertEqual(extra["extra"], "This is some good data")
        self.assertTrue("description" not in extra)
        self.assertTrue("url" not in extra)

    def test_bad_zipfile_metadata(self):
        bad_data = BytesIO(b"deadbeef")
        self.assertRaises(models.InvalidExtensionData, models.parse_zipfile_metadata, bad_data)

        with get_test_zipfile('TooLarge') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Zip file is too large"):
                models.parse_zipfile_metadata(f)

        with get_test_zipfile('NoMetadata') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Missing metadata.json"):
                models.parse_zipfile_metadata(f)

        with get_test_zipfile('BadMetadata') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Invalid JSON data"):
                models.parse_zipfile_metadata(f)


class ReplaceMetadataTest(BasicUserTestCase, TestCase):
    @unittest.expectedFailure
    def test_replace_metadata(self):
        old_zip_file = get_test_zipfile('LotsOfFiles')

        metadata = models.parse_zipfile_metadata(old_zip_file)
        old_zip_file.seek(0)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension,
                                          source=File(old_zip_file))

        version.parse_metadata_json(metadata)

        new_zip = version.get_zipfile('r')

        old_zip = ZipFile(File(old_zip_file), 'r')
        self.assertEqual(len(old_zip.infolist()), len(new_zip.infolist()))
        self.assertEqual(new_zip.read("metadata.json"),
                         version.make_metadata_json_string())

        for old_info in old_zip.infolist():
            if old_info.filename == "metadata.json":
                continue

            new_info = new_zip.getinfo(old_info.filename)
            self.assertEqual(old_zip.read(old_info), new_zip.read(new_info))
            self.assertEqual(old_info.date_time, new_info.date_time)

        old_zip.close()
        new_zip.close()

class UploadTest(BasicUserTestCase, TransactionTestCase):
    def upload_file(self, zipfile):
        with get_test_zipfile(zipfile) as f:
            return self.client.post(reverse('extensions-upload-file'),
                                    dict(source=f,<commit_msg>tests: restore ReplaceMetadataTest test<commit_after>
import os.path
import json
import tempfile
import unittest
from io import BytesIO
from uuid import uuid4
from zipfile import ZipFile

from django.test import TestCase, TransactionTestCase
from django.core.files.base import File
from django.urls import reverse
from sweettooth.extensions import models, views

from sweettooth.testutils import BasicUserTestCase
from django.test.utils import override_settings

testdata_dir = os.path.join(os.path.dirname(__file__), 'testdata')

def get_test_zipfile(testname):
    original = open(os.path.join(testdata_dir, testname, testname + ".zip"), 'rb')
    new_temp = tempfile.NamedTemporaryFile(suffix=testname + ".zip.temp")
    new_temp.write(original.read())
    new_temp.seek(0)
    original.close()

    return new_temp

class UUIDPolicyTest(TestCase):
    def test_uuid_policy(self):
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))
        self.assertTrue(models.validate_uuid("<EMAIL>"))

        for i in range(10):
            self.assertTrue(models.validate_uuid(str(uuid4())))

        self.assertFalse(models.validate_uuid("<Wonderful>"))

        self.assertFalse(models.validate_uuid("<EMAIL>"))
        self.assertFalse(models.validate_uuid("<EMAIL>"))

        self.assertTrue(models.validate_uuid("<EMAIL>"))

class ExtensionPropertiesTest(BasicUserTestCase, TestCase):
    def test_description_parsing(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "Simple test metadata"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "Simple test metadata")

        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "First line\nSecond line"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "First line")

        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": ""}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        self.assertEqual(extension.first_line_of_description, "")

    def test_shell_versions_json(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "shell-version": ["3.2", "3.2.1"]}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion.objects.create(extension=extension,
                                                         status=models.STATUS_UNREVIEWED)
        version.parse_metadata_json(metadata)

        self.assertEqual(version.shell_versions_json, '["3.2", "3.2.1"]')

class ParseZipfileTest(BasicUserTestCase, TestCase):
    def test_simple_metadata(self):
        metadata = {"uuid": "<EMAIL>",
                    "name": "Test Metadata",
                    "description": "Simple test metadata",
                    "url": "http://test-metadata.gnome.org"}

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        self.assertEqual(extension.name, "Test Metadata")
        self.assertEqual(extension.description, "Simple test metadata")
        self.assertEqual(extension.url, "http://test-metadata.gnome.org")

    def test_simple_zipdata_data(self):
        with get_test_zipfile('SimpleExtension') as f:
            metadata = models.parse_zipfile_metadata(f)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        self.assertEqual(extension.uuid, "<EMAIL>")
        self.assertEqual(extension.name, "Test Extension")
        self.assertEqual(extension.description, "Simple test metadata")
        self.assertEqual(extension.url, "http://test-metadata.gnome.org")

    def test_extra_metadata(self):
        with get_test_zipfile('ExtraMetadata') as f:
            metadata = models.parse_zipfile_metadata(f)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)
        version = models.ExtensionVersion(extension=extension)
        version.parse_metadata_json(metadata)

        extra = json.loads(version.extra_json_fields)
        self.assertEqual(extension.uuid, "<EMAIL>")
        self.assertEqual(extra["extra"], "This is some good data")
        self.assertTrue("description" not in extra)
        self.assertTrue("url" not in extra)

    def test_bad_zipfile_metadata(self):
        bad_data = BytesIO(b"deadbeef")
        self.assertRaises(models.InvalidExtensionData, models.parse_zipfile_metadata, bad_data)

        with get_test_zipfile('TooLarge') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Zip file is too large"):
                models.parse_zipfile_metadata(f)

        with get_test_zipfile('NoMetadata') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Missing metadata.json"):
                models.parse_zipfile_metadata(f)

        with get_test_zipfile('BadMetadata') as f:
            with self.assertRaisesMessage(models.InvalidExtensionData, "Invalid JSON data"):
                models.parse_zipfile_metadata(f)


class ReplaceMetadataTest(BasicUserTestCase, TestCase):
    @override_settings(MEDIA_ROOT=tempfile.gettempdir())
    def test_replace_metadata(self):
        old_zip_file = get_test_zipfile('LotsOfFiles')

        metadata = models.parse_zipfile_metadata(old_zip_file)
        old_zip_file.seek(0)

        extension = models.Extension.objects.create_from_metadata(metadata, creator=self.user)

        version = models.ExtensionVersion.objects.create(extension=extension,
                                          source=File(old_zip_file),
                                          status=models.STATUS_UNREVIEWED)

        version.parse_metadata_json(metadata)
        version.replace_metadata_json()
        version.save()

        new_zip = version.get_zipfile('r')

        old_zip = ZipFile(old_zip_file, 'r')
        self.assertEqual(len(old_zip.infolist()), len(new_zip.infolist()))
        self.assertEqual(new_zip.read("metadata.json").decode('utf-8'),
                         version.make_metadata_json_string())

        for old_info in old_zip.infolist():
            if old_info.filename == "metadata.json":
                continue

            new_info = new_zip.getinfo(old_info.filename)
            self.assertEqual(old_zip.read(old_info), new_zip.read(new_info))
            self.assertEqual(old_info.date_time, new_info.date_time)

        old_zip.close()
        new_zip.close()

class UploadTest(BasicUserTestCase, TransactionTestCase):
    def upload_file(self, zipfile):
        with get_test_zipfile(zipfile) as f:
            return self.client.post(reverse('extensions-upload-file'),
                                    dict(source=f,
{'fraction_non_alphanumeric': 0.10906466909490757, 'fraction_numerical': 0.002267885368703182, 'mean_word_length': 3.050097411633732, 'pattern_counts': {'":': 34, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6414299', 'n_tokens_mistral': 4027, 'n_tokens_neox': 3936, 'n_words': 673}