Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception from Translate plugin when doing Unit Test #546

Closed
chrisvidal opened this issue Jan 30, 2020 · 14 comments
Closed

Exception from Translate plugin when doing Unit Test #546

chrisvidal opened this issue Jan 30, 2020 · 14 comments

Comments

@chrisvidal
Copy link

chrisvidal commented Jan 30, 2020

Given that my plugin is depending on a depending who is depending on Rainlab.Translate.
I am writing (well at least trying) to write some unit test for my plugin, testing API endpoints mostly, and I got this exception:

The test class manages to run the setUp() method.

[2020-01-30 09:26:37] dev.ERROR: Exception: Class Cms\Classes\Page has already been extended with RainLab\Translate\Behaviors\TranslatablePageUrl in /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/ExtendableTrait.php:206
Stack trace:
#0 /Users/christophevidal/Sites/oc-eclia/plugins/rainlab/translate/Plugin.php(51): October\Rain\Extension\Extendable->extendClassWith('RainLab\\Transla...')
#1 [internal function]: RainLab\Translate\Plugin->RainLab\Translate\{closure}(Object(Cms\Classes\Page))
#2 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/ExtendableTrait.php(60): call_user_func(Object(Closure), Object(Cms\Classes\Page))
#3 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/Extendable.php(31): October\Rain\Extension\Extendable->extendableConstruct()
#4 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Halcyon/Model.php(158): October\Rain\Extension\Extendable->__construct()
#5 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Page.php(56): October\Rain\Halcyon\Model->__construct(Array)
#6 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Halcyon/Model.php(550): Cms\Classes\Page->__construct()
#7 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/CmsObject.php(184): October\Rain\Halcyon\Model::on('demo')
#8 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/CmsObject.php(124): Cms\Classes\CmsObject::inTheme(Object(Cms\Classes\Theme))
#9 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Theme.php(130): Cms\Classes\CmsObject::listInTheme(Object(Cms\Classes\Theme), false)
#10 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Router.php(242): Cms\Classes\Theme->listPages()
#11 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Router.php(213): Cms\Classes\Router->loadUrlMap()
#12 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Router.php(194): Cms\Classes\Router->getUrlMap()
#13 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Router.php(114): Cms\Classes\Router->getRouterObject()
#14 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/Controller.php(153): Cms\Classes\Router->findByUrl('/eclia/api/arca...')
#15 /Users/christophevidal/Sites/oc-eclia/modules/cms/Classes/CmsController.php(50): Cms\Classes\Controller->run('eclia/api/arcad...')
#16 [internal function]: Cms\Classes\CmsController->run('eclia/api/arcad...')
#17 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): call_user_func_array(Array, Array)
#18 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\Controller->callAction('run', Array)
#19 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Route.php(212): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Cms\Classes\CmsController), 'run')
#20 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Route.php(169): Illuminate\Routing\Route->runController()
#21 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Router.php(658): Illuminate\Routing\Route->run()
#22 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#23 /Users/christophevidal/Sites/oc-eclia/plugins/rainlab/translate/classes/LocaleMiddleware.php(29): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#24 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): RainLab\Translate\Classes\LocaleMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#25 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#26 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#27 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#28 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#29 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#30 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#31 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#32 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(63): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#33 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#34 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#36 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#37 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#38 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(66): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#39 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#40 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#41 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#42 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Router.php(660): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#43 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Router.php(635): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#44 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Router.php(601): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#45 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Router/CoreRouter.php(20): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#46 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): October\Rain\Router\CoreRouter->dispatch(Object(Illuminate\Http\Request))
#47 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#48 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#49 /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Foundation/Http/Middleware/CheckForMaintenanceMode.php(24): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#50 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): October\Rain\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#51 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#52 /Users/christophevidal/Sites/oc-eclia/plugins/rluders/cors/vendor/barryvdh/laravel-cors/src/HandlePreflight.php(29): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#53 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(149): Barryvdh\Cors\HandlePreflight->handle(Object(Illuminate\Http\Request), Object(Closure))
#54 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#55 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#56 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#57 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#58 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(345): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#59 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php(168): Illuminate\Foundation\Testing\TestCase->call('GET', '/api/arcadier/p...', Array, Array, Array, Array)
#60 /Users/christophevidal/Sites/oc-eclia/plugins/voilaah/backpack/tests/unit/api/PingControllerTest.php(53): Illuminate\Foundation\Testing\TestCase->get('/api/arcadier/p...', Array)
#61 [internal function]: Voilaah\Backpack\Tests\Unit\Api\PingControllerTest->test_ping()
#62 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/Framework/TestCase.php(1071): ReflectionMethod->invokeArgs(Object(Voilaah\Backpack\Tests\Unit\Api\PingControllerTest), Array)
#63 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/Framework/TestCase.php(939): PHPUnit\Framework\TestCase->runTest()
#64 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/Framework/TestResult.php(698): PHPUnit\Framework\TestCase->runBare()
#65 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/Framework/TestCase.php(894): PHPUnit\Framework\TestResult->run(Object(Voilaah\Backpack\Tests\Unit\Api\PingControllerTest))
#66 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/Framework/TestSuite.php(755): PHPUnit\Framework\TestCase->run(Object(PHPUnit\Framework\TestResult))
#67 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(545): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#68 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/TextUI/Command.php(195): PHPUnit\TextUI\TestRunner->doRun(Object(PHPUnit\Framework\TestSuite), Array, true)
#69 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/src/TextUI/Command.php(148): PHPUnit\TextUI\Command->run(Array, true)
#70 /Users/christophevidal/Sites/oc-eclia/vendor/phpunit/phpunit/phpunit(53): PHPUnit\TextUI\Command::main()
#71 {main}  
@LukeTowers
Copy link
Contributor

