async def test_skip_loaded_versions(self, fake_future):
        workspace = MagicMock()
        workspace.list_versions.return_value = fake_future(
            ["1.0", "10.1", "2.0"])

        hasher = RepositoryHasher(storage=MagicMock(), hasher=MagicMock())
        hasher.collect_for_version = MagicMock()
        hasher.collect_for_version.return_value = fake_future([
            Signature(path="wp-content/plugins/a-plugin/readme.txt",
                      hash="12345")
        ])

        stored = VersionList(producer="RepositoryHasher",
                             key="plugins/a-plugin")
        stored.get_version("1.0", create_missing=True)
        stored.get_version("2.0", create_missing=True)

        hasher.storage.read_versions.return_value = stored

        await hasher.collect_for_workspace(
            "plugins/a-plugin",
            workspace,
            prefix="wp-content/plugins/a-plugin")

        hasher.storage.read_versions.assert_called_with("plugins/a-plugin")
        hasher.collect_for_version.assert_called_once_with(
            workspace, "10.1", prefix="wp-content/plugins/a-plugin")
    def test_update_file_list_set_versions_in_order_when_adding_versions_to_signature(self):
        self.version_builder._shrink_version_list = MagicMock()
        version_list = VersionList(key="key", producer="producer")
        version0 = version_list.get_version(version="1.0", create_missing=True)
        version0.add_signature("file", "hash")
        version1 = version_list.get_version(version="1.1", create_missing=True)
        version1.add_signature("file", "hash")
        file_list = self.version_builder.create_file_list_from_version_list(version_list, 50)
        version2 = version_list.get_version("1.2", create_missing=True)
        version2.add_signature("file", "hash")

        self.version_builder.update_file_list(file_list, version_list, 50)

        self.assertEqual(file_list.files[0].signatures[0].versions, ["1.0", "1.1", "1.2"])
    def test_update_hashes(self):
        version_list = VersionList(key="wordpress", producer="Test")
        v392 = version_list.get_version("3.9.2", create_missing=True)
        v392.add_signature("readme.html", "1234")
        v392.add_signature("randomfile", "1234")

        v466 = version_list.get_version("4.6.6", create_missing=True)
        v466.add_signature("readme.html", "12345")

        self.rebuild.update(version_list)

        self.assertEqual(
            self.rebuild.get_hash("readme.html", "3.9.2").attrib["sha256"],
            "1234")
        self.assertEqual(
            self.rebuild.get_hash("readme.html", "4.6.6").attrib["sha256"],
            "12345")
    def test_get_hash_algo_raise_value_error_if_not_all_signature_use_same_algo(self):
        version_list = VersionList(key="key", producer="producer")
        for i in range(5):
            version = version_list.get_version("1.%d" % i, create_missing=True)
            version.add_signature("file0", hash="123", algo="SHA512")
            version.add_signature("file1", hash="123", algo="md5")

        with self.assertRaises(ValueError):
            self.version_builder._get_hash_algo(version_list)
    def test_get_hash_algo_return_algo_used_by_all_signatures_in_version_list(self):
        version_list = VersionList(key="key", producer="producer")
        for i in range(5):
            version = version_list.get_version("1.%d" % i, create_missing=True)
            version.add_signature("file0", hash="123", algo="SHA512")
            version.add_signature("file1", hash="123", algo="SHA512")

        algo = self.version_builder._get_hash_algo(version_list)

        self.assertEqual(algo, "SHA512")
    async def test_brand_new_file(self, fake_future):
        workspace = MagicMock()
        workspace.list_versions.return_value = fake_future(
            ["1.0", "10.1", "2.0"])

        hasher = RepositoryHasher(storage=MagicMock(), hasher=MagicMock())
        hasher.collect_for_version = MagicMock()
        hasher.collect_for_version.return_value = fake_future([
            Signature(path="wp-content/plugins/a-plugin/readme.txt",
                      hash="12345")
        ])

        hasher.storage.read_versions.side_effect = FileNotFoundError()

        await hasher.collect_for_workspace(
            "plugins/a-plugin",
            workspace,
            prefix="wp-content/plugins/a-plugin")

        hasher.storage.read_versions.assert_called_with("plugins/a-plugin")
        hasher.collect_for_version.assert_has_calls([
            call(workspace, "1.0", prefix="wp-content/plugins/a-plugin"),
            call(workspace, "2.0", prefix="wp-content/plugins/a-plugin"),
            call(workspace, "10.1", prefix="wp-content/plugins/a-plugin"),
        ],
                                                    any_order=False)

        expect = VersionList(producer="RepositoryHasher",
                             key="plugins/a-plugin")
        v1 = expect.get_version("1.0", create_missing=True)
        v1.add_signature("wp-content/plugins/a-plugin/readme.txt",
                         hash="12345")
        v2 = expect.get_version("2.0", create_missing=True)
        v2.add_signature("wp-content/plugins/a-plugin/readme.txt",
                         hash="12345")
        v10 = expect.get_version("10.1", create_missing=True)
        v10.add_signature("wp-content/plugins/a-plugin/readme.txt",
                          hash="12345")

        hasher.storage.write_versions.assert_called_with(expect)
    def test_update_file_list_keep_file_order_and_append_new_file_at_end(self):
        self.version_builder._shrink_version_list = MagicMock()
        signature0 = Signature(path="path/to/files/abc.html", hash="12345")
        signature1 = Signature(path="path/to/files/file.js", hash="12345")
        signature2 = Signature(path="path/to/files/js/file.js", hash="12345")
        signature3 = Signature(path="path/to/files/readme.txt", hash="12345")
        signature4 = Signature(path="path/to/files/style/color.css", hash="12345")
        signature5 = Signature(path="path/to/files/style/style.css", hash="12345")
        signature6 = Signature(path="path/to/files/style/color.css", hash="23456")
        signature7 = Signature(path="path/to/files/readme.txt", hash="23456")
        signatures = [signature0, signature1, signature2, signature3, signature4]
        version_list = VersionList(key="key", producer="producer",
                                   versions=[VersionDefinition(version="1.0", signatures=signatures)])
        file_list = self.version_builder.create_file_list_from_version_list(version_list, 50)
        initial_file_order = [file.path for file in file_list.files]
        version = version_list.get_version("1.1", create_missing=True)
        version.signatures = [signature5, signature6, signature7]

        self.version_builder.update_file_list(file_list, version_list, 50)

        for i in range(len(initial_file_order)):
            self.assertEqual(file_list.files[i].path, initial_file_order[i])
        self.assertEqual(signature5.path, file_list.files[-1].path)