TYPO3 4.5 extbase test backend module - unit-testing

I search for a way to test my extbase-extension. I work with two different templatepaths for front- and backend.
module.myext{
view {
templateRootPath = myext/Resources/Private/Backend/Templates/
partialRootPath = myext/Resources/Private/Backend/Partials/
layoutRootPath = myext/Resources/Private/Backend/Layouts/
}
}
The backendmodule works without any problem, but my test will not get the different templatepath. If i write the view.templateRootPath to config.tx_extbase in the ext_typoscript_setup.txt it works, but in this case all my frontendtests do not work any more. The simplest way to resolve this issue is to merge the templatepaths and work with only one, but there must be a way around this solution.
Does somebody has an idea?

Did you statically include the extension setup in your root page?
Then the backend module should work as long as you include it in the web tools and select the root page in the page-tree...
If you include your module in the user tools, this is a known bug. See here:
http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2011-December/011174.html
You could put this code in your *ext_localconf.php*:
if (TYPO3_MODE === 'BE') {
t3lib_extMgm::addTypoScript($_EXTKEY, 'constants', $tsIncludeConstants);
t3lib_extMgm::addTypoScript($_EXTKEY, 'setup', $tsIncludeSetup);
}
where $tsIncludeXXis your TS code to include the configuration files of your extension:
$tsIncludeConstants = "<INCLUDE_TYPOSCRIPT: source=FILE:EXT:$_EXTKEY/Configuration/TypoScript/constants.txt>";
$tsIncludeSetup = "<INCLUDE_TYPOSCRIPT: source=FILE:EXT:$_EXTKEY/Configuration/TypoScript/setup.txt>";
This is kind of brute force, but it works...

Related

In-repo addon writing public files on build causes endless build loop on serve

I'm having difficulty with my in-repo addon writing to appDir/public. What I'd like to do is write out a JSON file on each build to be included in the app /dist. The problem I'm running into is when running "ember serve", the file watcher detects the new file and rebuilds again, causing an endless loop.
I've tried writing the JSON file using preBuild() and postBuild() hooks, saving to /public, but after build, the watcher detects it and rebuild over and over, writing a new file again each time. I also tried using my-addon/public folder and writing to that, same thing.
The only thing that partially works is writing on init(), which is fine, except I don't see the changes using ember serve.
I did try using the treeForPublic() method, but did not get any further. I can write the file and use treeForPublic(). This only runs once though, on initial build. It partially solves my problem, because I get the files into app dist folder. But I don't think ember serve will re-run treeForPublic on subsequent file change in the app.
Is there a way to ignore specific files from file watch? Yet still allow files to include into the build? Maybe there's an exclude watch property in ember-cli-build?
Here's my treeForPublic() , but I'm guessing my problems aren't here:
treeForPublic: function() {
const publicTree = this._super.treeForPublic.apply(this, arguments);
const trees = [];
if (publicTree) {
trees.push(publicTree);
}
// this writes out the json
this.saveSettingsFile(this.pubSettingsFile, this.settings);
trees.push(new Funnel(this.addonPubDataPath, {
include: [this.pubSettingsFileName],
destDir: '/data'
}));
return mergeTrees(trees);
},
UPDATE 05/20/2019
I should probably make a new question at this point...
My goal here is to create an auto-increment build number that updates both on ember build and ember serve. My comments under #real_ates's answer below help explain why. In the end, if I can only use this on build, that's totally ok.
The answer from #real_ate was very helpful and solved the endless loop problem, but it doesn't run on ember serve. Maybe this just can't be done, but I'd really like to know either way. I'm currently trying to change environment variables instead of using treeforPublic(). I've asked that as a separate question about addon config() updates to Ember environment:
Updating Ember.js environment variables do not take effect using in-repo addon config() method on ember serve
I don't know if can mark #real_ate's answer as the accepted solution because it doesn't work on ember serve. It was extremely helpful and educational!
This is a great question, and it's often something that people can be a bit confused about when working with broccoli (I know for sure that I've been stung by this in the past)
The issue that you have is that your treeForPublic() is actually writing a file to the source directory and then you're using broccoli-funnel to select that new custom file and include it in the build. The correct method to do this is instead to use broccoli-file-creator to create an output tree that includes your new file. I'll go into more detail with an example below:
treeForPublic: function() {
const publicTree = this._super.treeForPublic.apply(this, arguments);
const trees = [];
if (publicTree) {
trees.push(publicTree);
}
let data = getSettingsData(this.settings);
trees.push(writeFile('/data/the-settings-file.json', JSON.stringify(data)));
return mergeTrees(trees);
}
As you will see the most of the code is exactly the same as your example. The two main differences are that instead of having a function this.saveSettingsFile() that writes out a settings file on disk we now have a function this.getSettingsData() that returns the content that we would like to see in the newly created file. Here is the simple example that we came up with when we were testing this out:
function getSettingsData() {
return {
setting1: 'face',
setting2: 'my',
}
}
you can edit this function to take whatever parameters you need it to and have whatever functionality you would like.
The next major difference is that we are using the writeFile() function which is actually just the broccoli-file-creator plugin. Here is the import that you would put at the top of the file:
let writeFile = require('broccoli-file-creator');
Now when you run your application it won't be writing to the source directory any more which means it will stop constantly reloading 🎉
This question was answered as part of "May I Ask a Question" Season 2 Episode 2. If you would like to see us discuss this answer in full you can check out the video here: https://youtu.be/9kMGMK9Ur4E

