Test RESTful JSON Grails Webservice - rest

I want to test my secured webservice to the following:
UrlMapping correct, so are the following services available or not?
Test GET/POST/PUT/DELETE and their rendered feedback as well as errors
Test error messages when logged in and not logged in
Can somebody give me some hints how to do this? I have no clue how accessing the grails security service and as well running tests against my controllers when logged in and when not. As well I need some Mock Server or something to test against my controllers or?
Sorry I am very new to this topic but I want to go in the right direction before loosing control over my webservices.
Thank you for your help!

We use the REST Client plugin along with the functional testing plugin to test all our web services.
For example...
void testCreateTag() {
def name = 'Test Name'
def jsonText = """
{
"class":"Tag",
"name":"${name}"
}
"""
post('/api/tag') {
headers['x-user-external-id'] = securityUser.externalId
headers['x-user-api-key'] = securityUser.apiKey
headers['Content-type'] = 'application/json'
body {
jsonText
}
}
def model = this.response.contentAsString
def map = JSON.parse(model)
assertNotNull(map.attributes.id)
Tag.withNewSession {
def tag = Tag.get(map.attributes.id)
assertNotNull(tag)
assertEquals(name, tag.name)
}
}

I have similar code which uses the built in (groovy 1.8) JsonSlurper which I think might be more reliable and only needs the functional test plugin but not the REST Client plugin.
String baseUrlString = 'http://localhost:8080/**YOURAPP**'
baseURL = baseUrlString
post('/j_spring_security_check?')
assertStatus 200
assertContentDoesNotContain('Access Denied')
get("/*your test URL*/")
def jsonObj = new JsonSlurper().parseText(this.response.contentAsString)
assertEquals(jsonObj.your.object.model, **yourContent**)

Related

How to build soap request with script view?

I'm trying to build a SOAP request with Groovy/Java.
However, I didn't found any information on web and on Katalon documentation.
There is a lot of documentation for REST testing, but not for SOAP ...
https://docs.katalon.com/katalon-studio/docs/create_rest_api_requests_manually.html#introduction
https://docs.katalon.com/katalon-studio/docs/web-services-builder.html
https://api-docs.katalon.com/
My objective is to do something like :
// THIS CODE IS WRONG !!!! It's just to give you an idea of my need
RequestObject requestObject = new SOAPRequestBuilder()
def variables = new HashMap<String, String>()
variables.put('variable', 'some text')
requestObject.setVariables(variables)
def response = WS.sendRequest(requestObject)
Someone has any idea how to do that? Thank you for help.
Update 1
I found this solution but I don't know if it is a best pratice ...
def request = findTestObject('RequestObject', [('variable') : 'some text'])
def response = WS.sendRequest(request)
If you're looking for something product-agnostic, you could use groovy-wslite, which handles both REST and SOAP. For example:
def client = new SOAPClient("http://...")
def response = client.send(SOAPAction: ...) {
body {
...
}
}

Unit testing NancyFX API - ConfigurableBootstrapper Exception

Im trying to get nunit test setup for my Nancy API. I have a very simpLe end point:
this.Get["/"] = _ =>
{
return Negotiate
.WithModel(" API is running")
.WithStatusCode(HttpStatusCode.OK);
};
When I try to test it with this test:
this._browser = new Browser(with => {
with.Module(new IndexModule());
});
var result = this._browser.Get("/", with => { with.HttpRequest(); });
Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.OK));
I get ConfigurableBootstrapper Exception and with message of "OhNoes".
If I change the return to:
return "API is running";
It works. I think I might be missing something in the test setup to allow the negotiated return.
Does anyone have an idea of what I'm doing wrong? Thanks.
There will be a clue in the "Oh Noes" exception - probably something like;
Nancy.ViewEngines.ViewNotFoundException
Try adding
with.Header("Accept", "application/json")
or similar to your request setup. By default I think the testing browser requests HTML content, which Negotiate will want to render in a view. See here https://github.com/NancyFx/Nancy/wiki/Content-Negotiation under the section "Default response processors"

How to write a Integration test in Grails for Domain Class as a REST resource?

I am using a Domain Class as a rest resource as mentioned in Grails documentation
So while using this approach there are no controllers or service classes created. And I tried to find a way to write Integration tests for the Domain as a REST resource but could not find it. So kindly tell me how to do it or post a link to somewhere which tells the same.
Regarding this approach, well it is the exact approach asked to make so I cannot change to other way of using REST services.
Thanks in advance.
You should consider using Spock as your test framework:
https://spock-framework.readthedocs.org/en/latest/
Example how to use it for REST:
class ExampleWebAppSpecification extends Specification {
def "Should return 200 & a message with the input appended"() {
setup:
def primerEndpoint = new RESTClient( 'http://localhost:8080/' )
when:
def resp = primerEndpoint.get([ path: 'exampleendpoint', query : [ input : 'Get a hair cut' ]])
then:
with(resp) {
status == 200
contentType == "application/json"
}
with(resp.data) {
payload == "Something really important: Get a hair cut"
}
}
}
EDIT -
In the buildConfig.groovy:
compile("org.codehaus.groovy:groovy-all:2.2.0")
compile("com.fasterxml.jackson.core:jackson-databind")
testCompile("org.spockframework:spock-core:0.7-groovy-2.0")
testCompile("org.codehaus.groovy.modules.http-builder:http-builder:0.7+")
testCompile("net.sf.json-lib:json-lib:2.4+")

Spray Authentication method with BasicAuth

