"Thou shalt not spam" or what are web notifications

Web notifications are one of the newer features added into modern browsers. They are intended as alerts for the user outside of the web page context. The idea is for them to be browsers and system independent, for example, when using a mobile browser notification could go into the home screen of the device. On the desktop usually they show up on the right-corner of the screen, at least on most desktop environments. They can be very annoying thing and you should think if thoroughly before you decide this is the right way to inform the users. There are some restrictions that avoid the creation of popup but I still have a bad feeling whenever I see one of these. One example of these notifications are the gmail/gtalk updates that show up on new messages (they are useful and annoying at the same time). This is done via the Notification API and we will do a simple example of its usage.

The implementation

First we can start with a simple wrapper for the Notification API that will have a fallback for the WebKit temporary implementation. We will define a simpleNotification object that will be the wrapper and it will contain a function called show that accepts data parameter. This data parameter is also a wrapper object that contains all the required info for a simple notification. For example :

var data = {
    icon: "http://upload.wikimedia.org/wikipedia/commons/7/7e/Jacob_de_Gheyn_-_Wapenhandelinge_4.jpg",
    title: "The Art of War - The Use of Spies ",
    body: "text",
    timeout : 7000,
    errorCallback: function(){
      $("#fallback").text(this.body);
    }
  };

Where the errorCallback is executed if non of our implementations are supported by the browser, as for the others, they should be self descriptive.

var simpleNotification = (function () {
   var my = {};
    my.show = function (data) {
     if (window.webkitNotifications) {
       //check if there is a support for webkitNotifications
       if (window.webkitNotifications.checkPermission() == 0) {
         var notification = webkitNotifications.createNotification(data.icon, data.title, data.body);
         notification.show();
         //set timeout to hide it
         setTimeout(function(){
             notification.cancel();
          }, data.timeout);
       } else {
         webkitNotifications.requestPermission(function () {
           //call the same function again
           my.show(data);
         });
       }
     }else if (window.Notification) {
   //Currently a fallback, but this should be the real implementation on all browsers
       if ("granted" === Notification.permissionLevel()) {
         var notification = new Notification(data.title, data);
         notification.show();
       } else if ("default" === Notification.permissionLevel() ) {
         Notification.requestPermission(function () {
           //call the same function again
           my.show(data);
         });
       }
     }else{
       //Notifications not supported,going with fallback
      data.errorCallback();
     }
   };
 return my;
}());

The standard based implementation is the one that uses window.Notification. An interface defined by W3C

  [Constructor(DOMString title, optional NotificationOptions options)]
  interface Notification : EventTarget {
    static readonly attribute NotificationPermission permission;
    static void requestPermission(optional NotificationPermissionCallback callback);

    attribute EventHandler onclick;
    attribute EventHandler onshow;
    attribute EventHandler onerror;
    attribute EventHandler onclose;

    readonly attribute NotificationDirection dir;
    readonly attribute DOMString lang;
    readonly attribute DOMString body;
    readonly attribute DOMString tag;
    readonly attribute DOMString icon;

    void close();
  };

Since our data object already contains similar values it can be passed directly in the instantiation of the Notification object. For example :

var notification = new Notification(data.title, data);

On the other hand window.webkitNotifications is the non-standard Chrome implementation. For a more detailed usage of the webkit version please see decadecity blogpost.

In order for us to be able to trigger the notification it is important in the html snippet to have some element that can be user triggered. We have some simple html containing a button

 <body>
   <button id="show">Show quote</button>
   <div id="fallback"> my fallback notification</div>
 </body>

This is needed in order to have request for the permission and to avoid “spam” notification. In our case this is the onClick function on the button. More specifically the jQuery click event. The call now is very simple, we just create the data object using some defaults and load some random data.

