Handling Auth Token
Sample REST APIs
Let us use Reqres as our APIs under test.
It is common that APIs accept authorization token. Let us see how do we pass auth token to API. We have a login API that generates auth token and let us assume Create User API accepts auth token as part of header. Let’s automate the same.
Login API
To start with let us understand the Login API.
curl -X POST \
https://reqres.in/api/login \
-H 'content-type: application/json' \
-d '{
"email": "eve.holt@reqres.in",
"password": "cityslicka"
}'
Request JSON:
{
"email": "eve.holt@reqres.in",
"password": "cityslicka"
}
Response JSON:
{
"token": "QpwL5tke4Pnpja7X4"
}
Create a postman collection having the Login API
In postman, create a collection with the name “ReqRes“. Create a new request with the name “Login” as shown below
Export postman collection
Export the postman collection “ReqRes” which would generate a JSON file.
The postman collection JSON file would look like below:
{
"variables": [],
"info": {
"name": "ReqRes",
"_postman_id": "1259b5b2-c7e5-6899-d937-5ba036c0c02d",
"description": "",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "Login",
"request": {
"url": "https://reqres.in/api/login",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\n \"email\": \"eve.holt@reqres.in\",\n \"password\": \"cityslicka\"\n}"
},
"description": ""
},
"response": []
}
]
}
Now let us get back to IntelliJ Idea and see how do we call this API
Specify baseUrl
Open src/test/resources/api/hosts.json
and specify baseUrl
as below.
{
"baseUrl": "https://reqres.in/"
}
Specify hosts in config
Open config/default.properties
file & add the api.hosts
property as below
# Api Config
api.hosts: hosts
Generate a model or POJO to represent Request and Response
As we understood from postman, Login API has a Request body and Response body. Let us generate model/POJO classes for both.
From postman, copy the request JSON of Login API to the clipboard.
Right-click on the api/user/login
folder, choose New → Generate POJO from JSON
- Paste the JSON response from clipboard.
- Choose Lombok.
- Enter Root object name as LoginRequest.
- Click Generate button.
This would generate POJO class representing the JSON.
Note: Please replace the @Data
annotation of Lombok with @Getter
in all the generated classes.
LoginRequest.java
package ekam.example.api.login;
import lombok.Getter;
@Getter
public class LoginRequest{
private String password;
private String email;
}
In the same way, please generate LoginResponse POJO representing the response JSON.
LoginResponse.java
package ekam.example.api.login;
import lombok.Getter;
@Getter
public class LoginResponse{
private String token;
}
Generate Retrofit Service & Client
Right-click on api/user/login New → Ekam Component → Retrofit Client. Enter name as Login
This would generate LoginClient
class as below
package ekam.example.api.login;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import com.testvagrant.ekam.reports.annotations.APIStep;
import retrofit2.Call;
import retrofit2.http.*;
public class LoginClient extends RetrofitBaseClient {
private interface LoginService {
}
private final LoginService service;
@Inject
public LoginClient(@Named("baseUrl") String baseUrl) {
super(baseUrl);
service = httpClient.getService(LoginService.class);
}
}
Generate Login Service method
Copy the postman collection JSON to the clipboard
Place the cursor within the interface body. Press Control + Enter (or Code → Generate… menu option) to invoke the below popup.
Choose the “Ekam Retrofit2 Generator” option.
This will open up a dialog “Postman collection“
Paste the postman collection JSON from the clipboard.
Click OK button. This will generate the below code.
@Headers({"Content-Type: application/json"})
@POST("/api/login")
Call<LoginResponse> login(@Body LoginRequest request);
The complete file would look like below.
package ekam.example.api.login;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public class LoginClient extends RetrofitBaseClient {
private interface LoginService {
@Headers({"Content-Type: application/json"})
@POST("/api/login")
Call<LoginResponse> login(@Body LoginRequest request);
}
private final LoginService service;
@Inject
public LoginClient(@Named("baseUrl") String baseUrl) {
super(baseUrl);
service = httpClient.getService(LoginService.class);
}
}
Generate a method to invoke Login API
Let us generate a method that would invoke CreateUser API. To do this, Ekam provides a live template. Press Control+Enter (Code → Generate…) and choose API Step
Complete the template to generate code as below.
@APIStep(keyword = "When", description = "I invoke Login API")
public LoginResponse login(LoginRequest request) {
Call<LoginResponse> call = service.login(request);
return httpClient.execute(call);
}
The LoginClient
class would like as below:
package ekam.example.api.login;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.testvagrant.ekam.api.retrofit.RetrofitBaseClient;
import com.testvagrant.ekam.reports.annotations.APIStep;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public class LoginClient extends RetrofitBaseClient {
private interface LoginService {
@Headers({"Content-Type: application/json"})
@POST("/api/login")
Call<LoginResponse> login(@Body LoginRequest request);
}
private final LoginService service;
@Inject
public LoginClient(@Named("baseUrl") String baseUrl) {
super(baseUrl);
service = httpClient.getService(LoginService.class);
}
@APIStep(keyword = "When", description = "I invoke Login API")
public LoginResponse login(LoginRequest request) {
Call<LoginResponse> call = service.login(request);
return httpClient.execute(call);
}
}
Making CreateUser API accept authorization header
Add a dynamic header to the createUser
service method
@Headers({"Content-Type: application/json"})
@POST("/api/users")
Call<CreateUserResponse> createUser(
@Body CreateUserRequest request,
@Header("authorization") String token);
Refactor createUser
to include the token as parameter
@APIStep(keyword = "When", description = "I invoke createUser API")
public CreateUserResponse createUser(CreateUserRequest request, String token) {
Call<CreateUserResponse> call = service.createUser(request, token);
return httpClient.execute(call);
}
Create a Test which does Login and calls CreateUser API
Let us create a test which calls Login API to get the authorization token, then calls createUser API to create a user.
Here is the test
@Test(groups = "SmokeTest")
public void shouldCreateUser() {
LoginRequest loginRequest = LoginRequest.builder()
.email("eve.holt@reqres.in")
.password("cityslicka")
.build();
String token = Client(LoginClient.class)
.login(loginRequest)
.getToken();
CreateUserRequest createUserRequest = CreateUserRequest.builder()
.name("Bob")
.job("Builder")
.build();
CreateUserResponse response = Client(UserClient.class)
.createUser(createUserRequest, token);
assertEquals(response.getName(), "Bob");
}