The testing class you are using isn't properly tearing down the application after each test run. Please verify that you have the latest code. Additionally, we're making some pretty big improvements to testing in the L6 upgrade branch, so perhaps you should wait until octobercms/october#4919 is merged into the upgrade branch and then use the upgrade branch to build your tests on.

@chrisvidal
Copy link
Author

thanks @LukeTowers
ya I have the latest version of each plugin and the last OC build as well.

I can wait for the next upgrade branch for this tests, sure,

my base test case class looks like the example from the doc.

/**
     * Set up function, called before each test.
     *
     * @return void
     */
    public function setUp()
    {
        parent::setUp();
// set up plugins
        $pluginManager = PluginManager::instance();
       $pluginManager->registerAll(true);
        $pluginManager->bootAll(true);

        // disable mailer
        Mail::pretend();
}

    /**
     * Tear down function, called after each test.
     *
     * @return void
     */
    public function tearDown()
    {
        parent::tearDown();

        // clean up plugins
        $pluginManager = PluginManager::instance();
        $pluginManager->unregisterAll();

        // close all mocks
        Mockery::close();
    }

@LukeTowers
Copy link
Contributor

@chrisvidal try adding this method:

static $initialized = false;
protected function runOctoberUpCommand()
    {
        if (static::$initialized) {
            return;
        }

        static::$initialized = true;

        // Get all tables and views then drop them to reset the database
        $views = array_keys(\DB::connection()->getDoctrineSchemaManager()->listViews());
        $tables = \DB::connection()->getDoctrineSchemaManager()->listTableNames();
        foreach ($tables as $table) {
            \Schema::drop($table);
        }
        foreach ($views as $view) {
            \DB::statement("DROP VIEW $view");
        }

        // Initialize the database
        \Artisan::call('october:up');
    }

@chrisvidal
Copy link
Author

thanks @LukeTowers

adding this in my base test class, still gives me the error

[2020-02-01 10:46:12] dev.ERROR: Exception: Class Cms\Classes\Page has already been extended with RainLab\Translate\Behaviors\TranslatablePageUrl in /Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/ExtendableTrait.php:206
Stack trace:
#0 /Users/christophevidal/Sites/oc-eclia/plugins/rainlab/translate/Plugin.php(51): October\Rain\Extension\Extendable->extendClassWith('RainLab\\Transla...')
#1 [internal function]: RainLab\Translate\Plugin->RainLab\Translate\{closure}(Object(Cms\Classes\Page))

