I'm building a test for a controller name GeneController that uses a service called Gene to make a bunch of API GET requests. I've mocked the main GET request like this and I'm pretty sure it's working properly:
$httpBackend.expectGET '/api/knowledge/genes/param1'
.respond(200, JSON.stringify({
data: {
mutationsUrl: 'http://localhost:3000/api/knowledge/genes/param1/mutations',
frequenciesUrl: 'http://localhost:3000/api/knowledge/genes/param1/frequencies',
annotationUrl: 'http://localhost:3000/api/knowledge/genes/param1/annotation',
sections: {
description: {
data: 'holder'
}
}
}
}))
Controller: GeneController
.controller 'GeneController', Array '$scope', '$routeParams', '$http', 'Gene', ($scope, $routeParams, $http, Gene) ->
$scope.entity = Gene.get($routeParams
(entity) ->
$scope.description = entity.data.sections.description.data
entity.getUrl entity.data.mutationsUrl, {limit: 10}, (err, mutationsData) ->
if ! err?
for m in mutationsData.data
m.selected = true
$scope.mutations = mutationsData
entity.getUrl entity.data.frequenciesUrl, {}, (err, frequenciesData) ->
if ! err?
$scope.frequencies = frequenciesData
entity.getUrl entity.data.annotationUrl, {}, (err, annotationData) ->
if ! err?
$scope.annotation = annotationData
(error) ->
console.log error
)
Service: Gene
.factory 'Gene', Array '$resource', '$http', ($resource, $http) ->
Gene = $resource '/api/knowledge/genes/:gene', {},
query:
method: 'GET'
Gene.prototype.getUrl = (url, options, callback) ->
$http {method: 'GET', url: url, params: options}
.then (res) -> # Success callback
callback null, res.data
,(res) -> # Error callback
callback res.status, res.data
Gene
The problem I'm having is with the "secondary" GET requests that are being facilitated by the Gene.prototype.getUrl method. I think the method itself is working fine because the proper content (from mutations, frequencies, and annotation) is displaying on the webpage. However these GET requests are failing and I'm getting the following error from mocha: "undefined is not an object (evaluating 'mutationsData.data')".
I've mocked the responses to these GET requests to no avail. Here is my test for the controller.
Test
...
describe 'GeneController', () ->
Gene = undefined
beforeEach inject (_$controller_, $rootScope, _Gene_, _$httpBackend_) ->
scope = $rootScope.$new()
controller = _$controller_ 'GeneController', {
$scope: scope
$routeParams: { gene: 'param1' }
}
Gene: _Gene_
$httpBackend = _$httpBackend_
describe 'valid response', () ->
beforeEach () ->
$httpBackend.whenGET 'http://localhost:3000/api/knowledge/genes/param1/mutations'
.respond(200, JSON.stringify({
data: "something"
}))
$httpBackend.whenGET 'http://localhost:3000/api/knowledge/genes/param1/frequencies'
.respond(200, JSON.stringify({
data: 'somethingelse'
}))
$httpBackend.whenGET 'http://localhost:3000/api/kowledge/gene/param1/annotation'
.respond(200, JSON.stringify({
data: 'somethingelser'
}))
$httpBackend.expectGET '/api/knowledge/genes/param1'
.respond(200, JSON.stringify({
data: {
mutationsUrl: 'http://localhost:3000/api/knowledge/genes/param1/mutations',
frequenciesUrl: 'http://localhost:3000/api/knowledge/genes/param1/frequencies',
annotationUrl: 'http://localhost:3000/api/knowledge/genes/param1/annotation',
sections: {
description: {
data: 'holder'
}
}
}
}))
$httpBackend.flush()
it "should set $scope.description when the Gene is called", () ->
expect(scope.description).to.equal "holder"
Any help with this problem would be very much appreciated. I'm quite thoroughly stuck on this. Thank you in advance :)
The controller was making calls to our Rest API in a non-Restful way. I have split each GET request into its own code block, using restangular to implement promises:
.controller 'GeneController', Array '$scope', '$routeParams', 'Gene', 'Restangular', ($scope, $routeParams, Gene, Restangular) ->
_genes_ = Restangular.all('knowledge').all('genes')
_genes_.get($routeParams.gene).then (results) ->
$scope.entity = results.data
$scope.description = $scope.entity.data.sections.description.data
.catch (error) ->
console.log 'Unable to load genes data'
_genes_.all($routeParams.gene).get('mutations').then (results) ->
for m in results.data.data
m.selected = true
$scope.mutations = results.data
.catch (error) ->
console.log 'Unable to load mutations data'
_genes_.all($routeParams.gene).get('frequencies').then (results) ->
$scope.frequencies = results.data
.catch (error) ->
console.log 'Unable to load frequencies data'
_genes_.all($routeParams.gene).get('annotation').then (results) ->
$scope.annotation = results.data
.catch (error) ->
console.log 'Unable to load annotation data'