Jest global variables with require modules - testing

I'm working on some test for a very small vanilla js library, so I have this module
var otherModule = require('../module/mymodule');
var postscribe = require('postscribe');
var exports = module.exports = {};
var API_URL = URL;
exports.myFunction = function (arg1, arg2, arg3) {
if (arg1 && arg2) {
var myUrl = getApiUrl(arg1, arg2, arg3);
callSomeURL(myUrl);
}
}
function getApiUrl(arg1, arg2, arg3) {
var param1 = otherModule.getParams(arg1);
var param2 = otherModule.getOtherParams(arg1);
return `${API_URL}/v1/pixels/${arg1}/${arg2}${param1}${param2}`;
}
...
then I have otherModule module with my functions
var GLOBAL_VALUE = MY_VALUE;
var otherModule = {};
otherModule.getParams = function (arg1) {
return arg1 ? `&value=${arg1}` : '';
}
otherModule.getOtherParams = function (arg1) {
return GLOBAL_VALUE + arg1
}
module.exports = otherModule;
And my webpack configs
const { DefinePlugin } = require('webpack');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const devConfig = require('./src/config/dev');
module.exports = () => {
var envConfig = devConfig;
return merge(common, {
mode: 'development',
devtool: 'inline-source-map',
plugins: [
new DefinePlugin({
__DEV__: true,
URL: JSON.stringify(envConfig.URL),
MY_VALUE: JSON.stringify(envConfig.VALUE)
})
]
})
}
my common is:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
plugins: [
new CleanWebpackPlugin()
],
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
And my jest.config
const config = require('./src/config/dev');
module.exports = {
globals: {
"MY_VALUE": config.VALUE,
"URL" : config.URL
}
}
my problem appears when I try to test exports.myFunction via rewire to have access to private function getApiUrl it seems that I can't access to the imported global values, like GLOBAL_VALUE
in my myOther, I keep getting ReferenceError: GLOBAL_VALUE is not defined, but when I test myOther module directly everything seems to work, can someone throw some light or resources on what I'm doing wrong?

Related

webpack with express-handlebars

I'm trying to migrate an old express site to webpack, but don't wanna rework all the layout tempaltes which use express-handlebars. Is it possible to use express-handlebars with webpack?
handlebars-loader seems not to support the layout concept of express-handlebars, so is no help here.
A custom loader seems to do the trick:
express-handlebars-loader.js:
const loaderUtils = require('loader-utils');
const validateOptions = require('schema-utils');
const path = require('path');
const express = require('express');
const exphbs = require('express-handlebars');
module.exports = function (content) {
const options = loaderUtils.getOptions(this);
const app = options.app;
const contextCallback = options.contextCallback;
const view = path.relative(options.basePath, this.resourcePath);
const context = contextCallback(this.resourcePath, view);
var loaderAsyncCallback = this.async();
app.render(view, context, function (err, html) {
if (err) {
return loaderAsyncCallback(err);
}
const slug =
'// Module\n'
+ 'var code = ' + JSON.stringify(html) + ';\n'
+ '// Exports\n'
+ 'module.exports = code;'
loaderAsyncCallback(null, slug);
});
};
webpack.config.js:
const CopyPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const fs = require('fs');
const url = require('url');
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
// Handlebars Setup
/**
* Instantiate a Handlebars instance with our config (default layout, helpers, etc.)
*/
const handlebasInstance = exphbs.create({
defaultLayout: 'mainLayout',
// Specify helpers which are only registered on this instance.
helpers
});
app.engine('handlebars', handlebasInstance.engine);
app.set('view engine', 'handlebars');
app.use('/assets', express.static('assets'));
const basePath = path.resolve(__dirname, './views');
function generateHtmlPlugins(templateDir) {
const itemList = fs.readdirSync(templateDir);
return itemList.flatMap(item => {
const [ name, extension ] = item.split('.');
if (extension == 'handlebars') {
const templatePath = path.resolve(templateDir, item);
const outputPath = path.resolve(templateDir, name + '.html');
const outputName = path.relative(basePath, outputPath);
return new HtmlWebpackPlugin({
filename: outputName,
inject: false,
template: templatePath
})
} else {
return [];
}
})
}
const siteHtmlPlugins = generateHtmlPlugins(basePath);
function contextCallback(resourcePath, view) {
var context = {};
if (view.includes('documentation/')) {
context.layout = 'documentationLayout';
}
return context;
}
module.exports = {
mode: 'development',
resolveLoader: {
modules: [ 'node_modules', path.resolve(__dirname, 'loaders') ]
},
entry: './src/entry-workaround.js',
output: {
filename: 'entry-workaround.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [{
test: /\.handlebars$/,
loader: "express-handlebars-loader",
options: {
app: app,
basePath: basePath,
contextCallback: contextCallback,
}
}]
},
plugins: []
};

Testing a cloudflare worker with HTMLRewriter fails as its undefined

I have a test to test my cloudflare worker that looks like this:
const workerScript = fs.readFileSync(
path.resolve(__dirname, '../pkg-prd/worker.js'),
'utf8'
);
describe('worker unit test', function () {
// this.timeout(60000);
let worker;
beforeEach(() => {
worker = new Cloudworker(workerScript, {
bindings: {
HTMLRewriter
},
});
});
it('tests requests and responses', async () => {
const request = new Cloudworker.Request('https://www.example.com/pathname')
const response = await worker.dispatch(request);
console.log(response);
// const body = await response.json();
expect(response.status).to.eql(200);
// expect(body).to.eql({message: 'Hello mocha!'});
});
});
In my worker I do something like this:
const response = await fetch(BASE_URL, request);
const modifiedResponse = new Response(response.body, response);
// Remove the webflow badge
class ElementHandler {
element(element) {
element.append('<style type="text/css">body .w-webflow-badge {display: none!important}</style>', {html: true})
}
}
console.log(3);
return new HTMLRewriter()
.on('head', new ElementHandler()).transform(modifiedResponse);
Now when i run my test I get this error message:
● worker unit test › tests requests and responses
TypeError: Cannot read property 'transform' of undefined
at evalmachine.<anonymous>:1:1364
at FetchEvent.respondWith (node_modules/#dollarshaveclub/cloudworker/lib/cloudworker.js:39:17)
What seems to be wrong?
HTMLRewriter i created looks like this:
function HTMLRewriter() {
const elementHandler = {};
const on = (selector, handler) => {
if (handler && handler.element) {
if (!elementHandler[selector]) {
elementHandler[selector] = [];
}
elementHandler[selector].push(handler.element.bind(handler));
}
};
const transform = async response => {
const tempResponse = response.clone();
const doc = HTMLParser.parse(await tempResponse.text());
Object.keys(elementHandler).forEach(selector => {
const el = doc.querySelector(selector);
if (el) {
elementHandler[selector].map(callback => {
callback(new _Element(el));
});
}
});
return new Response(doc.toString(), response);
};
return {
on,
transform
};
}
Since HTMLRewriter() is called with new, the function needs to be a constructor. In JavaScript, a constructor function should set properties on this and should not return a value. But, your function is written to return a value.
So, try changing this:
return {
on,
transform
};
To this:
this.on = on;
this.transform = transform;

Import sequelize model in vuejs

I'm building a CRUD app using electron + vuejs + sequelize, i have used sequelize init and configured the .sequelizerc as below
const path = require('path');
module.exports = {
'config': path.resolve('src/renderer/database/config', 'config.json'),
'models-path': path.resolve('src/renderer/database', 'models'),
'seeders-path': path.resolve('src/renderer/database', 'seeders'),
'migrations-path': path.resolve('src/renderer/database', 'migrations')
}
Now i'm trying to populate a table with data from the database, I've tried to import the models in many ways, always leading to errors.
Error: Uncaught TypeError: Path must be a string. Received undefined
Component:
var models = require('./../../database/models'); // LINE WITH ERROR
export default {
name: "user-index",
data: function() {
return {
users: []
};
},
created: function() {
models.Users.findAll().then(users => {
//
});
},
components: {},
methods: {}
};
Thanks.
EDIT:
I found the problem, it is in the models/index.js:
'use strict';
var fs = require('fs');
var path = require('path');
var Sequelize = require('sequelize');
var basename = path.basename(__filename);
var env = process.env.NODE_ENV || 'development';
var config = require(__dirname + '/../config/config.json')[env];
var db = {};
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
var model = sequelize['import'](path.join(__dirname, file)); // THIS LINE
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
I fixed by changing path.join to path.resolve and changing this:
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
to
for (var modelName in db) {
if (db[modelName].associate) {
db[modelName].associate(db);
}
}
in models/index.js file.

TypeError: instance.web.core is undefined

I can not add new action in Odoo9
openerp.pr_finance = function(instance, local) {
var _t = instance.web._t, _lt = instance.web._lt;
var QWeb = instance.web.qweb;
var Widget = instance.web.Widget;
var core = instance.web.core;
var data = instance.web.data;
var session = instance.web.session;
var utils = instance.web.utils;
var Model = instance.web.Model;
var ControlPanelMixin = instance.web.ControlPanelMixin;
instance.web.ListView.include({
init: function() {
//console.log('JS loaded');
this._super.apply(this, arguments);
},
render_buttons: function(data) {
console.log('JS loaded load_list');
console.log(data);
this._super(data);
if (this.$buttons) {
this.$buttons.find('.oe_my_button').click(this.proxy('do_import_file_csv_ya_tz')) ;
}
},
do_import_file_csv_ya_tz: function () {
console.log('123123123123123123 ooops....');
this.do_action(
{
name: _t("IMPORT MY FILE"),
type: "ir.actions.client",
tag: 'import_csv',
params: {}
}
);
}
});
var import_csv_yandex = Widget.extend({
template: 'ImportViewYaTC',
start: function () {
console.log("ImportViewYandexTC page loaded");
},
});
var DataImport = Widget.extend(ControlPanelMixin, {
template: 'ImportView',
init: function(parent, action) {
console.log("init ImportView");
this._super.apply(this, arguments);
action.display_name = _t('Import a File');
},
start: function () {
console.log("ImportView page loaded");
},
});
console.log("core.action_registry.add");
try {
instance.web.core.action_registry.add('import_csv', DataImport);
} catch (err) {
console.log(err);
}
console.log("core.action_registry.add - OK!");
}
I received error here:
instance.web.core.action_registry.add('import_csv', DataImport);
Error:
TypeError: instance.web.core is undefined Stack trace:
openerp.pr_finance#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:4579:1276
start_modules#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:3235:1
.init#http//localhost:8069/web/content/2798-e13ba1c/web.assets_backend.js:3229:3951
OdooClass.extend/Class.include/
Why this variable is undefined?
You need to use require to get the variables of the env: ie.
odoo.define('yourmodulename.pr_finance', function (require) {
"use strict";
var core = require('web.core');
});
a good place to look at to understand inheritance in odoo is the github.com/oca/web repo.

Issues testing hapijs plugin

Here's my test
'use strict';
var assert = require('assert');
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var Lab = require('lab');
var lab = exports.lab = Lab.script();
lab.experiment("src.mysql", function () {
var server = {
settings: {
app: {
mysql: {
connectionLimit: 10,
host: "none",
user: "me",
password: "nope",
database: "db"
}
}
},
expose: sinon.stub()
};
var mysql = sinon.stub();
var next = sinon.stub();
var plugin = proxyquire('../../src/mysql', {
mysql: mysql
});
lab.test("successful loads", function(done) {
plugin.register(server, {}, next, function(err) {
assert(err === 'hello');
});
done();
});
});
I'm not getting an error, but the test is passing, which is a false positive. Not sure what I am doing wrong
The latest version of hapi 8.x.x uses a new method for loading plugins, you should call server.register with arguments described here http://hapijs.com/api#serverregisterplugins-options-callback.