How do I get $resource to resolve its promise in test environment - angular-resource

I have a controller that needs to run several asynchronous methods that interact with the data on the client and make no calls to the server. I have one method working fine in the browser, but I want to drive the methods with tests and I can't get it to work in the test environment (Karma and Mocha). The reason is that the empty array that $resource.query() returns never gets populated in the test environment because the promise doesn't get resolved. Here is my beforeEach in the test suite.
beforeEach(inject(function($rootScope, $controller, scheduleService){
scope = $rootScope.$new();
sc = $controller('scheduleCtrl', {
$scope: scope, service: scheduleService
});
scope.$apply();
}));
scheduleCtrl has a property schedule that is assigned to the result of Resource.query() in it's constructor. I can see the three returned objects loaded into the MockHttpExpectation.
But when I go to run the test sc.schedule is an still an empty array, so the test fails. How do I get the Resource.query() to resolve in the test?

Resource.query() works with promisses, which is a assync process.
It happens that your test execute before the assynchronous request have completed and before array gets populated.
You could use $httpBackend so you can call expect after $httpBackend.flush().
Or you could retrieve the $promisse returned from Resource.query().$promisse on your test and do the expectation inside its implementation.
Ex:
$scope.promisse = Resource.query().$promisse;
sc.promisse(function(values) {
expect(values.length).not.toBe(0);
});

Related

Create post status notification method for all pipelines

thanks in advance for the help.
For our project, for which we use Jenkins, I'm working on a shared library to house all methods for our different pipelines (3 different ones).
Currently I'm facing an issue, that I don't really know how to solve.
I configured the jenkins-mattermost-plugin for the project. Ideally, I'd like to create one method for the post task in Jenkins that takes currentBuild.currentResult as an argument and returns the corresponding condition block and its message.
Ex:
if success:
success {
mattermostSend(...success build notification)
}
}
if failure:
failure {
mattermostSend(...failure build notification)
}
}
etc.
The problem is not writing the method itself, but when to call it in the pipeline.
I can't call it in a stage block, not without any block wrapper.
I hope this makes sense what I'm trying to say.
You can call the function in always post-condition:
post {
always {
mattermostSend("${currentBuild.currentResult}")
}
}
Then inside mattermostSend create condition which depending on the build result will send the required message.

Trouble mocking `Resolv::DNS.open`

