Gmail Api Java Client - Use mockito/powermock example to mock Gmail API calls - mockito

We are using the Gmail API Java Client version 1.19.0. Is there anyone that has implemented successfully a working mock object that could be used for stubing requests such as:
gmailClient.users().history().list("me").setStartHistoryId(startHistoryId).setPageToken(pageToken).execute();
Essentially, we would like to stub the above call and create a specific response, to test different business scenarios.

Please check below a working example of the above question. No need to use powermock. Mockito is only needed.
#Before
public void init() throws Exception{
ListHistoryResponse historyResponse = new ListHistoryResponse();
historyResponse.setHistoryId(BigInteger.valueOf(1234L));
List<History> historyList = new ArrayList<>();
History historyEntry = new History();
Message message = new Message();
message.setId("123456");
message.setThreadId("123456");
List<Message> messages = new ArrayList<>();
messages.add(message);
historyEntry.setMessages(messages);
historyList.add(historyEntry);
mock = mock(Gmail.class);
Gmail.Users users = mock(Gmail.Users.class);
Gmail.Users.History history = mock(Gmail.Users.History.class);
Gmail.Users.History.List list = mock(Gmail.Users.History.List.class);
when(mock.users()).thenReturn(users);
when(users.history()).thenReturn(history);
when(history.list("me")).thenReturn(list);
when(list.setStartHistoryId(BigInteger.valueOf(123L))).thenReturn(list);
when(list.setPageToken(null)).thenReturn(list);
when(list.execute()).thenReturn(historyResponse);
}

you can mock the classes are long as they're not final, etc. what's the limitation here? (haven't looked at the source code for the Google java client libraries but shouldn't be gmail-specific--if you've found someone doing it for another Google java client API you should be able to re-use it).

There is also MockHttpTransport helper class for such a scenario. Please consult with documentation chapter HTTP Unit Testing
HttpTransport transport = new MockHttpTransport() {
#Override
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
return new MockLowLevelHttpRequest() {
#Override
public LowLevelHttpResponse execute() throws IOException {
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
response.addHeader("custom_header", "value");
response.setStatusCode(404);
response.setContentType(Json.MEDIA_TYPE);
response.setContent("{\"error\":\"not found\"}");
return response;
}
};
}
};

Related

How to mock two APIs with MockWebServer Android test cases

I am performing instrumentation testing, in that I am invoking one of the activities which call 2 APIs when activity is created.
Now I want to write instrumentation test cases for this activity, where I have to mock the API response with mockWebServer of mockito. My mocking code works fine when I call one single API, but it fails when two APIs are getting called simultaneously.
Even there is another scenario let's say, we have API to fetch recent message data, but before that, we always authenticate the user by sending refresh token.
In such cases, we need to call API which authenticates the user and then another API to fetch message data. Hence we need to call 2 APIs one after another, let's say in a single method. How will I mock authentication API response and messages API response while writing test cases of that single method?
How should I deal with this issue? Is there any other approach to deal with such a situation where we need to call more than one API at the same time?
Also, I have used SystemClock.sleep(4000); as my callbacks were getting performed asynchronously.
Below is my code to mock API:
public class MyAPIActivityTest {
#Rule
public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule();
#Rule
public ActivityTestRule<MyAPIActivity> myAPIActivityTestRule = new ActivityTestRule<>(MyAPIActivity.class, true, false);
MockWebServer mockWebServer;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void checkVisibilityOfTaskListMockedValidData() throws Exception {
myAPIActivityTestRule.launchActivity(null);
String fileName = "json_files/valid_api_response.json";
mockWebServer = new MockWebServer();
int PORT_NUMBER = 50205;
mockWebServer.start(PORT_NUMBER);
ApiUrls.BASE_QUERY_URL = mockWebServer.url("/").toString();
mockWebServer.enqueue(new MockResponse()
.setBody(getStringFromFile(getContext(), fileName)));
SystemClock.sleep(4000);
Assert.assertEquals(View.VISIBLE, myAPIActivityTestRule.IvDataIsPresent.getVisibility());
Assert.assertEquals(View.GONE, myAPIActivityTestRule.IvDataNotPresent.getVisibility());
}
#After
public void tearDown() throws Exception {
mockWebServer.shutdown();
}
public static String convertStreamToString(InputStream inputStream) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append(StringCharacters.NEW_LINE);
}
reader.close();
return stringBuilder.toString();
}
public static String getStringFromFile(Context context, String filePath) throws Exception {
final InputStream stream = context.getResources().getAssets().open(filePath);
String text = convertStreamToString(stream);
stream.close();
return text;
}
}
Any help is appreciated. Thanks in advance.