$(document).ready(function() {
    $("#show").click(function () {
      var data = {
        icon: "http://upload.wikimedia.org/wikipedia/commons/7/7e/Jacob_de_Gheyn_-_Wapenhandelinge_4.jpg",
        title: "The Art of War - The Use of Spies ",
        body: "text",
        timeout : 7000,
        errorCallback: function() {
          $("#fallback").text(this.body);
        }
      };
      var randomSampleId = Math.floor(Math.random()*sampleData.quotes.length)+1;
      var sample = sampleData.quotes[randomSampleId];
      for (var key in sample) {
        data.title += key;
        data.body = sample[key];
       }

      simpleNotification.show(data);
    });
});

The sample data used is a JSON containing quotes from “Sun Tzu -The Art of War” which is also available for for free on project gutenberg (win for public domain). The data is structured in the following format :

var sampleData = {
    quotes: [
     {
       "1": "Sun Tzu said: Raising a host of a hundred thousand men and marching them great distances entails heavy loss on the people and a drain on the resources of the State.The daily expenditure will amount to a thousand ounce of silver. There will be commotion at home and abroad, and men will drop down exhausted on the highways, As many as seven hundred thousand lies will be impededin their labor."
     },
     {
       "2": "Hostile armies may face each other for years, striving for the victory which is decided in a single day.This being so, to remain in ignorance of the enemy's condition simply because one grudges the outlay of a hundred ounces of silver in honors and emoluments, is the height of inhumanity."
     }
    ]
 };

One more thing to note is that Web Notifications were not supported by IE when this article was written.

You can play around with the jsfiddle to see it in action.

Related links

Published on Jan 20, 2014 by Mite Mitreski
Updated on 1/20/2014 02:37:00 AM

Run, JUnit! Run!!!

This blog post is crossposted and originally part of the 2013 edition Java Advent Calendar a lovely initiative from Attila-Mihaly Balazs and the Transilvania JUG 

JUnit together with JavaScript and SVN are some of the technologies that programmers often start using without even reading a single blog post let alone a book.  Maybe this is a good thing since they look simple enough and understandable so we can use them right away without any manuals, but this also means that they are also underused. In this article we will go through some features of JUnit that I consider very useful.

Parameterized tests 

Sometimes we need to run the same method or functionality with many different inputs and different expected results. One way to do this would be to create separate tests for each of the cases, or you
can use loop but that it would be harder to track down the origin of a possible test failure.

For example if we have the following value object representing rational numbers:

public class RationalNumber {

  private final long numerator;
  private final long denominator;

  public RationalNumber(long numerator, long denominator) {
    this.numerator = numerator;
    this.denominator = denominator;
  }

  public long getNumerator() {
    return numerator;
  }

  public long getDenominator() {
    return denominator;
  }

  @Override
  public String toString() {
    return String.format("%d/%d", numerator, denominator);
  }
}
And we have a service class called App with a method convert that divides the number to a rounded value of 5 decimal :

public class App {

  /**
   * THE Logic
   *
   * @param number some rational number
   * @return BigDecimal rounded to 5 decimal points
   */
  public static BigDecimal convert(RationalNumber number) {
    BigDecimal numerator = new BigDecimal(number.getNumerator()).
        setScale(5, RoundingMode.HALF_UP);

    BigDecimal result = numerator.divide(
        new BigDecimal(number.getDenominator()),
        RoundingMode.HALF_UP);

    return result;
  }
}

And for the actual AppTest class we have

@RunWith(Parameterized.class)
public class AppTest {

  private RationalNumber input;
  private BigDecimal expected;

  public AppTest(RationalNumber input, BigDecimal expected) {
    this.input = input;
    this.expected = expected;
  }

  @Parameterized.Parameters(name = "{index}: number[{0}]= {1}")
  public static Collection<Object> data() {
    return Arrays.asList(new Object[][]{
      {new RationalNumber(1, 2), new BigDecimal("0.50000")},
      {new RationalNumber(1, 1), new BigDecimal("1.00000")},
      {new RationalNumber(1, 3), new BigDecimal("0.33333")},
      {new RationalNumber(1, 5), new BigDecimal("0.20000")},
      {new RationalNumber(10000, 3), new BigDecimal("3333.33333")}
    });
  }

