I want to test my ArticleForm which contains CKEditor field:
$builder->add('content', CKEditorType::class, array(
'config' => array('uiColor' => '#ffffff'),
'required' => true));
However when I run PHPUnit I got the following error:
Argument 1 passed to Ivory\CKEditorBundle\Form\Type\CKEditorType::__construct()
must be an instance of Ivory\CKEditorBundle\Model\ConfigManagerInterface, none given
My test config is the same as for dev and prod where CKEditor works fine:
ivory_ck_editor:
default_config: default
configs:
default:
filebrowserBrowseRoute: elfinder
filebrowserBrowseRouteParameters: []
The test case extends Symfonys' TypeTestCase which creates its' own factory. This probably is the cause. However I don't know how to force this factory to provide the proper CKEditor instance. Does anybody know how to do it?
Problem solved with PreloadedExtension:
class ArticleTypeTest {
protected function getExtensions() {
return array(new PreloadedExtension(array($this->getCKEditor()), array()));
}
...
protected function getCKEditor() {
$configManager = $this->getMockBuilder ( ConfigManagerInterface::class )->disableOriginalConstructor ()->getMock ();
$pluginManager = $this->getMockBuilder ( PluginManagerInterface::class )->disableOriginalConstructor ()->getMock ();
$stylesSetManager = $this->getMockBuilder ( StylesSetManagerInterface::class )->disableOriginalConstructor ()->getMock ();
$templateManager = $this->getMockBuilder ( TemplateManagerInterface::class )->disableOriginalConstructor ()->getMock ();
$type = new CKEditorType($configManager, $pluginManager, $stylesSetManager, $templateManager);
return $type;
}
}
Related
I have an Entity named Page that can be a callToAction (boolean) and I would like to display the Page Entity with callToAction == false on one subMenu and the Page Entity with callToAction == true on another subMenu. I have a CRUD for the Page Entity. So the Dashboard would be something like that:
MenuItem::subMenu('Page', 'far fa-file-alt')->setSubItems([
MenuItem::linkToCrud('Page', 'fa fa-alt', Page::class),
MenuItem::linkToCrud('Call To Action', 'fa fa-file-alt', Page::class),
])
But I don't know where to put the dql to display the entities I want (callToAction true or false) and I don't even know if it's possible, but I know it was with Easy Admin 2, that's why I wonder.
I also would like that on the NEW Action, when you're on the Page with callToAction == true, when you create the new Entity Page from here, that the callToAction is set to true immediatly and the User doesn't even see the field. Still don't know if it's possible.
Thanks :)
EDIT: So i've found that I can use createIndexQueryBuilder() to display on the index exactly the entities, and it works well but I don't know how to call two different createIndexQueryBuilder depending of the subMenu we display. I tried doing a custom action and using createQueryBuilder but I don't have the params searchDto, etc:
public function configureActions(Actions $actions): Actions
{
$indexIsCallToAction = Action::new('indexIsCallToAction', 'Index Call To Action', 'fa fa-send')
->linkToCrudAction('indexIsCallToAction');
$actions->add(CRUD::PAGE_INDEX, $indexIsCallToAction);
return $actions;
//return parent::configureActions($actions); // TODO: Change the autogenerated stub
}
public function indexIsCallToAction(AdminContext $context,SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters){
$response = $this->get(EntityRepository::class)->createQueryBuilder($searchDto, $entityDto, $fields, $filters);
return $response;
}
So it doesn't work.
As a dashboard controller is an ordinary controller you can do something like this:
public function __construct(PageRepository $pageRepo)
{
$this->pageRepo = $pageRepo;
}
public function configureMenuItems(): iterable
{
$submenuItems = [];
if (null !== $pages = $this->pageRepo->findBy(["callToAction" => true ])) {
foreach ($pages as $page) {
$submenuItems[] = MenuItem::linkToCrud('Call To Action', 'fa fa-file-alt', Page::class);
}
}
yield MenuItem::subMenu('Page Submenu with callToAction', 'far fa-file-alt')->setSubItems($submenuItems);
$submenuItems = [];
if (null !== $pages = $this->pageRepo->findBy(["callToAction" => false ])) {
foreach ($pages as $page) {
$submenuItems[] = MenuItem::linkToCrud('Page', 'fa fa-alt', Page::class);
}
}
yield MenuItem::subMenu('Other Page Submenu', 'far fa-file-alt')->setSubItems($submenuItems);
}
I have this button and I'd like to make it so when I click on it, there's an ajax that goes directly into my create function in symfony but doesn't display any form (at this point I already have the informations I need). But I have no idea how to get the form that way.
I used to do
$livre = new Livre();
$livre->setUuid(Uuid::v4());
$form = $this->createForm(LivreType::class, $livre);
$form->handleRequest($request);
But obviously I can't use LivreType::class anymore cause I don't need the form.
I keep searching for information about this but I can't find anything
Any ideas?
You'll have multiple way of doing it.
I'm gonna show you a simple way to do it, and try to adapt or find a better way for doing it!
LivreController.php
/**
* #Route(path="/livre/create", methods={POST})
*/
public function createNewLivre(Request $request, EntityManagerInterface $em)
{
$json = $this->getJSON($request);
$newLivre = new Livre();
// Set to your new entity parameters...
$em->persist($newLivre);
$em->flush();
return $this->json([
'message' => 'A new Livre has been added.' // It could also be empty if you don't want to manage anything
]);
}
private function getJSON(Request $request)
{
$data = json_decode($request->getContent(), true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new HttpException(400, 'json invalid');
}
return $data;
}
script.js
let button = document.getElementById('livreCreatorButton');
button.addEventListener("click", e => {
e.preventDefault();
fetch('http://127.0.0.1:8000/livre/create', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: '{}',
})
});
I'm trying to write tests for a custom module I've written on Drupal 8 and keep getting an error and at this point I'm out of ideas. Here is the error:
Error: Class 'Drupal\mypackage\Services\Config\MyClassServiceConfig' not found
The PhpUnit class is under
modules\custom\mypackage\tests\src\Unit\mypackageUserAuthTest
Here is the code
class mypackageUserAuthTest extends UnitTestCase
{
protected $user;
protected $loginService;
public function setUp()
{
parent::setUp();
$this->loginService = new LoginService();
$this->user = [
'username' => 'xxx',
'password' => 'xxx',
'deviceId' => 'xxx',
'some-token' => 'xxx'
];
}
/** #test */
public function that_we_can_authenticate_a_user()
{
$IsUserLoggedIn = $this->loginService->login($this->user['username'], $this->user['password']);
$this->assertTrue($IsUserLoggedIn);
}
Now the method login in loginService code
<?php
namespace Drupal\mypackage\Rest;
use GuzzleHttp\Exception\ClientException;
use Drupal\mypackage\Services\RestServiceFactory;
use Drupal\mypackage\Services\Config\MyClassServiceConfig;
class LoginService
{
public function login($username, $password)
{
$configs = new MyClassServiceConfig(null, "mobile", "v1");
$client = RestServiceFactory::create($configs);
try {
$response = $client->post('login', [
'json' => [
'username' => $username,
'password' => $password,
'deviceId' => 'onepiece',
],
]);
return json_decode($response->getBody(), true);
} catch (ClientException $exception) {
switch ($$exception->getResponse()->getStatusCode()) {
case 402: // This only applies to co members
throw new SubscriptionRequiredException();
case 403:
throw new BlockedAccountException();
case 409:
throw new DuplicateEmailException();
case 410:
throw new PasswordDoesNotExistException();
}
throw $exception;
}
}
}
pwd result on MyClassServiceConfig class directory
/var/www/cms/web/modules/custom/mypackage/src/Services/Config
But it seems to fail on the line $configs = new MyClassServiceConfig(null, "mobile", "v1"); with the previously mentioned error :
1) Drupal\Tests\mypackage\Unit\mypackageUserAuthTest::that_we_can_authenticate_a_user
Error: Class 'Drupal\mypackage\Services\Config\MyClassServiceConfig' not found
Btw, I'm using drupal-project structure (https://github.com/drupal-composer/drupal-project)
So I spent days checking the path but it seemed that the files were not loading so I ended up adding the custom module to autload-dev part composer.json.
"autoload": {
"classmap": [
"scripts/composer/ScriptHandler.php"
],
"files": ["load.environment.php"]
},
"autoload-dev": {
"psr-4": { "Drupal\\mypackage\\": "web/modules/custom/mypackage" }
},
Now at least it seems to load the module as I'm getting an other error related to Drupal Container
\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
It is an old question, the same thing happened to me, as I managed to solve it in my case it was as follows:
In the comment of the class where the tests are carried out, something similar to this should go:
The #coversDefaultClass annotation must go with the namespace of the class to test.
/**
* #coversDefaultClass \Drupal\my_module\MyModuleClassName
* #group my_module
*/
class MyModuleCaseTest extends UnitTestCase {
}
Maybe it will serve someone else
I´m quite new to Angular 2 and I have a little Problem:
I load data from a service asynrochnus.
The data arrives in my component and i can handle with it.
Here i save the data in a local variable.
Here´s the code from the component:
export class ConfigurationComponent implements OnInit {
private tab: string = 'general';
private config = [];
constructor(private router: Router, private variables: Variables, private apiService: ApiService) {
if (!this.variables.getIsLoggedIn()) {
this.router.navigate(['login']);
}
}
ngOnInit() {
this.getConfigService();
}
getConfigService() {
this.apiService.getConfigService().
subscribe(
data => {
this.config = data.settings.section;
},
//error => this.error = <any>error,
error => this.variables.setFailure(error)
//() => console.log('done:' + this.status)
);
}
And here´s the code in html:
<th>{{config[5].entry.name}}</th>
<th>{{config[5].entry.text}}</th>
The problem is, that on the time when the view loads, the local variable 'config' is just '[]'. So the 'config[5]' fails.
But if i do not define the local variable in the component, it fails, too.
Can someone help me here?
Thanks!
You should push each of elements from data.settings.section into your config and check it does exist in view;
//in component
data.settings.section.forEach(i => this.config.push(i));
//in html
<div *ngIf="config[5]">
{{config[5].entry.name}}
</div>
I hope it helps!
I asked this on https://github.com/silexphp/Silex/issues/1442 but I have a feeling it isn't necessarily a code problem so I thought I would extend the reach.
upgrading to silex 2 and symfony 3 and all the rest...
routes are included at end of app.php and look something like this...
$app->get('/', 'queue.controller:indexAction')
->after(function (Request $request, Response $response, $app) {
$response->setPublic();
$response->setSharedMaxAge($app['cache']['s-maxage']);
})
->host($app['domains']['xxx'])
->bind('homepage');
this works great in a browser, goto homepage, works fine. If I am running phpunit though... I get the following error when trying to generate a route...
Symfony\Component\Routing\Exception\RouteNotFoundException: Unable to generate a URL for the named route "homepage" as such route does not exist.
and the test looks something like this...
public function testTargetingOnHomepage()
{
$client = $this->createClient();
echo $this->app->url('homepage');
.....
}
i am bewildered as to why my routes are not getting added to app when being executed from phpunit.
test case class has ...
class AdTargetControllerTest extends SomeWebTestCase
and that somewebtestcase.php looks like ...
<?php
namespace theapp\SomeFramework;
use Silex\WebTestCase;
use Fixtures\UserFixture;
use Symfony\Component\BrowserKit\Client;
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
class SomeWebTestCase extends WebTestCase
{
public $youtubeEmbed;
private $mockSessionDir;
public function createApplication()
{
$appDir = __DIR__.'/../../..';
$app = include "$appDir/app.php";
$app['debug'] = true;
$app['session.test'] = true;
$this->mockSessionDir = $app['tmpdir']. '/mocksessions';
$app['session.storage.test'] = function ($app) {
return new MockFileSessionStorage($app['tmpdir']. '/mocksessions');
};
unset($app['exception_handler']);
// Emails get stored in the mail "logger" ... not delivered.
$app['mailer.logger'] = function ($app) {
return new \Someecards\SomeFramework\MessageLogger();
};
// Force silex to use transport and not spooltransport
$app['swiftmailer.use_spool'] = false;
$app["swiftmailer.transport"] = function ($app) {
return new \Swift_Transport_NullTransport($app['swiftmailer.transport.eventdispatcher']);
};
$app->extend('mailer', function ($mailer, $app) {
$mailer->registerPlugin($app['mailer.logger']);
return $mailer;
});
$this->youtubeEmbed = '<iframe width="480" height="270" src="https://www.youtube.com/embed/';
$this->youtubeEmbed .= 'LDtHJYa6xu4?feature=oembed" frameborder="0" allowfullscreen></iframe>';
// using Mockery since this library uses a static method for create
$app['oembedMock'] = \Mockery::mock('alias:Embed\Embed');
$app['oembedMock']
->shouldReceive('create')
->andReturn(
(object) array(
'title' => 'Oembed title',
'description' => 'Oembed Description',
'providerName' => 'YouTube',
'code' => $this->youtubeEmbed,
'type' => 'video',
'author' => 'test',
'authorUrl' => 'test',
'width' => 500,
'height' => 500,
'image' => 'test',
'imageWidth' => 500,
'imageHeight' => 500
)
);
$app->boot();
return $app;
}
there are other functions here but thats the important one i believe.
phpunit bootstraps with ...
<?php
use theapp\SomeFramework\TestingUtil;
// autoload libraries
require_once __DIR__.'/../thirdparty/vendor/autoload.php';
TestingUtil::init();
and then testingutil.php looks like ...
namespace Someecards\SomeFramework;
class TestingUtil
{
public static function init()
{
// This if/else allows the phpunit processIsolation flag to be set to true.
// We're not currently doing that because it slows things down three fold.
// If you see errors about too many open connections/files you can run
// ulimit -n 10000, try to close db connections and log files (couldn't fclose
// these in tearDowns for some reason), or turn on processIsolation.
if (!defined('PHPUNIT_HAS_BOOTSTRAPED')) {
self::bootstrap();
define('PHPUNIT_HAS_BOOTSTRAPED', true);
}
}
public static function bootstrap()
{
$app = require __DIR__.'/../../../app.php';
$app->boot();
$dbOptions = $app['db.options'];
if ($dbOptions['driver'] == 'pdo_sqlite') {
$testdb = $dbOptions['path'];
if (file_exists($testdb)) {
#unlink($testdb);
}
$cacheDriver = $app['orm.em']->getConfiguration()->getMetadataCacheImpl();
$cacheDriver->deleteAll();
$cacheDriver = $app['orm.em']->getConfiguration()->getResultCacheImpl();
$cacheDriver->deleteAll();
$cacheDriver = $app['orm.em']->getConfiguration()->getQueryCacheImpl();
$cacheDriver->deleteAll();
$tool = new \Doctrine\ORM\Tools\SchemaTool($app['orm.em']);
$classes = $app['orm.em']->getMetadataFactory()->getAllMetadata();
$tool->createSchema($classes);
$loader = new \Doctrine\Common\DataFixtures\Loader();
$loader->loadFromDirectory(__DIR__ ."/../../Fixtures");
$purger = new \Doctrine\Common\DataFixtures\Purger\ORMPurger();
$executor = new \Doctrine\Common\DataFixtures\Executor\ORMExecutor($app['orm.em'], $purger);
$executor->execute($loader->getFixtures());
}
register_shutdown_function(
function ($app) {
$path = $app['orm.default_cache']['path'];
if (is_dir($path) === true) {
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
if (in_array($file->getBasename(), array('.', '..')) !== true) {
if ($file->isDir() === true) {
rmdir($file->getPathName());
} elseif (($file->isFile() === true) || ($file->isLink() === true)) {
unlink($file->getPathname());
}
}
}
rmdir($path);
} elseif ((is_file($path) === true) || (is_link($path) === true)) {
return unlink($path);
}
},
$app
);
}
}