Extension doesn't get enabled

I'm migrating extension for Opencart 2.3 to Opencart 3. Everything seems to work fine, except that I can't enable the extension. When I go to extension->shipping the status doesn't change it stays disabled, however if I go to settings, the drop down shows that enabled is selected. There aren't any errors on the front-end, or in the log files. I tried debugging but everything seems fine. Any ideas what may be wrong? Also the setting in the database(extensionName_status) is 1
Note: the extension is large, and it will be too much if I post it here. If you need specific fragment of code, I will provide it.
The tricky thing about the 2.3->3.0 migration was that some variable names changed in a subtle way (as noted in my comment above). The status variable could be your problem. Here's Better Together 3.0 (left) vs 2.3 (right) in the controller file:
< $data['total_better_together_status'] = $this->config->get('total_better_together_status');
---
> $data['better_together_status'] = $this->config->get('better_together_status');
If your OpenCart 3.x module is labeled in the Modules category, then:
if (isset($this->request->post['module_mymodule_status'])) {
$data['module_mymodule_status'] = $this->request->post['module_mymodule_status'];
} else {
$data['module_mymodule_status'] = $this->config->get('module_mymodule_status');
}
Or if it's labeled in the Analytics category, then you just change the module to analytics as shown below:
if (isset($this->request->post['analytics_mymodule_status'])) {
$data['analytics_mymodule_status'] = $this->request->post['analytics_mymodule_status'];
} else {
$data['analytics_mymodule_status'] = $this->config->get('analytics_mymodule_status');
}

Including specific style sheets or javascript in ember-cli-build

