From 0575c78279e8e5a81f6c1d9ae075a7cd98760874 Mon Sep 17 00:00:00 2001
From: Patrick Barroca <pbarroca@afi-sa.fr>
Date: Wed, 13 Feb 2019 18:54:14 +0100
Subject: [PATCH] cosmogramme database upgrade should not rely on Bokeh ACL

---
 VERSIONS_HOTLINE/gitlab-2                     |   1 +
 .../DatabaseMigrationController.php           |   4 +-
 .../DatabaseMigrationControllerTest.php       |  20 +-
 .../cosmo/controllers/MigrationFixture.php    | 216 ++++++++++++++++++
 cosmogramme/php/_accueil.php                  |   2 +-
 scripts/install-bokeh.php                     |  18 +-
 6 files changed, 239 insertions(+), 22 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/gitlab-2
 rename {application/modules/opac => cosmogramme/cosmozend/application/modules/cosmo}/controllers/DatabaseMigrationController.php (94%)
 rename tests/application/modules/opac/controllers/MigrateControllerTest.php => cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/DatabaseMigrationControllerTest.php (87%)
 create mode 100644 cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/MigrationFixture.php

diff --git a/VERSIONS_HOTLINE/gitlab-2 b/VERSIONS_HOTLINE/gitlab-2
new file mode 100644
index 00000000000..7bbaad2abf1
--- /dev/null
+++ b/VERSIONS_HOTLINE/gitlab-2
@@ -0,0 +1 @@
+ - ticket gitlab#2 : Installation : correction de l'écran de mise à jour de la base de données
\ No newline at end of file
diff --git a/application/modules/opac/controllers/DatabaseMigrationController.php b/cosmogramme/cosmozend/application/modules/cosmo/controllers/DatabaseMigrationController.php
similarity index 94%
rename from application/modules/opac/controllers/DatabaseMigrationController.php
rename to cosmogramme/cosmozend/application/modules/cosmo/controllers/DatabaseMigrationController.php
index 748cd48d001..149930b5a55 100644
--- a/application/modules/opac/controllers/DatabaseMigrationController.php
+++ b/cosmogramme/cosmozend/application/modules/cosmo/controllers/DatabaseMigrationController.php
@@ -20,9 +20,7 @@
  */
 
 