Spray is hard!! I now know that my knowledge on HTTP protocol is not nearly enough and API design isn't easy. However, I still very much want my practice app to work. I'm writing this authentication for POST/PUT/DELETE method. It appears that there are at least two ways to do this: BasicAuth or write a custom directive.
I found this article:
BasicAuth: https://github.com/jacobus/s4/blob/master/src/main/scala/s4/rest/S4Service.scala
I'm trying it out because it looks simple.
The compile and run stages are fine, and the server runs. However, when I'm trying to send a PUT request to test the implementation (using Python's Httpie: http PUT 127.0.0.1:8080/sec-company/casper username=username token=123), the feedback is:HTTP/1.1 404 Not Found
Here's my route:
pathPrefix("sec-company") {
path("casper") {
//first examine username and token
authenticate(BasicAuth(CustomUserPassAuthenticator, "company-security")) {userProfile =>
post { ctx =>
entity(as[Company.Company]) { company =>
complete {
company
}
}
}
}
Here is my implementation of UserPassAuthenticator:
object CustomUserPassAuthenticator extends UserPassAuthenticator[UserProfile] {
def apply(userPass: Option[UserPass]) = Promise.successful(
userPass match {
case Some(UserPass(user, token)) => getUserProfile(user, token)
case _ => None
}
).future
}
First of all, is this the right way to implement authentication? Second, where does UserPassAuthenticator find the username and password?? Can I send back a better HTTP header other than 404 to indicate failed authentication?
If this is far from correct, is there any tutorial on authentication that I can follow? TypeSafe's Spray templates are more about overall patterns and less about Spray's functionality!
Thank you!
I had the same problem, even after looking at https://github.com/spray/spray/wiki/Authentication-Authorization (which says it's for an older version of Akka but it still seems to apply) I came up with the following:
trait Authenticator {
def basicUserAuthenticator(implicit ec: ExecutionContext): AuthMagnet[AuthInfo] = {
def validateUser(userPass: Option[UserPass]): Option[AuthInfo] = {
for {
p <- userPass
user <- Repository.apiUsers(p.user)
if user.passwordMatches(p.pass)
} yield AuthInfo(user)
}
def authenticator(userPass: Option[UserPass]): Future[Option[AuthInfo]] = Future { validateUser(userPass) }
BasicAuth(authenticator _, realm = "Private API")
}
}
I mix in this trait into the Actor that runs the routes and then I call it like this:
runRoute(
pathPrefix("api") {
authenticate(basicUserAuthenticator) { authInfo =>
path("private") {
get {
authorize(authInfo.hasPermission("get") {
// ... and so on and so forth
}
}
}
}
}
}
The AuthInfo object returned by the validateUser method is passed as a parameter to the closure given to the authorize method. Here it is:
case class AuthInfo(user: ApiUser) {
def hasPermission(permission: String) = user.hasPermission(permission)
}
In Spray (and HTTP), authentication (determining whether you have a valid user) is separate from authorization (determining whether the user has access to a resource). In the ApiUser class I also store the set of permissions the user has. This is a simplified version, my hasPermission method is a bit more complex since I also parametrize permissions, so it's not just that a particular user has permission to do a get on a resource, he might have permission to read only some parts of that resource. You might make things very simple (any logged-in user can access any resource) or extremely complex, depending on your needs.
As to your question, when using HTTP BASIC authentication (the BasicAuth object), the credentials are passed in the request in an Authorization: header. Your HTTP library should take care of generating that for you. According to the HTTP standard, the server should return a 401 status code if the authentication was incorrect or not provided, or a 403 status code if the authentication was correct but the user doesn't have permissions to view the content.

Spray testing basicauth from js html

I have code like:
https://gist.github.com/daaatz/7665224
but dont know how to test request.
Trying mydomain/secured?user=John&password=p4ssw0rd etc but nothing works.
Can some one tell me or show example in js+html how to check is it working fine ?
Thanks
I've never used BasicAuth in Spray, so i'm not sure if this would be the complete answer, but i hope this will help you.
At first. in spray there is a great spray-testkit written on top of akka testkit. You should definitely check out SecurityDirectives test on github, this will show you how to test basic authentication. A little example, to make this simpler:
As for your route example, i would better edit to the following one:
val myRoute =
(path("secured") & get) {
authenticate(BasicAuth(myUserPassAuthenticator _, realm = "secure site")) {
userName => complete(s"The user is '$userName'")
}
}
}
Adding get directive will specify that this route expects a Get request and sealRoute is obsolete cause RejectionHandler and ExceptionHandler are provided implicitly with runRoute. It is used only in tests, if you want wo check exceptions/rejections.
Now in your tests you should construct auth entities, similar to the test one:
val challenge = `WWW-Authenticate`(HttpChallenge("Basic", "Realm"))
val doAuth = BasicAuth(UserPassAuthenticator[BasicUserContext] { userPassOption ⇒
Future.successful(Some(BasicUserContext(userPassOption.get.user)))
}, "Realm")
And you test case:
"simple auth test" in {
Get("security") ~> Authorization(BasicHttpCredentials("Alice", "")) ~> {
authenticate(doAuth) { echoComplete }
} ~> check { responseAs[String] === "BasicUserContext(Alice)" }
}
In Get("security") specifies that your test will send a Get request on "/security", then add Authorization to the test request, some action and the check part to test the request.
I've never tried to test BasicAuth, so there could be some mistakes.
I would look into CURL for testing routes in web applications, but I've also used the chrome extension Postman with great results as well.