How to make outgoing request or webhook in Acumatica?

I'm integrating an Asp.NET application with Acumatica that needs to update shipping information (tracking #, carrier, etc.) when it becomes available in Acumatica. Is there a way to have Acumatica call an endpoint on my Asp.NET app when a shipment is created? I've searched through a lot of the docs (available here), but I haven't come across anything to send OUT information from Acumatica to another web service.
Ideally, this outgoing call would send the shipment object in the payload.
This wasn't available when you asked the question but push notifications seem to be exactly what you're looking for:
Help - https://help.acumatica.com/(W(9))/Main?ScreenId=ShowWiki&pageid=d8d2835f-5450-4b83-852e-dbadd76a5af8
Presentation - https://adn.acumatica.com/content/uploads/2018/05/Push-Notifications.pdf
In my answer I suppose that you know how to call some outside service from C# code, and for your is a challenge how to send notification from Acumatica.
I propose you to extend each Persist method in each Acumatica graph, from which you expect to send notification when object is persisted in db. IMHO the best option for this is to override method persist ( btw, it overriding persist method is well described in T300 ). In code of extension class you can do the following:
public void Persist(PersistDelegate baseMethod)
{
baseMethod(); // calling this method will preserve your changes in db
//here should go your code, that will send push/pop/delete etc web request into your asp.net application. Or in other words your web hook.
}
If you don't have Acumatica 2017R2, then you have to create your own extension project and then you can call it from your Acumatica code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
namespace MyApp
{
public static class Utility
{
private static WebRequest CreateRequest(string url, Dictionary headers)
{
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
WebRequest req = WebRequest.Create(url);
if (headers != null)
{
foreach (var header in headers)
{
if (!WebHeaderCollection.IsRestricted(header.Key))
{
req.Headers.Add(header.Key, header.Value);
}
}
}
return req;
}
else
{
throw(new ArgumentException("Invalid URL provided.", "url"));
}
}
public static string MakeRequest(string url, Dictionary headers = null)
{
WebResponse resp = CreateRequest(url, headers).GetResponse();
StreamReader reader = new StreamReader(resp.GetResponseStream());
string response = reader.ReadToEnd();
reader.Close();
resp.Close();
return response;
}
public static byte[] MakeRequestInBytes(string url, Dictionary headers = null)
{
byte[] rb = null;
WebResponse resp = CreateRequest(url, headers).GetResponse();
using (BinaryReader br = new BinaryReader(resp.GetResponseStream()))
{
rb = br.ReadBytes((int)resp.ContentLength);
br.Close();
}
resp.Close();
return rb;
}
}
}
You can then call it like this:
try
{
Utility.MakeRequest(theUrl, anyHeadersYouNeed);
}
catch(System.Net.WebException ex)
{
throw(new PXException("There was an error.", ex));
}

Calling #Asynchronous metod from library on Wildfly Linux