I'm trying to mock the code below using MiniTest/Mocks. But I keep getting this error when running my test.
Minitest::Assertion: unexpected invocation: #<Mock:0x7fa76b53d5d0>.size()
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:0x7fa76b53d5d0>.getresources("_F5DC2A7B3840CF8DD20E021B6C4E5FE0.corwin.co", Resolv::DNS::Resource::IN::CNAME)
satisfied expectations:
- expected exactly once, invoked once: Resolv::DNS.open(any_parameters)
code being tested
txt = Resolv::DNS.open do |dns|
records = dns.getresources(options[:cname_origin], Resolv::DNS::Resource::IN::CNAME)
end
binding.pry
return (txt.size > 0) ? (options[:cname_destination].downcase == txt.last.name.to_s.downcase) : false
my test
::Resolv::DNS.expects(:open).returns(dns = mock)
dns.expects(:getresources)
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.returns([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
.once
Right now you are testing that Resolv::DNS receives open returns your mock but
since you seem to be trying to test that the dns mock is receiving messages you need to stub the method and provide it with the object to be yielded
Try this instead:
dns = mock
dns.expects(:getresources)
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.once
::Resolv::DNS.stub :open, [Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)], dns do
# whatever code actually calls the "code being tested"
end
dns.verify
The second argument to stub is the stubbed return value and third argument to stub is what will be yielded to the block in place of the original yielded.
In RSpec the syntax is a bit simpler (and more semantic) such that:
dns = double
allow(::Resolv::DNS).to receive(:open).and_yield(dns)
expect(:dns).to receive(:getresources).once
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.and_return([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
# whatever code actually calls the "code being tested"
You can write more readable integration tests with DnsMock instead of stubbing/mocking parts of your code: https://github.com/mocktools/ruby-dns-mock

Project Reactor test never completes

I have created a simple Kafka consumer that returns a Flux of objects (the received messages) and I'm trying to test it using the StepVerifier.
In my test, I do something like that:
Flux<Pojo> flux = consumer.start();
StepVerifier.create(flux)
.expectNextMatches(p -> p.getList().size() == 3)
.verifyComplete();
The assertion works ok (if I change the value from 3 to something else, the test fails). But, if the assertion passes, than the test never exit.
I have also tried to use the verify method like so:
StepVerifier.create(flux)
.expectNextMatches(f -> f.getEntitlements().size() == 3)
.expectComplete()
.verify(Duration.ofSeconds(3));
In this case, I get this error:
java.lang.AssertionError: VerifySubscriber timed out on false
Any idea what I'm doing wrong?
The Kafka Flux is probably infinite, so it never emits the onComplete signal, which the test waits for. You can call .thenCancel().verify() if you're only interested in testing that first value.

Zendesk - CreateUser JobStatus Results is Null

So I am currently working with the ZenDesk API. I am creating many users using the batch CreateUser method that takes an array of up to 100 user objects. Now, for some reason, some users fail to generate. Therefore, I wanted to obtain the result of the JobStatus after creating the users so that I can identify the problem easily. The issue is that the result variable is null after performing the CreateUsers() method.
Some sample code:
public static void createEndUsers(Zendesk zd){
for(Organization org : zd.getOrganizations()){
List<User> usersList = getUsersPerOrg(org, 0)
JobStatus js = zd.createUsers(usersList);
List<T> resultElements = js.getResults();
}
}
Why is getResults() returning null in this instance? Is it because the operation has not yet been performed when it reaches that part of the code? How can I make sure that I "wait" until the result is ready before I try to access it?
If you have a look at the posssible values from org.zendesk.client.v2.model.JobStatus.JobStatusEnum you will notice that the job may be queued for execution or it could still be running at the time that the job status was returned by the operation org.zendesk.client.v2.Zendesk#createUsers(org.zendesk.client.v2.model.User...).
As can be seen from the Zendesk Documentation for createUsers Operation
This endpoint returns a job_status JSON object and queues a background job to do the work. Use the Show Job Status endpoint to check for the job's completion.
only when the job is completed, there will be a corresponding result delivered for the operation.
A possible solution in your case would be to check (possibly in a separate thread) every 500ms whether the job status is not queued or not running (otherwise said whether it completed) and if it successfully completed to retrieve the results.

Strange Problem calling remote service

I am new to Grails and Groovy however my problem is a simple but strange one.
I am making calls to a remote web service as follows:
public Boolean addInvites(eventid,sessionkey ){
String url = this.API_URL+"AddInvites?apikey=${sessionkey}&eventid=${eventid}&userids[]=5&userids[]=23";
def callurl = new URL(url);
println callurl;
def jsonResponse = callurl.getText();
println jsonResponse;
def jsonParsedObject = JSON.parse(jsonResponse);
if(jsonParsedObject){
println jsonParsedObject;
if(jsonParsedObject.code == 200){
return true;
}
}
}
return false;
}
The API_URL here is a "https://api..com/"
Normally making these calls works fine. Json gets returned and parsed. However with the above method, if I add only one userids[]=5 then it works fine but if i add a second one everything hangs after the "println callurl;"
I've checked on the webservice side and the call happens and everything works as expected. If I call it in the browser it works fine. but from the grails web app it simply hangs. I know I'm probably doing something silly here, but I am really stuck. Hope you guys can help.
Are you sure that the [] characters are supposed to be there? If you use the following at the end of your query string, it will effectively pass userids=[5,23] to the server:
&userids=5&userids=23
If the brackets really are necessary, use the URL-escaped values %5B and %5D for them instead.
first of all, you should consider the following bug entry:
http://jira.codehaus.org/browse/GROOVY-3921
URL.getText() does not specify a connection timeout.
if you have access to the server logs check if requests from your grails app are actually received (when adding a second userids[] parameter). if this is not the case, you will probably have to use tcpdump or Wireshark in order to debug on TCP level.

Resources