Qunit assert throws not working - ember.js

I am trying to assert that a few steps in the code (visiting page, providing wrong card-number, password combination and clicking submit)should generate an error from the backend service - I have referred to this already..
and tried the suggestion of using Error Object as the second argument to assert.throws but that doesn't work for me.
i did see this link as well before posting my question,
My problem is - I don't have control over the code that throws the exception/error in this case. (I cannot change it to say Ember.assert etc) I just want to be able to catch an erroneous case.
Secondly, I don't have a component in this case. Its a straight forward API call that's made when click on submit is done, basically an action submitAuthForm is called in controller which calls ember cli mirage scenario that returns the following object problems object.
return new Response(401,{'X-Auth-Token': 'wrong-username-password-combination'},failResponse401);
and the returned object looks like
var failResponse401 = {
problems: [ {
field: null,
index: null,
value: null,
code: '0006',
subCode: '',
details: {},
_type: 'error'
} ]
};
We have a node_module dependency on an in-house exceptions kit that throws an Error object based on this.
Here's my Qunit test
test('ERROR_CASE_visiting /signon, provide cardNumber(2342314) and ' +
'password, submit and expect to see invalid cardnumber/password error',
function (assert) {
assert.expect(2);
assert.throws(
function () {
visit('/signon');
fillIn('#a8n-signon-card-number input', '2342314');
fillIn('#a8n-signon-password input', 'password');
click('#a8n-signon-submit-button button');
},
Error,
"Error Thrown"
);
});
I keep getting this error from Qunit
Error Thrown# 110 ms
Expected:
function Error( a ){
[code]
}
Result:
undefined
Diff:
function Error( a ){
[code]
}defined
Source:
at Object.<anonymous> (http://localhost:7357/assets/tests.js:175:12)
at runTest (http://localhost:7357/assets/test-support.js:3884:30)
at Test.run (http://localhost:7357/assets/test-support.js:3870:6)
at http://localhost:7357/assets/test-support.js:4076:12
at Object.advance (http://localhost:7357/assets/test-support.js:3529:26)
at begin (http://localhost:7357/assets/test-support.js:5341:20)
API rejected the request because of : []# 1634 ms
Expected:
true
Result:
false
Source:
Error: API rejected the request because of : []
at Class.init (http://localhost:7357/assets/vendor.js:172237:14)
at Class.superWrapper [as init] (http://localhost:7357/assets/vendor.js:55946:22)
at new Class (http://localhost:7357/assets/vendor.js:51657:19)
at Function._ClassMixinProps.create (http://localhost:7357/assets/vendor.js:51849:12)
at Function.createException (http://localhost:7357/assets/vendor.js:172664:16)
at Class.<anonymous> (http://localhost:7357/assets/vendor.js:133592:72)
at ComputedPropertyPrototype.get (http://localhost:7357/assets/vendor.js:32450:27)
at Object.get (http://localhost:7357/assets/vendor.js:37456:19)
at Class.get (http://localhost:7357/assets/vendor.js:50194:26)
at http://localhost:7357/assets/vendor.js:133645:30
Is there anything else that i can try to get it to work.
Is there someway i could somehow pass this test, by wrapping the returned response somehow in a way that it doesn't break my test altogether.

I found a workaround following this link
the user pablobm has posted a link to a helper
I used that to workaround this Qunit issue.

Related

Handling errors with Ember Data JSON-API adapter not working

I have a problem Handling errors using JSON-API, I done all steps like wrote in documentation but it's doesn't works.
I have model:
var user = this.get('store').createRecord('user', {
'email': 'test#test.com',
'name': 'Lorem ipsum',
'password': '123',
});
user.save().then(function(){
...
}).catch(function(data){
console.log(user.get('errors'), data);
// data is ErrorClass with deserialize errors inside
});
And API responce (422 Unprocessable Entity):
{
"errors":[
{
"detail":"Email address must be between 6 and 128 characters in length",
"source":{
"pointer":"/data/attributes/password"
}
}
]
}
In this case isError flag is false, user.get('errors') -> empty
I also tried response with 500 Internal Server Error code
In this case isError flag is true (as expected) and error object contain in adapterError
So what I'm doing wrong or what try to check,
thanks in advance
As for the isError flag, it shouldn't be true if you got Validation error (the one that has 422 code). It's described in docs.
Your main problem is that you have a redundant forward slash in the beginning. So you have to change this "pointer":"/data/attributes/password" to this "pointer":"data/attributes/password"
After this change you'll be able to get the errors for this property through user.get('errors.password');
Hope it helps!

Handling typeError through Ember.onerror

I would like to be able to be able to handle javascript errors in my Ember application and display a generic modal defined in my application's templates. I'm able to process errors by defining a function for Ember.onerror, but haven't been able to find a way to trigger an event or action against my application for certain error types, for instance a TypeError.
Below is a sample of how I've approached defining Ember.onerror
App.report_errors = (error) ->
console.log "error", error
# Would like to be able to use something like the below line
# to call an action on the application route
#send "showError"
# Log to api
Em.onerror = App.report_errors
Here is a full example fiddle illustrating what I would like to accomplish: http://jsfiddle.net/mandrakus/c8E3x/1/
Thanks!
This solution (courtesy Alex Speller) adds an errorReporter object which is injected during initialization with the ability to access the router and therefore router actions.
App.initializer
name: 'errorReporter'
initialize: (container) ->
container.injection 'reporter:error', 'router', 'router:main'
container.injection 'route', 'errorReporter', 'reporter:error'
reporter = container.lookup 'reporter:error'
Em.onerror = (error) ->
reporter.report error
App.ErrorReporter = Em.Object.extend
report: (error) ->
console.log "error", error
#Would like to be able to use something like the below line
#to call an action on the application route
#router.send "showError"
App.ApplicationRoute = Ember.Route.extend
actions:
error: (error) -> #errorReporter.report error
showError: ->
console.log "displaying error"
#the final application generate a modal or other notification
alert "Generic Error Message"
How about this?
App.report_errors = function (error) {
App.__container__.lookup("route:application").send("showError", error);
};
Two potential problems:
Using global App object. Not a big deal, unless you're trying to host two ember apps side-by-side
Using the hidden container property. This might change name/location in the future, but as I see it used all over the place, I doubt Ember team will remove it completely.

Laravel Response::download() test

I have the following code in one of my routes:
return Response::download('cv.pdf');
Any idea how to test this? I've tried to use shouldReceive() but that doesn't seem to work ('shouldReceive() undefined function....').
$response->assertDownload() was added in Laravel 8.45.0:
Assert that the response is a "download". Typically, this means the invoked route that returned the response returned a Response::download response, BinaryFileResponse, or Storage::download response:
$response->assertDownload();
Learn More:
https://laravel.com/docs/8.x/http-tests#assert-download
EDIT: As pointed by #DavidBarker in his comment to the OP question
The Illuminate\Support\Facades\Response class doesn't actually extend
Illuminate\Support\Facades\Facade so doesnt have the shouldRecieve()
method. You need to test the response of this route after calling it
in a test.
So if you want to test your download functionality, you can try checking the response for errors with:
$this->assertTrue(preg_match('/(error|notice)/i', $response) === false);
You can assert that the status code is 200
$this->assertEquals($response->getStatusCode(), 200);
because sometimes you might have some data returned that match "error" or "notice" and that would be misleading.
I additionally assert that there's an attachment in the response headers:
$this->assertContains('attachment', (string)$response);
You can use Mockery to mock the download method, for this you will need to mock ResponseFactory.
public function testDownloadCsv()
{
$this->instance(
ResponseFactory::class, Mockery::mock(ResponseFactory::class, function ($mock) {
$mock->shouldReceive('download')
->once()
->andReturn(['header' => 'data']);
}));
$response = $this->get('/dowload-csv');
$response->assertStatus(Response::HTTP_OK);
$response->assertJson(['header' => 'data']); // Response
}

Controller Unit Test fails with SQLSTATE[42000] error

I want to unit test a controller action and have some problem toio excecute it.
The Error i got is the following:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'questionExists'
at line 1
The Method:
questionExists
is defined inside the Question Model.
My test function looks like this:
public function testView() {
$result = $this->testAction('/questions/questions/view/1', array('return' => 'vars'));
}
The Controller action i want to test looks like this:
public function view($id = null) {
if (!$this->Question->questionExists($id, 'id_virtual')) {
throw new NotFoundException(__('Invalid question'));
}
$options = array('conditions' => array('Question.id_virtual' => $id));
$this->set('question', $this->Question->find('first', $options));
}
So this is very confusing to me.
Can anybody point me to the right direction ?
Your model class is not found, CakePHP creates an instance on the fly for that table but this is not more than the basic Model class. When the code is then called it tries to call that method on an instance that is not your Question model in your app. You'll have to figure out what that happens.

test of angularjs controller: unsatistifed post request

I'm testing an angularjs controller, using also mocks, but it raises the error 'Error: Unsatisfied requests: POST /myurl
My file for test contains a beforeEach method like this
httpBackend.whenPOST('/myurl')
.respond( 200,obj1 );
httpBackend.expectPOST('/myurl')
scope = $rootScope.$new();
MainCtrl = $controller('MyCtrl', {
$scope:scope
});
and my test case is:
it('scope.mymethod should work fine', function(){
httpBackend.flush()
// verify size of array before calling the method
expect(scope.myobjs.length).toEqual(2)
// call the method
scope.saveNewPage(myobj)
// verify size of array after calling the method
expect(scope.myobjs.length).toEqual(3)
})
The method saveNewPage looks like:
function saveNewPage(p){
console.log('Hello')
$http.post('/myurl', {
e:p.e, url:p.url, name:p.name
}).then(function (response) {
otherMethod(new Page(response.data.page))
}, handleError);
}
Note that console.log('Hello') is never executed (in karma console it's never printed).
EDIT:
In the meanwhile I'm studying the doc about httpBackend, I tried to change the position of httpBackend.flush(). Basically, i'm executing a first flush(), to initialize data in the scope, then I execute the method, and then I execute an other flush() for the pending request. Specifically, in this situation the test case look like:
it('scope.saveNewPage should work fine', function(){
var p=new Object(pages[0])
httpBackend.flush()
httpBackend.whenPOST('/myurl',{
url:pages[0].url,
existingPage:new Object(pages[0]),
name:pages[0].name
}).respond(200,{data:pages[0]})
httpBackend.expectPOST('/myurl')
scope.saveNewPage(p)
httpBackend.flush()
expect(scope.pages.length).toBe(3)
})
But now it raises Error: No response defined !, like if I didn't specified the mock for that url
I solved in this way:
I put the calls of whenPOST and expectPOST before calling the method to test
I put httpBackend.flush() after calling the method to test, such that, invoking the method it generates pending request, and by httpBackend.flush() it satisfies the pending requests
I adjusted the parameter of respond method. Basically it didn't need to associate the response to a data key of the response
Assuming the POST is supposed to come from saveNewPage, you will need to call httpBackend.flush() between saveNewPage and the line where you inspect the result. flush only flushes the responses that have already been requested by your code.
it('scope.mymethod should work fine', function(){
expect(scope.myobjs.length).toEqual(2)
scope.saveNewPage(myobj)
expect(scope.myobjs.length).toEqual(2)
httpBackend.flush()
expect(scope.myobjs.length).toEqual(3)
})