params is empty when i call Post method on Grails - web-services

i'm writing webservices for my application.
my problem is that when i call it using GET method it works , but when i use the POST method params doesn't contains ant of my parameters:
when i call using GET , this is the content of params :
params : [username:azerty, test:test, param2:param2, action:editProfile, controller:userWebService]
when i call using POST, this is the content of params :
params : [action:editProfile, controller:userWebService]
EDIT :
/* user controller */
"/service/$action?"(controller: "userWebService", parseRequest: true)
in UserWebServiceController
....
static allowedMethods = [editProfile:['POST', 'GET']]
....
def editProfile(){
println "params : "+ params
....
}
to test i'm using REST console plugin in chrome

params are not sent as a query string in POST requests unlike GET. The parameter strings has to be embedded in the request body in case of POST request.
Use content-type: application/x-www-form-urlencoded
and in the request-body use
username=azerty&test=test
You should be able to see the parameters in params inside controller.
You should be able to see
params : [age:25, name:Hamila, action:editProfile, controller:userWebService]
Did I make you look younger in the test? :)

Related

Store Data from Postman request in variables to use in tests

Im currently trying to get used to POSTMAN and i was wondering if there is a way to store variables from my request JSON Body via Pre Request in some environment variable so ican resuse it in the tests for response value cheks
This is how my json File might look like
{
"text" : "myText",
"attachments": {
"text": "myText2",
"anotherText" : "myText3"
}
So i want to get all Values, store them in a variable before sending my request, and then test if they match the expected value in my response
(example: myText2 gets mapped to green, myText3 gets mapped to red and so on)
That would make it possible to write one test for several request
Thanks a lot!
You can write the following in your script:
let body = JSON.parse(pm.request.body);
_.forEach(body, (value, key) => pm.environment.set(key, JSON.stringify(value)));
This will set each key and it's associated value as an environment variables.
Note you'll need to JSON.parse the value in the test script before using it for testing.
For eg in your test script you'll need to do something like this:
let attachments = JSON.parse(pm.environment.get('attachments'));
pm.test('All attachments are of correct value', function () {
// ...write your test here using the `attachments` variable
});

How do I configure mime types in a grails Spock test?

Grails 2.3.10.
How can I configure the available mime types for content type negotiation in a Grails Spock test?
When I try to tell the controller to produce JSON content, it seems to want to return an HTTP 406 error. I send in the Accept header in my test code; but, the parser is not able to match it because HTML is the only MIME type that's configured.
My use case...
I have implemented a controller action using the Grails respond method which can return a JSON response. When I hit the endpoint using a REST API call, I am able to get back JSON output (even if no Accept header is specified).
The controller code:
#Transactional(readOnly = true)
class MyObjectController {
static allowedMethods = [save: 'POST']
static responseFormats = ['json']
def myService
#Transactional
def save(MyObject obj) {
obj.validate()
if (obj.hasErrors()) {
respond obj.getErrors(), [status: BAD_REQUEST]
}
myService.addNewCustomer(obj)
respond obj, [formats: responseFormats]
}
}
And my test code:
#TestFor(MyObjectController)
class MyObjectControllerSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test save - json success"() {
given:
def myObj = new MyObject()
controller.myService= Mock(MyObjectService)
when:
request.addHeader "Accept", "application/json"
controller.save(individual)
then:
response.status == HttpStatus.CREATED.value()
response.text == "{}" //.text is giving me an empty string
response.json.x == x //.json throws an exception (parsing an empty string)
}
}
I have verified in the debugger that obj has a valid value and that the respond method is invoked on the last line of the controller action.
What I am finding is that inside the Grails ResponseMimeTypesApi class, the DefaultAcceptHeaderParser is getting constructed with only the HTML mime type. Even though the JSON accept header is being read correctly, the DefaultAcceptHeaderParser isn't able to understand it because no mime types are configured.
How do I control the mime types that get sent to ResponseMimeTypesApi in my unit test spec?
Edit
I have also tried setting the response.format property, as suggested in this answer; but, to no avail.
If you assign a value to request.json that will set the content type. You can also set the content type explicitly with something like request.contentType = 'application/json' or request.contentType = JSON_CONTENT_TYPE. For a list of the content type constants available in your unit tests see the "Testing Mime Type Handling" section under http://grails.org/doc/latest/guide/testing.html#unitTestingControllers.
Another resource to look at is the unit tests at https://github.com/grails/grails-core/blob/4f8d1a605cde60a4a00021102959578dae8bc5a8/grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding/json/JsonBindingSpec.groovy and https://github.com/grails/grails-core/blob/801d507cf3fec5866baa14f6d6b0acd05aa5fb56/grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding/xml/XmlBindingSpec.groovy.
I hope that helps.
EDIT:
To clarify...
I mentioned assigning a value to request.json. The value you assign to that of course is JSON, not the content type. Like this...
request.json = '''
{
"name": "Douglas", "age": "42"
}
'''
When you do that, the content type gets set automatically.
I found that I could write the test that I wanted by converting from a unit to an integration test.
Move the test to the /integration path.
Change the test spec to extend IntegrationSpec
#Autowire the class under test instead of using #TestFor:
Set controller.response.format = 'json' and call controller.request.addHeader 'Accept', 'application/json'