-class DatabaseMigrationController extends ZendAfi_Controller_Action {
-
-
+class Cosmo_DatabaseMigrationController extends ZendAfi_Controller_Action {
   public function preDispatch() {
     parent::preDispatch();
     $this->getHelper('ViewRenderer')->setNoRender();
diff --git a/tests/application/modules/opac/controllers/MigrateControllerTest.php b/cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/DatabaseMigrationControllerTest.php
similarity index 87%
rename from tests/application/modules/opac/controllers/MigrateControllerTest.php
rename to cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/DatabaseMigrationControllerTest.php
index 3ede344a7c8..6004f1264a2 100644
--- a/tests/application/modules/opac/controllers/MigrateControllerTest.php
+++ b/cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/DatabaseMigrationControllerTest.php
@@ -19,7 +19,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-abstract class MigrateControllerTestCase extends AbstractControllerTestCase {
+require_once 'MigrationFixture.php';
+
+
+abstract class MigrateControllerTestCase extends CosmoControllerTestCase {
   public function setUp() {
     parent::setUp();
     Storm_Model_Loader::defaultToVolatile();
@@ -38,7 +41,7 @@ class MigrateControllerPhpDisplayTest extends MigrateControllerTestCase{
   public function setUp() {
     parent::setUp();
     MigrationFixture::mockFileSystemWithPhpScripts();
-    $this->dispatch('/database-migration/migrate', true);
+    $this->dispatch('/cosmo/database-migration/migrate', true);
   }
 
 
@@ -64,7 +67,7 @@ class MigrateControllerPhpDisplayTest extends MigrateControllerTestCase{
 
   /** @test */
   public function migrationforceLinkShouldContainSkipPhp() {
-    $this->assertXPath('//a[contains(@href, "/database-migration/migrate/skip_php/1")]',
+    $this->assertXPath('//a[contains(@href, "/cosmo/database-migration/migrate/skip_php/1")]',
                        $this->_response->getBody());
   }
 
@@ -83,7 +86,7 @@ class MigrateControllerSqlDisplayTest extends MigrateControllerTestCase{
   public function setUp() {
     parent::setUp();
     MigrationFixture::mockFileSystemWithSql();
-    $this->dispatch('/database-migration/migrate', true);
+    $this->dispatch('/cosmo/database-migration/migrate', true);
   }
 
 
@@ -109,7 +112,7 @@ class MigrateControllerSqlDisplayTest extends MigrateControllerTestCase{
 
   /** @test */
   public function migrationforceLinkShouldContainReprise() {
-    $this->assertXPath('//a[contains(@href, "/database-migration/migrate/reprise/1")]',
+    $this->assertXPath('//a[contains(@href, "/cosmo/database-migration/migrate/reprise/1")]',
                        $this->_response->getBody());
   }
 
@@ -128,7 +131,7 @@ class MigrateControllerForcePhpTest extends MigrateControllerTestCase{
   public function setUp() {
     parent::setUp();
     MigrationFixture::mockFileSystemWithPhpScripts();
-    $this->dispatch('/database-migration/migrate/skip_php/1', true);
+    $this->dispatch('/cosmo/database-migration/migrate/skip_php/1', true);
   }
 
 
@@ -147,13 +150,13 @@ class MigrateControllerForceSqlTest extends MigrateControllerTestCase{
   public function setUp() {
     parent::setUp();
     MigrationFixture::mockFileSystemWithSql();
-    $this->dispatch('/database-migration/migrate/reprise/12', true);
+    $this->dispatch('/cosmo/database-migration/migrate/reprise/12', true);
   }
 
 
   /** @test */
   public function migrationShouldStopOnPatch13() {
-    $this->assertXPath('//a[contains(@href, "/database-migration/migrate/reprise/13")]');
+    $this->assertXPath('//a[contains(@href, "/cosmo/database-migration/migrate/reprise/13")]');
   }
 
 
@@ -171,4 +174,3 @@ class MigrateControllerForceSqlTest extends MigrateControllerTestCase{
   }
 
 }
-?>
\ No newline at end of file
diff --git a/cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/MigrationFixture.php b/cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/MigrationFixture.php
new file mode 100644
index 00000000000..1ede80a1340
--- /dev/null
+++ b/cosmogramme/cosmozend/tests/application/modules/cosmo/controllers/MigrationFixture.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class MigrationFixture {
+  use Storm_Test_THelpers;
+  public static function mockEmptyFileSystem() {
+    Class_Migration_Patchs::setFileSystem(Storm_Test_ObjectWrapper::mock()
+                                          ->whenCalled('glob')
+                                          ->answers([]
+                                          ));
+  }
+
+  public static function mockFileSystemWithSql() {
+    Class_Migration_Patchs::setFileSystem(Storm_Test_ObjectWrapper::mock()
+                                          ->whenCalled('glob')
+                                          ->answers(['./cosmogramme/sql/patch/patch_03.sql',
+                                                     './cosmogramme/sql/patch/patch_13.sql',
+                                                     './cosmogramme/sql/patch/patch_10.sql',
+
+                                                     './cosmogramme/sql/patch/patch_14.php',
+                                                     './cosmogramme/sql/patch/patch_12.sql',
+                                                     './cosmogramme/sql/patch/patch_05.sql'
+                                                     ])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_03.sql')
+                                          ->answers([ 'runFrom update working;'])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_05.sql')
+                                          ->answers([ 'runFrom update working;'])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_10.sql')
+                                          ->answers([ 'runFrom update working;'])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_12.sql')
+                                          ->answers([ 'update working;'])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_13.sql')
+                                          ->answers(['update not working;',
+                                                     '-- commented update;',
+                                                     'another update;'])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_14.sql')
+                                          ->answers([ 'another working update;'])
+
+                                          ->whenCalled('sha1_file')
+                                          ->willDo(function() { return uniqid();} )
+    );
+
+    $_mock_system_include = Storm_Test_ObjectWrapper::mock()
+      ->whenCalled('include_file')
+      ->answers(true);
+
+    $mock_sql = Storm_Test_ObjectWrapper::mock();
+    $mock_sql->whenCalled('execute')
+             ->with('update not working;')
+             ->willDo(function() {throw new CustomException('database error' , '666');})
+             ->whenCalled('execute')
+             ->with('update working;')
+             ->answers(true)
+             ->whenCalled('query')
+             ->with("SHOW TABLES LIKE 'patch_hash'")
+             ->answers(1);
+
+    Zend_Registry::set('sql', $mock_sql);
+    Class_Systeme_Include::setInstance($_mock_system_include);
+
+  }
+
+  public static function mockFileSystemWithPhpScripts() {
+    Class_Migration_Patchs::setFileSystem(Storm_Test_ObjectWrapper::mock()
+                                          ->whenCalled('glob')
+                                          ->answers(['./cosmogramme/sql/patch/patch_03.sql',
+                                                     './cosmogramme/sql/patch/patch_13.php',
+                                                     './cosmogramme/sql/patch/patch_10.sql',
+                                                     './cosmogramme/sql/patch/patch_14.php',
+                                                     './cosmogramme/sql/patch/patch_12.sql',
+                                                     './cosmogramme/sql/patch/patch_15.sql',
+                                                     './cosmogramme/sql/patch/patch_5.sql'
+                                                     ])
+
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_12.sql')
+                                          ->answers([ 'update working;'])
+
+                                          ->whenCalled('sha1_file')
+                                          ->with('./cosmogramme/sql/patch/patch_12.sql')
+                                          ->answers('bidonquiapaslatetedunchathein')
+
+                                          ->whenCalled('sha1_file')
+                                          ->with('./cosmogramme/sql/patch/patch_13.php')
+                                          ->answers('patch_13_php_sum')
+
+                                          ->whenCalled('sha1_file')
+                                          ->with('./cosmogramme/sql/patch/patch_14.php')
+                                          ->answers('patch_14_php_sum')
+
+                                          ->whenCalled('sha1_file')
+                                          ->with('./cosmogramme/sql/patch/patch_15.sql')
+                                          ->answers('bidonquiapaslatetedunchathein')
+    );
+
+    $_mock_system_include = Storm_Test_ObjectWrapper::mock()
+      ->whenCalled('include_file')
+      ->with('./cosmogramme/sql/patch/patch_13.php')
+      ->answers(new CustomException('php error','111'))
+      ->whenCalled('include_file')
+      ->with('./cosmogramme/sql/patch/patch_14.php')
+      ->answers(true)
+
+      ->beStrict();
+    Class_Systeme_Include::setInstance($_mock_system_include);
+
+
+    $mock_sql = Storm_Test_ObjectWrapper::mock();
+    $mock_sql->whenCalled('execute')
+             ->with('update working;')
+             ->answers(true)
+             ->whenCalled('query')
+             ->with("SHOW TABLES LIKE 'patch_hash'")
+             ->answers(1);
+
+    Zend_Registry::set('sql', $mock_sql);
+  }
+
+
+  public static function mockFileSystemWithSqlFunctionScripts() {
+
+    Class_Migration_Patchs::setFileSystem(Storm_Test_ObjectWrapper::mock()
+                                          ->whenCalled('glob')
+                                          ->answers(['./cosmogramme/sql/patch/patch_03.sql',
+                                                     './cosmogramme/sql/patch/patch_14.sql',
+                                                     ])
+                                          ->whenCalled('file')
+                                          ->with('./cosmogramme/sql/patch/patch_14.sql')
+                                          ->answers([ 'CREATE FUNCTION clean_spaces(str VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC',
+                                                     'BEGIN',
+                                                     "while instr(str, '  ') > 0 do",
+                                                     "set str := replace(str, '  ', ' ');",
+                                                     "end while;",
+                                                     "return trim(str);",
+                                                     'END'
+                                                     ])
+
+                                          ->whenCalled('sha1_file')
+                                          ->answers('bidonquiapaslatetedunchathein')
+
+    );
+
+    $mock_sql = Storm_Test_ObjectWrapper::mock();
+    $mock_sql->whenCalled('execute')
+             ->with("CREATE FUNCTION clean_spaces(str VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC BEGIN while instr(str, '  ') > 0 do set str := replace(str, '  ', ' '); end while; return trim(str); END")
+             ->answers(true)
+             ->whenCalled('query')
+             ->with("SHOW TABLES LIKE 'patch_hash'")
+             ->answers(1)
+             ->beStrict();
+
+    Zend_Registry::set('sql', $mock_sql);
+
+  }
+
+}
+
+class CustomException extends Exception  {
+  protected $message = 'Unknown exception';     // Exception message
+  private   $string;                            // Unknown
+  protected $code    = 0;                       // User-defined exception code
+  protected $file;                              // Source filename of exception
+  protected $line;                              // Source line of exception
+  private   $trace;                             // Unknown
+
+  public function __construct($message = null, $code = 0)
+  {
+    if (!$message) {
+      throw new $this('Unknown '. get_class($this));
+    }
+    parent::__construct($message, $code);
+  }
+
+
+
+  public function __toString()
+  {
+    return get_class($this) . " '{$this->message}' in {$this->file}({$this->line})\n"
+      . "{$this->getTraceAsString()}";
+  }
+}
+
+
+
+?>
\ No newline at end of file
diff --git a/cosmogramme/php/_accueil.php b/cosmogramme/php/_accueil.php
index 124625bcb4b..c899c8bc9a8 100644
--- a/cosmogramme/php/_accueil.php
+++ b/cosmogramme/php/_accueil.php
@@ -38,7 +38,7 @@ $cosmo_path=new CosmoPaths();
 
 $last_patch_number = (new Class_Migration_Patchs())->getLastPatchNumber();
 if ($niveau_client < $last_patch_number)
-  afficherLigne(true, "Vous devez éxécuter une <a href='".$cosmo_path->getBaseUrl()."/database-migration/migrate' style='color:red;text-decoration:underline;font-size:13px'>mise à niveau de la base de données</a>. Niveau de patch : ".$niveau_client."/".$last_patch_number);
+  afficherLigne(true, "Vous devez éxécuter une <a href='../cosmozend/cosmo/database-migration/migrate' style='color:red;text-decoration:underline;font-size:13px'>mise à niveau de la base de données</a>. Niveau de patch : ".$niveau_client."/".$last_patch_number);
 
 //---------------------------------------------------------------------------------
 // Acces
diff --git a/scripts/install-bokeh.php b/scripts/install-bokeh.php
index cbb42629b29..412a48d6b7a 100644
--- a/scripts/install-bokeh.php
+++ b/scripts/install-bokeh.php
@@ -26,7 +26,7 @@
 		$avant = array_keys($remplacements); $apres = array_values($remplacements);
 		return str_replace($avant,$apres,$fichier);
 	}
-	
+
 	function paramBokeh($parametres) {
 		$logs = '';
 		//on commence par tester la connexion à la base de données
@@ -105,13 +105,13 @@
 			$logs .= "<ul><li><a href='".$parametres['path'].$parametres['url_admin']."'>Accèder a l'administration</a></li>";
 			$logs .= "<li><a href='".$parametres['path'].$parametres['url_cosmogramme']."'>Accèder au cosmogramme</a></li></ul>";
 			$logs .= "<b>Identification</b> : admin / achanger</div>";
-			
+
 			//on remplace le formulaire par la trace des opérations
 			$parametres['formulaire'] = $logs;
 		}
 		return $parametres;
 	}
-	
+
 	//install bokeh php - variables defaut
 	$vars = array('user' => 'Nom Utilisateur', 'pass' => 'Mot de passe', 'name' => 'Base de donnée', 'host' => 'Adresse');
 	$path = pathinfo($_SERVER["PHP_SELF"]);
@@ -122,7 +122,7 @@
 		'name' => 'opacce',
 		'host' => 'localhost',
 		'init' => 'scripts/opac2.sql',
-		'url_MAJ' => '/database-migration/migrate/',
+		'url_MAJ' => '/cosmogramme/cosmozend/cosmo/database-migration/migrate/',
 		'url_admin' => '/admin/',
 		'url_cosmogramme' => '/cosmogramme/',
 		'install-bokeh' => false,
@@ -131,7 +131,7 @@
 	if (!empty($path['dirname']) && $path['dirname'] != "\\")
 		$parametres['path'] = $path['dirname'];
 
-	
+
 	$parametres['formulaire'] = "Bokeh n'est pas configuré sur votre environnement<br/>\n";
 	$parametres['formulaire'] .= "Veuillez modifier les paramètres suivant selon vos besoin et Valider pour lancer le paramétrage<br/>\n";
 	$parametres['formulaire'] .= '<br/>';
@@ -145,15 +145,15 @@
 		$parametres['formulaire'] .= "<label for='".$k."'>".$v."</label><input id='".$k."' name='".$k."' value='".$parametres[$k]."'><br/>\n";
 	}
 	$k = 'install-bokeh';
-	
+
 	$parametres['formulaire'] .= '<br/>';
 	$parametres['formulaire'] .= "<input id='".$k."' name='".$k."' value='".$k."' type='checkbox'> <label for='".$k."'>Je souhaite Paramétrer Bokeh</label><br/>";
 	$parametres['formulaire'] .= '<br/>';
 	$parametres['formulaire'] .= "<input type='submit' value='Valider'>";
-	
+
 	$parametres[$k] = (!empty($_POST[$k]))?clean($_POST[$k]):$parametres[$k];
 	$parametres[$k] = ($parametres[$k] == $k);
-	
+
 
 	//préparation des fichiers de configuration
 	$configIni = array(
@@ -174,7 +174,7 @@
 		'config.ini' => paramFileConstruction("config.ini.default",$configIni),
 		'cosmogramme/config.php' => paramFileConstruction("cosmogramme/config.ref.php",$configCosmo)
 	);
-	
+
 	if ($parametres['install-bokeh'] == true) {
 		$parametres = paramBokeh($parametres);
 	}
-- 
GitLab