I've encounter some problem while applying a small library to send email using wildfly email resource
Idea with library is to provide singleton providing asynchronous method to send emails.
in short service looks like
#Singleton
public class MailService {
private static final String MIME_TYPE = "text/html; charset=utf-8";
private static final Logger LOG = Logger.getLogger(MailService.class.getName());
#Inject
private Session session;
#Asynchronous
public void sendEmail(final EmailModel email) {
try {
MimeMessage message = new MimeMessage(session);
if (email.normalRecipientsListIsEmpty()) {
throw new RuntimeException("need destination address.");
}
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email.getNormalRecipients()));
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(email.getCCRecipients()));
message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(email.getBCCRecipients()));
message.setSubject(email.getSubject());
message.setContent(email.getContent(), MIME_TYPE);
Transport.send(message);
} catch (MessagingException e) {
throw new RuntimeException("Failed to sen email.", e);
}
}
}
Injected session is produced in project via #Produces annotation in Stateless service field.
While on windows everything works fine, however if deployed on wildfly running on linux, there is an timeout exception with message like "could not obtain a lock on method within 5000milis"
When i moved whole code to project, with no changes, everything started to work perfectly.
My question is, why is this happening? Is there a difference in implementation somewhere or in configuration? How can i fix that and move code back to library where it can be reused in other projects?

"error": "invalid_client" from custom OWIN implementation

I am implementing OWIN authentication on a mysql backend, I dont thnk thats a problem as my registration work pretty well. I have basically worked off this post (i.e. nicked most of the code).
I am also using DI via autofac so I have changed a few things around to inject dependencies into the SimpleAuthorizationServerProvider
THE PROBLEM
I post grant_type=password, username and password to http://localhost/myappurl/token and I get back "error":"invalid_client". I get no hits when I try to debug so its probably failing in the library and not getting to my own code. Does anyone know why this would be?
Please pardon the lengthy code, I have no idea where the issue could be so I have posted everything I think is relevant, if anyone needs to see more code, please ask.
SimpleAuthorizationServerProvider
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
private readonly IUserService _userService;
public SimpleAuthorizationServerProvider(IUserService userService)
{
_userService = userService;
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var authenticate = await _userService.FindUser(context.UserName, context.Password);
if (!authenticate)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
}
Startup
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app, (IOAuthAuthorizationServerProvider)config.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)));
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app, IOAuthAuthorizationServerProvider provider)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(90),
Provider = provider,
ApplicationCanDisplayErrors=true,
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
IocConfig
public static class IocConfig
{
public static void Register(HttpConfiguration config)
{
var builder = new ContainerBuilder();
// Configure the container
// Register individual components
builder.Register(c => new MySQLContext()).As<IMySqlContext>().InstancePerRequest();
builder.RegisterType<SimpleAuthorizationServerProvider>().As<IOAuthAuthorizationServerProvider>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
You have a lot of code there, so it's not easy to isolate the problem. As a first step, consider removing the code for Autofac DI and see if that makes any difference. It's hard to tell what the problem might be otherwise.
If the issue is indeed related to the DI code, then perhaps this should be a raised as a separate question. In that case, try to create a small code example that demonstrates the issue succinctly. People are more likely to help if the problem code is short and to the point.
Make sure that you've set up SSL for your site. I had a similar issue and the problem was that I was not using SSL.

AsyncCallback with completed event

I am Creating a library using Facebook C# SDK for windows phone.Facebook SDK Library version is 6.0.10.0. Facebook C# SDK contains asynchronous function calls only.
In which there is a postCompleted event handler which takes object and FacebookApiEventArgs as arguments and return type is void.
I am using two classes one is UI class and other is Businesslogic class. from UI i want to call the BusinessLogic class(s) PostWall function which will simply return the last message id.
I want to create a function something like this
public string PostWall(string accessToken, string message)
{
var fb = new FacebookClient(accessToken);
fb.PostCompleted += (o, args) =>
{
if (args.Error != null)
{
return;
}
var result = (IDictionary<string, object>)args.GetResultData();
_lastMessageId = (string)result["id"];
};
var parameters = new Dictionary<string, object>();
parameters["message"] = message;
fb.PostAsync("me/feed", parameters);
}
I do not know how to implement this. Is this functionality achievable or not.
Any help appreciated
Thanks in Advance
you can check out the wp7 sample at at https://github.com/facebook-csharp-sdk/facebook-windows-phone-sample.
What you are doing is already correct.

Resources