Ionic 2 MobileFirst 8 handleChallenge function not called - ionic2

I am trying to call handleChallenge worklight methods in Mobilefirst 8.0. But is not called
AuthInit() {
this.challengeHandler =
WL.Client.createSecurityCheckChallengeHandler("UserLogin");
this.challengeHandler.handleChallenge = ((challenge) => {
console.log('---> inside handleChallenge');
});
}
And i have called a protected resource ( adapter methods )
getPosts() {
var resourceRequest = new
WLResourceRequest("/adapters/AppDataAdapter/posts",
WLResourceRequest.GET);
resourceRequest.send().then({
console.log(response);
});
}
but handleChallenge not called

Related

How to mock DialogService.open(...).whenClosed(...) with Jasmine?

We have some TypeScript code using the Aurelia framework and Dialog plugin that we are trying to test with Jasmine, but can't work out how to do properly.
This is the source function:
openDialog(action: string) {
this._dialogService.open({ viewModel: AddAccountWizard })
.whenClosed(result => {
if (!result.wasCancelled && result.output) {
const step = this.steps.find((i) => i.action === action);
if (step) {
step.isCompleted = true;
}
}
});
}
We can create a DialogService spy, and verify the open method easily - but we can't work out how to make the spy invoke the whenClosed method with a mocked result parameter so that we can then assert that the step is completed.
This is the current Jasmine code:
it("opens a dialog when clicking on incomplete bank account", async done => {
// arrange
arrangeMemberVerificationStatus();
await component.create(bootstrap);
const vm = component.viewModel as GettingStartedCustomElement;
dialogService.open.and.callFake(() => {
return { whenClosed: () => Promise.resolve({})};
});
// act
$(".link, .-arrow")[0].click();
// assert
expect(dialogService.open).toHaveBeenCalledWith({ viewModel: AddAccountWizard });
expect(vm.steps[2].isCompleted).toBeTruthy(); // FAILS
done();
});
We've just recently updated our DialogService and ran into the same issue, so we've made this primitive mock that suited our purposes so far. It's fairly limited and doesn't do well for mocking multiple calls with different results, but should work for your above case:
export class DialogServiceMock {
shouldCancelDialog = false;
leaveDialogOpen = false;
desiredOutput = {};
open = () => {
let result = { wasCancelled: this.shouldCancelDialog, output: this.desiredOutput };
let closedPromise = this.leaveDialogOpen ? new Promise((r) => { }) : Promise.resolve(result);
let resultPromise = Promise.resolve({ closeResult: closedPromise });
resultPromise.whenClosed = (callback) => {
return this.leaveDialogOpen ? new Promise((r) => { }) : Promise.resolve(typeof callback == "function" ? callback(result) : null);
};
return resultPromise;
};
}
This mock can be configured to test various responses, when a user cancels the dialog, and scenarios where the dialog is still open.
We haven't done e2e testing yet, so I don't know of a good way to make sure you wait until the .click() call finishes so you don't have a race condition between your expect()s and the whenClosed() logic, but I think you should be able to use the mock in the test like so:
it("opens a dialog when clicking on incomplete bank account", async done => {
// arrange
arrangeMemberVerificationStatus();
await component.create(bootstrap);
const vm = component.viewModel as GettingStartedCustomElement;
let mockDialogService = new MockDialogService();
vm.dialogService = mockDialogService; //Or however you're injecting the mock into the constructor; I don't see the code where you're doing that right now.
spyOn(mockDialogService, 'open').and.callThrough();
// act
$(".link, .-arrow")[0].click();
browser.sleep(100)//I'm guessing there's a better way to verify that it's finished with e2e testing, but the point is to make sure it finishes before we assert.
// assert
expect(mockDialogService.open).toHaveBeenCalledWith({ viewModel: AddAccountWizard });
expect(vm.steps[2].isCompleted).toBeTruthy(); // FAILS
done();
});

When launching icCube report how can I get the user name

in ic3Report.html file, is it possible to get the user name in the callback function ?
var options = {
root: "ic3-report/app/",
rootLocal: "ic3-report/app-local/",
rootVersion: "_IC3_ROOT_VERSION_",
callback: function () {
$('#intro').remove();
window.ic3application = ic3.startReport(
{
<!-- ic3-start-report-options (DO NOT REMOVE - USED TO GENERATE FILES) -->
});
// get user name here !
}
};
in order to gather current user information you should setup GVI configuration. It could be done with appropriate method:
var options = {
root: "ic3-report/app/",
rootLocal: "ic3-report/app-local/",
rootVersion: "_IC3_ROOT_VERSION_",
callback: function () {
$('#intro').remove();
var ic3reporting = new ic3.Reporting(
{
noticesLevel: ic3.NoticeLevel.INFO,
dsSettings: {
url: GVI_URL
}
});
ic3reporting.setupGVIConfiguration(function () {
var userName = ic3reporting.userName();
})
}
};
After that user information will be available inside context. See code above for details.
Update
A more robust solution is adding the code to the local files that are not overwritten with a new version of the reporting. You can use ic3bootstrapLocal function in Admin > Common JS configuration.
function ic3bootstrapLocal(options) {
var ic3reporting = new ic3.Reporting({
noticesLevel: ic3.NoticeLevel.INFO,
});
ic3reporting.setupGVIConfiguration(function(){
ic3reporting.userName()
options.callback && options.callback();
});
}