how pass Employee object in restFul Get method

I am passing an Employee Object Form Client in RestFul webservices Jaxrs2/jersy2
#GET
#Path("{empObj}")
#Produces(MediaType.APPLICATION_XML)
public Response readPK(#PathParam("empObj")Employee empObj) {
//do Some Work
System.out.println(empObj.getName());
return Response.status(Response.Status.OK).entity(result).build();
}
how can achive this object using GET method??
thanx in advance
By using #PathParam on a method parameter / class field you're basically telling JAX-RS runtime to inject path segment (usually string) to your (String) parameter. If you're sending an object (Employee) representation directly via your URI (query param, path param) you should also provide ParamConverterProvider. Beware that this is not possible in some situation and it's not a recommended practice. However, if you're sending the object from client to server in message body, simply remove #PathParam and MessageBodyReader will take care of converting input stream to your type:
#GET
#Path("{empObj}")
#Produces(MediaType.APPLICATION_XML)
public Response readPK(Employee empObj) {
//do Some Work
System.out.println(empObj.getName());
return Response.status(Response.Status.OK).entity(result).build();
}

Twitter Typeahead remote

I am trying to use Twitter typeahead but I am facing a problem. I don't know how typeahead passes the string to the server. Is it through a GET parameter? If so, what is the name of the parameter?
Easiest through a GET parameter, you can choose whatever parameter you want.
In JS:
$('#search').typeahead({
name: 'Search',
remote: '/search.php?query=%QUERY' // you can change anything but %QUERY, it's Typeahead default for the string to pass to backend
});
In PHP (or whatever backend you have):
$query = $_GET['query'];
Hope you get the basic idea.
You might want to consider something like this, it is a very basic remote datasource example. The get parameter in this example is 'q'
// Get your data source
var dataSource = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: 'path/to/your/url/json/datasource/?q=%QUERYSTRING',
wildcard: '%QUERYSTRING'
}
});
// initialize your element
var $typehead = $('#form input').typeahead(null, {
source: dataSource
});
// fire a select event, what you want once a user has selected an item
$typehead.on('typeahead:select', function(obj, datum, name) {
//your code here
});
////////////////////////////////////
# in python (django) we get a query string using the request object passed through a view like this
query = request.GET.get('q') or ""
//the caveat [or ""] is just to prevent null exceptions
///////////////////////////////////
# using php
$query = ($_GET['q']) ? $_GET['q'] : "";

Attaching a cookie to a view in Symfony2

I've found a few questions and pages dealing with cookies in Symfony2 but there doesn't seem to be any clear consensus on exactly how this is supposed to work. I can, of course, just fall back to using PHP's native setcookie function but I feel that it should be an easy thing to do with Symfony2 as well.
I have an action in my controller from which I simply want to return a view with a cookie attached. Thus far I have seem examples basically like this:
use Symfony\Compentnt\HttpFoundation\Response;
public function indexAction() {
$response = new Response();
$response->headers->setCookie(new Cookie('name', 'value', 0, '/');
$response->send();
}
The problem with this is that it sends the response... and doesn't render the view. If I set the cookie without sending the headers the view is rendered but the header (cookie) is not sent.
Poking around I found the sendHeaders() method in the Response object so I'm now manually calling that in my action before returning and that seems to work:
public function indexAction() {
...
$response->sendHeaders();
return array('variables' => 'values');
}
But is this really the expected pattern to use? In previous versions of symfony I could set the headers in my controller and expect the view controller to handle sending whatever I had sent. It seems now that I must manually send them from the action to get it to work, meaning I have to call this from any action that I set headers in. Is this the case or is there something that I'm missing that's so obvious that no one has bothered to even mention it in any of the documentation?
I think you're on the right lines with:
$response->headers->setCookie(new Cookie('name', 'value', 0, '/'));
If you're trying to render a template then check out the docs here:
Symfony2 Templating Service
If you look at the line:
return $this->render('AcmeArticleBundle:Article:index.html.twig');
basically the render method is returning a response (which the controller then returns) which has the content of the twig template, all you have to do is intercept this:
$response = $this->render('AcmeArticleBundle:Article:index.html.twig');
$response->headers->setCookie(new Cookie('name', 'value', 0, '/'));
return $response;
I think that's it anyway...