The problem
I am working on an Ember.js project which has different versions (products) for different clients. Though the functionality is more or less the same, the styling of each product differs big time. Hence we have "default" and product specific style sheets. I have been asked to modify the build code so that only the corresponding .css (.less) files are compiled into the final app.
Originally I was looking at this issue from the wrong side: I tried to exclude the folders containing the unnecessary files with little success. Only then did I realize that it makes more sense not to include the product specific files by default and add them to the tree during the build.
The solution
After changing my point of view I found out there is another way around. I changed the style sheets so that all the "default looks" went into an import-base.less and I created an import-[name_of_product].less for each of the products, with the latters containing the import statement to the default looks, so I only have one file to build. Using the outputPaths option in EmberApp and assuming that the name of the product is stored in the process environmental variable called FLAVOUR my code looks as follows.
// ember-cli-build.js
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
// y u do dis
const options = { outputPaths: { app: { css: { app: false } } } };
const lessFileName = 'import-' + process.env.FLAVOUR.toLowerCase();
options.outputPaths.app.css[lessFileName] = 'assets/application.css'
const app = new EmberApp(defaults, options);
return app.toTree();
};
There is always something
The only problem with that code is that it still needs an app.less and that line of code or else the build fails, couldn't (haven't had time to) figure out a solution.
I also have to mention that the above solution doesn't resolve the original problem, which was:
How to exclude specific files from the working directory before using app.toTree() so that they wouldn't increase file size unnecessarily. Lux was so kind and pointed out that probably in-repo-addons are to be used for such purposes. Yet again, haven't had time to check. :(
I think you can just use funnel!
something like this:
return new Funnel(app.toTree(), {
include: ['**/*']
exclude: ['styles/*.css']
});
general you can do anything you can do in a Brocfile in your ember-cli-build.js!

using phpunit without composer

I'm trying to instal PHPunit on an old system,
I'm dealing with several phar issues,
from now i've managed to have PHPunit running, to have my autoload working, also the pPHPunit, but now, it is trying to call composer.
i Had to add an extention "PHPUnit/Extensions/Story", it's also working, but now, i've got to manage composer...
I tried to add the phar, to extract the phar , ... but nothing seems to work (if "Composer\Autoload\ClassLoader.php" work, then I've got an "Instantiator\Instantiator.php" missing...)
So, is it possible to have PHPunit running without composer?
I juste solved the problem :
despite I called "spl_autoload_register" for my own framework afeter including PHPunit and Composer"s ones, mine was sometimes called before, so I juste added a whitelisting in my autoloader (see $tabLibCommunPrefixes):
function phpunit_bootstrap_autoload($class_name) {
$prefixe = substr($class_name, 0, strpos($class_name, '_'));
$tabLibCommunPrefixes = array('Smarty', 'Zend', 'Bvb', 'Composer', 'domxml-php4-compat', 'FirePhp', 'Mobile', 'Nusoap', 'Pear', 'phing', 'PhpMailer', 'phpThumb', 'Sitra', 'Smarty3', 'smarty', 'test', 'upload', );
if (in_array($prefixe, $tabLibCommunPrefixes)) {
require_once str_replace('_', '/', $class_name) . '.php';
return true;
}
return false;
}
One can simply use composer to handle only PHPunit and it's dependencies.
So the easiest way is to simply use composer. There is nothing wrong at using composer for just a small part of your dependencies. In fact, for some (small) projects I even use it for no dependency at all (only to handle the autoloading).
You can use it in the subdirectory test, or more conventionally at the root of the project.

Using hogan.js with express.js + vhosts

What is the correct way to use hogan.js with express.js?
I've tried the following:
var hogan = require('hogan.js')
...
app.set('view engine', 'hogan');
followed by
app.register('.hogan', hogan);
But I end up with the following error:
500 Error: Cannot find module 'hogan'
TJ put out a library called consolidate.js ( https://github.com/visionmedia/consolidate.js ) but I'm having trouble getting it to work with Express 2.5.8. After spending the day trying to figure this out I also came across a library called hulk-hogan.js ( https://github.com/quangv/hulk-hogan ) and another called hogan-express ( http://allampersandall.blogspot.com/2011/12/hoganjs-expressjs-nodejs.html ). But, do I really need all that?
If the solution can not be as simple as setting the templating engine with app.set() and app.register(), it would be great if someone could help me understand why. I'm using Hogan on the client and it's working great, it would just be so much better if I could also use it on the server.
UPDATE: Turns out there are two issues here.
While this is not causing the 500 error, Express does not work with Hogan out of the box (see: Linus G Thiel's answer below)
What seems to be causing the 500 error is that I'm using a virtual host and when I call res.render(), my res.render() call is actually calling the res.render() of a different virtual host on my same server.
Adding the full Express error dump. It looks like my app ('dataviz') is trying to use the render call from a different app ('datavizblocks')? Again, the two apps are virtual hosts on the same server.
dataviz 8000
Error: Cannot find module 'hogan.js'
at Function._resolveFilename (module.js:332:11)
at Function._load (module.js:279:25)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at View.templateEngine (/localhost/datavizblocks/node_modules/express/lib/view/view.js:134:38)
at Function.compile (/localhost/datavizblocks/node_modules/express/lib/view.js:68:17)
at ServerResponse._render (/localhost/datavizblocks/node_modules/express/lib/view.js:417:18)
at ServerResponse.render (/localhost/datavizblocks/node_modules/express/lib/view.js:318:17)
at /localhost/dataviz/routes/section.js:325:7
at callbacks (/localhost/dataviz/node_modules/express/lib/router/index.js:272:11)
dataviz 8000
Error: Cannot find module 'hogan.js'
at Function._resolveFilename (module.js:332:11)
at Function._load (module.js:279:25)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at View.templateEngine (/localhost/datavizblocks/node_modules/express/lib/view/view.js:134:38)
at Function.compile (/localhost/datavizblocks/node_modules/express/lib/view.js:68:17)
at ServerResponse._render (/localhost/datavizblocks/node_modules/express/lib/view.js:417:18)
at ServerResponse.render (/localhost/datavizblocks/node_modules/express/lib/view.js:318:17)
at /localhost/dataviz/routes/section.js:325:7
at callbacks (/localhost/dataviz/node_modules/express/lib/router/index.js:272:11)
The 500 error goes away when I comment out the datavizblock vhost, or when I switch the order of the vhost declarations around to have the dataviz vhost declared after datavizblocks vhost (of course, this then causes problems for the datavizblocks vhost)
Apologies ahead of time for the confusing question, but I was really confused when I came across this issue and never expected that switching to Hogan would have conflicts with virtual hosting.
The issue is that Express requires an interface from template engines, where the template engine is expected to have a compile method, and that compile method is expected to return a function which can be called with the template data.
Hogan has a compile method, but it returns a template object which has a render method. You need to expose that render method to Express, and this seems to be what the hogan-express module does. It shouldn't have to be that involved though, I think this will work (I have only tested it slightly, might be some gotchas?):
var express = require('express'),
hogan = require('hogan.js'),
app = express.createServer();
app.set('view engine', 'hogan');
app.register('hogan', {
compile: function() {
var t = hogan.compile.apply(hogan, arguments);
return function() {
return t.render.apply(t, arguments);
}
}
});
Basically, we are just creating our own object that has a compile method that maps to Hogan's render method.
This expects your templates to be named e.g. index.hogan.
As Linus said, you need an adapter to use Hogan with Express. consolidate works fine as long as you don't need support for partials or layouts (they are working on it but I don't know when it will be ready).
I was in the same spot you're in a few months ago and found hulk-hogan's and express-hogan's documentations to be quite confusing so I coded my own wrapper that has support for partials, layouts, template caching and can be plugged in Express in one line of code. You can check it out here: h4e - templating with hogan for express