How to test nested callbacks with Mocha/Sinon?

What is the/one correct way to test this piece of JavaScript code using, e.g, Mocha/Sinon:
var App = function(endPoint, successCallback) {
var channel = new WebSocket(endPoint);
channel.onopen = function(ev) {
successCallback();
};
};
I'm thinking of something like this:
describe('App', function() {
it('test should create instance and call success', function(done) {
var app = new App('ws://foo.bar:123/', done);
var stub = sinon.stub(app, 'channel');
stub.yield('onopen');
});
});
Apparently, that does not work as channel is not accessible from outside the constructor. How would you test this?
Why not create a factory for Websocket such as:
var myApp = {
createWebsocket: function () {
return new Websocket;
}
};
This would make spying on the myApp.createWebsocket return value channel very easy:
sinon.spy(myApp, 'createWebsocket);
var channel = myApp.createWebsocket.firstCall.returnValue;
var stub = sinon.stub(channel, 'onopen');
stub.yield('onopen');
// Clean up
myApp.createWebsocket.restore();

Testing initialization logic in closure in angular service

I have an angular service that is used as a factory function to instatiate many object instances of the type Engine like this:
angular.module('parts.engine', []).factory('Engine', function() {
var Engine = function( settings ) {
this.hp = settings.engine.hp;
this.miles = 0;
};
Engine.prototype.setMiles = function( miles ) { this.miles = miles; }
return Engine;
});
Say I have another angular service, that is also used to create instances of an object like this:
angular.module('car', ['parts.engine']).factory('carCreator', function( Engine ) {
var carCreator = function( settings ) {
var engine = new Engine( settings );
engine.setMiles( settings.engine.miles )
return {
brand: settings.brand;
engine: engine;
}
};
return carCreator;
});
So I now instatiate a new instance of a car object like this:
angular.module('carApp', ['car']).controller('AppCtrl', function( carCreator ) {
var settings = {
brand: 'Ford',
engine: {
hp: 125,
miles: 12000
}
};
var newCar = carCreator(settings);
});
Does anyone have an idea how to test the initialization logic:
var engine = new Engine( settings );
engine.setMiles( settings.engine.miles )
in the carCreator factory? I know I can instantiate an object with the carCreator class and check, if the returned objects engine.miles property is set to the correct value. But I have cases, where checking for this will not be as easy, because the initalization logic and the values returned are much more complex. What I would like to do is test the businesslogic of setMiles in the Engine class, and just setup a SpyOn on Engine and engine.setMiles when testing the carCreator class, but how do I do that, when engine is created in the closure?
You can use $provide to provide a mock version of the Engine service to carCreator. You'll then be able to spy on it and assert that the correct steps have been taken.
One of the trickier bits of this is that you're testing a constructor function, which jasmine mocks doesn't play so nicely with, you need to return a mockInstance and spy on that instance.
var mockEngine, mockEngineInstance, carCreatorService;
beforeEach(function () {
module('car', function ($provide) {
// Define a mock instance
mockEngineInstance = {
setMiles: function () {}
};
// Mock the engine service to give a mocked instance
mockEngine = function () {
return mockEngineInstance;
};
$provide.value('Engine', mockEngine);
});
inject(function (carCreator) {
carCreatorService = carCreator;
});
});
it('should test that miles are set when a car is created',
function () {
// Arrange.
spyOn(mockEngineInstance, 'setMiles');
// Act.
carCreatorService({
engine: {
miles: 100
}
});
// Assert.
expect(mockEngineInstance.setMiles).toHaveBeenCalledWith(100);
}
);

How do I mock an Angular service using jasmine?

This may be a duplicate but I have looked at a lot of other questions here and they usually miss what I am looking for in some way. They mostly talk about a service they created themselves. That I can do and have done. I am trying to override what angular is injecting with my mock. I thought it would be the same but for some reason when I step through the code it is always the angular $cookieStore and not my mock.
I have very limited experience with jasmine and angularjs. I come from a C# background. I usually write unit tests moq (mocking framework for C#). I am use to seeing something like this
[TestClass]
public PageControllerTests
{
private Mock<ICookieStore> mockCookieStore;
private PageController controller;
[TestInitialize]
public void SetUp()
{
mockCookieStore = new Mock<ICookieStore>();
controller = new PageController(mockCookieStore.Object);
}
[TestMethod]
public void GetsCarsFromCookieStore()
{
// Arrange
mockCookieStore.Setup(cs => cs.Get("cars"))
.Return(0);
// Act
controller.SomeMethod();
// Assert
mockCookieStore.VerifyAll();
}
}
I want mock the $cookieStore service which I use in one of my controllers.
app.controller('PageController', ['$scope', '$cookieStore', function($scope, $cookieStore) {
$scope.cars = $cookieStore.get('cars');
if($scope.cars == 0) {
// Do other logic here
.
}
$scope.foo = function() {
.
.
}
}]);
I want to make sure that the $cookieStore.get method is invoked with a 'garage' argument. I also want to be able to control what it gives back. I want it to give back 0 and then my controller must do some other logic.
Here is my test.
describe('Controller: PageController', function () {
var controller,
scope,
cookieStoreSpy;
beforeEach(function () {
cookieStoreSpy = jasmine.createSpyObj('CookieStore', ['get']);
cookieStoreSpy.get.andReturn(function(key) {
switch (key) {
case 'cars':
return 0;
case 'bikes':
return 1;
case 'garage':
return { cars: 0, bikes: 1 };
}
});
module(function($provide) {
$provide.value('$cookieStore', cookieStoreSpy);
});
module('App');
});
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller;
}));
it('Gets car from cookie', function () {
controller('PageController', { $scope: scope });
expect(cookieStoreSpy.get).toHaveBeenCalledWith('cars');
});
});
This is a solution for the discussion we had in my previous answer.
In my controller I'm using $location.path and $location.search. So to overwrite the $location with my mock I did:
locationMock = jasmine.createSpyObj('location', ['path', 'search']);
locationMock.location = "";
locationMock.path.andCallFake(function(path) {
console.log("### Using location set");
if (typeof path != "undefined") {
console.log("### Setting location: " + path);
this.location = path;
}
return this.location;
});
locationMock.search.andCallFake(function(query) {
console.log("### Using location search mock");
if (typeof query != "undefined") {
console.log("### Setting search location: " + JSON.stringify(query));
this.location = JSON.stringify(query);
}
return this.location;
});
module(function($provide) {
$provide.value('$location', locationMock);
});
I didn't have to inject anything in the $controller. It just worked. Look at the logs:
LOG: '### Using location set'
LOG: '### Setting location: /test'
LOG: '### Using location search mock'
LOG: '### Setting search location: {"limit":"50","q":"ani","tags":[1,2],"category_id":5}'
If you want to check the arguments, spy on the method
// declare the cookieStoreMock globally
var cookieStoreMock;
beforeEach(function() {
cookieStoreMock = {};
cookieStoreMock.get = jasmine.createSpy("cookieStore.get() spy").andCallFake(function(key) {
switch (key) {
case 'cars':
return 0;
case 'bikes':
return 1;
case 'garage':
return {
cars: 0,
bikes: 1
};
}
});
module(function($provide) {
$provide.value('cookieStore', cookieStoreMock);
});
});
And then to test the argument do
expect(searchServiceMock.search).toHaveBeenCalledWith('cars');
Here is an example https://github.com/lucassus/angular-seed/blob/81d820d06e1d00d3bae34b456c0655baa79e51f2/test/unit/controllers/products/index_ctrl_spec.coffee#L3 it's coffeescript code with mocha + sinon.js but the idea is the same.
Basically with the following code snippet you could load a module and substitute its services:
beforeEach(module("myModule", function($provide) {
var stub = xxx; //... create a stub here
$provide.value("myService", stub);
}));
Later in the spec you could inject this stubbed service and do assertions:
it("does something magical", inject(function(myService) {
subject.foo();
expect(myService).toHaveBeenCalledWith("bar");
}));
More details and tips about mocking and testing you could find in this excellent blog post: http://www.yearofmoo.com/2013/09/advanced-testing-and-debugging-in-angularjs.html
Why mock cookieStore when you may use it directly without modification? The code below is a partial unit test for a controller which uses $cookieStore to put and get cookies. If your controller has a method known as "setACookie" that uses $cookieStore.put('cookieName', cookieValue) ... then the test should be able to read the value that was set.
describe('My controller', function() {
var $cookieStore;
describe('MySpecificController', function() {
beforeEach(inject(function(_$httpBackend_, $controller, _$cookieStore_) {
$cookieStore = _$cookieStore_;
// [...] unrelated to cookieStore
}));
it('should be able to reference cookies now', function () {
scope.setACookie();
expect($cookieStore.get('myCookieName')).toBe('setToSomething');
});
});