@LukeTowers
Copy link
Contributor

@chrisvidal alright, got another idea for you. Remove that code, it's not really applicable unless you're using SQL views.

Instead, add in

\October\Rain\Halcyon\Model::clearBootedModels();
\October\Rain\Halcyon\Model::flushEventListeners();
\October\Rain\Halcyon\Model::clearExtendedClasses();

to your setUp() method.

@LukeTowers
Copy link
Contributor

Related: #509

@chrisvidal
Copy link
Author

oh this is working @LukeTowers
no more exception

thanks so much mate

@chrisvidal
Copy link
Author

chrisvidal commented Feb 1, 2020

damn! after few positive testing, a new exception is happening on the tearDown() method

Exception: Class System\Models\File has already been extended with October\Rain\Database\Behaviors\Purgeable

/Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/ExtendableTrait.php:206
/Users/christophevidal/Sites/oc-eclia/plugins/rainlab/translate/Plugin.php:63
/Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Extension/ExtendableTrait.php:60
/Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Database/Model.php:68
/Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php:299
/Users/christophevidal/Sites/oc-eclia/vendor/october/rain/src/Database/Model.php:210
/Users/christophevidal/Sites/oc-eclia/tests/PluginTestCase.php:217
/Users/christophevidal/Sites/oc-eclia/tests/PluginTestCase.php:110
/Users/christophevidal/Sites/oc-eclia/plugins/voilaah/backpack/tests/PluginTestCase.php:92

and

[2020-02-01 12:56:30] dev.ERROR: PDOException: SQLSTATE[HY000]: General error: 1 no such table: rainlab_translate_locales in /Users/christophevidal/Sites/oc-eclia/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
Stack trace:
#0 /Users/christophevidal/Sites/oc-eclia/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php(77): PDO->prepare('select "name", ...', Array)

@LukeTowers
Copy link
Contributor

@chrisvidal also add

\October\Rain\Database\Model::clearBootedModels();
\October\Rain\Database\Model::flushEventListeners();
\October\Rain\Database\Model::clearExtendedClasses();

@chrisvidal
Copy link
Author

thanks @LukeTowers
just tried and still gets this exception

[2020-02-03 09:54:41] dev.ERROR: PDOException: SQLSTATE[HY000]: General error: 1 no such table: rainlab_translate_locales in /Users/christophevidal/Sites/oc-eclia/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
Stack trace:
#0 /Users/christophevidal/Sites/oc-eclia/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php(77): PDO->prepare('select "name", ...', Array)
#1 /Users/christophevidal/Sites/oc-eclia/vendor/laravel/framework/src/Illuminate/Database/Connection.php(326): Doctrine\DBAL\Driver\PDOConnection->prepare('select "name", ...')

bennothommo added a commit to octobercms/library that referenced this issue Feb 3, 2020
Should resolve some issues in testing where models are not properly reset to a blank state.

Refs: rainlab/translate-plugin#546, rainlab/translate-plugin#509
@LukeTowers
Copy link
Contributor

@chrisvidal are you sure it's accessing the correct database? @bennothommo any ideas here?

@bennothommo
Copy link
Contributor

bennothommo commented Feb 3, 2020

@chrisvidal Another couple of things to check:

  • Make sure that your plugin explicitly depends on the Translate plugin (ie. in the Plugin.php file, the RainLab.Translate plugin has been added to the $require property.)
  • Are you using SQLite as your default connection? If so, there's a bug in the current test suite where it will use your actual database connection instead of the test one if you're using SQLite (this doesn't happen on any other connections). This has been fixed for the L6 upgrade, but as of the current build, it's still there.

@mjauvin
Copy link
Contributor

mjauvin commented Mar 15, 2020

@chrisvidal has this been resolved? Can we close this?

@chrisvidal
Copy link
Author

chrisvidal commented Mar 16, 2020

I haven't had time to look deeper into it. And deciding to wait for the Laravel 6 upgrade.

@bennothommo I am using MySQL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants