I am trying to find out how to write a server-unit-test with jasmine.
This is what I have so far:
/both/posts.coffee
#Posts = new Mongo.Collection('posts');
class #Post extends Minimongoid
#_collection: #Posts
#defaults:
title: ''
validate: ->
unless #title.length > 5
#error('title', 'Title is required and should be longer than 5 letters.')
/tests/server/unit/posts/spec/postSpec.coffee
describe 'Post', ->
post = undefined
beforeEach ->
post = new Post()
describe 'fields', ->
it 'should be able to assign title with strings', ->
title = "The Title"
post.title = title
expect(post.title).toBe title
server console:
(STDERR) [sanjo:jasmine]: The code has syntax errors. [ReferenceError: Minimongoid is not defined]
What is wrong there? How can I get this simple test passed?
I've got it working when I moved the whole content of the UNIT-Test to the INTEGRATION-Test folder and prepended the code with
/tests/server/integration/posts/spec/postSpec.coffee
Jasmine.onTest ->
# my code
Now is all green. Thank you #Marius Darila
Related
Despite carefully following the instructions on how to configure the Elastic Search Package to add Search functionality to my Meteor App, I keep getting this frustrating error message in my browser console:
details: undefined
error: "no-index"
errorType: "Meteor.Error"
isClientSafe: true
message: "Please provide an index for your component [no-index]"
reason: "Please provide an index for your component"
stack: "Error: Please provide an index for your component [no-index]
Following is my code:
../imports/api/tasks.js
import { Mongo } from "meteor/mongo";
import { Index, MinimongoEngine } from 'meteor/easy:search';
global.recipientsDetails = new Mongo.Collection("recipients");
global.recipientsDetailsIndex = new Index({
collection: recipientsDetails,
fields: ['recipientNumber', 'recipientAmount'],
engine: new MinimongoEngine(),
})
../client/main.js
import '../imports/api/tasks.js';
Template.navigationMenu.helpers({
enableButtonSearchResults: () => recipientsDetailsIndex,
});
../client/main.html
<template name="navigationMenu">
{{#EasySearch.Each index=recipientsDetailsIndex}}
<ul>
{{#EasySearch.Each index=recipientsDetailsIndex }}
<li>Recipients Number: {{recipientNumber}}</li>
{{/EasySearch.Each}}
</ul>
</template>
What I find strange is that, when I feed in the following code in my browser console:
var cursor = recipientsDetailsIndex.search("705087688");
// search all docs that contain "705087633" in the recipientNumber field.
console.log(cursor.fetch());
The following yeilds in the browser console:
[{…}]
0:
paymentDate: "2019-04-08 23:20:01"
recipientAmount: "110"
recipientNumber: "+254705087688"
_id: "Wo4oZNzs5fLTqadcn"
The above results suggest that the Elastic search package is working and the fault is in the template, though I might be wrong.
Kindly help point out what I have missed or got wrong in the template or elsewhere...
Wild guess here: But the http://matteodem.github.io/meteor-easy-search/docs/engines/ mention that there is a Elastic Search Engine and in your tasks file you use MiniMongoEngine...
I'm trying to get WordPress website title using javascript and WP API plugin
I didn't find any example on how to get the site's name but I found the variable name under the entities section in the developer guide
function _updateTitle(documentTitle) {
document.querySelector('title').innerHTML =
documentTitle + ' | '+ $http.get('wp-json/name');
}
The output string of $http.get('wp-json/name') is [object Object]
Does anyone know how to use fix this?
You didn't get enough context. What's $http? What happens when you go to wp-json/name directly in your browser? Here's what I see:
[{
"code":"json_no_route",
"message":"No route was found matching the URL and request method"
}]
Here's a simple example to get you the title:
var siteName;
$.getJSON( "/wp-json", function( data ) {
siteName = data.name;
});
See more elegant solution here https://wordpress.stackexchange.com/a/314767/94636
response will not contain extra data like:
authentication: []
namespaces: ["oembed/1.0", "akismet/v1", "acf/v3", "wp/v2"]
routes: {/: {namespace: "", methods: ["GET"],…},…}
timezone_string: ""
...
_links: {help: [{href: "http://v2.wp-api.org/"}]}
In the next phase of my Meteor journey (read: learning the ropes!), I'd like to implement a simple search based on user inputed values, then redirect to a route specific to the record returned from the server.
At the moment, I'm picking up the inputed values via this code:
Template.home.events 'submit form': (event, template) ->
event.preventDefault()
console.log 'form submitted!'
countryFirst = event.target.firstCountrySearch.value
countrySecond = event.target.secondCountrySearch.value
Session.set 'countryPairSearchInputs', [countryFirst, countrySecond]
countryPairSearchInputs = Session.get 'countryPairSearchInputs'
console.log(countryPairSearchInputs)
return Router.go('explore')
Happily, the console log returns the desired countryPairSearchInputs variable - an array of two ids. In my routes.coffee file I then have the following:
#route "explore",
path: "/explore/:_id"
waitOn: ->
Meteor.subscribe 'countryPairsSearch'
On the server side, I have:
Meteor.publish 'countryPairsSearch', getCountryPairsSearch
And finally, I have a search.coffee file in my /lib directory that defines the getCountryPairsSearch function:
#getCountryPairsSearch = ->
CountryPairs.findOne $and: [
{ country_a_id: $in: Session.get('countryPairSearchInputs') }
{ country_b_id: $in: Session.get('countryPairSearchInputs') }
]
With regards to the search function itself, I have a CountryPairs collection where each record has two ids (country_a_id and country_b_id) - the aim here is to allow users to input two countries, with the corresponding CountryPair then being returning.
I'm currently struggling to tie all the pieces together - the console output on searching is currently:
Uncaught Error: Missing required parameters on path "/explore/:_id". The missing params are: ["_id"]. The params object passed in was: undefined.
Any help would be greatly appreciated - as you can probably tell I'm new to Meteor and am still getting used to the pub/sub methodology!
Edited: mixed up client/server for the publish method when I first posted - the danger of late-night posting!
First, seems you're expecting an :id parameter on your 'explore' route.
If I understand you're case, you're not expecting any params here, so you can just delete ':id' from your route:
#route "explore",
path: "/explore/"
waitOn: ->
Meteor.subscribe 'countryPairsSearch'
or either add a params to your Router.go call:
Router.go('explore', {_id: yourIdVar});
Secondly, you're trying to use a client function: Session.get() server-side. Try to update the publication using a parameter ; or using a method.call.
client-side
Meteor.subscribe 'countryPairsSearch' countryA countryB
not sure about the coffeescript syntax, check http://docs.meteor.com/#/full/meteor_subscribe
and server-side
#getCountryPairsSearch = (countryA, countryB) ->
CountryPairs.findOne $and: [
{ country_a_id: $in: countryA }
{ country_b_id: $in: countryB }
]
I'm using Iron Router to pass data through to my templates:
#route 'singleProperty',
path: '/properties/:_id'
data: ->
Properties.findOne(#params._id)
controller: "SinglePropertyController"
And within my controller, I have my template waiting for the necessary collection to be published:
waitOn: ->
[
Meteor.subscribe "properties"
]
The issue that I am having is that when I try to access #data from within my helpers, it comes back as undefined:
Template.singleProperty.helpers
currentProperty: ->
console.log #data
That said, when I run the same console.log within a Template.rendered, I get the result that I would expect (the data object):
Template.singleProperty.rendered = ->
console.log #data
What do I need to change to be able to access data within a Template.helper?
Try this in your Template helper method:
Template.currentData()
Template.instance() is the key thing to read upon in the Meteor docs
hope this helps.
I was learning about unit testing and I attempted to resolve the following issue:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication
... using the only answer given at:
Simple ZF2 Unit Tests for a controller using ZfcUser
So my setUp function looks the same. Unfortunately, I get the error message:
Zend\Mvc\Exception\InvalidPluginException: Plugin of type Mock_ZfcUserAuthentication_868bf824 is invalid; must implement Zend\Mvc\Controller\Plugin\PluginInterface
It is caused at this part of the code (split up in my code in the same way):
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock); // Error refers to this line.
The $authMock object is apparently not implementing plugininterface, which I need to implement to pass into setService.
Is $authMock not meant to be passed there for it's use in unit testing? Should I be using a different (unit-testing oriented) setService method?
I need a way to handle logging into my application, or my unit testing is pointless.
Thanks for any advice.
=== Edit (11/02/2013) ===
I wanted to focus on this part for clarification, as I think this is the problem area:
// Getting mock of authentication object, which is used as a plugin.
$authMock = $this->getMock('ZfcUser\Controller\Plugin\ZfcUserAuthentication');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method('hasIdentity')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method('getIdentity')
-> will($this->returnValue($ZfcUserMock));
// At this point, PluginManager disallows mock being assigned as plugin because
// it will not implement plugin interface, as mentioned.
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
If the mock doesn't handle necessary implementations, how else am I to pretend to login?
You have a problem with name-spacing or your autoloader.
When you are creating your mock, the class definition of ZfcUser\Controller\Plugin\ZfcUserAuthentication is not being found. So PHPUnit creates a mock that only extends this class for your test. If the class was available then PHPUnit will use the actual class to extend when making its mock, which will then use the parent classes/interfaces.
You can see this logic here: https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/PHPUnit/Framework/MockObject/Generator.php
if (!class_exists($mockClassName['fullClassName'], $callAutoload) &&
!interface_exists($mockClassName['fullClassName'], $callAutoload)) {
$prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";
if (!empty($mockClassName['namespaceName'])) {
$prologue = 'namespace ' . $mockClassName['namespaceName'] .
" {\n\n" . $prologue . "}\n\n" .
"namespace {\n\n";
$epilogue = "\n\n}";
}
$cloneTemplate = new Text_Template(
$templateDir . 'mocked_clone.tpl'
);
So if there is no class or interface, PHPUnit will actually create one itself so that the mock will meet the type hinting of original class name. However, any parent classes or interfaces will not be included because PHPUnit is not aware of them.
This would be due to not including the proper namespace in your test or having a problem in your autoloader. It is difficult to tell without actually seeing the entire test file.
Alternatively rather than mocking ZfcUser\Controller\Plugin\ZfcUserAuthentication, you could mock the Zend\Mvc\Controller\Plugin\PluginInterface in your test and pass that into the plugin manager. Though if you are type-hinting for the plugin in your code, your test still won't work.
//Mock the plugin interface for checking authorization
$authMock = $this->getMock('Zend\Mvc\Controller\Plugin\PluginInterface');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method('hasIdentity')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method('getIdentity')
-> will($this->returnValue($ZfcUserMock));
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
I just made an example for the FlashMessenger plugin. You should just use the ControllerPluginManager to override the ControllerPlugin. Make sure that your application bootstrap calls setApplicationConfig();
<?php
namespace SimpleTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class SimpleControllerTest extends AbstractHttpControllerTestCase {
public function testControllerWillAddErrorMessageToFlashMessenger()
{
$flashMessengerMock = $this->getMockBuilder('\Zend\Mvc\Controller\Plugin\FlashMessenger', array('addErrorMessage'))->getMock();
$flashMessengerMock->expects($this->once())
->method('addErrorMessage')
->will($this->returnValue(array()));
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->get('ControllerPluginManager')->setService('flashMessenger', $flashMessengerMock);
$this->dispatch('/error/message');
}
}?>