  @Test
  public void testApp() {
    //given the test data
    //when
    BigDecimal out = App.convert(input);
    //then
    Assert.assertThat(out, is(equalTo(expected)));
  }

}


The Parametrized runner or  @RunWith(Parameterized.class)  enables the "parametrization" or in other words the injection of the collection of values annotated with  @Parameterized.Parameters into the Test constructor where each of the sublist is an parameter list.  This means that each of the RationalNumber objects in the data() method will be injected into the input variable and each of the BigDecimal values would be the expected value, so in our example we have 5 tests.

There is also an optional custom naming of the generated test added in the annotation, so "{index}: number[{0}]= {1}" will be replaced with the appropriate parameters defined in the data() method and the "{index}" placeholder will be the test case index, like in the following image

Running the parametrized tests in IntelliJ Idea 











JUnit rules

The simplest definition of JUnit rules is that they are in a sense an interceptors  and very similar to the Spring aspect oriented programming or Java EE interceptors API. Basically you can do useful things before and after the test execution.
OK so let's start with some of the built in test rules. One of them is ExternalResource  where the idea is that we setup an external resource and after the teardown garteet the resource was freed up. A classic example of such test is a creation of file, so for that purpose we have a built in class TemporaryFolder but we can also create our own ones for other resources :



  public class TheRuleTest {
  @Rule
  public TemporaryFolder folder = new TemporaryFolder();

  @Test
  public void someTest() throws IOException {
    //given
    final File tempFile = folder.newFile("thefile.txt");
    //when
    tempFile.setExecutable(true)  ;
    //then
    assertThat(tempFile.canExecute(), is(true));
  }
}

We could have done this in a @Before and @After blocks and use java temp files but it is easy to forget something and leave some of the files unclosed in some of the scenarios where a test fails.

For example there is also a Timeout rule for methods where if the the execution is not finished in given time limit the test will fail with a Timeout exception. For example to limit the running for 20 milliseconds :
 

@Rule
public MethodRule globalTimeout = new Timeout(20);

We can implement our own rules that can do a policy enforcement or various project specific changes. The only thing that needs to be done is for us to implement the TestRule interface.
A simple scenario to explain the behaviour is to add a rule that prints someting before and after test.


import org.junit.rules.TestRule;

import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class MyTestRule implements TestRule {

  public class MyStatement extends Statement {

    private final Statement statement;

    public MyStatement(Statement statement) {
      this.statement = statement;
    }

    @Override
    public void evaluate() throws Throwable {
      System.out.println("before statement" );
      statement.evaluate();
      System.out.println("after statement");
    }

  }

  @Override
  public Statement apply(Statement statement,
                         Description description) {

    System.out.println("apply rule");
    return new MyStatement(statement);
  }

}

So now that we have our rule we can use it in tests, were the tests will just print out different values:

public class SomeTest {

  @Rule
  public MyTestRule folder = new MyTestRule();

  @Test
  public void testA()  {
    System.out.println("A");
  }

  @Test
  public void testB()  {
    System.out.println("B");
  }
}
When we run a test the following output will be created on the  console output :

apply rule
before statement
A
after statement
apply rule
before statement
B
after statement
From the built in one there is one called ExpectedException that can very useful when trying out testing errors. Additionally there is an option to chain the rules that can be useful in many scenarios.

To sum up

If you wanna say that Spock or TestNG or some library build on top of JUnit have more features than JUnit, than that is probably true.
But you know what? We don't always have those on our class path and chances are that JUnit is there and already used all over the place. Than why not use it's full potential ?


Useful links

Published on Jan 8, 2014 by Mite Mitreski
Updated on 1/08/2014 12:40:00 AM